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 /* 239 * This structure uniquely identifies a USB device 240 * with all interfaces, or just one interface of a USB device. 241 * usba_device is associated with a devinfo node 242 * 243 * This structure is allocated and maintained by USBA and 244 * read-only for HCD 245 * 246 * There can be multiple clients per device (multi-class 247 * device) in which case this structure is shared. 248 */ 249 typedef struct usba_device { 250 /* for linking all usba_devices on this bus */ 251 usba_list_entry_t usb_device_list; 252 253 /* linked list of all pipe handles on this device per endpoint */ 254 struct usba_ph_impl usb_ph_list[USBA_N_ENDPOINTS]; 255 256 kmutex_t usb_mutex; /* protecting usba_device */ 257 258 dev_info_t *usb_dip; 259 260 struct usba_hcdi_ops *usb_hcdi_ops; /* ptr to HCD ops */ 261 262 struct usba_hubdi *usb_hubdi; 263 264 usb_addr_t usb_addr; /* usb address */ 265 266 uchar_t usb_no_cpr; /* CPR? */ 267 268 dev_info_t *usb_root_hub_dip; 269 struct hubd *usb_root_hubd; /* for HC or WA */ 270 271 usb_dev_descr_t *usb_dev_descr; /* device descriptor */ 272 273 uchar_t *usb_cfg; /* raw config descriptor */ 274 size_t usb_cfg_length; /* length of raw descr */ 275 276 char *usb_mfg_str; /* manufacturer string */ 277 char *usb_product_str; /* product string */ 278 char *usb_serialno_str; /* serial number string */ 279 char *usb_preferred_driver; /* user's choice */ 280 281 usb_port_status_t usb_port_status; /* usb hub port status */ 282 usb_port_t usb_port; 283 284 /* To support split transactions */ 285 struct usba_device *usb_hs_hub_usba_dev; /* HS hub usba device */ 286 usb_addr_t usb_hs_hub_addr; /* High speed hub address */ 287 usb_port_t usb_hs_hub_port; /* High speed hub port */ 288 289 /* For high speed hub bandwidth allocation scheme */ 290 uint_t usb_hs_hub_min_bandwidth; 291 uint_t usb_hs_hub_bandwidth[32]; 292 293 /* store all config cloud here */ 294 uchar_t **usb_cfg_array; 295 uint_t usb_cfg_array_length; 296 297 uint16_t *usb_cfg_array_len; 298 uint_t usb_cfg_array_len_length; 299 300 uint_t usb_cfg_value; 301 uint_t usb_active_cfg_ndx; 302 char **usb_cfg_str_descr; 303 uchar_t usb_n_cfgs; 304 uchar_t usb_n_ifs; 305 306 /* To support WUSB */ 307 boolean_t usb_is_wa; 308 boolean_t usb_is_wireless; 309 usba_wireless_data_t *usb_wireless_data; 310 311 /* 312 * power drawn from hub, if > 0, the power has been 313 * subtracted from the parent hub's power budget 314 */ 315 uint16_t usb_pwr_from_hub; 316 317 /* ref count, if > 0, this structure is in use */ 318 int usb_ref_count; 319 320 /* list of requests allocated for this device, detects leaks */ 321 usba_list_entry_t usb_allocated; /* alloc'ed reqs list */ 322 323 /* NDI event service cookies */ 324 ddi_eventcookie_t rm_cookie; 325 ddi_eventcookie_t ins_cookie; 326 ddi_eventcookie_t suspend_cookie; 327 ddi_eventcookie_t resume_cookie; 328 329 /* linked list of callid (per-devinfo) */ 330 usba_evdata_t *usb_evdata; 331 332 /* client cleanup checks */ 333 uchar_t *usb_client_flags; 334 335 struct { 336 dev_info_t *dip; 337 } *usb_client_attach_list; 338 339 usb_client_dev_data_list_t usb_client_dev_data_list; 340 341 struct { 342 dev_info_t *dip; 343 usb_event_t *ev_data; 344 } *usb_client_ev_cb_list; 345 346 /* Shared task queue implementation. */ 347 taskq_t *usb_shared_taskq[USBA_N_ENDPOINTS]; 348 uchar_t usb_shared_taskq_ref_count 349 [USBA_N_ENDPOINTS]; 350 } usba_device_t; 351 352 #define USBA_CLIENT_FLAG_SIZE 1 353 #define USBA_CLIENT_FLAG_ATTACH 0x01 354 #define USBA_CLIENT_FLAG_EV_CBS 0x02 355 #define USBA_CLIENT_FLAG_DEV_DATA 0x04 356 357 _NOTE(MUTEX_PROTECTS_DATA(usba_device::usb_mutex, usba_device)) 358 _NOTE(MUTEX_PROTECTS_DATA(usba_device::usb_mutex, usba_evdata)) 359 _NOTE(MUTEX_PROTECTS_DATA(usba_device::usb_mutex, usba_wireless_data)) 360 361 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", 362 usba_evdata::ev_rm_cb_id)) 363 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", 364 usba_evdata::ev_ins_cb_id)) 365 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", 366 usba_evdata::ev_suspend_cb_id)) 367 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", 368 usba_evdata::ev_resume_cb_id)) 369 370 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", 371 usba_wireless_data::wusb_bos)) 372 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", 373 usba_wireless_data::wusb_bos_length)) 374 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", 375 usba_wireless_data::uwb_descr)) 376 377 /* this should be really stable data */ 378 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_serialno_str)) 379 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_root_hub_dip)) 380 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_root_hubd)) 381 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_product_str)) 382 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_preferred_driver)) 383 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_port)) 384 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_n_ifs)) 385 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_n_cfgs)) 386 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_mfg_str)) 387 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_dev_descr)) 388 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_ph_list)) 389 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_value)) 390 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_str_descr)) 391 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_length)) 392 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array)) 393 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array_len)) 394 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array_length)) 395 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array_len_length)) 396 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg)) 397 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_hcdi_ops)) 398 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_addr)) 399 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_port_status)) 400 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::rm_cookie)) 401 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::ins_cookie)) 402 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::suspend_cookie)) 403 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::resume_cookie)) 404 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_flags)) 405 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_attach_list)) 406 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_ev_cb_list)) 407 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_dip)) 408 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_is_wireless)) 409 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_wireless_data)) 410 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_is_wa)) 411 _NOTE(SCHEME_PROTECTS_DATA("set at device creation", 412 usba_device::usb_shared_taskq)) 413 414 _NOTE(SCHEME_PROTECTS_DATA("local use only", 415 usb_key_descr::bDescriptorType)) 416 _NOTE(SCHEME_PROTECTS_DATA("local use only", 417 usb_key_descr::bLength)) 418 /* 419 * serialization in drivers 420 */ 421 typedef struct usba_serialization_impl { 422 dev_info_t *s_dip; 423 kcondvar_t s_cv; 424 kmutex_t s_mutex; 425 kthread_t *s_thread; 426 int s_count; 427 uint_t s_flag; 428 } usba_serialization_impl_t; 429 430 _NOTE(SCHEME_PROTECTS_DATA("unshared private data", 431 usba_serialization_impl)) 432 433 #ifdef __cplusplus 434 } 435 #endif 436 437 #endif /* _SYS_USB_USBA_USBA_TYPES_H */ 438