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