@@ -714,6 +714,9 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
struct aac_hba_cmd_req *hbacmd = (struct aac_hba_cmd_req *)
fibptr->hw_fib_va;
+ if (command != HBA_IU_TYPE_SCSI_CMD_REQ)
+ return -EINVAL;
+
fibptr->flags = (FIB_CONTEXT_FLAG | FIB_CONTEXT_FLAG_NATIVE_HBA);
if (callback) {
wait = 0;
@@ -725,13 +728,10 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
hbacmd->iu_type = command;
- if (command == HBA_IU_TYPE_SCSI_CMD_REQ) {
/* bit1 of request_id must be 0 */
- hbacmd->request_id =
- cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1);
- fibptr->flags |= FIB_CONTEXT_FLAG_SCSI_CMD;
- } else
- return -EINVAL;
+ hbacmd->request_id =
+ cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1);
+ fibptr->flags |= FIB_CONTEXT_FLAG_SCSI_CMD;
if (wait) {
@@ -681,7 +681,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;
@@ -690,334 +690,73 @@ 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)
- return ret;
-
- /* start a HBA_TMF_ABORT_TASK TMF request */
- fib = aac_fib_alloc(aac);
- if (!fib)
- return ret;
-
- tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
- memset(tmf, 0, sizeof(*tmf));
- tmf->tmf = HBA_TMF_ABORT_TASK;
- tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
- tmf->lun[1] = cmd->device->lun;
-
- address = (u64)fib->hw_error_pa;
- tmf->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
- tmf->error_ptr_lo = cpu_to_le32((u32)(address & 0xffffffff));
- tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
-
- fib->hbacmd_size = sizeof(*tmf);
- cmd->SCp.sent_command = 0;
-
- status = aac_hba_send(HBA_IU_TYPE_SCSI_TM_REQ, fib,
- (fib_callback) aac_hba_callback,
- (void *) cmd);
- if (status != -EINPROGRESS) {
- aac_fib_complete(fib);
- aac_fib_free(fib);
- return ret;
- }
- /* Wait up to 15 secs for completion */
- for (count = 0; count < 15; ++count) {
- if (cmd->SCp.sent_command) {
+ if (aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW)
+ return ret;
+
+ pr_err(
+ "%s: Host adapter abort request.\n"
+ "%s: Outstanding commands on (%d,%d,%d,%d):\n",
+ AAC_DRIVERNAME, AAC_DRIVERNAME,
+ host->host_no, sdev_channel(dev), sdev_id(dev),
+ (int)dev->lun);
+ switch (cmd->cmnd[0]) {
+ case SERVICE_ACTION_IN_16:
+ if (!(aac->raw_io_interface) ||
+ !(aac->raw_io_64) ||
+ ((cmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
+ break;
+ fallthrough;
+ case INQUIRY:
+ case READ_CAPACITY:
+ /*
+ * 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;
+ cmd->SCp.phase =
+ AAC_OWNER_ERROR_HANDLER;
ret = SUCCESS;
- break;
}
- msleep(1000);
}
+ break;
+ case TEST_UNIT_READY:
+ /*
+ * 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];
- if (ret != SUCCESS)
- pr_err("%s: Host adapter abort request timed out\n",
- AAC_DRIVERNAME);
- } else {
- pr_err(
- "%s: Host adapter abort request.\n"
- "%s: Outstanding commands on (%d,%d,%d,%d):\n",
- AAC_DRIVERNAME, AAC_DRIVERNAME,
- host->host_no, sdev_channel(dev), sdev_id(dev),
- (int)dev->lun);
- switch (cmd->cmnd[0]) {
- case SERVICE_ACTION_IN_16:
- if (!(aac->raw_io_interface) ||
- !(aac->raw_io_64) ||
- ((cmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
- break;
- /* fall through */
- case INQUIRY:
- case READ_CAPACITY:
- /*
- * 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 &&
+ command = fib->callback_data;
+
+ 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;
- cmd->SCp.phase =
- AAC_OWNER_ERROR_HANDLER;
+ ((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;
- case TEST_UNIT_READY:
- /*
- * 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;
- command->SCp.phase =
- AAC_OWNER_ERROR_HANDLER;
- if (command == cmd)
- ret = SUCCESS;
- }
- }
- break;
}
- }
- return ret;
-}
-
-static u8 aac_eh_tmf_lun_reset_fib(struct aac_hba_map_info *info,
- struct fib *fib, u64 tmf_lun)
-{
- struct aac_hba_tm_req *tmf;
- u64 address;
-
- /* start a HBA_TMF_LUN_RESET TMF request */
- tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
- memset(tmf, 0, sizeof(*tmf));
- tmf->tmf = HBA_TMF_LUN_RESET;
- tmf->it_nexus = info->rmw_nexus;
- int_to_scsilun(tmf_lun, (struct scsi_lun *)tmf->lun);
-
- address = (u64)fib->hw_error_pa;
- tmf->error_ptr_hi = cpu_to_le32
- ((u32)(address >> 32));
- tmf->error_ptr_lo = cpu_to_le32
- ((u32)(address & 0xffffffff));
- tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
- fib->hbacmd_size = sizeof(*tmf);
-
- return HBA_IU_TYPE_SCSI_TM_REQ;
-}
-
-static u8 aac_eh_tmf_hard_reset_fib(struct aac_hba_map_info *info,
- struct fib *fib)
-{
- struct aac_hba_reset_req *rst;
- u64 address;
-
- /* already tried, start a hard reset now */
- rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
- memset(rst, 0, sizeof(*rst));
- rst->it_nexus = info->rmw_nexus;
-
- address = (u64)fib->hw_error_pa;
- rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
- rst->error_ptr_lo = cpu_to_le32((u32)(address & 0xffffffff));
- rst->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
- fib->hbacmd_size = sizeof(*rst);
-
- return HBA_IU_TYPE_SATA_REQ;
-}
-
-static void aac_tmf_callback(void *context, struct fib *fibptr)
-{
- struct aac_hba_resp *err =
- &((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
- struct aac_hba_map_info *info = context;
- int res;
-
- switch (err->service_response) {
- case HBA_RESP_SVCRES_TMF_REJECTED:
- res = -1;
- break;
- case HBA_RESP_SVCRES_TMF_LUN_INVALID:
- res = 0;
- break;
- case HBA_RESP_SVCRES_TMF_COMPLETE:
- case HBA_RESP_SVCRES_TMF_SUCCEEDED:
- res = 0;
- break;
- default:
- res = -2;
break;
}
- aac_fib_complete(fibptr);
-
- info->reset_state = res;
-}
-
-/*
- * aac_eh_dev_reset - Device reset command handling
- * @scsi_cmd: SCSI command block causing the reset
- *
- */
-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;
- struct aac_hba_map_info *info;
- int count;
- u32 bus, cid;
- struct fib *fib;
- int ret = FAILED;
- 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)
- return FAILED;
-
- info = &aac->hba_map[bus][cid];
-
- if (!(info->devtype == AAC_DEVTYPE_NATIVE_RAW &&
- !(info->reset_state > 0)))
- return FAILED;
-
- pr_err("%s: Host device reset request. SCSI hang ?\n",
- AAC_DRIVERNAME);
-
- fib = aac_fib_alloc(aac);
- if (!fib)
- return ret;
-
- /* start a HBA_TMF_LUN_RESET TMF request */
- command = aac_eh_tmf_lun_reset_fib(info, fib, dev->lun);
-
- info->reset_state = 1;
-
- status = aac_hba_send(command, fib,
- (fib_callback) aac_tmf_callback,
- (void *) info);
- if (status != -EINPROGRESS) {
- info->reset_state = 0;
- aac_fib_complete(fib);
- aac_fib_free(fib);
- return ret;
- }
- /* Wait up to 15 seconds for completion */
- for (count = 0; count < 15; ++count) {
- if (info->reset_state == 0) {
- ret = info->reset_state == 0 ? SUCCESS : FAILED;
- break;
- }
- msleep(1000);
- }
-
- return ret;
-}
-
-/*
- * 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;
- struct aac_hba_map_info *info;
- 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)
- return FAILED;
-
- info = &aac->hba_map[bus][cid];
-
- if (!(info->devtype == AAC_DEVTYPE_NATIVE_RAW &&
- !(info->reset_state > 0)))
- return FAILED;
-
- pr_err("%s: Host target 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(info, fib);
-
- info->reset_state = 2;
-
- status = aac_hba_send(command, fib,
- (fib_callback) aac_tmf_callback,
- (void *) info);
-
- if (status != -EINPROGRESS) {
- info->reset_state = 0;
- aac_fib_complete(fib);
- aac_fib_free(fib);
- return ret;
- }
-
- /* Wait up to 15 seconds for completion */
- for (count = 0; count < 15; ++count) {
- if (info->reset_state <= 0) {
- ret = info->reset_state == 0 ? SUCCESS : FAILED;
- break;
- }
- msleep(1000);
- }
-
return ret;
}
@@ -1545,8 +1284,6 @@ 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_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,
Patch "bef18d308a22 scsi: aacraid: Disabling TM path and only processing IOP reset" has modified aac_hba_send so it returns -EINVAL for everything except HBA_IU_TYPE_SCSI_TM_REQ command. That makes callers using other commands useless - remove them together with related functions and make the test in aac_hba_send more visible. Patch also replaces a /* fall through */ comment. Signed-off-by: Tomas Henzl <thenzl@redhat.com> --- drivers/scsi/aacraid/commsup.c | 12 +- drivers/scsi/aacraid/linit.c | 379 +++++---------------------------- 2 files changed, 64 insertions(+), 327 deletions(-)