1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <linux/spinlock.h>
28#include "aic94xx.h"
29#include "aic94xx_sas.h"
30#include "aic94xx_hwi.h"
31
32
33
34static int asd_enqueue_internal(struct asd_ascb *ascb,
35 void (*tasklet_complete)(struct asd_ascb *,
36 struct done_list_struct *),
37 void (*timed_out)(unsigned long))
38{
39 int res;
40
41 ascb->tasklet_complete = tasklet_complete;
42 ascb->uldd_timer = 1;
43
44 ascb->timer.data = (unsigned long) ascb;
45 ascb->timer.function = timed_out;
46 ascb->timer.expires = jiffies + AIC94XX_SCB_TIMEOUT;
47
48 add_timer(&ascb->timer);
49
50 res = asd_post_ascb_list(ascb->ha, ascb, 1);
51 if (unlikely(res))
52 del_timer(&ascb->timer);
53 return res;
54}
55
56
57
58struct tasklet_completion_status {
59 int dl_opcode;
60 int tmf_state;
61 u8 tag_valid:1;
62 __be16 tag;
63};
64
65#define DECLARE_TCS(tcs) \
66 struct tasklet_completion_status tcs = { \
67 .dl_opcode = 0, \
68 .tmf_state = 0, \
69 .tag_valid = 0, \
70 .tag = 0, \
71 }
72
73
74static void asd_clear_nexus_tasklet_complete(struct asd_ascb *ascb,
75 struct done_list_struct *dl)
76{
77 struct tasklet_completion_status *tcs = ascb->uldd_task;
78 ASD_DPRINTK("%s: here\n", __func__);
79 if (!del_timer(&ascb->timer)) {
80 ASD_DPRINTK("%s: couldn't delete timer\n", __func__);
81 return;
82 }
83 ASD_DPRINTK("%s: opcode: 0x%x\n", __func__, dl->opcode);
84 tcs->dl_opcode = dl->opcode;
85 complete(ascb->completion);
86 asd_ascb_free(ascb);
87}
88
89static void asd_clear_nexus_timedout(unsigned long data)
90{
91 struct asd_ascb *ascb = (void *)data;
92 struct tasklet_completion_status *tcs = ascb->uldd_task;
93
94 ASD_DPRINTK("%s: here\n", __func__);
95 tcs->dl_opcode = TMF_RESP_FUNC_FAILED;
96 complete(ascb->completion);
97}
98
99#define CLEAR_NEXUS_PRE \
100 struct asd_ascb *ascb; \
101 struct scb *scb; \
102 int res; \
103 DECLARE_COMPLETION_ONSTACK(completion); \
104 DECLARE_TCS(tcs); \
105 \
106 ASD_DPRINTK("%s: PRE\n", __func__); \
107 res = 1; \
108 ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL); \
109 if (!ascb) \
110 return -ENOMEM; \
111 \
112 ascb->completion = &completion; \
113 ascb->uldd_task = &tcs; \
114 scb = ascb->scb; \
115 scb->header.opcode = CLEAR_NEXUS
116
117#define CLEAR_NEXUS_POST \
118 ASD_DPRINTK("%s: POST\n", __func__); \
119 res = asd_enqueue_internal(ascb, asd_clear_nexus_tasklet_complete, \
120 asd_clear_nexus_timedout); \
121 if (res) \
122 goto out_err; \
123 ASD_DPRINTK("%s: clear nexus posted, waiting...\n", __func__); \
124 wait_for_completion(&completion); \
125 res = tcs.dl_opcode; \
126 if (res == TC_NO_ERROR) \
127 res = TMF_RESP_FUNC_COMPLETE; \
128 return res; \
129out_err: \
130 asd_ascb_free(ascb); \
131 return res
132
133int asd_clear_nexus_ha(struct sas_ha_struct *sas_ha)
134{
135 struct asd_ha_struct *asd_ha = sas_ha->lldd_ha;
136
137 CLEAR_NEXUS_PRE;
138 scb->clear_nexus.nexus = NEXUS_ADAPTER;
139 CLEAR_NEXUS_POST;
140}
141
142int asd_clear_nexus_port(struct asd_sas_port *port)
143{
144 struct asd_ha_struct *asd_ha = port->ha->lldd_ha;
145
146 CLEAR_NEXUS_PRE;
147 scb->clear_nexus.nexus = NEXUS_PORT;
148 scb->clear_nexus.conn_mask = port->phy_mask;
149 CLEAR_NEXUS_POST;
150}
151
152enum clear_nexus_phase {
153 NEXUS_PHASE_PRE,
154 NEXUS_PHASE_POST,
155 NEXUS_PHASE_RESUME,
156};
157
158static int asd_clear_nexus_I_T(struct domain_device *dev,
159 enum clear_nexus_phase phase)
160{
161 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
162
163 CLEAR_NEXUS_PRE;
164 scb->clear_nexus.nexus = NEXUS_I_T;
165 switch (phase) {
166 case NEXUS_PHASE_PRE:
167 scb->clear_nexus.flags = EXEC_Q | SUSPEND_TX;
168 break;
169 case NEXUS_PHASE_POST:
170 scb->clear_nexus.flags = SEND_Q | NOTINQ;
171 break;
172 case NEXUS_PHASE_RESUME:
173 scb->clear_nexus.flags = RESUME_TX;
174 }
175 scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
176 dev->lldd_dev);
177 CLEAR_NEXUS_POST;
178}
179
180int asd_I_T_nexus_reset(struct domain_device *dev)
181{
182 int res, tmp_res, i;
183 struct sas_phy *phy = sas_find_local_phy(dev);
184
185
186 int reset_type = (dev->dev_type == SATA_DEV ||
187 (dev->tproto & SAS_PROTOCOL_STP)) ? 0 : 1;
188
189 asd_clear_nexus_I_T(dev, NEXUS_PHASE_PRE);
190
191 ASD_DPRINTK("sending %s reset to %s\n",
192 reset_type ? "hard" : "soft", dev_name(&phy->dev));
193 res = sas_phy_reset(phy, reset_type);
194 if (res == TMF_RESP_FUNC_COMPLETE) {
195
196 msleep(500);
197
198 asd_clear_nexus_I_T(dev, NEXUS_PHASE_POST);
199 }
200 for (i = 0 ; i < 3; i++) {
201 tmp_res = asd_clear_nexus_I_T(dev, NEXUS_PHASE_RESUME);
202 if (tmp_res == TC_RESUME)
203 return res;
204 msleep(500);
205 }
206
207
208
209
210 dev_printk(KERN_ERR, &phy->dev,
211 "Failed to resume nexus after reset 0x%x\n", tmp_res);
212
213 return TMF_RESP_FUNC_FAILED;
214}
215
216static int asd_clear_nexus_I_T_L(struct domain_device *dev, u8 *lun)
217{
218 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
219
220 CLEAR_NEXUS_PRE;
221 scb->clear_nexus.nexus = NEXUS_I_T_L;
222 scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ;
223 memcpy(scb->clear_nexus.ssp_task.lun, lun, 8);
224 scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
225 dev->lldd_dev);
226 CLEAR_NEXUS_POST;
227}
228
229static int asd_clear_nexus_tag(struct sas_task *task)
230{
231 struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
232 struct asd_ascb *tascb = task->lldd_task;
233
234 CLEAR_NEXUS_PRE;
235 scb->clear_nexus.nexus = NEXUS_TAG;
236 memcpy(scb->clear_nexus.ssp_task.lun, task->ssp_task.LUN, 8);
237 scb->clear_nexus.ssp_task.tag = tascb->tag;
238 if (task->dev->tproto)
239 scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
240 task->dev->lldd_dev);
241 CLEAR_NEXUS_POST;
242}
243
244static int asd_clear_nexus_index(struct sas_task *task)
245{
246 struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
247 struct asd_ascb *tascb = task->lldd_task;
248
249 CLEAR_NEXUS_PRE;
250 scb->clear_nexus.nexus = NEXUS_TRANS_CX;
251 if (task->dev->tproto)
252 scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
253 task->dev->lldd_dev);
254 scb->clear_nexus.index = cpu_to_le16(tascb->tc_index);
255 CLEAR_NEXUS_POST;
256}
257
258
259
260static void asd_tmf_timedout(unsigned long data)
261{
262 struct asd_ascb *ascb = (void *) data;
263 struct tasklet_completion_status *tcs = ascb->uldd_task;
264
265 ASD_DPRINTK("tmf timed out\n");
266 tcs->tmf_state = TMF_RESP_FUNC_FAILED;
267 complete(ascb->completion);
268}
269
270static int asd_get_tmf_resp_tasklet(struct asd_ascb *ascb,
271 struct done_list_struct *dl)
272{
273 struct asd_ha_struct *asd_ha = ascb->ha;
274 unsigned long flags;
275 struct tc_resp_sb_struct {
276 __le16 index_escb;
277 u8 len_lsb;
278 u8 flags;
279 } __attribute__ ((packed)) *resp_sb = (void *) dl->status_block;
280
281 int edb_id = ((resp_sb->flags & 0x70) >> 4)-1;
282 struct asd_ascb *escb;
283 struct asd_dma_tok *edb;
284 struct ssp_frame_hdr *fh;
285 struct ssp_response_iu *ru;
286 int res = TMF_RESP_FUNC_FAILED;
287
288 ASD_DPRINTK("tmf resp tasklet\n");
289
290 spin_lock_irqsave(&asd_ha->seq.tc_index_lock, flags);
291 escb = asd_tc_index_find(&asd_ha->seq,
292 (int)le16_to_cpu(resp_sb->index_escb));
293 spin_unlock_irqrestore(&asd_ha->seq.tc_index_lock, flags);
294
295 if (!escb) {
296 ASD_DPRINTK("Uh-oh! No escb for this dl?!\n");
297 return res;
298 }
299
300 edb = asd_ha->seq.edb_arr[edb_id + escb->edb_index];
301 ascb->tag = *(__be16 *)(edb->vaddr+4);
302 fh = edb->vaddr + 16;
303 ru = edb->vaddr + 16 + sizeof(*fh);
304 res = ru->status;
305 if (ru->datapres == 1)
306 res = ru->resp_data[3];
307#if 0
308 ascb->tag = fh->tag;
309#endif
310 ascb->tag_valid = 1;
311
312 asd_invalidate_edb(escb, edb_id);
313 return res;
314}
315
316static void asd_tmf_tasklet_complete(struct asd_ascb *ascb,
317 struct done_list_struct *dl)
318{
319 struct tasklet_completion_status *tcs;
320
321 if (!del_timer(&ascb->timer))
322 return;
323
324 tcs = ascb->uldd_task;
325 ASD_DPRINTK("tmf tasklet complete\n");
326
327 tcs->dl_opcode = dl->opcode;
328
329 if (dl->opcode == TC_SSP_RESP) {
330 tcs->tmf_state = asd_get_tmf_resp_tasklet(ascb, dl);
331 tcs->tag_valid = ascb->tag_valid;
332 tcs->tag = ascb->tag;
333 }
334
335 complete(ascb->completion);
336 asd_ascb_free(ascb);
337}
338
339static int asd_clear_nexus(struct sas_task *task)
340{
341 int res = TMF_RESP_FUNC_FAILED;
342 int leftover;
343 struct asd_ascb *tascb = task->lldd_task;
344 DECLARE_COMPLETION_ONSTACK(completion);
345 unsigned long flags;
346
347 tascb->completion = &completion;
348
349 ASD_DPRINTK("task not done, clearing nexus\n");
350 if (tascb->tag_valid)
351 res = asd_clear_nexus_tag(task);
352 else
353 res = asd_clear_nexus_index(task);
354 leftover = wait_for_completion_timeout(&completion,
355 AIC94XX_SCB_TIMEOUT);
356 tascb->completion = NULL;
357 ASD_DPRINTK("came back from clear nexus\n");
358 spin_lock_irqsave(&task->task_state_lock, flags);
359 if (leftover < 1)
360 res = TMF_RESP_FUNC_FAILED;
361 if (task->task_state_flags & SAS_TASK_STATE_DONE)
362 res = TMF_RESP_FUNC_COMPLETE;
363 spin_unlock_irqrestore(&task->task_state_lock, flags);
364
365 return res;
366}
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401int asd_abort_task(struct sas_task *task)
402{
403 struct asd_ascb *tascb = task->lldd_task;
404 struct asd_ha_struct *asd_ha = tascb->ha;
405 int res = 1;
406 unsigned long flags;
407 struct asd_ascb *ascb = NULL;
408 struct scb *scb;
409 int leftover;
410 DECLARE_TCS(tcs);
411 DECLARE_COMPLETION_ONSTACK(completion);
412 DECLARE_COMPLETION_ONSTACK(tascb_completion);
413
414 tascb->completion = &tascb_completion;
415
416 spin_lock_irqsave(&task->task_state_lock, flags);
417 if (task->task_state_flags & SAS_TASK_STATE_DONE) {
418 spin_unlock_irqrestore(&task->task_state_lock, flags);
419 res = TMF_RESP_FUNC_COMPLETE;
420 ASD_DPRINTK("%s: task 0x%p done\n", __func__, task);
421 goto out_done;
422 }
423 spin_unlock_irqrestore(&task->task_state_lock, flags);
424
425 ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL);
426 if (!ascb)
427 return -ENOMEM;
428
429 ascb->uldd_task = &tcs;
430 ascb->completion = &completion;
431 scb = ascb->scb;
432 scb->header.opcode = SCB_ABORT_TASK;
433
434 switch (task->task_proto) {
435 case SAS_PROTOCOL_SATA:
436 case SAS_PROTOCOL_STP:
437 scb->abort_task.proto_conn_rate = (1 << 5);
438 break;
439 case SAS_PROTOCOL_SSP:
440 scb->abort_task.proto_conn_rate = (1 << 4);
441 scb->abort_task.proto_conn_rate |= task->dev->linkrate;
442 break;
443 case SAS_PROTOCOL_SMP:
444 break;
445 default:
446 break;
447 }
448
449 if (task->task_proto == SAS_PROTOCOL_SSP) {
450 scb->abort_task.ssp_frame.frame_type = SSP_TASK;
451 memcpy(scb->abort_task.ssp_frame.hashed_dest_addr,
452 task->dev->hashed_sas_addr, HASHED_SAS_ADDR_SIZE);
453 memcpy(scb->abort_task.ssp_frame.hashed_src_addr,
454 task->dev->port->ha->hashed_sas_addr,
455 HASHED_SAS_ADDR_SIZE);
456 scb->abort_task.ssp_frame.tptt = cpu_to_be16(0xFFFF);
457
458 memcpy(scb->abort_task.ssp_task.lun, task->ssp_task.LUN, 8);
459 scb->abort_task.ssp_task.tmf = TMF_ABORT_TASK;
460 scb->abort_task.ssp_task.tag = cpu_to_be16(0xFFFF);
461 }
462
463 scb->abort_task.sister_scb = cpu_to_le16(0xFFFF);
464 scb->abort_task.conn_handle = cpu_to_le16(
465 (u16)(unsigned long)task->dev->lldd_dev);
466 scb->abort_task.retry_count = 1;
467 scb->abort_task.index = cpu_to_le16((u16)tascb->tc_index);
468 scb->abort_task.itnl_to = cpu_to_le16(ITNL_TIMEOUT_CONST);
469
470 res = asd_enqueue_internal(ascb, asd_tmf_tasklet_complete,
471 asd_tmf_timedout);
472 if (res)
473 goto out_free;
474 wait_for_completion(&completion);
475 ASD_DPRINTK("tmf came back\n");
476
477 tascb->tag = tcs.tag;
478 tascb->tag_valid = tcs.tag_valid;
479
480 spin_lock_irqsave(&task->task_state_lock, flags);
481 if (task->task_state_flags & SAS_TASK_STATE_DONE) {
482 spin_unlock_irqrestore(&task->task_state_lock, flags);
483 res = TMF_RESP_FUNC_COMPLETE;
484 ASD_DPRINTK("%s: task 0x%p done\n", __func__, task);
485 goto out_done;
486 }
487 spin_unlock_irqrestore(&task->task_state_lock, flags);
488
489 if (tcs.dl_opcode == TC_SSP_RESP) {
490
491
492 if (tcs.tmf_state == TMF_RESP_FUNC_COMPLETE)
493 res = asd_clear_nexus(task);
494 else
495 res = tcs.tmf_state;
496 } else if (tcs.dl_opcode == TC_NO_ERROR &&
497 tcs.tmf_state == TMF_RESP_FUNC_FAILED) {
498
499 res = TMF_RESP_FUNC_FAILED;
500 } else {
501
502
503
504
505 switch (tcs.dl_opcode) {
506 default:
507 res = asd_clear_nexus(task);
508
509 case TC_NO_ERROR:
510 break;
511
512
513
514
515 case TF_NAK_RECV:
516 res = TMF_RESP_INVALID_FRAME;
517 break;
518 case TF_TMF_TASK_DONE:
519 res = TMF_RESP_FUNC_FAILED;
520 leftover =
521 wait_for_completion_timeout(&tascb_completion,
522 AIC94XX_SCB_TIMEOUT);
523 spin_lock_irqsave(&task->task_state_lock, flags);
524 if (leftover < 1)
525 res = TMF_RESP_FUNC_FAILED;
526 if (task->task_state_flags & SAS_TASK_STATE_DONE)
527 res = TMF_RESP_FUNC_COMPLETE;
528 spin_unlock_irqrestore(&task->task_state_lock, flags);
529 break;
530 case TF_TMF_NO_TAG:
531 case TF_TMF_TAG_FREE:
532 case TF_TMF_NO_CONN_HANDLE:
533 res = TMF_RESP_FUNC_COMPLETE;
534 break;
535 case TF_TMF_NO_CTX:
536 res = TMF_RESP_FUNC_ESUPP;
537 break;
538 }
539 }
540 out_done:
541 tascb->completion = NULL;
542 if (res == TMF_RESP_FUNC_COMPLETE) {
543 task->lldd_task = NULL;
544 mb();
545 asd_ascb_free(tascb);
546 }
547 ASD_DPRINTK("task 0x%p aborted, res: 0x%x\n", task, res);
548 return res;
549
550 out_free:
551 asd_ascb_free(ascb);
552 ASD_DPRINTK("task 0x%p aborted, res: 0x%x\n", task, res);
553 return res;
554}
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571static int asd_initiate_ssp_tmf(struct domain_device *dev, u8 *lun,
572 int tmf, int index)
573{
574 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
575 struct asd_ascb *ascb;
576 int res = 1;
577 struct scb *scb;
578 DECLARE_COMPLETION_ONSTACK(completion);
579 DECLARE_TCS(tcs);
580
581 if (!(dev->tproto & SAS_PROTOCOL_SSP))
582 return TMF_RESP_FUNC_ESUPP;
583
584 ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL);
585 if (!ascb)
586 return -ENOMEM;
587
588 ascb->completion = &completion;
589 ascb->uldd_task = &tcs;
590 scb = ascb->scb;
591
592 if (tmf == TMF_QUERY_TASK)
593 scb->header.opcode = QUERY_SSP_TASK;
594 else
595 scb->header.opcode = INITIATE_SSP_TMF;
596
597 scb->ssp_tmf.proto_conn_rate = (1 << 4);
598 scb->ssp_tmf.proto_conn_rate |= dev->linkrate;
599
600 scb->ssp_tmf.ssp_frame.frame_type = SSP_TASK;
601 memcpy(scb->ssp_tmf.ssp_frame.hashed_dest_addr,
602 dev->hashed_sas_addr, HASHED_SAS_ADDR_SIZE);
603 memcpy(scb->ssp_tmf.ssp_frame.hashed_src_addr,
604 dev->port->ha->hashed_sas_addr, HASHED_SAS_ADDR_SIZE);
605 scb->ssp_tmf.ssp_frame.tptt = cpu_to_be16(0xFFFF);
606
607 memcpy(scb->ssp_tmf.ssp_task.lun, lun, 8);
608 scb->ssp_tmf.ssp_task.tmf = tmf;
609
610 scb->ssp_tmf.sister_scb = cpu_to_le16(0xFFFF);
611 scb->ssp_tmf.conn_handle= cpu_to_le16((u16)(unsigned long)
612 dev->lldd_dev);
613 scb->ssp_tmf.retry_count = 1;
614 scb->ssp_tmf.itnl_to = cpu_to_le16(ITNL_TIMEOUT_CONST);
615 if (tmf == TMF_QUERY_TASK)
616 scb->ssp_tmf.index = cpu_to_le16(index);
617
618 res = asd_enqueue_internal(ascb, asd_tmf_tasklet_complete,
619 asd_tmf_timedout);
620 if (res)
621 goto out_err;
622 wait_for_completion(&completion);
623
624 switch (tcs.dl_opcode) {
625 case TC_NO_ERROR:
626 res = TMF_RESP_FUNC_COMPLETE;
627 break;
628 case TF_NAK_RECV:
629 res = TMF_RESP_INVALID_FRAME;
630 break;
631 case TF_TMF_TASK_DONE:
632 res = TMF_RESP_FUNC_FAILED;
633 break;
634 case TF_TMF_NO_TAG:
635 case TF_TMF_TAG_FREE:
636 case TF_TMF_NO_CONN_HANDLE:
637 res = TMF_RESP_FUNC_COMPLETE;
638 break;
639 case TF_TMF_NO_CTX:
640 res = TMF_RESP_FUNC_ESUPP;
641 break;
642 default:
643
644 res = tcs.dl_opcode;
645 break;
646 }
647 return res;
648out_err:
649 asd_ascb_free(ascb);
650 return res;
651}
652
653int asd_abort_task_set(struct domain_device *dev, u8 *lun)
654{
655 int res = asd_initiate_ssp_tmf(dev, lun, TMF_ABORT_TASK_SET, 0);
656
657 if (res == TMF_RESP_FUNC_COMPLETE)
658 asd_clear_nexus_I_T_L(dev, lun);
659 return res;
660}
661
662int asd_clear_aca(struct domain_device *dev, u8 *lun)
663{
664 int res = asd_initiate_ssp_tmf(dev, lun, TMF_CLEAR_ACA, 0);
665
666 if (res == TMF_RESP_FUNC_COMPLETE)
667 asd_clear_nexus_I_T_L(dev, lun);
668 return res;
669}
670
671int asd_clear_task_set(struct domain_device *dev, u8 *lun)
672{
673 int res = asd_initiate_ssp_tmf(dev, lun, TMF_CLEAR_TASK_SET, 0);
674
675 if (res == TMF_RESP_FUNC_COMPLETE)
676 asd_clear_nexus_I_T_L(dev, lun);
677 return res;
678}
679
680int asd_lu_reset(struct domain_device *dev, u8 *lun)
681{
682 int res = asd_initiate_ssp_tmf(dev, lun, TMF_LU_RESET, 0);
683
684 if (res == TMF_RESP_FUNC_COMPLETE)
685 asd_clear_nexus_I_T_L(dev, lun);
686 return res;
687}
688
689
690
691
692
693
694
695
696
697
698
699int asd_query_task(struct sas_task *task)
700{
701 struct asd_ascb *ascb = task->lldd_task;
702 int index;
703
704 if (ascb) {
705 index = ascb->tc_index;
706 return asd_initiate_ssp_tmf(task->dev, task->ssp_task.LUN,
707 TMF_QUERY_TASK, index);
708 }
709 return TMF_RESP_FUNC_COMPLETE;
710}
711