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