41 #define PRIMITIVE_RECVD 0x08
42 #define PHY_EVENT 0x10
43 #define LINK_RESET_ERROR 0x18
44 #define TIMER_EVENT 0x20
45 #define REQ_TASK_ABORT 0xF0
46 #define REQ_DEVICE_RESET 0xF1
47 #define SIGNAL_NCQ_ERROR 0xF2
48 #define CLEAR_NCQ_ERROR 0xF3
50 #define PHY_EVENTS_STATUS (CURRENT_LOSS_OF_SIGNAL | CURRENT_OOB_DONE \
51 | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \
54 static void get_lrate_mode(
struct asd_phy *
phy,
u8 oob_mode)
58 switch (oob_mode & 7) {
85 static void asd_phy_event_tasklet(
struct asd_ascb *ascb,
101 sas_phy_disconnected(&phy->
sas_phy);
107 get_lrate_mode(phy, oob_mode);
108 ASD_DPRINTK(
"phy%d device plugged: lrate:0x%x, proto:0x%x\n",
119 ASD_DPRINTK(
"phy%d error while OOB: oob status:0x%x\n", phy_id,
122 sas_phy_disconnected(&phy->
sas_phy);
131 u8 enabled_mask = asd_ha->
hw_prof.enabled_phys;
135 if (&asd_ha->
phys[i] == phy)
156 if (phy->
sas_phy.frame_rcvd[0] == 0x34
162 addr += asd_ha->
hw_prof.sata_name_base + ord_phy(asd_ha, phy);
165 struct sas_identify_frame *idframe =
166 (
void *) phy->
sas_phy.frame_rcvd;
201 if (i >= ASD_MAX_PHYS) {
214 ASD_DPRINTK(
"%s: updating phy_mask 0x%x for phy%d\n",
215 __func__, phy->
asd_port->phy_mask, sas_phy->
id);
235 static void asd_bytes_dmaed_tasklet(
struct asd_ascb *ascb,
237 int edb_id,
int phy_id)
251 asd_get_attached_sas_addr(phy, phy->
sas_phy.attached_sas_addr);
252 spin_unlock_irqrestore(&phy->
sas_phy.frame_rcvd_lock, flags);
253 asd_dump_frame_rcvd(phy, dl);
254 asd_form_port(ascb->
ha, phy);
258 static void asd_link_reset_err_tasklet(
struct asd_ascb *ascb,
271 ASD_DPRINTK(
"phy%d: Receive ID timer expired\n", phy_id);
277 ASD_DPRINTK(
"phy%d: Loss of dword sync\n", phy_id);
280 ASD_DPRINTK(
"phy%d: Receive FIS timeout\n", phy_id);
283 ASD_DPRINTK(
"phy%d: unknown link reset error code: 0x%x\n",
289 sas_phy_disconnected(sas_phy);
290 asd_deform_port(asd_ha, phy);
293 if (retries_left == 0) {
301 ASD_DPRINTK(
"phy%d: retries:0 performing link reset seq\n",
311 static void asd_primitive_rcvd_tasklet(
struct asd_ascb *ascb,
331 ASD_DPRINTK(
"phy%d: BROADCAST change received:%d\n",
344 ASD_DPRINTK(
"phy%d: primitive reg:0x%x, cont:0x%04x\n",
356 asd_deform_port(asd_ha, phy);
361 ASD_DPRINTK(
"phy%d: primitive reg:0x%x, cont:0x%04x\n",
406 escb->
eb[i].flags = 0;
407 if (!list_empty(&ascb->
list))
408 list_del_init(&ascb->
list);
411 asd_printk(
"couldn't post escb, err:%d\n", i);
415 static void escb_tasklet_complete(
struct asd_ascb *ascb,
426 if (edb > 6 || edb < 0) {
432 "dma_handle: 0x%llx, next: 0x%llx, "
433 "index:%d, opcode:0x%02x\n",
435 (
unsigned long long)ascb->
dma_scb.dma_handle,
439 ascb->
scb->header.opcode);
467 failed_dev = task->
dev;
471 a->
scb->header.opcode);
477 ASD_DPRINTK(
"%s: Can't find task (tc=%d) to abort!\n",
490 task->
dev == failed_dev &&
506 ASD_DPRINTK(
"%s: REQ_DEVICE_RESET, reason=0x%X\n", __func__,
520 if (x == conn_handle)
521 last_dev_task =
task;
524 if (!last_dev_task) {
525 ASD_DPRINTK(
"%s: Device reset for idle device %d?\n",
526 __func__, conn_handle);
546 if (x == conn_handle)
560 sb_opcode &= ~DL_PHY_MASK;
564 ASD_DPRINTK(
"%s: phy%d: BYTES_DMAED\n", __func__, phy_id);
565 asd_bytes_dmaed_tasklet(ascb, dl, edb, phy_id);
568 ASD_DPRINTK(
"%s: phy%d: PRIMITIVE_RECVD\n", __func__,
570 asd_primitive_rcvd_tasklet(ascb, dl, phy_id);
573 ASD_DPRINTK(
"%s: phy%d: PHY_EVENT\n", __func__, phy_id);
574 asd_phy_event_tasklet(ascb, dl);
577 ASD_DPRINTK(
"%s: phy%d: LINK_RESET_ERROR\n", __func__,
579 asd_link_reset_err_tasklet(ascb, dl, phy_id);
582 ASD_DPRINTK(
"%s: phy%d: TIMER_EVENT, lost dw sync\n",
586 sas_phy_disconnected(sas_phy);
587 asd_deform_port(asd_ha, phy);
591 ASD_DPRINTK(
"%s: phy%d: unknown event:0x%x\n", __func__,
598 "dma_handle: 0x%llx, next: 0x%llx, "
599 "index:%d, opcode:0x%02x\n",
601 (
unsigned long long)ascb->
dma_scb.dma_handle,
605 ascb->
scb->header.opcode);
619 seq->
escb_arr[i]->tasklet_complete = escb_tasklet_complete;
627 #define CONTROL_PHY_STATUS (CURRENT_DEVICE_PRESENT | CURRENT_OOB_DONE \
628 | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \
642 static void control_phy_tasklet_complete(
struct asd_ascb *ascb,
657 ASD_DPRINTK(
"%s: phy%d status block opcode:0x%x\n",
658 __func__, phy_id, status);
667 ASD_DPRINTK(
"%s: disable phy%d\n", __func__, phy_id);
674 get_lrate_mode(phy, oob_mode);
677 __func__, phy_id,phy->
sas_phy.linkrate,
686 ASD_DPRINTK(
"%s: phy%d: error: oob status:0x%02x\n",
687 __func__, phy_id, oob_status);
692 ASD_DPRINTK(
"%s: phy%d: hot plug or device present\n",
699 __func__, phy_id, oob_status);
705 ASD_DPRINTK(
"%s: phy%d: sub_func:0x%x\n", __func__,
710 ASD_DPRINTK(
"%s: phy%d: sub_func:0x%x?\n", __func__,
825 static void link_adm_tasklet_complete(
struct asd_ascb *ascb,
833 asd_printk(
"phy%d: link adm task 0x%x completed with error "
834 "0x%x\n", phy_id, link_adm->
sub_func, opcode);
837 phy_id, link_adm->
sub_func, opcode);
842 void asd_build_initiate_link_adm_task(
struct asd_ascb *ascb,
int phy_id,
874 struct asd_ascb *ascb = (
void *) data;
882 list_del_init(&ascb->
list);
891 static const int phy_func_table[] = {