diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-12-09 02:20:44 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-29 16:13:40 -0500 |
commit | 43a5ab151f0268459c4368292c2ddb2266b8f243 (patch) | |
tree | e8ee97e0d49bc0c454ca90f16a836fd01830b11f /drivers/scsi/isci/task.c | |
parent | 9277699121b81891e303ada0a53fa1d04b7ffe72 (diff) |
[SCSI] isci: stop interpreting ->lldd_lu_reset() as an ata soft-reset
Driving resets from libsas-eh is pre-mature as libata will make a
decision about performing a softreset. Currently libata determines
whether to perform a softreset based on ata_eh_followup_srst_needed(),
and none of those conditions apply to isci.
Remove the srst implementation and translate ->lldd_lu_reset() for ata
devices as a request to drive a reset via libata-eh.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/isci/task.c')
-rw-r--r-- | drivers/scsi/isci/task.c | 93 |
1 files changed, 7 insertions, 86 deletions
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index c4d324ccee11..3f04e97128a6 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c | |||
@@ -247,46 +247,6 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags) | |||
247 | return 0; | 247 | return 0; |
248 | } | 248 | } |
249 | 249 | ||
250 | static enum sci_status isci_sata_management_task_request_build(struct isci_request *ireq) | ||
251 | { | ||
252 | struct isci_tmf *isci_tmf; | ||
253 | enum sci_status status; | ||
254 | |||
255 | if (!test_bit(IREQ_TMF, &ireq->flags)) | ||
256 | return SCI_FAILURE; | ||
257 | |||
258 | isci_tmf = isci_request_access_tmf(ireq); | ||
259 | |||
260 | switch (isci_tmf->tmf_code) { | ||
261 | |||
262 | case isci_tmf_sata_srst_high: | ||
263 | case isci_tmf_sata_srst_low: { | ||
264 | struct host_to_dev_fis *fis = &ireq->stp.cmd; | ||
265 | |||
266 | memset(fis, 0, sizeof(*fis)); | ||
267 | |||
268 | fis->fis_type = 0x27; | ||
269 | fis->flags &= ~0x80; | ||
270 | fis->flags &= 0xF0; | ||
271 | if (isci_tmf->tmf_code == isci_tmf_sata_srst_high) | ||
272 | fis->control |= ATA_SRST; | ||
273 | else | ||
274 | fis->control &= ~ATA_SRST; | ||
275 | break; | ||
276 | } | ||
277 | /* other management commnd go here... */ | ||
278 | default: | ||
279 | return SCI_FAILURE; | ||
280 | } | ||
281 | |||
282 | /* core builds the protocol specific request | ||
283 | * based on the h2d fis. | ||
284 | */ | ||
285 | status = sci_task_request_construct_sata(ireq); | ||
286 | |||
287 | return status; | ||
288 | } | ||
289 | |||
290 | static struct isci_request *isci_task_request_build(struct isci_host *ihost, | 250 | static struct isci_request *isci_task_request_build(struct isci_host *ihost, |
291 | struct isci_remote_device *idev, | 251 | struct isci_remote_device *idev, |
292 | u16 tag, struct isci_tmf *isci_tmf) | 252 | u16 tag, struct isci_tmf *isci_tmf) |
@@ -326,13 +286,6 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost, | |||
326 | return NULL; | 286 | return NULL; |
327 | } | 287 | } |
328 | 288 | ||
329 | if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { | ||
330 | isci_tmf->proto = SAS_PROTOCOL_SATA; | ||
331 | status = isci_sata_management_task_request_build(ireq); | ||
332 | |||
333 | if (status != SCI_SUCCESS) | ||
334 | return NULL; | ||
335 | } | ||
336 | return ireq; | 289 | return ireq; |
337 | } | 290 | } |
338 | 291 | ||
@@ -871,53 +824,20 @@ static int isci_task_send_lu_reset_sas( | |||
871 | return ret; | 824 | return ret; |
872 | } | 825 | } |
873 | 826 | ||
874 | static int isci_task_send_lu_reset_sata(struct isci_host *ihost, | 827 | int isci_task_lu_reset(struct domain_device *dev, u8 *lun) |
875 | struct isci_remote_device *idev, u8 *lun) | ||
876 | { | 828 | { |
877 | int ret = TMF_RESP_FUNC_FAILED; | 829 | struct isci_host *isci_host = dev_to_ihost(dev); |
878 | struct isci_tmf tmf; | ||
879 | |||
880 | /* Send the soft reset to the target */ | ||
881 | #define ISCI_SRST_TIMEOUT_MS 25000 /* 25 second timeout. */ | ||
882 | isci_task_build_tmf(&tmf, isci_tmf_sata_srst_high, NULL, NULL); | ||
883 | |||
884 | ret = isci_task_execute_tmf(ihost, idev, &tmf, ISCI_SRST_TIMEOUT_MS); | ||
885 | |||
886 | if (ret != TMF_RESP_FUNC_COMPLETE) { | ||
887 | dev_dbg(&ihost->pdev->dev, | ||
888 | "%s: Assert SRST failed (%p) = %x", | ||
889 | __func__, idev, ret); | ||
890 | |||
891 | /* Return the failure so that the LUN reset is escalated | ||
892 | * to a target reset. | ||
893 | */ | ||
894 | } | ||
895 | return ret; | ||
896 | } | ||
897 | |||
898 | /** | ||
899 | * isci_task_lu_reset() - This function is one of the SAS Domain Template | ||
900 | * functions. This is one of the Task Management functoins called by libsas, | ||
901 | * to reset the given lun. Note the assumption that while this call is | ||
902 | * executing, no I/O will be sent by the host to the device. | ||
903 | * @lun: This parameter specifies the lun to be reset. | ||
904 | * | ||
905 | * status, zero indicates success. | ||
906 | */ | ||
907 | int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun) | ||
908 | { | ||
909 | struct isci_host *isci_host = dev_to_ihost(domain_device); | ||
910 | struct isci_remote_device *isci_device; | 830 | struct isci_remote_device *isci_device; |
911 | unsigned long flags; | 831 | unsigned long flags; |
912 | int ret; | 832 | int ret; |
913 | 833 | ||
914 | spin_lock_irqsave(&isci_host->scic_lock, flags); | 834 | spin_lock_irqsave(&isci_host->scic_lock, flags); |
915 | isci_device = isci_lookup_device(domain_device); | 835 | isci_device = isci_lookup_device(dev); |
916 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); | 836 | spin_unlock_irqrestore(&isci_host->scic_lock, flags); |
917 | 837 | ||
918 | dev_dbg(&isci_host->pdev->dev, | 838 | dev_dbg(&isci_host->pdev->dev, |
919 | "%s: domain_device=%p, isci_host=%p; isci_device=%p\n", | 839 | "%s: domain_device=%p, isci_host=%p; isci_device=%p\n", |
920 | __func__, domain_device, isci_host, isci_device); | 840 | __func__, dev, isci_host, isci_device); |
921 | 841 | ||
922 | if (!isci_device) { | 842 | if (!isci_device) { |
923 | /* If the device is gone, stop the escalations. */ | 843 | /* If the device is gone, stop the escalations. */ |
@@ -929,8 +849,9 @@ int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun) | |||
929 | set_bit(IDEV_EH, &isci_device->flags); | 849 | set_bit(IDEV_EH, &isci_device->flags); |
930 | 850 | ||
931 | /* Send the task management part of the reset. */ | 851 | /* Send the task management part of the reset. */ |
932 | if (sas_protocol_ata(domain_device->tproto)) { | 852 | if (dev_is_sata(dev)) { |
933 | ret = isci_task_send_lu_reset_sata(isci_host, isci_device, lun); | 853 | sas_ata_schedule_reset(dev); |
854 | ret = TMF_RESP_FUNC_COMPLETE; | ||
934 | } else | 855 | } else |
935 | ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun); | 856 | ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun); |
936 | 857 | ||