usba_ugend.h revision 7492:2387323b838f
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 22 * Use is subject to license terms. 23 */ 24 25#ifndef _SYS_USBA_UGEND_H 26#define _SYS_USBA_UGEND_H 27 28 29/* 30 * UGEN - USB Generic Driver Support 31 * This file contains the UGEN specific data structure definitions 32 * and UGEN specific macros. 33 */ 34#include <sys/usb/usba/usbai_private.h> 35 36#ifdef __cplusplus 37extern "C" { 38#endif 39 40/* ugen handle passed to client drivers as an opaque token */ 41typedef struct { 42 dev_info_t *hdl_dip; 43 uint_t hdl_flags; 44 dev_t hdl_minor_node_ugen_bits_mask; 45 uint_t hdl_minor_node_ugen_bits_shift; 46 uint_t hdl_minor_node_ugen_bits_limit; 47 48 dev_t hdl_minor_node_instance_mask; 49 uint_t hdl_minor_node_instance_shift; 50 uint_t hdl_minor_node_instance_limit; 51 52 struct ugen_state *hdl_ugenp; 53 char *hdl_log_name; 54 uint_t hdl_log_name_length; 55} usb_ugen_hdl_impl_t; 56 57_NOTE(SCHEME_PROTECTS_DATA("stable data", usb_ugen_hdl_impl_t)) 58 59/* devt lookup support */ 60typedef struct ugen_devt_list_entry { 61 struct ugen_devt_list_entry *list_next; 62 struct ugen_devt_list_entry *list_prev; 63 dev_t list_dev; 64 struct ugen_state *list_state; 65} ugen_devt_list_entry_t; 66 67typedef struct ugen_devt_cache_entry { 68 dev_t cache_dev; 69 struct ugen_state *cache_state; 70 uint_t cache_hit; 71} ugen_devt_cache_entry_t; 72 73#define UGEN_DEVT_CACHE_SIZE 10 74 75/* minor node definition */ 76#ifdef _LP64 77#define UGEN_MINOR_NODE_SIZE 32 78#else 79#define UGEN_MINOR_NODE_SIZE 18 80#endif 81 82#define UGEN_MINOR_INSTANCE_MASK(ugenp) \ 83 (ugenp)->ug_hdl->hdl_minor_node_instance_mask 84#define UGEN_MINOR_INSTANCE_LIMIT(ugenp) \ 85 (ugenp)->ug_hdl->hdl_minor_node_instance_limit 86#define UGEN_MINOR_INSTANCE_SHIFT(ugenp) \ 87 (ugenp)->ug_hdl->hdl_minor_node_instance_shift 88 89#define UGEN_MINOR_IDX_SHIFT(ugenp) \ 90 (ugenp)->ug_hdl->hdl_minor_node_ugen_bits_shift 91#define UGEN_MINOR_IDX_LIMIT(ugenp) \ 92 (ugenp)->ug_hdl->hdl_minor_node_ugen_bits_limit 93 94#define UGEN_MINOR_GET_IDX(ugenp, dev) \ 95 ((getminor(dev) >> UGEN_MINOR_IDX_SHIFT(ugenp)) & \ 96 (ugenp)->ug_hdl->hdl_minor_node_ugen_bits_mask) 97 98#define UGEN_MINOR_INSTANCE(ugenp, dev) \ 99 (getminor(dev) & UGEN_MINOR_INSTANCE_MASK(ugenp)) 100 101 102#define UGEN_N_ENDPOINTS 32 103 104/* UGEN specific macros */ 105#define UGEN_SETUP_PKT_SIZE 8 /* Ctrl xfer Setup token sz */ 106 107/* 108 * minor node is contructed as follows for ugen driver (other client 109 * drivers that export a ugen interface may have a different layout): 110 * 111 * 17 9 0 112 * +---------------------+----------------------+ 113 * | minor index | instance | 114 * +---------------------+----------------------+ 115 * 116 * Note that only 512 endpoint minor nodes can be supported (each 117 * endpoint requires a status endpoint as well so we can only support 118 * 256 endpoints) 119 * 120 * the real minor node is: 121 * 122 * 47 40 32 24 16 8 0 123 * +-------+-------+-------+------+-------+-------+ 124 * | cfgval| cfgidx| iface | alt |epidx | type | 125 * +-------+-------+-------+------+-------+-------+ 126 * 127 * We get from the minor code to minor number thru ugen_minor_node_table 128 */ 129typedef uint64_t ugen_minor_t; 130 131#define UGEN_MINOR_DEV_STAT_NODE 0x00 132#define UGEN_MINOR_EP_XFER_NODE 0x01 133#define UGEN_MINOR_EP_STAT_NODE 0x02 134#define UGEN_OWNS_DEVICE 0x04 135 136#define UGEN_MINOR_EPIDX_SHIFT 8 137#define UGEN_MINOR_ALT_SHIFT 16 138#define UGEN_MINOR_IF_SHIFT 24 139#define UGEN_MINOR_CFGIDX_SHIFT 32 140#define UGEN_MINOR_CFGVAL_SHIFT 40 141 142#define UGEN_MINOR_TYPE(ugenp, dev) \ 143 (ugen_devt2minor((ugenp), (dev)) & 0x3) 144#define UGEN_MINOR_EPIDX(ugenp, dev) \ 145 ((ugen_devt2minor((ugenp), (dev)) >> UGEN_MINOR_EPIDX_SHIFT) & 0xFF) 146 147#define UGEN_MINOR_ALT(ugenp, dev) \ 148 ((ugen_devt2minor((ugenp), (dev)) >> UGEN_MINOR_ALT_SHIFT) & 0xFF) 149 150#define UGEN_MINOR_IF(ugenp, dev) \ 151 ((ugen_devt2minor((ugenp), (dev)) >> UGEN_MINOR_IF_SHIFT) & 0xFF) 152 153#define UGEN_MINOR_CFGIDX(ugenp, dev) \ 154 ((ugen_devt2minor((ugenp), (dev)) >> UGEN_MINOR_CFGIDX_SHIFT) & 0xFF) 155 156#define UGEN_MINOR_CFGVAL(ugenp, dev) \ 157 ((ugen_devt2minor((ugenp), (dev)) >> UGEN_MINOR_CFGVAL_SHIFT) & 0xFF) 158 159 160/* 161 * According to usb2.0 spec (table 9-13), for all ep, bits 10..0 specify the 162 * max pkt size; for high speed ISOC/INTR ep, bits 12..11 specify the number of 163 * additional transaction opportunities per microframe. 164 */ 165#define UGEN_PKT_SIZE(pktsize) (pktsize & 0x07ff) * (1 + ((pktsize >> 11) & 3)) 166 167 168/* 169 * Structure for holding isoc data packets information 170 */ 171typedef struct ugen_isoc_pkt_info { 172 ushort_t isoc_pkts_count; 173 uint_t isoc_pkts_length; 174 ugen_isoc_pkt_descr_t *isoc_pkt_descr; /* array of pkt descr */ 175} ugen_isoc_pkt_info_t; 176 177/* 178 * Endpoint structure 179 * Holds all the information needed to manage the endpoint 180 */ 181typedef struct ugen_ep { 182 uint_t ep_state; /* Endpoint state, see below */ 183 usb_ep_descr_t ep_descr; /* Endpoint descriptor */ 184 uchar_t ep_cfgidx; /* cfg index */ 185 uchar_t ep_if; /* Interface # */ 186 uchar_t ep_alt; /* alternate # */ 187 uchar_t ep_done; /* cmd is done */ 188 boolean_t ep_one_xfer; /* use one xfer on intr IN eps */ 189 uint_t ep_lcmd_status; /* last cmd status */ 190 int ep_xfer_oflag; /* open flag */ 191 int ep_stat_oflag; /* open flag */ 192 size_t ep_buf_limit; /* one second of data */ 193 usb_pipe_handle_t ep_ph; /* Endpoint pipe handle */ 194 usb_pipe_policy_t ep_pipe_policy; 195 kmutex_t ep_mutex; /* Mutex protecting ugen_ep */ 196 kcondvar_t ep_wait_cv; /* block for completion */ 197 usb_serialization_t ep_ser_cookie; /* one xfer at the time */ 198 mblk_t *ep_data; /* IN data (ctrl & intr) */ 199 struct buf *ep_bp; /* save current buf ptr */ 200 struct pollhead ep_pollhead; /* for polling */ 201 ugen_isoc_pkt_info_t ep_isoc_info; /* for isoc eps */ 202 int ep_isoc_in_inited; /* isoc IN init flag */ 203} ugen_ep_t; 204 205_NOTE(MUTEX_PROTECTS_DATA(ugen_ep::ep_mutex, ugen_ep)) 206 207/* endpoints descriptor access */ 208#define UGEN_XFER_TYPE(epp) ((epp)->ep_descr.bmAttributes & USB_EP_ATTR_MASK) 209#define UGEN_XFER_DIR(epp) ((epp)->ep_descr.bEndpointAddress & USB_EP_DIR_IN) 210#define UGEN_XFER_ADDR(epp) ((epp)->ep_descr.bEndpointAddress) 211 212#define UGEN_INTR_BUF_LIMIT 4096 213 214/* endpoint xfer/stat states */ 215#define UGEN_EP_STATE_NONE 0x00 216#define UGEN_EP_STATE_ACTIVE 0x01 217#define UGEN_EP_STATE_XFER_OPEN 0x02 218#define UGEN_EP_STATE_STAT_OPEN 0x04 219#define UGEN_EP_STATE_XS_OPEN (UGEN_EP_STATE_XFER_OPEN | \ 220 UGEN_EP_STATE_STAT_OPEN) 221#define UGEN_EP_STATE_INTR_IN_POLLING_ON 0x10 222#define UGEN_EP_STATE_INTR_IN_POLLING_IS_STOPPED 0x20 223#define UGEN_EP_STATE_INTR_IN_POLL_PENDING 0x40 224 225#define UGEN_EP_STATE_ISOC_IN_POLLING_ON 0x100 226#define UGEN_EP_STATE_ISOC_IN_POLLING_IS_STOPPED 0x200 227#define UGEN_EP_STATE_ISOC_IN_POLL_PENDING 0x400 228 229_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_ep::ep_ph)) 230_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_ep::ep_descr)) 231_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_ep::ep_ser_cookie)) 232_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_ep::ep_if)) 233 234_NOTE(SCHEME_PROTECTS_DATA("USBA", usb_ctrl_req)) 235_NOTE(SCHEME_PROTECTS_DATA("USBA", usb_bulk_req)) 236_NOTE(SCHEME_PROTECTS_DATA("USBA", usb_intr_req)) 237 238typedef struct ugen_dev_stat { 239 int dev_oflag; /* open flag */ 240 uint_t dev_stat; /* internal status */ 241 uint_t dev_state; /* exported state */ 242 kcondvar_t dev_wait_cv; /* block for change */ 243 struct pollhead dev_pollhead; /* for polling */ 244} ugen_dev_stat_t; 245 246/* dev_stat */ 247#define UGEN_DEV_STATUS_INACTIVE 0x0 248#define UGEN_DEV_STATUS_ACTIVE 0x1 249#define UGEN_DEV_STATUS_POLL_PENDING 0x2 250#define UGEN_DEV_STATUS_CHANGED 0x4 251 252/* Power Management support */ 253typedef struct ugen_power { 254 uint_t pwr_states; 255 int pwr_busy; /* busy accounting */ 256 uint8_t pwr_wakeup_enabled; 257 uint8_t pwr_current; 258} ugen_power_t; 259 260/* UGEN state structure */ 261typedef struct ugen_state { 262 usb_ugen_hdl_impl_t *ug_hdl; /* pointer to handle */ 263 dev_info_t *ug_dip; /* Dev info */ 264 uint_t ug_instance; /* Instance number */ 265 uint_t ug_dev_state; 266 uint_t ug_dev_stat_state; 267 uint_t ug_open_count; 268 uint_t ug_pending_cmds; 269 uint_t ug_initial_cfgidx; 270 271 /* locks */ 272 kmutex_t ug_mutex; /* Instance mutex */ 273 usb_serialization_t ug_ser_cookie; /* access */ 274 275 /* USB debugging system support */ 276 usb_log_handle_t ug_log_hdl; 277 278 /* registration data */ 279 usb_client_dev_data_t *ug_dev_data; 280 281 /* Endpoint management list */ 282 ugen_ep_t ug_ep[UGEN_N_ENDPOINTS]; 283 284 /* encoding minor numbers as we only have 8 bits in the minor # */ 285 ugen_minor_t *ug_minor_node_table; 286 int ug_minor_node_table_index; 287 size_t ug_minor_node_table_size; 288 289 /* device status management */ 290 ugen_dev_stat_t ug_ds; 291 292 /* PM Support */ 293 ugen_power_t *ug_pm; 294 295 /* Maximum transfer size for bulk endpoints */ 296 size_t ug_max_bulk_xfer_sz; 297 298 /* Used to deallocate allocated resources */ 299 ushort_t ug_cleanup_flags; 300} ugen_state_t; 301 302_NOTE(SCHEME_PROTECTS_DATA("unshared", buf)) 303 304_NOTE(MUTEX_PROTECTS_DATA(ugen_state::ug_mutex, ugen_state)) 305_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_state::ug_log_hdl)) 306_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_state::ug_hdl)) 307_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_state::ug_ser_cookie)) 308_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_state::ug_dip)) 309_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_state::ug_pm)) 310_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_state::ug_instance)) 311_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_state::ug_minor_node_table)) 312_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_state::ug_minor_node_table_index)) 313_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_state::ug_max_bulk_xfer_sz)) 314_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_state::ug_dev_data)) 315_NOTE(DATA_READABLE_WITHOUT_LOCK(ugen_state::ug_cleanup_flags)) 316 317 318/* ugen_cleanup_flags */ 319#define UGEN_INIT_LOCKS 0x01 320 321/* additional USB device states */ 322#define USB_UGEN_DEV_UNAVAILABLE_RESUME 0x90 323#define USB_UGEN_DEV_UNAVAILABLE_RECONNECT 0x91 324 325/* Debugging information */ 326#define UGEN_PRINT_ATTA 0x1 327#define UGEN_PRINT_CBOPS 0x2 328#define UGEN_PRINT_CPR 0x4 329#define UGEN_PRINT_POLL 0x8 330#define UGEN_PRINT_XFER 0x10 331#define UGEN_PRINT_HOTPLUG 0x20 332#define UGEN_PRINT_STAT 0x40 333#define UGEN_PRINT_PM 0x80 334#define UGEN_PRINT_ALL 0xFFFFFFFF 335 336#ifdef __cplusplus 337} 338#endif 339 340#endif /* _SYS_USBA_UGEND_H */ 341