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