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