Skip to content

Commit 09df469

Browse files
hreineckemartinkpetersen
authored andcommitted
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 <[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 bffebc1 commit 09df469

File tree

1 file changed

+38
-8
lines changed

1 file changed

+38
-8
lines changed

drivers/scsi/pmcraid.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2691,7 +2691,7 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd)
26912691
* SUCCESS / FAILED
26922692
*/
26932693
static int pmcraid_reset_device(
2694-
struct scsi_cmnd *scsi_cmd,
2694+
struct scsi_device *scsi_dev,
26952695
unsigned long timeout,
26962696
u8 modifier)
26972697
{
@@ -2703,11 +2703,11 @@ static int pmcraid_reset_device(
27032703
u32 ioasc;
27042704

27052705
pinstance =
2706-
(struct pmcraid_instance *)scsi_cmd->device->host->hostdata;
2707-
res = scsi_cmd->device->hostdata;
2706+
(struct pmcraid_instance *)scsi_dev->host->hostdata;
2707+
res = scsi_dev->hostdata;
27082708

27092709
if (!res) {
2710-
sdev_printk(KERN_ERR, scsi_cmd->device,
2710+
sdev_printk(KERN_ERR, scsi_dev,
27112711
"reset_device: NULL resource pointer\n");
27122712
return FAILED;
27132713
}
@@ -3018,16 +3018,46 @@ static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd)
30183018
{
30193019
scmd_printk(KERN_INFO, scmd,
30203020
"resetting device due to an I/O command timeout.\n");
3021-
return pmcraid_reset_device(scmd,
3021+
return pmcraid_reset_device(scmd->device,
30223022
PMCRAID_INTERNAL_TIMEOUT,
30233023
RESET_DEVICE_LUN);
30243024
}
30253025

30263026
static int pmcraid_eh_bus_reset_handler(struct scsi_cmnd *scmd)
30273027
{
3028-
scmd_printk(KERN_INFO, scmd,
3028+
struct Scsi_Host *host = scmd->device->host;
3029+
struct pmcraid_instance *pinstance =
3030+
(struct pmcraid_instance *)host->hostdata;
3031+
struct pmcraid_resource_entry *res = NULL;
3032+
struct pmcraid_resource_entry *temp;
3033+
struct scsi_device *sdev = NULL;
3034+
unsigned long lock_flags;
3035+
3036+
/*
3037+
* The reset device code insists on us passing down
3038+
* a device, so grab the first device on the bus.
3039+
*/
3040+
spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
3041+
list_for_each_entry(temp, &pinstance->used_res_q, queue) {
3042+
if (scmd->device->channel == PMCRAID_VSET_BUS_ID &&
3043+
RES_IS_VSET(temp->cfg_entry)) {
3044+
res = temp;
3045+
break;
3046+
} else if (scmd->device->channel == PMCRAID_PHYS_BUS_ID &&
3047+
RES_IS_GSCSI(temp->cfg_entry)) {
3048+
res = temp;
3049+
break;
3050+
}
3051+
}
3052+
if (res)
3053+
sdev = res->scsi_dev;
3054+
spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
3055+
if (!sdev)
3056+
return FAILED;
3057+
3058+
sdev_printk(KERN_INFO, sdev,
30293059
"Doing bus reset due to an I/O command timeout.\n");
3030-
return pmcraid_reset_device(scmd,
3060+
return pmcraid_reset_device(sdev,
30313061
PMCRAID_RESET_BUS_TIMEOUT,
30323062
RESET_DEVICE_BUS);
30333063
}
@@ -3036,7 +3066,7 @@ static int pmcraid_eh_target_reset_handler(struct scsi_cmnd *scmd)
30363066
{
30373067
scmd_printk(KERN_INFO, scmd,
30383068
"Doing target reset due to an I/O command timeout.\n");
3039-
return pmcraid_reset_device(scmd,
3069+
return pmcraid_reset_device(scmd->device,
30403070
PMCRAID_INTERNAL_TIMEOUT,
30413071
RESET_DEVICE_TARGET);
30423072
}

0 commit comments

Comments
 (0)