10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 52125Ssl147100 * Common Development and Distribution License (the "License"). 62125Ssl147100 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 225773Sqz150045 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #ifndef _SYS_USB_UHCID_H 270Sstevel@tonic-gate #define _SYS_USB_UHCID_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate 300Sstevel@tonic-gate #ifdef __cplusplus 310Sstevel@tonic-gate extern "C" { 320Sstevel@tonic-gate #endif 330Sstevel@tonic-gate 340Sstevel@tonic-gate /* 350Sstevel@tonic-gate * Universal Host Controller Driver (UHCI) 360Sstevel@tonic-gate * 370Sstevel@tonic-gate * The UHCI driver is a driver which interfaces to the Universal 380Sstevel@tonic-gate * Serial Bus Driver (USBA) and the Host Controller (HC). The interface to 390Sstevel@tonic-gate * the Host Controller is defined by the Universal Host Controller Interface. 400Sstevel@tonic-gate * 410Sstevel@tonic-gate * This file contains the data structures for the UHCI driver. 420Sstevel@tonic-gate */ 430Sstevel@tonic-gate #include <sys/types.h> 440Sstevel@tonic-gate #include <sys/pci.h> 450Sstevel@tonic-gate #include <sys/kstat.h> 460Sstevel@tonic-gate 470Sstevel@tonic-gate #include <sys/usb/usba/usbai_version.h> 480Sstevel@tonic-gate #include <sys/usb/usba.h> 490Sstevel@tonic-gate #include <sys/usb/usba/usba_types.h> 500Sstevel@tonic-gate 510Sstevel@tonic-gate #include <sys/usb/usba/genconsole.h> 520Sstevel@tonic-gate #include <sys/usb/usba/hcdi.h> 530Sstevel@tonic-gate 540Sstevel@tonic-gate #include <sys/usb/hubd/hub.h> 550Sstevel@tonic-gate #include <sys/usb/usba/hubdi.h> 560Sstevel@tonic-gate #include <sys/usb/hubd/hubdvar.h> 570Sstevel@tonic-gate 580Sstevel@tonic-gate #include <sys/usb/hcd/uhci/uhci.h> 590Sstevel@tonic-gate 600Sstevel@tonic-gate /* limit the xfer size for bulk */ 610Sstevel@tonic-gate #define UHCI_BULK_MAX_XFER_SIZE (124*1024) /* Max bulk xfer size */ 620Sstevel@tonic-gate 630Sstevel@tonic-gate /* Maximum allowable data transfer size per transaction */ 642125Ssl147100 #define UHCI_MAX_TD_XFER_SIZE 0x500 /* Maximum data per transaction */ 650Sstevel@tonic-gate 660Sstevel@tonic-gate /* 670Sstevel@tonic-gate * Generic UHCI Macro definitions 680Sstevel@tonic-gate */ 690Sstevel@tonic-gate #define UHCI_UNDERRUN_OCCURRED 0x1234 700Sstevel@tonic-gate #define UHCI_OVERRUN_OCCURRED 0x5678 710Sstevel@tonic-gate #define UHCI_PROP_MASK 0x01000020 720Sstevel@tonic-gate #define UHCI_RESET_DELAY 15000 730Sstevel@tonic-gate #define UHCI_TIMEWAIT 10000 740Sstevel@tonic-gate 750Sstevel@tonic-gate #define MAX_SOF_WAIT_COUNT 2 760Sstevel@tonic-gate #define MAX_RH_PORTS 2 770Sstevel@tonic-gate #define DISCONNECTED 2 780Sstevel@tonic-gate #define POLLING_FREQ_7MS 7 790Sstevel@tonic-gate #define PCI_CONF_IOBASE 0x20 800Sstevel@tonic-gate #define PCI_CONF_IOBASE_MASK 0xffe0 810Sstevel@tonic-gate 820Sstevel@tonic-gate #define UHCI_ONE_SECOND drv_usectohz(1000000) 830Sstevel@tonic-gate #define UHCI_ONE_MS drv_usectohz(1000) 840Sstevel@tonic-gate #define UHCI_32_MS drv_usectohz(32*1000) 85*7138Szl227052 #define UHCI_256_MS drv_usectohz(256*1000) 860Sstevel@tonic-gate #define UHCI_MAX_INSTS 4 870Sstevel@tonic-gate 880Sstevel@tonic-gate #define POLLED_RAW_BUF_SIZE 8 890Sstevel@tonic-gate 900Sstevel@tonic-gate /* Default time out values for bulk and ctrl commands */ 910Sstevel@tonic-gate #define UHCI_CTRL_TIMEOUT 5 920Sstevel@tonic-gate #define UHCI_BULK_TIMEOUT 60 930Sstevel@tonic-gate 940Sstevel@tonic-gate /* UHCI root hub structure */ 950Sstevel@tonic-gate typedef struct uhci_root_hub_info { 960Sstevel@tonic-gate uint_t rh_status; /* Last RH status */ 970Sstevel@tonic-gate uint_t rh_num_ports; /* #ports on the root */ 980Sstevel@tonic-gate 990Sstevel@tonic-gate /* Last status of ports */ 1000Sstevel@tonic-gate uint_t rh_port_status[MAX_RH_PORTS]; 1010Sstevel@tonic-gate uint_t rh_port_changes[MAX_RH_PORTS]; 1020Sstevel@tonic-gate uint_t rh_port_state[MAX_RH_PORTS]; /* See below */ 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate usba_pipe_handle_data_t *rh_intr_pipe_handle; /* RH intr pipe hndle */ 1050Sstevel@tonic-gate usb_hub_descr_t rh_descr; /* RH descr's copy */ 1060Sstevel@tonic-gate uint_t rh_pipe_state; /* RH intr pipe state */ 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate usb_intr_req_t *rh_curr_intr_reqp; /* Current intr req */ 1090Sstevel@tonic-gate usb_intr_req_t *rh_client_intr_req; /* save IN request */ 1100Sstevel@tonic-gate } uhci_root_hub_info_t; 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate /* 1130Sstevel@tonic-gate * UHCI Host Controller per instance data structure 1140Sstevel@tonic-gate * 1150Sstevel@tonic-gate * The Host Controller Driver (HCD) maintains the state of Host Controller 1160Sstevel@tonic-gate * (HC). There is an uhci_state structure per instance of the UHCI 1170Sstevel@tonic-gate * host controller. 1180Sstevel@tonic-gate */ 1190Sstevel@tonic-gate typedef struct uhci_state { 1200Sstevel@tonic-gate dev_info_t *uhci_dip; /* dip of HC */ 1210Sstevel@tonic-gate uint_t uhci_instance; 1220Sstevel@tonic-gate usba_hcdi_ops_t *uhci_hcdi_ops; /* HCDI structure */ 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate uint_t uhci_dma_addr_bind_flag; 1250Sstevel@tonic-gate 1265773Sqz150045 /* UHCI Host Controller Software State information */ 1275773Sqz150045 uint_t uhci_hc_soft_state; 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate hc_regs_t *uhci_regsp; /* Host ctlr regs */ 1300Sstevel@tonic-gate ddi_acc_handle_t uhci_regs_handle; /* Reg handle */ 1310Sstevel@tonic-gate 1320Sstevel@tonic-gate ddi_acc_handle_t uhci_config_handle; /* Config space hndle */ 1330Sstevel@tonic-gate 1340Sstevel@tonic-gate /* Frame interval reg */ 1350Sstevel@tonic-gate uint_t uhci_frame_interval; 1360Sstevel@tonic-gate ddi_dma_attr_t uhci_dma_attr; /* DMA attributes */ 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate ddi_intr_handle_t *uhci_htable; /* intr handle */ 139965Sgovinda int uhci_intr_type; /* intr type used */ 140965Sgovinda int uhci_intr_cnt; /* # of intrs inuse */ 141965Sgovinda uint_t uhci_intr_pri; /* intr priority */ 142965Sgovinda int uhci_intr_cap; /* intr capabilities */ 1430Sstevel@tonic-gate kmutex_t uhci_int_mutex; /* Mutex for struct */ 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate frame_lst_table_t *uhci_frame_lst_tablep; /* Virtual HCCA ptr */ 1460Sstevel@tonic-gate uhci_td_t *uhci_isoc_q_tailp[NUM_FRAME_LST_ENTRIES]; 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate ddi_dma_cookie_t uhci_flt_cookie; /* DMA cookie */ 1490Sstevel@tonic-gate ddi_dma_handle_t uhci_flt_dma_handle; /* DMA handle */ 1500Sstevel@tonic-gate ddi_acc_handle_t uhci_flt_mem_handle; /* Memory handle */ 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate /* 1530Sstevel@tonic-gate * There are two pools of memory. One pool contains the memory for 1540Sstevel@tonic-gate * the transfer descriptors and other pool contains the memory for 1550Sstevel@tonic-gate * the Queue Head pointers. The advantage of the pools is that it's 1560Sstevel@tonic-gate * easy to go back and forth between the iommu and the cpu addresses. 1570Sstevel@tonic-gate * 1580Sstevel@tonic-gate * The pools are protected by the int_mutex because the memory 1590Sstevel@tonic-gate * in the pools may be accessed by either the host controller or the 1600Sstevel@tonic-gate * host controller driver. 1610Sstevel@tonic-gate */ 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate /* General transfer descriptor pool */ 1640Sstevel@tonic-gate uhci_td_t *uhci_td_pool_addr; /* Start of the pool */ 1650Sstevel@tonic-gate ddi_dma_cookie_t uhci_td_pool_cookie; /* DMA cookie */ 1660Sstevel@tonic-gate ddi_dma_handle_t uhci_td_pool_dma_handle; /* DMA hndle */ 1670Sstevel@tonic-gate ddi_acc_handle_t uhci_td_pool_mem_handle; /* Mem hndle */ 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate /* Endpoint descriptor pool */ 1700Sstevel@tonic-gate queue_head_t *uhci_qh_pool_addr; /* Start of the pool */ 1710Sstevel@tonic-gate ddi_dma_cookie_t uhci_qh_pool_cookie; /* DMA cookie */ 1720Sstevel@tonic-gate ddi_dma_handle_t uhci_qh_pool_dma_handle; /* DMA handle */ 1730Sstevel@tonic-gate ddi_acc_handle_t uhci_qh_pool_mem_handle; /* Mem handle */ 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate /* Semaphore to serialize opens and closes */ 1760Sstevel@tonic-gate ksema_t uhci_ocsem; 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate /* Timeout id of the root hub status change pipe handler */ 1790Sstevel@tonic-gate timeout_id_t uhci_timeout_id; 1800Sstevel@tonic-gate 1810Sstevel@tonic-gate /* Timeout id of the ctrl/bulk/intr xfers timeout */ 1820Sstevel@tonic-gate timeout_id_t uhci_cmd_timeout_id; 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate /* 1850Sstevel@tonic-gate * Bandwidth fields 1860Sstevel@tonic-gate * 1870Sstevel@tonic-gate * The uhci_bandwidth array keeps track of the allocated bandwidth 1880Sstevel@tonic-gate * for this host controller. The uhci_bandwidth_isoch_sum field 1890Sstevel@tonic-gate * represents the sum of the allocated isochronous bandwidth. The 1900Sstevel@tonic-gate * total bandwidth allocated for least allocated list out of the 32 1910Sstevel@tonic-gate * interrupt lists is represented by the uhci_bandwdith_intr_min 1920Sstevel@tonic-gate * field. 1930Sstevel@tonic-gate */ 1940Sstevel@tonic-gate uint_t uhci_bandwidth[NUM_FRAME_LST_ENTRIES]; 1950Sstevel@tonic-gate uint_t uhci_bandwidth_isoch_sum; 1960Sstevel@tonic-gate uint_t uhci_bandwidth_intr_min; 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate uhci_root_hub_info_t uhci_root_hub; /* Root hub info */ 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate uhci_td_t *uhci_outst_tds_head; 2010Sstevel@tonic-gate uhci_td_t *uhci_outst_tds_tail; 2020Sstevel@tonic-gate 2030Sstevel@tonic-gate queue_head_t *uhci_ctrl_xfers_q_head; 2040Sstevel@tonic-gate queue_head_t *uhci_ctrl_xfers_q_tail; 2050Sstevel@tonic-gate queue_head_t *uhci_bulk_xfers_q_head; 2060Sstevel@tonic-gate queue_head_t *uhci_bulk_xfers_q_tail; 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate kcondvar_t uhci_cv_SOF; 2090Sstevel@tonic-gate uchar_t uhci_cv_signal; 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate /* Polled I/O support */ 2120Sstevel@tonic-gate frame_lst_table_t uhci_polled_save_IntTble[1024]; 2130Sstevel@tonic-gate uint_t uhci_polled_count; 2140Sstevel@tonic-gate uint32_t uhci_polled_flag; 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate /* Software frame number */ 2170Sstevel@tonic-gate usb_frame_number_t uhci_sw_frnum; 2180Sstevel@tonic-gate 2190Sstevel@tonic-gate /* Number of pending bulk commands */ 2200Sstevel@tonic-gate uint32_t uhci_pending_bulk_cmds; 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate /* logging support */ 2230Sstevel@tonic-gate usb_log_handle_t uhci_log_hdl; 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate /* 2260Sstevel@tonic-gate * TD's used for the generation of interrupt 2270Sstevel@tonic-gate */ 2280Sstevel@tonic-gate queue_head_t *uhci_isoc_qh; 2290Sstevel@tonic-gate uhci_td_t *uhci_sof_td; 2300Sstevel@tonic-gate uhci_td_t *uhci_isoc_td; 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate /* 2330Sstevel@tonic-gate * Keep io base address, for debugging purpose 2340Sstevel@tonic-gate */ 2350Sstevel@tonic-gate uint_t uhci_iobase; 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate /* 2380Sstevel@tonic-gate * kstat structures 2390Sstevel@tonic-gate */ 2400Sstevel@tonic-gate kstat_t *uhci_intrs_stats; 2410Sstevel@tonic-gate kstat_t *uhci_total_stats; 2420Sstevel@tonic-gate kstat_t *uhci_count_stats[USB_N_COUNT_KSTATS]; 2430Sstevel@tonic-gate } uhci_state_t; 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate 2460Sstevel@tonic-gate /* 2470Sstevel@tonic-gate * uhci_dma_addr_bind_flag values 2480Sstevel@tonic-gate * 2490Sstevel@tonic-gate * This flag indicates if the various DMA addresses allocated by the UHCI 2500Sstevel@tonic-gate * have been bound to their respective handles. This is needed to recover 2510Sstevel@tonic-gate * without errors from uhci_cleanup when it calls ddi_dma_unbind_handle() 2520Sstevel@tonic-gate */ 2530Sstevel@tonic-gate #define UHCI_TD_POOL_BOUND 0x01 /* for TD pools */ 2540Sstevel@tonic-gate #define UHCI_QH_POOL_BOUND 0x02 /* for QH pools */ 2550Sstevel@tonic-gate #define UHCI_FLA_POOL_BOUND 0x04 /* for Host Ctrlr Framelist Area */ 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate /* 2580Sstevel@tonic-gate * Definitions for uhci_polled_flag 2590Sstevel@tonic-gate * The flag is set to UHCI_POLLED_FLAG_FALSE by default. The flags is 2600Sstevel@tonic-gate * set to UHCI_POLLED_FLAG_TD_COMPL when shifting from normal mode to 2610Sstevel@tonic-gate * polled mode and if the normal TD is completed at that time. And the 2620Sstevel@tonic-gate * flag is set to UHCI_POLLED_FLAG_TRUE while exiting from the polled 2630Sstevel@tonic-gate * mode. In the timeout handler for root hub status change, this flag 2640Sstevel@tonic-gate * is checked. If set to UHCI_POLLED_FLAG_TRUE, the routine 2650Sstevel@tonic-gate * uhci_process_submitted_td_queue() to process the completed TD. 2660Sstevel@tonic-gate */ 2670Sstevel@tonic-gate #define UHCI_POLLED_FLAG_FALSE 0 2680Sstevel@tonic-gate #define UHCI_POLLED_FLAG_TRUE 1 2690Sstevel@tonic-gate #define UHCI_POLLED_FLAG_TD_COMPL 2 2700Sstevel@tonic-gate 2710Sstevel@tonic-gate /* 2720Sstevel@tonic-gate * Pipe private structure 2730Sstevel@tonic-gate * 2740Sstevel@tonic-gate * There is an instance of this structure per pipe. This structure holds 2750Sstevel@tonic-gate * HCD specific pipe information. A pointer to this structure is kept in 2760Sstevel@tonic-gate * the USBA pipe handle (usba_pipe_handle_data_t). 2770Sstevel@tonic-gate */ 2780Sstevel@tonic-gate typedef struct uhci_pipe_private { 2790Sstevel@tonic-gate usba_pipe_handle_data_t *pp_pipe_handle; /* Back ptr to pipe handle */ 2800Sstevel@tonic-gate queue_head_t *pp_qh; /* Pipe's ept */ 2810Sstevel@tonic-gate uint_t pp_state; /* See below */ 2820Sstevel@tonic-gate usb_pipe_policy_t pp_policy; /* Copy of the pipe policy */ 2830Sstevel@tonic-gate uint_t pp_node; /* Node in lattice */ 2840Sstevel@tonic-gate uchar_t pp_data_toggle; /* save data toggle bit */ 2850Sstevel@tonic-gate 2860Sstevel@tonic-gate /* 2870Sstevel@tonic-gate * Each pipe may have multiple transfer wrappers. Each transfer 2880Sstevel@tonic-gate * wrapper represents a USB transfer on the bus. A transfer is 2890Sstevel@tonic-gate * made up of one or more transactions. 2900Sstevel@tonic-gate */ 2910Sstevel@tonic-gate struct uhci_trans_wrapper *pp_tw_head; /* Head of the list */ 2920Sstevel@tonic-gate struct uhci_trans_wrapper *pp_tw_tail; /* Tail of the list */ 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate /* 2950Sstevel@tonic-gate * Starting frame number at which next isoc TD will be inserted 2960Sstevel@tonic-gate * for this pipe 2970Sstevel@tonic-gate */ 2980Sstevel@tonic-gate uint64_t pp_frame_num; 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate /* 3010Sstevel@tonic-gate * HCD gets Interrupt/Isochronous IN polling request only once and 3020Sstevel@tonic-gate * it has to insert next polling requests after completion of first 3030Sstevel@tonic-gate * request until either stop polling/pipe close is called. So HCD 3040Sstevel@tonic-gate * has to take copy of the original Interrupt/Isochronous IN request. 3050Sstevel@tonic-gate */ 3060Sstevel@tonic-gate usb_opaque_t pp_client_periodic_in_reqp; 3070Sstevel@tonic-gate } uhci_pipe_private_t; 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate /* warlock directives, stable data */ 3100Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(uhci_state_t::uhci_int_mutex, uhci_pipe_private_t)) 3110Sstevel@tonic-gate _NOTE(LOCK_ORDER(uhci_state::uhci_int_mutex \ 3120Sstevel@tonic-gate usba_pipe_handle_data::p_mutex \ 3130Sstevel@tonic-gate usba_device::usb_mutex \ 3140Sstevel@tonic-gate usba_ph_impl::usba_ph_mutex)) 3150Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("private mutex", kstat_io)) 3160Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("unshared", usb_isoc_pkt_descr)) 3170Sstevel@tonic-gate 3180Sstevel@tonic-gate /* 3190Sstevel@tonic-gate * Pipe states 3200Sstevel@tonic-gate * 3210Sstevel@tonic-gate * uhci pipe states will be similar to usba. Refer usbai.h. 3220Sstevel@tonic-gate */ 3230Sstevel@tonic-gate #define UHCI_PIPE_STATE_IDLE 1 /* Pipe has opened,ready state */ 3240Sstevel@tonic-gate #define UHCI_PIPE_STATE_ACTIVE 2 /* Polling the endpoint,busy state */ 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate /* 3270Sstevel@tonic-gate * to indicate if we are in close/reset so that we can issue callbacks to 3280Sstevel@tonic-gate * IN packets that are pending 3290Sstevel@tonic-gate */ 3300Sstevel@tonic-gate #define UHCI_IN_CLOSE 4 3310Sstevel@tonic-gate #define UHCI_IN_RESET 5 3320Sstevel@tonic-gate #define UHCI_IN_ERROR 6 3330Sstevel@tonic-gate 3340Sstevel@tonic-gate /* Function prototype */ 3350Sstevel@tonic-gate typedef void (*uhci_handler_function_t) (uhci_state_t *uhcip, uhci_td_t *td); 3360Sstevel@tonic-gate 3370Sstevel@tonic-gate /* 3380Sstevel@tonic-gate * Transfer wrapper 3390Sstevel@tonic-gate * 3400Sstevel@tonic-gate * The transfer wrapper represents a USB transfer on the bus and there 3410Sstevel@tonic-gate * is one instance per USB transfer. A transfer is made up of one or 3422125Ssl147100 * more transactions. UHCI uses one TD for one transaction. So one 3432125Ssl147100 * transfer wrapper may have one or more TDs associated. 3440Sstevel@tonic-gate * 3450Sstevel@tonic-gate * Control and bulk pipes will have one transfer wrapper per transfer 3460Sstevel@tonic-gate * and where as Isochronous and Interrupt pipes will only have one 3470Sstevel@tonic-gate * transfer wrapper. The transfers wrapper are continually reused for 3480Sstevel@tonic-gate * the Interrupt and Isochronous pipes as those pipes are polled. 3492125Ssl147100 * 3502125Ssl147100 * Control, bulk and interrupt transfers will have one DMA buffer per 3512125Ssl147100 * transfer. The data to be transferred are contained in the DMA buffer 3522125Ssl147100 * which is virtually contiguous but physically discontiguous. When 3532125Ssl147100 * preparing the TDs for a USB transfer, the DMA cookies contained in 3542125Ssl147100 * the buffer need to be walked through to retrieve the DMA addresses. 3552125Ssl147100 * 3562125Ssl147100 * Isochronous transfers will have multiple DMA buffers per transfer 3572125Ssl147100 * with each isoc packet having a DMA buffer. And the DMA buffers should 3582125Ssl147100 * only contain one cookie each, so no cookie walking is necessary. 3590Sstevel@tonic-gate */ 3600Sstevel@tonic-gate typedef struct uhci_trans_wrapper { 3610Sstevel@tonic-gate struct uhci_trans_wrapper *tw_next; /* Next wrapper */ 3620Sstevel@tonic-gate uhci_pipe_private_t *tw_pipe_private; 3630Sstevel@tonic-gate size_t tw_length; /* Txfer length */ 3640Sstevel@tonic-gate uint_t tw_tmp; /* Temp variable */ 3650Sstevel@tonic-gate ddi_dma_handle_t tw_dmahandle; /* DMA handle */ 3660Sstevel@tonic-gate ddi_acc_handle_t tw_accesshandle; /* Acc hndle */ 3670Sstevel@tonic-gate char *tw_buf; /* Buffer for txfer */ 3680Sstevel@tonic-gate ddi_dma_cookie_t tw_cookie; /* DMA cookie */ 3692125Ssl147100 uint_t tw_ncookies; /* DMA cookie count */ 3702125Ssl147100 uint_t tw_cookie_idx; /* DMA cookie index */ 3712125Ssl147100 size_t tw_dma_offs; /* DMA buffer offset */ 3720Sstevel@tonic-gate int tw_ctrl_state; /* See below */ 3730Sstevel@tonic-gate uhci_td_t *tw_hctd_head; /* Head TD */ 3740Sstevel@tonic-gate uhci_td_t *tw_hctd_tail; /* Tail TD */ 3750Sstevel@tonic-gate uint_t tw_direction; /* Direction of TD */ 3760Sstevel@tonic-gate usb_flags_t tw_flags; /* Flags */ 3770Sstevel@tonic-gate 3780Sstevel@tonic-gate /* 3790Sstevel@tonic-gate * This is the function to call when this td is done. This way 3800Sstevel@tonic-gate * we don't have to look in the td to figure out what kind it is. 3810Sstevel@tonic-gate */ 3820Sstevel@tonic-gate uhci_handler_function_t tw_handle_td; 3830Sstevel@tonic-gate 3840Sstevel@tonic-gate /* 3850Sstevel@tonic-gate * This is the callback value used when processing a done td. 3860Sstevel@tonic-gate */ 3870Sstevel@tonic-gate usb_opaque_t tw_handle_callback_value; 3880Sstevel@tonic-gate 3890Sstevel@tonic-gate uint_t tw_bytes_xfered; 3900Sstevel@tonic-gate uint_t tw_bytes_pending; 3910Sstevel@tonic-gate 3920Sstevel@tonic-gate /* Maximum amount of time for this command */ 3930Sstevel@tonic-gate uint_t tw_timeout_cnt; 3940Sstevel@tonic-gate 3950Sstevel@tonic-gate usb_isoc_req_t *tw_isoc_req; 3960Sstevel@tonic-gate uhci_bulk_isoc_xfer_t tw_xfer_info; 3972125Ssl147100 uhci_isoc_buf_t *tw_isoc_bufs; /* Isoc DMA buffers */ 3982125Ssl147100 size_t tw_isoc_strtlen; 3990Sstevel@tonic-gate 4000Sstevel@tonic-gate /* This is used to avoid multiple tw deallocation */ 4010Sstevel@tonic-gate uint_t tw_claim; 4020Sstevel@tonic-gate 4030Sstevel@tonic-gate /* 4040Sstevel@tonic-gate * Pointer to the data in case of send command 4050Sstevel@tonic-gate */ 4060Sstevel@tonic-gate mblk_t *tw_data; 4070Sstevel@tonic-gate 4080Sstevel@tonic-gate /* save a copy of current request */ 4090Sstevel@tonic-gate usb_opaque_t tw_curr_xfer_reqp; 4100Sstevel@tonic-gate } uhci_trans_wrapper_t; 4110Sstevel@tonic-gate 4122125Ssl147100 /* Macros for uhci DMA buffer */ 4132125Ssl147100 #define UHCI_DMA_ATTR_ALIGN 0x800 4142125Ssl147100 #define UHCI_DMA_ATTR_SGLLEN 0x7fffffff 4152125Ssl147100 #define UHCI_CTRL_EPT_MAX_SIZE 64 4162125Ssl147100 4172125Ssl147100 /* 4182125Ssl147100 * Macro for allocation of Bulk and Isoc TD pools 4192125Ssl147100 * 4202125Ssl147100 * When a Bulk or Isoc transfer needs to allocate too many TDs, 4212125Ssl147100 * the allocation for one physical contiguous TD pool may fail 4222125Ssl147100 * due to the fragmentation of physical memory. The number of 4232125Ssl147100 * TDs in one pool should be limited so that a TD pool is within 4242125Ssl147100 * page size under this situation. 4252125Ssl147100 */ 4262125Ssl147100 #if defined(__sparc) 4272125Ssl147100 #define UHCI_MAX_TD_NUM_PER_POOL 88 4282125Ssl147100 #else 4292125Ssl147100 #define UHCI_MAX_TD_NUM_PER_POOL 44 4302125Ssl147100 #endif 4312125Ssl147100 4320Sstevel@tonic-gate /* set timeout flag so as to decrement timeout_cnt only once */ 4330Sstevel@tonic-gate #define TW_TIMEOUT_FLAG 0x1000 4340Sstevel@tonic-gate 4350Sstevel@tonic-gate /* Macro for changing the data toggle */ 4360Sstevel@tonic-gate #define ADJ_DATA_TOGGLE(pp) \ 4370Sstevel@tonic-gate (pp)->pp_data_toggle = ((pp)->pp_data_toggle == 0) ? 1 : 0; 4380Sstevel@tonic-gate 4390Sstevel@tonic-gate /* 4400Sstevel@tonic-gate * Macros for setting/getting information 4410Sstevel@tonic-gate */ 4420Sstevel@tonic-gate #define Get_OpReg32(addr) ddi_get32(uhcip->uhci_regs_handle, \ 4430Sstevel@tonic-gate (uint32_t *)&uhcip->uhci_regsp->addr) 4440Sstevel@tonic-gate #define Get_OpReg16(addr) ddi_get16(uhcip->uhci_regs_handle, \ 4450Sstevel@tonic-gate (uint16_t *)&uhcip->uhci_regsp->addr) 4460Sstevel@tonic-gate #define Get_OpReg8(addr) ddi_get8(uhcip->uhci_regs_handle, \ 4470Sstevel@tonic-gate (uchar_t *)&uhcip->uhci_regsp->addr) 4480Sstevel@tonic-gate 4490Sstevel@tonic-gate #define Set_OpReg32(addr, val) ddi_put32(uhcip->uhci_regs_handle, \ 4500Sstevel@tonic-gate ((uint32_t *)&uhcip->uhci_regsp->addr), \ 4510Sstevel@tonic-gate ((int32_t)(val))) 4520Sstevel@tonic-gate #define Set_OpReg16(addr, val) ddi_put16(uhcip->uhci_regs_handle, \ 4530Sstevel@tonic-gate ((uint16_t *)&uhcip->uhci_regsp->addr), \ 4540Sstevel@tonic-gate ((int16_t)(val))) 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate #define QH_PADDR(addr) \ 4570Sstevel@tonic-gate ((uint32_t)(uhcip->uhci_qh_pool_cookie.dmac_address + \ 4580Sstevel@tonic-gate (uint32_t)((uintptr_t)(addr) - \ 4590Sstevel@tonic-gate (uintptr_t)uhcip->uhci_qh_pool_addr))) 4600Sstevel@tonic-gate 4610Sstevel@tonic-gate 4620Sstevel@tonic-gate #define QH_VADDR(addr) \ 4630Sstevel@tonic-gate ((void *)(((uint32_t)(addr) - \ 4640Sstevel@tonic-gate (uint32_t)uhcip->uhci_qh_pool_cookie.dmac_address) + \ 4650Sstevel@tonic-gate (char *)uhcip->uhci_qh_pool_addr)) 4660Sstevel@tonic-gate 4670Sstevel@tonic-gate #define TD_PADDR(addr) \ 4680Sstevel@tonic-gate ((uint32_t)uhcip->uhci_td_pool_cookie.dmac_address + \ 4690Sstevel@tonic-gate (uint32_t)((uintptr_t)(addr) - \ 4700Sstevel@tonic-gate (uintptr_t)(uhcip->uhci_td_pool_addr))) 4710Sstevel@tonic-gate 4720Sstevel@tonic-gate #define BULKTD_PADDR(x, addr)\ 4730Sstevel@tonic-gate ((uint32_t)((uintptr_t)(addr) - (uintptr_t)x->pool_addr) + \ 4740Sstevel@tonic-gate (uint32_t)(x)->cookie.dmac_address) 4750Sstevel@tonic-gate 4760Sstevel@tonic-gate #define BULKTD_VADDR(x, addr)\ 4770Sstevel@tonic-gate ((void *)(((uint32_t)(addr) - \ 4780Sstevel@tonic-gate (uint32_t)(x)->cookie.dmac_address) + \ 4790Sstevel@tonic-gate (char *)(x)->pool_addr)) 4800Sstevel@tonic-gate 4810Sstevel@tonic-gate #define ISOCTD_PADDR(x, addr)\ 4820Sstevel@tonic-gate ((uint32_t)((uintptr_t)(addr) - (uintptr_t)(x)->pool_addr) + \ 4830Sstevel@tonic-gate (uint32_t)(x)->cookie.dmac_address) 4840Sstevel@tonic-gate 4850Sstevel@tonic-gate #define TD_VADDR(addr) \ 4860Sstevel@tonic-gate ((void *)(((uint32_t)(addr) - \ 4870Sstevel@tonic-gate (uint32_t)uhcip->uhci_td_pool_cookie.dmac_address) + \ 4880Sstevel@tonic-gate (char *)uhcip->uhci_td_pool_addr)) 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate /* 4910Sstevel@tonic-gate * If the terminate bit is cleared, there shouldn't be any 4920Sstevel@tonic-gate * race condition problems. If the host controller reads the 4930Sstevel@tonic-gate * bit before the driver has a chance to set the bit, the bit 4940Sstevel@tonic-gate * will be reread on the next frame. 4950Sstevel@tonic-gate */ 4960Sstevel@tonic-gate #define UHCI_SET_TERMINATE_BIT(addr) \ 4970Sstevel@tonic-gate SetQH32(uhcip, addr, GetQH32(uhcip, (addr)) | HC_END_OF_LIST) 4980Sstevel@tonic-gate #define UHCI_CLEAR_TERMINATE_BIT(addr) \ 4990Sstevel@tonic-gate SetQH32(uhcip, addr, GetQH32(uhcip, (addr)) & ~HC_END_OF_LIST) 5000Sstevel@tonic-gate 5010Sstevel@tonic-gate #define UHCI_XFER_TYPE(ept) ((ept)->bmAttributes & USB_EP_ATTR_MASK) 5020Sstevel@tonic-gate #define UHCI_XFER_DIR(ept) ((ept)->bEndpointAddress & \ 5030Sstevel@tonic-gate USB_EP_DIR_MASK) 5040Sstevel@tonic-gate 5050Sstevel@tonic-gate /* 5060Sstevel@tonic-gate * for HCD based kstats: 5070Sstevel@tonic-gate * uhci_intrs_stats_t structure 5080Sstevel@tonic-gate */ 5090Sstevel@tonic-gate typedef struct uhci_intrs_stats { 5100Sstevel@tonic-gate struct kstat_named uhci_intrs_hc_halted; 5110Sstevel@tonic-gate struct kstat_named uhci_intrs_hc_process_err; 5120Sstevel@tonic-gate struct kstat_named uhci_intrs_host_sys_err; 5130Sstevel@tonic-gate struct kstat_named uhci_intrs_resume_detected; 5140Sstevel@tonic-gate struct kstat_named uhci_intrs_usb_err_intr; 5150Sstevel@tonic-gate struct kstat_named uhci_intrs_usb_intr; 5160Sstevel@tonic-gate struct kstat_named uhci_intrs_total; 5170Sstevel@tonic-gate struct kstat_named uhci_intrs_not_claimed; 5180Sstevel@tonic-gate } uhci_intrs_stats_t; 5190Sstevel@tonic-gate 5200Sstevel@tonic-gate /* 5210Sstevel@tonic-gate * uhci defines for kstats 5220Sstevel@tonic-gate */ 5230Sstevel@tonic-gate #define UHCI_INTRS_STATS(uhci) ((uhci)->uhci_intrs_stats) 5240Sstevel@tonic-gate #define UHCI_INTRS_STATS_DATA(uhci) \ 5250Sstevel@tonic-gate ((uhci_intrs_stats_t *)UHCI_INTRS_STATS((uhci))->ks_data) 5260Sstevel@tonic-gate 5270Sstevel@tonic-gate #define UHCI_TOTAL_STATS(uhci) ((uhci)->uhci_total_stats) 5280Sstevel@tonic-gate #define UHCI_TOTAL_STATS_DATA(uhci) (KSTAT_IO_PTR((uhci)->uhci_total_stats)) 5290Sstevel@tonic-gate #define UHCI_CTRL_STATS(uhci) \ 5300Sstevel@tonic-gate (KSTAT_IO_PTR((uhci)->uhci_count_stats[USB_EP_ATTR_CONTROL])) 5310Sstevel@tonic-gate #define UHCI_BULK_STATS(uhci) \ 5320Sstevel@tonic-gate (KSTAT_IO_PTR((uhci)->uhci_count_stats[USB_EP_ATTR_BULK])) 5330Sstevel@tonic-gate #define UHCI_INTR_STATS(uhci) \ 5340Sstevel@tonic-gate (KSTAT_IO_PTR((uhci)->uhci_count_stats[USB_EP_ATTR_INTR])) 5350Sstevel@tonic-gate #define UHCI_ISOC_STATS(uhci) \ 5360Sstevel@tonic-gate (KSTAT_IO_PTR((uhci)->uhci_count_stats[USB_EP_ATTR_ISOCH])) 5370Sstevel@tonic-gate 5380Sstevel@tonic-gate #define UHCI_UNIT(dev) (getminor((dev)) & ~HUBD_IS_ROOT_HUB) 5390Sstevel@tonic-gate 5400Sstevel@tonic-gate #define UHCI_PERIODIC_ENDPOINT(ept) \ 5410Sstevel@tonic-gate (((((ept)->bmAttributes) & USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) || \ 5420Sstevel@tonic-gate ((((ept)->bmAttributes) & USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH)) 5430Sstevel@tonic-gate 5440Sstevel@tonic-gate /* 5455773Sqz150045 * Host Contoller Software States 5465773Sqz150045 * 5475773Sqz150045 * UHCI_CTLR_INIT_STATE: 5485773Sqz150045 * The host controller soft state will be set to this during the 5495773Sqz150045 * uhci_attach. 5505773Sqz150045 * 5515773Sqz150045 * UHCI_CTLR_SUSPEND_STATE: 5525773Sqz150045 * The host controller soft state will be set to this during the 5535773Sqz150045 * uhci_cpr_suspend. 5545773Sqz150045 * 5555773Sqz150045 * UHCI_CTLR_OPERATIONAL_STATE: 5565773Sqz150045 * The host controller soft state will be set to this after moving 5575773Sqz150045 * host controller to operational state and host controller start 5585773Sqz150045 * generating SOF successfully. 5595773Sqz150045 * 5605773Sqz150045 * UHCI_CTLR_ERROR_STATE: 5615773Sqz150045 * The host controller soft state will be set to this during the 5625773Sqz150045 * hardware error or no SOF conditions. 5635773Sqz150045 * 5645773Sqz150045 * Under non-operational state, only pipe stop polling, pipe reset 5655773Sqz150045 * and pipe close are allowed. But all other entry points like pipe 5665773Sqz150045 * open, get/set pipe policy, cotrol send/receive, bulk send/receive 5675773Sqz150045 * isoch send/receive, start polling etc. will fail. 5685773Sqz150045 */ 5695773Sqz150045 #define UHCI_CTLR_INIT_STATE 0 /* Initilization state */ 5705773Sqz150045 #define UHCI_CTLR_SUSPEND_STATE 1 /* Suspend state */ 5715773Sqz150045 #define UHCI_CTLR_OPERATIONAL_STATE 2 /* Operational state */ 5725773Sqz150045 #define UHCI_CTLR_ERROR_STATE 3 /* Hardware error */ 5735773Sqz150045 5745773Sqz150045 /* 5750Sstevel@tonic-gate * Debug printing Masks 5760Sstevel@tonic-gate */ 5770Sstevel@tonic-gate #define PRINT_MASK_ATTA 0x00000001 /* Attach time */ 5780Sstevel@tonic-gate #define PRINT_MASK_LISTS 0x00000002 /* List management */ 5790Sstevel@tonic-gate #define PRINT_MASK_ROOT_HUB 0x00000004 /* Root hub stuff */ 5800Sstevel@tonic-gate #define PRINT_MASK_ALLOC 0x00000008 /* Alloc/dealloc descr */ 5810Sstevel@tonic-gate #define PRINT_MASK_INTR 0x00000010 /* Interrupt handling */ 5820Sstevel@tonic-gate #define PRINT_MASK_BW 0x00000020 /* Bandwidth */ 5830Sstevel@tonic-gate #define PRINT_MASK_CBOPS 0x00000040 /* CB-OPS */ 5840Sstevel@tonic-gate #define PRINT_MASK_HCDI 0x00000080 /* HCDI entry points */ 5850Sstevel@tonic-gate #define PRINT_MASK_DUMPING 0x00000100 /* Dump HCD state info */ 5860Sstevel@tonic-gate #define PRINT_MASK_ISOC 0x00000200 /* For ISOC xfers */ 5870Sstevel@tonic-gate 5880Sstevel@tonic-gate #define PRINT_MASK_ALL 0xFFFFFFFF 5890Sstevel@tonic-gate 5900Sstevel@tonic-gate #ifdef __cplusplus 5910Sstevel@tonic-gate } 5920Sstevel@tonic-gate #endif 5930Sstevel@tonic-gate 5940Sstevel@tonic-gate #endif /* _SYS_USB_UHCID_H */ 595