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