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 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #ifndef _SYS_USB_HCDI_H
  27 #define _SYS_USB_HCDI_H
  28 
  29 
  30 #ifdef  __cplusplus
  31 extern "C" {
  32 #endif
  33 
  34 #include <sys/usb/usba/genconsole.h>
  35 #include <sys/usb/usba/usba_types.h>
  36 
  37 /*
  38  * HCD ops structure
  39  *
  40  * - this structure defines all entry points into HCD
  41  *
  42  * - all client driver USBAI functions that require HCD
  43  *   involvement go through this ops table
  44  *
  45  * - at HCD attach time, the HCD ops are passed to
  46  *   to the USBA through usba_hcdi_attach()
  47  *
  48  * some of these ops implement the semantics of the corresponding
  49  * USBAI interfaces. Refer to usbai.h for detailed description
  50  */
  51 #define HCDI_OPS_VERSION_0 0
  52 #define HCDI_OPS_VERSION_1 1
  53 #define HCDI_OPS_VERSION        HCDI_OPS_VERSION_1
  54 
  55 typedef struct usba_hcdi_ops {
  56         int     usba_hcdi_ops_version;  /* implementation version */
  57 
  58         dev_info_t      *usba_hcdi_dip; /* HCD's devinfo ptr */
  59 
  60         /* can this hcd support pm? */
  61         int     (*usba_hcdi_pm_support)(dev_info_t *dip);
  62 
  63         /*
  64          * usba_hcdi_pipe_open:
  65          *      implements the semantics of usb_pipe_open()
  66          *      USBA allocate the pipe_handle which contains
  67          *      pipe_policy and endpoint pointers
  68          */
  69         int     (*usba_hcdi_pipe_open)(
  70                 usba_pipe_handle_data_t *pipe_handle,
  71                 usb_flags_t             usb_flags);
  72 
  73         /*
  74          * close a pipe
  75          */
  76         int     (*usba_hcdi_pipe_close)(
  77                 usba_pipe_handle_data_t *pipe_handle,
  78                 usb_flags_t             usb_flags);
  79 
  80         /*
  81          * pipe management
  82          */
  83         int     (*usba_hcdi_pipe_reset)(
  84                 usba_pipe_handle_data_t *pipe_handle,
  85                 usb_flags_t             usb_flags);
  86 
  87         /*
  88          * pipe management
  89          */
  90         void    (*usba_hcdi_pipe_reset_data_toggle)(
  91                 usba_pipe_handle_data_t *pipe_handle);
  92 
  93         /*
  94          * data transfer management
  95          */
  96         int     (*usba_hcdi_pipe_ctrl_xfer)(
  97                 usba_pipe_handle_data_t *pipe_handle,
  98                 usb_ctrl_req_t          *usb_ctrl_req,
  99                 usb_flags_t             usb_flags);
 100 
 101         /*
 102          * get HCD limitation on bulk xfer at a time?
 103          */
 104         int     (*usba_hcdi_bulk_transfer_size)(
 105                 usba_device_t           *usba_device,
 106                 size_t                  *size);
 107 
 108         /*
 109          * do bulk read/write
 110          */
 111         int     (*usba_hcdi_pipe_bulk_xfer)(
 112                 usba_pipe_handle_data_t *pipe_handle,
 113                 usb_bulk_req_t          *usb_bulk_req,
 114                 usb_flags_t             usb_flags);
 115 
 116         /*
 117          * do interrupt pipe read/write
 118          */
 119         int     (*usba_hcdi_pipe_intr_xfer)(
 120                 usba_pipe_handle_data_t *pipe_handle,
 121                 usb_intr_req_t          *usb_intr_req,
 122                 usb_flags_t             usb_flags);
 123 
 124         /*
 125          * stop interrupt pipe polling
 126          */
 127         int     (*usba_hcdi_pipe_stop_intr_polling)(
 128                 usba_pipe_handle_data_t *pipe_handle,
 129                 usb_flags_t             usb_flags);
 130 
 131         /*
 132          * do isoch pipe read/write
 133          */
 134         int     (*usba_hcdi_pipe_isoc_xfer)(
 135                 usba_pipe_handle_data_t *pipe_handle,
 136                 usb_isoc_req_t          *usb_isoc_req,
 137                 usb_flags_t             usb_flags);
 138 
 139         /*
 140          * stop isoc pipe polling
 141          */
 142         int     (*usba_hcdi_pipe_stop_isoc_polling)(
 143                 usba_pipe_handle_data_t *pipe_handle,
 144                 usb_flags_t             usb_flags);
 145 
 146         /* utility isoc functions */
 147         int     (*usba_hcdi_get_current_frame_number)(
 148                 usba_device_t           *usba_device,
 149                 usb_frame_number_t      *frame_number);
 150 
 151         int     (*usba_hcdi_get_max_isoc_pkts)(
 152                 usba_device_t           *usba_device,
 153                 uint_t                  *max_isoc_pkts_per_request);
 154 
 155         /*
 156          * Initialize OBP support for input
 157          */
 158         int     (*usba_hcdi_console_input_init)(
 159                 usba_pipe_handle_data_t         *pipe_handle,
 160                 uchar_t                         **obp_buf,
 161                 usb_console_info_impl_t         *console_input_info);
 162 
 163         /*
 164          * Free resources allocated by usba_hcdi_console_input_init
 165          */
 166         int     (*usba_hcdi_console_input_fini)(
 167                 usb_console_info_impl_t         *console_input_info);
 168 
 169         /*
 170          * Save controller state information
 171          */
 172         int     (*usba_hcdi_console_input_enter)(
 173                 usb_console_info_impl_t         *console_input_info);
 174 
 175         /*
 176          * Read character from controller
 177          */
 178         int     (*usba_hcdi_console_read)(
 179                 usb_console_info_impl_t         *console_input_info,
 180                 uint_t                          *num_characters);
 181 
 182         /*
 183          * Restore controller state information
 184          */
 185         int     (*usba_hcdi_console_input_exit)(
 186                 usb_console_info_impl_t         *console_input_info);
 187 
 188 
 189         /*
 190          * VERSION 1 ops: support for polled output
 191          */
 192         int     (*usba_hcdi_console_output_init)(
 193                 usba_pipe_handle_data_t         *pipe_handle,
 194                 usb_console_info_impl_t         *console_output_info);
 195 
 196         int     (*usba_hcdi_console_output_fini)(
 197                 usb_console_info_impl_t         *console_output_info);
 198 
 199         int     (*usba_hcdi_console_output_enter)(
 200                 usb_console_info_impl_t         *console_output_info);
 201 
 202         int     (*usba_hcdi_console_write)(
 203                 usb_console_info_impl_t         *console_output_info,
 204                 uchar_t                         *buf,
 205                 uint_t                          num_characters,
 206                 uint_t                          *num_characters_written);
 207 
 208         int     (*usba_hcdi_console_output_exit)(
 209                 usb_console_info_impl_t         *console_output_info);
 210 } usba_hcdi_ops_t;
 211 
 212 
 213 /*
 214  * callback support:
 215  *      this function handles all HCD callbacks as follows:
 216  *      - USB_FLAGS_SLEEP determines whether the client driver made
 217  *        a synchronous or asynchronous USBAI call
 218  *      - for synchronous calls, the args are copied into the pipe handle
 219  *              and the sync cv of the pipe handle is signalled
 220  *      - for async calls and completion_reason = 0, the normal callback
 221  *              is invoked
 222  *      - for async calls and completion_reason != 0, the exception
 223  *              callback is invoked
 224  */
 225 void
 226 usba_hcdi_cb(usba_pipe_handle_data_t    *ph,
 227                 usb_opaque_t            req,
 228                 usb_cr_t                completion_reason);
 229 
 230 /*
 231  * function to duplicate a interrupt/isoc request (for HCD)
 232  */
 233 usb_intr_req_t  *usba_hcdi_dup_intr_req(dev_info_t *,
 234                         usb_intr_req_t *, size_t, usb_flags_t);
 235 usb_isoc_req_t  *usba_hcdi_dup_isoc_req(dev_info_t *,
 236                         usb_isoc_req_t *, usb_flags_t);
 237 
 238 /* access to private member of requests */
 239 usb_opaque_t    usba_hcdi_get_req_private(usb_opaque_t);
 240 void            usba_hcdi_set_req_private(usb_opaque_t, usb_opaque_t);
 241 usba_pipe_handle_data_t *
 242                 usba_hcdi_get_ph_data(usba_device_t *, uint8_t);
 243 
 244 /* data toggle get and set */
 245 uchar_t         usba_hcdi_get_data_toggle(usba_device_t *, uint8_t);
 246 void            usba_hcdi_set_data_toggle(usba_device_t *, uint8_t, uchar_t);
 247 
 248 /*
 249  * HCD Nexus driver support:
 250  */
 251 
 252 /*
 253  * hcd_ops allocator/deallocator
 254  *      USBA allocates the usba_hcdi_ops so we can easily handle
 255  *      versioning
 256  */
 257 usba_hcdi_ops_t *usba_alloc_hcdi_ops();
 258 void            usba_free_hcdi_ops(usba_hcdi_ops_t *);
 259 
 260 /*
 261  * Argument structure for usba_hcdi_register
 262  */
 263 typedef struct usba_hcdi_register_args {
 264         uint_t                  usba_hcdi_register_version;
 265         dev_info_t              *usba_hcdi_register_dip;
 266         usba_hcdi_ops_t         *usba_hcdi_register_ops;
 267         ddi_dma_attr_t          *usba_hcdi_register_dma_attr;
 268         ddi_iblock_cookie_t     usba_hcdi_register_iblock_cookie;
 269 
 270 } usba_hcdi_register_args_t;
 271 
 272 #define HCDI_REGISTER_VERS_0            0
 273 #define HCDI_REGISTER_VERSION           HCDI_REGISTER_VERS_0
 274 
 275 
 276 /*
 277  * make this instance known to USBA
 278  *
 279  * the HCD must initialize the hcdi_ops before calling this function
 280  */
 281 int     usba_hcdi_register(usba_hcdi_register_args_t *, uint_t);
 282 
 283 /*
 284  * detach support
 285  */
 286 void    usba_hcdi_unregister(dev_info_t *);
 287 
 288 /*
 289  * Hotplug kstats named structure
 290  *
 291  * Number of types of USB transfers
 292  */
 293 #define USB_N_COUNT_KSTATS      4
 294 
 295 typedef struct hcdi_hotplug_stats {
 296         struct kstat_named      hcdi_hotplug_total_success;
 297         struct kstat_named      hcdi_hotplug_success;
 298         struct kstat_named      hcdi_hotplug_total_failure;
 299         struct kstat_named      hcdi_hotplug_failure;
 300         struct kstat_named      hcdi_device_count;
 301 } hcdi_hotplug_stats_t;
 302 
 303 /*
 304  * USB error kstats named structure
 305  */
 306 typedef struct hcdi_error_stats {
 307         /* transport completion codes */
 308         struct kstat_named      cc_crc;
 309         struct kstat_named      cc_bitstuffing;
 310         struct kstat_named      cc_data_toggle_mm;
 311         struct kstat_named      cc_stall;
 312         struct kstat_named      cc_dev_not_resp;
 313         struct kstat_named      cc_pid_checkfailure;
 314         struct kstat_named      cc_unexp_pid;
 315         struct kstat_named      cc_data_overrun;
 316         struct kstat_named      cc_data_underrun;
 317         struct kstat_named      cc_buffer_overrun;
 318         struct kstat_named      cc_buffer_underrun;
 319         struct kstat_named      cc_timeout;
 320         struct kstat_named      cc_not_accessed;
 321         struct kstat_named      cc_no_resources;
 322         struct kstat_named      cc_unspecified_err;
 323         struct kstat_named      cc_stopped_polling;
 324         struct kstat_named      cc_pipe_closing;
 325         struct kstat_named      cc_pipe_reset;
 326         struct kstat_named      cc_not_supported;
 327         struct kstat_named      cc_flushed;
 328 
 329 #ifdef  NOTYETNEEDED
 330         /* USBA function return values */
 331         struct kstat_named      hcdi_usb_failure;
 332         struct kstat_named      hcdi_usb_no_resources;
 333         struct kstat_named      hcdi_usb_no_bandwidth;
 334         struct kstat_named      hcdi_usb_pipe_reserved;
 335         struct kstat_named      hcdi_usb_pipe_unshareable;
 336         struct kstat_named      hcdi_usb_not_supported;
 337         struct kstat_named      hcdi_usb_pipe_error;
 338         struct kstat_named      hcdi_usb_pipe_busy;
 339 #endif
 340 } hcdi_error_stats_t;
 341 
 342 /*
 343  * hcdi kstat defines
 344  * XXX this needs to be a function
 345  */
 346 #define HCDI_HOTPLUG_STATS(hcdi)        ((hcdi)->hcdi_hotplug_stats)
 347 #define HCDI_HOTPLUG_STATS_DATA(hcdi)   \
 348         ((hcdi_hotplug_stats_t *)HCDI_HOTPLUG_STATS((hcdi))->ks_data)
 349 
 350 #define HCDI_ERROR_STATS(hcdi)          ((hcdi)->hcdi_error_stats)
 351 #define HCDI_ERROR_STATS_DATA(hcdi)     \
 352         ((hcdi_error_stats_t *)HCDI_ERROR_STATS((hcdi))->ks_data)
 353 
 354 
 355 #ifdef __cplusplus
 356 }
 357 #endif
 358 
 359 #endif  /* _SYS_USB_HCDI_H */