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 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #ifndef _SYS_USB_UHCID_H
  27 #define _SYS_USB_UHCID_H
  28 
  29 
  30 #ifdef __cplusplus
  31 extern "C" {
  32 #endif
  33 
  34 /*
  35  * Universal Host Controller Driver (UHCI)
  36  *
  37  * The UHCI driver is a driver which interfaces to the Universal
  38  * Serial Bus Driver (USBA) and the Host Controller (HC). The interface to
  39  * the Host Controller is defined by the Universal Host Controller Interface.
  40  *
  41  * This file contains the data structures for the UHCI driver.
  42  */
  43 #include <sys/types.h>
  44 #include <sys/pci.h>
  45 #include <sys/kstat.h>
  46 
  47 #include <sys/usb/usba/usbai_version.h>
  48 #include <sys/usb/usba.h>
  49 #include <sys/usb/usba/usba_types.h>
  50 
  51 #include <sys/usb/usba/genconsole.h>
  52 #include <sys/usb/usba/hcdi.h>
  53 
  54 #include <sys/usb/hubd/hub.h>
  55 #include <sys/usb/usba/hubdi.h>
  56 #include <sys/usb/hubd/hubdvar.h>
  57 
  58 #include <sys/usb/hcd/uhci/uhci.h>
  59 
  60 /* limit the xfer size for bulk */
  61 #define UHCI_BULK_MAX_XFER_SIZE (124*1024) /* Max bulk xfer size */
  62 
  63 /* Maximum allowable data transfer size per transaction */
  64 #define UHCI_MAX_TD_XFER_SIZE   0x500 /* Maximum data per transaction */
  65 
  66 /*
  67  * Generic UHCI Macro definitions
  68  */
  69 #define UHCI_UNDERRUN_OCCURRED  0x1234
  70 #define UHCI_OVERRUN_OCCURRED   0x5678
  71 #define UHCI_PROP_MASK          0x01000020
  72 #define UHCI_RESET_DELAY        15000
  73 #define UHCI_TIMEWAIT           10000
  74 
  75 #define MAX_SOF_WAIT_COUNT      2
  76 #define MAX_RH_PORTS            2
  77 #define DISCONNECTED            2
  78 #define POLLING_FREQ_7MS        7
  79 #define PCI_CONF_IOBASE         0x20
  80 #define PCI_CONF_IOBASE_MASK    0xffe0
  81 
  82 #define UHCI_ONE_SECOND         drv_usectohz(1000000)
  83 #define UHCI_ONE_MS             drv_usectohz(1000)
  84 #define UHCI_32_MS              drv_usectohz(32*1000)
  85 #define UHCI_256_MS             drv_usectohz(256*1000)
  86 #define UHCI_MAX_INSTS          4
  87 
  88 #define POLLED_RAW_BUF_SIZE     8
  89 
  90 /* Default time out values for bulk and ctrl commands */
  91 #define UHCI_CTRL_TIMEOUT       5
  92 #define UHCI_BULK_TIMEOUT       60
  93 
  94 /* UHCI root hub structure */
  95 typedef struct uhci_root_hub_info {
  96         uint_t                  rh_status;              /* Last RH status */
  97         uint_t                  rh_num_ports;           /* #ports on the root */
  98 
  99         /* Last status of ports */
 100         uint_t                  rh_port_status[MAX_RH_PORTS];
 101         uint_t                  rh_port_changes[MAX_RH_PORTS];
 102         uint_t                  rh_port_state[MAX_RH_PORTS]; /* See below */
 103 
 104         usba_pipe_handle_data_t *rh_intr_pipe_handle;   /* RH intr pipe hndle */
 105         usb_hub_descr_t         rh_descr;               /* RH descr's copy */
 106         uint_t                  rh_pipe_state;          /* RH intr pipe state */
 107 
 108         usb_intr_req_t          *rh_curr_intr_reqp;     /* Current intr req */
 109         usb_intr_req_t          *rh_client_intr_req;    /* save IN request */
 110 } uhci_root_hub_info_t;
 111 
 112 /*
 113  * UHCI Host Controller per instance data structure
 114  *
 115  * The Host Controller Driver (HCD) maintains the state of Host Controller
 116  * (HC). There is an uhci_state structure per instance  of the UHCI
 117  * host controller.
 118  */
 119 typedef struct uhci_state {
 120         dev_info_t              *uhci_dip;              /* dip of HC */
 121         uint_t                  uhci_instance;
 122         usba_hcdi_ops_t         *uhci_hcdi_ops;         /* HCDI structure */
 123 
 124         uint_t                  uhci_dma_addr_bind_flag;
 125 
 126         /* UHCI Host Controller Software State information */
 127         uint_t                  uhci_hc_soft_state;
 128 
 129         hc_regs_t               *uhci_regsp;            /* Host ctlr regs */
 130         ddi_acc_handle_t        uhci_regs_handle;       /* Reg handle */
 131 
 132         ddi_acc_handle_t        uhci_config_handle;     /* Config space hndle */
 133 
 134         /* Frame interval reg */
 135         uint_t                  uhci_frame_interval;
 136         ddi_dma_attr_t          uhci_dma_attr;          /* DMA attributes */
 137 
 138         ddi_intr_handle_t       *uhci_htable;           /* intr handle */
 139         int                     uhci_intr_type;         /* intr type used */
 140         int                     uhci_intr_cnt;          /* # of intrs inuse */
 141         uint_t                  uhci_intr_pri;          /* intr priority */
 142         int                     uhci_intr_cap;          /* intr capabilities */
 143         kmutex_t                uhci_int_mutex;         /* Mutex for struct */
 144 
 145         frame_lst_table_t       *uhci_frame_lst_tablep; /* Virtual HCCA ptr */
 146         uhci_td_t               *uhci_isoc_q_tailp[NUM_FRAME_LST_ENTRIES];
 147 
 148         ddi_dma_cookie_t        uhci_flt_cookie;        /* DMA cookie */
 149         ddi_dma_handle_t        uhci_flt_dma_handle;    /* DMA handle */
 150         ddi_acc_handle_t        uhci_flt_mem_handle;    /* Memory handle */
 151 
 152         /*
 153          * There are two pools of memory. One pool contains the memory for
 154          * the transfer descriptors and other pool contains the memory for
 155          * the Queue Head pointers. The advantage of the pools is that it's
 156          * easy to go back and forth between the iommu and the cpu addresses.
 157          *
 158          * The pools are protected by the int_mutex because the memory
 159          * in the pools may be accessed by either the host controller or the
 160          * host controller driver.
 161          */
 162 
 163         /* General transfer descriptor pool */
 164         uhci_td_t               *uhci_td_pool_addr;     /* Start of the pool */
 165         ddi_dma_cookie_t        uhci_td_pool_cookie;    /* DMA cookie */
 166         ddi_dma_handle_t        uhci_td_pool_dma_handle; /* DMA hndle */
 167         ddi_acc_handle_t        uhci_td_pool_mem_handle; /* Mem hndle */
 168 
 169         /* Endpoint descriptor pool */
 170         queue_head_t            *uhci_qh_pool_addr;     /* Start of the pool */
 171         ddi_dma_cookie_t        uhci_qh_pool_cookie;    /* DMA cookie */
 172         ddi_dma_handle_t        uhci_qh_pool_dma_handle; /* DMA handle */
 173         ddi_acc_handle_t        uhci_qh_pool_mem_handle; /* Mem handle */
 174 
 175         /* Semaphore to serialize opens and closes */
 176         ksema_t                 uhci_ocsem;
 177 
 178         /* Timeout id of the root hub status change pipe handler */
 179         timeout_id_t            uhci_timeout_id;
 180 
 181         /* Timeout id of the ctrl/bulk/intr xfers timeout */
 182         timeout_id_t            uhci_cmd_timeout_id;
 183 
 184         /*
 185          * Bandwidth fields
 186          *
 187          * The uhci_bandwidth array keeps track of the allocated bandwidth
 188          * for this host controller. The uhci_bandwidth_isoch_sum field
 189          * represents the sum of the allocated isochronous bandwidth. The
 190          * total bandwidth allocated for least allocated list out of the 32
 191          * interrupt lists is represented by the uhci_bandwdith_intr_min
 192          * field.
 193          */
 194         uint_t                  uhci_bandwidth[NUM_FRAME_LST_ENTRIES];
 195         uint_t                  uhci_bandwidth_isoch_sum;
 196         uint_t                  uhci_bandwidth_intr_min;
 197 
 198         uhci_root_hub_info_t    uhci_root_hub;  /* Root hub info */
 199 
 200         uhci_td_t               *uhci_outst_tds_head;
 201         uhci_td_t               *uhci_outst_tds_tail;
 202 
 203         queue_head_t            *uhci_ctrl_xfers_q_head;
 204         queue_head_t            *uhci_ctrl_xfers_q_tail;
 205         queue_head_t            *uhci_bulk_xfers_q_head;
 206         queue_head_t            *uhci_bulk_xfers_q_tail;
 207 
 208         kcondvar_t              uhci_cv_SOF;
 209         uchar_t                 uhci_cv_signal;
 210 
 211         /* Polled I/O support */
 212         frame_lst_table_t       uhci_polled_save_IntTble[1024];
 213         uint_t                  uhci_polled_count;
 214         uint32_t                uhci_polled_flag;
 215 
 216         /* Software frame number */
 217         usb_frame_number_t      uhci_sw_frnum;
 218 
 219         /* Number of pending bulk commands */
 220         uint32_t                uhci_pending_bulk_cmds;
 221 
 222         /* logging support */
 223         usb_log_handle_t        uhci_log_hdl;
 224 
 225         /*
 226          * TD's used for the generation of interrupt
 227          */
 228         queue_head_t            *uhci_isoc_qh;
 229         uhci_td_t               *uhci_sof_td;
 230         uhci_td_t               *uhci_isoc_td;
 231 
 232         /*
 233          * Keep io base address, for debugging purpose
 234          */
 235         uint_t                  uhci_iobase;
 236 
 237         /*
 238          * kstat structures
 239          */
 240         kstat_t                 *uhci_intrs_stats;
 241         kstat_t                 *uhci_total_stats;
 242         kstat_t                 *uhci_count_stats[USB_N_COUNT_KSTATS];
 243 } uhci_state_t;
 244 
 245 
 246 /*
 247  * uhci_dma_addr_bind_flag values
 248  *
 249  * This flag indicates if the various DMA addresses allocated by the UHCI
 250  * have been bound to their respective handles. This is needed to recover
 251  * without errors from uhci_cleanup when it calls ddi_dma_unbind_handle()
 252  */
 253 #define UHCI_TD_POOL_BOUND      0x01    /* for TD pools */
 254 #define UHCI_QH_POOL_BOUND      0x02    /* for QH pools */
 255 #define UHCI_FLA_POOL_BOUND     0x04    /* for Host Ctrlr Framelist Area */
 256 
 257 /*
 258  * Definitions for uhci_polled_flag
 259  * The flag is set to UHCI_POLLED_FLAG_FALSE by default. The flags is
 260  * set to UHCI_POLLED_FLAG_TD_COMPL when shifting from normal mode to
 261  * polled mode and if the normal TD is completed at that time. And the
 262  * flag is set to UHCI_POLLED_FLAG_TRUE while exiting from the polled
 263  * mode. In the timeout handler for root hub status change, this flag
 264  * is checked. If set to UHCI_POLLED_FLAG_TRUE, the routine
 265  * uhci_process_submitted_td_queue() to process the completed TD.
 266  */
 267 #define UHCI_POLLED_FLAG_FALSE          0
 268 #define UHCI_POLLED_FLAG_TRUE           1
 269 #define UHCI_POLLED_FLAG_TD_COMPL       2
 270 
 271 /*
 272  * Pipe private structure
 273  *
 274  * There is an instance of this structure per pipe.  This structure holds
 275  * HCD specific pipe information.  A pointer to this structure is kept in
 276  * the USBA pipe handle (usba_pipe_handle_data_t).
 277  */
 278 typedef struct uhci_pipe_private {
 279         usba_pipe_handle_data_t *pp_pipe_handle; /* Back ptr to pipe handle */
 280         queue_head_t            *pp_qh;         /* Pipe's ept */
 281         uint_t                  pp_state;       /* See below */
 282         usb_pipe_policy_t       pp_policy;      /* Copy of the pipe policy */
 283         uint_t                  pp_node;        /* Node in lattice */
 284         uchar_t                 pp_data_toggle; /* save data toggle bit */
 285 
 286         /*
 287          * Each pipe may have multiple transfer wrappers. Each transfer
 288          * wrapper represents a USB transfer on the bus.  A transfer is
 289          * made up of one or more transactions.
 290          */
 291         struct uhci_trans_wrapper *pp_tw_head;  /* Head of the list */
 292         struct uhci_trans_wrapper *pp_tw_tail;  /* Tail of the list */
 293 
 294         /*
 295          * Starting frame number at which next isoc TD will be inserted
 296          * for this pipe
 297          */
 298         uint64_t                pp_frame_num;
 299 
 300         /*
 301          * HCD gets Interrupt/Isochronous IN polling request only once and
 302          * it has to insert next polling requests after completion of first
 303          * request until either stop polling/pipe close is called. So  HCD
 304          * has to take copy of the original Interrupt/Isochronous IN request.
 305          */
 306         usb_opaque_t            pp_client_periodic_in_reqp;
 307 } uhci_pipe_private_t;
 308 
 309 /* warlock directives, stable data */
 310 _NOTE(MUTEX_PROTECTS_DATA(uhci_state_t::uhci_int_mutex, uhci_pipe_private_t))
 311 _NOTE(LOCK_ORDER(uhci_state::uhci_int_mutex \
 312                 usba_pipe_handle_data::p_mutex \
 313                 usba_device::usb_mutex \
 314                 usba_ph_impl::usba_ph_mutex))
 315 _NOTE(SCHEME_PROTECTS_DATA("private mutex", kstat_io))
 316 _NOTE(SCHEME_PROTECTS_DATA("unshared", usb_isoc_pkt_descr))
 317 
 318 /*
 319  * Pipe states
 320  *
 321  * uhci pipe states will be similar to usba. Refer usbai.h.
 322  */
 323 #define UHCI_PIPE_STATE_IDLE    1       /* Pipe has opened,ready state */
 324 #define UHCI_PIPE_STATE_ACTIVE  2       /* Polling the endpoint,busy state */
 325 
 326 /*
 327  * to indicate if we are in close/reset so that we can issue callbacks to
 328  * IN packets that are pending
 329  */
 330 #define UHCI_IN_CLOSE   4
 331 #define UHCI_IN_RESET   5
 332 #define UHCI_IN_ERROR   6
 333 
 334 /* Function prototype */
 335 typedef void (*uhci_handler_function_t) (uhci_state_t *uhcip, uhci_td_t  *td);
 336 
 337 /*
 338  * Transfer wrapper
 339  *
 340  * The transfer wrapper represents a USB transfer on the bus and there
 341  * is one instance per USB transfer.  A transfer is made up of one or
 342  * more transactions. UHCI uses one TD for one transaction. So one
 343  * transfer wrapper may have one or more TDs associated.
 344  *
 345  * Control and bulk pipes will have one transfer wrapper per transfer
 346  * and where as Isochronous and Interrupt pipes will only have one
 347  * transfer wrapper. The transfers wrapper are continually reused for
 348  * the Interrupt and Isochronous pipes as those pipes are polled.
 349  *
 350  * Control, bulk and interrupt transfers will have one DMA buffer per
 351  * transfer. The data to be transferred are contained in the DMA buffer
 352  * which is virtually contiguous but physically discontiguous. When
 353  * preparing the TDs for a USB transfer, the DMA cookies contained in
 354  * the buffer need to be walked through to retrieve the DMA addresses.
 355  *
 356  * Isochronous transfers will have multiple DMA buffers per transfer
 357  * with each isoc packet having a DMA buffer. And the DMA buffers should
 358  * only contain one cookie each, so no cookie walking is necessary.
 359  */
 360 typedef struct uhci_trans_wrapper {
 361         struct uhci_trans_wrapper       *tw_next;       /* Next wrapper */
 362         uhci_pipe_private_t             *tw_pipe_private;
 363         size_t                          tw_length;      /* Txfer length */
 364         uint_t                          tw_tmp;         /* Temp variable */
 365         ddi_dma_handle_t                tw_dmahandle;   /* DMA handle */
 366         ddi_acc_handle_t                tw_accesshandle; /* Acc hndle */
 367         char                            *tw_buf;        /* Buffer for txfer */
 368         ddi_dma_cookie_t                tw_cookie;      /* DMA cookie */
 369         uint_t                          tw_ncookies;    /* DMA cookie count */
 370         uint_t                          tw_cookie_idx;  /* DMA cookie index */
 371         size_t                          tw_dma_offs;    /* DMA buffer offset */
 372         int                             tw_ctrl_state;  /* See below */
 373         uhci_td_t                       *tw_hctd_head;  /* Head TD */
 374         uhci_td_t                       *tw_hctd_tail;  /* Tail TD */
 375         uint_t                          tw_direction;   /* Direction of TD */
 376         usb_flags_t                     tw_flags;       /* Flags */
 377 
 378         /*
 379          * This is the function to call when this td is done. This way
 380          * we don't have to look in the td to figure out what kind it is.
 381          */
 382         uhci_handler_function_t         tw_handle_td;
 383 
 384         /*
 385          * This is the callback value used when processing a done td.
 386          */
 387         usb_opaque_t                    tw_handle_callback_value;
 388 
 389         uint_t                          tw_bytes_xfered;
 390         uint_t                          tw_bytes_pending;
 391 
 392         /* Maximum amount of time for this command */
 393         uint_t                          tw_timeout_cnt;
 394 
 395         usb_isoc_req_t                  *tw_isoc_req;
 396         uhci_bulk_isoc_xfer_t           tw_xfer_info;
 397         uhci_isoc_buf_t                 *tw_isoc_bufs;  /* Isoc DMA buffers */
 398         size_t                          tw_isoc_strtlen;
 399 
 400         /* This is used to avoid multiple tw deallocation */
 401         uint_t                          tw_claim;
 402 
 403         /*
 404          * Pointer to the data in case of send command
 405          */
 406         mblk_t                          *tw_data;
 407 
 408         /* save a copy of current request */
 409         usb_opaque_t                    tw_curr_xfer_reqp;
 410 } uhci_trans_wrapper_t;
 411 
 412 /* Macros for uhci DMA buffer */
 413 #define UHCI_DMA_ATTR_ALIGN     0x800
 414 #define UHCI_DMA_ATTR_SGLLEN    0x7fffffff
 415 #define UHCI_CTRL_EPT_MAX_SIZE  64
 416 
 417 /*
 418  * Macro for allocation of Bulk and Isoc TD pools
 419  *
 420  * When a Bulk or Isoc transfer needs to allocate too many TDs,
 421  * the allocation for one physical contiguous TD pool may fail
 422  * due to the fragmentation of physical memory. The number of
 423  * TDs in one pool should be limited so that a TD pool is within
 424  * page size under this situation.
 425  */
 426 #if defined(__sparc)
 427 #define UHCI_MAX_TD_NUM_PER_POOL        88
 428 #else
 429 #define UHCI_MAX_TD_NUM_PER_POOL        44
 430 #endif
 431 
 432 /* set timeout flag so as to decrement timeout_cnt only once */
 433 #define TW_TIMEOUT_FLAG         0x1000
 434 
 435 /* Macro for changing the data toggle */
 436 #define ADJ_DATA_TOGGLE(pp) \
 437                 (pp)->pp_data_toggle = ((pp)->pp_data_toggle == 0) ? 1 : 0;
 438 
 439 /*
 440  * Macros for setting/getting information
 441  */
 442 #define Get_OpReg32(addr)       ddi_get32(uhcip->uhci_regs_handle, \
 443                                     (uint32_t *)&uhcip->uhci_regsp->addr)
 444 #define Get_OpReg16(addr)       ddi_get16(uhcip->uhci_regs_handle, \
 445                                     (uint16_t *)&uhcip->uhci_regsp->addr)
 446 #define Get_OpReg8(addr)        ddi_get8(uhcip->uhci_regs_handle, \
 447                                     (uchar_t *)&uhcip->uhci_regsp->addr)
 448 
 449 #define Set_OpReg32(addr, val)   ddi_put32(uhcip->uhci_regs_handle, \
 450                                     ((uint32_t *)&uhcip->uhci_regsp->addr), \
 451                                     ((int32_t)(val)))
 452 #define Set_OpReg16(addr, val)   ddi_put16(uhcip->uhci_regs_handle, \
 453                                     ((uint16_t *)&uhcip->uhci_regsp->addr), \
 454                                     ((int16_t)(val)))
 455 
 456 #define QH_PADDR(addr) \
 457                 ((uint32_t)(uhcip->uhci_qh_pool_cookie.dmac_address + \
 458                 (uint32_t)((uintptr_t)(addr) - \
 459                 (uintptr_t)uhcip->uhci_qh_pool_addr)))
 460 
 461 
 462 #define QH_VADDR(addr) \
 463                 ((void *)(((uint32_t)(addr) - \
 464                 (uint32_t)uhcip->uhci_qh_pool_cookie.dmac_address) + \
 465                 (char *)uhcip->uhci_qh_pool_addr))
 466 
 467 #define TD_PADDR(addr)  \
 468                 ((uint32_t)uhcip->uhci_td_pool_cookie.dmac_address + \
 469                 (uint32_t)((uintptr_t)(addr) - \
 470                 (uintptr_t)(uhcip->uhci_td_pool_addr)))
 471 
 472 #define BULKTD_PADDR(x, addr)\
 473                 ((uint32_t)((uintptr_t)(addr) - (uintptr_t)x->pool_addr) + \
 474                 (uint32_t)(x)->cookie.dmac_address)
 475 
 476 #define BULKTD_VADDR(x, addr)\
 477                 ((void *)(((uint32_t)(addr) - \
 478                 (uint32_t)(x)->cookie.dmac_address) + \
 479                 (char *)(x)->pool_addr))
 480 
 481 #define ISOCTD_PADDR(x, addr)\
 482                 ((uint32_t)((uintptr_t)(addr) - (uintptr_t)(x)->pool_addr) + \
 483                 (uint32_t)(x)->cookie.dmac_address)
 484 
 485 #define TD_VADDR(addr) \
 486                 ((void *)(((uint32_t)(addr) - \
 487                 (uint32_t)uhcip->uhci_td_pool_cookie.dmac_address) + \
 488                 (char *)uhcip->uhci_td_pool_addr))
 489 
 490 /*
 491  * If the terminate bit is cleared, there shouldn't be any
 492  * race condition problems. If the host controller reads the
 493  * bit before the driver has a chance to set the bit, the bit
 494  * will be reread on the next frame.
 495  */
 496 #define UHCI_SET_TERMINATE_BIT(addr)    \
 497         SetQH32(uhcip, addr, GetQH32(uhcip, (addr)) | HC_END_OF_LIST)
 498 #define UHCI_CLEAR_TERMINATE_BIT(addr)  \
 499         SetQH32(uhcip, addr, GetQH32(uhcip, (addr)) & ~HC_END_OF_LIST)
 500 
 501 #define UHCI_XFER_TYPE(ept)             ((ept)->bmAttributes & USB_EP_ATTR_MASK)
 502 #define UHCI_XFER_DIR(ept)              ((ept)->bEndpointAddress & \
 503                                                 USB_EP_DIR_MASK)
 504 
 505 /*
 506  * for HCD based kstats:
 507  * uhci_intrs_stats_t structure
 508  */
 509 typedef struct uhci_intrs_stats {
 510         struct kstat_named      uhci_intrs_hc_halted;
 511         struct kstat_named      uhci_intrs_hc_process_err;
 512         struct kstat_named      uhci_intrs_host_sys_err;
 513         struct kstat_named      uhci_intrs_resume_detected;
 514         struct kstat_named      uhci_intrs_usb_err_intr;
 515         struct kstat_named      uhci_intrs_usb_intr;
 516         struct kstat_named      uhci_intrs_total;
 517         struct kstat_named      uhci_intrs_not_claimed;
 518 } uhci_intrs_stats_t;
 519 
 520 /*
 521  * uhci defines for kstats
 522  */
 523 #define UHCI_INTRS_STATS(uhci)  ((uhci)->uhci_intrs_stats)
 524 #define UHCI_INTRS_STATS_DATA(uhci)     \
 525         ((uhci_intrs_stats_t *)UHCI_INTRS_STATS((uhci))->ks_data)
 526 
 527 #define UHCI_TOTAL_STATS(uhci)          ((uhci)->uhci_total_stats)
 528 #define UHCI_TOTAL_STATS_DATA(uhci)     (KSTAT_IO_PTR((uhci)->uhci_total_stats))
 529 #define UHCI_CTRL_STATS(uhci)   \
 530                 (KSTAT_IO_PTR((uhci)->uhci_count_stats[USB_EP_ATTR_CONTROL]))
 531 #define UHCI_BULK_STATS(uhci)   \
 532                 (KSTAT_IO_PTR((uhci)->uhci_count_stats[USB_EP_ATTR_BULK]))
 533 #define UHCI_INTR_STATS(uhci)   \
 534                 (KSTAT_IO_PTR((uhci)->uhci_count_stats[USB_EP_ATTR_INTR]))
 535 #define UHCI_ISOC_STATS(uhci)   \
 536                 (KSTAT_IO_PTR((uhci)->uhci_count_stats[USB_EP_ATTR_ISOCH]))
 537 
 538 #define UHCI_UNIT(dev)  (getminor((dev)) & ~HUBD_IS_ROOT_HUB)
 539 
 540 #define UHCI_PERIODIC_ENDPOINT(ept) \
 541         (((((ept)->bmAttributes) & USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) || \
 542         ((((ept)->bmAttributes) & USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH))
 543 
 544 /*
 545  * Host Contoller Software States
 546  *
 547  * UHCI_CTLR_INIT_STATE:
 548  *      The host controller soft state will be set to this during the
 549  *      uhci_attach.
 550  *
 551  * UHCI_CTLR_SUSPEND_STATE:
 552  *      The host controller soft state will be set to this during the
 553  *      uhci_cpr_suspend.
 554  *
 555  * UHCI_CTLR_OPERATIONAL_STATE:
 556  *      The host controller soft state will be set to this after moving
 557  *      host controller to operational state and host controller start
 558  *      generating SOF successfully.
 559  *
 560  * UHCI_CTLR_ERROR_STATE:
 561  *      The host controller soft state will be set to this during the
 562  *      hardware error or no SOF conditions.
 563  *
 564  *      Under non-operational state, only pipe stop polling, pipe reset
 565  *      and pipe close are allowed. But all other entry points like pipe
 566  *      open, get/set pipe policy, cotrol send/receive, bulk send/receive
 567  *      isoch send/receive, start polling etc. will fail.
 568  */
 569 #define UHCI_CTLR_INIT_STATE            0       /* Initilization state */
 570 #define UHCI_CTLR_SUSPEND_STATE         1       /* Suspend state */
 571 #define UHCI_CTLR_OPERATIONAL_STATE     2       /* Operational state */
 572 #define UHCI_CTLR_ERROR_STATE           3       /* Hardware error */
 573 
 574 /*
 575  * Debug printing Masks
 576  */
 577 #define PRINT_MASK_ATTA         0x00000001      /* Attach time */
 578 #define PRINT_MASK_LISTS        0x00000002      /* List management */
 579 #define PRINT_MASK_ROOT_HUB     0x00000004      /* Root hub stuff */
 580 #define PRINT_MASK_ALLOC        0x00000008      /* Alloc/dealloc descr */
 581 #define PRINT_MASK_INTR         0x00000010      /* Interrupt handling */
 582 #define PRINT_MASK_BW           0x00000020      /* Bandwidth */
 583 #define PRINT_MASK_CBOPS        0x00000040      /* CB-OPS */
 584 #define PRINT_MASK_HCDI         0x00000080      /* HCDI entry points */
 585 #define PRINT_MASK_DUMPING      0x00000100      /* Dump HCD state info */
 586 #define PRINT_MASK_ISOC         0x00000200      /* For ISOC xfers */
 587 
 588 #define PRINT_MASK_ALL          0xFFFFFFFF
 589 
 590 #ifdef __cplusplus
 591 }
 592 #endif
 593 
 594 #endif  /* _SYS_USB_UHCID_H */