Lines Matching +full:command +full:- +full:sequencer

1 /*-
4 * SPDX-License-Identifier: BSD-3-Clause
6 * Copyright (c) 1994-2001 Justin T. Gibbs.
7 * Copyright (c) 2000-2003 Adaptec Inc.
21 * 3. Neither the names of the above-listed copyright holders nor the names
54 return (ahd->name); in ahd_name()
57 /************************ Sequencer Execution Control *************************/
82 ahd->src_mode = src; in ahd_known_modes()
83 ahd->dst_mode = dst; in ahd_known_modes()
84 ahd->saved_src_mode = src; in ahd_known_modes()
85 ahd->saved_dst_mode = dst; in ahd_known_modes()
105 if (ahd->src_mode == src && ahd->dst_mode == dst) in ahd_set_modes()
108 if (ahd->src_mode == AHD_MODE_UNKNOWN in ahd_set_modes()
109 || ahd->dst_mode == AHD_MODE_UNKNOWN) in ahd_set_modes()
116 ahd->src_mode = src; in ahd_set_modes()
117 ahd->dst_mode = dst; in ahd_set_modes()
141 if ((srcmode & AHD_MK_MSK(ahd->src_mode)) == 0 in ahd_assert_modes()
142 || (dstmode & AHD_MK_MSK(ahd->dst_mode)) == 0) { in ahd_assert_modes()
152 if (ahd->src_mode == AHD_MODE_UNKNOWN in ahd_save_modes()
153 || ahd->dst_mode == AHD_MODE_UNKNOWN) in ahd_save_modes()
156 return (ahd_build_mode_state(ahd, ahd->src_mode, ahd->dst_mode)); in ahd_save_modes()
173 * Determine whether the sequencer has halted code execution.
174 * Returns non-zero status if the sequencer is stopped.
183 * Request that the sequencer stop and wait, indefinitely, for it
184 * to stop. The sequencer will only acknowledge that it is paused
186 * cleared in the SEQCTL register. The sequencer may use PAUSEDIS
192 ahd_outb(ahd, HCNTRL, ahd->pause); in ahd_pause()
195 * Since the sequencer can disable pausing in a critical section, we in ahd_pause()
203 * Allow the sequencer to continue program execution.
205 * sources that would cause the sequencer to halt have been
208 * we don't want to release the sequencer before going back
219 if (ahd->saved_src_mode != AHD_MODE_UNKNOWN in ahd_unpause()
220 && ahd->saved_dst_mode != AHD_MODE_UNKNOWN) { in ahd_unpause()
221 if ((ahd->flags & AHD_UPDATE_PEND_CMDS) != 0) in ahd_unpause()
223 ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode); in ahd_unpause()
227 ahd_outb(ahd, HCNTRL, ahd->unpause); in ahd_unpause()
247 scb->sg_count++; in ahd_sg_setup()
249 && (ahd->flags & AHD_64BIT_ADDRESSING) != 0) { in ahd_sg_setup()
253 sg->addr = aic_htole64(addr); in ahd_sg_setup()
254 sg->len = aic_htole32(len | (last ? AHD_DMA_LAST_SEG : 0)); in ahd_sg_setup()
260 sg->addr = aic_htole32(addr & 0xFFFFFFFF); in ahd_sg_setup()
261 sg->len = aic_htole32(len | ((addr >> 8) & 0x7F000000) in ahd_sg_setup()
271 scb->crc_retry_count = 0; in ahd_setup_scb_common()
272 if ((scb->flags & SCB_PACKETIZED) != 0) { in ahd_setup_scb_common()
274 scb->hscb->task_attribute = scb->hscb->control & SCB_TAG_TYPE; in ahd_setup_scb_common()
277 scb->hscb->task_attribute = SCB_XFERLEN_ODD; in ahd_setup_scb_common()
279 scb->hscb->task_attribute = 0; in ahd_setup_scb_common()
282 if (scb->hscb->cdb_len <= MAX_CDB_LEN_WITH_SENSE_ADDR in ahd_setup_scb_common()
283 || (scb->hscb->cdb_len & SCB_CDB_LEN_PTR) != 0) in ahd_setup_scb_common()
284 scb->hscb->shared_data.idata.cdb_plus_saddr.sense_addr = in ahd_setup_scb_common()
285 aic_htole32(scb->sense_busaddr); in ahd_setup_scb_common()
294 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) { in ahd_setup_data_scb()
297 sg = (struct ahd_dma64_seg *)scb->sg_list; in ahd_setup_data_scb()
298 scb->hscb->dataptr = sg->addr; in ahd_setup_data_scb()
299 scb->hscb->datacnt = sg->len; in ahd_setup_data_scb()
304 sg = (struct ahd_dma_seg *)scb->sg_list; in ahd_setup_data_scb()
305 dataptr_words = (uint32_t*)&scb->hscb->dataptr; in ahd_setup_data_scb()
306 dataptr_words[0] = sg->addr; in ahd_setup_data_scb()
308 if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) { in ahd_setup_data_scb()
311 high_addr = aic_le32toh(sg->len) & 0x7F000000; in ahd_setup_data_scb()
312 scb->hscb->dataptr |= aic_htole64(high_addr << 8); in ahd_setup_data_scb()
314 scb->hscb->datacnt = sg->len; in ahd_setup_data_scb()
319 * sequencer will clear as soon as a data transfer in ahd_setup_data_scb()
322 scb->hscb->sgptr = aic_htole32(scb->sg_list_busaddr|SG_FULL_RESID); in ahd_setup_data_scb()
328 scb->hscb->sgptr = aic_htole32(SG_LIST_NULL); in ahd_setup_noxfer_scb()
329 scb->hscb->dataptr = 0; in ahd_setup_noxfer_scb()
330 scb->hscb->datacnt = 0; in ahd_setup_noxfer_scb()
356 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) in ahd_sg_size()
367 sg_offset = sg_busaddr - (scb->sg_list_busaddr - ahd_sg_size(ahd)); in ahd_sg_bus_to_virt()
368 return ((uint8_t *)scb->sg_list + sg_offset); in ahd_sg_bus_to_virt()
377 sg_offset = ((uint8_t *)sg - (uint8_t *)scb->sg_list) in ahd_sg_virt_to_bus()
378 - ahd_sg_size(ahd); in ahd_sg_virt_to_bus()
380 return (scb->sg_list_busaddr + sg_offset); in ahd_sg_virt_to_bus()
386 aic_dmamap_sync(ahd, ahd->scb_data.hscb_dmat, in ahd_sync_scb()
387 scb->hscb_map->dmamap, in ahd_sync_scb()
388 /*offset*/(uint8_t*)scb->hscb - scb->hscb_map->vaddr, in ahd_sync_scb()
389 /*len*/sizeof(*scb->hscb), op); in ahd_sync_scb()
395 if (scb->sg_count == 0) in ahd_sync_sglist()
398 aic_dmamap_sync(ahd, ahd->scb_data.sg_dmat, in ahd_sync_sglist()
399 scb->sg_map->dmamap, in ahd_sync_sglist()
400 /*offset*/scb->sg_list_busaddr - ahd_sg_size(ahd), in ahd_sync_sglist()
401 /*len*/ahd_sg_size(ahd) * scb->sg_count, op); in ahd_sync_sglist()
407 aic_dmamap_sync(ahd, ahd->scb_data.sense_dmat, in ahd_sync_sense()
408 scb->sense_map->dmamap, in ahd_sync_sense()
409 /*offset*/scb->sense_busaddr, in ahd_sync_sense()
416 return (((uint8_t *)&ahd->targetcmds[index]) in ahd_targetcmd_offset()
417 - (uint8_t *)ahd->qoutfifo); in ahd_targetcmd_offset()
475 sgptr = aic_le32toh(scb->hscb->sgptr); in ahd_complete_scb()
483 * Determine whether the sequencer reported a residual
491 sgptr = aic_le32toh(scb->hscb->sgptr); in ahd_update_residual()
512 *tstate = ahd->enabled_targets[our_id]; in ahd_fetch_transinfo()
513 return (&(*tstate)->transinfo[remote_id]); in ahd_fetch_transinfo()
518 dst->hscb->scsiid = src->hscb->scsiid; \
519 dst->hscb->lun = src->hscb->lun; \
682 * Workaround PCI-X Rev A. hardware bug. in ahd_inb_scbram()
696 if ((ahd->bugs & AHD_PCIX_SCBRAM_RD_BUG) != 0) in ahd_inb_scbram()
729 scb = ahd->scb_data.scbindex[tag]; in ahd_lookup_scb()
747 * HSCB to download is saved off in ahd->next_queued_hscb. in ahd_swap_with_next_hscb()
750 * the sequencer knows about, swap HSCB pointers and in ahd_swap_with_next_hscb()
755 q_hscb = ahd->next_queued_hscb; in ahd_swap_with_next_hscb()
756 q_hscb_map = ahd->next_queued_hscb_map; in ahd_swap_with_next_hscb()
757 saved_hscb_busaddr = q_hscb->hscb_busaddr; in ahd_swap_with_next_hscb()
758 memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb)); in ahd_swap_with_next_hscb()
759 q_hscb->hscb_busaddr = saved_hscb_busaddr; in ahd_swap_with_next_hscb()
760 q_hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr; in ahd_swap_with_next_hscb()
763 ahd->next_queued_hscb = scb->hscb; in ahd_swap_with_next_hscb()
764 ahd->next_queued_hscb_map = scb->hscb_map; in ahd_swap_with_next_hscb()
765 scb->hscb = q_hscb; in ahd_swap_with_next_hscb()
766 scb->hscb_map = q_hscb_map; in ahd_swap_with_next_hscb()
769 ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb; in ahd_swap_with_next_hscb()
773 * Tell the sequencer about a new transaction to execute.
787 ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb); in ahd_queue_scb()
788 ahd->qinfifonext++; in ahd_queue_scb()
790 if (scb->sg_count != 0) in ahd_queue_scb()
806 host_dataptr = aic_le64toh(scb->hscb->dataptr); in ahd_queue_scb()
807 printf("%s: Queueing SCB %d:0x%x bus addr 0x%x - 0x%x%x/0x%x\n", in ahd_queue_scb()
809 SCB_GET_TAG(scb), scb->hscb->scsiid, in ahd_queue_scb()
810 aic_le32toh(scb->hscb->hscb_busaddr), in ahd_queue_scb()
813 aic_le32toh(scb->hscb->datacnt)); in ahd_queue_scb()
817 ahd_set_hnscb_qoff(ahd, ahd->qinfifonext); in ahd_queue_scb()
823 return (scb->sense_data); in ahd_get_sense_buf()
829 return (scb->sense_busaddr); in ahd_get_sense_bufaddr()
841 aic_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap, in ahd_sync_qoutfifo()
850 if ((ahd->flags & AHD_TARGETROLE) != 0) { in ahd_sync_tqinfifo()
851 aic_dmamap_sync(ahd, ahd->shared_data_dmat, in ahd_sync_tqinfifo()
852 ahd->shared_data_map.dmamap, in ahd_sync_tqinfifo()
862 * into our in-core command complete fifos.
872 aic_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap, in ahd_check_cmdcmpltqueues()
873 /*offset*/ahd->qoutfifonext * sizeof(*ahd->qoutfifo), in ahd_check_cmdcmpltqueues()
874 /*len*/sizeof(*ahd->qoutfifo), BUS_DMASYNC_POSTREAD); in ahd_check_cmdcmpltqueues()
875 if (ahd->qoutfifo[ahd->qoutfifonext].valid_tag in ahd_check_cmdcmpltqueues()
876 == ahd->qoutfifonext_valid_tag) in ahd_check_cmdcmpltqueues()
879 if ((ahd->flags & AHD_TARGETROLE) != 0 in ahd_check_cmdcmpltqueues()
880 && (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) { in ahd_check_cmdcmpltqueues()
881 aic_dmamap_sync(ahd, ahd->shared_data_dmat, in ahd_check_cmdcmpltqueues()
882 ahd->shared_data_map.dmamap, in ahd_check_cmdcmpltqueues()
883 ahd_targetcmd_offset(ahd, ahd->tqinfifofnext), in ahd_check_cmdcmpltqueues()
886 if (ahd->targetcmds[ahd->tqinfifonext].cmd_valid != 0) in ahd_check_cmdcmpltqueues()
901 if ((ahd->pause & INTEN) == 0) { in ahd_intr()
904 * and may be disabled for re-entrancy reasons, in ahd_intr()
913 * infer the cause of the interrupt by checking our in-core in ahd_intr()
917 if ((ahd->flags & AHD_ALL_INTERRUPTS) == 0 in ahd_intr()
934 * and after the sequencer has added new entries in ahd_intr()
937 if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) { in ahd_intr()
941 * If SEQINTCODE is non-zero, in ahd_intr()
951 ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket]++; in ahd_intr()
952 ahd->cmdcmplt_total++; in ahd_intr()
954 if ((ahd->flags & AHD_TARGETROLE) != 0) in ahd_intr()
963 if (intstat == 0xFF && (ahd->features & AHD_REMOVABLE) != 0) { in ahd_intr()
968 ahd->bus_intr(ahd); in ahd_intr()