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

scsi: aacraid: split off device, target, and bus reset

Split off device, target, and bus reset functionality into
individual functions.
Signed-off-by: default avatarHannes Reinecke <hare@suse.com>
Reviewed-by: default avatarRaghava Aditya Renukunta  <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 25188423
...@@ -861,68 +861,129 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib, ...@@ -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 * @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_device * dev = cmd->device;
struct Scsi_Host * host = dev->host; struct Scsi_Host * host = dev->host;
struct aac_dev * aac = (struct aac_dev *)host->hostdata; struct aac_dev * aac = (struct aac_dev *)host->hostdata;
int count; int count;
u32 bus, cid; u32 bus, cid;
struct fib *fib;
int ret = FAILED; int ret = FAILED;
int status = 0; int status;
u8 command;
bus = aac_logical_to_phys(scmd_channel(cmd)); bus = aac_logical_to_phys(scmd_channel(cmd));
cid = scmd_id(cmd); cid = scmd_id(cmd);
if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS && if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) { aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
struct fib *fib; return FAILED;
int status;
u8 command;
pr_err("%s: Host adapter reset request. SCSI hang ?\n", pr_err("%s: Host adapter reset request. SCSI hang ?\n",
AAC_DRIVERNAME); AAC_DRIVERNAME);
fib = aac_fib_alloc(aac); fib = aac_fib_alloc(aac);
if (!fib) if (!fib)
return ret; return ret;
if (aac->hba_map[bus][cid].reset_state == 0) { /* start a HBA_TMF_LUN_RESET TMF request */
/* start a HBA_TMF_LUN_RESET TMF request */ command = aac_eh_tmf_lun_reset_fib(aac, fib, bus, cid,
command = aac_eh_tmf_lun_reset_fib(aac, fib, cmd->device->lun);
bus, cid,
cmd->device->lun); cmd->SCp.sent_command = 0;
aac->hba_map[bus][cid].reset_state++;
} else if (aac->hba_map[bus][cid].reset_state >= 1) { status = aac_hba_send(command, fib,
/* already tried, start a hard reset now */ (fib_callback) aac_hba_callback,
command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid); (void *) cmd);
aac->hba_map[bus][cid].reset_state = 0;
/* 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, return ret;
(fib_callback) aac_hba_callback, }
(void *) cmd);
/* Wait up to 15 seconds for completion */ /*
for (count = 0; count < 15; ++count) { * aac_eh_target_reset - Target reset command handling
if (cmd->SCp.sent_command) { * @scsi_cmd: SCSI command block causing the reset
ret = SUCCESS; *
break; */
} static int aac_eh_target_reset(struct scsi_cmnd *cmd)
msleep(1000); {
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 */ /* Mark the assoc. FIB to not complete, eh handler does this */
for (count = 0; for (count = 0;
count < (host->can_queue + AAC_NUM_MGT_FIB); count < (host->can_queue + AAC_NUM_MGT_FIB);
...@@ -1409,7 +1470,9 @@ static struct scsi_host_template aac_driver_template = { ...@@ -1409,7 +1470,9 @@ static struct scsi_host_template aac_driver_template = {
.change_queue_depth = aac_change_queue_depth, .change_queue_depth = aac_change_queue_depth,
.sdev_attrs = aac_dev_attrs, .sdev_attrs = aac_dev_attrs,
.eh_abort_handler = aac_eh_abort, .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, .eh_host_reset_handler = aac_eh_host_reset,
.can_queue = AAC_NUM_IO_FIB, .can_queue = AAC_NUM_IO_FIB,
.this_id = MAXIMUM_NUM_CONTAINERS, .this_id = MAXIMUM_NUM_CONTAINERS,
......
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