Lines Matching +full:t +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0-only
23 /* ---------- Initialization ---------- */
28 if (asd_ha->hw_prof.sas_addr[0]) in asd_get_user_sas_addr()
31 return sas_request_addr(asd_ha->sas_ha.core.shost, in asd_get_user_sas_addr()
32 asd_ha->hw_prof.sas_addr); in asd_get_user_sas_addr()
40 if (asd_ha->hw_prof.phy_desc[i].sas_addr[0] == 0) in asd_propagate_sas_addr()
42 /* Set a phy's address only if it has none. in asd_propagate_sas_addr()
44 ASD_DPRINTK("setting phy%d addr to %llx\n", i, in asd_propagate_sas_addr()
45 SAS_ADDR(asd_ha->hw_prof.sas_addr)); in asd_propagate_sas_addr()
46 memcpy(asd_ha->hw_prof.phy_desc[i].sas_addr, in asd_propagate_sas_addr()
47 asd_ha->hw_prof.sas_addr, SAS_ADDR_SIZE); in asd_propagate_sas_addr()
51 /* ---------- PHY initialization ---------- */
53 static void asd_init_phy_identify(struct asd_phy *phy) in asd_init_phy_identify() argument
55 phy->identify_frame = phy->id_frm_tok->vaddr; in asd_init_phy_identify()
57 memset(phy->identify_frame, 0, sizeof(*phy->identify_frame)); in asd_init_phy_identify()
59 phy->identify_frame->dev_type = SAS_END_DEVICE; in asd_init_phy_identify()
60 if (phy->sas_phy.role & PHY_ROLE_INITIATOR) in asd_init_phy_identify()
61 phy->identify_frame->initiator_bits = phy->sas_phy.iproto; in asd_init_phy_identify()
62 if (phy->sas_phy.role & PHY_ROLE_TARGET) in asd_init_phy_identify()
63 phy->identify_frame->target_bits = phy->sas_phy.tproto; in asd_init_phy_identify()
64 memcpy(phy->identify_frame->sas_addr, phy->phy_desc->sas_addr, in asd_init_phy_identify()
66 phy->identify_frame->phy_id = phy->sas_phy.id; in asd_init_phy_identify()
69 static int asd_init_phy(struct asd_phy *phy) in asd_init_phy() argument
71 struct asd_ha_struct *asd_ha = phy->sas_phy.ha->lldd_ha; in asd_init_phy()
72 struct asd_sas_phy *sas_phy = &phy->sas_phy; in asd_init_phy()
74 sas_phy->enabled = 1; in asd_init_phy()
75 sas_phy->class = SAS; in asd_init_phy()
76 sas_phy->iproto = SAS_PROTOCOL_ALL; in asd_init_phy()
77 sas_phy->tproto = 0; in asd_init_phy()
78 sas_phy->type = PHY_TYPE_PHYSICAL; in asd_init_phy()
79 sas_phy->role = PHY_ROLE_INITIATOR; in asd_init_phy()
80 sas_phy->oob_mode = OOB_NOT_CONNECTED; in asd_init_phy()
81 sas_phy->linkrate = SAS_LINK_RATE_UNKNOWN; in asd_init_phy()
83 phy->id_frm_tok = asd_alloc_coherent(asd_ha, in asd_init_phy()
84 sizeof(*phy->identify_frame), in asd_init_phy()
86 if (!phy->id_frm_tok) { in asd_init_phy()
87 asd_printk("no mem for IDENTIFY for phy%d\n", sas_phy->id); in asd_init_phy()
88 return -ENOMEM; in asd_init_phy()
90 asd_init_phy_identify(phy); in asd_init_phy()
92 memset(phy->frame_rcvd, 0, sizeof(phy->frame_rcvd)); in asd_init_phy()
101 spin_lock_init(&asd_ha->asd_ports_lock); in asd_init_ports()
103 struct asd_port *asd_port = &asd_ha->asd_ports[i]; in asd_init_ports()
105 memset(asd_port->sas_addr, 0, SAS_ADDR_SIZE); in asd_init_ports()
106 memset(asd_port->attached_sas_addr, 0, SAS_ADDR_SIZE); in asd_init_ports()
107 asd_port->phy_mask = 0; in asd_init_ports()
108 asd_port->num_phys = 0; in asd_init_ports()
115 u8 phy_mask = asd_ha->hw_prof.enabled_phys; in asd_init_phys()
118 struct asd_phy *phy = &asd_ha->phys[i]; in asd_init_phys() local
120 phy->phy_desc = &asd_ha->hw_prof.phy_desc[i]; in asd_init_phys()
121 phy->asd_port = NULL; in asd_init_phys()
123 phy->sas_phy.enabled = 0; in asd_init_phys()
124 phy->sas_phy.id = i; in asd_init_phys()
125 phy->sas_phy.sas_addr = &phy->phy_desc->sas_addr[0]; in asd_init_phys()
126 phy->sas_phy.frame_rcvd = &phy->frame_rcvd[0]; in asd_init_phys()
127 phy->sas_phy.ha = &asd_ha->sas_ha; in asd_init_phys()
128 phy->sas_phy.lldd_phy = phy; in asd_init_phys()
133 int err = asd_init_phy(&asd_ha->phys[i]); in asd_init_phys()
141 /* ---------- Sliding windows ---------- */
145 struct pci_dev *pcidev = asd_ha->pcidev; in asd_init_sw()
152 asd_printk("couldn't access conf. space of %s\n", in asd_init_sw()
159 asd_printk("couldn't write to MBAR_KEY of %s\n", in asd_init_sw()
171 asd_ha->io_handle[0].swa_base = REG_BASE_ADDR; in asd_init_sw()
172 asd_ha->io_handle[0].swb_base = REG_BASE_ADDR_CSEQCIO; in asd_init_sw()
173 asd_ha->io_handle[0].swc_base = REG_BASE_ADDR_EXSI; in asd_init_sw()
174 MBAR0_SWB_SIZE = asd_ha->io_handle[0].len - 0x80; in asd_init_sw()
175 if (!asd_ha->iospace) { in asd_init_sw()
178 asd_ha->io_handle[1].swa_base = OCM_BASE_ADDR; in asd_init_sw()
180 spin_lock_init(&asd_ha->iolock); in asd_init_sw()
185 /* ---------- SCB initialization ---------- */
188 * asd_init_scbs - manually allocate the first SCB.
194 * the _next_ scb to be DMA-ed to the host adapter is read from the last
195 * SCB DMA-ed to the host adapter, we have to always stay one step
200 struct asd_seq_data *seq = &asd_ha->seq; in asd_init_scbs()
204 asd_ha->seq.tc_index_bitmap_bits = asd_ha->hw_prof.max_scbs; in asd_init_scbs()
205 asd_ha->seq.tc_index_array = kcalloc(asd_ha->seq.tc_index_bitmap_bits, in asd_init_scbs()
208 if (!asd_ha->seq.tc_index_array) in asd_init_scbs()
209 return -ENOMEM; in asd_init_scbs()
211 bitmap_bytes = (asd_ha->seq.tc_index_bitmap_bits+7)/8; in asd_init_scbs()
213 asd_ha->seq.tc_index_bitmap = kzalloc(bitmap_bytes, GFP_KERNEL); in asd_init_scbs()
214 if (!asd_ha->seq.tc_index_bitmap) { in asd_init_scbs()
215 kfree(asd_ha->seq.tc_index_array); in asd_init_scbs()
216 asd_ha->seq.tc_index_array = NULL; in asd_init_scbs()
217 return -ENOMEM; in asd_init_scbs()
220 spin_lock_init(&seq->tc_index_lock); in asd_init_scbs()
222 seq->next_scb.size = sizeof(struct scb); in asd_init_scbs()
223 seq->next_scb.vaddr = dma_pool_alloc(asd_ha->scb_pool, GFP_KERNEL, in asd_init_scbs()
224 &seq->next_scb.dma_handle); in asd_init_scbs()
225 if (!seq->next_scb.vaddr) { in asd_init_scbs()
226 kfree(asd_ha->seq.tc_index_bitmap); in asd_init_scbs()
227 kfree(asd_ha->seq.tc_index_array); in asd_init_scbs()
228 asd_ha->seq.tc_index_bitmap = NULL; in asd_init_scbs()
229 asd_ha->seq.tc_index_array = NULL; in asd_init_scbs()
230 return -ENOMEM; in asd_init_scbs()
233 seq->pending = 0; in asd_init_scbs()
234 spin_lock_init(&seq->pend_q_lock); in asd_init_scbs()
235 INIT_LIST_HEAD(&seq->pend_q); in asd_init_scbs()
242 asd_ha->hw_prof.max_scbs = asd_get_cmdctx_size(asd_ha)/ASD_SCB_SIZE; in asd_get_max_scb_ddb()
243 asd_ha->hw_prof.max_ddbs = asd_get_devctx_size(asd_ha)/ASD_DDB_SIZE; in asd_get_max_scb_ddb()
245 asd_ha->hw_prof.max_scbs, in asd_get_max_scb_ddb()
246 asd_ha->hw_prof.max_ddbs); in asd_get_max_scb_ddb()
249 /* ---------- Done List initialization ---------- */
255 asd_ha->seq.actual_dl in asd_init_dl()
259 if (!asd_ha->seq.actual_dl) in asd_init_dl()
260 return -ENOMEM; in asd_init_dl()
261 asd_ha->seq.dl = asd_ha->seq.actual_dl->vaddr; in asd_init_dl()
262 asd_ha->seq.dl_toggle = ASD_DEF_DL_TOGGLE; in asd_init_dl()
263 asd_ha->seq.dl_next = 0; in asd_init_dl()
264 tasklet_init(&asd_ha->seq.dl_tasklet, asd_dl_tasklet_handler, in asd_init_dl()
270 /* ---------- EDB and ESCB init ---------- */
274 struct asd_seq_data *seq = &asd_ha->seq; in asd_alloc_edbs()
277 seq->edb_arr = kmalloc_array(seq->num_edbs, sizeof(*seq->edb_arr), in asd_alloc_edbs()
279 if (!seq->edb_arr) in asd_alloc_edbs()
280 return -ENOMEM; in asd_alloc_edbs()
282 for (i = 0; i < seq->num_edbs; i++) { in asd_alloc_edbs()
283 seq->edb_arr[i] = asd_alloc_coherent(asd_ha, ASD_EDB_SIZE, in asd_alloc_edbs()
285 if (!seq->edb_arr[i]) in asd_alloc_edbs()
287 memset(seq->edb_arr[i]->vaddr, 0, ASD_EDB_SIZE); in asd_alloc_edbs()
290 ASD_DPRINTK("num_edbs:%d\n", seq->num_edbs); in asd_alloc_edbs()
295 for (i-- ; i >= 0; i--) in asd_alloc_edbs()
296 asd_free_coherent(asd_ha, seq->edb_arr[i]); in asd_alloc_edbs()
297 kfree(seq->edb_arr); in asd_alloc_edbs()
298 seq->edb_arr = NULL; in asd_alloc_edbs()
300 return -ENOMEM; in asd_alloc_edbs()
306 struct asd_seq_data *seq = &asd_ha->seq; in asd_alloc_escbs()
310 seq->escb_arr = kmalloc_array(seq->num_escbs, sizeof(*seq->escb_arr), in asd_alloc_escbs()
312 if (!seq->escb_arr) in asd_alloc_escbs()
313 return -ENOMEM; in asd_alloc_escbs()
315 escbs = seq->num_escbs; in asd_alloc_escbs()
318 asd_printk("couldn't allocate list of escbs\n"); in asd_alloc_escbs()
321 seq->num_escbs -= escbs; /* subtract what was not allocated */ in asd_alloc_escbs()
322 ASD_DPRINTK("num_escbs:%d\n", seq->num_escbs); in asd_alloc_escbs()
324 for (i = 0; i < seq->num_escbs; i++, escb = list_entry(escb->list.next, in asd_alloc_escbs()
327 seq->escb_arr[i] = escb; in asd_alloc_escbs()
328 escb->scb->header.opcode = EMPTY_SCB; in asd_alloc_escbs()
333 kfree(seq->escb_arr); in asd_alloc_escbs()
334 seq->escb_arr = NULL; in asd_alloc_escbs()
335 return -ENOMEM; in asd_alloc_escbs()
341 struct asd_seq_data *seq = &asd_ha->seq; in asd_assign_edbs2escbs()
344 for (i = 0; i < seq->num_escbs; i++) { in asd_assign_edbs2escbs()
345 struct asd_ascb *ascb = seq->escb_arr[i]; in asd_assign_edbs2escbs()
346 struct empty_scb *escb = &ascb->scb->escb; in asd_assign_edbs2escbs()
348 ascb->edb_index = z; in asd_assign_edbs2escbs()
350 escb->num_valid = ASD_EDBS_PER_SCB; in asd_assign_edbs2escbs()
353 struct sg_el *eb = &escb->eb[k]; in asd_assign_edbs2escbs()
354 struct asd_dma_tok *edb = seq->edb_arr[z++]; in asd_assign_edbs2escbs()
357 eb->bus_addr = cpu_to_le64(((u64) edb->dma_handle)); in asd_assign_edbs2escbs()
358 eb->size = cpu_to_le32(((u32) edb->size)); in asd_assign_edbs2escbs()
364 * asd_init_escbs -- allocate and initialize empty scbs
372 struct asd_seq_data *seq = &asd_ha->seq; in asd_init_escbs()
376 int edbs = 2*(1+asd_ha->hw_prof.num_phys); in asd_init_escbs()
378 seq->num_escbs = (edbs+ASD_EDBS_PER_SCB-1)/ASD_EDBS_PER_SCB; in asd_init_escbs()
379 seq->num_edbs = seq->num_escbs * ASD_EDBS_PER_SCB; in asd_init_escbs()
383 asd_printk("couldn't allocate edbs\n"); in asd_init_escbs()
389 asd_printk("couldn't allocate escbs\n"); in asd_init_escbs()
399 seq->pending = seq->num_escbs; in asd_init_escbs()
400 seq->can_queue = 1 + (asd_ha->hw_prof.max_scbs - seq->pending)/2; in asd_init_escbs()
405 /* ---------- HW initialization ---------- */
408 * asd_chip_hardrst -- hard reset the chip
432 } while (--count > 0); in asd_chip_hardrst()
434 return -ENODEV; in asd_chip_hardrst()
438 * asd_init_chip -- initialize the chip
451 asd_printk("couldn't hard reset %s\n", in asd_init_chip()
452 pci_name(asd_ha->pcidev)); in asd_init_chip()
460 asd_printk("couldn't init seqs for %s\n", in asd_init_chip()
461 pci_name(asd_ha->pcidev)); in asd_init_chip()
467 asd_printk("couldn't start seqs for %s\n", in asd_init_chip()
468 pci_name(asd_ha->pcidev)); in asd_init_chip()
494 dma_addr -= asd_ha->hw_prof.max_ddbs * ASD_DDB_SIZE; in asd_extend_devctx_ocm()
499 asd_ha->hw_prof.max_ddbs += MAX_DEVS; in asd_extend_devctx_ocm()
511 asd_ha->hw_prof.ddb_ext = NULL; in asd_extend_devctx()
512 if (max_devs <= asd_ha->hw_prof.max_ddbs || max_devs > 0xFFFF) { in asd_extend_devctx()
513 max_devs = asd_ha->hw_prof.max_ddbs; in asd_extend_devctx()
517 size = (max_devs - asd_ha->hw_prof.max_ddbs + 1) * ASD_DDB_SIZE; in asd_extend_devctx()
519 asd_ha->hw_prof.ddb_ext = asd_alloc_coherent(asd_ha, size, GFP_KERNEL); in asd_extend_devctx()
520 if (!asd_ha->hw_prof.ddb_ext) { in asd_extend_devctx()
521 asd_printk("couldn't allocate memory for %d devices\n", in asd_extend_devctx()
523 max_devs = asd_ha->hw_prof.max_ddbs; in asd_extend_devctx()
524 return -ENOMEM; in asd_extend_devctx()
526 dma_handle = asd_ha->hw_prof.ddb_ext->dma_handle; in asd_extend_devctx()
528 dma_addr -= asd_ha->hw_prof.max_ddbs * ASD_DDB_SIZE; in asd_extend_devctx()
535 asd_ha->hw_prof.max_ddbs = max_devs; in asd_extend_devctx()
547 asd_ha->hw_prof.scb_ext = NULL; in asd_extend_cmdctx()
548 if (max_cmnds <= asd_ha->hw_prof.max_scbs || max_cmnds > 0xFFFF) { in asd_extend_cmdctx()
549 max_cmnds = asd_ha->hw_prof.max_scbs; in asd_extend_cmdctx()
553 size = (max_cmnds - asd_ha->hw_prof.max_scbs + 1) * ASD_SCB_SIZE; in asd_extend_cmdctx()
555 asd_ha->hw_prof.scb_ext = asd_alloc_coherent(asd_ha, size, GFP_KERNEL); in asd_extend_cmdctx()
556 if (!asd_ha->hw_prof.scb_ext) { in asd_extend_cmdctx()
557 asd_printk("couldn't allocate memory for %d commands\n", in asd_extend_cmdctx()
559 max_cmnds = asd_ha->hw_prof.max_scbs; in asd_extend_cmdctx()
560 return -ENOMEM; in asd_extend_cmdctx()
562 dma_handle = asd_ha->hw_prof.scb_ext->dma_handle; in asd_extend_cmdctx()
564 dma_addr -= asd_ha->hw_prof.max_scbs * ASD_SCB_SIZE; in asd_extend_cmdctx()
571 asd_ha->hw_prof.max_scbs = max_cmnds; in asd_extend_cmdctx()
577 * asd_init_ctxmem -- initialize context memory
585 * thus allowing unlimited support for SCBs and DDBs -- only limited
597 bitmap_bytes = (asd_ha->hw_prof.max_ddbs+7)/8; in asd_init_ctxmem()
599 asd_ha->hw_prof.ddb_bitmap = kzalloc(bitmap_bytes, GFP_KERNEL); in asd_init_ctxmem()
600 if (!asd_ha->hw_prof.ddb_bitmap) in asd_init_ctxmem()
601 return -ENOMEM; in asd_init_ctxmem()
602 spin_lock_init(&asd_ha->hw_prof.ddb_lock); in asd_init_ctxmem()
616 err = pci_read_config_dword(asd_ha->pcidev, PCIC_HSTPCIX_CNTRL, &v); in asd_init_hw()
618 asd_printk("couldn't read PCIC_HSTPCIX_CNTRL of %s\n", in asd_init_hw()
619 pci_name(asd_ha->pcidev)); in asd_init_hw()
622 err = pci_write_config_dword(asd_ha->pcidev, PCIC_HSTPCIX_CNTRL, in asd_init_hw()
625 asd_printk("couldn't disable split completion timer of %s\n", in asd_init_hw()
626 pci_name(asd_ha->pcidev)); in asd_init_hw()
632 asd_printk("couldn't read ocm(%d)\n", err); in asd_init_hw()
634 * couldn't read the OCM. */ in asd_init_hw()
639 asd_printk("couldn't read flash(%d)\n", err); in asd_init_hw()
641 * couldn't read FLASH memory. in asd_init_hw()
649 pci_name(asd_ha->pcidev)); in asd_init_hw()
650 err = -ENODEV; in asd_init_hw()
658 asd_printk("couldn't initialize phys for %s\n", in asd_init_hw()
659 pci_name(asd_ha->pcidev)); in asd_init_hw()
667 asd_printk("couldn't initialize scbs for %s\n", in asd_init_hw()
668 pci_name(asd_ha->pcidev)); in asd_init_hw()
674 asd_printk("couldn't initialize the done list:%d\n", in asd_init_hw()
681 asd_printk("couldn't initialize escbs\n"); in asd_init_hw()
687 asd_printk("couldn't init the chip\n"); in asd_init_hw()
694 /* ---------- Chip reset ---------- */
697 * asd_chip_reset -- reset the host adapter, etc
701 * timeout. This should be no different than hot-unplugging the
708 ASD_DPRINTK("chip reset for %s\n", pci_name(asd_ha->pcidev)); in asd_chip_reset()
712 /* ---------- Done List Routines ---------- */
717 struct asd_seq_data *seq = &asd_ha->seq; in asd_dl_tasklet_handler()
721 struct done_list_struct *dl = &seq->dl[seq->dl_next]; in asd_dl_tasklet_handler()
724 if ((dl->toggle & DL_TOGGLE_MASK) != seq->dl_toggle) in asd_dl_tasklet_handler()
728 spin_lock_irqsave(&seq->tc_index_lock, flags); in asd_dl_tasklet_handler()
729 ascb = asd_tc_index_find(seq, (int)le16_to_cpu(dl->index)); in asd_dl_tasklet_handler()
730 spin_unlock_irqrestore(&seq->tc_index_lock, flags); in asd_dl_tasklet_handler()
734 } else if (ascb->scb->header.opcode == EMPTY_SCB) { in asd_dl_tasklet_handler()
736 } else if (!ascb->uldd_timer && !del_timer(&ascb->timer)) { in asd_dl_tasklet_handler()
739 spin_lock_irqsave(&seq->pend_q_lock, flags); in asd_dl_tasklet_handler()
740 list_del_init(&ascb->list); in asd_dl_tasklet_handler()
741 seq->pending--; in asd_dl_tasklet_handler()
742 spin_unlock_irqrestore(&seq->pend_q_lock, flags); in asd_dl_tasklet_handler()
744 ascb->tasklet_complete(ascb, dl); in asd_dl_tasklet_handler()
747 seq->dl_next = (seq->dl_next + 1) & (ASD_DL_SIZE-1); in asd_dl_tasklet_handler()
748 if (!seq->dl_next) in asd_dl_tasklet_handler()
749 seq->dl_toggle ^= DL_TOGGLE_MASK; in asd_dl_tasklet_handler()
753 /* ---------- Interrupt Service Routines ---------- */
756 * asd_process_donelist_isr -- schedule processing of done list entries
761 tasklet_schedule(&asd_ha->seq.dl_tasklet); in asd_process_donelist_isr()
765 * asd_com_sas_isr -- process device communication interrupt (COMINT)
777 pci_name(asd_ha->pcidev)); in asd_com_sas_isr()
784 pci_name(asd_ha->pcidev), in asd_com_sas_isr()
801 pci_name(asd_ha->pcidev), in asd_com_sas_isr()
853 pci_name(asd_ha->pcidev), in asd_arp2_err()
857 pci_name(asd_ha->pcidev), in asd_arp2_err()
861 pci_name(asd_ha->pcidev), in asd_arp2_err()
874 pci_name(asd_ha->pcidev), in asd_arp2_err()
879 pci_name(asd_ha->pcidev), in asd_arp2_err()
883 pci_name(asd_ha->pcidev), lseq, in asd_arp2_err()
891 * asd_dch_sas_isr -- process device channel interrupt (DEVINT)
899 asd_printk("%s: CFIFTOERR\n", pci_name(asd_ha->pcidev)); in asd_dch_sas_isr()
906 * asd_rbi_exsi_isr -- process external system interface interrupt (INITERR)
920 pci_name(asd_ha->pcidev)); in asd_rbi_exsi_isr()
925 pci_name(asd_ha->pcidev)); in asd_rbi_exsi_isr()
939 pci_name(asd_ha->pcidev), in asd_rbi_exsi_isr()
952 * asd_hst_pcix_isr -- process host interface interrupts
963 pci_read_config_word(asd_ha->pcidev, PCI_STATUS, &status); in asd_hst_pcix_isr()
964 pci_read_config_dword(asd_ha->pcidev, PCIX_STATUS, &pcix_status); in asd_hst_pcix_isr()
965 pci_read_config_dword(asd_ha->pcidev, ECC_CTRL_STAT, &ecc_status); in asd_hst_pcix_isr()
968 asd_printk("parity error for %s\n", pci_name(asd_ha->pcidev)); in asd_hst_pcix_isr()
970 asd_printk("master abort for %s\n", pci_name(asd_ha->pcidev)); in asd_hst_pcix_isr()
972 asd_printk("target abort for %s\n", pci_name(asd_ha->pcidev)); in asd_hst_pcix_isr()
974 asd_printk("data parity for %s\n", pci_name(asd_ha->pcidev)); in asd_hst_pcix_isr()
977 pci_name(asd_ha->pcidev)); in asd_hst_pcix_isr()
978 pci_write_config_dword(asd_ha->pcidev,PCIX_STATUS,pcix_status); in asd_hst_pcix_isr()
983 pci_name(asd_ha->pcidev)); in asd_hst_pcix_isr()
984 pci_write_config_dword(asd_ha->pcidev,PCIX_STATUS,pcix_status); in asd_hst_pcix_isr()
989 pci_name(asd_ha->pcidev)); in asd_hst_pcix_isr()
992 pci_name(asd_ha->pcidev)); in asd_hst_pcix_isr()
997 * asd_hw_isr -- host adapter interrupt service routine
1028 /* ---------- SCB handling ---------- */
1034 struct asd_seq_data *seq = &asd_ha->seq; in asd_ascb_alloc()
1041 ascb->dma_scb.size = sizeof(struct scb); in asd_ascb_alloc()
1042 ascb->dma_scb.vaddr = dma_pool_zalloc(asd_ha->scb_pool, in asd_ascb_alloc()
1044 &ascb->dma_scb.dma_handle); in asd_ascb_alloc()
1045 if (!ascb->dma_scb.vaddr) { in asd_ascb_alloc()
1051 spin_lock_irqsave(&seq->tc_index_lock, flags); in asd_ascb_alloc()
1052 ascb->tc_index = asd_tc_index_get(seq, ascb); in asd_ascb_alloc()
1053 spin_unlock_irqrestore(&seq->tc_index_lock, flags); in asd_ascb_alloc()
1054 if (ascb->tc_index == -1) in asd_ascb_alloc()
1057 ascb->scb->header.index = cpu_to_le16((u16)ascb->tc_index); in asd_ascb_alloc()
1062 dma_pool_free(asd_ha->scb_pool, ascb->dma_scb.vaddr, in asd_ascb_alloc()
1063 ascb->dma_scb.dma_handle); in asd_ascb_alloc()
1070 * asd_ascb_alloc_list -- allocate a list of aSCBs
1091 for ( ; *num > 0; --*num) { in asd_ascb_alloc_list()
1099 struct asd_ascb *last = list_entry(first->list.prev, in asd_ascb_alloc_list()
1102 list_add_tail(&ascb->list, &first->list); in asd_ascb_alloc_list()
1103 last->scb->header.next_scb = in asd_ascb_alloc_list()
1104 cpu_to_le64(((u64)ascb->dma_scb.dma_handle)); in asd_ascb_alloc_list()
1112 * asd_swap_head_scb -- swap the head scb
1118 * seq->next_scb keeps the address of this SCB. The sequencer will
1124 * of number of memcpy calls to the number of SCB DMA-ed is as small
1132 struct asd_seq_data *seq = &asd_ha->seq; in asd_swap_head_scb()
1133 struct asd_ascb *last = list_entry(ascb->list.prev, in asd_swap_head_scb()
1136 struct asd_dma_tok t = ascb->dma_scb; in asd_swap_head_scb() local
1138 memcpy(seq->next_scb.vaddr, ascb->scb, sizeof(*ascb->scb)); in asd_swap_head_scb()
1139 ascb->dma_scb = seq->next_scb; in asd_swap_head_scb()
1140 ascb->scb = ascb->dma_scb.vaddr; in asd_swap_head_scb()
1141 seq->next_scb = t; in asd_swap_head_scb()
1142 last->scb->header.next_scb = in asd_swap_head_scb()
1143 cpu_to_le64(((u64)seq->next_scb.dma_handle)); in asd_swap_head_scb()
1147 * asd_start_scb_timers -- (add and) start timers of SCBs
1159 if (!ascb->uldd_timer) { in asd_start_scb_timers()
1160 ascb->timer.function = asd_ascb_timedout; in asd_start_scb_timers()
1161 ascb->timer.expires = jiffies + AIC94XX_SCB_TIMEOUT; in asd_start_scb_timers()
1162 add_timer(&ascb->timer); in asd_start_scb_timers()
1168 * asd_post_ascb_list -- post a list of 1 or more aSCBs to the host adapter
1176 * to the number of ascbs sent, we try to batch-send as many ascbs as possible
1193 spin_lock_irqsave(&asd_ha->seq.pend_q_lock, flags); in asd_post_ascb_list()
1194 can_queue = asd_ha->hw_prof.max_scbs - asd_ha->seq.pending; in asd_post_ascb_list()
1196 asd_ha->seq.pending += num; in asd_post_ascb_list()
1201 spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags); in asd_post_ascb_list()
1202 asd_printk("%s: scb queue full\n", pci_name(asd_ha->pcidev)); in asd_post_ascb_list()
1203 return -SAS_QUEUE_FULL; in asd_post_ascb_list()
1208 __list_add(&list, ascb->list.prev, &ascb->list); in asd_post_ascb_list()
1212 asd_ha->seq.scbpro += num; in asd_post_ascb_list()
1213 list_splice_init(&list, asd_ha->seq.pend_q.prev); in asd_post_ascb_list()
1214 asd_write_reg_dword(asd_ha, SCBPRO, (u32)asd_ha->seq.scbpro); in asd_post_ascb_list()
1215 spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags); in asd_post_ascb_list()
1221 * asd_post_escb_list -- post a list of 1 or more empty scb
1243 spin_lock_irqsave(&asd_ha->seq.pend_q_lock, flags); in asd_post_escb_list()
1245 asd_ha->seq.scbpro += num; in asd_post_escb_list()
1246 asd_write_reg_dword(asd_ha, SCBPRO, (u32)asd_ha->seq.scbpro); in asd_post_escb_list()
1247 spin_unlock_irqrestore(&asd_ha->seq.pend_q_lock, flags); in asd_post_escb_list()
1252 /* ---------- LED ---------- */
1255 * asd_turn_led -- turn on/off an LED
1257 * @phy_id: the PHY id whose LED we want to manupulate
1273 * asd_control_led -- enable/disable an LED on the board
1275 * @phy_id: integer, the phy id
1302 /* ---------- PHY enable ---------- */
1306 struct asd_phy *phy = &asd_ha->phys[phy_id]; in asd_enable_phy() local
1315 phy->phy_desc->phy_control_0); in asd_enable_phy()
1317 phy->phy_desc->phy_control_1); in asd_enable_phy()
1319 phy->phy_desc->phy_control_2); in asd_enable_phy()
1321 phy->phy_desc->phy_control_3); in asd_enable_phy()
1327 phy->id_frm_tok->dma_handle); in asd_enable_phy()
1355 asd_printk("no memory for control phy ascb list\n"); in asd_enable_phys()
1356 return -ENOMEM; in asd_enable_phys()
1358 num -= k; in asd_enable_phys()
1363 ascb = list_entry(ascb->list.next, struct asd_ascb, list); in asd_enable_phys()
1365 ASD_DPRINTK("posting %d control phy scbs\n", num); in asd_enable_phys()