17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
502acac7eSsl  * Common Development and Distribution License (the "License").
602acac7eSsl  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*9b58c2adSzhigang lu - Sun Microsystems - Beijing China  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef _SYS_USB_OHCID_H
277c478bd9Sstevel@tonic-gate #define	_SYS_USB_OHCID_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
307c478bd9Sstevel@tonic-gate extern "C" {
317c478bd9Sstevel@tonic-gate #endif
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate /*
347c478bd9Sstevel@tonic-gate  * Open Host Controller Driver (OHCI)
357c478bd9Sstevel@tonic-gate  *
367c478bd9Sstevel@tonic-gate  * The USB Open Host Controller driver is a software driver which interfaces
377c478bd9Sstevel@tonic-gate  * to the Universal Serial Bus layer (USBA) and the USB Open Host Controller.
387c478bd9Sstevel@tonic-gate  * The interface to USB Open Host Controller is defined by the OpenHCI  Host
397c478bd9Sstevel@tonic-gate  * Controller Interface.
407c478bd9Sstevel@tonic-gate  *
417c478bd9Sstevel@tonic-gate  * This header file describes the data structures required for the USB Open
427c478bd9Sstevel@tonic-gate  * Host Controller Driver to maintain state of USB Open Host Controller, to
437c478bd9Sstevel@tonic-gate  * perform different USB transfers and for the bandwidth allocations.
447c478bd9Sstevel@tonic-gate  */
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #include <sys/usb/hcd/openhci/ohci.h>
477c478bd9Sstevel@tonic-gate #include <sys/usb/hcd/openhci/ohci_hub.h>
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate /*
507c478bd9Sstevel@tonic-gate  * OpenHCI interrupt status information structure
517c478bd9Sstevel@tonic-gate  *
527c478bd9Sstevel@tonic-gate  * The Host Controller Driver (HCD) has to maintain two different sets of
537c478bd9Sstevel@tonic-gate  * Host Controller (HC) state information that includes HC registers, the
547c478bd9Sstevel@tonic-gate  * interrupt tables etc.. for the normal and polled modes.  In	addition,
557c478bd9Sstevel@tonic-gate  * suppose if we switched to polled mode while ohci  interrupt handler is
567c478bd9Sstevel@tonic-gate  * executing in the normal mode then we need to save the interrupt status
577c478bd9Sstevel@tonic-gate  * information that includes interrupts for which ohci interrupt  handler
587c478bd9Sstevel@tonic-gate  * is called and HCCA done head list in the polled mode. This infromation
597c478bd9Sstevel@tonic-gate  * will be used later in normal mode to  service those missed interrupts.
607c478bd9Sstevel@tonic-gate  * This will avoid race conditions like missing of normal mode's ohci SOF
617c478bd9Sstevel@tonic-gate  * and WriteDoneHead interrupts because of this polled switch.
627c478bd9Sstevel@tonic-gate  */
637c478bd9Sstevel@tonic-gate typedef struct ohci_save_intr_sts {
647c478bd9Sstevel@tonic-gate 	/*
657c478bd9Sstevel@tonic-gate 	 * The following field has set of flags & these flags will be set
667c478bd9Sstevel@tonic-gate 	 * in the ohci interrupt handler to indicate that currently  ohci
677c478bd9Sstevel@tonic-gate 	 * interrupt handler is in execution and also while critical code
687c478bd9Sstevel@tonic-gate 	 * execution within the ohci interrupt handler.  These flags will
697c478bd9Sstevel@tonic-gate 	 * be verified in polled mode while saving the normal mode's ohci
707c478bd9Sstevel@tonic-gate 	 * interrupt status information.
717c478bd9Sstevel@tonic-gate 	 */
727c478bd9Sstevel@tonic-gate 	uint_t		ohci_intr_flag;		/* Intr handler flags */
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate 	/*
757c478bd9Sstevel@tonic-gate 	 * The following fields will be used to save the interrupt status
767c478bd9Sstevel@tonic-gate 	 * and the HCCA done head list that the ohci interrupt handler is
777c478bd9Sstevel@tonic-gate 	 * currently handling.
787c478bd9Sstevel@tonic-gate 	 */
797c478bd9Sstevel@tonic-gate 	uint_t		ohci_curr_intr_sts;	/* Current interrupts */
807c478bd9Sstevel@tonic-gate 	ohci_td_t	*ohci_curr_done_lst;	/* Current done head  */
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 	/*
837c478bd9Sstevel@tonic-gate 	 * The following fields will be used to save the interrupt status
847c478bd9Sstevel@tonic-gate 	 * and the HCCA done list currently being handled by the critical
857c478bd9Sstevel@tonic-gate 	 * section of the ohci interrupt handler..
867c478bd9Sstevel@tonic-gate 	 */
877c478bd9Sstevel@tonic-gate 	uint_t		ohci_critical_intr_sts;	/* Critical interrupts */
887c478bd9Sstevel@tonic-gate 	ohci_td_t	*ohci_critical_done_lst; /* Critical done head */
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 	/*
917c478bd9Sstevel@tonic-gate 	 * The following fields will be used to save the interrupt status
927c478bd9Sstevel@tonic-gate 	 * and HCCA done head list by the polled code if an  interrupt is
937c478bd9Sstevel@tonic-gate 	 * pending when polled code is entered. These missed interrupts &
947c478bd9Sstevel@tonic-gate 	 * done list will be serviced either in current  normal mode ohci
957c478bd9Sstevel@tonic-gate 	 * interrupt handler execution or during the next  ohci interrupt
967c478bd9Sstevel@tonic-gate 	 * handler execution.
977c478bd9Sstevel@tonic-gate 	 */
987c478bd9Sstevel@tonic-gate 	uint_t		ohci_missed_intr_sts;	/* Missed interrupts */
997c478bd9Sstevel@tonic-gate 	ohci_td_t	*ohci_missed_done_lst;	/* Missed done head  */
1007c478bd9Sstevel@tonic-gate } ohci_save_intr_sts_t;
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate /*
1037c478bd9Sstevel@tonic-gate  * These flags will be set in the the normal mode ohci	interrupt handler
1047c478bd9Sstevel@tonic-gate  * to indicate that currently ohci interrupt handler is in  execution and
1057c478bd9Sstevel@tonic-gate  * also while critical code  execution within the ohci interrupt handler.
1067c478bd9Sstevel@tonic-gate  * These flags will be verified in the polled mode while saving the normal
1077c478bd9Sstevel@tonic-gate  * mode's ohci interrupt status infromation.
1087c478bd9Sstevel@tonic-gate  */
1097c478bd9Sstevel@tonic-gate #define		OHCI_INTR_HANDLING	0x01	/* Handling ohci intrs */
1107c478bd9Sstevel@tonic-gate #define		OHCI_INTR_CRITICAL	0x02	/* Critical intr code  */
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate /*
1147c478bd9Sstevel@tonic-gate  * OpenHCI Host Controller state structure
1157c478bd9Sstevel@tonic-gate  *
1167c478bd9Sstevel@tonic-gate  * The Host Controller Driver (HCD) maintains the state of Host Controller
1177c478bd9Sstevel@tonic-gate  * (HC). There is an ohci_state structure per instance	of the OpenHCI
1187c478bd9Sstevel@tonic-gate  * host controller.
1197c478bd9Sstevel@tonic-gate  */
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate typedef struct ohci_state {
1227c478bd9Sstevel@tonic-gate 	dev_info_t		*ohci_dip;		/* Dip of HC */
1237c478bd9Sstevel@tonic-gate 	uint_t			ohci_instance;
1247c478bd9Sstevel@tonic-gate 	usba_hcdi_ops_t		*ohci_hcdi_ops;		/* HCDI structure */
1257c478bd9Sstevel@tonic-gate 	uint_t			ohci_flags;		/* Used for cleanup */
1267c478bd9Sstevel@tonic-gate 	uint16_t		ohci_vendor_id;		/* chip vendor */
1277c478bd9Sstevel@tonic-gate 	uint16_t		ohci_device_id;		/* chip device */
1287c478bd9Sstevel@tonic-gate 	uint8_t			ohci_rev_id;		/* chip revison */
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 	ohci_regs_t		*ohci_regsp;		/* Host ctlr regs */
1317c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t	ohci_regs_handle;	/* Reg handle */
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t	ohci_config_handle;	/* Config space hndle */
1347c478bd9Sstevel@tonic-gate 	uint_t			ohci_frame_interval;	/* Frme inter reg */
1357c478bd9Sstevel@tonic-gate 	ddi_dma_attr_t		ohci_dma_attr;		/* DMA attributes */
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 	ddi_intr_handle_t	*ohci_htable;		/* intr handle */
1389c75c6bfSgovinda 	int			ohci_intr_type;		/* intr type used */
1399c75c6bfSgovinda 	int			ohci_intr_cnt;		/* # of intrs inuse */
1407c478bd9Sstevel@tonic-gate 	uint_t			ohci_intr_pri;		/* intr priority */
1419c75c6bfSgovinda 	int			ohci_intr_cap;		/* intr capabilities */
142af95cb89Szhigang lu - Sun Microsystems - Beijing China 	boolean_t		ohci_msi_enabled;	/* default to true */
1437c478bd9Sstevel@tonic-gate 	kmutex_t		ohci_int_mutex;		/* Mutex for struct */
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	/* HCCA area */
1467c478bd9Sstevel@tonic-gate 	ohci_hcca_t		*ohci_hccap;		/* Virtual HCCA ptr */
1477c478bd9Sstevel@tonic-gate 	ddi_dma_cookie_t	ohci_hcca_cookie;	/* DMA cookie */
1487c478bd9Sstevel@tonic-gate 	ddi_dma_handle_t	ohci_hcca_dma_handle;	/* DMA handle */
1497c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t	ohci_hcca_mem_handle;	/* Memory handle */
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 	/*
1527c478bd9Sstevel@tonic-gate 	 * There are two pools of memory. One pool contains the memory for
1537c478bd9Sstevel@tonic-gate 	 * the transfer descriptors and other pool contains the memory for
1547c478bd9Sstevel@tonic-gate 	 * the endpoint descriptors. The advantage of the pools is that it's
1557c478bd9Sstevel@tonic-gate 	 * easy to go back and forth between the iommu and the cpu addresses.
1567c478bd9Sstevel@tonic-gate 	 *
1577c478bd9Sstevel@tonic-gate 	 * The pools are protected by the ohci_int_mutex because the memory
1587c478bd9Sstevel@tonic-gate 	 * in the pools may be accessed by either the host controller or the
1597c478bd9Sstevel@tonic-gate 	 * host controller driver.
1607c478bd9Sstevel@tonic-gate 	 */
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 	/* General transfer descriptor pool */
1637c478bd9Sstevel@tonic-gate 	ohci_td_t		*ohci_td_pool_addr;	/* Start of the pool */
1647c478bd9Sstevel@tonic-gate 	ddi_dma_cookie_t	ohci_td_pool_cookie;	/* DMA cookie */
1657c478bd9Sstevel@tonic-gate 	ddi_dma_handle_t	ohci_td_pool_dma_handle;	/* DMA hndle */
1667c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t	ohci_td_pool_mem_handle;	/* Mem hndle */
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 	/* Endpoint descriptor pool */
1697c478bd9Sstevel@tonic-gate 	ohci_ed_t		*ohci_ed_pool_addr;	/* Start of the pool */
1707c478bd9Sstevel@tonic-gate 	ddi_dma_cookie_t	ohci_ed_pool_cookie;	/* DMA cookie */
1717c478bd9Sstevel@tonic-gate 	ddi_dma_handle_t	ohci_ed_pool_dma_handle;	/* DMA handle */
1727c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t	ohci_ed_pool_mem_handle;	/* Mem handle */
1737c478bd9Sstevel@tonic-gate 	uint_t			ohci_dma_addr_bind_flag;	/* DMA flag */
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 	/* Condition variables */
1767c478bd9Sstevel@tonic-gate 	kcondvar_t		ohci_SOF_cv;		/* SOF variable */
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	/* Semaphore to serialize opens and closes */
1797c478bd9Sstevel@tonic-gate 	ksema_t			ohci_ocsem;
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 	/*
1827c478bd9Sstevel@tonic-gate 	 * Bandwidth fields
1837c478bd9Sstevel@tonic-gate 	 *
1847c478bd9Sstevel@tonic-gate 	 * The ohci_bandwidth array keeps track of the allocated bandwidth
1857c478bd9Sstevel@tonic-gate 	 * for this host controller. The total bandwidth allocated for least
1867c478bd9Sstevel@tonic-gate 	 * allocated list out of the 32 periodic lists is represented by the
1877c478bd9Sstevel@tonic-gate 	 * ohci_periodic_minimum_bandwidth field.
1887c478bd9Sstevel@tonic-gate 	 */
1897c478bd9Sstevel@tonic-gate 	uint_t			ohci_periodic_minimum_bandwidth;
1907c478bd9Sstevel@tonic-gate 	uint_t			ohci_periodic_bandwidth[NUM_INTR_ED_LISTS];
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	/* Different transfer open pipe counts */
1937c478bd9Sstevel@tonic-gate 	uint_t			ohci_open_pipe_count;
1947c478bd9Sstevel@tonic-gate 	uint_t			ohci_open_ctrl_pipe_count;
1957c478bd9Sstevel@tonic-gate 	uint_t			ohci_open_bulk_pipe_count;
1967c478bd9Sstevel@tonic-gate 	uint_t			ohci_open_periodic_pipe_count;
1977c478bd9Sstevel@tonic-gate 	uint_t			ohci_open_isoch_pipe_count;
1987c478bd9Sstevel@tonic-gate 	/*
1997c478bd9Sstevel@tonic-gate 	 * Endpoint Reclamation List
2007c478bd9Sstevel@tonic-gate 	 *
2017c478bd9Sstevel@tonic-gate 	 * The interrupt or isochronous list processing cannot be stopped
2027c478bd9Sstevel@tonic-gate 	 * when a periodic endpoint is removed from the list. The endpoints
2037c478bd9Sstevel@tonic-gate 	 * are detached from the interrupt lattice tree and put on to the
2047c478bd9Sstevel@tonic-gate 	 * reclaimation list. On next SOF interrupt all those endpoints,
2057c478bd9Sstevel@tonic-gate 	 * which are on the reclaimation list will be deallocated.
2067c478bd9Sstevel@tonic-gate 	 */
2077c478bd9Sstevel@tonic-gate 	ohci_ed_t		*ohci_reclaim_list;	/* Reclaimation list */
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	ohci_root_hub_t		ohci_root_hub;		/* Root hub info */
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	/*
2127c478bd9Sstevel@tonic-gate 	 * Global transfer timeout handling & this transfer timeout handling
2137c478bd9Sstevel@tonic-gate 	 * will be per USB Host Controller.
2147c478bd9Sstevel@tonic-gate 	 */
2157c478bd9Sstevel@tonic-gate 	struct ohci_trans_wrapper *ohci_timeout_list;	/* Timeout List */
2167c478bd9Sstevel@tonic-gate 	timeout_id_t		ohci_timer_id;		/* Timer id  */
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	/* Frame number overflow information */
2197c478bd9Sstevel@tonic-gate 	usb_frame_number_t	ohci_fno;
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate 	/* For Schedule Overrun error counter */
2227c478bd9Sstevel@tonic-gate 	uint_t			ohci_so_error;
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	/* For host controller error counter */
2257c478bd9Sstevel@tonic-gate 	uint_t			ohci_hc_error;
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 	/* For SOF interrupt event */
2287c478bd9Sstevel@tonic-gate 	boolean_t		ohci_sof_flag;
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	/* Openhci Host Controller Software State information */
2317c478bd9Sstevel@tonic-gate 	uint_t			ohci_hc_soft_state;
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 	/*
2347c478bd9Sstevel@tonic-gate 	 * ohci_save_intr_stats is used to save the normal mode interrupt
2357c478bd9Sstevel@tonic-gate 	 * status information while executing interrupt handler & also by
2367c478bd9Sstevel@tonic-gate 	 * the polled code if an interrupt is pending for the normal mode
2377c478bd9Sstevel@tonic-gate 	 * when polled code is entered.
2387c478bd9Sstevel@tonic-gate 	 */
2397c478bd9Sstevel@tonic-gate 	ohci_save_intr_sts_t	ohci_save_intr_sts;
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate 	/*
2427c478bd9Sstevel@tonic-gate 	 * Saved copy of the ohci registers of the normal mode & change
2437c478bd9Sstevel@tonic-gate 	 * required ohci registers values for the polled mode operation.
2447c478bd9Sstevel@tonic-gate 	 * Before returning from the polled mode to normal mode replace
2457c478bd9Sstevel@tonic-gate 	 * the required current registers with this saved ohci registers
2467c478bd9Sstevel@tonic-gate 	 * copy.
2477c478bd9Sstevel@tonic-gate 	 */
2487c478bd9Sstevel@tonic-gate 	ohci_regs_t	ohci_polled_save_regs;
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 	/*
2517c478bd9Sstevel@tonic-gate 	 * Saved copy of the interrupt table used in normal ohci mode and
2527c478bd9Sstevel@tonic-gate 	 * replace this table by another interrupt table that used in the
2537c478bd9Sstevel@tonic-gate 	 * POLLED mode.
2547c478bd9Sstevel@tonic-gate 	 */
2557c478bd9Sstevel@tonic-gate 	ohci_ed_t	*ohci_polled_save_IntTble[NUM_INTR_ED_LISTS];
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 	/* ohci polled mode enter counter for the input devices */
2587c478bd9Sstevel@tonic-gate 	uint_t			ohci_polled_enter_count;
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 	/*
2617c478bd9Sstevel@tonic-gate 	 * Counter for polled mode and used in suspend mode to see if
2627c478bd9Sstevel@tonic-gate 	 * there is a input device connected.
2637c478bd9Sstevel@tonic-gate 	 */
2647c478bd9Sstevel@tonic-gate 	uint_t			ohci_polled_kbd_count;
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 	/* Done list for the Polled mode */
2677c478bd9Sstevel@tonic-gate 	ohci_td_t		*ohci_polled_done_list;
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 	/* Log handle for debug, console, log messages */
2707c478bd9Sstevel@tonic-gate 	usb_log_handle_t	ohci_log_hdl;
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate 	/* Kstat structures */
2737c478bd9Sstevel@tonic-gate 	kstat_t			*ohci_intrs_stats;
2747c478bd9Sstevel@tonic-gate 	kstat_t			*ohci_total_stats;
2757c478bd9Sstevel@tonic-gate 	kstat_t			*ohci_count_stats[USB_N_COUNT_KSTATS];
2767c478bd9Sstevel@tonic-gate } ohci_state_t;
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate typedef struct ohci_intrs_stats {
2797c478bd9Sstevel@tonic-gate 	struct kstat_named	ohci_hcr_intr_so;
2807c478bd9Sstevel@tonic-gate 	struct kstat_named	ohci_hcr_intr_wdh;
2817c478bd9Sstevel@tonic-gate 	struct kstat_named	ohci_hcr_intr_sof;
2827c478bd9Sstevel@tonic-gate 	struct kstat_named	ohci_hcr_intr_rd;
2837c478bd9Sstevel@tonic-gate 	struct kstat_named	ohci_hcr_intr_ue;
2847c478bd9Sstevel@tonic-gate 	struct kstat_named	ohci_hcr_intr_fno;
2857c478bd9Sstevel@tonic-gate 	struct kstat_named	ohci_hcr_intr_rhsc;
2867c478bd9Sstevel@tonic-gate 	struct kstat_named	ohci_hcr_intr_oc;
2877c478bd9Sstevel@tonic-gate 	struct kstat_named	ohci_hcr_intr_not_claimed;
2887c478bd9Sstevel@tonic-gate 	struct kstat_named	ohci_hcr_intr_total;
2897c478bd9Sstevel@tonic-gate } ohci_intrs_stats_t;
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate /*
2927c478bd9Sstevel@tonic-gate  * ohci kstat defines
2937c478bd9Sstevel@tonic-gate  */
2947c478bd9Sstevel@tonic-gate #define	OHCI_INTRS_STATS(ohci)	((ohci)->ohci_intrs_stats)
2957c478bd9Sstevel@tonic-gate #define	OHCI_INTRS_STATS_DATA(ohci)	\
2967c478bd9Sstevel@tonic-gate 	((ohci_intrs_stats_t *)OHCI_INTRS_STATS((ohci))->ks_data)
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate #define	OHCI_TOTAL_STATS(ohci)	((ohci)->ohci_total_stats)
2997c478bd9Sstevel@tonic-gate #define	OHCI_TOTAL_STATS_DATA(ohci)	(KSTAT_IO_PTR((ohci)->ohci_total_stats))
3007c478bd9Sstevel@tonic-gate #define	OHCI_CTRL_STATS(ohci)	\
3017c478bd9Sstevel@tonic-gate 	(KSTAT_IO_PTR((ohci)->ohci_count_stats[USB_EP_ATTR_CONTROL]))
3027c478bd9Sstevel@tonic-gate #define	OHCI_BULK_STATS(ohci)	\
3037c478bd9Sstevel@tonic-gate 	(KSTAT_IO_PTR((ohci)->ohci_count_stats[USB_EP_ATTR_BULK]))
3047c478bd9Sstevel@tonic-gate #define	OHCI_INTR_STATS(ohci)	\
3057c478bd9Sstevel@tonic-gate 	(KSTAT_IO_PTR((ohci)->ohci_count_stats[USB_EP_ATTR_INTR]))
3067c478bd9Sstevel@tonic-gate #define	OHCI_ISOC_STATS(ohci)	\
3077c478bd9Sstevel@tonic-gate 	(KSTAT_IO_PTR((ohci)->ohci_count_stats[USB_EP_ATTR_ISOCH]))
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate /* warlock directives, stable data */
3107c478bd9Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ohci_state_t::ohci_int_mutex, ohci_state_t))
3117c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_intr_pri))
3127c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_dip))
3137c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_regsp))
3147c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_instance))
3157c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_vendor_id))
3167c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_device_id))
3177c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_rev_id))
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate /* this may not be stable data in the future */
3207c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_td_pool_addr))
3217c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_td_pool_mem_handle))
3227c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_ed_pool_addr))
3237c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_ed_pool_mem_handle))
3247c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_td_pool_cookie))
3257c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_ed_pool_cookie))
3267c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_hcca_mem_handle))
3277c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_hccap))
3287c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_dma_addr_bind_flag))
3297c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(ohci_state_t::ohci_log_hdl))
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate _NOTE(LOCK_ORDER(ohci_state::ohci_int_mutex \
3327c478bd9Sstevel@tonic-gate 		usba_pipe_handle_data::p_mutex \
3337c478bd9Sstevel@tonic-gate 		usba_device::usb_mutex \
3347c478bd9Sstevel@tonic-gate 		usba_ph_impl::usba_ph_mutex))
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate /*
3377c478bd9Sstevel@tonic-gate  * Host Contoller Software States
3387c478bd9Sstevel@tonic-gate  *
3397c478bd9Sstevel@tonic-gate  * OHCI_CTLR_INIT_STATE:
3407c478bd9Sstevel@tonic-gate  *	The host controller soft state will be set to this during the
3417c478bd9Sstevel@tonic-gate  *	ohci_attach.
3427c478bd9Sstevel@tonic-gate  *
3437c478bd9Sstevel@tonic-gate  * OHCI_CTLR_SUSPEND_STATE:
3447c478bd9Sstevel@tonic-gate  *	The host controller soft state will be set to this during the
3457c478bd9Sstevel@tonic-gate  *	ohci_cpr_suspend.
3467c478bd9Sstevel@tonic-gate  *
3477c478bd9Sstevel@tonic-gate  * OHCI_CTLR_OPERATIONAL_STATE:
3487c478bd9Sstevel@tonic-gate  *	The host controller soft state will be set to this after moving
3497c478bd9Sstevel@tonic-gate  *	host controller to operational state and host controller start
3507c478bd9Sstevel@tonic-gate  *	generating SOF successfully.
3517c478bd9Sstevel@tonic-gate  *
3527c478bd9Sstevel@tonic-gate  * OHCI_CTLR_ERROR_STATE:
3537c478bd9Sstevel@tonic-gate  *	The host controller soft state will be set to this during the
3547c478bd9Sstevel@tonic-gate  *	no SOF or UE error conditions.
3557c478bd9Sstevel@tonic-gate  *
3567c478bd9Sstevel@tonic-gate  *	Under this state or condition, only pipe stop polling, pipe reset
3577c478bd9Sstevel@tonic-gate  *	and pipe close are allowed. But all other entry points like  pipe
3587c478bd9Sstevel@tonic-gate  *	open, get/set pipe policy, cotrol send/receive, bulk send/receive
3597c478bd9Sstevel@tonic-gate  *	isoch send/receive, start polling etc. will fail.
3607c478bd9Sstevel@tonic-gate  *
3617c478bd9Sstevel@tonic-gate  * State Diagram for the host controller software state
3627c478bd9Sstevel@tonic-gate  *
3637c478bd9Sstevel@tonic-gate  *
3647c478bd9Sstevel@tonic-gate  * ohci_attach->[INIT_STATE]
3657c478bd9Sstevel@tonic-gate  *	|
3667c478bd9Sstevel@tonic-gate  *	|	-------->----[ERROR_STATE]--<-----------<---
3677c478bd9Sstevel@tonic-gate  *	|      |      Failure (UE/no SOF condition)	    |
3687c478bd9Sstevel@tonic-gate  *	|      ^					    ^
3697c478bd9Sstevel@tonic-gate  *	V      |      Success				    |
3707c478bd9Sstevel@tonic-gate  * ohci_init_ctlr--->--------[OPERATIONAL_STATE]------>-ohci_send/recv/polling
3717c478bd9Sstevel@tonic-gate  *	^					    |
3727c478bd9Sstevel@tonic-gate  *	|					    |
3737c478bd9Sstevel@tonic-gate  *	|					    V
3747c478bd9Sstevel@tonic-gate  *	-<-ohci_cpr_resume--[SUSPEND_STATE]-<-ohci_cpr_suspend
3757c478bd9Sstevel@tonic-gate  */
3767c478bd9Sstevel@tonic-gate #define	OHCI_CTLR_INIT_STATE		0	/* Initilization state */
3777c478bd9Sstevel@tonic-gate #define	OHCI_CTLR_SUSPEND_STATE		1	/* Suspend state */
3787c478bd9Sstevel@tonic-gate #define	OHCI_CTLR_OPERATIONAL_STATE	2	/* Operational state */
3797c478bd9Sstevel@tonic-gate #define	OHCI_CTLR_ERROR_STATE		3	/* Ue error or no sof state */
3807c478bd9Sstevel@tonic-gate 
3817c478bd9Sstevel@tonic-gate /*
3827c478bd9Sstevel@tonic-gate  * Define all ohci's Vendor-id and Device-id Here
3837c478bd9Sstevel@tonic-gate  */
3847c478bd9Sstevel@tonic-gate #define	RIO_VENDOR	0x108e
3857c478bd9Sstevel@tonic-gate #define	RIO_DEVICE	0x1103
3867c478bd9Sstevel@tonic-gate #define	OHCI_IS_RIO(ohcip)	(ohcip->ohci_vendor_id == RIO_VENDOR)
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate /*
3897c478bd9Sstevel@tonic-gate  * Periodic and non-periodic macros
3907c478bd9Sstevel@tonic-gate  */
3917c478bd9Sstevel@tonic-gate #define	OHCI_PERIODIC_ENDPOINT(endpoint) (((endpoint->bmAttributes &\
3927c478bd9Sstevel@tonic-gate 				USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) ||\
3937c478bd9Sstevel@tonic-gate 				((endpoint->bmAttributes &\
3947c478bd9Sstevel@tonic-gate 				USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH))
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate #define	OHCI_NON_PERIODIC_ENDPOINT(endpoint) (((endpoint->bmAttributes &\
3977c478bd9Sstevel@tonic-gate 				USB_EP_ATTR_MASK) == USB_EP_ATTR_CONTROL) ||\
3987c478bd9Sstevel@tonic-gate 				((endpoint->bmAttributes &\
3997c478bd9Sstevel@tonic-gate 				USB_EP_ATTR_MASK) == USB_EP_ATTR_BULK))
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate /*
4027c478bd9Sstevel@tonic-gate  * OHCI ED and TD Pool sizes.
4037c478bd9Sstevel@tonic-gate  */
4047c478bd9Sstevel@tonic-gate #define	OHCI_ED_POOL_SIZE	100
4057c478bd9Sstevel@tonic-gate #define	OHCI_TD_POOL_SIZE	200
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate /*
4087c478bd9Sstevel@tonic-gate  * ohci_dma_addr_bind_flag values
4097c478bd9Sstevel@tonic-gate  *
4107c478bd9Sstevel@tonic-gate  * This flag indicates if the various DMA addresses allocated by the OHCI
4117c478bd9Sstevel@tonic-gate  * have been bound to their respective handles. This is needed to recover
4127c478bd9Sstevel@tonic-gate  * without errors from ohci_cleanup when it calls ddi_dma_unbind_handle()
4137c478bd9Sstevel@tonic-gate  */
4147c478bd9Sstevel@tonic-gate #define	OHCI_TD_POOL_BOUND	0x01	/* For TD pools  */
4157c478bd9Sstevel@tonic-gate #define	OHCI_ED_POOL_BOUND	0x02	/* For ED pools  */
4167c478bd9Sstevel@tonic-gate #define	OHCI_HCCA_DMA_BOUND	0x04	/* For HCCA area */
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate /*
4197c478bd9Sstevel@tonic-gate  * Maximum SOF wait count
4207c478bd9Sstevel@tonic-gate  */
4217c478bd9Sstevel@tonic-gate #define	MAX_SOF_WAIT_COUNT	2	/* Wait for maximum SOF frames */
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate /*
4257c478bd9Sstevel@tonic-gate  * Pipe private structure
4267c478bd9Sstevel@tonic-gate  *
4277c478bd9Sstevel@tonic-gate  * There is an instance of this structure per pipe.  This structure holds
4287c478bd9Sstevel@tonic-gate  * HCD specific pipe information.  A pointer to this structure is kept in
4297c478bd9Sstevel@tonic-gate  * the USBA pipe handle (usba_pipe_handle_data_t).
4307c478bd9Sstevel@tonic-gate  */
4317c478bd9Sstevel@tonic-gate typedef struct ohci_pipe_private {
4327c478bd9Sstevel@tonic-gate 	usba_pipe_handle_data_t	*pp_pipe_handle;	/* Back ptr to handle */
4337c478bd9Sstevel@tonic-gate 	ohci_ed_t		*pp_ept;		/* Pipe's ept */
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate 	/* State of the pipe */
4367c478bd9Sstevel@tonic-gate 	uint_t			pp_state;		/* See below */
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 	/* Local copy of the pipe policy */
4397c478bd9Sstevel@tonic-gate 	usb_pipe_policy_t	pp_policy;
4407c478bd9Sstevel@tonic-gate 
4417c478bd9Sstevel@tonic-gate 	/* For Periodic Pipes Only */
4427c478bd9Sstevel@tonic-gate 	uint_t			pp_node;		/* Node in lattice */
4437c478bd9Sstevel@tonic-gate 	uint_t			pp_cur_periodic_req_cnt; /* Curr req count */
4447c478bd9Sstevel@tonic-gate 	uint_t			pp_max_periodic_req_cnt; /* Max req count */
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate 	/* For isochronous pipe only */
4477c478bd9Sstevel@tonic-gate 	usb_frame_number_t	pp_next_frame_number;	/* Next frame no */
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate 	/*
4507c478bd9Sstevel@tonic-gate 	 * Each pipe may have multiple transfer wrappers. Each transfer
4517c478bd9Sstevel@tonic-gate 	 * wrapper represents a USB transfer on the bus.  A transfer is
4527c478bd9Sstevel@tonic-gate 	 * made up of one or more transactions.
4537c478bd9Sstevel@tonic-gate 	 */
4547c478bd9Sstevel@tonic-gate 	struct ohci_trans_wrapper *pp_tw_head;	/* Head of the list */
4557c478bd9Sstevel@tonic-gate 	struct ohci_trans_wrapper *pp_tw_tail;	/* Tail of the list */
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate 	/* Done td count */
4587c478bd9Sstevel@tonic-gate 	uint_t			pp_count_done_tds;	/* Done td count */
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate 	/* Errors */
4617c478bd9Sstevel@tonic-gate 	usb_cr_t		pp_error;		/* Pipe error */
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate 	/* Flags */
4647c478bd9Sstevel@tonic-gate 	uint_t			pp_flag;		/* Flags */
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 	/* Condition variable for transfers completion event */
4677c478bd9Sstevel@tonic-gate 	kcondvar_t		pp_xfer_cmpl_cv;	/* Xfer completion */
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 	/*
4707c478bd9Sstevel@tonic-gate 	 * HCD gets Interrupt/Isochronous IN polling request only once and
4717c478bd9Sstevel@tonic-gate 	 * it has to insert next polling requests after completion of first
4727c478bd9Sstevel@tonic-gate 	 * request until either stop polling/pipe close is called. So  HCD
4737c478bd9Sstevel@tonic-gate 	 * has to take copy of the original Interrupt/Isochronous IN request.
4747c478bd9Sstevel@tonic-gate 	 */
4757c478bd9Sstevel@tonic-gate 	usb_opaque_t		pp_client_periodic_in_reqp;
4767c478bd9Sstevel@tonic-gate } ohci_pipe_private_t;
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate /* warlock directives, stable data */
4797c478bd9Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ohci_state_t::ohci_int_mutex, ohci_pipe_private_t))
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate /*
4827c478bd9Sstevel@tonic-gate  * Pipe states
4837c478bd9Sstevel@tonic-gate  *
4847c478bd9Sstevel@tonic-gate  * ohci pipe states will be similar to usba. Refer usbai.h.
4857c478bd9Sstevel@tonic-gate  */
4867c478bd9Sstevel@tonic-gate #define	OHCI_PIPE_STATE_IDLE		1	/* Pipe is in ready state */
4877c478bd9Sstevel@tonic-gate #define	OHCI_PIPE_STATE_ACTIVE		2	/* Pipe is in busy state */
4887c478bd9Sstevel@tonic-gate #define	OHCI_PIPE_STATE_ERROR		3	/* Pipe is in error state */
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate /* Additional ohci pipe states for the ohci_pipe_cleanup */
4917c478bd9Sstevel@tonic-gate #define	OHCI_PIPE_STATE_CLOSE		4	/* Pipe close */
4927c478bd9Sstevel@tonic-gate #define	OHCI_PIPE_STATE_RESET		5	/* Pipe reset */
4937c478bd9Sstevel@tonic-gate #define	OHCI_PIPE_STATE_STOP_POLLING	6	/* Pipe stop polling */
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate /*
4967c478bd9Sstevel@tonic-gate  * Pipe specific Flags
4977c478bd9Sstevel@tonic-gate  */
4987c478bd9Sstevel@tonic-gate #define	OHCI_ISOC_XFER_CONTINUE	1	/* For isoc transfers */
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate /*
5017c478bd9Sstevel@tonic-gate  * The maximum allowable usb isochronous data transfer size or maximum
5027c478bd9Sstevel@tonic-gate  * number of isochronous data packets.
5037c478bd9Sstevel@tonic-gate  *
5047c478bd9Sstevel@tonic-gate  * Each usb isochronous request must not exceed multiples of isochronous
5057c478bd9Sstevel@tonic-gate  * endpoint packet size and OHCI_MAX_ISOC_PKTS_PER_XFER.
5067c478bd9Sstevel@tonic-gate  *
5077c478bd9Sstevel@tonic-gate  * Ex: usb isochronous endpoint maximum packet size is 64 bytes
5087c478bd9Sstevel@tonic-gate  *     maximum usb isochronous request will be OHCI_MAX_ISOC_PKTS_PER_XFER
5097c478bd9Sstevel@tonic-gate  *     * 64 bytes
5107c478bd9Sstevel@tonic-gate  */
5117c478bd9Sstevel@tonic-gate #define		OHCI_MAX_ISOC_PKTS_PER_XFER	256	/* Max pkts per req */
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate /*
5147c478bd9Sstevel@tonic-gate  * The ohci supports maximum of eight isochronous data packets per transfer
5157c478bd9Sstevel@tonic-gate  * descriptor.
5167c478bd9Sstevel@tonic-gate  */
5177c478bd9Sstevel@tonic-gate #define		OHCI_ISOC_PKTS_PER_TD		8	/* Packets per TD */
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate /*
5207c478bd9Sstevel@tonic-gate  * USB frame offset
5217c478bd9Sstevel@tonic-gate  *
5227c478bd9Sstevel@tonic-gate  * Add appropriate frame offset to the current usb frame number and use it
5237c478bd9Sstevel@tonic-gate  * as a starting frame number for a given usb isochronous request.
5247c478bd9Sstevel@tonic-gate  */
5257c478bd9Sstevel@tonic-gate #define		OHCI_FRAME_OFFSET		2	/* Frame offset */
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate /*
5287c478bd9Sstevel@tonic-gate  * Default usb isochronous receive packets per request before ohci will do
5297c478bd9Sstevel@tonic-gate  * callback.
5307c478bd9Sstevel@tonic-gate  */
5317c478bd9Sstevel@tonic-gate #define		OHCI_DEFAULT_ISOC_RCV_PKTS	1	/* isoc pkts per req */
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate /*
5347c478bd9Sstevel@tonic-gate  * Different interrupt polling intervals supported
5357c478bd9Sstevel@tonic-gate  */
5367c478bd9Sstevel@tonic-gate #define		INTR_1MS_POLL	1
5377c478bd9Sstevel@tonic-gate #define		INTR_2MS_POLL	2
5387c478bd9Sstevel@tonic-gate #define		INTR_4MS_POLL	4
5397c478bd9Sstevel@tonic-gate #define		INTR_8MS_POLL	8
5407c478bd9Sstevel@tonic-gate #define		INTR_16MS_POLL	16
5417c478bd9Sstevel@tonic-gate #define		INTR_32MS_POLL	32
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate /*
5447c478bd9Sstevel@tonic-gate  * Number of interrupt/isochronous transfer requests that should
5457c478bd9Sstevel@tonic-gate  * be maintained on the interrupt/isochronous endpoint corresponding
5467c478bd9Sstevel@tonic-gate  * to different polling intervals supported.
5477c478bd9Sstevel@tonic-gate  */
5487c478bd9Sstevel@tonic-gate #define		INTR_1MS_REQS	4	/* 1ms polling interval */
5497c478bd9Sstevel@tonic-gate #define		INTR_2MS_REQS	2	/* 2ms polling interval */
5507c478bd9Sstevel@tonic-gate #define		INTR_XMS_REQS	1	/* Between 4ms and 32ms */
5517c478bd9Sstevel@tonic-gate 
5527c478bd9Sstevel@tonic-gate /* Function prototype */
5537c478bd9Sstevel@tonic-gate typedef void (*ohci_handler_function_t)(
5547c478bd9Sstevel@tonic-gate 	ohci_state_t			*ohcip,
5557c478bd9Sstevel@tonic-gate 	ohci_pipe_private_t		*pp,
5567c478bd9Sstevel@tonic-gate 	struct ohci_trans_wrapper	*tw,
5577c478bd9Sstevel@tonic-gate 	ohci_td_t			*td,
5587c478bd9Sstevel@tonic-gate 	void				*ohci_handle_callback_value);
5597c478bd9Sstevel@tonic-gate 
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate /*
5627c478bd9Sstevel@tonic-gate  * Transfer wrapper
5637c478bd9Sstevel@tonic-gate  *
5647c478bd9Sstevel@tonic-gate  * The transfer wrapper represents a USB transfer on the bus and there
5657c478bd9Sstevel@tonic-gate  * is one instance per USB transfer.  A transfer is made up of one or
56602acac7eSsl  * more transactions. OHCI uses one TD for one transaction. So one
56702acac7eSsl  * transfer wrapper may have one or more TDs associated.
5687c478bd9Sstevel@tonic-gate  *
5697c478bd9Sstevel@tonic-gate  * Control and bulk pipes will have one transfer wrapper per transfer
5707c478bd9Sstevel@tonic-gate  * and where as Isochronous and Interrupt pipes will only have one
5717c478bd9Sstevel@tonic-gate  * transfer wrapper. The transfers wrapper are continually reused for
5727c478bd9Sstevel@tonic-gate  * the Interrupt and Isochronous pipes as those pipes are polled.
57302acac7eSsl  *
57402acac7eSsl  * Control, bulk and interrupt transfers will have one DMA buffer per
57502acac7eSsl  * transfer. The data to be transferred are contained in the DMA buffer
57602acac7eSsl  * which is virtually contiguous but physically discontiguous. When
57702acac7eSsl  * preparing the TDs for a USB transfer, the DMA cookies contained in
57802acac7eSsl  * the buffer need to be walked through to retrieve the DMA addresses.
57902acac7eSsl  *
58002acac7eSsl  * Isochronous transfers may have multiple DMA buffers per transfer
58102acac7eSsl  * with each isoc TD having a DMA buffer. And one isoc TD may hold up to
58202acac7eSsl  * eight isoc packets, but two cookies at most.
5837c478bd9Sstevel@tonic-gate  */
5847c478bd9Sstevel@tonic-gate typedef struct ohci_trans_wrapper {
5857c478bd9Sstevel@tonic-gate 	struct ohci_trans_wrapper	*tw_next;	/* Next wrapper */
5867c478bd9Sstevel@tonic-gate 	ohci_pipe_private_t		*tw_pipe_private; /* Back ptr */
5877c478bd9Sstevel@tonic-gate 	ddi_dma_handle_t		tw_dmahandle;	/* DMA handle */
5887c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t		tw_accesshandle; /* Acc hndle */
5897c478bd9Sstevel@tonic-gate 	ddi_dma_cookie_t		tw_cookie;	/* DMA cookie */
5907c478bd9Sstevel@tonic-gate 	uint32_t			tw_id;		/* 32bit ID */
5917c478bd9Sstevel@tonic-gate 	size_t				tw_length;	/* Txfer length */
5927c478bd9Sstevel@tonic-gate 	char				*tw_buf;	/* Buffer for Xfer */
59302acac7eSsl 	uint_t				tw_ncookies;	/* DMA cookie count */
59402acac7eSsl 	uint_t				tw_cookie_idx;	/* DMA cookie index */
59502acac7eSsl 	size_t				tw_dma_offs;	/* DMA buffer offset */
5967c478bd9Sstevel@tonic-gate 	usb_flags_t			tw_flags;	/* Flags */
5977c478bd9Sstevel@tonic-gate 	uint_t				tw_num_tds;	/* Number of TDs */
5987c478bd9Sstevel@tonic-gate 	ohci_td_t			*tw_hctd_head;	/* Head TD */
5997c478bd9Sstevel@tonic-gate 	ohci_td_t			*tw_hctd_tail;	/* Tail TD */
6007c478bd9Sstevel@tonic-gate 	uint_t				tw_direction;	/* Direction of TD */
601b3001defSlg 	uint_t				tw_pkt_idx;	/* packet index */
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate 	/* We preallocate all the td's for each tw and place them here */
6047c478bd9Sstevel@tonic-gate 	ohci_td_t			*tw_hctd_free_list;
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 	/* Current transfer request pointer */
6077c478bd9Sstevel@tonic-gate 	usb_opaque_t			tw_curr_xfer_reqp;
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate 	/* Current isochronous packet descriptor pointer */
6107c478bd9Sstevel@tonic-gate 	usb_isoc_pkt_descr_t		*tw_curr_isoc_pktp;
6117c478bd9Sstevel@tonic-gate 
61202acac7eSsl 	/* Isochronous DMA handlers and buffer pointers are stored here */
61302acac7eSsl 	ohci_isoc_buf_t			*tw_isoc_bufs;
61402acac7eSsl 	size_t				tw_isoc_strtlen;
61502acac7eSsl 
6167c478bd9Sstevel@tonic-gate 	/* Transfer timeout information */
6177c478bd9Sstevel@tonic-gate 	uint_t				tw_timeout;	/* Timeout value */
6187c478bd9Sstevel@tonic-gate 	struct ohci_trans_wrapper	*tw_timeout_next; /* Xfer Timeout Q */
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate 	/*
6217c478bd9Sstevel@tonic-gate 	 * This is the function to call when this td is done. This way
6227c478bd9Sstevel@tonic-gate 	 * we don't have to look in the td to figure out what kind it is.
6237c478bd9Sstevel@tonic-gate 	 */
6247c478bd9Sstevel@tonic-gate 	ohci_handler_function_t		tw_handle_td;
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate 	/*
6277c478bd9Sstevel@tonic-gate 	 * This is the callback value used when processing a done td.
6287c478bd9Sstevel@tonic-gate 	 */
6297c478bd9Sstevel@tonic-gate 	usb_opaque_t			tw_handle_callback_value;
6307c478bd9Sstevel@tonic-gate } ohci_trans_wrapper_t;
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ohci_state_t::ohci_int_mutex, ohci_trans_wrapper))
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate 
6357c478bd9Sstevel@tonic-gate /*
6367c478bd9Sstevel@tonic-gate  * Time waits for the different OHCI specific operations.
6377c478bd9Sstevel@tonic-gate  * These timeout values are specified in terms of microseconds.
6387c478bd9Sstevel@tonic-gate  */
6397c478bd9Sstevel@tonic-gate #define	OHCI_RESET_TIMEWAIT	10000	/* HC reset waiting time */
6407c478bd9Sstevel@tonic-gate #define	OHCI_RESUME_TIMEWAIT	40000	/* HC resume waiting time */
6417c478bd9Sstevel@tonic-gate #define	OHCI_TIMEWAIT		10000	/* HC any other waiting time */
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate /* These timeout values are specified in seconds */
6447c478bd9Sstevel@tonic-gate #define	OHCI_DEFAULT_XFER_TIMEOUT	5 /* Default transfer timeout */
6457c478bd9Sstevel@tonic-gate #define	OHCI_MAX_SOF_TIMEWAIT		3 /* Maximum SOF waiting time */
6467c478bd9Sstevel@tonic-gate #define	OHCI_XFER_CMPL_TIMEWAIT		3 /* Xfers completion timewait */
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate /* OHCI flags for general use */
6497c478bd9Sstevel@tonic-gate #define	OHCI_FLAGS_NOSLEEP	0x000	/* Don't wait for SOF */
6507c478bd9Sstevel@tonic-gate #define	OHCI_FLAGS_SLEEP	0x100	/* Wait for SOF */
6517c478bd9Sstevel@tonic-gate #define	OHCI_FLAGS_DMA_SYNC	0x200	/* Call ddi_dma_sync */
6527c478bd9Sstevel@tonic-gate 
6537c478bd9Sstevel@tonic-gate /*
6547c478bd9Sstevel@tonic-gate  * Maximum allowable data transfer  size per transaction as supported
6557c478bd9Sstevel@tonic-gate  * by OHCI is 8k. (See Open Host Controller Interface Spec rev 1.0a)
6567c478bd9Sstevel@tonic-gate  */
6577c478bd9Sstevel@tonic-gate #define	OHCI_MAX_TD_XFER_SIZE	0x2000	/* Maxmum data per transaction */
6587c478bd9Sstevel@tonic-gate 
65902acac7eSsl /*
66002acac7eSsl  * One OHCI TD allows two physically discontiguous pages. The page size
66102acac7eSsl  * is 4k.
66202acac7eSsl  */
66302acac7eSsl #define	OHCI_MAX_TD_BUF_SIZE	0x1000
66402acac7eSsl 
6657c478bd9Sstevel@tonic-gate /*
6667c478bd9Sstevel@tonic-gate  * The maximum allowable bulk data transfer size. It can be different
6677c478bd9Sstevel@tonic-gate  * from OHCI_MAX_TD_XFER_SIZE and if it is more then ohci driver will
6687c478bd9Sstevel@tonic-gate  * take care of  breaking a bulk data request into  multiples of ohci
6697c478bd9Sstevel@tonic-gate  * OHCI_MAX_TD_XFER_SIZE  until request is satisfied.  Currently this
6707c478bd9Sstevel@tonic-gate  * value is set to 256k bytes.
6717c478bd9Sstevel@tonic-gate  */
6727c478bd9Sstevel@tonic-gate #define	OHCI_MAX_BULK_XFER_SIZE	0x40000	/* Maximum bulk transfer size */
6737c478bd9Sstevel@tonic-gate 
6747c478bd9Sstevel@tonic-gate /*
6757c478bd9Sstevel@tonic-gate  * Timeout flags
6767c478bd9Sstevel@tonic-gate  *
6777c478bd9Sstevel@tonic-gate  * These flags will be used to stop the timer before timeout handler
6787c478bd9Sstevel@tonic-gate  * gets executed.
6797c478bd9Sstevel@tonic-gate  */
6807c478bd9Sstevel@tonic-gate #define	OHCI_REMOVE_XFER_IFLAST	1	/* Stop the timer if  it is last TD */
6817c478bd9Sstevel@tonic-gate #define	OHCI_REMOVE_XFER_ALWAYS	2	/* Stop the timer without condition */
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate /*
6857c478bd9Sstevel@tonic-gate  * Bandwidth allocation
6867c478bd9Sstevel@tonic-gate  *
6877c478bd9Sstevel@tonic-gate  * The following definitions are  used during  bandwidth calculations
6887c478bd9Sstevel@tonic-gate  * for a given endpoint maximum packet size.
6897c478bd9Sstevel@tonic-gate  */
6907c478bd9Sstevel@tonic-gate #define	MAX_USB_BUS_BANDWIDTH	1500	/* Up to 1500 bytes per frame */
6917c478bd9Sstevel@tonic-gate #define	MAX_POLL_INTERVAL	255	/* Maximum polling interval */
6927c478bd9Sstevel@tonic-gate #define	MIN_POLL_INTERVAL	1	/* Minimum polling interval */
6937c478bd9Sstevel@tonic-gate #define	SOF			6	/* Length in bytes of SOF */
6947c478bd9Sstevel@tonic-gate #define	EOF			4	/* Length in bytes of EOF */
6957c478bd9Sstevel@tonic-gate #define	TREE_HEIGHT		5	/* Log base 2 of 32 */
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate /*
6987c478bd9Sstevel@tonic-gate  * Minimum polling interval for low speed endpoint
6997c478bd9Sstevel@tonic-gate  *
7007c478bd9Sstevel@tonic-gate  * According USB Specifications, a full-speed endpoint can specify
7017c478bd9Sstevel@tonic-gate  * a desired polling interval 1ms to 255ms and a low speed endpoints
7027c478bd9Sstevel@tonic-gate  * are limited to specifying only 10ms to 255ms. But some old keyboards
7037c478bd9Sstevel@tonic-gate  * and mice uses polling interval of 8ms. For compatibility purpose,
7047c478bd9Sstevel@tonic-gate  * we are using polling interval between 8ms and 255ms for low speed
7057c478bd9Sstevel@tonic-gate  * endpoints. But ohci driver will reject any low speed endpoints which
7067c478bd9Sstevel@tonic-gate  * request polling interval less than 8ms.
7077c478bd9Sstevel@tonic-gate  */
7087c478bd9Sstevel@tonic-gate #define	MIN_LOW_SPEED_POLL_INTERVAL	8
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate /*
7117c478bd9Sstevel@tonic-gate  * For non-periodic transfers, reserve atleast for one low-speed device
7127c478bd9Sstevel@tonic-gate  * transaction. According to USB Bandwidth Analysis white paper and also
7137c478bd9Sstevel@tonic-gate  * as per OHCI Specification 1.0a, section 7.3.5, page 123, one low-speed
7147c478bd9Sstevel@tonic-gate  * transaction takes 0x628h full speed bits (197 bytes), which comes to
7157c478bd9Sstevel@tonic-gate  * around 13% of USB frame time.
7167c478bd9Sstevel@tonic-gate  *
7177c478bd9Sstevel@tonic-gate  * The periodic transfers will  get around 87% of USB frame time.
7187c478bd9Sstevel@tonic-gate  */
7197c478bd9Sstevel@tonic-gate #define	MAX_NON_PERIODIC_BANDWIDTH	197
7207c478bd9Sstevel@tonic-gate #define	MAX_PERIODIC_BANDWIDTH		(MAX_USB_BUS_BANDWIDTH - SOF - \
7217c478bd9Sstevel@tonic-gate 					EOF - MAX_NON_PERIODIC_BANDWIDTH)
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate /*
7247c478bd9Sstevel@tonic-gate  * The USB periodic transfers like interrupt and isochronous transfers
7257c478bd9Sstevel@tonic-gate  * after completion of SOF and USB non-periodic transfers.
7267c478bd9Sstevel@tonic-gate  */
7277c478bd9Sstevel@tonic-gate #define	PERIODIC_XFER_STARTS		(MAX_USB_BUS_BANDWIDTH - \
7287c478bd9Sstevel@tonic-gate 					SOF - MAX_NON_PERIODIC_BANDWIDTH)
7297c478bd9Sstevel@tonic-gate 
7307c478bd9Sstevel@tonic-gate /* Number of Bits Per Byte */
7317c478bd9Sstevel@tonic-gate #define	BITS_PER_BYTE			8
7327c478bd9Sstevel@tonic-gate 
7337c478bd9Sstevel@tonic-gate /*
7347c478bd9Sstevel@tonic-gate  * The following are the protocol overheads in terms of Bytes for the
7357c478bd9Sstevel@tonic-gate  * different transfer types.  All these protocol overhead  values are
7367c478bd9Sstevel@tonic-gate  * derived from the 5.9.3 section of USB Specification	and  with the
7377c478bd9Sstevel@tonic-gate  * help of Bandwidth Analysis white paper which is posted on the  USB
7387c478bd9Sstevel@tonic-gate  * developer forum.
7397c478bd9Sstevel@tonic-gate  */
7407c478bd9Sstevel@tonic-gate #define	FS_NON_ISOC_PROTO_OVERHEAD	14
7417c478bd9Sstevel@tonic-gate #define	FS_ISOC_INPUT_PROTO_OVERHEAD	11
7427c478bd9Sstevel@tonic-gate #define	FS_ISOC_OUTPUT_PROTO_OVERHEAD	10
7437c478bd9Sstevel@tonic-gate #define	LOW_SPEED_PROTO_OVERHEAD	97
7447c478bd9Sstevel@tonic-gate #define	HUB_LOW_SPEED_PROTO_OVERHEAD	01
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate /*
7477c478bd9Sstevel@tonic-gate  * The Host Controller (HC) delays are the USB host controller specific
7487c478bd9Sstevel@tonic-gate  * delays. The value shown below is the host  controller delay for  the
7497c478bd9Sstevel@tonic-gate  * RIO USB host controller.  This value was calculated and  given by the
7507c478bd9Sstevel@tonic-gate  * Sun USB hardware people.
7517c478bd9Sstevel@tonic-gate  */
7527c478bd9Sstevel@tonic-gate #define	HOST_CONTROLLER_DELAY		18
7537c478bd9Sstevel@tonic-gate 
7547c478bd9Sstevel@tonic-gate /*
7557c478bd9Sstevel@tonic-gate  * The low speed clock below represents that to transmit one low-speed
7567c478bd9Sstevel@tonic-gate  * bit takes eight times more than one full speed bit time.
7577c478bd9Sstevel@tonic-gate  */
7587c478bd9Sstevel@tonic-gate #define	LOW_SPEED_CLOCK			8
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate 
7617c478bd9Sstevel@tonic-gate /*
7627c478bd9Sstevel@tonic-gate  * Macros for setting/getting information
7637c478bd9Sstevel@tonic-gate  */
7647c478bd9Sstevel@tonic-gate #define	Get_ED(addr)		ddi_get32(ohcip->ohci_ed_pool_mem_handle, \
7657c478bd9Sstevel@tonic-gate 					(uint32_t *)&addr)
7667c478bd9Sstevel@tonic-gate 
7677c478bd9Sstevel@tonic-gate #define	Set_ED(addr, val)	ddi_put32(ohcip->ohci_ed_pool_mem_handle,  \
7687c478bd9Sstevel@tonic-gate 					((uint32_t *)&addr), \
7697c478bd9Sstevel@tonic-gate 					((int32_t)(val)))
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate #define	Get_TD(addr)		ddi_get32(ohcip->ohci_td_pool_mem_handle, \
7727c478bd9Sstevel@tonic-gate 					(uint32_t *)&addr)
7737c478bd9Sstevel@tonic-gate 
7747c478bd9Sstevel@tonic-gate #define	Set_TD(addr, val)	ddi_put32(ohcip->ohci_td_pool_mem_handle, \
7757c478bd9Sstevel@tonic-gate 					((uint32_t *)&addr), \
7767c478bd9Sstevel@tonic-gate 					((uint32_t)(uintptr_t)(val)))
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate #define	Get_HCCA(addr)		ddi_get32(ohcip->ohci_hcca_mem_handle, \
7797c478bd9Sstevel@tonic-gate 					(uint32_t *)&addr)
7807c478bd9Sstevel@tonic-gate 
7817c478bd9Sstevel@tonic-gate #define	Set_HCCA(addr, val)	ddi_put32(ohcip->ohci_hcca_mem_handle, \
7827c478bd9Sstevel@tonic-gate 					((uint32_t *)&addr), \
7837c478bd9Sstevel@tonic-gate 					((int32_t)(val)))
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate #define	Get_OpReg(addr)		ddi_get32(ohcip->ohci_regs_handle, \
7867c478bd9Sstevel@tonic-gate 					(uint32_t *)&ohcip->ohci_regsp->addr)
7877c478bd9Sstevel@tonic-gate 
7887c478bd9Sstevel@tonic-gate #define	Set_OpReg(addr, val)	ddi_put32(ohcip->ohci_regs_handle, \
7897c478bd9Sstevel@tonic-gate 				((uint32_t *)&ohcip->ohci_regsp->addr), \
7907c478bd9Sstevel@tonic-gate 					((int32_t)(val)))
7917c478bd9Sstevel@tonic-gate 
7927c478bd9Sstevel@tonic-gate #define	Sync_HCCA(ohcip)	(void) ddi_dma_sync( \
7937c478bd9Sstevel@tonic-gate 				ohcip->ohci_hcca_dma_handle, \
7947c478bd9Sstevel@tonic-gate 				0, sizeof (ohci_hcca_t), \
7957c478bd9Sstevel@tonic-gate 				DDI_DMA_SYNC_FORCPU);
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate #define	Sync_ED_TD_Pool(ohcip)	(void) ddi_dma_sync( \
7987c478bd9Sstevel@tonic-gate 				ohcip->ohci_ed_pool_dma_handle, \
7997c478bd9Sstevel@tonic-gate 				0, OHCI_ED_POOL_SIZE * sizeof (ohci_ed_t), \
8007c478bd9Sstevel@tonic-gate 				DDI_DMA_SYNC_FORCPU); \
8017c478bd9Sstevel@tonic-gate 				(void) ddi_dma_sync( \
8027c478bd9Sstevel@tonic-gate 				ohcip->ohci_td_pool_dma_handle, \
8037c478bd9Sstevel@tonic-gate 				0, OHCI_TD_POOL_SIZE * sizeof (ohci_td_t), \
8047c478bd9Sstevel@tonic-gate 				DDI_DMA_SYNC_FORCPU);
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate #define	Sync_IO_Buffer(dma_handle, length) \
8077c478bd9Sstevel@tonic-gate 				(void) ddi_dma_sync(dma_handle, \
8087c478bd9Sstevel@tonic-gate 				0, length, DDI_DMA_SYNC_FORCPU);
809*9b58c2adSzhigang lu - Sun Microsystems - Beijing China #define	Sync_IO_Buffer_for_device(dma_handle, length) \
810*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				(void) ddi_dma_sync(dma_handle, \
811*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				0, length, DDI_DMA_SYNC_FORDEV);
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate /*
8147c478bd9Sstevel@tonic-gate  * Macros to speed handling of 32bit IDs
8157c478bd9Sstevel@tonic-gate  */
8167c478bd9Sstevel@tonic-gate #define	OHCI_GET_ID(x)		id32_alloc((void *)(x), KM_SLEEP)
8177c478bd9Sstevel@tonic-gate #define	OHCI_LOOKUP_ID(x)	id32_lookup((x))
8187c478bd9Sstevel@tonic-gate #define	OHCI_FREE_ID(x)		id32_free((x))
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate /*
8227c478bd9Sstevel@tonic-gate  * Miscellaneous definitions.
8237c478bd9Sstevel@tonic-gate  */
8247c478bd9Sstevel@tonic-gate 
8257c478bd9Sstevel@tonic-gate /* Data toggle bits */
8267c478bd9Sstevel@tonic-gate #define	DATA0		0
8277c478bd9Sstevel@tonic-gate #define	DATA1		1
8287c478bd9Sstevel@tonic-gate 
8297c478bd9Sstevel@tonic-gate /* sKip bit actions */
8307c478bd9Sstevel@tonic-gate #define	CLEAR_sKip	0
8317c478bd9Sstevel@tonic-gate #define	SET_sKip	1
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate typedef uint_t		skip_bit_t;
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate /*
8367c478bd9Sstevel@tonic-gate  * Setup Packet
8377c478bd9Sstevel@tonic-gate  */
8387c478bd9Sstevel@tonic-gate typedef struct setup_pkt {
8397c478bd9Sstevel@tonic-gate 	uchar_t	bmRequestType;
8407c478bd9Sstevel@tonic-gate 	uchar_t	bRequest;
8417c478bd9Sstevel@tonic-gate 	ushort_t wValue;
8427c478bd9Sstevel@tonic-gate 	ushort_t wIndex;
8437c478bd9Sstevel@tonic-gate 	ushort_t wLength;
8447c478bd9Sstevel@tonic-gate }setup_pkt_t;
8457c478bd9Sstevel@tonic-gate 
8467c478bd9Sstevel@tonic-gate #define	SETUP_SIZE		8	/* Setup packet is always 8 bytes */
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate #define	REQUEST_TYPE_OFFSET	0
8497c478bd9Sstevel@tonic-gate #define	REQUEST_OFFSET		1
8507c478bd9Sstevel@tonic-gate #define	VALUE_OFFSET		2
8517c478bd9Sstevel@tonic-gate #define	INDEX_OFFSET		4
8527c478bd9Sstevel@tonic-gate #define	LENGTH_OFFSET		6
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate #define	TYPE_DEV_TO_HOST	0x80000000
8557c478bd9Sstevel@tonic-gate #define	DEVICE			0x00000001
8567c478bd9Sstevel@tonic-gate #define	CONFIGURATION		0x00000002
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate /*
8597c478bd9Sstevel@tonic-gate  * The following are used in attach to	 indicate
8607c478bd9Sstevel@tonic-gate  * what has been succesfully allocated, so detach
8617c478bd9Sstevel@tonic-gate  * can remove them.
8627c478bd9Sstevel@tonic-gate  */
8637c478bd9Sstevel@tonic-gate #define	OHCI_ATTACH		0x01	/* ohci driver initilization */
8647c478bd9Sstevel@tonic-gate #define	OHCI_ZALLOC		0x02	/* Memory for ohci state structure */
8657c478bd9Sstevel@tonic-gate #define	OHCI_INTR		0x04	/* Interrupt handler registered */
8667c478bd9Sstevel@tonic-gate #define	OHCI_USBAREG		0x08	/* USBA registered */
8677c478bd9Sstevel@tonic-gate #define	OHCI_RHREG		0x10	/* Root hub driver loaded */
8687c478bd9Sstevel@tonic-gate 
8697c478bd9Sstevel@tonic-gate #define	OHCI_UNIT(dev)	(getminor((dev)) & ~HUBD_IS_ROOT_HUB)
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate /*
8727c478bd9Sstevel@tonic-gate  * Debug printing
8737c478bd9Sstevel@tonic-gate  * Masks
8747c478bd9Sstevel@tonic-gate  */
8757c478bd9Sstevel@tonic-gate #define	PRINT_MASK_ATTA		0x00000001	/* Attach time */
8767c478bd9Sstevel@tonic-gate #define	PRINT_MASK_LISTS	0x00000002	/* List management */
8777c478bd9Sstevel@tonic-gate #define	PRINT_MASK_ROOT_HUB	0x00000004	/* Root hub stuff */
8787c478bd9Sstevel@tonic-gate #define	PRINT_MASK_ALLOC	0x00000008	/* Alloc/dealloc descr */
8797c478bd9Sstevel@tonic-gate #define	PRINT_MASK_INTR		0x00000010	/* Interrupt handling */
8807c478bd9Sstevel@tonic-gate #define	PRINT_MASK_BW		0x00000020	/* Bandwidth */
8817c478bd9Sstevel@tonic-gate #define	PRINT_MASK_CBOPS	0x00000040	/* CB-OPS */
8827c478bd9Sstevel@tonic-gate #define	PRINT_MASK_HCDI		0x00000080	/* HCDI entry points */
8837c478bd9Sstevel@tonic-gate #define	PRINT_MASK_DUMPING	0x00000100	/* Dump ohci info */
8847c478bd9Sstevel@tonic-gate #define	PRINT_MASK_ALL		0xFFFFFFFF
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate /* Polling support */
8887c478bd9Sstevel@tonic-gate int		ohci_hcdi_polled_input_init(
8897c478bd9Sstevel@tonic-gate 				usba_pipe_handle_data_t	*ph,
8907c478bd9Sstevel@tonic-gate 				uchar_t			**polled_buf,
8917c478bd9Sstevel@tonic-gate 				usb_console_info_impl_t	*info);
8927c478bd9Sstevel@tonic-gate int		ohci_hcdi_polled_input_enter(
8937c478bd9Sstevel@tonic-gate 				usb_console_info_impl_t	*info);
8947c478bd9Sstevel@tonic-gate int		ohci_hcdi_polled_read(
8957c478bd9Sstevel@tonic-gate 				usb_console_info_impl_t	*info,
8967c478bd9Sstevel@tonic-gate 				uint_t			*num_characters);
8977c478bd9Sstevel@tonic-gate int		ohci_hcdi_polled_input_exit(
8987c478bd9Sstevel@tonic-gate 				usb_console_info_impl_t	*info);
8997c478bd9Sstevel@tonic-gate int		ohci_hcdi_polled_input_fini(
9007c478bd9Sstevel@tonic-gate 				usb_console_info_impl_t	*info);
9017c478bd9Sstevel@tonic-gate 
902*9b58c2adSzhigang lu - Sun Microsystems - Beijing China int		ohci_hcdi_polled_output_init(
903*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				usba_pipe_handle_data_t	*ph,
904*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				usb_console_info_impl_t	*console_output_info);
905*9b58c2adSzhigang lu - Sun Microsystems - Beijing China int		ohci_hcdi_polled_output_enter(
906*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				usb_console_info_impl_t	*info);
907*9b58c2adSzhigang lu - Sun Microsystems - Beijing China int		ohci_hcdi_polled_write(
908*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				usb_console_info_impl_t *info,
909*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				uchar_t *buf,
910*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				uint_t num_characters,
911*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				uint_t *num_characters_written);
912*9b58c2adSzhigang lu - Sun Microsystems - Beijing China int		ohci_hcdi_polled_output_exit(
913*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				usb_console_info_impl_t	*info);
914*9b58c2adSzhigang lu - Sun Microsystems - Beijing China int		ohci_hcdi_polled_output_fini(
915*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				usb_console_info_impl_t *info);
916*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 
9177c478bd9Sstevel@tonic-gate /* Root hub related functions */
9187c478bd9Sstevel@tonic-gate int		ohci_init_root_hub(
9197c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip);
9207c478bd9Sstevel@tonic-gate int		ohci_load_root_hub_driver(
9217c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip);
9227c478bd9Sstevel@tonic-gate int		ohci_unload_root_hub_driver(
9237c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip);
9247c478bd9Sstevel@tonic-gate int		ohci_handle_root_hub_pipe_open(
9257c478bd9Sstevel@tonic-gate 				usba_pipe_handle_data_t	*ph,
9267c478bd9Sstevel@tonic-gate 				usb_flags_t		flags);
9277c478bd9Sstevel@tonic-gate int		ohci_handle_root_hub_pipe_close(
9287c478bd9Sstevel@tonic-gate 				usba_pipe_handle_data_t	*ph);
9297c478bd9Sstevel@tonic-gate int		ohci_handle_root_hub_pipe_reset(
9307c478bd9Sstevel@tonic-gate 				usba_pipe_handle_data_t	*ph,
9317c478bd9Sstevel@tonic-gate 				usb_flags_t		flags);
9327c478bd9Sstevel@tonic-gate int		ohci_handle_root_hub_request(
9337c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip,
9347c478bd9Sstevel@tonic-gate 				usba_pipe_handle_data_t	*ph,
9357c478bd9Sstevel@tonic-gate 				usb_ctrl_req_t		*ctrl_reqp);
9367c478bd9Sstevel@tonic-gate int		ohci_handle_root_hub_pipe_start_intr_polling(
9377c478bd9Sstevel@tonic-gate 				usba_pipe_handle_data_t	*ph,
9387c478bd9Sstevel@tonic-gate 				usb_intr_req_t		*intr_reqp,
9397c478bd9Sstevel@tonic-gate 				usb_flags_t		flags);
9407c478bd9Sstevel@tonic-gate void		ohci_handle_root_hub_pipe_stop_intr_polling(
9417c478bd9Sstevel@tonic-gate 				usba_pipe_handle_data_t	*ph,
9427c478bd9Sstevel@tonic-gate 				usb_flags_t		flags);
9437c478bd9Sstevel@tonic-gate void		ohci_handle_root_hub_status_change(void *arg);
9447c478bd9Sstevel@tonic-gate 
9457c478bd9Sstevel@tonic-gate /* Endpoint Descriptor (ED) related functions */
9467c478bd9Sstevel@tonic-gate ohci_ed_t	*ohci_alloc_hc_ed(
9477c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip,
9487c478bd9Sstevel@tonic-gate 				usba_pipe_handle_data_t	*ph);
9497c478bd9Sstevel@tonic-gate void		ohci_deallocate_ed(
9507c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip,
9517c478bd9Sstevel@tonic-gate 				ohci_ed_t		*old_ed);
9527c478bd9Sstevel@tonic-gate uint32_t	ohci_ed_cpu_to_iommu(
9537c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip,
9547c478bd9Sstevel@tonic-gate 				ohci_ed_t		*addr);
9557c478bd9Sstevel@tonic-gate 
9567c478bd9Sstevel@tonic-gate /* Transfer Descriptor (TD) related functions */
9577c478bd9Sstevel@tonic-gate int		ohci_start_periodic_pipe_polling(
9587c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip,
9597c478bd9Sstevel@tonic-gate 				usba_pipe_handle_data_t	*ph,
9607c478bd9Sstevel@tonic-gate 				usb_opaque_t		periodic_in_reqp,
9617c478bd9Sstevel@tonic-gate 				usb_flags_t		flags);
9627c478bd9Sstevel@tonic-gate void		ohci_traverse_tds(
9637c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip,
9647c478bd9Sstevel@tonic-gate 				usba_pipe_handle_data_t	*ph);
9657c478bd9Sstevel@tonic-gate void		ohci_deallocate_td(
9667c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip,
9677c478bd9Sstevel@tonic-gate 				ohci_td_t		*old_td);
9687c478bd9Sstevel@tonic-gate uint32_t	ohci_td_cpu_to_iommu(
9697c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip,
9707c478bd9Sstevel@tonic-gate 				ohci_td_t		*addr);
9717c478bd9Sstevel@tonic-gate ohci_td_t	*ohci_td_iommu_to_cpu(
9727c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip,
9737c478bd9Sstevel@tonic-gate 				uintptr_t		addr);
97402acac7eSsl size_t		ohci_get_td_residue(
97502acac7eSsl 				ohci_state_t		*ohcip,
97602acac7eSsl 				ohci_td_t		*td);
97702acac7eSsl void		ohci_init_td(
97802acac7eSsl 				ohci_state_t		*ohcip,
97902acac7eSsl 				ohci_trans_wrapper_t	*tw,
98002acac7eSsl 				uint32_t		hctd_dma_offs,
98102acac7eSsl 				size_t			hctd_length,
98202acac7eSsl 				ohci_td_t		*td);
9837c478bd9Sstevel@tonic-gate 
9847c478bd9Sstevel@tonic-gate /* Transfer Wrapper (TW) functions */
9857c478bd9Sstevel@tonic-gate void		ohci_deallocate_tw_resources(
9867c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip,
9877c478bd9Sstevel@tonic-gate 				ohci_pipe_private_t	*pp,
9887c478bd9Sstevel@tonic-gate 				ohci_trans_wrapper_t	*tw);
9897c478bd9Sstevel@tonic-gate 
9907c478bd9Sstevel@tonic-gate /* Interrupt Handling functions */
9917c478bd9Sstevel@tonic-gate void		ohci_handle_frame_number_overflow(
9927c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip);
9937c478bd9Sstevel@tonic-gate 
9947c478bd9Sstevel@tonic-gate /* Miscillaneous functions */
9957c478bd9Sstevel@tonic-gate ohci_state_t	*ohci_obtain_state(
9967c478bd9Sstevel@tonic-gate 				dev_info_t		*dip);
9977c478bd9Sstevel@tonic-gate int		ohci_state_is_operational(
9987c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip);
9997c478bd9Sstevel@tonic-gate int		ohci_do_soft_reset(
10007c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip);
10017c478bd9Sstevel@tonic-gate usb_frame_number_t ohci_get_current_frame_number(
10027c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip);
10037c478bd9Sstevel@tonic-gate void		ohci_handle_outstanding_requests(
10047c478bd9Sstevel@tonic-gate 				ohci_state_t		*ohcip,
10057c478bd9Sstevel@tonic-gate 				ohci_pipe_private_t	*pp);
1006*9b58c2adSzhigang lu - Sun Microsystems - Beijing China int	ohci_allocate_tds_for_tw(
1007*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				ohci_state_t		*ohcip,
1008*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				ohci_trans_wrapper_t	*tw,
1009*9b58c2adSzhigang lu - Sun Microsystems - Beijing China 				size_t			td_count);
10107c478bd9Sstevel@tonic-gate 
10117c478bd9Sstevel@tonic-gate #ifdef __cplusplus
10127c478bd9Sstevel@tonic-gate }
10137c478bd9Sstevel@tonic-gate #endif
10147c478bd9Sstevel@tonic-gate 
10157c478bd9Sstevel@tonic-gate #endif /* _SYS_USB_OHCID_H */
1016