Lines Matching +full:tcs +full:- +full:wait

1 // SPDX-License-Identifier: GPL-2.0-only
15 /* ---------- Internal enqueue ---------- */
24 ascb->tasklet_complete = tasklet_complete; in asd_enqueue_internal()
25 ascb->uldd_timer = 1; in asd_enqueue_internal()
27 ascb->timer.function = timed_out; in asd_enqueue_internal()
28 ascb->timer.expires = jiffies + AIC94XX_SCB_TIMEOUT; in asd_enqueue_internal()
30 add_timer(&ascb->timer); in asd_enqueue_internal()
32 res = asd_post_ascb_list(ascb->ha, ascb, 1); in asd_enqueue_internal()
34 del_timer(&ascb->timer); in asd_enqueue_internal()
38 /* ---------- CLEAR NEXUS ---------- */
47 #define DECLARE_TCS(tcs) \ argument
48 struct tasklet_completion_status tcs = { \
59 struct tasklet_completion_status *tcs = ascb->uldd_task; in asd_clear_nexus_tasklet_complete() local
61 if (!del_timer(&ascb->timer)) { in asd_clear_nexus_tasklet_complete()
65 ASD_DPRINTK("%s: opcode: 0x%x\n", __func__, dl->opcode); in asd_clear_nexus_tasklet_complete()
66 tcs->dl_opcode = dl->opcode; in asd_clear_nexus_tasklet_complete()
67 complete(ascb->completion); in asd_clear_nexus_tasklet_complete()
74 struct tasklet_completion_status *tcs = ascb->uldd_task; in asd_clear_nexus_timedout() local
77 tcs->dl_opcode = TMF_RESP_FUNC_FAILED; in asd_clear_nexus_timedout()
78 complete(ascb->completion); in asd_clear_nexus_timedout()
86 DECLARE_TCS(tcs); \
92 return -ENOMEM; \
94 ascb->completion = &completion; \
95 ascb->uldd_task = &tcs; \
96 scb = ascb->scb; \
97 scb->header.opcode = CLEAR_NEXUS
107 res = tcs.dl_opcode; \
117 struct asd_ha_struct *asd_ha = sas_ha->lldd_ha; in asd_clear_nexus_ha()
120 scb->clear_nexus.nexus = NEXUS_ADAPTER; in asd_clear_nexus_ha()
126 struct asd_ha_struct *asd_ha = port->ha->lldd_ha; in asd_clear_nexus_port()
129 scb->clear_nexus.nexus = NEXUS_PORT; in asd_clear_nexus_port()
130 scb->clear_nexus.conn_mask = port->phy_mask; in asd_clear_nexus_port()
143 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; in asd_clear_nexus_I_T()
146 scb->clear_nexus.nexus = NEXUS_I_T; in asd_clear_nexus_I_T()
149 scb->clear_nexus.flags = EXEC_Q | SUSPEND_TX; in asd_clear_nexus_I_T()
152 scb->clear_nexus.flags = SEND_Q | NOTINQ; in asd_clear_nexus_I_T()
155 scb->clear_nexus.flags = RESUME_TX; in asd_clear_nexus_I_T()
157 scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long) in asd_clear_nexus_I_T()
158 dev->lldd_dev); in asd_clear_nexus_I_T()
168 int reset_type = (dev->dev_type == SAS_SATA_DEV || in asd_I_T_nexus_reset()
169 (dev->tproto & SAS_PROTOCOL_STP)) ? 0 : 1; in asd_I_T_nexus_reset()
174 reset_type ? "hard" : "soft", dev_name(&phy->dev)); in asd_I_T_nexus_reset()
176 if (res == TMF_RESP_FUNC_COMPLETE || res == -ENODEV) { in asd_I_T_nexus_reset()
177 /* wait for the maximum settle time */ in asd_I_T_nexus_reset()
192 dev_printk(KERN_ERR, &phy->dev, in asd_I_T_nexus_reset()
203 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; in asd_clear_nexus_I_T_L()
206 scb->clear_nexus.nexus = NEXUS_I_T_L; in asd_clear_nexus_I_T_L()
207 scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ; in asd_clear_nexus_I_T_L()
208 memcpy(scb->clear_nexus.ssp_task.lun, lun, 8); in asd_clear_nexus_I_T_L()
209 scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long) in asd_clear_nexus_I_T_L()
210 dev->lldd_dev); in asd_clear_nexus_I_T_L()
216 struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha; in asd_clear_nexus_tag()
217 struct asd_ascb *tascb = task->lldd_task; in asd_clear_nexus_tag()
220 scb->clear_nexus.nexus = NEXUS_TAG; in asd_clear_nexus_tag()
221 memcpy(scb->clear_nexus.ssp_task.lun, task->ssp_task.LUN, 8); in asd_clear_nexus_tag()
222 scb->clear_nexus.ssp_task.tag = tascb->tag; in asd_clear_nexus_tag()
223 if (task->dev->tproto) in asd_clear_nexus_tag()
224 scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long) in asd_clear_nexus_tag()
225 task->dev->lldd_dev); in asd_clear_nexus_tag()
231 struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha; in asd_clear_nexus_index()
232 struct asd_ascb *tascb = task->lldd_task; in asd_clear_nexus_index()
235 scb->clear_nexus.nexus = NEXUS_TRANS_CX; in asd_clear_nexus_index()
236 if (task->dev->tproto) in asd_clear_nexus_index()
237 scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long) in asd_clear_nexus_index()
238 task->dev->lldd_dev); in asd_clear_nexus_index()
239 scb->clear_nexus.index = cpu_to_le16(tascb->tc_index); in asd_clear_nexus_index()
243 /* ---------- TMFs ---------- */
248 struct tasklet_completion_status *tcs = ascb->uldd_task; in asd_tmf_timedout() local
251 tcs->tmf_state = TMF_RESP_FUNC_FAILED; in asd_tmf_timedout()
252 complete(ascb->completion); in asd_tmf_timedout()
258 struct asd_ha_struct *asd_ha = ascb->ha; in asd_get_tmf_resp_tasklet()
264 } __attribute__ ((packed)) *resp_sb = (void *) dl->status_block; in asd_get_tmf_resp_tasklet()
266 int edb_id = ((resp_sb->flags & 0x70) >> 4)-1; in asd_get_tmf_resp_tasklet()
275 spin_lock_irqsave(&asd_ha->seq.tc_index_lock, flags); in asd_get_tmf_resp_tasklet()
276 escb = asd_tc_index_find(&asd_ha->seq, in asd_get_tmf_resp_tasklet()
277 (int)le16_to_cpu(resp_sb->index_escb)); in asd_get_tmf_resp_tasklet()
278 spin_unlock_irqrestore(&asd_ha->seq.tc_index_lock, flags); in asd_get_tmf_resp_tasklet()
281 ASD_DPRINTK("Uh-oh! No escb for this dl?!\n"); in asd_get_tmf_resp_tasklet()
285 edb = asd_ha->seq.edb_arr[edb_id + escb->edb_index]; in asd_get_tmf_resp_tasklet()
286 ascb->tag = *(__be16 *)(edb->vaddr+4); in asd_get_tmf_resp_tasklet()
287 fh = edb->vaddr + 16; in asd_get_tmf_resp_tasklet()
288 ru = edb->vaddr + 16 + sizeof(*fh); in asd_get_tmf_resp_tasklet()
289 res = ru->status; in asd_get_tmf_resp_tasklet()
290 if (ru->datapres == 1) /* Response data present */ in asd_get_tmf_resp_tasklet()
291 res = ru->resp_data[3]; in asd_get_tmf_resp_tasklet()
293 ascb->tag = fh->tag; in asd_get_tmf_resp_tasklet()
295 ascb->tag_valid = 1; in asd_get_tmf_resp_tasklet()
304 struct tasklet_completion_status *tcs; in asd_tmf_tasklet_complete() local
306 if (!del_timer(&ascb->timer)) in asd_tmf_tasklet_complete()
309 tcs = ascb->uldd_task; in asd_tmf_tasklet_complete()
312 tcs->dl_opcode = dl->opcode; in asd_tmf_tasklet_complete()
314 if (dl->opcode == TC_SSP_RESP) { in asd_tmf_tasklet_complete()
315 tcs->tmf_state = asd_get_tmf_resp_tasklet(ascb, dl); in asd_tmf_tasklet_complete()
316 tcs->tag_valid = ascb->tag_valid; in asd_tmf_tasklet_complete()
317 tcs->tag = ascb->tag; in asd_tmf_tasklet_complete()
320 complete(ascb->completion); in asd_tmf_tasklet_complete()
328 struct asd_ascb *tascb = task->lldd_task; in asd_clear_nexus()
332 tascb->completion = &completion; in asd_clear_nexus()
335 if (tascb->tag_valid) in asd_clear_nexus()
341 tascb->completion = NULL; in asd_clear_nexus()
343 spin_lock_irqsave(&task->task_state_lock, flags); in asd_clear_nexus()
346 if (task->task_state_flags & SAS_TASK_STATE_DONE) in asd_clear_nexus()
348 spin_unlock_irqrestore(&task->task_state_lock, flags); in asd_clear_nexus()
354 * asd_abort_task -- ABORT TASK TMF
363 * -ENOMEM,
364 * -SAS_QUEUE_FULL.
367 * task->task_state_flags, and then the return value of ABORT TASK.
371 * caller of ABORT TASK has responsibility to call task->task_done()
378 * ABORT TASK has responsibility to call task->task_done()
388 struct asd_ascb *tascb = task->lldd_task; in asd_abort_task()
389 struct asd_ha_struct *asd_ha = tascb->ha; in asd_abort_task()
395 DECLARE_TCS(tcs); in asd_abort_task()
399 tascb->completion = &tascb_completion; in asd_abort_task()
401 spin_lock_irqsave(&task->task_state_lock, flags); in asd_abort_task()
402 if (task->task_state_flags & SAS_TASK_STATE_DONE) { in asd_abort_task()
403 spin_unlock_irqrestore(&task->task_state_lock, flags); in asd_abort_task()
408 spin_unlock_irqrestore(&task->task_state_lock, flags); in asd_abort_task()
412 return -ENOMEM; in asd_abort_task()
414 ascb->uldd_task = &tcs; in asd_abort_task()
415 ascb->completion = &completion; in asd_abort_task()
416 scb = ascb->scb; in asd_abort_task()
417 scb->header.opcode = SCB_ABORT_TASK; in asd_abort_task()
419 switch (task->task_proto) { in asd_abort_task()
422 scb->abort_task.proto_conn_rate = (1 << 5); /* STP */ in asd_abort_task()
425 scb->abort_task.proto_conn_rate = (1 << 4); /* SSP */ in asd_abort_task()
426 scb->abort_task.proto_conn_rate |= task->dev->linkrate; in asd_abort_task()
434 if (task->task_proto == SAS_PROTOCOL_SSP) { in asd_abort_task()
435 scb->abort_task.ssp_frame.frame_type = SSP_TASK; in asd_abort_task()
436 memcpy(scb->abort_task.ssp_frame.hashed_dest_addr, in asd_abort_task()
437 task->dev->hashed_sas_addr, HASHED_SAS_ADDR_SIZE); in asd_abort_task()
438 memcpy(scb->abort_task.ssp_frame.hashed_src_addr, in asd_abort_task()
439 task->dev->port->ha->hashed_sas_addr, in asd_abort_task()
441 scb->abort_task.ssp_frame.tptt = cpu_to_be16(0xFFFF); in asd_abort_task()
443 memcpy(scb->abort_task.ssp_task.lun, task->ssp_task.LUN, 8); in asd_abort_task()
444 scb->abort_task.ssp_task.tmf = TMF_ABORT_TASK; in asd_abort_task()
445 scb->abort_task.ssp_task.tag = cpu_to_be16(0xFFFF); in asd_abort_task()
448 scb->abort_task.sister_scb = cpu_to_le16(0xFFFF); in asd_abort_task()
449 scb->abort_task.conn_handle = cpu_to_le16( in asd_abort_task()
450 (u16)(unsigned long)task->dev->lldd_dev); in asd_abort_task()
451 scb->abort_task.retry_count = 1; in asd_abort_task()
452 scb->abort_task.index = cpu_to_le16((u16)tascb->tc_index); in asd_abort_task()
453 scb->abort_task.itnl_to = cpu_to_le16(ITNL_TIMEOUT_CONST); in asd_abort_task()
462 tascb->tag = tcs.tag; in asd_abort_task()
463 tascb->tag_valid = tcs.tag_valid; in asd_abort_task()
465 spin_lock_irqsave(&task->task_state_lock, flags); in asd_abort_task()
466 if (task->task_state_flags & SAS_TASK_STATE_DONE) { in asd_abort_task()
467 spin_unlock_irqrestore(&task->task_state_lock, flags); in asd_abort_task()
472 spin_unlock_irqrestore(&task->task_state_lock, flags); in asd_abort_task()
474 if (tcs.dl_opcode == TC_SSP_RESP) { in asd_abort_task()
477 if (tcs.tmf_state == TMF_RESP_FUNC_COMPLETE) in asd_abort_task()
480 res = tcs.tmf_state; in asd_abort_task()
481 } else if (tcs.dl_opcode == TC_NO_ERROR && in asd_abort_task()
482 tcs.tmf_state == TMF_RESP_FUNC_FAILED) { in asd_abort_task()
490 switch (tcs.dl_opcode) { in asd_abort_task()
508 spin_lock_irqsave(&task->task_state_lock, flags); in asd_abort_task()
511 if (task->task_state_flags & SAS_TASK_STATE_DONE) in asd_abort_task()
513 spin_unlock_irqrestore(&task->task_state_lock, flags); in asd_abort_task()
526 tascb->completion = NULL; in asd_abort_task()
528 task->lldd_task = NULL; in asd_abort_task()
542 * asd_initiate_ssp_tmf -- send a TMF to an I_T_L or I_T_L_Q nexus
559 struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; in asd_initiate_ssp_tmf()
564 DECLARE_TCS(tcs); in asd_initiate_ssp_tmf()
566 if (!(dev->tproto & SAS_PROTOCOL_SSP)) in asd_initiate_ssp_tmf()
571 return -ENOMEM; in asd_initiate_ssp_tmf()
573 ascb->completion = &completion; in asd_initiate_ssp_tmf()
574 ascb->uldd_task = &tcs; in asd_initiate_ssp_tmf()
575 scb = ascb->scb; in asd_initiate_ssp_tmf()
578 scb->header.opcode = QUERY_SSP_TASK; in asd_initiate_ssp_tmf()
580 scb->header.opcode = INITIATE_SSP_TMF; in asd_initiate_ssp_tmf()
582 scb->ssp_tmf.proto_conn_rate = (1 << 4); /* SSP */ in asd_initiate_ssp_tmf()
583 scb->ssp_tmf.proto_conn_rate |= dev->linkrate; in asd_initiate_ssp_tmf()
585 scb->ssp_tmf.ssp_frame.frame_type = SSP_TASK; in asd_initiate_ssp_tmf()
586 memcpy(scb->ssp_tmf.ssp_frame.hashed_dest_addr, in asd_initiate_ssp_tmf()
587 dev->hashed_sas_addr, HASHED_SAS_ADDR_SIZE); in asd_initiate_ssp_tmf()
588 memcpy(scb->ssp_tmf.ssp_frame.hashed_src_addr, in asd_initiate_ssp_tmf()
589 dev->port->ha->hashed_sas_addr, HASHED_SAS_ADDR_SIZE); in asd_initiate_ssp_tmf()
590 scb->ssp_tmf.ssp_frame.tptt = cpu_to_be16(0xFFFF); in asd_initiate_ssp_tmf()
592 memcpy(scb->ssp_tmf.ssp_task.lun, lun, 8); in asd_initiate_ssp_tmf()
593 scb->ssp_tmf.ssp_task.tmf = tmf; in asd_initiate_ssp_tmf()
595 scb->ssp_tmf.sister_scb = cpu_to_le16(0xFFFF); in asd_initiate_ssp_tmf()
596 scb->ssp_tmf.conn_handle= cpu_to_le16((u16)(unsigned long) in asd_initiate_ssp_tmf()
597 dev->lldd_dev); in asd_initiate_ssp_tmf()
598 scb->ssp_tmf.retry_count = 1; in asd_initiate_ssp_tmf()
599 scb->ssp_tmf.itnl_to = cpu_to_le16(ITNL_TIMEOUT_CONST); in asd_initiate_ssp_tmf()
601 scb->ssp_tmf.index = cpu_to_le16(index); in asd_initiate_ssp_tmf()
609 switch (tcs.dl_opcode) { in asd_initiate_ssp_tmf()
629 res = tcs.dl_opcode; in asd_initiate_ssp_tmf()
675 * asd_query_task -- send a QUERY TASK TMF to an I_T_L_Q nexus
686 struct asd_ascb *ascb = task->lldd_task; in asd_query_task()
690 index = ascb->tc_index; in asd_query_task()
691 return asd_initiate_ssp_tmf(task->dev, task->ssp_task.LUN, in asd_query_task()