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@xxxxxxx> --- drivers/scsi/aacraid/linit.c | 137 ++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 75 deletions(-) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 91a4780d9815..e3f8eac6cebe 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -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])); -- 2.16.4