mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
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 <hare@suse.de> Link: https://lore.kernel.org/r/20231002154328.43718-15-hare@suse.de Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
4980ae18c3
commit
c7c559d2b3
@ -564,7 +564,10 @@ static void sym53c8xx_timer(struct timer_list *t)
|
||||
* Generic method for our eh processing.
|
||||
* The 'op' argument tells what we have to do.
|
||||
*/
|
||||
static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
|
||||
/*
|
||||
* Error handlers called from the eh thread (one thread per HBA).
|
||||
*/
|
||||
static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd)
|
||||
{
|
||||
struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd);
|
||||
struct Scsi_Host *shost = cmd->device->host;
|
||||
@ -576,7 +579,7 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
|
||||
int sts = -1;
|
||||
struct completion eh_done;
|
||||
|
||||
scmd_printk(KERN_WARNING, cmd, "%s operation started\n", opname);
|
||||
scmd_printk(KERN_WARNING, cmd, "ABORT operation started\n");
|
||||
|
||||
/*
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to proceed the operation we have been asked for */
|
||||
sts = -1;
|
||||
switch(op) {
|
||||
case SYM_EH_ABORT:
|
||||
sts = sym_abort_scsiio(np, cmd, 1);
|
||||
break;
|
||||
case SYM_EH_DEVICE_RESET:
|
||||
sts = sym_reset_scsi_target(np, cmd->device->id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
sts = sym_abort_scsiio(np, cmd, 1);
|
||||
/* On error, restore everything and cross fingers :) */
|
||||
if (sts)
|
||||
cmd_queued = 0;
|
||||
@ -623,23 +614,60 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
|
||||
dev_warn(&cmd->device->sdev_gendev, "%s operation %s.\n", opname,
|
||||
dev_warn(&cmd->device->sdev_gendev, "ABORT operation %s.\n",
|
||||
sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed");
|
||||
return sts ? SCSI_FAILED : SCSI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Error handlers called from the eh thread (one thread per HBA).
|
||||
*/
|
||||
static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd)
|
||||
static int sym53c8xx_eh_target_reset_handler(struct scsi_cmnd *cmd)
|
||||
{
|
||||
return sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd);
|
||||
}
|
||||
struct scsi_target *starget = scsi_target(cmd->device);
|
||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||
struct sym_data *sym_data = shost_priv(shost);
|
||||
struct pci_dev *pdev = sym_data->pdev;
|
||||
struct sym_hcb *np = sym_data->ncb;
|
||||
SYM_QUEHEAD *qp;
|
||||
int sts;
|
||||
struct completion eh_done;
|
||||
|
||||
static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd)
|
||||
{
|
||||
return sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd);
|
||||
starget_printk(KERN_WARNING, starget,
|
||||
"TARGET RESET operation started\n");
|
||||
|
||||
/*
|
||||
* Escalate to host reset if the PCI bus went down
|
||||
*/
|
||||
if (pci_channel_offline(pdev))
|
||||
return SCSI_FAILED;
|
||||
|
||||
spin_lock_irq(shost->host_lock);
|
||||
sts = sym_reset_scsi_target(np, starget->id);
|
||||
if (!sts) {
|
||||
FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
|
||||
struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb,
|
||||
link_ccbq);
|
||||
struct scsi_cmnd *cmd = cp->cmd;
|
||||
struct sym_ucmd *ucmd;
|
||||
|
||||
if (!cmd || cmd->device->channel != starget->channel ||
|
||||
cmd->device->id != starget->id)
|
||||
continue;
|
||||
|
||||
ucmd = SYM_UCMD_PTR(cmd);
|
||||
init_completion(&eh_done);
|
||||
ucmd->eh_done = &eh_done;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
if (!wait_for_completion_timeout(&eh_done, 5*HZ)) {
|
||||
ucmd->eh_done = NULL;
|
||||
sts = -2;
|
||||
}
|
||||
spin_lock_irq(shost->host_lock);
|
||||
}
|
||||
}
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
starget_printk(KERN_WARNING, starget, "TARGET RESET operation %s.\n",
|
||||
sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed");
|
||||
return SCSI_SUCCESS;
|
||||
}
|
||||
|
||||
static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)
|
||||
@ -1660,7 +1688,7 @@ static const struct scsi_host_template sym2_template = {
|
||||
.slave_configure = sym53c8xx_slave_configure,
|
||||
.slave_destroy = sym53c8xx_slave_destroy,
|
||||
.eh_abort_handler = sym53c8xx_eh_abort_handler,
|
||||
.eh_device_reset_handler = sym53c8xx_eh_device_reset_handler,
|
||||
.eh_target_reset_handler = sym53c8xx_eh_target_reset_handler,
|
||||
.eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler,
|
||||
.eh_host_reset_handler = sym53c8xx_eh_host_reset_handler,
|
||||
.this_id = 7,
|
||||
|
Loading…
Reference in New Issue
Block a user