17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* 287c478bd9Sstevel@tonic-gate * hci1394_ixl_comp.c 297c478bd9Sstevel@tonic-gate * Isochronous IXL Compiler. 307c478bd9Sstevel@tonic-gate * The compiler converts the general hardware independent IXL command 317c478bd9Sstevel@tonic-gate * blocks into OpenHCI DMA descriptors. 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 357c478bd9Sstevel@tonic-gate #include <sys/types.h> 367c478bd9Sstevel@tonic-gate #include <sys/conf.h> 377c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 387c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #include <sys/tnf_probe.h> 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate #include <sys/1394/h1394.h> 437c478bd9Sstevel@tonic-gate #include <sys/1394/ixl1394.h> 447c478bd9Sstevel@tonic-gate #include <sys/1394/adapters/hci1394.h> 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* compiler allocation size for DMA descriptors. 8000 is 500 descriptors */ 477c478bd9Sstevel@tonic-gate #define HCI1394_IXL_PAGESIZE 8000 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate /* invalid opcode */ 507c478bd9Sstevel@tonic-gate #define IXL1394_OP_INVALID (0 | IXL1394_OPTY_OTHER) 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate /* 537c478bd9Sstevel@tonic-gate * maximum number of interrupts permitted for a single context in which 547c478bd9Sstevel@tonic-gate * the context does not advance to the next DMA descriptor. Interrupts are 557c478bd9Sstevel@tonic-gate * triggered by 1) hardware completing a DMA descriptor block which has the 567c478bd9Sstevel@tonic-gate * interrupt (i) bits set, 2) a cycle_inconsistent interrupt, or 3) a cycle_lost 577c478bd9Sstevel@tonic-gate * interrupt. Once the max is reached, the HCI1394_IXL_INTR_NOADV error is 587c478bd9Sstevel@tonic-gate * returned. 597c478bd9Sstevel@tonic-gate */ 607c478bd9Sstevel@tonic-gate int hci1394_ixl_max_noadv_intrs = 8; 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate static void hci1394_compile_ixl_init(hci1394_comp_ixl_vars_t *wvp, 647c478bd9Sstevel@tonic-gate hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp, 657c478bd9Sstevel@tonic-gate ixl1394_command_t *ixlp); 667c478bd9Sstevel@tonic-gate static void hci1394_compile_ixl_endup(hci1394_comp_ixl_vars_t *wvp); 677c478bd9Sstevel@tonic-gate static void hci1394_parse_ixl(hci1394_comp_ixl_vars_t *wvp, 687c478bd9Sstevel@tonic-gate ixl1394_command_t *ixlp); 697c478bd9Sstevel@tonic-gate static void hci1394_finalize_all_xfer_desc(hci1394_comp_ixl_vars_t *wvp); 707c478bd9Sstevel@tonic-gate static void hci1394_finalize_cur_xfer_desc(hci1394_comp_ixl_vars_t *wvp); 717c478bd9Sstevel@tonic-gate static void hci1394_bld_recv_pkt_desc(hci1394_comp_ixl_vars_t *wvp); 727c478bd9Sstevel@tonic-gate static void hci1394_bld_recv_buf_ppb_desc(hci1394_comp_ixl_vars_t *wvp); 737c478bd9Sstevel@tonic-gate static void hci1394_bld_recv_buf_fill_desc(hci1394_comp_ixl_vars_t *wvp); 747c478bd9Sstevel@tonic-gate static void hci1394_bld_xmit_pkt_desc(hci1394_comp_ixl_vars_t *wvp); 757c478bd9Sstevel@tonic-gate static void hci1394_bld_xmit_buf_desc(hci1394_comp_ixl_vars_t *wvp); 767c478bd9Sstevel@tonic-gate static void hci1394_bld_xmit_hdronly_nopkt_desc(hci1394_comp_ixl_vars_t *wvp); 777c478bd9Sstevel@tonic-gate static int hci1394_bld_dma_mem_desc_blk(hci1394_comp_ixl_vars_t *wvp, 787c478bd9Sstevel@tonic-gate caddr_t *dma_descpp, uint32_t *dma_desc_bound); 797c478bd9Sstevel@tonic-gate static void hci1394_set_xmit_pkt_hdr(hci1394_comp_ixl_vars_t *wvp); 807c478bd9Sstevel@tonic-gate static void hci1394_set_xmit_skip_mode(hci1394_comp_ixl_vars_t *wvp); 817c478bd9Sstevel@tonic-gate static void hci1394_set_xmit_storevalue_desc(hci1394_comp_ixl_vars_t *wvp); 827c478bd9Sstevel@tonic-gate static int hci1394_set_next_xfer_buf(hci1394_comp_ixl_vars_t *wvp, 837c478bd9Sstevel@tonic-gate uint32_t bufp, uint16_t size); 847c478bd9Sstevel@tonic-gate static int hci1394_flush_end_desc_check(hci1394_comp_ixl_vars_t *wvp, 857c478bd9Sstevel@tonic-gate uint32_t count); 867c478bd9Sstevel@tonic-gate static int hci1394_flush_hci_cache(hci1394_comp_ixl_vars_t *wvp); 877c478bd9Sstevel@tonic-gate static uint32_t hci1394_alloc_storevalue_dma_mem(hci1394_comp_ixl_vars_t *wvp); 887c478bd9Sstevel@tonic-gate static hci1394_xfer_ctl_t *hci1394_alloc_xfer_ctl(hci1394_comp_ixl_vars_t *wvp, 897c478bd9Sstevel@tonic-gate uint32_t dmacnt); 907c478bd9Sstevel@tonic-gate static void *hci1394_alloc_dma_mem(hci1394_comp_ixl_vars_t *wvp, 917c478bd9Sstevel@tonic-gate uint32_t size, uint32_t *dma_bound); 927c478bd9Sstevel@tonic-gate static boolean_t hci1394_is_opcode_valid(uint16_t ixlopcode); 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate /* 967c478bd9Sstevel@tonic-gate * FULL LIST OF ACCEPTED IXL COMMAND OPCOCDES: 977c478bd9Sstevel@tonic-gate * Receive Only: Transmit Only: 987c478bd9Sstevel@tonic-gate * IXL1394_OP_RECV_PKT_ST IXL1394_OP_SEND_PKT_WHDR_ST 997c478bd9Sstevel@tonic-gate * IXL1394_OP_RECV_PKT IXL1394_OP_SEND_PKT_ST 1007c478bd9Sstevel@tonic-gate * IXL1394_OP_RECV_BUF IXL1394_OP_SEND_PKT 1017c478bd9Sstevel@tonic-gate * IXL1394_OP_SET_SYNCWAIT IXL1394_OP_SEND_BUF 1027c478bd9Sstevel@tonic-gate * IXL1394_OP_SEND_HDR_ONLY 1037c478bd9Sstevel@tonic-gate * Receive or Transmit: IXL1394_OP_SEND_NO_PKT 1047c478bd9Sstevel@tonic-gate * IXL1394_OP_CALLBACK IXL1394_OP_SET_TAGSYNC 1057c478bd9Sstevel@tonic-gate * IXL1394_OP_LABEL IXL1394_OP_SET_SKIPMODE 1067c478bd9Sstevel@tonic-gate * IXL1394_OP_JUMP IXL1394_OP_STORE_TIMESTAMP 1077c478bd9Sstevel@tonic-gate */ 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate /* 1107c478bd9Sstevel@tonic-gate * hci1394_compile_ixl() 1117c478bd9Sstevel@tonic-gate * Top level ixl compiler entry point. Scans ixl and builds openHCI 1.0 1127c478bd9Sstevel@tonic-gate * descriptor blocks in dma memory. 1137c478bd9Sstevel@tonic-gate */ 1147c478bd9Sstevel@tonic-gate int 1157c478bd9Sstevel@tonic-gate hci1394_compile_ixl(hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp, 1167c478bd9Sstevel@tonic-gate ixl1394_command_t *ixlp, int *resultp) 1177c478bd9Sstevel@tonic-gate { 1187c478bd9Sstevel@tonic-gate hci1394_comp_ixl_vars_t wv; /* working variables used throughout */ 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate ASSERT(soft_statep != NULL); 1217c478bd9Sstevel@tonic-gate ASSERT(ctxtp != NULL); 1227c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_compile_ixl_enter, 1237c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate /* Initialize compiler working variables */ 1267c478bd9Sstevel@tonic-gate hci1394_compile_ixl_init(&wv, soft_statep, ctxtp, ixlp); 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate /* 1297c478bd9Sstevel@tonic-gate * First pass: 1307c478bd9Sstevel@tonic-gate * Parse ixl commands, building desc blocks, until end of IXL 1317c478bd9Sstevel@tonic-gate * linked list. 1327c478bd9Sstevel@tonic-gate */ 1337c478bd9Sstevel@tonic-gate hci1394_parse_ixl(&wv, ixlp); 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate /* 1367c478bd9Sstevel@tonic-gate * Second pass: 1377c478bd9Sstevel@tonic-gate * Resolve all generated descriptor block jump and skip addresses. 1387c478bd9Sstevel@tonic-gate * Set interrupt enable in descriptor blocks which have callback 1397c478bd9Sstevel@tonic-gate * operations in their execution scope. (Previously store_timesamp 1407c478bd9Sstevel@tonic-gate * operations were counted also.) Set interrupt enable in descriptor 1417c478bd9Sstevel@tonic-gate * blocks which were introduced by an ixl label command. 1427c478bd9Sstevel@tonic-gate */ 1437c478bd9Sstevel@tonic-gate if (wv.dma_bld_error == 0) { 1447c478bd9Sstevel@tonic-gate hci1394_finalize_all_xfer_desc(&wv); 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate /* Endup: finalize and cleanup ixl compile, return result */ 1487c478bd9Sstevel@tonic-gate hci1394_compile_ixl_endup(&wv); 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate *resultp = wv.dma_bld_error; 1517c478bd9Sstevel@tonic-gate if (*resultp != 0) { 1527c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_compile_ixl_exit, 1537c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 1547c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 1557c478bd9Sstevel@tonic-gate } else { 1567c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_compile_ixl_exit, 1577c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 1587c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate /* 1637c478bd9Sstevel@tonic-gate * hci1394_compile_ixl_init() 1647c478bd9Sstevel@tonic-gate * Initialize the isoch context structure associated with the IXL 1657c478bd9Sstevel@tonic-gate * program, and initialize the temporary working variables structure. 1667c478bd9Sstevel@tonic-gate */ 1677c478bd9Sstevel@tonic-gate static void 1687c478bd9Sstevel@tonic-gate hci1394_compile_ixl_init(hci1394_comp_ixl_vars_t *wvp, 1697c478bd9Sstevel@tonic-gate hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp, 1707c478bd9Sstevel@tonic-gate ixl1394_command_t *ixlp) 1717c478bd9Sstevel@tonic-gate { 1727c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_compile_ixl_init_enter, 1737c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate /* initialize common recv/xmit compile values */ 1767c478bd9Sstevel@tonic-gate wvp->soft_statep = soft_statep; 1777c478bd9Sstevel@tonic-gate wvp->ctxtp = ctxtp; 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate /* init/clear ctxtp values */ 180*ffc2b7d4SToomas Soome ctxtp->dma_mem_execp = 0; 1817c478bd9Sstevel@tonic-gate ctxtp->dma_firstp = NULL; 1827c478bd9Sstevel@tonic-gate ctxtp->dma_last_time = 0; 1837c478bd9Sstevel@tonic-gate ctxtp->xcs_firstp = NULL; 1847c478bd9Sstevel@tonic-gate ctxtp->ixl_exec_depth = 0; 1857c478bd9Sstevel@tonic-gate ctxtp->ixl_execp = NULL; 1867c478bd9Sstevel@tonic-gate ctxtp->ixl_firstp = ixlp; 1877c478bd9Sstevel@tonic-gate ctxtp->default_skipxferp = NULL; 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate /* 1907c478bd9Sstevel@tonic-gate * the context's max_noadv_intrs is set here instead of in isoch init 1917c478bd9Sstevel@tonic-gate * because the default is patchable and would only be picked up this way 1927c478bd9Sstevel@tonic-gate */ 1937c478bd9Sstevel@tonic-gate ctxtp->max_noadv_intrs = hci1394_ixl_max_noadv_intrs; 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate /* init working variables */ 1967c478bd9Sstevel@tonic-gate wvp->xcs_firstp = NULL; 1977c478bd9Sstevel@tonic-gate wvp->xcs_currentp = NULL; 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate wvp->dma_firstp = NULL; 2007c478bd9Sstevel@tonic-gate wvp->dma_currentp = NULL; 2017c478bd9Sstevel@tonic-gate wvp->dma_bld_error = 0; 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate wvp->ixl_io_mode = ctxtp->ctxt_flags; 2047c478bd9Sstevel@tonic-gate wvp->ixl_cur_cmdp = NULL; 2057c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp = NULL; 2067c478bd9Sstevel@tonic-gate wvp->ixl_cur_labelp = NULL; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate wvp->ixl_xfer_st_cnt = 0; /* count of xfer start commands found */ 2097c478bd9Sstevel@tonic-gate wvp->xfer_state = XFER_NONE; /* none, pkt, buf, skip, hdronly */ 2107c478bd9Sstevel@tonic-gate wvp->xfer_hci_flush = 0; /* updateable - xfer, jump, set */ 2117c478bd9Sstevel@tonic-gate wvp->xfer_pktlen = 0; 2127c478bd9Sstevel@tonic-gate wvp->xfer_bufcnt = 0; 2137c478bd9Sstevel@tonic-gate wvp->descriptors = 0; 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate /* START RECV ONLY SECTION */ 2167c478bd9Sstevel@tonic-gate wvp->ixl_setsyncwait_cnt = 0; 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate /* START XMIT ONLY SECTION */ 2197c478bd9Sstevel@tonic-gate wvp->ixl_settagsync_cmdp = NULL; 2207c478bd9Sstevel@tonic-gate wvp->ixl_setskipmode_cmdp = NULL; 2217c478bd9Sstevel@tonic-gate wvp->default_skipmode = ctxtp->default_skipmode; /* nxt,self,stop,jmp */ 2227c478bd9Sstevel@tonic-gate wvp->default_skiplabelp = ctxtp->default_skiplabelp; 2237c478bd9Sstevel@tonic-gate wvp->default_skipxferp = NULL; 2247c478bd9Sstevel@tonic-gate wvp->skipmode = ctxtp->default_skipmode; 2257c478bd9Sstevel@tonic-gate wvp->skiplabelp = NULL; 2267c478bd9Sstevel@tonic-gate wvp->skipxferp = NULL; 2277c478bd9Sstevel@tonic-gate wvp->default_tag = ctxtp->default_tag; 2287c478bd9Sstevel@tonic-gate wvp->default_sync = ctxtp->default_sync; 2297c478bd9Sstevel@tonic-gate wvp->storevalue_bufp = hci1394_alloc_storevalue_dma_mem(wvp); 2307c478bd9Sstevel@tonic-gate wvp->storevalue_data = 0; 2317c478bd9Sstevel@tonic-gate wvp->xmit_pkthdr1 = 0; 2327c478bd9Sstevel@tonic-gate wvp->xmit_pkthdr2 = 0; 2337c478bd9Sstevel@tonic-gate /* END XMIT ONLY SECTION */ 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_compile_ixl_init_exit, 2367c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate /* 2407c478bd9Sstevel@tonic-gate * hci1394_compile_ixl_endup() 2417c478bd9Sstevel@tonic-gate * This routine is called just before the main hci1394_compile_ixl() exits. 2427c478bd9Sstevel@tonic-gate * It checks for errors and performs the appropriate cleanup, or it rolls any 2437c478bd9Sstevel@tonic-gate * relevant info from the working variables struct into the context structure 2447c478bd9Sstevel@tonic-gate */ 2457c478bd9Sstevel@tonic-gate static void 2467c478bd9Sstevel@tonic-gate hci1394_compile_ixl_endup(hci1394_comp_ixl_vars_t *wvp) 2477c478bd9Sstevel@tonic-gate { 2487c478bd9Sstevel@tonic-gate ixl1394_command_t *ixl_exec_stp; 2497c478bd9Sstevel@tonic-gate hci1394_idma_desc_mem_t *dma_nextp; 2507c478bd9Sstevel@tonic-gate int err; 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_compile_ixl_endup_enter, 2537c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate /* error if no descriptor blocks found in ixl & created in dma memory */ 2567c478bd9Sstevel@tonic-gate if ((wvp->dma_bld_error == 0) && (wvp->ixl_xfer_st_cnt == 0)) { 2577c478bd9Sstevel@tonic-gate TNF_PROBE_1(hci1394_compile_ixl_endup_nodata_error, 2587c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 2597c478bd9Sstevel@tonic-gate "IXL1394_ENO_DATA_PKTS: prog has no data packets"); 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS; 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate /* if no errors yet, find the first IXL command that's a transfer cmd */ 2657c478bd9Sstevel@tonic-gate if (wvp->dma_bld_error == 0) { 2667c478bd9Sstevel@tonic-gate err = hci1394_ixl_find_next_exec_xfer(wvp->ctxtp->ixl_firstp, 2677c478bd9Sstevel@tonic-gate NULL, &ixl_exec_stp); 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate /* error if a label<->jump loop, or no xfer */ 2707c478bd9Sstevel@tonic-gate if ((err == DDI_FAILURE) || (ixl_exec_stp == NULL)) { 2717c478bd9Sstevel@tonic-gate TNF_PROBE_1(hci1394_compile_ixl_endup_error, 2727c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 2737c478bd9Sstevel@tonic-gate "IXL1394_ENO_DATA_PKTS: loop or no xfer detected"); 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS; 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate /* Sync all the DMA descriptor buffers */ 2807c478bd9Sstevel@tonic-gate dma_nextp = wvp->ctxtp->dma_firstp; 2817c478bd9Sstevel@tonic-gate while (dma_nextp != NULL) { 2827c478bd9Sstevel@tonic-gate err = ddi_dma_sync(dma_nextp->mem.bi_dma_handle, 2837c478bd9Sstevel@tonic-gate (off_t)dma_nextp->mem.bi_kaddr, dma_nextp->mem.bi_length, 2847c478bd9Sstevel@tonic-gate DDI_DMA_SYNC_FORDEV); 2857c478bd9Sstevel@tonic-gate if (err != DDI_SUCCESS) { 2867c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EINTERNAL_ERROR; 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate TNF_PROBE_1(hci1394_compile_ixl_endup_error, 2897c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 2907c478bd9Sstevel@tonic-gate "IXL1394_INTERNAL_ERROR: dma_sync() failed"); 2917c478bd9Sstevel@tonic-gate break; 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate /* advance to next dma memory descriptor */ 2957c478bd9Sstevel@tonic-gate dma_nextp = dma_nextp->dma_nextp; 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate /* 2997c478bd9Sstevel@tonic-gate * If error, cleanup and return. delete all allocated xfer_ctl structs 3007c478bd9Sstevel@tonic-gate * and all dma descriptor page memory and its dma memory blocks too. 3017c478bd9Sstevel@tonic-gate */ 3027c478bd9Sstevel@tonic-gate if (wvp->dma_bld_error != 0) { 3037c478bd9Sstevel@tonic-gate wvp->ctxtp->xcs_firstp = (void *)wvp->xcs_firstp; 3047c478bd9Sstevel@tonic-gate wvp->ctxtp->dma_firstp = wvp->dma_firstp; 3057c478bd9Sstevel@tonic-gate hci1394_ixl_cleanup(wvp->soft_statep, wvp->ctxtp); 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_compile_ixl_endup_exit, 3087c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 3097c478bd9Sstevel@tonic-gate return; 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate /* can only get to here if the first ixl transfer command is found */ 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate /* set required processing vars into ctxtp struct */ 3157c478bd9Sstevel@tonic-gate wvp->ctxtp->default_skipxferp = wvp->default_skipxferp; 3167c478bd9Sstevel@tonic-gate wvp->ctxtp->dma_mem_execp = 0; 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate /* 3197c478bd9Sstevel@tonic-gate * the transfer command's compiler private xfer_ctl structure has the 3207c478bd9Sstevel@tonic-gate * appropriate bound address 3217c478bd9Sstevel@tonic-gate */ 3227c478bd9Sstevel@tonic-gate wvp->ctxtp->dma_mem_execp = (uint32_t)((hci1394_xfer_ctl_t *) 3237c478bd9Sstevel@tonic-gate ixl_exec_stp->compiler_privatep)->dma[0].dma_bound; 3247c478bd9Sstevel@tonic-gate wvp->ctxtp->xcs_firstp = (void *)wvp->xcs_firstp; 3257c478bd9Sstevel@tonic-gate wvp->ctxtp->dma_firstp = wvp->dma_firstp; 3267c478bd9Sstevel@tonic-gate wvp->ctxtp->dma_last_time = 0; 3277c478bd9Sstevel@tonic-gate wvp->ctxtp->ixl_exec_depth = 0; 3287c478bd9Sstevel@tonic-gate wvp->ctxtp->ixl_execp = NULL; 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate /* compile done */ 3317c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_compile_ixl_endup_exit, 3327c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate /* 3367c478bd9Sstevel@tonic-gate * hci1394_parse_ixl() 3377c478bd9Sstevel@tonic-gate * Scan IXL program and build ohci DMA descriptor blocks in dma memory. 3387c478bd9Sstevel@tonic-gate * 3397c478bd9Sstevel@tonic-gate * Parse/process succeeding ixl commands until end of IXL linked list is 3407c478bd9Sstevel@tonic-gate * reached. Evaluate ixl syntax and build (xmit or recv) descriptor 3417c478bd9Sstevel@tonic-gate * blocks. To aid execution time evaluation of current location, enable 3427c478bd9Sstevel@tonic-gate * status recording on each descriptor block built. 3437c478bd9Sstevel@tonic-gate * On xmit, set sync & tag bits. On recv, optionally set wait for sync bit. 3447c478bd9Sstevel@tonic-gate */ 3457c478bd9Sstevel@tonic-gate static void 3467c478bd9Sstevel@tonic-gate hci1394_parse_ixl(hci1394_comp_ixl_vars_t *wvp, ixl1394_command_t *ixlp) 3477c478bd9Sstevel@tonic-gate { 3487c478bd9Sstevel@tonic-gate ixl1394_command_t *ixlnextp = ixlp; /* addr of next ixl cmd */ 3497c478bd9Sstevel@tonic-gate ixl1394_command_t *ixlcurp = NULL; /* addr of current ixl cmd */ 3507c478bd9Sstevel@tonic-gate uint16_t ixlopcode = 0; /* opcode of currnt ixl cmd */ 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate uint32_t pktsize; 3537c478bd9Sstevel@tonic-gate uint32_t pktcnt; 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_parse_ixl_enter, HCI1394_TNF_HAL_STACK_ISOCH, 3567c478bd9Sstevel@tonic-gate ""); 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate /* follow ixl links until reach end or find error */ 3597c478bd9Sstevel@tonic-gate while ((ixlnextp != NULL) && (wvp->dma_bld_error == 0)) { 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate /* set this command as the current ixl command */ 3627c478bd9Sstevel@tonic-gate wvp->ixl_cur_cmdp = ixlcurp = ixlnextp; 3637c478bd9Sstevel@tonic-gate ixlnextp = ixlcurp->next_ixlp; 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate ixlopcode = ixlcurp->ixl_opcode; 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate /* init compiler controlled values in current ixl command */ 3687c478bd9Sstevel@tonic-gate ixlcurp->compiler_privatep = NULL; 3697c478bd9Sstevel@tonic-gate ixlcurp->compiler_resv = 0; 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate /* error if xmit/recv mode not appropriate for current cmd */ 3727c478bd9Sstevel@tonic-gate if ((((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) != 0) && 373*ffc2b7d4SToomas Soome ((ixlopcode & IXL1394_OPF_ONRECV) == 0)) || 3747c478bd9Sstevel@tonic-gate (((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) == 0) && 375*ffc2b7d4SToomas Soome ((ixlopcode & IXL1394_OPF_ONXMIT) == 0))) { 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate /* check if command op failed because it was invalid */ 3787c478bd9Sstevel@tonic-gate if (hci1394_is_opcode_valid(ixlopcode) != B_TRUE) { 3797c478bd9Sstevel@tonic-gate TNF_PROBE_3(hci1394_parse_ixl_bad_opcode_error, 3807c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 3817c478bd9Sstevel@tonic-gate errmsg, "IXL1394_BAD_IXL_OPCODE", 3827c478bd9Sstevel@tonic-gate tnf_opaque, ixl_commandp, ixlcurp, 3837c478bd9Sstevel@tonic-gate tnf_opaque, ixl_opcode, ixlopcode); 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EBAD_IXL_OPCODE; 3867c478bd9Sstevel@tonic-gate } else { 3877c478bd9Sstevel@tonic-gate TNF_PROBE_3(hci1394_parse_ixl_mode_error, 3887c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 3897c478bd9Sstevel@tonic-gate errmsg, "IXL1394_EWRONG_XR_CMD_MODE: " 3907c478bd9Sstevel@tonic-gate "invalid ixlop in mode", tnf_uint, io_mode, 3917c478bd9Sstevel@tonic-gate wvp->ixl_io_mode, tnf_opaque, ixl_opcode, 3927c478bd9Sstevel@tonic-gate ixlopcode); 3937c478bd9Sstevel@tonic-gate 3947c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EWRONG_XR_CMD_MODE; 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate continue; 3977c478bd9Sstevel@tonic-gate } 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate /* 4007c478bd9Sstevel@tonic-gate * if ends xfer flag set, finalize current xfer descriptor 4017c478bd9Sstevel@tonic-gate * block build 4027c478bd9Sstevel@tonic-gate */ 4037c478bd9Sstevel@tonic-gate if ((ixlopcode & IXL1394_OPF_ENDSXFER) != 0) { 4047c478bd9Sstevel@tonic-gate /* finalize any descriptor block build in progress */ 4057c478bd9Sstevel@tonic-gate hci1394_finalize_cur_xfer_desc(wvp); 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate if (wvp->dma_bld_error != 0) { 4087c478bd9Sstevel@tonic-gate continue; 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate } 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate /* 4137c478bd9Sstevel@tonic-gate * now process based on specific opcode value 4147c478bd9Sstevel@tonic-gate */ 4157c478bd9Sstevel@tonic-gate switch (ixlopcode) { 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate case IXL1394_OP_RECV_BUF: 4187c478bd9Sstevel@tonic-gate case IXL1394_OP_RECV_BUF_U: { 4197c478bd9Sstevel@tonic-gate ixl1394_xfer_buf_t *cur_xfer_buf_ixlp; 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate cur_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)ixlcurp; 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate /* 4247c478bd9Sstevel@tonic-gate * In packet-per-buffer mode: 4257c478bd9Sstevel@tonic-gate * This ixl command builds a collection of xfer 4267c478bd9Sstevel@tonic-gate * descriptor blocks (size/pkt_size of them) each to 4277c478bd9Sstevel@tonic-gate * recv a packet whose buffer size is pkt_size and 4287c478bd9Sstevel@tonic-gate * whose buffer ptr is (pktcur*pkt_size + bufp) 4297c478bd9Sstevel@tonic-gate * 4307c478bd9Sstevel@tonic-gate * In buffer fill mode: 4317c478bd9Sstevel@tonic-gate * This ixl command builds a single xfer descriptor 4327c478bd9Sstevel@tonic-gate * block to recv as many packets or parts of packets 4337c478bd9Sstevel@tonic-gate * as can fit into the buffer size specified 4347c478bd9Sstevel@tonic-gate * (pkt_size is not used). 4357c478bd9Sstevel@tonic-gate */ 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate /* set xfer_state for new descriptor block build */ 4387c478bd9Sstevel@tonic-gate wvp->xfer_state = XFER_BUF; 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate /* set this ixl command as current xferstart command */ 4417c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp = ixlcurp; 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate /* 4447c478bd9Sstevel@tonic-gate * perform packet-per-buffer checks 4457c478bd9Sstevel@tonic-gate * (no checks needed when in buffer fill mode) 4467c478bd9Sstevel@tonic-gate */ 4477c478bd9Sstevel@tonic-gate if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_BFFILL) == 0) { 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate /* the packets must use the buffer exactly */ 4507c478bd9Sstevel@tonic-gate pktsize = cur_xfer_buf_ixlp->pkt_size; 4517c478bd9Sstevel@tonic-gate pktcnt = 0; 4527c478bd9Sstevel@tonic-gate if (pktsize != 0) { 4537c478bd9Sstevel@tonic-gate pktcnt = cur_xfer_buf_ixlp->size / 4547c478bd9Sstevel@tonic-gate pktsize; 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate if ((pktcnt == 0) || ((pktsize * pktcnt) != 4577c478bd9Sstevel@tonic-gate cur_xfer_buf_ixlp->size)) { 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate TNF_PROBE_3(hci1394_parse_ixl_rat_error, 4607c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", 4617c478bd9Sstevel@tonic-gate tnf_string, errmsg, 4627c478bd9Sstevel@tonic-gate "IXL1394_EPKTSIZE_RATIO", tnf_int, 4637c478bd9Sstevel@tonic-gate buf_size, cur_xfer_buf_ixlp->size, 4647c478bd9Sstevel@tonic-gate tnf_int, pkt_size, pktsize); 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate wvp->dma_bld_error = 4677c478bd9Sstevel@tonic-gate IXL1394_EPKTSIZE_RATIO; 4687c478bd9Sstevel@tonic-gate continue; 4697c478bd9Sstevel@tonic-gate } 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate /* 4737c478bd9Sstevel@tonic-gate * set buffer pointer & size into first xfer_bufp 4747c478bd9Sstevel@tonic-gate * and xfer_size 4757c478bd9Sstevel@tonic-gate */ 4767c478bd9Sstevel@tonic-gate if (hci1394_set_next_xfer_buf(wvp, 4777c478bd9Sstevel@tonic-gate cur_xfer_buf_ixlp->ixl_buf.ixldmac_addr, 4787c478bd9Sstevel@tonic-gate cur_xfer_buf_ixlp->size) != DDI_SUCCESS) { 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 4817c478bd9Sstevel@tonic-gate continue; 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate break; 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate case IXL1394_OP_RECV_PKT_ST: 4877c478bd9Sstevel@tonic-gate case IXL1394_OP_RECV_PKT_ST_U: { 4887c478bd9Sstevel@tonic-gate ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp; 4897c478bd9Sstevel@tonic-gate 4907c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp; 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate /* error if in buffer fill mode */ 4937c478bd9Sstevel@tonic-gate if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_BFFILL) != 0) { 4947c478bd9Sstevel@tonic-gate TNF_PROBE_1(hci1394_parse_ixl_mode_error, 4957c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 4967c478bd9Sstevel@tonic-gate errmsg, "IXL1394_EWRONG_XR_CMD_MODE: " 4977c478bd9Sstevel@tonic-gate "RECV_PKT_ST used in BFFILL mode"); 4987c478bd9Sstevel@tonic-gate 4997c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EWRONG_XR_CMD_MODE; 5007c478bd9Sstevel@tonic-gate continue; 5017c478bd9Sstevel@tonic-gate } 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate /* set xfer_state for new descriptor block build */ 5047c478bd9Sstevel@tonic-gate /* set this ixl command as current xferstart command */ 5057c478bd9Sstevel@tonic-gate wvp->xfer_state = XFER_PKT; 5067c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp = ixlcurp; 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate /* 5097c478bd9Sstevel@tonic-gate * set buffer pointer & size into first xfer_bufp 5107c478bd9Sstevel@tonic-gate * and xfer_size 5117c478bd9Sstevel@tonic-gate */ 5127c478bd9Sstevel@tonic-gate if (hci1394_set_next_xfer_buf(wvp, 5137c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr, 5147c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp->size) != DDI_SUCCESS) { 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 5177c478bd9Sstevel@tonic-gate continue; 5187c478bd9Sstevel@tonic-gate } 5197c478bd9Sstevel@tonic-gate break; 5207c478bd9Sstevel@tonic-gate } 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate case IXL1394_OP_RECV_PKT: 5237c478bd9Sstevel@tonic-gate case IXL1394_OP_RECV_PKT_U: { 5247c478bd9Sstevel@tonic-gate ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp; 5257c478bd9Sstevel@tonic-gate 5267c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp; 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate /* error if in buffer fill mode */ 5297c478bd9Sstevel@tonic-gate if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_BFFILL) != 0) { 5307c478bd9Sstevel@tonic-gate TNF_PROBE_1(hci1394_parse_ixl_mode_error, 5317c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 5327c478bd9Sstevel@tonic-gate errmsg, "IXL1394_EWRONG_XR_CMD_MODE: " 5337c478bd9Sstevel@tonic-gate "RECV_PKT_ST used in BFFILL mode"); 5347c478bd9Sstevel@tonic-gate 5357c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EWRONG_XR_CMD_MODE; 5367c478bd9Sstevel@tonic-gate continue; 5377c478bd9Sstevel@tonic-gate } 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate /* error if xfer_state not xfer pkt */ 5407c478bd9Sstevel@tonic-gate if (wvp->xfer_state != XFER_PKT) { 5417c478bd9Sstevel@tonic-gate TNF_PROBE_1(hci1394_parse_ixl_misplacercv_error, 5427c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 5437c478bd9Sstevel@tonic-gate errmsg, "IXL1394_EMISPLACED_RECV: " 5447c478bd9Sstevel@tonic-gate "RECV_PKT without RECV_PKT_ST"); 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EMISPLACED_RECV; 5477c478bd9Sstevel@tonic-gate continue; 5487c478bd9Sstevel@tonic-gate } 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate /* 5517c478bd9Sstevel@tonic-gate * save xfer start cmd ixl ptr in compiler_privatep 5527c478bd9Sstevel@tonic-gate * field of this cmd 5537c478bd9Sstevel@tonic-gate */ 5547c478bd9Sstevel@tonic-gate ixlcurp->compiler_privatep = (void *) 5557c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp; 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate /* 5587c478bd9Sstevel@tonic-gate * save pkt index [1-n] in compiler_resv field of 5597c478bd9Sstevel@tonic-gate * this cmd 5607c478bd9Sstevel@tonic-gate */ 5617c478bd9Sstevel@tonic-gate ixlcurp->compiler_resv = wvp->xfer_bufcnt; 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate /* 5647c478bd9Sstevel@tonic-gate * set buffer pointer & size into next xfer_bufp 5657c478bd9Sstevel@tonic-gate * and xfer_size 5667c478bd9Sstevel@tonic-gate */ 5677c478bd9Sstevel@tonic-gate if (hci1394_set_next_xfer_buf(wvp, 5687c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr, 5697c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp->size) != DDI_SUCCESS) { 5707c478bd9Sstevel@tonic-gate 5717c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 5727c478bd9Sstevel@tonic-gate continue; 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate /* 5767c478bd9Sstevel@tonic-gate * set updateable xfer cache flush eval flag if 5777c478bd9Sstevel@tonic-gate * updateable opcode 5787c478bd9Sstevel@tonic-gate */ 5797c478bd9Sstevel@tonic-gate if ((ixlopcode & IXL1394_OPF_UPDATE) != 0) { 5807c478bd9Sstevel@tonic-gate wvp->xfer_hci_flush |= UPDATEABLE_XFER; 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate break; 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_BUF: 5867c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_BUF_U: { 5877c478bd9Sstevel@tonic-gate ixl1394_xfer_buf_t *cur_xfer_buf_ixlp; 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate cur_xfer_buf_ixlp = (ixl1394_xfer_buf_t *)ixlcurp; 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate /* 5927c478bd9Sstevel@tonic-gate * These send_buf commands build a collection of xmit 5937c478bd9Sstevel@tonic-gate * descriptor blocks (size/pkt_size of them) each to 5947c478bd9Sstevel@tonic-gate * xfer a packet whose buffer size is pkt_size and whose 5957c478bd9Sstevel@tonic-gate * buffer pt is (pktcur*pkt_size + bufp). (ptr and size 5967c478bd9Sstevel@tonic-gate * are adjusted if they have header form of ixl cmd) 5977c478bd9Sstevel@tonic-gate */ 5987c478bd9Sstevel@tonic-gate 5997c478bd9Sstevel@tonic-gate /* set xfer_state for new descriptor block build */ 6007c478bd9Sstevel@tonic-gate wvp->xfer_state = XFER_BUF; 6017c478bd9Sstevel@tonic-gate 6027c478bd9Sstevel@tonic-gate /* set this ixl command as current xferstart command */ 6037c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp = ixlcurp; 6047c478bd9Sstevel@tonic-gate 6057c478bd9Sstevel@tonic-gate /* the packets must use the buffer exactly,else error */ 6067c478bd9Sstevel@tonic-gate pktsize = cur_xfer_buf_ixlp->pkt_size; 6077c478bd9Sstevel@tonic-gate pktcnt = 0; 6087c478bd9Sstevel@tonic-gate if (pktsize != 0) { 6097c478bd9Sstevel@tonic-gate pktcnt = cur_xfer_buf_ixlp->size / pktsize; 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate if ((pktcnt == 0) || ((pktsize * pktcnt) != 6127c478bd9Sstevel@tonic-gate cur_xfer_buf_ixlp->size)) { 6137c478bd9Sstevel@tonic-gate 6147c478bd9Sstevel@tonic-gate TNF_PROBE_3(hci1394_parse_ixl_rat_error, 6157c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 6167c478bd9Sstevel@tonic-gate errmsg, "IXL1394_EPKTSIZE_RATIO", tnf_int, 6177c478bd9Sstevel@tonic-gate buf_size, cur_xfer_buf_ixlp->size, tnf_int, 6187c478bd9Sstevel@tonic-gate pkt_size, pktsize); 6197c478bd9Sstevel@tonic-gate 6207c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EPKTSIZE_RATIO; 6217c478bd9Sstevel@tonic-gate continue; 6227c478bd9Sstevel@tonic-gate } 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate /* set buf ptr & size into 1st xfer_bufp & xfer_size */ 6257c478bd9Sstevel@tonic-gate if (hci1394_set_next_xfer_buf(wvp, 6267c478bd9Sstevel@tonic-gate cur_xfer_buf_ixlp->ixl_buf.ixldmac_addr, 6277c478bd9Sstevel@tonic-gate cur_xfer_buf_ixlp->size) != DDI_SUCCESS) { 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 6307c478bd9Sstevel@tonic-gate continue; 6317c478bd9Sstevel@tonic-gate } 6327c478bd9Sstevel@tonic-gate break; 6337c478bd9Sstevel@tonic-gate } 6347c478bd9Sstevel@tonic-gate 6357c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_PKT_ST: 6367c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_PKT_ST_U: { 6377c478bd9Sstevel@tonic-gate ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp; 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp; 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate /* set xfer_state for new descriptor block build */ 6427c478bd9Sstevel@tonic-gate /* set this ixl command as current xferstart command */ 6437c478bd9Sstevel@tonic-gate wvp->xfer_state = XFER_PKT; 6447c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp = ixlcurp; 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate /* 6477c478bd9Sstevel@tonic-gate * set buffer pointer & size into first xfer_bufp and 6487c478bd9Sstevel@tonic-gate * xfer_size 6497c478bd9Sstevel@tonic-gate */ 6507c478bd9Sstevel@tonic-gate if (hci1394_set_next_xfer_buf(wvp, 6517c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr, 6527c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp->size) != DDI_SUCCESS) { 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 6557c478bd9Sstevel@tonic-gate continue; 6567c478bd9Sstevel@tonic-gate } 6577c478bd9Sstevel@tonic-gate break; 6587c478bd9Sstevel@tonic-gate } 6597c478bd9Sstevel@tonic-gate 6607c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_PKT_WHDR_ST: 6617c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_PKT_WHDR_ST_U: { 6627c478bd9Sstevel@tonic-gate ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp; 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp; 6657c478bd9Sstevel@tonic-gate 6667c478bd9Sstevel@tonic-gate /* set xfer_state for new descriptor block build */ 6677c478bd9Sstevel@tonic-gate /* set this ixl command as current xferstart command */ 6687c478bd9Sstevel@tonic-gate wvp->xfer_state = XFER_PKT; 6697c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp = ixlcurp; 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate /* 6727c478bd9Sstevel@tonic-gate * buffer size must be at least 4 (must include header), 6737c478bd9Sstevel@tonic-gate * else error 6747c478bd9Sstevel@tonic-gate */ 6757c478bd9Sstevel@tonic-gate if (cur_xfer_pkt_ixlp->size < 4) { 6767c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_parse_ixl_hdr_missing_error, 6777c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 6787c478bd9Sstevel@tonic-gate errmsg, "IXL1394_EPKT_HDR_MISSING", tnf_int, 6797c478bd9Sstevel@tonic-gate pkt_size, cur_xfer_pkt_ixlp->size); 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EPKT_HDR_MISSING; 6827c478bd9Sstevel@tonic-gate continue; 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate /* 6867c478bd9Sstevel@tonic-gate * set buffer and size(excluding header) into first 6877c478bd9Sstevel@tonic-gate * xfer_bufp and xfer_size 6887c478bd9Sstevel@tonic-gate */ 6897c478bd9Sstevel@tonic-gate if (hci1394_set_next_xfer_buf(wvp, 6907c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr + 4, 6917c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp->size - 4) != DDI_SUCCESS) { 6927c478bd9Sstevel@tonic-gate 6937c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 6947c478bd9Sstevel@tonic-gate continue; 6957c478bd9Sstevel@tonic-gate } 6967c478bd9Sstevel@tonic-gate break; 6977c478bd9Sstevel@tonic-gate } 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_PKT: 7007c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_PKT_U: { 7017c478bd9Sstevel@tonic-gate ixl1394_xfer_pkt_t *cur_xfer_pkt_ixlp; 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp = (ixl1394_xfer_pkt_t *)ixlcurp; 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate /* error if xfer_state not xfer pkt */ 7067c478bd9Sstevel@tonic-gate if (wvp->xfer_state != XFER_PKT) { 7077c478bd9Sstevel@tonic-gate TNF_PROBE_1(hci1394_parse_ixl_misplacesnd_error, 7087c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 7097c478bd9Sstevel@tonic-gate errmsg, "IXL1394_EMISPLACED_SEND: SEND_PKT " 7107c478bd9Sstevel@tonic-gate "without SEND_PKT_ST"); 7117c478bd9Sstevel@tonic-gate 7127c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EMISPLACED_SEND; 7137c478bd9Sstevel@tonic-gate continue; 7147c478bd9Sstevel@tonic-gate } 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate /* 7177c478bd9Sstevel@tonic-gate * save xfer start cmd ixl ptr in compiler_privatep 7187c478bd9Sstevel@tonic-gate * field of this cmd 7197c478bd9Sstevel@tonic-gate */ 7207c478bd9Sstevel@tonic-gate ixlcurp->compiler_privatep = (void *) 7217c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp; 7227c478bd9Sstevel@tonic-gate 7237c478bd9Sstevel@tonic-gate /* 7247c478bd9Sstevel@tonic-gate * save pkt index [1-n] in compiler_resv field of this 7257c478bd9Sstevel@tonic-gate * cmd 7267c478bd9Sstevel@tonic-gate */ 7277c478bd9Sstevel@tonic-gate ixlcurp->compiler_resv = wvp->xfer_bufcnt; 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate /* 7307c478bd9Sstevel@tonic-gate * set buffer pointer & size into next xfer_bufp 7317c478bd9Sstevel@tonic-gate * and xfer_size 7327c478bd9Sstevel@tonic-gate */ 7337c478bd9Sstevel@tonic-gate if (hci1394_set_next_xfer_buf(wvp, 7347c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp->ixl_buf.ixldmac_addr, 7357c478bd9Sstevel@tonic-gate cur_xfer_pkt_ixlp->size) != DDI_SUCCESS) { 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 7387c478bd9Sstevel@tonic-gate continue; 7397c478bd9Sstevel@tonic-gate } 7407c478bd9Sstevel@tonic-gate 7417c478bd9Sstevel@tonic-gate /* 7427c478bd9Sstevel@tonic-gate * set updateable xfer cache flush eval flag if 7437c478bd9Sstevel@tonic-gate * updateable opcode 7447c478bd9Sstevel@tonic-gate */ 7457c478bd9Sstevel@tonic-gate if ((ixlopcode & IXL1394_OPF_UPDATE) != 0) { 7467c478bd9Sstevel@tonic-gate wvp->xfer_hci_flush |= UPDATEABLE_XFER; 7477c478bd9Sstevel@tonic-gate } 7487c478bd9Sstevel@tonic-gate break; 7497c478bd9Sstevel@tonic-gate } 7507c478bd9Sstevel@tonic-gate 7517c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_HDR_ONLY: 7527c478bd9Sstevel@tonic-gate /* set xfer_state for new descriptor block build */ 7537c478bd9Sstevel@tonic-gate wvp->xfer_state = XMIT_HDRONLY; 7547c478bd9Sstevel@tonic-gate 7557c478bd9Sstevel@tonic-gate /* set this ixl command as current xferstart command */ 7567c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp = ixlcurp; 7577c478bd9Sstevel@tonic-gate break; 7587c478bd9Sstevel@tonic-gate 7597c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_NO_PKT: 7607c478bd9Sstevel@tonic-gate /* set xfer_state for new descriptor block build */ 7617c478bd9Sstevel@tonic-gate wvp->xfer_state = XMIT_NOPKT; 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate /* set this ixl command as current xferstart command */ 7647c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp = ixlcurp; 7657c478bd9Sstevel@tonic-gate break; 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate case IXL1394_OP_JUMP: 7687c478bd9Sstevel@tonic-gate case IXL1394_OP_JUMP_U: { 7697c478bd9Sstevel@tonic-gate ixl1394_jump_t *cur_jump_ixlp; 7707c478bd9Sstevel@tonic-gate 7717c478bd9Sstevel@tonic-gate cur_jump_ixlp = (ixl1394_jump_t *)ixlcurp; 7727c478bd9Sstevel@tonic-gate 7737c478bd9Sstevel@tonic-gate /* 7747c478bd9Sstevel@tonic-gate * verify label indicated by IXL1394_OP_JUMP is 7757c478bd9Sstevel@tonic-gate * actually an IXL1394_OP_LABEL or NULL 7767c478bd9Sstevel@tonic-gate */ 7777c478bd9Sstevel@tonic-gate if ((cur_jump_ixlp->label != NULL) && 7787c478bd9Sstevel@tonic-gate (cur_jump_ixlp->label->ixl_opcode != 7797c478bd9Sstevel@tonic-gate IXL1394_OP_LABEL)) { 7807c478bd9Sstevel@tonic-gate TNF_PROBE_3(hci1394_parse_ixl_jumplabel_error, 7817c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 7827c478bd9Sstevel@tonic-gate errmsg, "IXL1394_EJUMP_NOT_TO_LABEL", 7837c478bd9Sstevel@tonic-gate tnf_opaque, jumpixl_commandp, ixlcurp, 7847c478bd9Sstevel@tonic-gate tnf_opaque, jumpto_ixl, 7857c478bd9Sstevel@tonic-gate cur_jump_ixlp->label); 7867c478bd9Sstevel@tonic-gate 7877c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EJUMP_NOT_TO_LABEL; 7887c478bd9Sstevel@tonic-gate continue; 7897c478bd9Sstevel@tonic-gate } 7907c478bd9Sstevel@tonic-gate break; 7917c478bd9Sstevel@tonic-gate } 7927c478bd9Sstevel@tonic-gate 7937c478bd9Sstevel@tonic-gate case IXL1394_OP_LABEL: 7947c478bd9Sstevel@tonic-gate /* 7957c478bd9Sstevel@tonic-gate * save current ixl label command for xfer cmd 7967c478bd9Sstevel@tonic-gate * finalize processing 7977c478bd9Sstevel@tonic-gate */ 7987c478bd9Sstevel@tonic-gate wvp->ixl_cur_labelp = ixlcurp; 7997c478bd9Sstevel@tonic-gate 8007c478bd9Sstevel@tonic-gate /* set initiating label flag to cause cache flush */ 8017c478bd9Sstevel@tonic-gate wvp->xfer_hci_flush |= INITIATING_LBL; 8027c478bd9Sstevel@tonic-gate break; 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate case IXL1394_OP_CALLBACK: 8057c478bd9Sstevel@tonic-gate case IXL1394_OP_CALLBACK_U: 8067c478bd9Sstevel@tonic-gate case IXL1394_OP_STORE_TIMESTAMP: 8077c478bd9Sstevel@tonic-gate /* 8087c478bd9Sstevel@tonic-gate * these commands are accepted during compile, 8097c478bd9Sstevel@tonic-gate * processed during execution (interrupt handling) 8107c478bd9Sstevel@tonic-gate * No further processing is needed here. 8117c478bd9Sstevel@tonic-gate */ 8127c478bd9Sstevel@tonic-gate break; 8137c478bd9Sstevel@tonic-gate 8147c478bd9Sstevel@tonic-gate case IXL1394_OP_SET_SKIPMODE: 8157c478bd9Sstevel@tonic-gate case IXL1394_OP_SET_SKIPMODE_U: 8167c478bd9Sstevel@tonic-gate /* 8177c478bd9Sstevel@tonic-gate * Error if already have a set skipmode cmd for 8187c478bd9Sstevel@tonic-gate * this xfer 8197c478bd9Sstevel@tonic-gate */ 8207c478bd9Sstevel@tonic-gate if (wvp->ixl_setskipmode_cmdp != NULL) { 8217c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_parse_ixl_dup_set_error, 8227c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 8237c478bd9Sstevel@tonic-gate errmsg, "IXL1394_EDUPLICATE_SET_CMD:" 8247c478bd9Sstevel@tonic-gate " duplicate set skipmode", tnf_opaque, 8257c478bd9Sstevel@tonic-gate ixl_commandp, ixlcurp); 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EDUPLICATE_SET_CMD; 8287c478bd9Sstevel@tonic-gate continue; 8297c478bd9Sstevel@tonic-gate } 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate /* save skip mode ixl command and verify skipmode */ 8327c478bd9Sstevel@tonic-gate wvp->ixl_setskipmode_cmdp = (ixl1394_set_skipmode_t *) 8337c478bd9Sstevel@tonic-gate ixlcurp; 8347c478bd9Sstevel@tonic-gate 8357c478bd9Sstevel@tonic-gate if ((wvp->ixl_setskipmode_cmdp->skipmode != 836*ffc2b7d4SToomas Soome IXL1394_SKIP_TO_NEXT) && 8377c478bd9Sstevel@tonic-gate (wvp->ixl_setskipmode_cmdp->skipmode != 838*ffc2b7d4SToomas Soome IXL1394_SKIP_TO_SELF) && 8397c478bd9Sstevel@tonic-gate (wvp->ixl_setskipmode_cmdp->skipmode != 840*ffc2b7d4SToomas Soome IXL1394_SKIP_TO_STOP) && 8417c478bd9Sstevel@tonic-gate (wvp->ixl_setskipmode_cmdp->skipmode != 842*ffc2b7d4SToomas Soome IXL1394_SKIP_TO_LABEL)) { 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate TNF_PROBE_3(hci1394_parse_ixl_dup_set_error, 8457c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 8467c478bd9Sstevel@tonic-gate errmsg, "IXL EBAD_SKIPMODE", tnf_opaque, 8477c478bd9Sstevel@tonic-gate ixl_commandp, ixlcurp, tnf_int, skip, 8487c478bd9Sstevel@tonic-gate wvp->ixl_setskipmode_cmdp->skipmode); 8497c478bd9Sstevel@tonic-gate 8507c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EBAD_SKIPMODE; 8517c478bd9Sstevel@tonic-gate continue; 8527c478bd9Sstevel@tonic-gate } 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate /* 8557c478bd9Sstevel@tonic-gate * if mode is IXL1394_SKIP_TO_LABEL, verify label 8567c478bd9Sstevel@tonic-gate * references an IXL1394_OP_LABEL 8577c478bd9Sstevel@tonic-gate */ 8587c478bd9Sstevel@tonic-gate if ((wvp->ixl_setskipmode_cmdp->skipmode == 859*ffc2b7d4SToomas Soome IXL1394_SKIP_TO_LABEL) && 8607c478bd9Sstevel@tonic-gate ((wvp->ixl_setskipmode_cmdp->label == NULL) || 8617c478bd9Sstevel@tonic-gate (wvp->ixl_setskipmode_cmdp->label->ixl_opcode != 862*ffc2b7d4SToomas Soome IXL1394_OP_LABEL))) { 8637c478bd9Sstevel@tonic-gate 8647c478bd9Sstevel@tonic-gate TNF_PROBE_3(hci1394_parse_ixl_jump_error, 8657c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 8667c478bd9Sstevel@tonic-gate errmsg, "IXL1394_EJUMP_NOT_TO_LABEL", 8677c478bd9Sstevel@tonic-gate tnf_opaque, jumpixl_commandp, ixlcurp, 8687c478bd9Sstevel@tonic-gate tnf_opaque, jumpto_ixl, 8697c478bd9Sstevel@tonic-gate wvp->ixl_setskipmode_cmdp->label); 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EJUMP_NOT_TO_LABEL; 8727c478bd9Sstevel@tonic-gate continue; 8737c478bd9Sstevel@tonic-gate } 8747c478bd9Sstevel@tonic-gate /* 8757c478bd9Sstevel@tonic-gate * set updateable set cmd cache flush eval flag if 8767c478bd9Sstevel@tonic-gate * updateable opcode 8777c478bd9Sstevel@tonic-gate */ 8787c478bd9Sstevel@tonic-gate if ((ixlopcode & IXL1394_OPF_UPDATE) != 0) { 8797c478bd9Sstevel@tonic-gate wvp->xfer_hci_flush |= UPDATEABLE_SET; 8807c478bd9Sstevel@tonic-gate } 8817c478bd9Sstevel@tonic-gate break; 8827c478bd9Sstevel@tonic-gate 8837c478bd9Sstevel@tonic-gate case IXL1394_OP_SET_TAGSYNC: 8847c478bd9Sstevel@tonic-gate case IXL1394_OP_SET_TAGSYNC_U: 8857c478bd9Sstevel@tonic-gate /* 8867c478bd9Sstevel@tonic-gate * is an error if already have a set tag and sync cmd 8877c478bd9Sstevel@tonic-gate * for this xfer 8887c478bd9Sstevel@tonic-gate */ 8897c478bd9Sstevel@tonic-gate if (wvp->ixl_settagsync_cmdp != NULL) { 8907c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_parse_ixl_dup_set_error, 8917c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 8927c478bd9Sstevel@tonic-gate errmsg, "IXL1394_EDUPLICATE_SET_CMD:" 8937c478bd9Sstevel@tonic-gate " duplicate set tagsync", tnf_opaque, 8947c478bd9Sstevel@tonic-gate ixl_commandp, ixlcurp); 8957c478bd9Sstevel@tonic-gate 8967c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EDUPLICATE_SET_CMD; 8977c478bd9Sstevel@tonic-gate continue; 8987c478bd9Sstevel@tonic-gate } 8997c478bd9Sstevel@tonic-gate 9007c478bd9Sstevel@tonic-gate /* save ixl command containing tag and sync values */ 9017c478bd9Sstevel@tonic-gate wvp->ixl_settagsync_cmdp = 9027c478bd9Sstevel@tonic-gate (ixl1394_set_tagsync_t *)ixlcurp; 9037c478bd9Sstevel@tonic-gate 9047c478bd9Sstevel@tonic-gate /* 9057c478bd9Sstevel@tonic-gate * set updateable set cmd cache flush eval flag if 9067c478bd9Sstevel@tonic-gate * updateable opcode 9077c478bd9Sstevel@tonic-gate */ 9087c478bd9Sstevel@tonic-gate if ((ixlopcode & IXL1394_OPF_UPDATE) != 0) { 9097c478bd9Sstevel@tonic-gate wvp->xfer_hci_flush |= UPDATEABLE_SET; 9107c478bd9Sstevel@tonic-gate } 9117c478bd9Sstevel@tonic-gate break; 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate case IXL1394_OP_SET_SYNCWAIT: 9147c478bd9Sstevel@tonic-gate /* 9157c478bd9Sstevel@tonic-gate * count ixl wait-for-sync commands since last 9167c478bd9Sstevel@tonic-gate * finalize ignore multiple occurrences for same xfer 9177c478bd9Sstevel@tonic-gate * command 9187c478bd9Sstevel@tonic-gate */ 9197c478bd9Sstevel@tonic-gate wvp->ixl_setsyncwait_cnt++; 9207c478bd9Sstevel@tonic-gate break; 9217c478bd9Sstevel@tonic-gate 9227c478bd9Sstevel@tonic-gate default: 9237c478bd9Sstevel@tonic-gate /* error - unknown/unimplemented ixl command */ 9247c478bd9Sstevel@tonic-gate TNF_PROBE_3(hci1394_parse_ixl_bad_opcode_error, 9257c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 9267c478bd9Sstevel@tonic-gate "IXL1394_BAD_IXL_OPCODE", tnf_opaque, ixl_commandp, 9277c478bd9Sstevel@tonic-gate ixlcurp, tnf_opaque, ixl_opcode, ixlopcode); 9287c478bd9Sstevel@tonic-gate 9297c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EBAD_IXL_OPCODE; 9307c478bd9Sstevel@tonic-gate continue; 9317c478bd9Sstevel@tonic-gate } 9327c478bd9Sstevel@tonic-gate } /* while */ 9337c478bd9Sstevel@tonic-gate 9347c478bd9Sstevel@tonic-gate /* finalize any last descriptor block build */ 9357c478bd9Sstevel@tonic-gate wvp->ixl_cur_cmdp = NULL; 9367c478bd9Sstevel@tonic-gate if (wvp->dma_bld_error == 0) { 9377c478bd9Sstevel@tonic-gate hci1394_finalize_cur_xfer_desc(wvp); 9387c478bd9Sstevel@tonic-gate } 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_parse_ixl_exit, 9417c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 9427c478bd9Sstevel@tonic-gate } 9437c478bd9Sstevel@tonic-gate 9447c478bd9Sstevel@tonic-gate /* 9457c478bd9Sstevel@tonic-gate * hci1394_finalize_all_xfer_desc() 9467c478bd9Sstevel@tonic-gate * Pass 2: Scan IXL resolving all dma descriptor jump and skip addresses. 9477c478bd9Sstevel@tonic-gate * 9487c478bd9Sstevel@tonic-gate * Set interrupt enable on first descriptor block associated with current 9497c478bd9Sstevel@tonic-gate * xfer IXL command if current IXL xfer was introduced by an IXL label cmnd. 9507c478bd9Sstevel@tonic-gate * 9517c478bd9Sstevel@tonic-gate * Set interrupt enable on last descriptor block associated with current xfer 9527c478bd9Sstevel@tonic-gate * IXL command if any callback ixl commands are found on the execution path 9537c478bd9Sstevel@tonic-gate * between the current and the next xfer ixl command. (Previously, this 9547c478bd9Sstevel@tonic-gate * applied to store timestamp ixl commands, as well.) 9557c478bd9Sstevel@tonic-gate */ 9567c478bd9Sstevel@tonic-gate static void 9577c478bd9Sstevel@tonic-gate hci1394_finalize_all_xfer_desc(hci1394_comp_ixl_vars_t *wvp) 9587c478bd9Sstevel@tonic-gate { 9597c478bd9Sstevel@tonic-gate ixl1394_command_t *ixlcurp; /* current ixl command */ 9607c478bd9Sstevel@tonic-gate ixl1394_command_t *ixlnextp; /* next ixl command */ 9617c478bd9Sstevel@tonic-gate ixl1394_command_t *ixlexecnext; 9627c478bd9Sstevel@tonic-gate hci1394_xfer_ctl_t *xferctl_curp; 9637c478bd9Sstevel@tonic-gate hci1394_xfer_ctl_t *xferctl_nxtp; 9647c478bd9Sstevel@tonic-gate hci1394_desc_t *hcidescp; 9657c478bd9Sstevel@tonic-gate ddi_acc_handle_t acc_hdl; 9667c478bd9Sstevel@tonic-gate uint32_t temp; 9677c478bd9Sstevel@tonic-gate uint32_t dma_execnext_addr; 9687c478bd9Sstevel@tonic-gate uint32_t dma_skiplabel_addr; 9697c478bd9Sstevel@tonic-gate uint32_t dma_skip_addr; 9707c478bd9Sstevel@tonic-gate uint32_t callback_cnt; 9717c478bd9Sstevel@tonic-gate uint16_t repcnt; 9727c478bd9Sstevel@tonic-gate uint16_t ixlopcode; 9737c478bd9Sstevel@tonic-gate int ii; 9747c478bd9Sstevel@tonic-gate int err; 9757c478bd9Sstevel@tonic-gate 9767c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_finalize_all_xfer_desc_enter, 9777c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 9787c478bd9Sstevel@tonic-gate 9797c478bd9Sstevel@tonic-gate /* 9807c478bd9Sstevel@tonic-gate * If xmit mode and if default skipmode is skip to label - 9817c478bd9Sstevel@tonic-gate * follow exec path starting at default skipmode label until 9827c478bd9Sstevel@tonic-gate * find the first ixl xfer command which is to be executed. 9837c478bd9Sstevel@tonic-gate * Set its address into default_skipxferp. 9847c478bd9Sstevel@tonic-gate */ 9857c478bd9Sstevel@tonic-gate if (((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) == 0) && 9867c478bd9Sstevel@tonic-gate (wvp->ctxtp->default_skipmode == IXL1394_SKIP_TO_LABEL)) { 9877c478bd9Sstevel@tonic-gate 9887c478bd9Sstevel@tonic-gate err = hci1394_ixl_find_next_exec_xfer(wvp->default_skiplabelp, 9897c478bd9Sstevel@tonic-gate NULL, &wvp->default_skipxferp); 9907c478bd9Sstevel@tonic-gate if (err == DDI_FAILURE) { 9917c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_finalize_all_xfer_desc_error, 9927c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 9937c478bd9Sstevel@tonic-gate "IXL1394_ENO_DATA_PKTS: label<->jump loop detected " 9947c478bd9Sstevel@tonic-gate "for skiplabel default w/no xfers", tnf_opaque, 9957c478bd9Sstevel@tonic-gate skipixl_cmdp, wvp->default_skiplabelp); 9967c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_finalize_all_xfer_desc_exit, 9977c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 9987c478bd9Sstevel@tonic-gate 9997c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS; 10007c478bd9Sstevel@tonic-gate return; 10017c478bd9Sstevel@tonic-gate } 10027c478bd9Sstevel@tonic-gate } 10037c478bd9Sstevel@tonic-gate 10047c478bd9Sstevel@tonic-gate /* set first ixl cmd */ 10057c478bd9Sstevel@tonic-gate ixlnextp = wvp->ctxtp->ixl_firstp; 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate /* follow ixl links until reach end or find error */ 10087c478bd9Sstevel@tonic-gate while ((ixlnextp != NULL) && (wvp->dma_bld_error == 0)) { 10097c478bd9Sstevel@tonic-gate 10107c478bd9Sstevel@tonic-gate /* set this command as the current ixl command */ 10117c478bd9Sstevel@tonic-gate ixlcurp = ixlnextp; 10127c478bd9Sstevel@tonic-gate ixlnextp = ixlcurp->next_ixlp; 10137c478bd9Sstevel@tonic-gate 10147c478bd9Sstevel@tonic-gate /* get command opcode removing unneeded update flag */ 10157c478bd9Sstevel@tonic-gate ixlopcode = ixlcurp->ixl_opcode & ~IXL1394_OPF_UPDATE; 10167c478bd9Sstevel@tonic-gate 10177c478bd9Sstevel@tonic-gate /* 10187c478bd9Sstevel@tonic-gate * Scan for next ixl xfer start command (including this one), 10197c478bd9Sstevel@tonic-gate * along ixl link path. Once xfer command found, find next IXL 10207c478bd9Sstevel@tonic-gate * xfer cmd along execution path and fill in branch address of 10217c478bd9Sstevel@tonic-gate * current xfer command. If is composite ixl xfer command, first 10227c478bd9Sstevel@tonic-gate * link forward branch dma addresses of each descriptor block in 10237c478bd9Sstevel@tonic-gate * composite, until reach final one then set its branch address 10247c478bd9Sstevel@tonic-gate * to next execution path xfer found. Next determine skip mode 10257c478bd9Sstevel@tonic-gate * and fill in skip address(es) appropriately. 10267c478bd9Sstevel@tonic-gate */ 10277c478bd9Sstevel@tonic-gate /* skip to next if not xfer start ixl command */ 10287c478bd9Sstevel@tonic-gate if (((ixlopcode & IXL1394_OPF_ISXFER) == 0) || 10297c478bd9Sstevel@tonic-gate ((ixlopcode & IXL1394_OPTY_MASK) == 0)) { 10307c478bd9Sstevel@tonic-gate continue; 10317c478bd9Sstevel@tonic-gate } 10327c478bd9Sstevel@tonic-gate 10337c478bd9Sstevel@tonic-gate /* 10347c478bd9Sstevel@tonic-gate * get xfer_ctl structure and composite repeat count for current 10357c478bd9Sstevel@tonic-gate * IXL xfer cmd 10367c478bd9Sstevel@tonic-gate */ 10377c478bd9Sstevel@tonic-gate xferctl_curp = (hci1394_xfer_ctl_t *)ixlcurp->compiler_privatep; 10387c478bd9Sstevel@tonic-gate repcnt = xferctl_curp->cnt; 10397c478bd9Sstevel@tonic-gate 10407c478bd9Sstevel@tonic-gate /* 10417c478bd9Sstevel@tonic-gate * if initiated by an IXL label command, set interrupt enable 10427c478bd9Sstevel@tonic-gate * flag into last component of first descriptor block of 10437c478bd9Sstevel@tonic-gate * current IXL xfer cmd 10447c478bd9Sstevel@tonic-gate */ 10457c478bd9Sstevel@tonic-gate if ((xferctl_curp->ctl_flags & XCTL_LABELLED) != 0) { 10467c478bd9Sstevel@tonic-gate hcidescp = (hci1394_desc_t *) 10477c478bd9Sstevel@tonic-gate xferctl_curp->dma[0].dma_descp; 10487c478bd9Sstevel@tonic-gate acc_hdl = xferctl_curp->dma[0].dma_buf->bi_handle; 10497c478bd9Sstevel@tonic-gate temp = ddi_get32(acc_hdl, &hcidescp->hdr); 10507c478bd9Sstevel@tonic-gate temp |= DESC_INTR_ENBL; 10517c478bd9Sstevel@tonic-gate ddi_put32(acc_hdl, &hcidescp->hdr, temp); 10527c478bd9Sstevel@tonic-gate } 10537c478bd9Sstevel@tonic-gate 10547c478bd9Sstevel@tonic-gate /* find next xfer IXL cmd by following execution path */ 10557c478bd9Sstevel@tonic-gate err = hci1394_ixl_find_next_exec_xfer(ixlcurp->next_ixlp, 10567c478bd9Sstevel@tonic-gate &callback_cnt, &ixlexecnext); 10577c478bd9Sstevel@tonic-gate 10587c478bd9Sstevel@tonic-gate /* if label<->jump loop detected, return error */ 10597c478bd9Sstevel@tonic-gate if (err == DDI_FAILURE) { 10607c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS; 10617c478bd9Sstevel@tonic-gate 10627c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_finalize_all_xfer_desc_error, 10637c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 10647c478bd9Sstevel@tonic-gate "IXL1394_ENO_DATA_PKTS: label<->jump loop detected " 10657c478bd9Sstevel@tonic-gate "w/no xfers", tnf_opaque, ixl_cmdp, 10667c478bd9Sstevel@tonic-gate ixlcurp->next_ixlp); 10677c478bd9Sstevel@tonic-gate continue; 10687c478bd9Sstevel@tonic-gate } 10697c478bd9Sstevel@tonic-gate 10707c478bd9Sstevel@tonic-gate /* link current IXL's xfer_ctl to next xfer IXL on exec path */ 10717c478bd9Sstevel@tonic-gate xferctl_curp->execp = ixlexecnext; 10727c478bd9Sstevel@tonic-gate 10737c478bd9Sstevel@tonic-gate /* 10747c478bd9Sstevel@tonic-gate * if callbacks have been seen during execution path scan, 10757c478bd9Sstevel@tonic-gate * set interrupt enable flag into last descriptor of last 10767c478bd9Sstevel@tonic-gate * descriptor block of current IXL xfer cmd 10777c478bd9Sstevel@tonic-gate */ 10787c478bd9Sstevel@tonic-gate if (callback_cnt != 0) { 10797c478bd9Sstevel@tonic-gate hcidescp = (hci1394_desc_t *) 10807c478bd9Sstevel@tonic-gate xferctl_curp->dma[repcnt - 1].dma_descp; 10817c478bd9Sstevel@tonic-gate acc_hdl = 10827c478bd9Sstevel@tonic-gate xferctl_curp->dma[repcnt - 1].dma_buf->bi_handle; 10837c478bd9Sstevel@tonic-gate temp = ddi_get32(acc_hdl, &hcidescp->hdr); 10847c478bd9Sstevel@tonic-gate temp |= DESC_INTR_ENBL; 10857c478bd9Sstevel@tonic-gate ddi_put32(acc_hdl, &hcidescp->hdr, temp); 10867c478bd9Sstevel@tonic-gate } 10877c478bd9Sstevel@tonic-gate 10887c478bd9Sstevel@tonic-gate /* 10897c478bd9Sstevel@tonic-gate * obtain dma bound addr of next exec path IXL xfer command, 10907c478bd9Sstevel@tonic-gate * if any 10917c478bd9Sstevel@tonic-gate */ 10927c478bd9Sstevel@tonic-gate dma_execnext_addr = 0; 10937c478bd9Sstevel@tonic-gate 10947c478bd9Sstevel@tonic-gate if (ixlexecnext != NULL) { 10957c478bd9Sstevel@tonic-gate xferctl_nxtp = (hci1394_xfer_ctl_t *) 10967c478bd9Sstevel@tonic-gate ixlexecnext->compiler_privatep; 10977c478bd9Sstevel@tonic-gate dma_execnext_addr = xferctl_nxtp->dma[0].dma_bound; 10987c478bd9Sstevel@tonic-gate } else { 10997c478bd9Sstevel@tonic-gate /* 11007c478bd9Sstevel@tonic-gate * If this is last descriptor (next == NULL), then 11017c478bd9Sstevel@tonic-gate * make sure the interrupt bit is enabled. This 11027c478bd9Sstevel@tonic-gate * way we can ensure that we are notified when the 11037c478bd9Sstevel@tonic-gate * descriptor chain processing has come to an end. 11047c478bd9Sstevel@tonic-gate */ 11057c478bd9Sstevel@tonic-gate hcidescp = (hci1394_desc_t *) 11067c478bd9Sstevel@tonic-gate xferctl_curp->dma[repcnt - 1].dma_descp; 11077c478bd9Sstevel@tonic-gate acc_hdl = 11087c478bd9Sstevel@tonic-gate xferctl_curp->dma[repcnt - 1].dma_buf->bi_handle; 11097c478bd9Sstevel@tonic-gate temp = ddi_get32(acc_hdl, &hcidescp->hdr); 11107c478bd9Sstevel@tonic-gate temp |= DESC_INTR_ENBL; 11117c478bd9Sstevel@tonic-gate ddi_put32(acc_hdl, &hcidescp->hdr, temp); 11127c478bd9Sstevel@tonic-gate } 11137c478bd9Sstevel@tonic-gate 11147c478bd9Sstevel@tonic-gate /* 11157c478bd9Sstevel@tonic-gate * set jump address of final cur IXL xfer cmd to addr next 11167c478bd9Sstevel@tonic-gate * IXL xfer cmd 11177c478bd9Sstevel@tonic-gate */ 11187c478bd9Sstevel@tonic-gate hcidescp = (hci1394_desc_t *) 11197c478bd9Sstevel@tonic-gate xferctl_curp->dma[repcnt - 1].dma_descp; 11207c478bd9Sstevel@tonic-gate acc_hdl = xferctl_curp->dma[repcnt - 1].dma_buf->bi_handle; 11217c478bd9Sstevel@tonic-gate ddi_put32(acc_hdl, &hcidescp->branch, dma_execnext_addr); 11227c478bd9Sstevel@tonic-gate 11237c478bd9Sstevel@tonic-gate /* 11247c478bd9Sstevel@tonic-gate * if a composite object, forward link initial jump 11257c478bd9Sstevel@tonic-gate * dma addresses 11267c478bd9Sstevel@tonic-gate */ 11277c478bd9Sstevel@tonic-gate for (ii = 0; ii < repcnt - 1; ii++) { 11287c478bd9Sstevel@tonic-gate hcidescp = (hci1394_desc_t *) 11297c478bd9Sstevel@tonic-gate xferctl_curp->dma[ii].dma_descp; 11307c478bd9Sstevel@tonic-gate acc_hdl = xferctl_curp->dma[ii].dma_buf->bi_handle; 11317c478bd9Sstevel@tonic-gate ddi_put32(acc_hdl, &hcidescp->branch, 11327c478bd9Sstevel@tonic-gate xferctl_curp->dma[ii + 1].dma_bound); 11337c478bd9Sstevel@tonic-gate } 11347c478bd9Sstevel@tonic-gate 11357c478bd9Sstevel@tonic-gate /* 11367c478bd9Sstevel@tonic-gate * fill in skip address(es) for all descriptor blocks belonging 11377c478bd9Sstevel@tonic-gate * to current IXL xfer command; note:skip addresses apply only 11387c478bd9Sstevel@tonic-gate * to xmit mode commands 11397c478bd9Sstevel@tonic-gate */ 11407c478bd9Sstevel@tonic-gate if ((ixlopcode & IXL1394_OPF_ONXMIT) != 0) { 11417c478bd9Sstevel@tonic-gate 11427c478bd9Sstevel@tonic-gate /* first obtain and set skip mode information */ 11437c478bd9Sstevel@tonic-gate wvp->ixl_setskipmode_cmdp = xferctl_curp->skipmodep; 11447c478bd9Sstevel@tonic-gate hci1394_set_xmit_skip_mode(wvp); 11457c478bd9Sstevel@tonic-gate 11467c478bd9Sstevel@tonic-gate /* 11477c478bd9Sstevel@tonic-gate * if skip to label,init dma bound addr to be 11487c478bd9Sstevel@tonic-gate * 1st xfer cmd after label 11497c478bd9Sstevel@tonic-gate */ 11507c478bd9Sstevel@tonic-gate dma_skiplabel_addr = 0; 11517c478bd9Sstevel@tonic-gate if ((wvp->skipmode == IXL1394_SKIP_TO_LABEL) && 11527c478bd9Sstevel@tonic-gate (wvp->skipxferp != NULL)) { 11537c478bd9Sstevel@tonic-gate xferctl_nxtp = (hci1394_xfer_ctl_t *) 11547c478bd9Sstevel@tonic-gate wvp->skipxferp->compiler_privatep; 11557c478bd9Sstevel@tonic-gate dma_skiplabel_addr = 11567c478bd9Sstevel@tonic-gate xferctl_nxtp->dma[0].dma_bound; 11577c478bd9Sstevel@tonic-gate } 11587c478bd9Sstevel@tonic-gate 11597c478bd9Sstevel@tonic-gate /* 11607c478bd9Sstevel@tonic-gate * set skip addrs for each descriptor blk at this 11617c478bd9Sstevel@tonic-gate * xfer start IXL cmd 11627c478bd9Sstevel@tonic-gate */ 11637c478bd9Sstevel@tonic-gate for (ii = 0; ii < repcnt; ii++) { 11647c478bd9Sstevel@tonic-gate switch (wvp->skipmode) { 11657c478bd9Sstevel@tonic-gate 11667c478bd9Sstevel@tonic-gate case IXL1394_SKIP_TO_LABEL: 11677c478bd9Sstevel@tonic-gate /* set dma bound address - label */ 11687c478bd9Sstevel@tonic-gate dma_skip_addr = dma_skiplabel_addr; 11697c478bd9Sstevel@tonic-gate break; 11707c478bd9Sstevel@tonic-gate 11717c478bd9Sstevel@tonic-gate case IXL1394_SKIP_TO_NEXT: 11727c478bd9Sstevel@tonic-gate /* set dma bound address - next */ 11737c478bd9Sstevel@tonic-gate if (ii < repcnt - 1) { 11747c478bd9Sstevel@tonic-gate dma_skip_addr = xferctl_curp-> 11757c478bd9Sstevel@tonic-gate dma[ii + 1].dma_bound; 11767c478bd9Sstevel@tonic-gate } else { 11777c478bd9Sstevel@tonic-gate dma_skip_addr = 11787c478bd9Sstevel@tonic-gate dma_execnext_addr; 11797c478bd9Sstevel@tonic-gate } 11807c478bd9Sstevel@tonic-gate break; 11817c478bd9Sstevel@tonic-gate 11827c478bd9Sstevel@tonic-gate case IXL1394_SKIP_TO_SELF: 11837c478bd9Sstevel@tonic-gate /* set dma bound address - self */ 11847c478bd9Sstevel@tonic-gate dma_skip_addr = 11857c478bd9Sstevel@tonic-gate xferctl_curp->dma[ii].dma_bound; 11867c478bd9Sstevel@tonic-gate break; 11877c478bd9Sstevel@tonic-gate 11887c478bd9Sstevel@tonic-gate case IXL1394_SKIP_TO_STOP: 11897c478bd9Sstevel@tonic-gate default: 11907c478bd9Sstevel@tonic-gate /* set dma bound address - stop */ 11917c478bd9Sstevel@tonic-gate dma_skip_addr = 0; 11927c478bd9Sstevel@tonic-gate break; 11937c478bd9Sstevel@tonic-gate } 11947c478bd9Sstevel@tonic-gate 11957c478bd9Sstevel@tonic-gate /* 11967c478bd9Sstevel@tonic-gate * determine address of first descriptor of 11977c478bd9Sstevel@tonic-gate * current descriptor block by adjusting addr of 11987c478bd9Sstevel@tonic-gate * last descriptor of current descriptor block 11997c478bd9Sstevel@tonic-gate */ 12007c478bd9Sstevel@tonic-gate hcidescp = ((hci1394_desc_t *) 12017c478bd9Sstevel@tonic-gate xferctl_curp->dma[ii].dma_descp); 12027c478bd9Sstevel@tonic-gate acc_hdl = 12037c478bd9Sstevel@tonic-gate xferctl_curp->dma[ii].dma_buf->bi_handle; 12047c478bd9Sstevel@tonic-gate 12057c478bd9Sstevel@tonic-gate /* 12067c478bd9Sstevel@tonic-gate * adjust by count of descriptors in this desc 12077c478bd9Sstevel@tonic-gate * block not including the last one (size of 12087c478bd9Sstevel@tonic-gate * descriptor) 12097c478bd9Sstevel@tonic-gate */ 12107c478bd9Sstevel@tonic-gate hcidescp -= ((xferctl_curp->dma[ii].dma_bound & 12117c478bd9Sstevel@tonic-gate DESC_Z_MASK) - 1); 12127c478bd9Sstevel@tonic-gate 12137c478bd9Sstevel@tonic-gate /* 12147c478bd9Sstevel@tonic-gate * adjust further if the last descriptor is 12157c478bd9Sstevel@tonic-gate * double sized 12167c478bd9Sstevel@tonic-gate */ 12177c478bd9Sstevel@tonic-gate if (ixlopcode == IXL1394_OP_SEND_HDR_ONLY) { 12187c478bd9Sstevel@tonic-gate hcidescp++; 12197c478bd9Sstevel@tonic-gate } 12207c478bd9Sstevel@tonic-gate /* 12217c478bd9Sstevel@tonic-gate * now set skip address into first descriptor 12227c478bd9Sstevel@tonic-gate * of descriptor block 12237c478bd9Sstevel@tonic-gate */ 12247c478bd9Sstevel@tonic-gate ddi_put32(acc_hdl, &hcidescp->branch, 12257c478bd9Sstevel@tonic-gate dma_skip_addr); 12267c478bd9Sstevel@tonic-gate } /* for */ 12277c478bd9Sstevel@tonic-gate } /* if */ 12287c478bd9Sstevel@tonic-gate } /* while */ 12297c478bd9Sstevel@tonic-gate 12307c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_finalize_all_xfer_desc_exit, 12317c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 12327c478bd9Sstevel@tonic-gate } 12337c478bd9Sstevel@tonic-gate 12347c478bd9Sstevel@tonic-gate /* 12357c478bd9Sstevel@tonic-gate * hci1394_finalize_cur_xfer_desc() 12367c478bd9Sstevel@tonic-gate * Build the openHCI descriptor for a packet or buffer based on info 12377c478bd9Sstevel@tonic-gate * currently collected into the working vars struct (wvp). After some 12387c478bd9Sstevel@tonic-gate * checks, this routine dispatches to the appropriate descriptor block 12397c478bd9Sstevel@tonic-gate * build (bld) routine for the packet or buf type. 12407c478bd9Sstevel@tonic-gate */ 12417c478bd9Sstevel@tonic-gate static void 12427c478bd9Sstevel@tonic-gate hci1394_finalize_cur_xfer_desc(hci1394_comp_ixl_vars_t *wvp) 12437c478bd9Sstevel@tonic-gate { 12447c478bd9Sstevel@tonic-gate uint16_t ixlopcode; 12457c478bd9Sstevel@tonic-gate uint16_t ixlopraw; 12467c478bd9Sstevel@tonic-gate 12477c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_enter, 12487c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 12497c478bd9Sstevel@tonic-gate 12507c478bd9Sstevel@tonic-gate /* extract opcode from current IXL cmd (if any) */ 12517c478bd9Sstevel@tonic-gate if (wvp->ixl_cur_cmdp != NULL) { 12527c478bd9Sstevel@tonic-gate ixlopcode = wvp->ixl_cur_cmdp->ixl_opcode; 12537c478bd9Sstevel@tonic-gate ixlopraw = ixlopcode & ~IXL1394_OPF_UPDATE; 12547c478bd9Sstevel@tonic-gate } else { 12557c478bd9Sstevel@tonic-gate ixlopcode = ixlopraw = IXL1394_OP_INVALID; 12567c478bd9Sstevel@tonic-gate } 12577c478bd9Sstevel@tonic-gate 12587c478bd9Sstevel@tonic-gate /* 12597c478bd9Sstevel@tonic-gate * if no xfer descriptor block being built, perform validity checks 12607c478bd9Sstevel@tonic-gate */ 12617c478bd9Sstevel@tonic-gate if (wvp->xfer_state == XFER_NONE) { 12627c478bd9Sstevel@tonic-gate /* 12637c478bd9Sstevel@tonic-gate * error if being finalized by IXL1394_OP_LABEL or 12647c478bd9Sstevel@tonic-gate * IXL1394_OP_JUMP or if at end, and have an unapplied 12657c478bd9Sstevel@tonic-gate * IXL1394_OP_SET_TAGSYNC, IXL1394_OP_SET_SKIPMODE or 12667c478bd9Sstevel@tonic-gate * IXL1394_OP_SET_SYNCWAIT 12677c478bd9Sstevel@tonic-gate */ 12687c478bd9Sstevel@tonic-gate if ((ixlopraw == IXL1394_OP_JUMP) || 12697c478bd9Sstevel@tonic-gate (ixlopraw == IXL1394_OP_LABEL) || 12707c478bd9Sstevel@tonic-gate (wvp->ixl_cur_cmdp == NULL) || 12717c478bd9Sstevel@tonic-gate (wvp->ixl_cur_cmdp->next_ixlp == NULL)) { 12727c478bd9Sstevel@tonic-gate if ((wvp->ixl_settagsync_cmdp != NULL) || 12737c478bd9Sstevel@tonic-gate (wvp->ixl_setskipmode_cmdp != NULL) || 12747c478bd9Sstevel@tonic-gate (wvp->ixl_setsyncwait_cnt != 0)) { 12757c478bd9Sstevel@tonic-gate 12767c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EUNAPPLIED_SET_CMD; 12777c478bd9Sstevel@tonic-gate 12787c478bd9Sstevel@tonic-gate TNF_PROBE_2( 12797c478bd9Sstevel@tonic-gate hci1394_finalize_cur_xfer_desc_set_error, 12807c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 12817c478bd9Sstevel@tonic-gate errmsg, "IXL1394_UNAPPLIED_SET_CMD: " 12827c478bd9Sstevel@tonic-gate "orphaned set (no associated packet)", 12837c478bd9Sstevel@tonic-gate tnf_opaque, ixl_commandp, 12847c478bd9Sstevel@tonic-gate wvp->ixl_cur_cmdp); 12857c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG( 12867c478bd9Sstevel@tonic-gate hci1394_finalize_cur_xfer_desc_exit, 12877c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 12887c478bd9Sstevel@tonic-gate return; 12897c478bd9Sstevel@tonic-gate } 12907c478bd9Sstevel@tonic-gate } 12917c478bd9Sstevel@tonic-gate 12927c478bd9Sstevel@tonic-gate /* error if finalize is due to updateable jump cmd */ 12937c478bd9Sstevel@tonic-gate if (ixlopcode == IXL1394_OP_JUMP_U) { 12947c478bd9Sstevel@tonic-gate 12957c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EUPDATE_DISALLOWED; 12967c478bd9Sstevel@tonic-gate 12977c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_finalize_cur_xfer_desc_upd_error, 12987c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 12997c478bd9Sstevel@tonic-gate "IXL1394_EUPDATE_DISALLOWED: jumpU w/out pkt", 13007c478bd9Sstevel@tonic-gate tnf_opaque, ixl_commandp, wvp->ixl_cur_cmdp); 13017c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_exit, 13027c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 13037c478bd9Sstevel@tonic-gate return; 13047c478bd9Sstevel@tonic-gate } 13057c478bd9Sstevel@tonic-gate 13067c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_exit, 13077c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 13087c478bd9Sstevel@tonic-gate 13097c478bd9Sstevel@tonic-gate /* no error, no xfer */ 13107c478bd9Sstevel@tonic-gate return; 13117c478bd9Sstevel@tonic-gate } 13127c478bd9Sstevel@tonic-gate 13137c478bd9Sstevel@tonic-gate /* 13147c478bd9Sstevel@tonic-gate * finalize current xfer descriptor block being built 13157c478bd9Sstevel@tonic-gate */ 13167c478bd9Sstevel@tonic-gate 13177c478bd9Sstevel@tonic-gate /* count IXL xfer start command for descriptor block being built */ 13187c478bd9Sstevel@tonic-gate wvp->ixl_xfer_st_cnt++; 13197c478bd9Sstevel@tonic-gate 13207c478bd9Sstevel@tonic-gate /* 13217c478bd9Sstevel@tonic-gate * complete setting of cache flush evaluation flags; flags will already 13227c478bd9Sstevel@tonic-gate * have been set by updateable set cmds and non-start xfer pkt cmds 13237c478bd9Sstevel@tonic-gate */ 13247c478bd9Sstevel@tonic-gate /* now set cache flush flag if current xfer start cmnd is updateable */ 13257c478bd9Sstevel@tonic-gate if ((wvp->ixl_cur_xfer_stp->ixl_opcode & IXL1394_OPF_UPDATE) != 0) { 13267c478bd9Sstevel@tonic-gate wvp->xfer_hci_flush |= UPDATEABLE_XFER; 13277c478bd9Sstevel@tonic-gate } 13287c478bd9Sstevel@tonic-gate /* 13297c478bd9Sstevel@tonic-gate * also set cache flush flag if xfer being finalized by 13307c478bd9Sstevel@tonic-gate * updateable jump cmd 13317c478bd9Sstevel@tonic-gate */ 13327c478bd9Sstevel@tonic-gate if ((ixlopcode == IXL1394_OP_JUMP_U) != 0) { 13337c478bd9Sstevel@tonic-gate wvp->xfer_hci_flush |= UPDATEABLE_JUMP; 13347c478bd9Sstevel@tonic-gate } 13357c478bd9Sstevel@tonic-gate 13367c478bd9Sstevel@tonic-gate /* 13377c478bd9Sstevel@tonic-gate * Determine if cache flush required before building next descriptor 13387c478bd9Sstevel@tonic-gate * block. If xfer pkt command and any cache flush flags are set, 13397c478bd9Sstevel@tonic-gate * hci flush needed. 13407c478bd9Sstevel@tonic-gate * If buffer or special xfer command and xfer command is updateable or 13417c478bd9Sstevel@tonic-gate * an associated set command is updateable, hci flush is required now. 13427c478bd9Sstevel@tonic-gate * If a single-xfer buffer or special xfer command is finalized by 13437c478bd9Sstevel@tonic-gate * updateable jump command, hci flush is required now. 13447c478bd9Sstevel@tonic-gate * Note: a cache flush will be required later, before the last 13457c478bd9Sstevel@tonic-gate * descriptor block of a multi-xfer set of descriptor blocks is built, 13467c478bd9Sstevel@tonic-gate * if this (non-pkt) xfer is finalized by an updateable jump command. 13477c478bd9Sstevel@tonic-gate */ 13487c478bd9Sstevel@tonic-gate if (wvp->xfer_hci_flush != 0) { 13497c478bd9Sstevel@tonic-gate if (((wvp->ixl_cur_xfer_stp->ixl_opcode & 13507c478bd9Sstevel@tonic-gate IXL1394_OPTY_XFER_PKT_ST) != 0) || ((wvp->xfer_hci_flush & 1351*ffc2b7d4SToomas Soome (UPDATEABLE_XFER | UPDATEABLE_SET | INITIATING_LBL)) != 1352*ffc2b7d4SToomas Soome 0)) { 13537c478bd9Sstevel@tonic-gate 13547c478bd9Sstevel@tonic-gate if (hci1394_flush_hci_cache(wvp) != DDI_SUCCESS) { 13557c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG( 13567c478bd9Sstevel@tonic-gate hci1394_finalize_cur_xfer_desc_exit, 13577c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 13587c478bd9Sstevel@tonic-gate 13597c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 13607c478bd9Sstevel@tonic-gate return; 13617c478bd9Sstevel@tonic-gate } 13627c478bd9Sstevel@tonic-gate } 13637c478bd9Sstevel@tonic-gate } 13647c478bd9Sstevel@tonic-gate 13657c478bd9Sstevel@tonic-gate /* 13667c478bd9Sstevel@tonic-gate * determine which kind of descriptor block to build based on 13677c478bd9Sstevel@tonic-gate * xfer state - hdr only, skip cycle, pkt or buf. 13687c478bd9Sstevel@tonic-gate */ 13697c478bd9Sstevel@tonic-gate switch (wvp->xfer_state) { 13707c478bd9Sstevel@tonic-gate 13717c478bd9Sstevel@tonic-gate case XFER_PKT: 13727c478bd9Sstevel@tonic-gate if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) != 0) { 13737c478bd9Sstevel@tonic-gate hci1394_bld_recv_pkt_desc(wvp); 13747c478bd9Sstevel@tonic-gate } else { 13757c478bd9Sstevel@tonic-gate hci1394_bld_xmit_pkt_desc(wvp); 13767c478bd9Sstevel@tonic-gate } 13777c478bd9Sstevel@tonic-gate break; 13787c478bd9Sstevel@tonic-gate 13797c478bd9Sstevel@tonic-gate case XFER_BUF: 13807c478bd9Sstevel@tonic-gate if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_RECV) != 0) { 13817c478bd9Sstevel@tonic-gate if ((wvp->ixl_io_mode & HCI1394_ISO_CTXT_BFFILL) != 0) { 13827c478bd9Sstevel@tonic-gate hci1394_bld_recv_buf_fill_desc(wvp); 13837c478bd9Sstevel@tonic-gate } else { 13847c478bd9Sstevel@tonic-gate hci1394_bld_recv_buf_ppb_desc(wvp); 13857c478bd9Sstevel@tonic-gate } 13867c478bd9Sstevel@tonic-gate } else { 13877c478bd9Sstevel@tonic-gate hci1394_bld_xmit_buf_desc(wvp); 13887c478bd9Sstevel@tonic-gate } 13897c478bd9Sstevel@tonic-gate break; 13907c478bd9Sstevel@tonic-gate 13917c478bd9Sstevel@tonic-gate case XMIT_HDRONLY: 13927c478bd9Sstevel@tonic-gate case XMIT_NOPKT: 13937c478bd9Sstevel@tonic-gate hci1394_bld_xmit_hdronly_nopkt_desc(wvp); 13947c478bd9Sstevel@tonic-gate break; 13957c478bd9Sstevel@tonic-gate 13967c478bd9Sstevel@tonic-gate default: 13977c478bd9Sstevel@tonic-gate /* internal compiler error */ 13987c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_finalize_cur_xfer_desc_internal_error, 13997c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 14007c478bd9Sstevel@tonic-gate "IXL1394_INTERNAL_ERROR: invalid state", tnf_opaque, 14017c478bd9Sstevel@tonic-gate ixl_commandp, wvp->ixl_cur_cmdp); 14027c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EINTERNAL_ERROR; 14037c478bd9Sstevel@tonic-gate } 14047c478bd9Sstevel@tonic-gate 14057c478bd9Sstevel@tonic-gate /* return if error */ 14067c478bd9Sstevel@tonic-gate if (wvp->dma_bld_error != 0) { 14077c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_exit, 14087c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 14097c478bd9Sstevel@tonic-gate 14107c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 14117c478bd9Sstevel@tonic-gate return; 14127c478bd9Sstevel@tonic-gate } 14137c478bd9Sstevel@tonic-gate 14147c478bd9Sstevel@tonic-gate /* 14157c478bd9Sstevel@tonic-gate * if was finalizing IXL jump cmd, set compiler_privatep to 14167c478bd9Sstevel@tonic-gate * cur xfer IXL cmd 14177c478bd9Sstevel@tonic-gate */ 14187c478bd9Sstevel@tonic-gate if (ixlopraw == IXL1394_OP_JUMP) { 14197c478bd9Sstevel@tonic-gate wvp->ixl_cur_cmdp->compiler_privatep = 14207c478bd9Sstevel@tonic-gate (void *)wvp->ixl_cur_xfer_stp; 14217c478bd9Sstevel@tonic-gate } 14227c478bd9Sstevel@tonic-gate 14237c478bd9Sstevel@tonic-gate /* if cur xfer IXL initiated by IXL label cmd, set flag in xfer_ctl */ 14247c478bd9Sstevel@tonic-gate if (wvp->ixl_cur_labelp != NULL) { 14257c478bd9Sstevel@tonic-gate ((hci1394_xfer_ctl_t *) 14267c478bd9Sstevel@tonic-gate (wvp->ixl_cur_xfer_stp->compiler_privatep))->ctl_flags |= 14277c478bd9Sstevel@tonic-gate XCTL_LABELLED; 14287c478bd9Sstevel@tonic-gate wvp->ixl_cur_labelp = NULL; 14297c478bd9Sstevel@tonic-gate } 14307c478bd9Sstevel@tonic-gate 14317c478bd9Sstevel@tonic-gate /* 14327c478bd9Sstevel@tonic-gate * set any associated IXL set skipmode cmd into xfer_ctl of 14337c478bd9Sstevel@tonic-gate * cur xfer IXL cmd 14347c478bd9Sstevel@tonic-gate */ 14357c478bd9Sstevel@tonic-gate if (wvp->ixl_setskipmode_cmdp != NULL) { 14367c478bd9Sstevel@tonic-gate ((hci1394_xfer_ctl_t *) 14377c478bd9Sstevel@tonic-gate (wvp->ixl_cur_xfer_stp->compiler_privatep))->skipmodep = 14387c478bd9Sstevel@tonic-gate wvp->ixl_setskipmode_cmdp; 14397c478bd9Sstevel@tonic-gate } 14407c478bd9Sstevel@tonic-gate 14417c478bd9Sstevel@tonic-gate /* set no current xfer start cmd */ 14427c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp = NULL; 14437c478bd9Sstevel@tonic-gate 14447c478bd9Sstevel@tonic-gate /* set no current set tag&sync, set skipmode or set syncwait commands */ 14457c478bd9Sstevel@tonic-gate wvp->ixl_settagsync_cmdp = NULL; 14467c478bd9Sstevel@tonic-gate wvp->ixl_setskipmode_cmdp = NULL; 14477c478bd9Sstevel@tonic-gate wvp->ixl_setsyncwait_cnt = 0; 14487c478bd9Sstevel@tonic-gate 14497c478bd9Sstevel@tonic-gate /* set no currently active descriptor blocks */ 14507c478bd9Sstevel@tonic-gate wvp->descriptors = 0; 14517c478bd9Sstevel@tonic-gate 14527c478bd9Sstevel@tonic-gate /* reset total packet length and buffers count */ 14537c478bd9Sstevel@tonic-gate wvp->xfer_pktlen = 0; 14547c478bd9Sstevel@tonic-gate wvp->xfer_bufcnt = 0; 14557c478bd9Sstevel@tonic-gate 14567c478bd9Sstevel@tonic-gate /* reset flush cache evaluation flags */ 14577c478bd9Sstevel@tonic-gate wvp->xfer_hci_flush = 0; 14587c478bd9Sstevel@tonic-gate 14597c478bd9Sstevel@tonic-gate /* set no xmit descriptor block being built */ 14607c478bd9Sstevel@tonic-gate wvp->xfer_state = XFER_NONE; 14617c478bd9Sstevel@tonic-gate 14627c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_finalize_cur_xfer_desc_exit, 14637c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 14647c478bd9Sstevel@tonic-gate } 14657c478bd9Sstevel@tonic-gate 14667c478bd9Sstevel@tonic-gate /* 14677c478bd9Sstevel@tonic-gate * hci1394_bld_recv_pkt_desc() 14687c478bd9Sstevel@tonic-gate * Used to create the openHCI dma descriptor block(s) for a receive packet. 14697c478bd9Sstevel@tonic-gate */ 14707c478bd9Sstevel@tonic-gate static void 14717c478bd9Sstevel@tonic-gate hci1394_bld_recv_pkt_desc(hci1394_comp_ixl_vars_t *wvp) 14727c478bd9Sstevel@tonic-gate { 14737c478bd9Sstevel@tonic-gate hci1394_xfer_ctl_t *xctlp; 14747c478bd9Sstevel@tonic-gate caddr_t dma_descp; 14757c478bd9Sstevel@tonic-gate uint32_t dma_desc_bound; 14767c478bd9Sstevel@tonic-gate uint32_t wait_for_sync; 14777c478bd9Sstevel@tonic-gate uint32_t ii; 14787c478bd9Sstevel@tonic-gate hci1394_desc_t *wv_descp; /* shorthand to local descrpt */ 14797c478bd9Sstevel@tonic-gate 14807c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_enter, 14817c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 14827c478bd9Sstevel@tonic-gate 14837c478bd9Sstevel@tonic-gate /* 14847c478bd9Sstevel@tonic-gate * is error if number of descriptors to be built exceeds maximum 14857c478bd9Sstevel@tonic-gate * descriptors allowed in a descriptor block. 14867c478bd9Sstevel@tonic-gate */ 14877c478bd9Sstevel@tonic-gate if ((wvp->descriptors + wvp->xfer_bufcnt) > HCI1394_DESC_MAX_Z) { 14887c478bd9Sstevel@tonic-gate 14897c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EFRAGMENT_OFLO; 14907c478bd9Sstevel@tonic-gate 14917c478bd9Sstevel@tonic-gate TNF_PROBE_3(hci1394_bld_recv_pkt_desc_fragment_oflo_error, 14927c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 14937c478bd9Sstevel@tonic-gate "IXL1394_EFRAGMENT_OFLO", tnf_opaque, ixl_commandp, 14947c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp, tnf_int, frag_count, 14957c478bd9Sstevel@tonic-gate wvp->descriptors + wvp->xfer_bufcnt); 14967c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_exit, 14977c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 14987c478bd9Sstevel@tonic-gate return; 14997c478bd9Sstevel@tonic-gate } 15007c478bd9Sstevel@tonic-gate 15017c478bd9Sstevel@tonic-gate /* allocate an xfer_ctl struct, including 1 xfer_ctl_dma struct */ 15027c478bd9Sstevel@tonic-gate if ((xctlp = hci1394_alloc_xfer_ctl(wvp, 1)) == NULL) { 15037c478bd9Sstevel@tonic-gate 15047c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL; 15057c478bd9Sstevel@tonic-gate 15067c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_bld_recv_pkt_desc_mem_alloc_fail, 15077c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 15087c478bd9Sstevel@tonic-gate "IXL1394_EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque, 15097c478bd9Sstevel@tonic-gate ixl_commandp, wvp->ixl_cur_xfer_stp); 15107c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_exit, 15117c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 15127c478bd9Sstevel@tonic-gate return; 15137c478bd9Sstevel@tonic-gate } 15147c478bd9Sstevel@tonic-gate 15157c478bd9Sstevel@tonic-gate /* 15167c478bd9Sstevel@tonic-gate * save xfer_ctl struct addr in compiler_privatep of 15177c478bd9Sstevel@tonic-gate * current IXL xfer cmd 15187c478bd9Sstevel@tonic-gate */ 15197c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp; 15207c478bd9Sstevel@tonic-gate 15217c478bd9Sstevel@tonic-gate /* 15227c478bd9Sstevel@tonic-gate * if enabled, set wait for sync flag in first descriptor of 15237c478bd9Sstevel@tonic-gate * descriptor block 15247c478bd9Sstevel@tonic-gate */ 15257c478bd9Sstevel@tonic-gate if (wvp->ixl_setsyncwait_cnt > 0) { 15267c478bd9Sstevel@tonic-gate wvp->ixl_setsyncwait_cnt = 1; 15277c478bd9Sstevel@tonic-gate wait_for_sync = DESC_W_ENBL; 15287c478bd9Sstevel@tonic-gate } else { 15297c478bd9Sstevel@tonic-gate wait_for_sync = DESC_W_DSABL; 15307c478bd9Sstevel@tonic-gate } 15317c478bd9Sstevel@tonic-gate 15327c478bd9Sstevel@tonic-gate /* create descriptor block for this recv packet (xfer status enabled) */ 15337c478bd9Sstevel@tonic-gate for (ii = 0; ii < wvp->xfer_bufcnt; ii++) { 15347c478bd9Sstevel@tonic-gate wv_descp = &wvp->descriptor_block[wvp->descriptors]; 15357c478bd9Sstevel@tonic-gate 15367c478bd9Sstevel@tonic-gate if (ii == (wvp->xfer_bufcnt - 1)) { 15377c478bd9Sstevel@tonic-gate HCI1394_INIT_IR_PPB_ILAST(wv_descp, DESC_HDR_STAT_ENBL, 15387c478bd9Sstevel@tonic-gate DESC_INTR_DSABL, wait_for_sync, wvp->xfer_size[ii]); 15397c478bd9Sstevel@tonic-gate } else { 15407c478bd9Sstevel@tonic-gate HCI1394_INIT_IR_PPB_IMORE(wv_descp, wait_for_sync, 15417c478bd9Sstevel@tonic-gate wvp->xfer_size[ii]); 15427c478bd9Sstevel@tonic-gate } 15437c478bd9Sstevel@tonic-gate wv_descp->data_addr = wvp->xfer_bufp[ii]; 15447c478bd9Sstevel@tonic-gate wv_descp->branch = 0; 15457c478bd9Sstevel@tonic-gate wv_descp->status = (wvp->xfer_size[ii] << 15467c478bd9Sstevel@tonic-gate DESC_ST_RESCOUNT_SHIFT) & DESC_ST_RESCOUNT_MASK; 15477c478bd9Sstevel@tonic-gate wvp->descriptors++; 15487c478bd9Sstevel@tonic-gate } 15497c478bd9Sstevel@tonic-gate 15507c478bd9Sstevel@tonic-gate /* allocate and copy descriptor block to dma memory */ 15517c478bd9Sstevel@tonic-gate if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp, &dma_desc_bound) != 15527c478bd9Sstevel@tonic-gate DDI_SUCCESS) { 15537c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_exit, 15547c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 15557c478bd9Sstevel@tonic-gate 15567c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above function call */ 15577c478bd9Sstevel@tonic-gate return; 15587c478bd9Sstevel@tonic-gate } 15597c478bd9Sstevel@tonic-gate 15607c478bd9Sstevel@tonic-gate /* 15617c478bd9Sstevel@tonic-gate * set dma addrs into xfer_ctl structure (unbound addr (kernel virtual) 15627c478bd9Sstevel@tonic-gate * is last component) 15637c478bd9Sstevel@tonic-gate */ 15647c478bd9Sstevel@tonic-gate xctlp->dma[0].dma_bound = dma_desc_bound; 15657c478bd9Sstevel@tonic-gate xctlp->dma[0].dma_descp = 15667c478bd9Sstevel@tonic-gate dma_descp + (wvp->xfer_bufcnt - 1) * sizeof (hci1394_desc_t); 15677c478bd9Sstevel@tonic-gate xctlp->dma[0].dma_buf = &wvp->dma_currentp->mem; 15687c478bd9Sstevel@tonic-gate 15697c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_pkt_desc_exit, 15707c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 15717c478bd9Sstevel@tonic-gate } 15727c478bd9Sstevel@tonic-gate 15737c478bd9Sstevel@tonic-gate /* 15747c478bd9Sstevel@tonic-gate * hci1394_bld_recv_buf_ppb_desc() 15757c478bd9Sstevel@tonic-gate * Used to create the openHCI dma descriptor block(s) for a receive buf 15767c478bd9Sstevel@tonic-gate * in packet per buffer mode. 15777c478bd9Sstevel@tonic-gate */ 15787c478bd9Sstevel@tonic-gate static void 15797c478bd9Sstevel@tonic-gate hci1394_bld_recv_buf_ppb_desc(hci1394_comp_ixl_vars_t *wvp) 15807c478bd9Sstevel@tonic-gate { 15817c478bd9Sstevel@tonic-gate hci1394_xfer_ctl_t *xctlp; 15827c478bd9Sstevel@tonic-gate ixl1394_xfer_buf_t *local_ixl_cur_xfer_stp; 15837c478bd9Sstevel@tonic-gate caddr_t dma_descp; 15847c478bd9Sstevel@tonic-gate uint32_t dma_desc_bound; 15857c478bd9Sstevel@tonic-gate uint32_t pktsize; 15867c478bd9Sstevel@tonic-gate uint32_t pktcnt; 15877c478bd9Sstevel@tonic-gate uint32_t wait_for_sync; 15887c478bd9Sstevel@tonic-gate uint32_t ii; 15897c478bd9Sstevel@tonic-gate hci1394_desc_t *wv_descp; /* shorthand to local descriptor */ 15907c478bd9Sstevel@tonic-gate 15917c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_ppb_desc_enter, 15927c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 15937c478bd9Sstevel@tonic-gate 15947c478bd9Sstevel@tonic-gate local_ixl_cur_xfer_stp = (ixl1394_xfer_buf_t *)wvp->ixl_cur_xfer_stp; 15957c478bd9Sstevel@tonic-gate 15967c478bd9Sstevel@tonic-gate /* determine number and size of pkt desc blocks to create */ 15977c478bd9Sstevel@tonic-gate pktsize = local_ixl_cur_xfer_stp->pkt_size; 15987c478bd9Sstevel@tonic-gate pktcnt = local_ixl_cur_xfer_stp->size / pktsize; 15997c478bd9Sstevel@tonic-gate 16007c478bd9Sstevel@tonic-gate /* allocate an xfer_ctl struct including pktcnt xfer_ctl_dma structs */ 16017c478bd9Sstevel@tonic-gate if ((xctlp = hci1394_alloc_xfer_ctl(wvp, pktcnt)) == NULL) { 16027c478bd9Sstevel@tonic-gate 16037c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL; 16047c478bd9Sstevel@tonic-gate 16057c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_bld_recv_buf_ppb_desc_mem_alloc_fail, 16067c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 16077c478bd9Sstevel@tonic-gate "IXL1394_EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque, 16087c478bd9Sstevel@tonic-gate ixl_commandp, wvp->ixl_cur_xfer_stp); 16097c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_ppb_desc_exit, 16107c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 16117c478bd9Sstevel@tonic-gate return; 16127c478bd9Sstevel@tonic-gate } 16137c478bd9Sstevel@tonic-gate 16147c478bd9Sstevel@tonic-gate /* 16157c478bd9Sstevel@tonic-gate * save xfer_ctl struct addr in compiler_privatep of 16167c478bd9Sstevel@tonic-gate * current IXL xfer cmd 16177c478bd9Sstevel@tonic-gate */ 16187c478bd9Sstevel@tonic-gate local_ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp; 16197c478bd9Sstevel@tonic-gate 16207c478bd9Sstevel@tonic-gate /* 16217c478bd9Sstevel@tonic-gate * if enabled, set wait for sync flag in first descriptor in 16227c478bd9Sstevel@tonic-gate * descriptor block 16237c478bd9Sstevel@tonic-gate */ 16247c478bd9Sstevel@tonic-gate if (wvp->ixl_setsyncwait_cnt > 0) { 16257c478bd9Sstevel@tonic-gate wvp->ixl_setsyncwait_cnt = 1; 16267c478bd9Sstevel@tonic-gate wait_for_sync = DESC_W_ENBL; 16277c478bd9Sstevel@tonic-gate } else { 16287c478bd9Sstevel@tonic-gate wait_for_sync = DESC_W_DSABL; 16297c478bd9Sstevel@tonic-gate } 16307c478bd9Sstevel@tonic-gate 16317c478bd9Sstevel@tonic-gate /* create first descriptor block for this recv packet */ 16327c478bd9Sstevel@tonic-gate /* consists of one descriptor and xfer status is enabled */ 16337c478bd9Sstevel@tonic-gate wv_descp = &wvp->descriptor_block[wvp->descriptors]; 16347c478bd9Sstevel@tonic-gate HCI1394_INIT_IR_PPB_ILAST(wv_descp, DESC_HDR_STAT_ENBL, DESC_INTR_DSABL, 16357c478bd9Sstevel@tonic-gate wait_for_sync, pktsize); 16367c478bd9Sstevel@tonic-gate wv_descp->data_addr = local_ixl_cur_xfer_stp->ixl_buf.ixldmac_addr; 16377c478bd9Sstevel@tonic-gate wv_descp->branch = 0; 16387c478bd9Sstevel@tonic-gate wv_descp->status = (pktsize << DESC_ST_RESCOUNT_SHIFT) & 16397c478bd9Sstevel@tonic-gate DESC_ST_RESCOUNT_MASK; 16407c478bd9Sstevel@tonic-gate wvp->descriptors++; 16417c478bd9Sstevel@tonic-gate 16427c478bd9Sstevel@tonic-gate /* useful debug trace info - IXL command, and packet count and size */ 16437c478bd9Sstevel@tonic-gate TNF_PROBE_3_DEBUG(hci1394_bld_recv_buf_ppb_desc_recv_buf_info, 16447c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_INFO_ISOCH, "", tnf_opaque, ixl_commandp, 16457c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp, tnf_int, pkt_count, pktcnt, tnf_int, 16467c478bd9Sstevel@tonic-gate pkt_size, pktsize); 16477c478bd9Sstevel@tonic-gate 16487c478bd9Sstevel@tonic-gate /* 16497c478bd9Sstevel@tonic-gate * generate as many contiguous descriptor blocks as there are 16507c478bd9Sstevel@tonic-gate * recv pkts 16517c478bd9Sstevel@tonic-gate */ 16527c478bd9Sstevel@tonic-gate for (ii = 0; ii < pktcnt; ii++) { 16537c478bd9Sstevel@tonic-gate 16547c478bd9Sstevel@tonic-gate /* if about to create last descriptor block */ 16557c478bd9Sstevel@tonic-gate if (ii == (pktcnt - 1)) { 16567c478bd9Sstevel@tonic-gate /* check and perform any required hci cache flush */ 16577c478bd9Sstevel@tonic-gate if (hci1394_flush_end_desc_check(wvp, ii) != 16587c478bd9Sstevel@tonic-gate DDI_SUCCESS) { 16597c478bd9Sstevel@tonic-gate TNF_PROBE_1_DEBUG( 16607c478bd9Sstevel@tonic-gate hci1394_bld_recv_buf_ppb_desc_fl_error, 16617c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_INFO_ISOCH, "", tnf_int, 16627c478bd9Sstevel@tonic-gate for_ii, ii); 16637c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG( 16647c478bd9Sstevel@tonic-gate hci1394_bld_recv_buf_ppb_desc_exit, 16657c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 16667c478bd9Sstevel@tonic-gate 16677c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 16687c478bd9Sstevel@tonic-gate return; 16697c478bd9Sstevel@tonic-gate } 16707c478bd9Sstevel@tonic-gate } 16717c478bd9Sstevel@tonic-gate 16727c478bd9Sstevel@tonic-gate /* allocate and copy descriptor block to dma memory */ 16737c478bd9Sstevel@tonic-gate if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp, 16747c478bd9Sstevel@tonic-gate &dma_desc_bound) != DDI_SUCCESS) { 16757c478bd9Sstevel@tonic-gate 16767c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_ppb_desc_exit, 16777c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 16787c478bd9Sstevel@tonic-gate 16797c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 16807c478bd9Sstevel@tonic-gate return; 16817c478bd9Sstevel@tonic-gate } 16827c478bd9Sstevel@tonic-gate 16837c478bd9Sstevel@tonic-gate /* 16847c478bd9Sstevel@tonic-gate * set dma addrs into xfer_ctl struct (unbound addr (kernel 16857c478bd9Sstevel@tonic-gate * virtual) is last component (descriptor)) 16867c478bd9Sstevel@tonic-gate */ 16877c478bd9Sstevel@tonic-gate xctlp->dma[ii].dma_bound = dma_desc_bound; 16887c478bd9Sstevel@tonic-gate xctlp->dma[ii].dma_descp = dma_descp; 16897c478bd9Sstevel@tonic-gate xctlp->dma[ii].dma_buf = &wvp->dma_currentp->mem; 16907c478bd9Sstevel@tonic-gate 16917c478bd9Sstevel@tonic-gate /* advance buffer ptr by pktsize in descriptor block */ 16927c478bd9Sstevel@tonic-gate wvp->descriptor_block[wvp->descriptors - 1].data_addr += 16937c478bd9Sstevel@tonic-gate pktsize; 16947c478bd9Sstevel@tonic-gate } 16957c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_ppb_desc_exit, 16967c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 16977c478bd9Sstevel@tonic-gate } 16987c478bd9Sstevel@tonic-gate 16997c478bd9Sstevel@tonic-gate /* 17007c478bd9Sstevel@tonic-gate * hci1394_bld_recv_buf_fill_desc() 17017c478bd9Sstevel@tonic-gate * Used to create the openHCI dma descriptor block(s) for a receive buf 17027c478bd9Sstevel@tonic-gate * in buffer fill mode. 17037c478bd9Sstevel@tonic-gate */ 17047c478bd9Sstevel@tonic-gate static void 17057c478bd9Sstevel@tonic-gate hci1394_bld_recv_buf_fill_desc(hci1394_comp_ixl_vars_t *wvp) 17067c478bd9Sstevel@tonic-gate { 17077c478bd9Sstevel@tonic-gate hci1394_xfer_ctl_t *xctlp; 17087c478bd9Sstevel@tonic-gate caddr_t dma_descp; 17097c478bd9Sstevel@tonic-gate uint32_t dma_desc_bound; 17107c478bd9Sstevel@tonic-gate uint32_t wait_for_sync; 17117c478bd9Sstevel@tonic-gate ixl1394_xfer_buf_t *local_ixl_cur_xfer_stp; 17127c478bd9Sstevel@tonic-gate 17137c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_enter, 17147c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 17157c478bd9Sstevel@tonic-gate 17167c478bd9Sstevel@tonic-gate local_ixl_cur_xfer_stp = (ixl1394_xfer_buf_t *)wvp->ixl_cur_xfer_stp; 17177c478bd9Sstevel@tonic-gate 17187c478bd9Sstevel@tonic-gate 17197c478bd9Sstevel@tonic-gate /* allocate an xfer_ctl struct including 1 xfer_ctl_dma structs */ 17207c478bd9Sstevel@tonic-gate if ((xctlp = hci1394_alloc_xfer_ctl(wvp, 1)) == NULL) { 17217c478bd9Sstevel@tonic-gate 17227c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL; 17237c478bd9Sstevel@tonic-gate 17247c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_bld_recv_buf_fill_desc_mem_alloc_fail, 17257c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 17267c478bd9Sstevel@tonic-gate "IXL1394_EMEM_ALLOC_FAIL: xfer_ctl", tnf_opaque, 17277c478bd9Sstevel@tonic-gate ixl_commandp, wvp->ixl_cur_xfer_stp); 17287c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_exit, 17297c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 17307c478bd9Sstevel@tonic-gate return; 17317c478bd9Sstevel@tonic-gate } 17327c478bd9Sstevel@tonic-gate 17337c478bd9Sstevel@tonic-gate /* 17347c478bd9Sstevel@tonic-gate * save xfer_ctl struct addr in compiler_privatep of 17357c478bd9Sstevel@tonic-gate * current IXL xfer cmd 17367c478bd9Sstevel@tonic-gate */ 17377c478bd9Sstevel@tonic-gate local_ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp; 17387c478bd9Sstevel@tonic-gate 17397c478bd9Sstevel@tonic-gate /* 17407c478bd9Sstevel@tonic-gate * if enabled, set wait for sync flag in first descriptor of 17417c478bd9Sstevel@tonic-gate * descriptor block 17427c478bd9Sstevel@tonic-gate */ 17437c478bd9Sstevel@tonic-gate if (wvp->ixl_setsyncwait_cnt > 0) { 17447c478bd9Sstevel@tonic-gate wvp->ixl_setsyncwait_cnt = 1; 17457c478bd9Sstevel@tonic-gate wait_for_sync = DESC_W_ENBL; 17467c478bd9Sstevel@tonic-gate } else { 17477c478bd9Sstevel@tonic-gate wait_for_sync = DESC_W_DSABL; 17487c478bd9Sstevel@tonic-gate } 17497c478bd9Sstevel@tonic-gate 17507c478bd9Sstevel@tonic-gate /* 17517c478bd9Sstevel@tonic-gate * create descriptor block for this buffer fill mode recv command which 17527c478bd9Sstevel@tonic-gate * consists of one descriptor with xfer status enabled 17537c478bd9Sstevel@tonic-gate */ 17547c478bd9Sstevel@tonic-gate HCI1394_INIT_IR_BF_IMORE(&wvp->descriptor_block[wvp->descriptors], 17557c478bd9Sstevel@tonic-gate DESC_INTR_DSABL, wait_for_sync, local_ixl_cur_xfer_stp->size); 17567c478bd9Sstevel@tonic-gate 17577c478bd9Sstevel@tonic-gate wvp->descriptor_block[wvp->descriptors].data_addr = 17587c478bd9Sstevel@tonic-gate local_ixl_cur_xfer_stp->ixl_buf.ixldmac_addr; 17597c478bd9Sstevel@tonic-gate wvp->descriptor_block[wvp->descriptors].branch = 0; 17607c478bd9Sstevel@tonic-gate wvp->descriptor_block[wvp->descriptors].status = 17617c478bd9Sstevel@tonic-gate (local_ixl_cur_xfer_stp->size << DESC_ST_RESCOUNT_SHIFT) & 17627c478bd9Sstevel@tonic-gate DESC_ST_RESCOUNT_MASK; 17637c478bd9Sstevel@tonic-gate wvp->descriptors++; 17647c478bd9Sstevel@tonic-gate 17657c478bd9Sstevel@tonic-gate /* check and perform any required hci cache flush */ 17667c478bd9Sstevel@tonic-gate if (hci1394_flush_end_desc_check(wvp, 0) != DDI_SUCCESS) { 17677c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_exit, 17687c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 17697c478bd9Sstevel@tonic-gate 17707c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 17717c478bd9Sstevel@tonic-gate return; 17727c478bd9Sstevel@tonic-gate } 17737c478bd9Sstevel@tonic-gate 17747c478bd9Sstevel@tonic-gate /* allocate and copy descriptor block to dma memory */ 17757c478bd9Sstevel@tonic-gate if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp, &dma_desc_bound) 17767c478bd9Sstevel@tonic-gate != DDI_SUCCESS) { 17777c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_exit, 17787c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 17797c478bd9Sstevel@tonic-gate 17807c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 17817c478bd9Sstevel@tonic-gate return; 17827c478bd9Sstevel@tonic-gate } 17837c478bd9Sstevel@tonic-gate 17847c478bd9Sstevel@tonic-gate /* 17857c478bd9Sstevel@tonic-gate * set dma addrs into xfer_ctl structure (unbound addr (kernel virtual) 17867c478bd9Sstevel@tonic-gate * is last component. 17877c478bd9Sstevel@tonic-gate */ 17887c478bd9Sstevel@tonic-gate xctlp->dma[0].dma_bound = dma_desc_bound; 17897c478bd9Sstevel@tonic-gate xctlp->dma[0].dma_descp = dma_descp; 17907c478bd9Sstevel@tonic-gate xctlp->dma[0].dma_buf = &wvp->dma_currentp->mem; 17917c478bd9Sstevel@tonic-gate 17927c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_recv_buf_fill_desc_exit, 17937c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 17947c478bd9Sstevel@tonic-gate } 17957c478bd9Sstevel@tonic-gate 17967c478bd9Sstevel@tonic-gate /* 17977c478bd9Sstevel@tonic-gate * hci1394_bld_xmit_pkt_desc() 17987c478bd9Sstevel@tonic-gate * Used to create the openHCI dma descriptor block(s) for a transmit packet. 17997c478bd9Sstevel@tonic-gate */ 18007c478bd9Sstevel@tonic-gate static void 18017c478bd9Sstevel@tonic-gate hci1394_bld_xmit_pkt_desc(hci1394_comp_ixl_vars_t *wvp) 18027c478bd9Sstevel@tonic-gate { 18037c478bd9Sstevel@tonic-gate hci1394_xfer_ctl_t *xctlp; 18047c478bd9Sstevel@tonic-gate hci1394_output_more_imm_t *wv_omi_descp; /* shorthand to local descrp */ 18057c478bd9Sstevel@tonic-gate hci1394_desc_t *wv_descp; /* shorthand to local descriptor */ 18067c478bd9Sstevel@tonic-gate caddr_t dma_descp; /* dma bound memory for descriptor */ 18077c478bd9Sstevel@tonic-gate uint32_t dma_desc_bound; 18087c478bd9Sstevel@tonic-gate uint32_t ii; 18097c478bd9Sstevel@tonic-gate 18107c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_enter, 18117c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 18127c478bd9Sstevel@tonic-gate 18137c478bd9Sstevel@tonic-gate /* 18147c478bd9Sstevel@tonic-gate * is error if number of descriptors to be built exceeds maximum 18157c478bd9Sstevel@tonic-gate * descriptors allowed in a descriptor block. Add 2 for the overhead 18167c478bd9Sstevel@tonic-gate * of the OMORE-Immediate. 18177c478bd9Sstevel@tonic-gate */ 18187c478bd9Sstevel@tonic-gate if ((wvp->descriptors + 2 + wvp->xfer_bufcnt) > HCI1394_DESC_MAX_Z) { 18197c478bd9Sstevel@tonic-gate 18207c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EFRAGMENT_OFLO; 18217c478bd9Sstevel@tonic-gate 18227c478bd9Sstevel@tonic-gate TNF_PROBE_3(hci1394_bld_xmit_pkt_desc_fragment_oflo_error, 18237c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 18247c478bd9Sstevel@tonic-gate "IXL1394_EFRAGMENT_OFLO", tnf_opaque, ixl_commandp, 18257c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp, tnf_int, frag_count, 18267c478bd9Sstevel@tonic-gate wvp->descriptors + 2 + wvp->xfer_bufcnt); 18277c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit, 18287c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 18297c478bd9Sstevel@tonic-gate return; 18307c478bd9Sstevel@tonic-gate } 18317c478bd9Sstevel@tonic-gate 18327c478bd9Sstevel@tonic-gate /* is error if total packet length exceeds 0xFFFF */ 18337c478bd9Sstevel@tonic-gate if (wvp->xfer_pktlen > 0xFFFF) { 18347c478bd9Sstevel@tonic-gate 18357c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EPKTSIZE_MAX_OFLO; 18367c478bd9Sstevel@tonic-gate 18377c478bd9Sstevel@tonic-gate TNF_PROBE_3(hci1394_bld_xmit_pkt_desc_packet_oflo_error, 18387c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 18397c478bd9Sstevel@tonic-gate "IXL1394_EPKTSIZE_MAX_OFLO", tnf_opaque, ixl_commandp, 18407c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp, tnf_int, total_pktlen, 18417c478bd9Sstevel@tonic-gate wvp->xfer_pktlen); 18427c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit, 18437c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 18447c478bd9Sstevel@tonic-gate return; 18457c478bd9Sstevel@tonic-gate } 18467c478bd9Sstevel@tonic-gate 18477c478bd9Sstevel@tonic-gate /* allocate an xfer_ctl struct, including 1 xfer_ctl_dma struct */ 18487c478bd9Sstevel@tonic-gate if ((xctlp = hci1394_alloc_xfer_ctl(wvp, 1)) == NULL) { 18497c478bd9Sstevel@tonic-gate 18507c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL; 18517c478bd9Sstevel@tonic-gate 18527c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_bld_xmit_pkt_desc_mem_alloc_fail, 18537c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 18547c478bd9Sstevel@tonic-gate "IXL1394_EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque, 18557c478bd9Sstevel@tonic-gate ixl_commandp, wvp->ixl_cur_cmdp); 18567c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit, 18577c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 18587c478bd9Sstevel@tonic-gate return; 18597c478bd9Sstevel@tonic-gate } 18607c478bd9Sstevel@tonic-gate 18617c478bd9Sstevel@tonic-gate /* 18627c478bd9Sstevel@tonic-gate * save xfer_ctl struct addr in compiler_privatep of 18637c478bd9Sstevel@tonic-gate * current IXL xfer cmd 18647c478bd9Sstevel@tonic-gate */ 18657c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp; 18667c478bd9Sstevel@tonic-gate 18677c478bd9Sstevel@tonic-gate /* generate values for the xmit pkt hdrs */ 18687c478bd9Sstevel@tonic-gate hci1394_set_xmit_pkt_hdr(wvp); 18697c478bd9Sstevel@tonic-gate 18707c478bd9Sstevel@tonic-gate /* 18717c478bd9Sstevel@tonic-gate * xmit pkt starts with an output more immediate, 18727c478bd9Sstevel@tonic-gate * a double sized hci1394_desc 18737c478bd9Sstevel@tonic-gate */ 18747c478bd9Sstevel@tonic-gate wv_omi_descp = (hci1394_output_more_imm_t *) 18757c478bd9Sstevel@tonic-gate (&wvp->descriptor_block[wvp->descriptors]); 18767c478bd9Sstevel@tonic-gate HCI1394_INIT_IT_OMORE_IMM(wv_omi_descp); 18777c478bd9Sstevel@tonic-gate 18787c478bd9Sstevel@tonic-gate wv_omi_descp->data_addr = 0; 18797c478bd9Sstevel@tonic-gate wv_omi_descp->branch = 0; 18807c478bd9Sstevel@tonic-gate wv_omi_descp->status = 0; 18817c478bd9Sstevel@tonic-gate wv_omi_descp->q1 = wvp->xmit_pkthdr1; 18827c478bd9Sstevel@tonic-gate wv_omi_descp->q2 = wvp->xmit_pkthdr2; 18837c478bd9Sstevel@tonic-gate wv_omi_descp->q3 = 0; 18847c478bd9Sstevel@tonic-gate wv_omi_descp->q4 = 0; 18857c478bd9Sstevel@tonic-gate 18867c478bd9Sstevel@tonic-gate wvp->descriptors += 2; 18877c478bd9Sstevel@tonic-gate 18887c478bd9Sstevel@tonic-gate /* 18897c478bd9Sstevel@tonic-gate * create the required output more hci1394_desc descriptor, then create 18907c478bd9Sstevel@tonic-gate * an output last hci1394_desc descriptor with xfer status enabled 18917c478bd9Sstevel@tonic-gate */ 18927c478bd9Sstevel@tonic-gate for (ii = 0; ii < wvp->xfer_bufcnt; ii++) { 18937c478bd9Sstevel@tonic-gate wv_descp = &wvp->descriptor_block[wvp->descriptors]; 18947c478bd9Sstevel@tonic-gate 18957c478bd9Sstevel@tonic-gate if (ii == (wvp->xfer_bufcnt - 1)) { 18967c478bd9Sstevel@tonic-gate HCI1394_INIT_IT_OLAST(wv_descp, DESC_HDR_STAT_ENBL, 18977c478bd9Sstevel@tonic-gate DESC_INTR_DSABL, wvp->xfer_size[ii]); 18987c478bd9Sstevel@tonic-gate } else { 18997c478bd9Sstevel@tonic-gate HCI1394_INIT_IT_OMORE(wv_descp, wvp->xfer_size[ii]); 19007c478bd9Sstevel@tonic-gate } 19017c478bd9Sstevel@tonic-gate wv_descp->data_addr = wvp->xfer_bufp[ii]; 19027c478bd9Sstevel@tonic-gate wv_descp->branch = 0; 19037c478bd9Sstevel@tonic-gate wv_descp->status = 0; 19047c478bd9Sstevel@tonic-gate wvp->descriptors++; 19057c478bd9Sstevel@tonic-gate } 19067c478bd9Sstevel@tonic-gate 19077c478bd9Sstevel@tonic-gate /* allocate and copy descriptor block to dma memory */ 19087c478bd9Sstevel@tonic-gate if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp, &dma_desc_bound) != 19097c478bd9Sstevel@tonic-gate DDI_SUCCESS) { 19107c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit, 19117c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 19127c478bd9Sstevel@tonic-gate 19137c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 19147c478bd9Sstevel@tonic-gate return; 19157c478bd9Sstevel@tonic-gate } 19167c478bd9Sstevel@tonic-gate 19177c478bd9Sstevel@tonic-gate /* 19187c478bd9Sstevel@tonic-gate * set dma addrs into xfer_ctl structure (unbound addr (kernel virtual) 19197c478bd9Sstevel@tonic-gate * is last component (descriptor)) 19207c478bd9Sstevel@tonic-gate */ 19217c478bd9Sstevel@tonic-gate xctlp->dma[0].dma_bound = dma_desc_bound; 19227c478bd9Sstevel@tonic-gate xctlp->dma[0].dma_descp = 19237c478bd9Sstevel@tonic-gate dma_descp + (wvp->xfer_bufcnt + 1) * sizeof (hci1394_desc_t); 19247c478bd9Sstevel@tonic-gate xctlp->dma[0].dma_buf = &wvp->dma_currentp->mem; 19257c478bd9Sstevel@tonic-gate 19267c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_pkt_desc_exit, 19277c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 19287c478bd9Sstevel@tonic-gate } 19297c478bd9Sstevel@tonic-gate 19307c478bd9Sstevel@tonic-gate /* 19317c478bd9Sstevel@tonic-gate * hci1394_bld_xmit_buf_desc() 19327c478bd9Sstevel@tonic-gate * Used to create the openHCI dma descriptor blocks for a transmit buffer. 19337c478bd9Sstevel@tonic-gate */ 19347c478bd9Sstevel@tonic-gate static void 19357c478bd9Sstevel@tonic-gate hci1394_bld_xmit_buf_desc(hci1394_comp_ixl_vars_t *wvp) 19367c478bd9Sstevel@tonic-gate { 19377c478bd9Sstevel@tonic-gate hci1394_xfer_ctl_t *xctlp; 19387c478bd9Sstevel@tonic-gate ixl1394_xfer_buf_t *local_ixl_cur_xfer_stp; 19397c478bd9Sstevel@tonic-gate hci1394_output_more_imm_t *wv_omi_descp; /* shorthand to local descrp */ 19407c478bd9Sstevel@tonic-gate hci1394_desc_t *wv_descp; /* shorthand to local descriptor */ 19417c478bd9Sstevel@tonic-gate caddr_t dma_descp; 19427c478bd9Sstevel@tonic-gate uint32_t dma_desc_bound; 19437c478bd9Sstevel@tonic-gate uint32_t pktsize; 19447c478bd9Sstevel@tonic-gate uint32_t pktcnt; 19457c478bd9Sstevel@tonic-gate uint32_t ii; 19467c478bd9Sstevel@tonic-gate 19477c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_buf_desc_enter, 19487c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 19497c478bd9Sstevel@tonic-gate 19507c478bd9Sstevel@tonic-gate local_ixl_cur_xfer_stp = (ixl1394_xfer_buf_t *)wvp->ixl_cur_xfer_stp; 19517c478bd9Sstevel@tonic-gate 19527c478bd9Sstevel@tonic-gate /* determine number and size of pkt desc blocks to create */ 19537c478bd9Sstevel@tonic-gate pktsize = local_ixl_cur_xfer_stp->pkt_size; 19547c478bd9Sstevel@tonic-gate pktcnt = local_ixl_cur_xfer_stp->size / pktsize; 19557c478bd9Sstevel@tonic-gate 19567c478bd9Sstevel@tonic-gate /* allocate an xfer_ctl struct including pktcnt xfer_ctl_dma structs */ 19577c478bd9Sstevel@tonic-gate if ((xctlp = hci1394_alloc_xfer_ctl(wvp, pktcnt)) == NULL) { 19587c478bd9Sstevel@tonic-gate 19597c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL; 19607c478bd9Sstevel@tonic-gate 19617c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_bld_xmit_buf_desc_mem_alloc_fail, 19627c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 19637c478bd9Sstevel@tonic-gate "IXL1394_EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque, 19647c478bd9Sstevel@tonic-gate ixl_commandp, wvp->ixl_cur_cmdp); 19657c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_buf_desc_exit, 19667c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 19677c478bd9Sstevel@tonic-gate return; 19687c478bd9Sstevel@tonic-gate } 19697c478bd9Sstevel@tonic-gate 19707c478bd9Sstevel@tonic-gate /* 19717c478bd9Sstevel@tonic-gate * save xfer_ctl struct addr in compiler_privatep of 19727c478bd9Sstevel@tonic-gate * current IXL xfer cmd 19737c478bd9Sstevel@tonic-gate */ 19747c478bd9Sstevel@tonic-gate local_ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp; 19757c478bd9Sstevel@tonic-gate 19767c478bd9Sstevel@tonic-gate /* generate values for the xmit pkt hdrs */ 19777c478bd9Sstevel@tonic-gate wvp->xfer_pktlen = pktsize; 19787c478bd9Sstevel@tonic-gate hci1394_set_xmit_pkt_hdr(wvp); 19797c478bd9Sstevel@tonic-gate 19807c478bd9Sstevel@tonic-gate /* 19817c478bd9Sstevel@tonic-gate * xmit pkt starts with an output more immediate, 19827c478bd9Sstevel@tonic-gate * a double sized hci1394_desc 19837c478bd9Sstevel@tonic-gate */ 19847c478bd9Sstevel@tonic-gate wv_omi_descp = (hci1394_output_more_imm_t *) 19857c478bd9Sstevel@tonic-gate &wvp->descriptor_block[wvp->descriptors]; 19867c478bd9Sstevel@tonic-gate 19877c478bd9Sstevel@tonic-gate HCI1394_INIT_IT_OMORE_IMM(wv_omi_descp); 19887c478bd9Sstevel@tonic-gate 19897c478bd9Sstevel@tonic-gate wv_omi_descp->data_addr = 0; 19907c478bd9Sstevel@tonic-gate wv_omi_descp->branch = 0; 19917c478bd9Sstevel@tonic-gate wv_omi_descp->status = 0; 19927c478bd9Sstevel@tonic-gate wv_omi_descp->q1 = wvp->xmit_pkthdr1; 19937c478bd9Sstevel@tonic-gate wv_omi_descp->q2 = wvp->xmit_pkthdr2; 19947c478bd9Sstevel@tonic-gate wv_omi_descp->q3 = 0; 19957c478bd9Sstevel@tonic-gate wv_omi_descp->q4 = 0; 19967c478bd9Sstevel@tonic-gate 19977c478bd9Sstevel@tonic-gate wvp->descriptors += 2; 19987c478bd9Sstevel@tonic-gate 19997c478bd9Sstevel@tonic-gate /* follow with a single output last descriptor w/status enabled */ 20007c478bd9Sstevel@tonic-gate wv_descp = &wvp->descriptor_block[wvp->descriptors]; 20017c478bd9Sstevel@tonic-gate HCI1394_INIT_IT_OLAST(wv_descp, DESC_HDR_STAT_ENBL, DESC_INTR_DSABL, 20027c478bd9Sstevel@tonic-gate pktsize); 20037c478bd9Sstevel@tonic-gate wv_descp->data_addr = local_ixl_cur_xfer_stp->ixl_buf.ixldmac_addr; 20047c478bd9Sstevel@tonic-gate wv_descp->branch = 0; 20057c478bd9Sstevel@tonic-gate wv_descp->status = 0; 20067c478bd9Sstevel@tonic-gate wvp->descriptors++; 20077c478bd9Sstevel@tonic-gate 20087c478bd9Sstevel@tonic-gate /* 20097c478bd9Sstevel@tonic-gate * generate as many contiguous descriptor blocks as there are 20107c478bd9Sstevel@tonic-gate * xmit packets 20117c478bd9Sstevel@tonic-gate */ 20127c478bd9Sstevel@tonic-gate for (ii = 0; ii < pktcnt; ii++) { 20137c478bd9Sstevel@tonic-gate 20147c478bd9Sstevel@tonic-gate /* if about to create last descriptor block */ 20157c478bd9Sstevel@tonic-gate if (ii == (pktcnt - 1)) { 20167c478bd9Sstevel@tonic-gate /* check and perform any required hci cache flush */ 20177c478bd9Sstevel@tonic-gate if (hci1394_flush_end_desc_check(wvp, ii) != 20187c478bd9Sstevel@tonic-gate DDI_SUCCESS) { 20197c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG( 20207c478bd9Sstevel@tonic-gate hci1394_bld_xmit_buf_desc_exit, 20217c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 20227c478bd9Sstevel@tonic-gate 20237c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 20247c478bd9Sstevel@tonic-gate return; 20257c478bd9Sstevel@tonic-gate } 20267c478bd9Sstevel@tonic-gate } 20277c478bd9Sstevel@tonic-gate 20287c478bd9Sstevel@tonic-gate /* allocate and copy descriptor block to dma memory */ 20297c478bd9Sstevel@tonic-gate if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp, 20307c478bd9Sstevel@tonic-gate &dma_desc_bound) != DDI_SUCCESS) { 20317c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_buf_desc_exit, 20327c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 20337c478bd9Sstevel@tonic-gate 20347c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 20357c478bd9Sstevel@tonic-gate return; 20367c478bd9Sstevel@tonic-gate } 20377c478bd9Sstevel@tonic-gate 20387c478bd9Sstevel@tonic-gate /* 20397c478bd9Sstevel@tonic-gate * set dma addrs into xfer_ctl structure (unbound addr 20407c478bd9Sstevel@tonic-gate * (kernel virtual) is last component (descriptor)) 20417c478bd9Sstevel@tonic-gate */ 20427c478bd9Sstevel@tonic-gate xctlp->dma[ii].dma_bound = dma_desc_bound; 20437c478bd9Sstevel@tonic-gate xctlp->dma[ii].dma_descp = dma_descp + 2 * 20447c478bd9Sstevel@tonic-gate sizeof (hci1394_desc_t); 20457c478bd9Sstevel@tonic-gate xctlp->dma[ii].dma_buf = &wvp->dma_currentp->mem; 20467c478bd9Sstevel@tonic-gate 20477c478bd9Sstevel@tonic-gate /* advance buffer ptr by pktsize in descriptor block */ 20487c478bd9Sstevel@tonic-gate wvp->descriptor_block[wvp->descriptors - 1].data_addr += 20497c478bd9Sstevel@tonic-gate pktsize; 20507c478bd9Sstevel@tonic-gate } 20517c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_buf_desc_exit, 20527c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 20537c478bd9Sstevel@tonic-gate } 20547c478bd9Sstevel@tonic-gate 20557c478bd9Sstevel@tonic-gate /* 20567c478bd9Sstevel@tonic-gate * hci1394_bld_xmit_hdronly_nopkt_desc() 20577c478bd9Sstevel@tonic-gate * Used to create the openHCI dma descriptor blocks for transmitting 20587c478bd9Sstevel@tonic-gate * a packet consisting of an isochronous header with no data payload, 20597c478bd9Sstevel@tonic-gate * or for not sending a packet at all for a cycle. 20607c478bd9Sstevel@tonic-gate * 20617c478bd9Sstevel@tonic-gate * A Store_Value openhci descriptor is built at the start of each 20627c478bd9Sstevel@tonic-gate * IXL1394_OP_SEND_HDR_ONLY and IXL1394_OP_SEND_NO_PKT command's dma 20637c478bd9Sstevel@tonic-gate * descriptor block (to allow for skip cycle specification and set skipmode 20647c478bd9Sstevel@tonic-gate * processing for these commands). 20657c478bd9Sstevel@tonic-gate */ 20667c478bd9Sstevel@tonic-gate static void 20677c478bd9Sstevel@tonic-gate hci1394_bld_xmit_hdronly_nopkt_desc(hci1394_comp_ixl_vars_t *wvp) 20687c478bd9Sstevel@tonic-gate { 20697c478bd9Sstevel@tonic-gate hci1394_xfer_ctl_t *xctlp; 20707c478bd9Sstevel@tonic-gate hci1394_output_last_t *wv_ol_descp; /* shorthand to local descrp */ 20717c478bd9Sstevel@tonic-gate hci1394_output_last_imm_t *wv_oli_descp; /* shorthand to local descrp */ 20727c478bd9Sstevel@tonic-gate caddr_t dma_descp; 20737c478bd9Sstevel@tonic-gate uint32_t dma_desc_bound; 20747c478bd9Sstevel@tonic-gate uint32_t repcnt; 20757c478bd9Sstevel@tonic-gate uint32_t ii; 20767c478bd9Sstevel@tonic-gate 20777c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_hdronly_nopkt_desc_enter, 20787c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 20797c478bd9Sstevel@tonic-gate 20807c478bd9Sstevel@tonic-gate /* determine # of instances of output hdronly/nopkt to generate */ 20817c478bd9Sstevel@tonic-gate repcnt = ((ixl1394_xmit_special_t *)wvp->ixl_cur_xfer_stp)->count; 20827c478bd9Sstevel@tonic-gate 20837c478bd9Sstevel@tonic-gate /* 20847c478bd9Sstevel@tonic-gate * allocate an xfer_ctl structure which includes repcnt 20857c478bd9Sstevel@tonic-gate * xfer_ctl_dma structs 20867c478bd9Sstevel@tonic-gate */ 20877c478bd9Sstevel@tonic-gate if ((xctlp = hci1394_alloc_xfer_ctl(wvp, repcnt)) == NULL) { 20887c478bd9Sstevel@tonic-gate 20897c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL; 20907c478bd9Sstevel@tonic-gate 20917c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_bld_xmit_hdronly_nopkt_desc_mem_alloc_fail, 20927c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 20937c478bd9Sstevel@tonic-gate "IXL EMEM_ALLOC_FAIL: for xfer_ctl", tnf_opaque, 20947c478bd9Sstevel@tonic-gate ixl_commandp, wvp->ixl_cur_cmdp); 20957c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_hdronly_nopkt_desc_exit, 20967c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 20977c478bd9Sstevel@tonic-gate return; 20987c478bd9Sstevel@tonic-gate } 20997c478bd9Sstevel@tonic-gate 21007c478bd9Sstevel@tonic-gate /* 21017c478bd9Sstevel@tonic-gate * save xfer_ctl struct addr in compiler_privatep of 21027c478bd9Sstevel@tonic-gate * current IXL xfer command 21037c478bd9Sstevel@tonic-gate */ 21047c478bd9Sstevel@tonic-gate wvp->ixl_cur_xfer_stp->compiler_privatep = (void *)xctlp; 21057c478bd9Sstevel@tonic-gate 21067c478bd9Sstevel@tonic-gate /* 21077c478bd9Sstevel@tonic-gate * create a storevalue descriptor 21087c478bd9Sstevel@tonic-gate * (will be used for skip vs jump processing) 21097c478bd9Sstevel@tonic-gate */ 21107c478bd9Sstevel@tonic-gate hci1394_set_xmit_storevalue_desc(wvp); 21117c478bd9Sstevel@tonic-gate 21127c478bd9Sstevel@tonic-gate /* 21137c478bd9Sstevel@tonic-gate * processing now based on opcode: 21147c478bd9Sstevel@tonic-gate * IXL1394_OP_SEND_HDR_ONLY or IXL1394_OP_SEND_NO_PKT 21157c478bd9Sstevel@tonic-gate */ 21167c478bd9Sstevel@tonic-gate if ((wvp->ixl_cur_xfer_stp->ixl_opcode & ~IXL1394_OPF_UPDATE) == 21177c478bd9Sstevel@tonic-gate IXL1394_OP_SEND_HDR_ONLY) { 21187c478bd9Sstevel@tonic-gate 21197c478bd9Sstevel@tonic-gate /* for header only, generate values for the xmit pkt hdrs */ 21207c478bd9Sstevel@tonic-gate hci1394_set_xmit_pkt_hdr(wvp); 21217c478bd9Sstevel@tonic-gate 21227c478bd9Sstevel@tonic-gate /* 21237c478bd9Sstevel@tonic-gate * create an output last immediate (double sized) descriptor 21247c478bd9Sstevel@tonic-gate * xfer status enabled 21257c478bd9Sstevel@tonic-gate */ 21267c478bd9Sstevel@tonic-gate wv_oli_descp = (hci1394_output_last_imm_t *) 21277c478bd9Sstevel@tonic-gate &wvp->descriptor_block[wvp->descriptors]; 21287c478bd9Sstevel@tonic-gate 21297c478bd9Sstevel@tonic-gate HCI1394_INIT_IT_OLAST_IMM(wv_oli_descp, DESC_HDR_STAT_ENBL, 21307c478bd9Sstevel@tonic-gate DESC_INTR_DSABL); 21317c478bd9Sstevel@tonic-gate 21327c478bd9Sstevel@tonic-gate wv_oli_descp->data_addr = 0; 21337c478bd9Sstevel@tonic-gate wv_oli_descp->branch = 0; 21347c478bd9Sstevel@tonic-gate wv_oli_descp->status = 0; 21357c478bd9Sstevel@tonic-gate wv_oli_descp->q1 = wvp->xmit_pkthdr1; 21367c478bd9Sstevel@tonic-gate wv_oli_descp->q2 = wvp->xmit_pkthdr2; 21377c478bd9Sstevel@tonic-gate wv_oli_descp->q3 = 0; 21387c478bd9Sstevel@tonic-gate wv_oli_descp->q4 = 0; 21397c478bd9Sstevel@tonic-gate wvp->descriptors += 2; 21407c478bd9Sstevel@tonic-gate } else { 21417c478bd9Sstevel@tonic-gate /* 21427c478bd9Sstevel@tonic-gate * for skip cycle, create a single output last descriptor 21437c478bd9Sstevel@tonic-gate * with xfer status enabled 21447c478bd9Sstevel@tonic-gate */ 21457c478bd9Sstevel@tonic-gate wv_ol_descp = &wvp->descriptor_block[wvp->descriptors]; 21467c478bd9Sstevel@tonic-gate HCI1394_INIT_IT_OLAST(wv_ol_descp, DESC_HDR_STAT_ENBL, 21477c478bd9Sstevel@tonic-gate DESC_INTR_DSABL, 0); 21487c478bd9Sstevel@tonic-gate wv_ol_descp->data_addr = 0; 21497c478bd9Sstevel@tonic-gate wv_ol_descp->branch = 0; 21507c478bd9Sstevel@tonic-gate wv_ol_descp->status = 0; 21517c478bd9Sstevel@tonic-gate wvp->descriptors++; 21527c478bd9Sstevel@tonic-gate } 21537c478bd9Sstevel@tonic-gate 21547c478bd9Sstevel@tonic-gate /* 21557c478bd9Sstevel@tonic-gate * generate as many contiguous descriptor blocks as repeat count 21567c478bd9Sstevel@tonic-gate * indicates 21577c478bd9Sstevel@tonic-gate */ 21587c478bd9Sstevel@tonic-gate for (ii = 0; ii < repcnt; ii++) { 21597c478bd9Sstevel@tonic-gate 21607c478bd9Sstevel@tonic-gate /* if about to create last descriptor block */ 21617c478bd9Sstevel@tonic-gate if (ii == (repcnt - 1)) { 21627c478bd9Sstevel@tonic-gate /* check and perform any required hci cache flush */ 21637c478bd9Sstevel@tonic-gate if (hci1394_flush_end_desc_check(wvp, ii) != 21647c478bd9Sstevel@tonic-gate DDI_SUCCESS) { 21657c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG( 21667c478bd9Sstevel@tonic-gate hci1394_bld_xmit_hdronly_nopkt_desc_exit, 21677c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 21687c478bd9Sstevel@tonic-gate 21697c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 21707c478bd9Sstevel@tonic-gate return; 21717c478bd9Sstevel@tonic-gate } 21727c478bd9Sstevel@tonic-gate } 21737c478bd9Sstevel@tonic-gate 21747c478bd9Sstevel@tonic-gate /* allocate and copy descriptor block to dma memory */ 21757c478bd9Sstevel@tonic-gate if (hci1394_bld_dma_mem_desc_blk(wvp, &dma_descp, 21767c478bd9Sstevel@tonic-gate &dma_desc_bound) != DDI_SUCCESS) { 21777c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG( 21787c478bd9Sstevel@tonic-gate hci1394_bld_xmit_hdronly_nopkt_desc_exit, 21797c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 21807c478bd9Sstevel@tonic-gate 21817c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 21827c478bd9Sstevel@tonic-gate return; 21837c478bd9Sstevel@tonic-gate } 21847c478bd9Sstevel@tonic-gate 21857c478bd9Sstevel@tonic-gate /* 21867c478bd9Sstevel@tonic-gate * set dma addrs into xfer_ctl structure (unbound addr 21877c478bd9Sstevel@tonic-gate * (kernel virtual) is last component (descriptor) 21887c478bd9Sstevel@tonic-gate */ 21897c478bd9Sstevel@tonic-gate xctlp->dma[ii].dma_bound = dma_desc_bound; 21907c478bd9Sstevel@tonic-gate xctlp->dma[ii].dma_descp = dma_descp + sizeof (hci1394_desc_t); 21917c478bd9Sstevel@tonic-gate xctlp->dma[ii].dma_buf = &wvp->dma_currentp->mem; 21927c478bd9Sstevel@tonic-gate } 21937c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_xmit_hdronly_nopkt_desc_exit, 21947c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 21957c478bd9Sstevel@tonic-gate } 21967c478bd9Sstevel@tonic-gate 21977c478bd9Sstevel@tonic-gate /* 21987c478bd9Sstevel@tonic-gate * hci1394_bld_dma_mem_desc_blk() 21997c478bd9Sstevel@tonic-gate * Used to put a given OpenHCI descriptor block into dma bound memory. 22007c478bd9Sstevel@tonic-gate */ 22017c478bd9Sstevel@tonic-gate static int 22027c478bd9Sstevel@tonic-gate hci1394_bld_dma_mem_desc_blk(hci1394_comp_ixl_vars_t *wvp, caddr_t *dma_descpp, 22037c478bd9Sstevel@tonic-gate uint32_t *dma_desc_bound) 22047c478bd9Sstevel@tonic-gate { 22057c478bd9Sstevel@tonic-gate uint32_t dma_bound; 22067c478bd9Sstevel@tonic-gate 22077c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_dma_mem_desc_blk_enter, 22087c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 22097c478bd9Sstevel@tonic-gate 22107c478bd9Sstevel@tonic-gate /* set internal error if no descriptor blocks to build */ 22117c478bd9Sstevel@tonic-gate if (wvp->descriptors == 0) { 22127c478bd9Sstevel@tonic-gate 22137c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EINTERNAL_ERROR; 22147c478bd9Sstevel@tonic-gate 22157c478bd9Sstevel@tonic-gate TNF_PROBE_1(hci1394_bld_dma_mem_desc_blk_error, 22167c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 22177c478bd9Sstevel@tonic-gate "IXL1394_INTERNAL_ERROR: no descriptors to build"); 22187c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_dma_mem_desc_blk_exit, 22197c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 22207c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 22217c478bd9Sstevel@tonic-gate } 22227c478bd9Sstevel@tonic-gate 22237c478bd9Sstevel@tonic-gate /* allocate dma memory and move this descriptor block to it */ 22247c478bd9Sstevel@tonic-gate *dma_descpp = (caddr_t)hci1394_alloc_dma_mem(wvp, wvp->descriptors * 22257c478bd9Sstevel@tonic-gate sizeof (hci1394_desc_t), &dma_bound); 22267c478bd9Sstevel@tonic-gate 22277c478bd9Sstevel@tonic-gate if (*dma_descpp == NULL) { 22287c478bd9Sstevel@tonic-gate 22297c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL; 22307c478bd9Sstevel@tonic-gate 22317c478bd9Sstevel@tonic-gate TNF_PROBE_1(hci1394_bld_dma_mem_desc_blk_fail, 22327c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 22337c478bd9Sstevel@tonic-gate "IXL1394_EMEM_ALLOC_FAIL: for descriptors"); 22347c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_dma_mem_desc_blk_exit, 22357c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 22367c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 22377c478bd9Sstevel@tonic-gate } 22387c478bd9Sstevel@tonic-gate #ifdef _KERNEL 22397c478bd9Sstevel@tonic-gate ddi_rep_put32(wvp->dma_currentp->mem.bi_handle, 22407c478bd9Sstevel@tonic-gate (uint_t *)wvp->descriptor_block, (uint_t *)*dma_descpp, 22417c478bd9Sstevel@tonic-gate wvp->descriptors * (sizeof (hci1394_desc_t) >> 2), 22427c478bd9Sstevel@tonic-gate DDI_DEV_AUTOINCR); 22437c478bd9Sstevel@tonic-gate #else 22447c478bd9Sstevel@tonic-gate bcopy(wvp->descriptor_block, *dma_descpp, 22457c478bd9Sstevel@tonic-gate wvp->descriptors * sizeof (hci1394_desc_t)); 22467c478bd9Sstevel@tonic-gate #endif 22477c478bd9Sstevel@tonic-gate /* 22487c478bd9Sstevel@tonic-gate * convert allocated block's memory address to bus address space 22497c478bd9Sstevel@tonic-gate * include properly set Z bits (descriptor count). 22507c478bd9Sstevel@tonic-gate */ 22517c478bd9Sstevel@tonic-gate *dma_desc_bound = (dma_bound & ~DESC_Z_MASK) | wvp->descriptors; 22527c478bd9Sstevel@tonic-gate 22537c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_bld_dma_mem_desc_blk_exit, 22547c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 22557c478bd9Sstevel@tonic-gate 22567c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 22577c478bd9Sstevel@tonic-gate } 22587c478bd9Sstevel@tonic-gate 22597c478bd9Sstevel@tonic-gate /* 22607c478bd9Sstevel@tonic-gate * hci1394_set_xmit_pkt_hdr() 22617c478bd9Sstevel@tonic-gate * Compose the 2 quadlets for the xmit packet header. 22627c478bd9Sstevel@tonic-gate */ 22637c478bd9Sstevel@tonic-gate static void 22647c478bd9Sstevel@tonic-gate hci1394_set_xmit_pkt_hdr(hci1394_comp_ixl_vars_t *wvp) 22657c478bd9Sstevel@tonic-gate { 22667c478bd9Sstevel@tonic-gate uint16_t tag; 22677c478bd9Sstevel@tonic-gate uint16_t sync; 22687c478bd9Sstevel@tonic-gate 22697c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_set_xmit_pkt_hdr_enter, 22707c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 22717c478bd9Sstevel@tonic-gate 22727c478bd9Sstevel@tonic-gate /* 22737c478bd9Sstevel@tonic-gate * choose tag and sync bits for header either from default values or 22747c478bd9Sstevel@tonic-gate * from currently active set tag and sync IXL command 22757c478bd9Sstevel@tonic-gate * (clear command after use) 22767c478bd9Sstevel@tonic-gate */ 22777c478bd9Sstevel@tonic-gate if (wvp->ixl_settagsync_cmdp == NULL) { 22787c478bd9Sstevel@tonic-gate tag = wvp->default_tag; 22797c478bd9Sstevel@tonic-gate sync = wvp->default_sync; 22807c478bd9Sstevel@tonic-gate } else { 22817c478bd9Sstevel@tonic-gate tag = wvp->ixl_settagsync_cmdp->tag; 22827c478bd9Sstevel@tonic-gate sync = wvp->ixl_settagsync_cmdp->sync; 22837c478bd9Sstevel@tonic-gate wvp->ixl_settagsync_cmdp = NULL; 22847c478bd9Sstevel@tonic-gate } 22857c478bd9Sstevel@tonic-gate tag &= (DESC_PKT_TAG_MASK >> DESC_PKT_TAG_SHIFT); 22867c478bd9Sstevel@tonic-gate sync &= (DESC_PKT_SY_MASK >> DESC_PKT_SY_SHIFT); 22877c478bd9Sstevel@tonic-gate 22887c478bd9Sstevel@tonic-gate /* 22897c478bd9Sstevel@tonic-gate * build xmit pkt header - 22907c478bd9Sstevel@tonic-gate * hdr1 has speed, tag, channel number and sync bits 22917c478bd9Sstevel@tonic-gate * hdr2 has the packet length. 22927c478bd9Sstevel@tonic-gate */ 22937c478bd9Sstevel@tonic-gate wvp->xmit_pkthdr1 = (wvp->ctxtp->isospd << DESC_PKT_SPD_SHIFT) | 22947c478bd9Sstevel@tonic-gate (tag << DESC_PKT_TAG_SHIFT) | (wvp->ctxtp->isochan << 22957c478bd9Sstevel@tonic-gate DESC_PKT_CHAN_SHIFT) | (IEEE1394_TCODE_ISOCH << 22967c478bd9Sstevel@tonic-gate DESC_PKT_TCODE_SHIFT) | (sync << DESC_PKT_SY_SHIFT); 22977c478bd9Sstevel@tonic-gate 22987c478bd9Sstevel@tonic-gate wvp->xmit_pkthdr2 = wvp->xfer_pktlen << DESC_PKT_DATALEN_SHIFT; 22997c478bd9Sstevel@tonic-gate 23007c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_set_xmit_pkt_hdr_exit, 23017c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 23027c478bd9Sstevel@tonic-gate } 23037c478bd9Sstevel@tonic-gate 23047c478bd9Sstevel@tonic-gate /* 23057c478bd9Sstevel@tonic-gate * hci1394_set_xmit_skip_mode() 23067c478bd9Sstevel@tonic-gate * Set current skip mode from default or from currently active command. 23077c478bd9Sstevel@tonic-gate * If non-default skip mode command's skip mode is skip to label, find 23087c478bd9Sstevel@tonic-gate * and set xfer start IXL command which follows skip to label into 23097c478bd9Sstevel@tonic-gate * compiler_privatep of set skipmode IXL command. 23107c478bd9Sstevel@tonic-gate */ 23117c478bd9Sstevel@tonic-gate static void 23127c478bd9Sstevel@tonic-gate hci1394_set_xmit_skip_mode(hci1394_comp_ixl_vars_t *wvp) 23137c478bd9Sstevel@tonic-gate { 23147c478bd9Sstevel@tonic-gate int err; 23157c478bd9Sstevel@tonic-gate 23167c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_set_xmit_skip_mode_enter, 23177c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 23187c478bd9Sstevel@tonic-gate 23197c478bd9Sstevel@tonic-gate if (wvp->ixl_setskipmode_cmdp == NULL) { 23207c478bd9Sstevel@tonic-gate wvp->skipmode = wvp->default_skipmode; 23217c478bd9Sstevel@tonic-gate wvp->skiplabelp = wvp->default_skiplabelp; 23227c478bd9Sstevel@tonic-gate wvp->skipxferp = wvp->default_skipxferp; 23237c478bd9Sstevel@tonic-gate } else { 23247c478bd9Sstevel@tonic-gate wvp->skipmode = wvp->ixl_setskipmode_cmdp->skipmode; 23257c478bd9Sstevel@tonic-gate wvp->skiplabelp = wvp->ixl_setskipmode_cmdp->label; 23267c478bd9Sstevel@tonic-gate wvp->skipxferp = NULL; 23277c478bd9Sstevel@tonic-gate if (wvp->skipmode == IXL1394_SKIP_TO_LABEL) { 23287c478bd9Sstevel@tonic-gate err = hci1394_ixl_find_next_exec_xfer(wvp->skiplabelp, 23297c478bd9Sstevel@tonic-gate NULL, &wvp->skipxferp); 23307c478bd9Sstevel@tonic-gate if (err == DDI_FAILURE) { 23317c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_set_xmit_skip_mode_error, 23327c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, 23337c478bd9Sstevel@tonic-gate errmsg, "IXL1394_ENO_DATA_PKTS: " 23347c478bd9Sstevel@tonic-gate "label<->jump loop detected for skiplabel " 23357c478bd9Sstevel@tonic-gate "w/no xfers", tnf_opaque, setskip_cmdp, 23367c478bd9Sstevel@tonic-gate wvp->ixl_setskipmode_cmdp); 23377c478bd9Sstevel@tonic-gate wvp->skipxferp = NULL; 23387c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_ENO_DATA_PKTS; 23397c478bd9Sstevel@tonic-gate } 23407c478bd9Sstevel@tonic-gate } 23417c478bd9Sstevel@tonic-gate wvp->ixl_setskipmode_cmdp->compiler_privatep = 23427c478bd9Sstevel@tonic-gate (void *)wvp->skipxferp; 23437c478bd9Sstevel@tonic-gate } 23447c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_set_xmit_skip_mode_exit, 23457c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 23467c478bd9Sstevel@tonic-gate } 23477c478bd9Sstevel@tonic-gate 23487c478bd9Sstevel@tonic-gate /* 23497c478bd9Sstevel@tonic-gate * hci1394_set_xmit_storevalue_desc() 23507c478bd9Sstevel@tonic-gate * Set up store_value DMA descriptor. 23517c478bd9Sstevel@tonic-gate * XMIT_HDRONLY or XMIT_NOPKT xfer states use a store value as first 23527c478bd9Sstevel@tonic-gate * descriptor in the descriptor block (to handle skip mode processing) 23537c478bd9Sstevel@tonic-gate */ 23547c478bd9Sstevel@tonic-gate static void 23557c478bd9Sstevel@tonic-gate hci1394_set_xmit_storevalue_desc(hci1394_comp_ixl_vars_t *wvp) 23567c478bd9Sstevel@tonic-gate { 23577c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_set_xmit_storevalue_desc_enter, 23587c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 23597c478bd9Sstevel@tonic-gate 23607c478bd9Sstevel@tonic-gate wvp->descriptors++; 23617c478bd9Sstevel@tonic-gate 23627c478bd9Sstevel@tonic-gate HCI1394_INIT_IT_STORE(&wvp->descriptor_block[wvp->descriptors - 1], 23637c478bd9Sstevel@tonic-gate wvp->storevalue_data); 23647c478bd9Sstevel@tonic-gate wvp->descriptor_block[wvp->descriptors - 1].data_addr = 23657c478bd9Sstevel@tonic-gate wvp->storevalue_bufp; 23667c478bd9Sstevel@tonic-gate wvp->descriptor_block[wvp->descriptors - 1].branch = 0; 23677c478bd9Sstevel@tonic-gate wvp->descriptor_block[wvp->descriptors - 1].status = 0; 23687c478bd9Sstevel@tonic-gate 23697c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_set_xmit_storevalue_desc_exit, 23707c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 23717c478bd9Sstevel@tonic-gate } 23727c478bd9Sstevel@tonic-gate 23737c478bd9Sstevel@tonic-gate /* 23747c478bd9Sstevel@tonic-gate * hci1394_set_next_xfer_buf() 23757c478bd9Sstevel@tonic-gate * This routine adds the data buffer to the current wvp list. 23767c478bd9Sstevel@tonic-gate * Returns DDI_SUCCESS or DDI_FAILURE. If DDI_FAILURE, wvp->dma_bld_error 23777c478bd9Sstevel@tonic-gate * contains the error code. 23787c478bd9Sstevel@tonic-gate */ 23797c478bd9Sstevel@tonic-gate static int 23807c478bd9Sstevel@tonic-gate hci1394_set_next_xfer_buf(hci1394_comp_ixl_vars_t *wvp, uint32_t bufp, 23817c478bd9Sstevel@tonic-gate uint16_t size) 23827c478bd9Sstevel@tonic-gate { 23837c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_set_next_xfer_buf_enter, 23847c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 23857c478bd9Sstevel@tonic-gate 23867c478bd9Sstevel@tonic-gate /* error if buffer pointer is null (size may be 0) */ 2387*ffc2b7d4SToomas Soome if (bufp == 0) { 23887c478bd9Sstevel@tonic-gate 23897c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_ENULL_BUFFER_ADDR; 23907c478bd9Sstevel@tonic-gate 23917c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_set_next_xfer_buf_exit, 23927c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 23937c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 23947c478bd9Sstevel@tonic-gate } 23957c478bd9Sstevel@tonic-gate 23967c478bd9Sstevel@tonic-gate /* count new xfer buffer */ 23977c478bd9Sstevel@tonic-gate wvp->xfer_bufcnt++; 23987c478bd9Sstevel@tonic-gate 23997c478bd9Sstevel@tonic-gate /* error if exceeds maximum xfer buffer components allowed */ 24007c478bd9Sstevel@tonic-gate if (wvp->xfer_bufcnt > HCI1394_DESC_MAX_Z) { 24017c478bd9Sstevel@tonic-gate 24027c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EFRAGMENT_OFLO; 24037c478bd9Sstevel@tonic-gate 24047c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_set_next_xfer_buf_error, 24057c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 24067c478bd9Sstevel@tonic-gate "IXL1394_EFRAGMENT_OFLO", tnf_int, frag_count, 24077c478bd9Sstevel@tonic-gate wvp->xfer_bufcnt); 24087c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_set_next_xfer_buf_exit, 24097c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 24107c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 24117c478bd9Sstevel@tonic-gate } 24127c478bd9Sstevel@tonic-gate 24137c478bd9Sstevel@tonic-gate /* save xmit buffer and size */ 24147c478bd9Sstevel@tonic-gate wvp->xfer_bufp[wvp->xfer_bufcnt - 1] = bufp; 24157c478bd9Sstevel@tonic-gate wvp->xfer_size[wvp->xfer_bufcnt - 1] = size; 24167c478bd9Sstevel@tonic-gate 24177c478bd9Sstevel@tonic-gate /* accumulate total packet length */ 24187c478bd9Sstevel@tonic-gate wvp->xfer_pktlen += size; 24197c478bd9Sstevel@tonic-gate 24207c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_set_next_xfer_buf_exit, 24217c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 24227c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 24237c478bd9Sstevel@tonic-gate } 24247c478bd9Sstevel@tonic-gate 24257c478bd9Sstevel@tonic-gate /* 24267c478bd9Sstevel@tonic-gate * hci1394_flush_end_desc_check() 24277c478bd9Sstevel@tonic-gate * Check if flush required before last descriptor block of a 24287c478bd9Sstevel@tonic-gate * non-unary set generated by an xfer buff or xmit special command 24297c478bd9Sstevel@tonic-gate * or a unary set provided no other flush has already been done. 24307c478bd9Sstevel@tonic-gate * 24317c478bd9Sstevel@tonic-gate * hci flush is required if xfer is finalized by an updateable 24327c478bd9Sstevel@tonic-gate * jump command. 24337c478bd9Sstevel@tonic-gate * 24347c478bd9Sstevel@tonic-gate * Returns DDI_SUCCESS or DDI_FAILURE. If DDI_FAILURE, wvp->dma_bld_error 24357c478bd9Sstevel@tonic-gate * will contain the error code. 24367c478bd9Sstevel@tonic-gate */ 24377c478bd9Sstevel@tonic-gate static int 24387c478bd9Sstevel@tonic-gate hci1394_flush_end_desc_check(hci1394_comp_ixl_vars_t *wvp, uint32_t count) 24397c478bd9Sstevel@tonic-gate { 24407c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_flush_end_desc_check_enter, 24417c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 24427c478bd9Sstevel@tonic-gate 24437c478bd9Sstevel@tonic-gate if ((count != 0) || 24447c478bd9Sstevel@tonic-gate ((wvp->xfer_hci_flush & (UPDATEABLE_XFER | UPDATEABLE_SET | 2445*ffc2b7d4SToomas Soome INITIATING_LBL)) == 0)) { 24467c478bd9Sstevel@tonic-gate 24477c478bd9Sstevel@tonic-gate if (wvp->xfer_hci_flush & UPDATEABLE_JUMP) { 24487c478bd9Sstevel@tonic-gate if (hci1394_flush_hci_cache(wvp) != DDI_SUCCESS) { 24497c478bd9Sstevel@tonic-gate 24507c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG( 24517c478bd9Sstevel@tonic-gate hci1394_flush_end_desc_check_exit, 24527c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 24537c478bd9Sstevel@tonic-gate 24547c478bd9Sstevel@tonic-gate /* wvp->dma_bld_error is set by above call */ 24557c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 24567c478bd9Sstevel@tonic-gate } 24577c478bd9Sstevel@tonic-gate } 24587c478bd9Sstevel@tonic-gate } 24597c478bd9Sstevel@tonic-gate 24607c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_flush_end_desc_check_exit, 24617c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 24627c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 24637c478bd9Sstevel@tonic-gate } 24647c478bd9Sstevel@tonic-gate 24657c478bd9Sstevel@tonic-gate /* 24667c478bd9Sstevel@tonic-gate * hci1394_flush_hci_cache() 24677c478bd9Sstevel@tonic-gate * Sun hci controller (RIO) implementation specific processing! 24687c478bd9Sstevel@tonic-gate * 24697c478bd9Sstevel@tonic-gate * Allocate dma memory for 1 hci descriptor block which will be left unused. 24707c478bd9Sstevel@tonic-gate * During execution this will cause a break in the contiguous address space 24717c478bd9Sstevel@tonic-gate * processing required by Sun's RIO implementation of the ohci controller and 24727c478bd9Sstevel@tonic-gate * will require the controller to refetch the next descriptor block from 24737c478bd9Sstevel@tonic-gate * host memory. 24747c478bd9Sstevel@tonic-gate * 24757c478bd9Sstevel@tonic-gate * General rules for cache flush preceeding a descriptor block in dma memory: 24767c478bd9Sstevel@tonic-gate * 1. Current IXL Xfer Command Updateable Rule: 24777c478bd9Sstevel@tonic-gate * Cache flush of IXL xfer command is required if it, or any of the 24787c478bd9Sstevel@tonic-gate * non-start IXL packet xfer commands associated with it, is flagged 24797c478bd9Sstevel@tonic-gate * updateable. 24807c478bd9Sstevel@tonic-gate * 2. Next IXL Xfer Command Indeterminate Rule: 24817c478bd9Sstevel@tonic-gate * Cache flush of IXL xfer command is required if an IXL jump command 24827c478bd9Sstevel@tonic-gate * which is flagged updateable has finalized the current IXL xfer 24837c478bd9Sstevel@tonic-gate * command. 24847c478bd9Sstevel@tonic-gate * 3. Updateable IXL Set Command Rule: 24857c478bd9Sstevel@tonic-gate * Cache flush of an IXL xfer command is required if any of the IXL 24867c478bd9Sstevel@tonic-gate * "Set" commands (IXL1394_OP_SET_*) associated with the IXL xfer 24877c478bd9Sstevel@tonic-gate * command (i.e. immediately preceeding it), is flagged updateable. 24887c478bd9Sstevel@tonic-gate * 4. Label Initiating Xfer Command Rule: 24897c478bd9Sstevel@tonic-gate * Cache flush of IXL xfer command is required if it is initiated by a 24907c478bd9Sstevel@tonic-gate * label IXL command. (This is to allow both a flush of the cache and 24917c478bd9Sstevel@tonic-gate * an interrupt to be generated easily and in close proximity to each 24927c478bd9Sstevel@tonic-gate * other. This can make possible simpler more successful reset of 24937c478bd9Sstevel@tonic-gate * descriptor statuses, especially under circumstances where the cycle 24947c478bd9Sstevel@tonic-gate * of hci commands is short and/or there are no callbacks distributed 24957c478bd9Sstevel@tonic-gate * through the span of xfers, etc... This is especially important for 24967c478bd9Sstevel@tonic-gate * input where statuses must be reset before execution cycles back 24977c478bd9Sstevel@tonic-gate * again. 24987c478bd9Sstevel@tonic-gate * 24997c478bd9Sstevel@tonic-gate * Application of above rules: 25007c478bd9Sstevel@tonic-gate * Packet mode IXL xfer commands: 25017c478bd9Sstevel@tonic-gate * If any of the above flush rules apply, flush cache should be done 25027c478bd9Sstevel@tonic-gate * immediately preceeding the generation of the dma descriptor block 25037c478bd9Sstevel@tonic-gate * for the packet xfer. 25047c478bd9Sstevel@tonic-gate * Non-packet mode IXL xfer commands (including IXL1394_OP_*BUF*, 25057c478bd9Sstevel@tonic-gate * SEND_HDR_ONLY, and SEND_NO_PKT): 25067c478bd9Sstevel@tonic-gate * If Rules #1, #3 or #4 applies, a flush cache should be done 25077c478bd9Sstevel@tonic-gate * immediately before the first generated dma descriptor block of the 25087c478bd9Sstevel@tonic-gate * non-packet xfer. 25097c478bd9Sstevel@tonic-gate * If Rule #2 applies, a flush cache should be done immediately before 25107c478bd9Sstevel@tonic-gate * the last generated dma descriptor block of the non-packet xfer. 25117c478bd9Sstevel@tonic-gate * 25127c478bd9Sstevel@tonic-gate * Note: The flush cache should be done at most once in each location that is 25137c478bd9Sstevel@tonic-gate * required to be flushed no matter how many rules apply (i.e. only once 25147c478bd9Sstevel@tonic-gate * before the first descriptor block and/or only once before the last 25157c478bd9Sstevel@tonic-gate * descriptor block generated). If more than one place requires a flush, 25167c478bd9Sstevel@tonic-gate * then both flush operations must be performed. This is determined by 25177c478bd9Sstevel@tonic-gate * taking all rules that apply into account. 25187c478bd9Sstevel@tonic-gate * 25197c478bd9Sstevel@tonic-gate * Returns DDI_SUCCESS or DDI_FAILURE. If DDI_FAILURE, wvp->dma_bld_error 25207c478bd9Sstevel@tonic-gate * will contain the error code. 25217c478bd9Sstevel@tonic-gate */ 25227c478bd9Sstevel@tonic-gate static int 25237c478bd9Sstevel@tonic-gate hci1394_flush_hci_cache(hci1394_comp_ixl_vars_t *wvp) 25247c478bd9Sstevel@tonic-gate { 25257c478bd9Sstevel@tonic-gate uint32_t dma_bound; 25267c478bd9Sstevel@tonic-gate 25277c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_flush_hci_cache_enter, 25287c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 25297c478bd9Sstevel@tonic-gate 25307c478bd9Sstevel@tonic-gate if (hci1394_alloc_dma_mem(wvp, sizeof (hci1394_desc_t), &dma_bound) == 25317c478bd9Sstevel@tonic-gate NULL) { 25327c478bd9Sstevel@tonic-gate 25337c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL; 25347c478bd9Sstevel@tonic-gate 25357c478bd9Sstevel@tonic-gate TNF_PROBE_1(hci1394_flush_hci_cache_fail, 25367c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 25377c478bd9Sstevel@tonic-gate "IXL1394_EMEM_ALLOC_FAIL: for flush_hci_cache"); 25387c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_flush_hci_cache_exit, 25397c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 25407c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 25417c478bd9Sstevel@tonic-gate } 25427c478bd9Sstevel@tonic-gate 25437c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_flush_hci_cache_exit, 25447c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 25457c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 25467c478bd9Sstevel@tonic-gate } 25477c478bd9Sstevel@tonic-gate 25487c478bd9Sstevel@tonic-gate /* 25497c478bd9Sstevel@tonic-gate * hci1394_alloc_storevalue_dma_mem() 25507c478bd9Sstevel@tonic-gate * Allocate dma memory for a 1 hci component descriptor block 25517c478bd9Sstevel@tonic-gate * which will be used as the dma memory location that ixl 25527c478bd9Sstevel@tonic-gate * compiler generated storevalue descriptor commands will 25537c478bd9Sstevel@tonic-gate * specify as location to store their data value. 25547c478bd9Sstevel@tonic-gate * 25557c478bd9Sstevel@tonic-gate * Returns 32-bit bound address of allocated mem, or NULL. 25567c478bd9Sstevel@tonic-gate */ 25577c478bd9Sstevel@tonic-gate static uint32_t 25587c478bd9Sstevel@tonic-gate hci1394_alloc_storevalue_dma_mem(hci1394_comp_ixl_vars_t *wvp) 25597c478bd9Sstevel@tonic-gate { 25607c478bd9Sstevel@tonic-gate uint32_t dma_bound; 25617c478bd9Sstevel@tonic-gate 25627c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_storevalue_dma_mem_enter, 25637c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 25647c478bd9Sstevel@tonic-gate 25657c478bd9Sstevel@tonic-gate if (hci1394_alloc_dma_mem(wvp, sizeof (hci1394_desc_t), 25667c478bd9Sstevel@tonic-gate &dma_bound) == NULL) { 25677c478bd9Sstevel@tonic-gate 25687c478bd9Sstevel@tonic-gate wvp->dma_bld_error = IXL1394_EMEM_ALLOC_FAIL; 25697c478bd9Sstevel@tonic-gate 25707c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_bld_alloc_storevalue_dma_mem_alloc_fail, 25717c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_ERROR_ISOCH, "", tnf_string, errmsg, 25727c478bd9Sstevel@tonic-gate "IXL1394_EMEM_ALLOC_FAIL: for storevalue dma", 25737c478bd9Sstevel@tonic-gate tnf_opaque, ixl_commandp, wvp->ixl_cur_cmdp); 25747c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_storevalue_dma_mem_exit, 25757c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 2576*ffc2b7d4SToomas Soome return (0); 25777c478bd9Sstevel@tonic-gate } 25787c478bd9Sstevel@tonic-gate 25797c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_storevalue_dma_mem_exit, 25807c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 25817c478bd9Sstevel@tonic-gate 25827c478bd9Sstevel@tonic-gate /* return bound address of allocated memory */ 25837c478bd9Sstevel@tonic-gate return (dma_bound); 25847c478bd9Sstevel@tonic-gate } 25857c478bd9Sstevel@tonic-gate 25867c478bd9Sstevel@tonic-gate 25877c478bd9Sstevel@tonic-gate /* 25887c478bd9Sstevel@tonic-gate * hci1394_alloc_xfer_ctl() 25897c478bd9Sstevel@tonic-gate * Allocate an xfer_ctl structure. 25907c478bd9Sstevel@tonic-gate */ 25917c478bd9Sstevel@tonic-gate static hci1394_xfer_ctl_t * 25927c478bd9Sstevel@tonic-gate hci1394_alloc_xfer_ctl(hci1394_comp_ixl_vars_t *wvp, uint32_t dmacnt) 25937c478bd9Sstevel@tonic-gate { 25947c478bd9Sstevel@tonic-gate hci1394_xfer_ctl_t *xcsp; 25957c478bd9Sstevel@tonic-gate 25967c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_xfer_ctl_enter, 25977c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 25987c478bd9Sstevel@tonic-gate 25997c478bd9Sstevel@tonic-gate /* 26007c478bd9Sstevel@tonic-gate * allocate an xfer_ctl struct which includes dmacnt of 26017c478bd9Sstevel@tonic-gate * xfer_ctl_dma structs 26027c478bd9Sstevel@tonic-gate */ 26037c478bd9Sstevel@tonic-gate #ifdef _KERNEL 26047c478bd9Sstevel@tonic-gate if ((xcsp = (hci1394_xfer_ctl_t *)kmem_zalloc( 26057c478bd9Sstevel@tonic-gate (sizeof (hci1394_xfer_ctl_t) + (dmacnt - 1) * 26067c478bd9Sstevel@tonic-gate sizeof (hci1394_xfer_ctl_dma_t)), KM_NOSLEEP)) == NULL) { 26077c478bd9Sstevel@tonic-gate 26087c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_xfer_ctl_exit, 26097c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 26107c478bd9Sstevel@tonic-gate return (NULL); 26117c478bd9Sstevel@tonic-gate } 26127c478bd9Sstevel@tonic-gate #else 26137c478bd9Sstevel@tonic-gate /* 26147c478bd9Sstevel@tonic-gate * This section makes it possible to easily run and test the compiler in 26157c478bd9Sstevel@tonic-gate * user mode. 26167c478bd9Sstevel@tonic-gate */ 26177c478bd9Sstevel@tonic-gate if ((xcsp = (hci1394_xfer_ctl_t *)calloc(1, 26187c478bd9Sstevel@tonic-gate sizeof (hci1394_xfer_ctl_t) + (dmacnt - 1) * 26197c478bd9Sstevel@tonic-gate sizeof (hci1394_xfer_ctl_dma_t))) == NULL) { 26207c478bd9Sstevel@tonic-gate 26217c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_xfer_ctl_exit, 26227c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 26237c478bd9Sstevel@tonic-gate return (NULL); 26247c478bd9Sstevel@tonic-gate } 26257c478bd9Sstevel@tonic-gate #endif 26267c478bd9Sstevel@tonic-gate /* 26277c478bd9Sstevel@tonic-gate * set dma structure count into allocated xfer_ctl struct for 26287c478bd9Sstevel@tonic-gate * later deletion. 26297c478bd9Sstevel@tonic-gate */ 26307c478bd9Sstevel@tonic-gate xcsp->cnt = dmacnt; 26317c478bd9Sstevel@tonic-gate 26327c478bd9Sstevel@tonic-gate /* link it to previously allocated xfer_ctl structs or set as first */ 26337c478bd9Sstevel@tonic-gate if (wvp->xcs_firstp == NULL) { 26347c478bd9Sstevel@tonic-gate wvp->xcs_firstp = wvp->xcs_currentp = xcsp; 26357c478bd9Sstevel@tonic-gate } else { 26367c478bd9Sstevel@tonic-gate wvp->xcs_currentp->ctl_nextp = xcsp; 26377c478bd9Sstevel@tonic-gate wvp->xcs_currentp = xcsp; 26387c478bd9Sstevel@tonic-gate } 26397c478bd9Sstevel@tonic-gate 26407c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_xfer_ctl_exit, 26417c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 26427c478bd9Sstevel@tonic-gate 26437c478bd9Sstevel@tonic-gate /* return allocated xfer_ctl structure */ 26447c478bd9Sstevel@tonic-gate return (xcsp); 26457c478bd9Sstevel@tonic-gate } 26467c478bd9Sstevel@tonic-gate 26477c478bd9Sstevel@tonic-gate /* 26487c478bd9Sstevel@tonic-gate * hci1394_alloc_dma_mem() 26497c478bd9Sstevel@tonic-gate * Allocates and binds memory for openHCI DMA descriptors as needed. 26507c478bd9Sstevel@tonic-gate */ 26517c478bd9Sstevel@tonic-gate static void * 26527c478bd9Sstevel@tonic-gate hci1394_alloc_dma_mem(hci1394_comp_ixl_vars_t *wvp, uint32_t size, 26537c478bd9Sstevel@tonic-gate uint32_t *dma_bound) 26547c478bd9Sstevel@tonic-gate { 26557c478bd9Sstevel@tonic-gate hci1394_idma_desc_mem_t *dma_new; 26567c478bd9Sstevel@tonic-gate hci1394_buf_parms_t parms; 26577c478bd9Sstevel@tonic-gate hci1394_buf_info_t *memp; 26587c478bd9Sstevel@tonic-gate void *dma_mem_ret; 26597c478bd9Sstevel@tonic-gate int ret; 26607c478bd9Sstevel@tonic-gate 26617c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_enter, 26627c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 26637c478bd9Sstevel@tonic-gate 26647c478bd9Sstevel@tonic-gate /* 26657c478bd9Sstevel@tonic-gate * if no dma has been allocated or current request exceeds 26667c478bd9Sstevel@tonic-gate * remaining memory 26677c478bd9Sstevel@tonic-gate */ 26687c478bd9Sstevel@tonic-gate if ((wvp->dma_currentp == NULL) || 26697c478bd9Sstevel@tonic-gate (size > (wvp->dma_currentp->mem.bi_cookie.dmac_size - 2670*ffc2b7d4SToomas Soome wvp->dma_currentp->used))) { 26717c478bd9Sstevel@tonic-gate #ifdef _KERNEL 26727c478bd9Sstevel@tonic-gate /* kernel-mode memory allocation for driver */ 26737c478bd9Sstevel@tonic-gate 26747c478bd9Sstevel@tonic-gate /* allocate struct to track more dma descriptor memory */ 26757c478bd9Sstevel@tonic-gate if ((dma_new = (hci1394_idma_desc_mem_t *) 26767c478bd9Sstevel@tonic-gate kmem_zalloc(sizeof (hci1394_idma_desc_mem_t), 26777c478bd9Sstevel@tonic-gate KM_NOSLEEP)) == NULL) { 26787c478bd9Sstevel@tonic-gate 26797c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit, 26807c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 26817c478bd9Sstevel@tonic-gate return (NULL); 26827c478bd9Sstevel@tonic-gate } 26837c478bd9Sstevel@tonic-gate 26847c478bd9Sstevel@tonic-gate /* 26857c478bd9Sstevel@tonic-gate * if more cookies available from the current mem, try to find 26867c478bd9Sstevel@tonic-gate * one of suitable size. Cookies that are too small will be 26877c478bd9Sstevel@tonic-gate * skipped and unused. Given that cookie size is always at least 26887c478bd9Sstevel@tonic-gate * 1 page long and HCI1394_DESC_MAX_Z is much smaller than that, 26897c478bd9Sstevel@tonic-gate * it's a small price to pay for code simplicity. 26907c478bd9Sstevel@tonic-gate */ 26917c478bd9Sstevel@tonic-gate if (wvp->dma_currentp != NULL) { 26927c478bd9Sstevel@tonic-gate /* new struct is derived from current */ 26937c478bd9Sstevel@tonic-gate memp = &wvp->dma_currentp->mem; 26947c478bd9Sstevel@tonic-gate dma_new->mem = *memp; 26957c478bd9Sstevel@tonic-gate dma_new->offset = wvp->dma_currentp->offset + 26967c478bd9Sstevel@tonic-gate memp->bi_cookie.dmac_size; 26977c478bd9Sstevel@tonic-gate 26987c478bd9Sstevel@tonic-gate for (; memp->bi_cookie_count > 1; 26997c478bd9Sstevel@tonic-gate memp->bi_cookie_count--) { 27007c478bd9Sstevel@tonic-gate ddi_dma_nextcookie(memp->bi_dma_handle, 27017c478bd9Sstevel@tonic-gate &dma_new->mem.bi_cookie); 27027c478bd9Sstevel@tonic-gate 27037c478bd9Sstevel@tonic-gate if (dma_new->mem.bi_cookie.dmac_size >= size) { 27047c478bd9Sstevel@tonic-gate dma_new->mem_handle = 27057c478bd9Sstevel@tonic-gate wvp->dma_currentp->mem_handle; 27067c478bd9Sstevel@tonic-gate wvp->dma_currentp->mem_handle = NULL; 27077c478bd9Sstevel@tonic-gate dma_new->mem.bi_cookie_count--; 27087c478bd9Sstevel@tonic-gate break; 27097c478bd9Sstevel@tonic-gate } 27107c478bd9Sstevel@tonic-gate dma_new->offset += 27117c478bd9Sstevel@tonic-gate dma_new->mem.bi_cookie.dmac_size; 27127c478bd9Sstevel@tonic-gate } 27137c478bd9Sstevel@tonic-gate } 27147c478bd9Sstevel@tonic-gate 27157c478bd9Sstevel@tonic-gate /* if no luck with current buffer, allocate a new one */ 27167c478bd9Sstevel@tonic-gate if (dma_new->mem_handle == NULL) { 27177c478bd9Sstevel@tonic-gate parms.bp_length = HCI1394_IXL_PAGESIZE; 27187c478bd9Sstevel@tonic-gate parms.bp_max_cookies = OHCI_MAX_COOKIE; 27197c478bd9Sstevel@tonic-gate parms.bp_alignment = 16; 27207c478bd9Sstevel@tonic-gate ret = hci1394_buf_alloc(&wvp->soft_statep->drvinfo, 27217c478bd9Sstevel@tonic-gate &parms, &dma_new->mem, &dma_new->mem_handle); 27227c478bd9Sstevel@tonic-gate if (ret != DDI_SUCCESS) { 27237c478bd9Sstevel@tonic-gate kmem_free(dma_new, 27247c478bd9Sstevel@tonic-gate sizeof (hci1394_idma_desc_mem_t)); 27257c478bd9Sstevel@tonic-gate 27267c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit, 27277c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 27287c478bd9Sstevel@tonic-gate return (NULL); 27297c478bd9Sstevel@tonic-gate } 27307c478bd9Sstevel@tonic-gate 27317c478bd9Sstevel@tonic-gate /* paranoia: this is not supposed to happen */ 27327c478bd9Sstevel@tonic-gate if (dma_new->mem.bi_cookie.dmac_size < size) { 27337c478bd9Sstevel@tonic-gate hci1394_buf_free(&dma_new->mem_handle); 27347c478bd9Sstevel@tonic-gate kmem_free(dma_new, 27357c478bd9Sstevel@tonic-gate sizeof (hci1394_idma_desc_mem_t)); 27367c478bd9Sstevel@tonic-gate 27377c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit, 27387c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 27397c478bd9Sstevel@tonic-gate return (NULL); 27407c478bd9Sstevel@tonic-gate } 27417c478bd9Sstevel@tonic-gate dma_new->offset = 0; 27427c478bd9Sstevel@tonic-gate } 27437c478bd9Sstevel@tonic-gate #else 27447c478bd9Sstevel@tonic-gate /* user-mode memory allocation for user mode compiler tests */ 27457c478bd9Sstevel@tonic-gate /* allocate another dma_desc_mem struct */ 27467c478bd9Sstevel@tonic-gate if ((dma_new = (hci1394_idma_desc_mem_t *) 2747*ffc2b7d4SToomas Soome calloc(1, sizeof (hci1394_idma_desc_mem_t))) == NULL) { 27487c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit, 27497c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 27507c478bd9Sstevel@tonic-gate return (NULL); 27517c478bd9Sstevel@tonic-gate } 27527c478bd9Sstevel@tonic-gate dma_new->mem.bi_dma_handle = NULL; 27537c478bd9Sstevel@tonic-gate dma_new->mem.bi_handle = NULL; 27547c478bd9Sstevel@tonic-gate if ((dma_new->mem.bi_kaddr = (caddr_t)calloc(1, 2755*ffc2b7d4SToomas Soome HCI1394_IXL_PAGESIZE)) == NULL) { 27567c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit, 27577c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 27587c478bd9Sstevel@tonic-gate return (NULL); 27597c478bd9Sstevel@tonic-gate } 27607c478bd9Sstevel@tonic-gate dma_new->mem.bi_cookie.dmac_address = 27617c478bd9Sstevel@tonic-gate (unsigned long)dma_new->mem.bi_kaddr; 27627c478bd9Sstevel@tonic-gate dma_new->mem.bi_real_length = HCI1394_IXL_PAGESIZE; 27637c478bd9Sstevel@tonic-gate dma_new->mem.bi_cookie_count = 1; 27647c478bd9Sstevel@tonic-gate #endif 27657c478bd9Sstevel@tonic-gate 27667c478bd9Sstevel@tonic-gate /* if this is not first dma_desc_mem, link last one to it */ 27677c478bd9Sstevel@tonic-gate if (wvp->dma_currentp != NULL) { 27687c478bd9Sstevel@tonic-gate wvp->dma_currentp->dma_nextp = dma_new; 27697c478bd9Sstevel@tonic-gate wvp->dma_currentp = dma_new; 27707c478bd9Sstevel@tonic-gate } else { 27717c478bd9Sstevel@tonic-gate /* else set it as first one */ 27727c478bd9Sstevel@tonic-gate wvp->dma_currentp = wvp->dma_firstp = dma_new; 27737c478bd9Sstevel@tonic-gate } 27747c478bd9Sstevel@tonic-gate } 27757c478bd9Sstevel@tonic-gate 27767c478bd9Sstevel@tonic-gate /* now allocate requested memory from current block */ 27777c478bd9Sstevel@tonic-gate dma_mem_ret = wvp->dma_currentp->mem.bi_kaddr + 27787c478bd9Sstevel@tonic-gate wvp->dma_currentp->offset + wvp->dma_currentp->used; 27797c478bd9Sstevel@tonic-gate *dma_bound = wvp->dma_currentp->mem.bi_cookie.dmac_address + 27807c478bd9Sstevel@tonic-gate wvp->dma_currentp->used; 27817c478bd9Sstevel@tonic-gate wvp->dma_currentp->used += size; 27827c478bd9Sstevel@tonic-gate 27837c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_alloc_dma_mem_exit, 27847c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 27857c478bd9Sstevel@tonic-gate return (dma_mem_ret); 27867c478bd9Sstevel@tonic-gate } 27877c478bd9Sstevel@tonic-gate 27887c478bd9Sstevel@tonic-gate 27897c478bd9Sstevel@tonic-gate /* 27907c478bd9Sstevel@tonic-gate * hci1394_is_opcode_valid() 27917c478bd9Sstevel@tonic-gate * given an ixl opcode, this routine returns B_TRUE if it is a 27927c478bd9Sstevel@tonic-gate * recognized opcode and B_FALSE if it is not recognized. 27937c478bd9Sstevel@tonic-gate * Note that the FULL 16 bits of the opcode are checked which includes 27947c478bd9Sstevel@tonic-gate * various flags and not just the low order 8 bits of unique code. 27957c478bd9Sstevel@tonic-gate */ 27967c478bd9Sstevel@tonic-gate static boolean_t 27977c478bd9Sstevel@tonic-gate hci1394_is_opcode_valid(uint16_t ixlopcode) 27987c478bd9Sstevel@tonic-gate { 27997c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_is_opcode_bad_enter, 28007c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 28017c478bd9Sstevel@tonic-gate 28027c478bd9Sstevel@tonic-gate /* if it's not one we know about, then it's bad */ 28037c478bd9Sstevel@tonic-gate switch (ixlopcode) { 28047c478bd9Sstevel@tonic-gate case IXL1394_OP_LABEL: 28057c478bd9Sstevel@tonic-gate case IXL1394_OP_JUMP: 28067c478bd9Sstevel@tonic-gate case IXL1394_OP_CALLBACK: 28077c478bd9Sstevel@tonic-gate case IXL1394_OP_RECV_PKT: 28087c478bd9Sstevel@tonic-gate case IXL1394_OP_RECV_PKT_ST: 28097c478bd9Sstevel@tonic-gate case IXL1394_OP_RECV_BUF: 28107c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_PKT: 28117c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_PKT_ST: 28127c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_PKT_WHDR_ST: 28137c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_BUF: 28147c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_HDR_ONLY: 28157c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_NO_PKT: 28167c478bd9Sstevel@tonic-gate case IXL1394_OP_STORE_TIMESTAMP: 28177c478bd9Sstevel@tonic-gate case IXL1394_OP_SET_TAGSYNC: 28187c478bd9Sstevel@tonic-gate case IXL1394_OP_SET_SKIPMODE: 28197c478bd9Sstevel@tonic-gate case IXL1394_OP_SET_SYNCWAIT: 28207c478bd9Sstevel@tonic-gate case IXL1394_OP_JUMP_U: 28217c478bd9Sstevel@tonic-gate case IXL1394_OP_CALLBACK_U: 28227c478bd9Sstevel@tonic-gate case IXL1394_OP_RECV_PKT_U: 28237c478bd9Sstevel@tonic-gate case IXL1394_OP_RECV_PKT_ST_U: 28247c478bd9Sstevel@tonic-gate case IXL1394_OP_RECV_BUF_U: 28257c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_PKT_U: 28267c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_PKT_ST_U: 28277c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_PKT_WHDR_ST_U: 28287c478bd9Sstevel@tonic-gate case IXL1394_OP_SEND_BUF_U: 28297c478bd9Sstevel@tonic-gate case IXL1394_OP_SET_TAGSYNC_U: 28307c478bd9Sstevel@tonic-gate case IXL1394_OP_SET_SKIPMODE_U: 28317c478bd9Sstevel@tonic-gate TNF_PROBE_1_DEBUG(hci1394_is_opcode_valid_enter, 28327c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, msg, 28337c478bd9Sstevel@tonic-gate "ixl opcode is valid"); 28347c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_is_opcode_bad_enter, 28357c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 28367c478bd9Sstevel@tonic-gate return (B_TRUE); 28377c478bd9Sstevel@tonic-gate default: 28387c478bd9Sstevel@tonic-gate TNF_PROBE_2(hci1394_is_opcode_valid_enter, 28397c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, "", tnf_string, msg, 28407c478bd9Sstevel@tonic-gate "ixl opcode is NOT valid", tnf_opaque, ixl_opcode, 28417c478bd9Sstevel@tonic-gate ixlopcode); 28427c478bd9Sstevel@tonic-gate TNF_PROBE_0_DEBUG(hci1394_is_opcode_valid_enter, 28437c478bd9Sstevel@tonic-gate HCI1394_TNF_HAL_STACK_ISOCH, ""); 28447c478bd9Sstevel@tonic-gate return (B_FALSE); 28457c478bd9Sstevel@tonic-gate } 28467c478bd9Sstevel@tonic-gate } 2847