diff options
author | Hannes Reinecke <hare@suse.de> | 2017-06-30 19:18:08 +0200 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-08-07 14:04:00 -0400 |
commit | f799319e0746ec1cd86e35983c96e99fa0b22f07 (patch) | |
tree | 7e53402d6ec5161995a61215b028d141fa761689 /drivers/scsi/aacraid | |
parent | 25188423d4c90371a967a688c9bc511dbc5d5ae1 (diff) |
scsi: aacraid: split off device, target, and bus reset
Split off device, target, and bus reset functionality into
individual functions.
Signed-off-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/aacraid')
-rw-r--r-- | drivers/scsi/aacraid/linit.c | 141 |
1 files changed, 102 insertions, 39 deletions
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index bf21006257b3..57b207720be5 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -861,68 +861,129 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib, } /* - * aac_eh_reset - Reset command handling + * aac_eh_dev_reset - Device reset command handling * @scsi_cmd: SCSI command block causing the reset * */ -static int aac_eh_reset(struct scsi_cmnd* cmd) +static int aac_eh_dev_reset(struct scsi_cmnd *cmd) { struct scsi_device * dev = cmd->device; struct Scsi_Host * host = dev->host; struct aac_dev * aac = (struct aac_dev *)host->hostdata; int count; u32 bus, cid; + struct fib *fib; int ret = FAILED; - int status = 0; - + int status; + u8 command; bus = aac_logical_to_phys(scmd_channel(cmd)); cid = scmd_id(cmd); - if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS && - aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) { - struct fib *fib; - int status; - u8 command; + if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS || + aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW) + return FAILED; - pr_err("%s: Host adapter reset request. SCSI hang ?\n", - AAC_DRIVERNAME); + pr_err("%s: Host adapter reset request. SCSI hang ?\n", + AAC_DRIVERNAME); - fib = aac_fib_alloc(aac); - if (!fib) - return ret; + fib = aac_fib_alloc(aac); + if (!fib) + return ret; - if (aac->hba_map[bus][cid].reset_state == 0) { - /* start a HBA_TMF_LUN_RESET TMF request */ - command = aac_eh_tmf_lun_reset_fib(aac, fib, - bus, cid, - cmd->device->lun); - aac->hba_map[bus][cid].reset_state++; - } else if (aac->hba_map[bus][cid].reset_state >= 1) { - /* already tried, start a hard reset now */ - command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid); - aac->hba_map[bus][cid].reset_state = 0; + /* start a HBA_TMF_LUN_RESET TMF request */ + command = aac_eh_tmf_lun_reset_fib(aac, fib, bus, cid, + cmd->device->lun); + + cmd->SCp.sent_command = 0; + + status = aac_hba_send(command, fib, + (fib_callback) aac_hba_callback, + (void *) cmd); + + /* Wait up to 15 seconds for completion */ + for (count = 0; count < 15; ++count) { + if (cmd->SCp.sent_command) { + ret = SUCCESS; + break; } - cmd->SCp.sent_command = 0; + msleep(1000); + } - status = aac_hba_send(command, fib, - (fib_callback) aac_hba_callback, - (void *) cmd); + return ret; +} - /* Wait up to 15 seconds for completion */ - for (count = 0; count < 15; ++count) { - if (cmd->SCp.sent_command) { - ret = SUCCESS; - break; - } - msleep(1000); +/* + * aac_eh_target_reset - Target reset command handling + * @scsi_cmd: SCSI command block causing the reset + * + */ +static int aac_eh_target_reset(struct scsi_cmnd *cmd) +{ + struct scsi_device * dev = cmd->device; + struct Scsi_Host * host = dev->host; + struct aac_dev * aac = (struct aac_dev *)host->hostdata; + int count; + u32 bus, cid; + int ret = FAILED; + struct fib *fib; + int status; + u8 command; + + bus = aac_logical_to_phys(scmd_channel(cmd)); + cid = scmd_id(cmd); + if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS || + aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW) + return FAILED; + + pr_err("%s: Host adapter reset request. SCSI hang ?\n", + AAC_DRIVERNAME); + + fib = aac_fib_alloc(aac); + if (!fib) + return ret; + + + /* already tried, start a hard reset now */ + command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid); + + cmd->SCp.sent_command = 0; + + status = aac_hba_send(command, fib, + (fib_callback) aac_hba_callback, + (void *) cmd); + + /* Wait up to 15 seconds for completion */ + for (count = 0; count < 15; ++count) { + if (cmd->SCp.sent_command) { + ret = SUCCESS; + break; } + msleep(1000); + } - if (ret == SUCCESS) - return ret; + return ret; +} + +/* + * aac_eh_bus_reset - Bus reset command handling + * @scsi_cmd: SCSI command block causing the reset + * + */ +static int aac_eh_bus_reset(struct scsi_cmnd* cmd) +{ + struct scsi_device * dev = cmd->device; + struct Scsi_Host * host = dev->host; + struct aac_dev * aac = (struct aac_dev *)host->hostdata; + int count; + u32 bus, cid; + int status = 0; - } else { + bus = aac_logical_to_phys(scmd_channel(cmd)); + cid = scmd_id(cmd); + if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS || + aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW) { /* Mark the assoc. FIB to not complete, eh handler does this */ for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); @@ -1409,7 +1470,9 @@ static struct scsi_host_template aac_driver_template = { .change_queue_depth = aac_change_queue_depth, .sdev_attrs = aac_dev_attrs, .eh_abort_handler = aac_eh_abort, - .eh_bus_reset_handler = aac_eh_reset, + .eh_device_reset_handler = aac_eh_dev_reset, + .eh_target_reset_handler = aac_eh_target_reset, + .eh_bus_reset_handler = aac_eh_bus_reset, .eh_host_reset_handler = aac_eh_host_reset, .can_queue = AAC_NUM_IO_FIB, .this_id = MAXIMUM_NUM_CONTAINERS, |