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

scsi: mpt3sas: simplify mpt3sas_scsi_issue_tm()

Move the check for outstanding commands out of the function allowing us
to simplify the overall code.
Signed-off-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarSuganath Prabu S <suganath-prabu.subramani@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 74fcfa53
...@@ -1444,11 +1444,9 @@ u8 mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, ...@@ -1444,11 +1444,9 @@ u8 mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
void mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase); void mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);
int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
uint channel, uint id, uint lun, u8 type, u16 smid_task, u64 lun, u8 type, u16 smid_task, u16 msix_task, ulong timeout);
ulong timeout);
int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
uint channel, uint id, uint lun, u8 type, u16 smid_task, u64 lun, u8 type, u16 smid_task, u16 msix_task, ulong timeout);
ulong timeout);
void mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle); void mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
void mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle); void mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
......
...@@ -1075,8 +1075,8 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, ...@@ -1075,8 +1075,8 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
le16_to_cpu(mpi_request->FunctionDependent1)); le16_to_cpu(mpi_request->FunctionDependent1));
mpt3sas_halt_firmware(ioc); mpt3sas_halt_firmware(ioc);
mpt3sas_scsih_issue_locked_tm(ioc, mpt3sas_scsih_issue_locked_tm(ioc,
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0, le16_to_cpu(mpi_request->FunctionDependent1), 0,
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30); MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 0, 30);
} else } else
mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
} }
......
...@@ -1495,25 +1495,24 @@ _scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc, u16 smid) ...@@ -1495,25 +1495,24 @@ _scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc, u16 smid)
* This will search for a scmd pointer in the scsi_lookup array, * This will search for a scmd pointer in the scsi_lookup array,
* returning the revelent smid. A returned value of zero means invalid. * returning the revelent smid. A returned value of zero means invalid.
*/ */
static u16 struct scsiio_tracker *
_scsih_scsi_lookup_find_by_scmd(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd _scsih_scsi_lookup_find_by_scmd(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd
*scmd) *scmd)
{ {
u16 smid; struct scsiio_tracker *st = NULL;
unsigned long flags; unsigned long flags;
int i; int i;
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
smid = 0;
for (i = 0; i < ioc->scsiio_depth; i++) { for (i = 0; i < ioc->scsiio_depth; i++) {
if (ioc->scsi_lookup[i].scmd == scmd) { if (ioc->scsi_lookup[i].scmd == scmd) {
smid = ioc->scsi_lookup[i].smid; st = &ioc->scsi_lookup[i];
goto out; goto out;
} }
} }
out: out:
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
return smid; return st;
} }
/** /**
...@@ -2646,32 +2645,30 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -2646,32 +2645,30 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
/** /**
* mpt3sas_scsih_issue_tm - main routine for sending tm requests * mpt3sas_scsih_issue_tm - main routine for sending tm requests
* @ioc: per adapter struct * @ioc: per adapter struct
* @device_handle: device handle * @handle: device handle
* @channel: the channel assigned by the OS
* @id: the id assigned by the OS
* @lun: lun number * @lun: lun number
* @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h) * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
* @smid_task: smid assigned to the task * @smid_task: smid assigned to the task
* @msix_task: MSIX table index supplied by the OS
* @timeout: timeout in seconds * @timeout: timeout in seconds
* Context: user * Context: user
* *
* A generic API for sending task management requests to firmware. * A generic API for sending task management requests to firmware.
* *
* The callback index is set inside `ioc->tm_cb_idx`. * The callback index is set inside `ioc->tm_cb_idx`.
* The caller is responsible to check for outstanding commands.
* *
* Return SUCCESS or FAILED. * Return SUCCESS or FAILED.
*/ */
int int
mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
uint id, uint lun, u8 type, u16 smid_task, ulong timeout) u64 lun, u8 type, u16 smid_task, u16 msix_task, ulong timeout)
{ {
Mpi2SCSITaskManagementRequest_t *mpi_request; Mpi2SCSITaskManagementRequest_t *mpi_request;
Mpi2SCSITaskManagementReply_t *mpi_reply; Mpi2SCSITaskManagementReply_t *mpi_reply;
u16 smid = 0; u16 smid = 0;
u32 ioc_state; u32 ioc_state;
struct scsiio_tracker *scsi_lookup = NULL;
int rc; int rc;
u16 msix_task = 0;
lockdep_assert_held(&ioc->tm_cmds.mutex); lockdep_assert_held(&ioc->tm_cmds.mutex);
...@@ -2703,14 +2700,6 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, ...@@ -2703,14 +2700,6 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
return (!rc) ? SUCCESS : FAILED; return (!rc) ? SUCCESS : FAILED;
} }
if (type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
scsi_lookup = mpt3sas_get_st_from_smid(ioc, smid_task);
if (!scsi_lookup)
return FAILED;
if (scsi_lookup->cb_idx == 0xFF)
return SUCCESS;
}
smid = mpt3sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx); smid = mpt3sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx);
if (!smid) { if (!smid) {
pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n",
...@@ -2733,12 +2722,6 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, ...@@ -2733,12 +2722,6 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN); int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
mpt3sas_scsih_set_tm_flag(ioc, handle); mpt3sas_scsih_set_tm_flag(ioc, handle);
init_completion(&ioc->tm_cmds.done); init_completion(&ioc->tm_cmds.done);
if ((type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK) &&
scsi_lookup &&
(scsi_lookup->msix_io < ioc->reply_queue_count))
msix_task = scsi_lookup->msix_io;
else
msix_task = 0;
ioc->put_smid_hi_priority(ioc, smid, msix_task); ioc->put_smid_hi_priority(ioc, smid, msix_task);
wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ); wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) { if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) {
...@@ -2772,25 +2755,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, ...@@ -2772,25 +2755,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
sizeof(Mpi2SCSITaskManagementRequest_t)/4); sizeof(Mpi2SCSITaskManagementRequest_t)/4);
} }
} }
switch (type) {
case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
rc = SUCCESS;
if (scsi_lookup && scsi_lookup->scmd == NULL)
break;
rc = FAILED;
break;
case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
rc = SUCCESS; rc = SUCCESS;
break;
default:
rc = FAILED;
break;
}
out: out:
mpt3sas_scsih_clear_tm_flag(ioc, handle); mpt3sas_scsih_clear_tm_flag(ioc, handle);
...@@ -2799,13 +2764,13 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, ...@@ -2799,13 +2764,13 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
} }
int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
uint channel, uint id, uint lun, u8 type, u16 smid_task, ulong timeout) u64 lun, u8 type, u16 smid_task, u16 msix_task, ulong timeout)
{ {
int ret; int ret;
mutex_lock(&ioc->tm_cmds.mutex); mutex_lock(&ioc->tm_cmds.mutex);
ret = mpt3sas_scsih_issue_tm(ioc, handle, channel, id, lun, type, ret = mpt3sas_scsih_issue_tm(ioc, handle, lun, type, smid_task,
smid_task, timeout); msix_task, timeout);
mutex_unlock(&ioc->tm_cmds.mutex); mutex_unlock(&ioc->tm_cmds.mutex);
return ret; return ret;
...@@ -2904,7 +2869,7 @@ scsih_abort(struct scsi_cmnd *scmd) ...@@ -2904,7 +2869,7 @@ scsih_abort(struct scsi_cmnd *scmd)
{ {
struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
struct MPT3SAS_DEVICE *sas_device_priv_data; struct MPT3SAS_DEVICE *sas_device_priv_data;
u16 smid; struct scsiio_tracker *st = NULL;
u16 handle; u16 handle;
int r; int r;
...@@ -2923,8 +2888,8 @@ scsih_abort(struct scsi_cmnd *scmd) ...@@ -2923,8 +2888,8 @@ scsih_abort(struct scsi_cmnd *scmd)
} }
/* search for the command */ /* search for the command */
smid = _scsih_scsi_lookup_find_by_scmd(ioc, scmd); st = _scsih_scsi_lookup_find_by_scmd(ioc, scmd);
if (!smid) { if (!st) {
scmd->result = DID_RESET << 16; scmd->result = DID_RESET << 16;
r = SUCCESS; r = SUCCESS;
goto out; goto out;
...@@ -2942,10 +2907,12 @@ scsih_abort(struct scsi_cmnd *scmd) ...@@ -2942,10 +2907,12 @@ scsih_abort(struct scsi_cmnd *scmd)
mpt3sas_halt_firmware(ioc); mpt3sas_halt_firmware(ioc);
handle = sas_device_priv_data->sas_target->handle; handle = sas_device_priv_data->sas_target->handle;
r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel, r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->lun,
scmd->device->id, scmd->device->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30); st->smid, st->msix_io, 30);
/* Command must be cleared after abort */
if (r == SUCCESS && st->scmd)
r = FAILED;
out: out:
sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n", sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
...@@ -3001,9 +2968,8 @@ scsih_dev_reset(struct scsi_cmnd *scmd) ...@@ -3001,9 +2968,8 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
goto out; goto out;
} }
r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel, r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->lun,
scmd->device->id, scmd->device->lun, MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 0, 30);
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30);
/* Check for busy commands after reset */ /* Check for busy commands after reset */
if (r == SUCCESS && atomic_read(&scmd->device->device_busy)) if (r == SUCCESS && atomic_read(&scmd->device->device_busy))
r = FAILED; r = FAILED;
...@@ -3065,9 +3031,8 @@ scsih_target_reset(struct scsi_cmnd *scmd) ...@@ -3065,9 +3031,8 @@ scsih_target_reset(struct scsi_cmnd *scmd)
goto out; goto out;
} }
r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel, r = mpt3sas_scsih_issue_locked_tm(ioc, handle, 0,
scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 0, 30);
30);
/* Check for busy commands after reset */ /* Check for busy commands after reset */
if (r == SUCCESS && atomic_read(&starget->target_busy)) if (r == SUCCESS && atomic_read(&starget->target_busy))
r = FAILED; r = FAILED;
...@@ -7421,6 +7386,7 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc, ...@@ -7421,6 +7386,7 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
{ {
struct scsi_cmnd *scmd; struct scsi_cmnd *scmd;
struct scsi_device *sdev; struct scsi_device *sdev;
struct scsiio_tracker *st;
u16 smid, handle; u16 smid, handle;
u32 lun; u32 lun;
struct MPT3SAS_DEVICE *sas_device_priv_data; struct MPT3SAS_DEVICE *sas_device_priv_data;
...@@ -7462,7 +7428,8 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc, ...@@ -7462,7 +7428,8 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
for (smid = 1; smid <= ioc->scsiio_depth; smid++) { for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
if (ioc->shost_recovery) if (ioc->shost_recovery)
goto out; goto out;
scmd = ioc->scsi_lookup[smid - 1].scmd; st = &ioc->scsi_lookup[smid - 1];
scmd = st->scmd;
if (!scmd) if (!scmd)
continue; continue;
sdev = scmd->device; sdev = scmd->device;
...@@ -7486,8 +7453,9 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc, ...@@ -7486,8 +7453,9 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
goto out; goto out;
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
r = mpt3sas_scsih_issue_tm(ioc, handle, 0, 0, lun, r = mpt3sas_scsih_issue_tm(ioc, handle, lun,
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30); MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid,
st->msix_io, 30);
if (r == FAILED) { if (r == FAILED) {
sdev_printk(KERN_WARNING, sdev, sdev_printk(KERN_WARNING, sdev,
"mpt3sas_scsih_issue_tm: FAILED when sending " "mpt3sas_scsih_issue_tm: FAILED when sending "
...@@ -7526,10 +7494,10 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc, ...@@ -7526,10 +7494,10 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
if (ioc->shost_recovery) if (ioc->shost_recovery)
goto out_no_lock; goto out_no_lock;
r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id, r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->lun,
sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid,
30); st->msix_io, 30);
if (r == FAILED) { if (r == FAILED || st->scmd) {
sdev_printk(KERN_WARNING, sdev, sdev_printk(KERN_WARNING, sdev,
"mpt3sas_scsih_issue_tm: ABORT_TASK: FAILED : " "mpt3sas_scsih_issue_tm: ABORT_TASK: FAILED : "
"scmd(%p)\n", scmd); "scmd(%p)\n", scmd);
......
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