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