mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-19 03:00:07 -05:00
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: Hannes Reinecke <hare@suse.de> Link: https://lore.kernel.org/r/20231002154328.43718-17-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:
committed by
Martin K. Petersen
parent
bffebc1993
commit
09df469722
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user