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 2009 Sun Microsystems, Inc. All rights reserved. 22 * Use is subject to license terms. 23 */ 24 25 #ifndef _SYS_USB_USBA_USBA_TYPES_H 26 #define _SYS_USB_USBA_USBA_TYPES_H 27 28 29 #include <sys/taskq.h> 30 #include <sys/usb/usba/usba_private.h> 31 #include <sys/usb/usba/usbai_private.h> 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 /* backup structure for opaque usb_pipe_handle_t */ 38 typedef struct usba_ph_impl { 39 kmutex_t usba_ph_mutex; 40 struct usba_pipe_handle_data *usba_ph_data; /* actual pipe handle */ 41 dev_info_t *usba_ph_dip; /* owner dip */ 42 usb_ep_descr_t usba_ph_ep; /* save ep descr */ 43 usb_pipe_policy_t usba_ph_policy; /* saved pipe policy */ 44 uint_t usba_ph_flags; 45 46 /* 47 * usba_ph_ref_count is a count of the number of 48 * concurrent activities on this pipe 49 */ 50 int usba_ph_ref_count; 51 52 /* pipe state management */ 53 usb_pipe_state_t usba_ph_state; 54 int usba_ph_state_changing; 55 } usba_ph_impl_t; 56 57 _NOTE(MUTEX_PROTECTS_DATA(usba_ph_impl::usba_ph_mutex, usba_ph_impl)) 58 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_ph_impl::usba_ph_data)) 59 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_ph_impl::usba_ph_dip)) 60 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_ph_impl::usba_ph_ep)) 61 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_ph_impl::usba_ph_policy)) 62 63 /* for usba_ph_flags */ 64 #define USBA_PH_DATA_TOGGLE 0x01 /* mask for data toggle */ 65 #define USBA_PH_DATA_PERSISTENT 0x02 /* persistent pipe */ 66 67 68 /* 69 * usba_pipe_handle_data 70 * allocated by USBA and used by USBA and HCD but opaque to 71 * client driver 72 * 73 * pipes can be shared but pipe_handles are unique 74 * 75 * p_hcd_private is a pointer to private data for HCD. This space 76 * is allocated and maintained by HCD 77 */ 78 typedef struct usba_pipe_handle_data { 79 struct usba_ph_impl *p_ph_impl; /* backpointer to ph_impl */ 80 81 /* For linking pipe requests on the pipe */ 82 usba_list_entry_t p_queue; 83 84 /* shared usba_device structure */ 85 struct usba_device *p_usba_device; /* set on pipe open */ 86 87 /* pipe policy and endpoint descriptor for this pipe */ 88 usb_pipe_policy_t p_policy; /* maintained by USBA */ 89 usb_ep_descr_t p_ep; 90 91 /* passed during open. needed for reset etc. */ 92 dev_info_t *p_dip; 93 94 /* access control */ 95 kmutex_t p_mutex; /* mutex protecting pipe handle */ 96 97 /* per-pipe private data for HCD */ 98 usb_opaque_t p_hcd_private; 99 100 /* per-pipe private data for client */ 101 usb_opaque_t p_client_private; 102 103 /* 104 * p_req_count is the count of number requests active 105 * on this pipe 106 */ 107 int p_req_count; 108 109 /* private use by USBA */ 110 usb_opaque_t p_usba_private; 111 112 /* 113 * each pipe handle has its own taskq for callbacks and async reqs 114 * Note that this will not be used for normal callbacks if 115 * USB_FLAGS_SERIALIZED_CB is passed to usb_pipe_open(). 116 */ 117 taskq_t *p_taskq; 118 119 /* thread currently serving the queue */ 120 kthread_t *p_thread_id; 121 122 /* cb queue serviced by taskq thread */ 123 usba_list_entry_t p_cb_queue; 124 125 /* count for soft interrupts */ 126 uint_t p_soft_intr; 127 128 /* flag for special things */ 129 uint_t p_spec_flag; 130 131 } usba_pipe_handle_data_t; 132 133 #define USBA_PH_FLAG_USE_SOFT_INTR 0x1 134 #define USBA_PH_FLAG_TQ_SHARE 0x2 /* Shared TaskQ for callbacks */ 135 136 137 138 /* macro to get the endpoint descriptor */ 139 #define USBA_DEFAULT_PIPE_EP 0 /* ep 0 is default pipe */ 140 #define USBA_PH2ENDPOINT(ph) (((usba_pipe_handle_data_t *)(ph))->p_ep) 141 142 #define USBA_PIPE_CLOSING(state) \ 143 (((state) == USB_PIPE_STATE_CLOSING) || \ 144 ((state) == USB_PIPE_STATE_CLOSED)) 145 146 #define USBA_IS_DEFAULT_PIPE(ph) ((ph) == \ 147 (ph)->p_usba_device->usb_ph_list[USBA_DEFAULT_PIPE_EP].usba_ph_data) 148 149 _NOTE(MUTEX_PROTECTS_DATA(usba_pipe_handle_data::p_mutex, \ 150 usba_pipe_handle_data)) 151 152 /* these should be really stable data */ 153 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_ph_impl)) 154 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_usba_device)) 155 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_hcd_private)) 156 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_client_private)) 157 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_ep)) 158 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_dip)) 159 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_taskq)) 160 161 162 /* 163 * usb_addr: 164 * This is the USB address of a device 165 */ 166 typedef uchar_t usb_addr_t; 167 168 #define USBA_DEFAULT_ADDR 0 169 170 /* 171 * number of endpoint per device, 16 IN and 16 OUT. 172 * this define is used for pipehandle list, pipe reserved list 173 * and pipe open count array. 174 * these lists are indexed by endpoint number * ((address & direction)? 2 : 1) 175 * 176 * We use a bit mask for exclusive open tracking and therefore 177 * USB_N_ENDPOINTS must be equal to the bit size of int. 178 * 179 */ 180 #define USBA_N_ENDPOINTS 32 181 182 /* 183 * USB spec defines 4 different power states of any usb device. 184 * They are D0, D1, D2 & D3. So, we need a total of 5 pm-components 185 * 4 for power and 1 for name. 186 */ 187 #define USBA_N_PMCOMP 5 188 189 /* 190 * usb port status 191 */ 192 typedef uint8_t usb_port_status_t; 193 typedef uint16_t usb_port_t; 194 typedef uint32_t usb_port_mask_t; 195 196 #define USBA_LOW_SPEED_DEV 0x1 197 #define USBA_FULL_SPEED_DEV 0x2 198 #define USBA_HIGH_SPEED_DEV 0x3 199 200 /* 201 * NDI event is registered on a per-dip basis. usba_device can be 202 * shared by multiple dips, hence the following structure is 203 * need to keep per-dip event info. 204 */ 205 typedef struct usba_evdata { 206 struct usba_evdata *ev_next; 207 dev_info_t *ev_dip; 208 209 /* NDI evetn service callback ids */ 210 ddi_callback_id_t ev_rm_cb_id; 211 ddi_callback_id_t ev_ins_cb_id; 212 ddi_callback_id_t ev_suspend_cb_id; 213 ddi_callback_id_t ev_resume_cb_id; 214 } usba_evdata_t; 215 216 /* 217 * a client may request dev_data multiple times (eg. for 218 * ugen support) so we need a linked list 219 */ 220 typedef struct usb_client_dev_data_list { 221 struct usb_client_dev_data_list *cddl_next; 222 struct usb_client_dev_data_list *cddl_prev; 223 dev_info_t *cddl_dip; 224 usb_client_dev_data_t *cddl_dev_data; 225 uint_t cddl_ifno; 226 } usb_client_dev_data_list_t; 227 228 /* 229 * wireless usb specific data 230 */ 231 typedef struct usba_wireless_data { 232 uint8_t *wusb_bos; /* raw bos descr */ 233 uint_t wusb_bos_length; /* length of bos descr */ 234 usb_uwb_cap_descr_t *uwb_descr; /* UWB capability descr */ 235 } usba_wireless_data_t; 236 237 /* 238 * This structure uniquely identifies a USB device 239 * with all interfaces, or just one interface of a USB device. 240 * usba_device is associated with a devinfo node 241 * 242 * This structure is allocated and maintained by USBA and 243 * read-only for HCD 244 * 245 * There can be multiple clients per device (multi-class 246 * device) in which case this structure is shared. 247 */ 248 typedef struct usba_device { 249 /* for linking all usba_devices on this bus */ 250 usba_list_entry_t usb_device_list; 251 252 /* linked list of all pipe handles on this device per endpoint */ 253 struct usba_ph_impl usb_ph_list[USBA_N_ENDPOINTS]; 254 255 kmutex_t usb_mutex; /* protecting usba_device */ 256 257 dev_info_t *usb_dip; 258 259 struct usba_hcdi_ops *usb_hcdi_ops; /* ptr to HCD ops */ 260 261 struct usba_hubdi *usb_hubdi; 262 263 usb_addr_t usb_addr; /* usb address */ 264 265 uchar_t usb_no_cpr; /* CPR? */ 266 267 dev_info_t *usb_root_hub_dip; 268 struct hubd *usb_root_hubd; /* for HC or WA */ 269 270 usb_dev_descr_t *usb_dev_descr; /* device descriptor */ 271 272 uchar_t *usb_cfg; /* raw config descriptor */ 273 size_t usb_cfg_length; /* length of raw descr */ 274 275 char *usb_mfg_str; /* manufacturer string */ 276 char *usb_product_str; /* product string */ 277 char *usb_serialno_str; /* serial number string */ 278 char *usb_preferred_driver; /* user's choice */ 279 280 usb_port_status_t usb_port_status; /* usb hub port status */ 281 usb_port_t usb_port; 282 283 /* To support split transactions */ 284 struct usba_device *usb_hs_hub_usba_dev; /* HS hub usba device */ 285 usb_addr_t usb_hs_hub_addr; /* High speed hub address */ 286 usb_port_t usb_hs_hub_port; /* High speed hub port */ 287 288 /* For high speed hub bandwidth allocation scheme */ 289 uint_t usb_hs_hub_min_bandwidth; 290 uint_t usb_hs_hub_bandwidth[32]; 291 292 /* store all config cloud here */ 293 uchar_t **usb_cfg_array; 294 uint_t usb_cfg_array_length; 295 296 uint16_t *usb_cfg_array_len; 297 uint_t usb_cfg_array_len_length; 298 299 uint_t usb_cfg_value; 300 uint_t usb_active_cfg_ndx; 301 char **usb_cfg_str_descr; 302 uchar_t usb_n_cfgs; 303 uchar_t usb_n_ifs; 304 305 /* To support WUSB */ 306 boolean_t usb_is_wa; 307 boolean_t usb_is_wireless; 308 usba_wireless_data_t *usb_wireless_data; 309 310 /* 311 * power drawn from hub, if > 0, the power has been 312 * subtracted from the parent hub's power budget 313 */ 314 uint16_t usb_pwr_from_hub; 315 316 /* ref count, if > 0, this structure is in use */ 317 int usb_ref_count; 318 319 /* list of requests allocated for this device, detects leaks */ 320 usba_list_entry_t usb_allocated; /* alloc'ed reqs list */ 321 322 /* NDI event service cookies */ 323 ddi_eventcookie_t rm_cookie; 324 ddi_eventcookie_t ins_cookie; 325 ddi_eventcookie_t suspend_cookie; 326 ddi_eventcookie_t resume_cookie; 327 328 /* linked list of callid (per-devinfo) */ 329 usba_evdata_t *usb_evdata; 330 331 /* client cleanup checks */ 332 uchar_t *usb_client_flags; 333 334 struct { 335 dev_info_t *dip; 336 } *usb_client_attach_list; 337 338 usb_client_dev_data_list_t usb_client_dev_data_list; 339 340 struct { 341 dev_info_t *dip; 342 usb_event_t *ev_data; 343 } *usb_client_ev_cb_list; 344 345 /* Shared task queue implementation. */ 346 taskq_t *usb_shared_taskq[USBA_N_ENDPOINTS]; 347 uchar_t usb_shared_taskq_ref_count 348 [USBA_N_ENDPOINTS]; 349 } usba_device_t; 350 351 #define USBA_CLIENT_FLAG_SIZE 1 352 #define USBA_CLIENT_FLAG_ATTACH 0x01 353 #define USBA_CLIENT_FLAG_EV_CBS 0x02 354 #define USBA_CLIENT_FLAG_DEV_DATA 0x04 355 356 _NOTE(MUTEX_PROTECTS_DATA(usba_device::usb_mutex, usba_device)) 357 _NOTE(MUTEX_PROTECTS_DATA(usba_device::usb_mutex, usba_evdata)) 358 359 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", 360 usba_evdata::ev_rm_cb_id)) 361 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", 362 usba_evdata::ev_ins_cb_id)) 363 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", 364 usba_evdata::ev_suspend_cb_id)) 365 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", 366 usba_evdata::ev_resume_cb_id)) 367 368 /* this should be really stable data */ 369 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_serialno_str)) 370 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_root_hub_dip)) 371 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_root_hubd)) 372 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_product_str)) 373 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_preferred_driver)) 374 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_port)) 375 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_n_ifs)) 376 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_n_cfgs)) 377 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_mfg_str)) 378 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_dev_descr)) 379 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_ph_list)) 380 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_value)) 381 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_str_descr)) 382 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_length)) 383 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array)) 384 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array_len)) 385 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array_length)) 386 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array_len_length)) 387 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg)) 388 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_hcdi_ops)) 389 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_addr)) 390 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_port_status)) 391 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::rm_cookie)) 392 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::ins_cookie)) 393 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::suspend_cookie)) 394 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::resume_cookie)) 395 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_flags)) 396 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_attach_list)) 397 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_ev_cb_list)) 398 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_dip)) 399 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_is_wireless)) 400 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_wireless_data)) 401 _NOTE(SCHEME_PROTECTS_DATA("set at device creation", 402 usba_device::usb_shared_taskq)) 403 404 /* 405 * serialization in drivers 406 */ 407 typedef struct usba_serialization_impl { 408 dev_info_t *s_dip; 409 kcondvar_t s_cv; 410 kmutex_t s_mutex; 411 kthread_t *s_thread; 412 int s_count; 413 uint_t s_flag; 414 } usba_serialization_impl_t; 415 416 _NOTE(SCHEME_PROTECTS_DATA("unshared private data", 417 usba_serialization_impl)) 418 419 #ifdef __cplusplus 420 } 421 #endif 422 423 #endif /* _SYS_USB_USBA_USBA_TYPES_H */ 424