diff options
| author | Hannes Reinecke <hare@suse.de> | 2019-05-29 13:55:03 +0200 |
|---|---|---|
| committer | Hannes Reinecke <hare@suse.de> | 2021-11-08 10:35:47 +0100 |
| commit | e3dcd2298e3f61c338f266efbdccd03b0083a463 (patch) | |
| tree | 8126eeb93eff54849b64a7eff553c156ad3a9b28 | |
| parent | 62ef655cc63719b6556a5233e305edc9ffc644bc (diff) | |
| download | scsi-devel-e3dcd2298e3f61c338f266efbdccd03b0083a463.tar.gz | |
aacraid: use scsi_host_busy_iter() to traverse outstanding commands
Instead of walking the array of potential commands and trying to figure out
which one might be pending the driver should be using
scsi_host_busy_iter() to traverse all outstanding commands.
And for command abort we can now lookup the fibs directly as we now have
a 1:1 mapping between request tags and fibs.
Signed-off-by: Hannes Reinecke <hare@suse.de>
| -rw-r--r-- | drivers/scsi/aacraid/commsup.c | 51 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/linit.c | 133 |
2 files changed, 88 insertions, 96 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 9cb5b970bac40..6838093bf97d5 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1465,6 +1465,34 @@ static void aac_schedule_bus_scan(struct aac_dev *aac) aac_schedule_src_reinit_aif_worker(aac); } +static bool aac_close_sync_fib_iter(struct scsi_cmnd *command, void *data, + bool reserved) +{ + struct Scsi_Host *host = command->device->host; + struct aac_dev *aac = (struct aac_dev *)host->hostdata; + struct fib *fib = &aac->fibs[command->request->tag]; + int *retval = data; + __le32 XferState = fib->hw_fib_va->header.XferState; + bool is_response_expected = false; + + if (!fib->scmd) + return true; + if (!(XferState & cpu_to_le32(NoResponseExpected | Async)) && + (XferState & cpu_to_le32(ResponseExpected))) + is_response_expected = true; + + if (is_response_expected + || fib->flags & FIB_CONTEXT_FLAG_WAIT) { + unsigned long flagv; + spin_lock_irqsave(&fib->event_lock, flagv); + complete(&fib->event_wait); + spin_unlock_irqrestore(&fib->event_lock, flagv); + schedule(); + *retval = 0; + } + return true; +} + static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) { int index, quirks; @@ -1473,7 +1501,6 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) int jafo = 0; int bled; u64 dmamask; - int num_of_fibs = 0; /* * Assumptions: @@ -1507,27 +1534,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) * Loop through the fibs, close the synchronous FIBS */ retval = 1; - num_of_fibs = aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB; - for (index = 0; index < num_of_fibs; index++) { - - struct fib *fib = &aac->fibs[index]; - __le32 XferState = fib->hw_fib_va->header.XferState; - bool is_response_expected = false; - - if (!(XferState & cpu_to_le32(NoResponseExpected | Async)) && - (XferState & cpu_to_le32(ResponseExpected))) - is_response_expected = true; - - if (is_response_expected - || fib->flags & FIB_CONTEXT_FLAG_WAIT) { - unsigned long flagv; - spin_lock_irqsave(&fib->event_lock, flagv); - complete(&fib->event_wait); - spin_unlock_irqrestore(&fib->event_lock, flagv); - schedule(); - retval = 0; - } - } + scsi_host_busy_iter(host, aac_close_sync_fib_iter, &retval); /* Give some extra time for ioctls to complete. */ if (retval == 0) ssleep(2); diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 9e75aedcb6d44..e6d5349147c55 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -687,7 +687,8 @@ static int aac_eh_abort(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, found; + struct fib *fib; + int count; u32 bus, cid; int ret = FAILED; @@ -697,26 +698,20 @@ static int aac_eh_abort(struct scsi_cmnd* cmd) bus = aac_logical_to_phys(scmd_channel(cmd)); cid = scmd_id(cmd); if (aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) { - struct fib *fib; struct aac_hba_tm_req *tmf; int status; u64 address; pr_err("%s: Host adapter abort request (%d,%d,%d,%d)\n", - AAC_DRIVERNAME, - host->host_no, sdev_channel(dev), sdev_id(dev), (int)dev->lun); - - found = 0; - for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { - fib = &aac->fibs[count]; - if (*(u8 *)fib->hw_fib_va != 0 && - (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) && - (fib->callback_data == cmd)) { - found = 1; - break; - } - } - if (!found) + AAC_DRIVERNAME, host->host_no, + sdev_channel(dev), sdev_id(dev), (int)dev->lun); + + fib = &aac->fibs[cmd->request->tag]; + if (*(u8 *)fib->hw_fib_va != 0 && + (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) && + (fib->callback_data == cmd)) + ret = SUCCESS; + if (ret == FAILED) return ret; /* start a HBA_TMF_ABORT_TASK TMF request */ @@ -778,20 +773,13 @@ static int aac_eh_abort(struct scsi_cmnd* cmd) * Mark associated FIB to not complete, * eh handler does this */ - for (count = 0; - count < (host->can_queue + AAC_NUM_MGT_FIB); - ++count) { - struct fib *fib = &aac->fibs[count]; - - if (fib->hw_fib_va->header.XferState && - (fib->flags & FIB_CONTEXT_FLAG) && - (fib->callback_data == cmd)) { - fib->flags |= - FIB_CONTEXT_FLAG_TIMED_OUT; - fib->owner = - AAC_OWNER_ERROR_HANDLER; - ret = SUCCESS; - } + fib = &aac->fibs[cmd->request->tag]; + if (fib->hw_fib_va->header.XferState && + (fib->flags & FIB_CONTEXT_FLAG) && + (fib->callback_data == cmd)) { + fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; + fib->owner = AAC_OWNER_ERROR_HANDLER; + ret = SUCCESS; } break; case TEST_UNIT_READY: @@ -799,27 +787,14 @@ static int aac_eh_abort(struct scsi_cmnd* cmd) * Mark associated FIB to not complete, * eh handler does this */ - for (count = 0; - count < (host->can_queue + AAC_NUM_MGT_FIB); - ++count) { - struct scsi_cmnd *command; - struct fib *fib = &aac->fibs[count]; - - command = fib->callback_data; - - if ((fib->hw_fib_va->header.XferState & - cpu_to_le32 - (Async | NoResponseExpected)) && - (fib->flags & FIB_CONTEXT_FLAG) && - ((command)) && - (command->device == cmd->device)) { - fib->flags |= - FIB_CONTEXT_FLAG_TIMED_OUT; - fib->owner = - AAC_OWNER_ERROR_HANDLER; - if (command == cmd) - ret = SUCCESS; - } + fib = &aac->fibs[cmd->request->tag]; + if ((fib->hw_fib_va->header.XferState & + cpu_to_le32(Async | NoResponseExpected)) && + (fib->flags & FIB_CONTEXT_FLAG) && + (fib->callback_data == cmd)) { + fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; + fib->owner = AAC_OWNER_ERROR_HANDLER; + ret = SUCCESS; } break; } @@ -1027,6 +1002,38 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd) return ret; } +static bool aac_eh_bus_reset_iter(struct scsi_cmnd *cmd, void *data, + bool reserved) +{ + struct Scsi_Host *host = cmd->device->host; + struct aac_dev *aac = (struct aac_dev *)host->hostdata; + struct fib *fib = &aac->fibs[cmd->request->tag]; + int *cmd_bus = data; + + if (!fib->scmd) + return true; + if (fib->hw_fib_va->header.XferState && + (fib->flags & FIB_CONTEXT_FLAG) && + (fib->flags & FIB_CONTEXT_FLAG_SCSI_CMD)) { + struct aac_hba_map_info *info; + u32 bus, cid; + + if (cmd != (struct scsi_cmnd *)fib->callback_data) + return true; + bus = aac_logical_to_phys(scmd_channel(cmd)); + if (bus != *cmd_bus) + return true; + cid = scmd_id(cmd); + info = &aac->hba_map[bus][cid]; + if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS || + info->devtype != AAC_DEVTYPE_NATIVE_RAW) { + fib->flags |= FIB_CONTEXT_FLAG_EH_RESET; + cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; + } + } + return true; +} + /* * aac_eh_bus_reset - Bus reset command handling * @scsi_cmd: SCSI command block causing the reset @@ -1044,29 +1051,7 @@ static int aac_eh_bus_reset(struct scsi_cmnd* cmd) cmd_bus = aac_logical_to_phys(scmd_channel(cmd)); /* Mark the assoc. FIB to not complete, eh handler does this */ - for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { - struct fib *fib = &aac->fibs[count]; - - if (fib->hw_fib_va->header.XferState && - (fib->flags & FIB_CONTEXT_FLAG) && - (fib->flags & FIB_CONTEXT_FLAG_SCSI_CMD)) { - struct aac_hba_map_info *info; - u32 bus, cid; - - cmd = (struct scsi_cmnd *)fib->callback_data; - bus = aac_logical_to_phys(scmd_channel(cmd)); - if (bus != cmd_bus) - continue; - cid = scmd_id(cmd); - info = &aac->hba_map[bus][cid]; - if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS || - info->devtype != AAC_DEVTYPE_NATIVE_RAW) { - fib->flags |= FIB_CONTEXT_FLAG_EH_RESET; - fib->owner = AAC_OWNER_ERROR_HANDLER; - } - } - } - + scsi_host_busy_iter(host, aac_eh_bus_reset_iter, &cmd_bus); pr_err("%s: Host bus reset request. SCSI hang ?\n", AAC_DRIVERNAME); /* |
