Commit 09df4697 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Martin K. Petersen

scsi: pmcraid: Select device in pmcraid_eh_bus_reset_handler()

The reset code requires a device to be selected, but we shouldn't rely on
the command to provide a device for us. So select the first device on the
bus when sending down a bus reset.
Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
Link: https://lore.kernel.org/r/20231002154328.43718-17-hare@suse.deReviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent bffebc19
......@@ -2691,7 +2691,7 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd)
* SUCCESS / FAILED
*/
static int pmcraid_reset_device(
struct scsi_cmnd *scsi_cmd,
struct scsi_device *scsi_dev,
unsigned long timeout,
u8 modifier)
{
......@@ -2703,11 +2703,11 @@ static int pmcraid_reset_device(
u32 ioasc;
pinstance =
(struct pmcraid_instance *)scsi_cmd->device->host->hostdata;
res = scsi_cmd->device->hostdata;
(struct pmcraid_instance *)scsi_dev->host->hostdata;
res = scsi_dev->hostdata;
if (!res) {
sdev_printk(KERN_ERR, scsi_cmd->device,
sdev_printk(KERN_ERR, scsi_dev,
"reset_device: NULL resource pointer\n");
return FAILED;
}
......@@ -3018,16 +3018,46 @@ static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd)
{
scmd_printk(KERN_INFO, scmd,
"resetting device due to an I/O command timeout.\n");
return pmcraid_reset_device(scmd,
return pmcraid_reset_device(scmd->device,
PMCRAID_INTERNAL_TIMEOUT,
RESET_DEVICE_LUN);
}
static int pmcraid_eh_bus_reset_handler(struct scsi_cmnd *scmd)
{
scmd_printk(KERN_INFO, scmd,
struct Scsi_Host *host = scmd->device->host;
struct pmcraid_instance *pinstance =
(struct pmcraid_instance *)host->hostdata;
struct pmcraid_resource_entry *res = NULL;
struct pmcraid_resource_entry *temp;
struct scsi_device *sdev = NULL;
unsigned long lock_flags;
/*
* The reset device code insists on us passing down
* a device, so grab the first device on the bus.
*/
spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
list_for_each_entry(temp, &pinstance->used_res_q, queue) {
if (scmd->device->channel == PMCRAID_VSET_BUS_ID &&
RES_IS_VSET(temp->cfg_entry)) {
res = temp;
break;
} else if (scmd->device->channel == PMCRAID_PHYS_BUS_ID &&
RES_IS_GSCSI(temp->cfg_entry)) {
res = temp;
break;
}
}
if (res)
sdev = res->scsi_dev;
spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
if (!sdev)
return FAILED;
sdev_printk(KERN_INFO, sdev,
"Doing bus reset due to an I/O command timeout.\n");
return pmcraid_reset_device(scmd,
return pmcraid_reset_device(sdev,
PMCRAID_RESET_BUS_TIMEOUT,
RESET_DEVICE_BUS);
}
......@@ -3036,7 +3066,7 @@ static int pmcraid_eh_target_reset_handler(struct scsi_cmnd *scmd)
{
scmd_printk(KERN_INFO, scmd,
"Doing target reset due to an I/O command timeout.\n");
return pmcraid_reset_device(scmd,
return pmcraid_reset_device(scmd->device,
PMCRAID_INTERNAL_TIMEOUT,
RESET_DEVICE_TARGET);
}
......
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