Commit 4980ae18 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Martin K. Petersen

scsi: sym53c8xx_2: Split off bus reset from host reset

The current handler does both, bus reset and host reset.  So split them off
into two distinct functions.
Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
Link: https://lore.kernel.org/r/20231002154328.43718-14-hare@suse.de
Cc: Matthew Wilcox <willy@infradead.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent c8102e42
......@@ -559,8 +559,6 @@ static void sym53c8xx_timer(struct timer_list *t)
*/
#define SYM_EH_ABORT 0
#define SYM_EH_DEVICE_RESET 1
#define SYM_EH_BUS_RESET 2
#define SYM_EH_HOST_RESET 3
/*
* Generic method for our eh processing.
......@@ -580,35 +578,11 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
scmd_printk(KERN_WARNING, cmd, "%s operation started\n", opname);
/* We may be in an error condition because the PCI bus
* went down. In this case, we need to wait until the
* PCI bus is reset, the card is reset, and only then
* proceed with the scsi error recovery. There's no
* point in hurrying; take a leisurely wait.
/*
* Escalate to host reset if the PCI bus went down
*/
#define WAIT_FOR_PCI_RECOVERY 35
if (pci_channel_offline(pdev)) {
int finished_reset = 0;
init_completion(&eh_done);
spin_lock_irq(shost->host_lock);
/* Make sure we didn't race */
if (pci_channel_offline(pdev)) {
BUG_ON(sym_data->io_reset);
sym_data->io_reset = &eh_done;
} else {
finished_reset = 1;
}
spin_unlock_irq(shost->host_lock);
if (!finished_reset)
finished_reset = wait_for_completion_timeout
(sym_data->io_reset,
WAIT_FOR_PCI_RECOVERY*HZ);
spin_lock_irq(shost->host_lock);
sym_data->io_reset = NULL;
spin_unlock_irq(shost->host_lock);
if (!finished_reset)
return SCSI_FAILED;
}
if (pci_channel_offline(pdev))
return SCSI_FAILED;
spin_lock_irq(shost->host_lock);
/* This one is queued in some place -> to wait for completion */
......@@ -629,15 +603,6 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
case SYM_EH_DEVICE_RESET:
sts = sym_reset_scsi_target(np, cmd->device->id);
break;
case SYM_EH_BUS_RESET:
sym_reset_scsi_bus(np, 1);
sts = 0;
break;
case SYM_EH_HOST_RESET:
sym_reset_scsi_bus(np, 0);
sym_start_up(shost, 1);
sts = 0;
break;
default:
break;
}
......@@ -679,12 +644,72 @@ static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd)
static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)
{
return sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd);
struct Scsi_Host *shost = cmd->device->host;
struct sym_data *sym_data = shost_priv(shost);
struct pci_dev *pdev = sym_data->pdev;
struct sym_hcb *np = sym_data->ncb;
scmd_printk(KERN_WARNING, cmd, "BUS 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);
sym_reset_scsi_bus(np, 1);
spin_unlock_irq(shost->host_lock);
dev_warn(&cmd->device->sdev_gendev, "BUS RESET operation complete.\n");
return SCSI_SUCCESS;
}
static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd)
{
return sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd);
struct Scsi_Host *shost = cmd->device->host;
struct sym_data *sym_data = shost_priv(shost);
struct pci_dev *pdev = sym_data->pdev;
struct sym_hcb *np = sym_data->ncb;
struct completion eh_done;
int finished_reset = 1;
shost_printk(KERN_WARNING, shost, "HOST RESET operation started\n");
/* We may be in an error condition because the PCI bus
* went down. In this case, we need to wait until the
* PCI bus is reset, the card is reset, and only then
* proceed with the scsi error recovery. There's no
* point in hurrying; take a leisurely wait.
*/
#define WAIT_FOR_PCI_RECOVERY 35
if (pci_channel_offline(pdev)) {
init_completion(&eh_done);
spin_lock_irq(shost->host_lock);
/* Make sure we didn't race */
if (pci_channel_offline(pdev)) {
BUG_ON(sym_data->io_reset);
sym_data->io_reset = &eh_done;
finished_reset = 0;
}
spin_unlock_irq(shost->host_lock);
if (!finished_reset)
finished_reset = wait_for_completion_timeout
(sym_data->io_reset,
WAIT_FOR_PCI_RECOVERY*HZ);
spin_lock_irq(shost->host_lock);
sym_data->io_reset = NULL;
spin_unlock_irq(shost->host_lock);
}
if (finished_reset) {
sym_reset_scsi_bus(np, 0);
sym_start_up(shost, 1);
}
shost_printk(KERN_WARNING, shost, "HOST RESET operation %s.\n",
finished_reset==1 ? "complete" : "failed");
return finished_reset ? SCSI_SUCCESS : SCSI_FAILED;
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment