aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/task.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-03-31 16:10:44 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:00:36 -0400
commit4393aa4e6b9517a666f0ef6b774fd421a9dc4c68 (patch)
treeec5e0c222d16f2368e5589a11fc4ec191ceca365 /drivers/scsi/isci/task.c
parent037afc7812e2b202fbc18218e6c0eff34dad36ed (diff)
isci: fix fragile/conditional isci_host lookups
A domain_device can always reference back to ->lldd_ha unlike local lldd structures. Fix up cases where the driver uses local objects to look up the isci_host. This also changes the calling conventions of some routines to expect a valid isci_host parameter rather than re-lookup the pointer on entry. Incidentally cleans up some macros that are longer to type than the open-coded equivalent: isci_host_from_sas_ha isci_dev_from_domain_dev Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/task.c')
-rw-r--r--drivers/scsi/isci/task.c87
1 files changed, 27 insertions, 60 deletions
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index 5bcea60fd8c4..c6c97ad58c9f 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -146,7 +146,7 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task,
146 */ 146 */
147int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) 147int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
148{ 148{
149 struct isci_host *ihost = task->dev->port->ha->lldd_ha; 149 struct isci_host *ihost = dev_to_ihost(task->dev);
150 struct isci_request *request = NULL; 150 struct isci_request *request = NULL;
151 struct isci_remote_device *device; 151 struct isci_remote_device *device;
152 unsigned long flags; 152 unsigned long flags;
@@ -169,7 +169,7 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
169 "task = %p, num = %d; dev = %p; cmd = %p\n", 169 "task = %p, num = %d; dev = %p; cmd = %p\n",
170 task, num, task->dev, task->uldd_task); 170 task, num, task->dev, task->uldd_task);
171 171
172 device = isci_dev_from_domain_dev(task->dev); 172 device = task->dev->lldd_dev;
173 173
174 if (device) 174 if (device)
175 device_status = device->status; 175 device_status = device->status;
@@ -593,7 +593,6 @@ static void isci_task_build_abort_task_tmf(
593 593
594static struct isci_request *isci_task_get_request_from_task( 594static struct isci_request *isci_task_get_request_from_task(
595 struct sas_task *task, 595 struct sas_task *task,
596 struct isci_host **isci_host,
597 struct isci_remote_device **isci_device) 596 struct isci_remote_device **isci_device)
598{ 597{
599 598
@@ -609,9 +608,6 @@ static struct isci_request *isci_task_get_request_from_task(
609 (task->task_state_flags & SAS_TASK_AT_INITIATOR) && 608 (task->task_state_flags & SAS_TASK_AT_INITIATOR) &&
610 (request != NULL)) { 609 (request != NULL)) {
611 610
612 if (isci_host != NULL)
613 *isci_host = request->isci_host;
614
615 if (isci_device != NULL) 611 if (isci_device != NULL)
616 *isci_device = request->isci_device; 612 *isci_device = request->isci_device;
617 } 613 }
@@ -1027,26 +1023,17 @@ static int isci_task_send_lu_reset_sas(
1027 * 1023 *
1028 * status, zero indicates success. 1024 * status, zero indicates success.
1029 */ 1025 */
1030int isci_task_lu_reset( 1026int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun)
1031 struct domain_device *domain_device,
1032 u8 *lun)
1033{ 1027{
1034 struct isci_host *isci_host = NULL; 1028 struct isci_host *isci_host = dev_to_ihost(domain_device);
1035 struct isci_remote_device *isci_device = NULL; 1029 struct isci_remote_device *isci_device = NULL;
1036 int ret; 1030 int ret;
1037 bool device_stopping = false; 1031 bool device_stopping = false;
1038 1032
1039 if (domain_device == NULL) { 1033 isci_device = domain_device->lldd_dev;
1040 pr_warn("%s: domain_device == NULL\n", __func__);
1041 return TMF_RESP_FUNC_FAILED;
1042 }
1043
1044 isci_device = isci_dev_from_domain_dev(domain_device);
1045
1046 if (domain_device->port != NULL)
1047 isci_host = isci_host_from_sas_ha(domain_device->port->ha);
1048 1034
1049 pr_debug("%s: domain_device=%p, isci_host=%p; isci_device=%p\n", 1035 dev_dbg(&isci_host->pdev->dev,
1036 "%s: domain_device=%p, isci_host=%p; isci_device=%p\n",
1050 __func__, domain_device, isci_host, isci_device); 1037 __func__, domain_device, isci_host, isci_device);
1051 1038
1052 if (isci_device != NULL) 1039 if (isci_device != NULL)
@@ -1057,24 +1044,18 @@ int isci_task_lu_reset(
1057 * device's list, fail this LUN reset request in order to 1044 * device's list, fail this LUN reset request in order to
1058 * escalate to the device reset. 1045 * escalate to the device reset.
1059 */ 1046 */
1060 if ((isci_device == NULL) || 1047 if (!isci_device || device_stopping ||
1061 (isci_host == NULL) || 1048 isci_device_is_reset_pending(isci_host, isci_device)) {
1062 ((isci_host != NULL) &&
1063 (isci_device != NULL) &&
1064 (device_stopping ||
1065 (isci_device_is_reset_pending(isci_host, isci_device))))) {
1066 dev_warn(&isci_host->pdev->dev, 1049 dev_warn(&isci_host->pdev->dev,
1067 "%s: No dev (%p), no host (%p), or " 1050 "%s: No dev (%p), or "
1068 "RESET PENDING: domain_device=%p\n", 1051 "RESET PENDING: domain_device=%p\n",
1069 __func__, isci_device, isci_host, domain_device); 1052 __func__, isci_device, domain_device);
1070 return TMF_RESP_FUNC_FAILED; 1053 return TMF_RESP_FUNC_FAILED;
1071 } 1054 }
1072 1055
1073 /* Send the task management part of the reset. */ 1056 /* Send the task management part of the reset. */
1074 if (sas_protocol_ata(domain_device->tproto)) { 1057 if (sas_protocol_ata(domain_device->tproto)) {
1075 ret = isci_task_send_lu_reset_sata( 1058 ret = isci_task_send_lu_reset_sata(isci_host, isci_device, lun);
1076 isci_host, isci_device, lun
1077 );
1078 } else 1059 } else
1079 ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun); 1060 ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun);
1080 1061
@@ -1173,11 +1154,11 @@ static void isci_abort_task_process_cb(
1173 */ 1154 */
1174int isci_task_abort_task(struct sas_task *task) 1155int isci_task_abort_task(struct sas_task *task)
1175{ 1156{
1157 struct isci_host *isci_host = dev_to_ihost(task->dev);
1176 DECLARE_COMPLETION_ONSTACK(aborted_io_completion); 1158 DECLARE_COMPLETION_ONSTACK(aborted_io_completion);
1177 struct isci_request *old_request = NULL; 1159 struct isci_request *old_request = NULL;
1178 enum isci_request_status old_state; 1160 enum isci_request_status old_state;
1179 struct isci_remote_device *isci_device = NULL; 1161 struct isci_remote_device *isci_device = NULL;
1180 struct isci_host *isci_host = NULL;
1181 struct isci_tmf tmf; 1162 struct isci_tmf tmf;
1182 int ret = TMF_RESP_FUNC_FAILED; 1163 int ret = TMF_RESP_FUNC_FAILED;
1183 unsigned long flags; 1164 unsigned long flags;
@@ -1189,8 +1170,7 @@ int isci_task_abort_task(struct sas_task *task)
1189 * in the device, because tasks driving resets may land here 1170 * in the device, because tasks driving resets may land here
1190 * after completion in the core. 1171 * after completion in the core.
1191 */ 1172 */
1192 old_request = isci_task_get_request_from_task(task, &isci_host, 1173 old_request = isci_task_get_request_from_task(task, &isci_device);
1193 &isci_device);
1194 1174
1195 dev_dbg(&isci_host->pdev->dev, 1175 dev_dbg(&isci_host->pdev->dev,
1196 "%s: task = %p\n", __func__, task); 1176 "%s: task = %p\n", __func__, task);
@@ -1610,37 +1590,29 @@ u32 isci_task_ssp_request_get_response_data_length(
1610 */ 1590 */
1611int isci_bus_reset_handler(struct scsi_cmnd *cmd) 1591int isci_bus_reset_handler(struct scsi_cmnd *cmd)
1612{ 1592{
1593 struct domain_device *dev = cmd_to_domain_dev(cmd);
1594 struct isci_host *isci_host = dev_to_ihost(dev);
1613 unsigned long flags = 0; 1595 unsigned long flags = 0;
1614 struct isci_host *isci_host = NULL;
1615 enum sci_status status; 1596 enum sci_status status;
1616 int base_status; 1597 int base_status;
1617 struct isci_remote_device *isci_dev 1598 struct isci_remote_device *isci_dev = dev->lldd_dev;
1618 = isci_dev_from_domain_dev(
1619 sdev_to_domain_dev(cmd->device));
1620 1599
1621 dev_dbg(&cmd->device->sdev_gendev, 1600 dev_dbg(&isci_host->pdev->dev,
1622 "%s: cmd %p, isci_dev %p\n", 1601 "%s: cmd %p, isci_dev %p\n",
1623 __func__, cmd, isci_dev); 1602 __func__, cmd, isci_dev);
1624 1603
1625 if (!isci_dev) { 1604 if (!isci_dev) {
1626 dev_warn(&cmd->device->sdev_gendev, 1605 dev_warn(&isci_host->pdev->dev,
1627 "%s: isci_dev is GONE!\n", 1606 "%s: isci_dev is GONE!\n",
1628 __func__); 1607 __func__);
1629 1608
1630 return TMF_RESP_FUNC_COMPLETE; /* Nothing to reset. */ 1609 return TMF_RESP_FUNC_COMPLETE; /* Nothing to reset. */
1631 } 1610 }
1632 1611
1633 if (isci_dev->isci_port != NULL) 1612 spin_lock_irqsave(&isci_host->scic_lock, flags);
1634 isci_host = isci_dev->isci_port->isci_host;
1635
1636 if (isci_host != NULL)
1637 spin_lock_irqsave(&isci_host->scic_lock, flags);
1638
1639 status = scic_remote_device_reset(to_sci_dev(isci_dev)); 1613 status = scic_remote_device_reset(to_sci_dev(isci_dev));
1640 if (status != SCI_SUCCESS) { 1614 if (status != SCI_SUCCESS) {
1641 1615 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1642 if (isci_host != NULL)
1643 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1644 1616
1645 scmd_printk(KERN_WARNING, cmd, 1617 scmd_printk(KERN_WARNING, cmd,
1646 "%s: scic_remote_device_reset(%p) returned %d!\n", 1618 "%s: scic_remote_device_reset(%p) returned %d!\n",
@@ -1648,14 +1620,13 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd)
1648 1620
1649 return TMF_RESP_FUNC_FAILED; 1621 return TMF_RESP_FUNC_FAILED;
1650 } 1622 }
1651 if (isci_host != NULL) 1623 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1652 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1653 1624
1654 /* Make sure all pending requests are able to be fully terminated. */ 1625 /* Make sure all pending requests are able to be fully terminated. */
1655 isci_device_clear_reset_pending(isci_dev); 1626 isci_device_clear_reset_pending(isci_host, isci_dev);
1656 1627
1657 /* Terminate in-progress I/O now. */ 1628 /* Terminate in-progress I/O now. */
1658 isci_remote_device_nuke_requests(isci_dev); 1629 isci_remote_device_nuke_requests(isci_host, isci_dev);
1659 1630
1660 /* Call into the libsas default handler (which calls sas_phy_reset). */ 1631 /* Call into the libsas default handler (which calls sas_phy_reset). */
1661 base_status = sas_eh_bus_reset_handler(cmd); 1632 base_status = sas_eh_bus_reset_handler(cmd);
@@ -1672,13 +1643,9 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd)
1672 } 1643 }
1673 1644
1674 /* WHAT TO DO HERE IF sas_phy_reset FAILS? */ 1645 /* WHAT TO DO HERE IF sas_phy_reset FAILS? */
1675 1646 spin_lock_irqsave(&isci_host->scic_lock, flags);
1676 if (isci_host != NULL)
1677 spin_lock_irqsave(&isci_host->scic_lock, flags);
1678 status = scic_remote_device_reset_complete(to_sci_dev(isci_dev)); 1647 status = scic_remote_device_reset_complete(to_sci_dev(isci_dev));
1679 1648 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1680 if (isci_host != NULL)
1681 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1682 1649
1683 if (status != SCI_SUCCESS) { 1650 if (status != SCI_SUCCESS) {
1684 scmd_printk(KERN_WARNING, cmd, 1651 scmd_printk(KERN_WARNING, cmd,
@@ -1688,7 +1655,7 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd)
1688 } 1655 }
1689 /* WHAT TO DO HERE IF scic_remote_device_reset_complete FAILS? */ 1656 /* WHAT TO DO HERE IF scic_remote_device_reset_complete FAILS? */
1690 1657
1691 dev_dbg(&cmd->device->sdev_gendev, 1658 dev_dbg(&isci_host->pdev->dev,
1692 "%s: cmd %p, isci_dev %p complete.\n", 1659 "%s: cmd %p, isci_dev %p complete.\n",
1693 __func__, cmd, isci_dev); 1660 __func__, cmd, isci_dev);
1694 1661