@@ -409,26 +409,31 @@ qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
409409
410410 mutex_lock (& ha -> fce_mutex );
411411
412- seq_puts (s , "FCE Trace Buffer\n" );
413- seq_printf (s , "In Pointer = %llx\n\n" , (unsigned long long )ha -> fce_wr );
414- seq_printf (s , "Base = %llx\n\n" , (unsigned long long ) ha -> fce_dma );
415- seq_puts (s , "FCE Enable Registers\n" );
416- seq_printf (s , "%08x %08x %08x %08x %08x %08x\n" ,
417- ha -> fce_mb [0 ], ha -> fce_mb [2 ], ha -> fce_mb [3 ], ha -> fce_mb [4 ],
418- ha -> fce_mb [5 ], ha -> fce_mb [6 ]);
419-
420- fce = (uint32_t * ) ha -> fce ;
421- fce_start = (unsigned long long ) ha -> fce_dma ;
422- for (cnt = 0 ; cnt < fce_calc_size (ha -> fce_bufs ) / 4 ; cnt ++ ) {
423- if (cnt % 8 == 0 )
424- seq_printf (s , "\n%llx: " ,
425- (unsigned long long )((cnt * 4 ) + fce_start ));
426- else
427- seq_putc (s , ' ' );
428- seq_printf (s , "%08x" , * fce ++ );
429- }
412+ if (ha -> flags .user_enabled_fce ) {
413+ seq_puts (s , "FCE Trace Buffer\n" );
414+ seq_printf (s , "In Pointer = %llx\n\n" , (unsigned long long )ha -> fce_wr );
415+ seq_printf (s , "Base = %llx\n\n" , (unsigned long long )ha -> fce_dma );
416+ seq_puts (s , "FCE Enable Registers\n" );
417+ seq_printf (s , "%08x %08x %08x %08x %08x %08x\n" ,
418+ ha -> fce_mb [0 ], ha -> fce_mb [2 ], ha -> fce_mb [3 ], ha -> fce_mb [4 ],
419+ ha -> fce_mb [5 ], ha -> fce_mb [6 ]);
420+
421+ fce = (uint32_t * )ha -> fce ;
422+ fce_start = (unsigned long long )ha -> fce_dma ;
423+ for (cnt = 0 ; cnt < fce_calc_size (ha -> fce_bufs ) / 4 ; cnt ++ ) {
424+ if (cnt % 8 == 0 )
425+ seq_printf (s , "\n%llx: " ,
426+ (unsigned long long )((cnt * 4 ) + fce_start ));
427+ else
428+ seq_putc (s , ' ' );
429+ seq_printf (s , "%08x" , * fce ++ );
430+ }
430431
431- seq_puts (s , "\nEnd\n" );
432+ seq_puts (s , "\nEnd\n" );
433+ } else {
434+ seq_puts (s , "FCE Trace is currently not enabled\n" );
435+ seq_puts (s , "\techo [ 1 | 0 ] > fce\n" );
436+ }
432437
433438 mutex_unlock (& ha -> fce_mutex );
434439
@@ -467,7 +472,7 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
467472 struct qla_hw_data * ha = vha -> hw ;
468473 int rval ;
469474
470- if (ha -> flags .fce_enabled )
475+ if (ha -> flags .fce_enabled || ! ha -> fce )
471476 goto out ;
472477
473478 mutex_lock (& ha -> fce_mutex );
@@ -488,11 +493,88 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
488493 return single_release (inode , file );
489494}
490495
496+ static ssize_t
497+ qla2x00_dfs_fce_write (struct file * file , const char __user * buffer ,
498+ size_t count , loff_t * pos )
499+ {
500+ struct seq_file * s = file -> private_data ;
501+ struct scsi_qla_host * vha = s -> private ;
502+ struct qla_hw_data * ha = vha -> hw ;
503+ char * buf ;
504+ int rc = 0 ;
505+ unsigned long enable ;
506+
507+ if (!IS_QLA25XX (ha ) && !IS_QLA81XX (ha ) && !IS_QLA83XX (ha ) &&
508+ !IS_QLA27XX (ha ) && !IS_QLA28XX (ha )) {
509+ ql_dbg (ql_dbg_user , vha , 0xd034 ,
510+ "this adapter does not support FCE." );
511+ return - EINVAL ;
512+ }
513+
514+ buf = memdup_user_nul (buffer , count );
515+ if (IS_ERR (buf )) {
516+ ql_dbg (ql_dbg_user , vha , 0xd037 ,
517+ "fail to copy user buffer." );
518+ return PTR_ERR (buf );
519+ }
520+
521+ enable = kstrtoul (buf , 0 , 0 );
522+ rc = count ;
523+
524+ mutex_lock (& ha -> fce_mutex );
525+
526+ if (enable ) {
527+ if (ha -> flags .user_enabled_fce ) {
528+ mutex_unlock (& ha -> fce_mutex );
529+ goto out_free ;
530+ }
531+ ha -> flags .user_enabled_fce = 1 ;
532+ if (!ha -> fce ) {
533+ rc = qla2x00_alloc_fce_trace (vha );
534+ if (rc ) {
535+ ha -> flags .user_enabled_fce = 0 ;
536+ mutex_unlock (& ha -> fce_mutex );
537+ goto out_free ;
538+ }
539+
540+ /* adjust fw dump buffer to take into account of this feature */
541+ if (!ha -> flags .fce_dump_buf_alloced )
542+ qla2x00_alloc_fw_dump (vha );
543+ }
544+
545+ if (!ha -> flags .fce_enabled )
546+ qla_enable_fce_trace (vha );
547+
548+ ql_dbg (ql_dbg_user , vha , 0xd045 , "User enabled FCE .\n" );
549+ } else {
550+ if (!ha -> flags .user_enabled_fce ) {
551+ mutex_unlock (& ha -> fce_mutex );
552+ goto out_free ;
553+ }
554+ ha -> flags .user_enabled_fce = 0 ;
555+ if (ha -> flags .fce_enabled ) {
556+ qla2x00_disable_fce_trace (vha , NULL , NULL );
557+ ha -> flags .fce_enabled = 0 ;
558+ }
559+
560+ qla2x00_free_fce_trace (ha );
561+ /* no need to re-adjust fw dump buffer */
562+
563+ ql_dbg (ql_dbg_user , vha , 0xd04f , "User disabled FCE .\n" );
564+ }
565+
566+ mutex_unlock (& ha -> fce_mutex );
567+ out_free :
568+ kfree (buf );
569+ return rc ;
570+ }
571+
491572static const struct file_operations dfs_fce_ops = {
492573 .open = qla2x00_dfs_fce_open ,
493574 .read = seq_read ,
494575 .llseek = seq_lseek ,
495576 .release = qla2x00_dfs_fce_release ,
577+ .write = qla2x00_dfs_fce_write ,
496578};
497579
498580static int
@@ -626,8 +708,6 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
626708 if (!IS_QLA25XX (ha ) && !IS_QLA81XX (ha ) && !IS_QLA83XX (ha ) &&
627709 !IS_QLA27XX (ha ) && !IS_QLA28XX (ha ))
628710 goto out ;
629- if (!ha -> fce )
630- goto out ;
631711
632712 if (qla2x00_dfs_root )
633713 goto create_dir ;
0 commit comments