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