diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-03-31 16:10:44 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:00:36 -0400 |
commit | 4393aa4e6b9517a666f0ef6b774fd421a9dc4c68 (patch) | |
tree | ec5e0c222d16f2368e5589a11fc4ec191ceca365 /drivers/scsi/isci/task.c | |
parent | 037afc7812e2b202fbc18218e6c0eff34dad36ed (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.c | 87 |
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 | */ |
147 | int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | 147 | int 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 | ||
594 | static struct isci_request *isci_task_get_request_from_task( | 594 | static 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 | */ |
1030 | int isci_task_lu_reset( | 1026 | int 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 | */ |
1174 | int isci_task_abort_task(struct sas_task *task) | 1155 | int 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 | */ |
1611 | int isci_bus_reset_handler(struct scsi_cmnd *cmd) | 1591 | int 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 | ||