@@ -564,7 +564,10 @@ static void sym53c8xx_timer(struct timer_list *t)
564564 * Generic method for our eh processing.
565565 * The 'op' argument tells what we have to do.
566566 */
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 )
568571{
569572 struct sym_ucmd * ucmd = SYM_UCMD_PTR (cmd );
570573 struct Scsi_Host * shost = cmd -> device -> host ;
@@ -576,7 +579,7 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
576579 int sts = -1 ;
577580 struct completion eh_done ;
578581
579- scmd_printk (KERN_WARNING , cmd , "%s operation started\n" , opname );
582+ scmd_printk (KERN_WARNING , cmd , "ABORT operation started\n" );
580583
581584 /*
582585 * 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)
594597 }
595598 }
596599
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 );
610601 /* On error, restore everything and cross fingers :) */
611602 if (sts )
612603 cmd_queued = 0 ;
@@ -623,23 +614,60 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
623614 spin_unlock_irq (shost -> host_lock );
624615 }
625616
626- dev_warn (& cmd -> device -> sdev_gendev , "%s operation %s.\n" , opname ,
617+ dev_warn (& cmd -> device -> sdev_gendev , "ABORT operation %s.\n" ,
627618 sts == 0 ? "complete" :sts == -2 ? "timed-out" : "failed" );
628619 return sts ? SCSI_FAILED : SCSI_SUCCESS ;
629620}
630621
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 )
636623{
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 ;
639632
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 ;
643671}
644672
645673static int sym53c8xx_eh_bus_reset_handler (struct scsi_cmnd * cmd )
@@ -1660,7 +1688,7 @@ static const struct scsi_host_template sym2_template = {
16601688 .slave_configure = sym53c8xx_slave_configure ,
16611689 .slave_destroy = sym53c8xx_slave_destroy ,
16621690 .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 ,
16641692 .eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler ,
16651693 .eh_host_reset_handler = sym53c8xx_eh_host_reset_handler ,
16661694 .this_id = 7 ,
0 commit comments