@@ -564,7 +564,10 @@ static void sym53c8xx_timer(struct timer_list *t)
564
564
* Generic method for our eh processing.
565
565
* The 'op' argument tells what we have to do.
566
566
*/
567
- static int sym_eh_handler (int op , char * opname , struct scsi_cmnd * cmd )
567
+ /*
568
+ * Error handlers called from the eh thread (one thread per HBA).
569
+ */
570
+ static int sym53c8xx_eh_abort_handler (struct scsi_cmnd * cmd )
568
571
{
569
572
struct sym_ucmd * ucmd = SYM_UCMD_PTR (cmd );
570
573
struct Scsi_Host * shost = cmd -> device -> host ;
@@ -576,7 +579,7 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
576
579
int sts = -1 ;
577
580
struct completion eh_done ;
578
581
579
- scmd_printk (KERN_WARNING , cmd , "%s operation started\n" , opname );
582
+ scmd_printk (KERN_WARNING , cmd , "ABORT operation started\n" );
580
583
581
584
/*
582
585
* Escalate to host reset if the PCI bus went down
@@ -594,19 +597,7 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
594
597
}
595
598
}
596
599
597
- /* Try to proceed the operation we have been asked for */
598
- sts = -1 ;
599
- switch (op ) {
600
- case SYM_EH_ABORT :
601
- sts = sym_abort_scsiio (np , cmd , 1 );
602
- break ;
603
- case SYM_EH_DEVICE_RESET :
604
- sts = sym_reset_scsi_target (np , cmd -> device -> id );
605
- break ;
606
- default :
607
- break ;
608
- }
609
-
600
+ sts = sym_abort_scsiio (np , cmd , 1 );
610
601
/* On error, restore everything and cross fingers :) */
611
602
if (sts )
612
603
cmd_queued = 0 ;
@@ -623,23 +614,60 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
623
614
spin_unlock_irq (shost -> host_lock );
624
615
}
625
616
626
- dev_warn (& cmd -> device -> sdev_gendev , "%s operation %s.\n" , opname ,
617
+ dev_warn (& cmd -> device -> sdev_gendev , "ABORT operation %s.\n" ,
627
618
sts == 0 ? "complete" :sts == -2 ? "timed-out" : "failed" );
628
619
return sts ? SCSI_FAILED : SCSI_SUCCESS ;
629
620
}
630
621
631
-
632
- /*
633
- * Error handlers called from the eh thread (one thread per HBA).
634
- */
635
- static int sym53c8xx_eh_abort_handler (struct scsi_cmnd * cmd )
622
+ static int sym53c8xx_eh_target_reset_handler (struct scsi_cmnd * cmd )
636
623
{
637
- return sym_eh_handler (SYM_EH_ABORT , "ABORT" , cmd );
638
- }
624
+ struct scsi_target * starget = scsi_target (cmd -> device );
625
+ struct Scsi_Host * shost = dev_to_shost (starget -> dev .parent );
626
+ struct sym_data * sym_data = shost_priv (shost );
627
+ struct pci_dev * pdev = sym_data -> pdev ;
628
+ struct sym_hcb * np = sym_data -> ncb ;
629
+ SYM_QUEHEAD * qp ;
630
+ int sts ;
631
+ struct completion eh_done ;
639
632
640
- static int sym53c8xx_eh_device_reset_handler (struct scsi_cmnd * cmd )
641
- {
642
- return sym_eh_handler (SYM_EH_DEVICE_RESET , "DEVICE RESET" , cmd );
633
+ starget_printk (KERN_WARNING , starget ,
634
+ "TARGET RESET operation started\n" );
635
+
636
+ /*
637
+ * Escalate to host reset if the PCI bus went down
638
+ */
639
+ if (pci_channel_offline (pdev ))
640
+ return SCSI_FAILED ;
641
+
642
+ spin_lock_irq (shost -> host_lock );
643
+ sts = sym_reset_scsi_target (np , starget -> id );
644
+ if (!sts ) {
645
+ FOR_EACH_QUEUED_ELEMENT (& np -> busy_ccbq , qp ) {
646
+ struct sym_ccb * cp = sym_que_entry (qp , struct sym_ccb ,
647
+ link_ccbq );
648
+ struct scsi_cmnd * cmd = cp -> cmd ;
649
+ struct sym_ucmd * ucmd ;
650
+
651
+ if (!cmd || cmd -> device -> channel != starget -> channel ||
652
+ cmd -> device -> id != starget -> id )
653
+ continue ;
654
+
655
+ ucmd = SYM_UCMD_PTR (cmd );
656
+ init_completion (& eh_done );
657
+ ucmd -> eh_done = & eh_done ;
658
+ spin_unlock_irq (shost -> host_lock );
659
+ if (!wait_for_completion_timeout (& eh_done , 5 * HZ )) {
660
+ ucmd -> eh_done = NULL ;
661
+ sts = -2 ;
662
+ }
663
+ spin_lock_irq (shost -> host_lock );
664
+ }
665
+ }
666
+ spin_unlock_irq (shost -> host_lock );
667
+
668
+ starget_printk (KERN_WARNING , starget , "TARGET RESET operation %s.\n" ,
669
+ sts == 0 ? "complete" :sts == -2 ? "timed-out" : "failed" );
670
+ return SCSI_SUCCESS ;
643
671
}
644
672
645
673
static int sym53c8xx_eh_bus_reset_handler (struct scsi_cmnd * cmd )
@@ -1660,7 +1688,7 @@ static const struct scsi_host_template sym2_template = {
1660
1688
.slave_configure = sym53c8xx_slave_configure ,
1661
1689
.slave_destroy = sym53c8xx_slave_destroy ,
1662
1690
.eh_abort_handler = sym53c8xx_eh_abort_handler ,
1663
- .eh_device_reset_handler = sym53c8xx_eh_device_reset_handler ,
1691
+ .eh_target_reset_handler = sym53c8xx_eh_target_reset_handler ,
1664
1692
.eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler ,
1665
1693
.eh_host_reset_handler = sym53c8xx_eh_host_reset_handler ,
1666
1694
.this_id = 7 ,
0 commit comments