@@ -680,7 +680,7 @@ 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;
+ int count;
u32 bus, cid;
int ret = FAILED;
@@ -699,17 +699,13 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
AAC_DRIVERNAME,
host->host_no, sdev_channel(dev), sdev_id(dev), (int)dev->lun);
- found = 0;
- for (count = 0; count < host->can_queue; ++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)
+ if (cmd->request->tag >= host->can_queue)
+ return ret;
+
+ fib = &aac->fibs[cmd->request->tag];
+ if (*(u8 *)fib->hw_fib_va == 0 ||
+ !(fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) ||
+ (fib->callback_data != cmd))
return ret;
/* start a HBA_TMF_ABORT_TASK TMF request */
@@ -767,12 +763,13 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
/* fall through */
case INQUIRY:
case READ_CAPACITY:
+ case TEST_UNIT_READY:
/*
* Mark associated FIB to not complete,
* eh handler does this
*/
- for (count = 0; count < host->can_queue; ++count) {
- struct fib *fib = &aac->fibs[count];
+ if (cmd->request->tag < host->can_queue) {
+ struct fib *fib = &aac->fibs[cmd->request->tag];
if (fib->hw_fib_va->header.XferState &&
(fib->flags & FIB_CONTEXT_FLAG) &&
@@ -785,32 +782,6 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
}
}
break;
- case TEST_UNIT_READY:
- /*
- * Mark associated FIB to not complete,
- * eh handler does this
- */
- for (count = 0; count < host->can_queue; ++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;
- command->SCp.phase =
- AAC_OWNER_ERROR_HANDLER;
- if (command == cmd)
- ret = SUCCESS;
- }
- }
- break;
}
}
return ret;
@@ -1016,6 +987,36 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
return ret;
}
+struct aac_abort_fibs_iter_data {
+ struct aac_dev *aac;
+ u32 bus;
+};
+
+static bool aac_abort_fibs_iter(struct scsi_cmnd *scmd, void *data, bool rsvd)
+{
+ struct aac_abort_fibs_iter_data *iter_data = data;
+ struct aac_dev *aac = iter_data->aac;
+ struct fib *fib = &aac->fibs[scmd->request->tag];
+
+ 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;
+
+ bus = aac_logical_to_phys(scmd_channel(scmd));
+ if (bus != iter_data->bus)
+ return true;
+ cid = scmd_id(scmd);
+ 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;
+ scmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
+ }
+ }
+ return true;
+}
/*
* aac_eh_bus_reset - Bus reset command handling
* @scsi_cmd: SCSI command block causing the reset
@@ -1027,34 +1028,13 @@ static int aac_eh_bus_reset(struct scsi_cmnd* cmd)
struct Scsi_Host * host = dev->host;
struct aac_dev * aac = (struct aac_dev *)host->hostdata;
int count;
- u32 cmd_bus;
int status = 0;
+ struct aac_abort_fibs_iter_data data = {
+ .aac = aac,
+ .bus = aac_logical_to_phys(scmd_channel(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; ++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;
- cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
- }
- }
- }
+ scsi_host_busy_iter(host, aac_abort_fibs_iter, &data);
pr_err("%s: Host bus reset request. SCSI hang ?\n", AAC_DRIVERNAME);
@@ -1558,23 +1538,28 @@ static struct scsi_host_template aac_driver_template = {
.no_write_same = 1,
};
-static void __aac_shutdown(struct aac_dev * aac)
+static bool __aac_shutdown_iter(struct scsi_cmnd *scmd, void *data, bool rsvd)
{
- int i;
+ struct aac_dev *aac = data;
+ struct fib *fib = &aac->fibs[scmd->request->tag];
+
+ if (!(fib->hw_fib_va->header.XferState &
+ cpu_to_le32(NoResponseExpected | Async)) &&
+ (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected)))
+ complete(&fib->event_wait);
+ return true;
+}
+static void __aac_shutdown(struct aac_dev * aac)
+{
mutex_lock(&aac->ioctl_mutex);
aac->adapter_shutdown = 1;
mutex_unlock(&aac->ioctl_mutex);
if (aac->aif_thread) {
- int i;
/* Clear out events first */
- for (i = 0; i < aac->scsi_host_ptr->can_queue; i++) {
- struct fib *fib = &aac->fibs[i];
- if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) &&
- (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected)))
- complete(&fib->event_wait);
- }
+ scsi_host_busy_iter(aac->scsi_host_ptr,
+ __aac_shutdown_iter, aac);
kthread_stop(aac->thread);
aac->thread = NULL;
}
@@ -1585,6 +1570,8 @@ static void __aac_shutdown(struct aac_dev * aac)
if (aac_is_src(aac)) {
if (aac->max_msix > 1) {
+ int i;
+
for (i = 0; i < aac->max_msix; i++) {
free_irq(pci_irq_vector(aac->pdev, i),
&(aac->aac_msix[i]));
Now that the block layer manages all commands we can use scsi_host_busy_iter() to traverse outstanding commands. Signed-off-by: Hannes Reinecke <hare@suse.de> --- drivers/scsi/aacraid/linit.c | 137 ++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 75 deletions(-)