Skip to content

Commit c7c559d

Browse files
hreineckemartinkpetersen
authored andcommitted
scsi: sym53c8xx_2: Rework reset handling
Split off the combined abort and device reset handling into distinct functions. And rename the current device reset handler into a target reset handler, seeing that it really is a target reset. Signed-off-by: Hannes Reinecke <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 4980ae1 commit c7c559d

File tree

1 file changed

+55
-27
lines changed

1 file changed

+55
-27
lines changed

drivers/scsi/sym53c8xx_2/sym_glue.c

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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

645673
static 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

Comments
 (0)