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