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 */