aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/task.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/isci/task.c')
-rw-r--r--drivers/scsi/isci/task.c100
1 files changed, 80 insertions, 20 deletions
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index 20112cd5b646..5d962b6b03eb 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -61,7 +61,6 @@
61#include "remote_node_context.h" 61#include "remote_node_context.h"
62#include "isci.h" 62#include "isci.h"
63#include "request.h" 63#include "request.h"
64#include "sata.h"
65#include "task.h" 64#include "task.h"
66#include "host.h" 65#include "host.h"
67 66
@@ -238,6 +237,46 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
238 return 0; 237 return 0;
239} 238}
240 239
240static enum sci_status isci_sata_management_task_request_build(struct isci_request *ireq)
241{
242 struct isci_tmf *isci_tmf;
243 enum sci_status status;
244
245 if (tmf_task != ireq->ttype)
246 return SCI_FAILURE;
247
248 isci_tmf = isci_request_access_tmf(ireq);
249
250 switch (isci_tmf->tmf_code) {
251
252 case isci_tmf_sata_srst_high:
253 case isci_tmf_sata_srst_low: {
254 struct host_to_dev_fis *fis = &ireq->stp.cmd;
255
256 memset(fis, 0, sizeof(*fis));
257
258 fis->fis_type = 0x27;
259 fis->flags &= ~0x80;
260 fis->flags &= 0xF0;
261 if (isci_tmf->tmf_code == isci_tmf_sata_srst_high)
262 fis->control |= ATA_SRST;
263 else
264 fis->control &= ~ATA_SRST;
265 break;
266 }
267 /* other management commnd go here... */
268 default:
269 return SCI_FAILURE;
270 }
271
272 /* core builds the protocol specific request
273 * based on the h2d fis.
274 */
275 status = sci_task_request_construct_sata(ireq);
276
277 return status;
278}
279
241static struct isci_request *isci_task_request_build(struct isci_host *ihost, 280static struct isci_request *isci_task_request_build(struct isci_host *ihost,
242 struct isci_remote_device *idev, 281 struct isci_remote_device *idev,
243 u16 tag, struct isci_tmf *isci_tmf) 282 u16 tag, struct isci_tmf *isci_tmf)
@@ -287,9 +326,9 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost,
287 return ireq; 326 return ireq;
288} 327}
289 328
290int isci_task_execute_tmf(struct isci_host *ihost, 329static int isci_task_execute_tmf(struct isci_host *ihost,
291 struct isci_remote_device *idev, 330 struct isci_remote_device *idev,
292 struct isci_tmf *tmf, unsigned long timeout_ms) 331 struct isci_tmf *tmf, unsigned long timeout_ms)
293{ 332{
294 DECLARE_COMPLETION_ONSTACK(completion); 333 DECLARE_COMPLETION_ONSTACK(completion);
295 enum sci_task_status status = SCI_TASK_FAILURE; 334 enum sci_task_status status = SCI_TASK_FAILURE;
@@ -401,13 +440,12 @@ int isci_task_execute_tmf(struct isci_host *ihost,
401 return ret; 440 return ret;
402} 441}
403 442
404void isci_task_build_tmf( 443static void isci_task_build_tmf(struct isci_tmf *tmf,
405 struct isci_tmf *tmf, 444 enum isci_tmf_function_codes code,
406 enum isci_tmf_function_codes code, 445 void (*tmf_sent_cb)(enum isci_tmf_cb_state,
407 void (*tmf_sent_cb)(enum isci_tmf_cb_state, 446 struct isci_tmf *,
408 struct isci_tmf *, 447 void *),
409 void *), 448 void *cb_data)
410 void *cb_data)
411{ 449{
412 memset(tmf, 0, sizeof(*tmf)); 450 memset(tmf, 0, sizeof(*tmf));
413 451
@@ -416,16 +454,14 @@ void isci_task_build_tmf(
416 tmf->cb_data = cb_data; 454 tmf->cb_data = cb_data;
417} 455}
418 456
419static void isci_task_build_abort_task_tmf( 457static void isci_task_build_abort_task_tmf(struct isci_tmf *tmf,
420 struct isci_tmf *tmf, 458 enum isci_tmf_function_codes code,
421 enum isci_tmf_function_codes code, 459 void (*tmf_sent_cb)(enum isci_tmf_cb_state,
422 void (*tmf_sent_cb)(enum isci_tmf_cb_state, 460 struct isci_tmf *,
423 struct isci_tmf *, 461 void *),
424 void *), 462 struct isci_request *old_request)
425 struct isci_request *old_request)
426{ 463{
427 isci_task_build_tmf(tmf, code, tmf_sent_cb, 464 isci_task_build_tmf(tmf, code, tmf_sent_cb, old_request);
428 (void *)old_request);
429 tmf->io_tag = old_request->io_tag; 465 tmf->io_tag = old_request->io_tag;
430} 466}
431 467
@@ -804,6 +840,30 @@ static int isci_task_send_lu_reset_sas(
804 return ret; 840 return ret;
805} 841}
806 842
843static int isci_task_send_lu_reset_sata(struct isci_host *ihost,
844 struct isci_remote_device *idev, u8 *lun)
845{
846 int ret = TMF_RESP_FUNC_FAILED;
847 struct isci_tmf tmf;
848
849 /* Send the soft reset to the target */
850 #define ISCI_SRST_TIMEOUT_MS 25000 /* 25 second timeout. */
851 isci_task_build_tmf(&tmf, isci_tmf_sata_srst_high, NULL, NULL);
852
853 ret = isci_task_execute_tmf(ihost, idev, &tmf, ISCI_SRST_TIMEOUT_MS);
854
855 if (ret != TMF_RESP_FUNC_COMPLETE) {
856 dev_warn(&ihost->pdev->dev,
857 "%s: Assert SRST failed (%p) = %x",
858 __func__, idev, ret);
859
860 /* Return the failure so that the LUN reset is escalated
861 * to a target reset.
862 */
863 }
864 return ret;
865}
866
807/** 867/**
808 * isci_task_lu_reset() - This function is one of the SAS Domain Template 868 * isci_task_lu_reset() - This function is one of the SAS Domain Template
809 * functions. This is one of the Task Management functoins called by libsas, 869 * functions. This is one of the Task Management functoins called by libsas,