xref: /openbsd-src/sys/dev/usb/uhcivar.h (revision ca68072a688cf728a88c80bb1a274b92d9c7ce09)
1*ca68072aSmpi /*	$OpenBSD: uhcivar.h,v 1.33 2014/05/18 17:10:27 mpi Exp $ */
272a11251Snate /*	$NetBSD: uhcivar.h,v 1.36 2002/12/31 00:39:11 augustss Exp $	*/
35deafb75Saaron /*	$FreeBSD: src/sys/dev/usb/uhcivar.h,v 1.14 1999/11/17 22:33:42 n_hibma Exp $	*/
412fe8f0eSfgsch 
512fe8f0eSfgsch /*
612fe8f0eSfgsch  * Copyright (c) 1998 The NetBSD Foundation, Inc.
712fe8f0eSfgsch  * All rights reserved.
812fe8f0eSfgsch  *
912fe8f0eSfgsch  * This code is derived from software contributed to The NetBSD Foundation
1082426cf3Sfgsch  * by Lennart Augustsson (lennart@augustsson.net) at
1112fe8f0eSfgsch  * Carlstedt Research & Technology.
1212fe8f0eSfgsch  *
1312fe8f0eSfgsch  * Redistribution and use in source and binary forms, with or without
1412fe8f0eSfgsch  * modification, are permitted provided that the following conditions
1512fe8f0eSfgsch  * are met:
1612fe8f0eSfgsch  * 1. Redistributions of source code must retain the above copyright
1712fe8f0eSfgsch  *    notice, this list of conditions and the following disclaimer.
1812fe8f0eSfgsch  * 2. Redistributions in binary form must reproduce the above copyright
1912fe8f0eSfgsch  *    notice, this list of conditions and the following disclaimer in the
2012fe8f0eSfgsch  *    documentation and/or other materials provided with the distribution.
2112fe8f0eSfgsch  *
2212fe8f0eSfgsch  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2312fe8f0eSfgsch  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2412fe8f0eSfgsch  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2512fe8f0eSfgsch  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2612fe8f0eSfgsch  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2712fe8f0eSfgsch  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2812fe8f0eSfgsch  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2912fe8f0eSfgsch  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3012fe8f0eSfgsch  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3112fe8f0eSfgsch  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3212fe8f0eSfgsch  * POSSIBILITY OF SUCH DAMAGE.
3312fe8f0eSfgsch  */
3412fe8f0eSfgsch 
3512fe8f0eSfgsch /*
3612fe8f0eSfgsch  * To avoid having 1024 TDs for each isochronous transfer we introduce
3712fe8f0eSfgsch  * a virtual frame list.  Every UHCI_VFRAMELIST_COUNT entries in the real
38bcc0e93aSaaron  * frame list points to a non-active TD.  These, in turn, form the
3912fe8f0eSfgsch  * starts of the virtual frame list.  This also has the advantage that it
40bcc0e93aSaaron  * simplifies linking in/out of TDs/QHs in the schedule.
4112fe8f0eSfgsch  * Furthermore, initially each of the inactive TDs point to an inactive
4212fe8f0eSfgsch  * QH that forms the start of the interrupt traffic for that slot.
4312fe8f0eSfgsch  * Each of these QHs point to the same QH that is the start of control
44bcc0e93aSaaron  * traffic.  This QH points at another QH which is the start of the
45bcc0e93aSaaron  * bulk traffic.
4612fe8f0eSfgsch  *
4712fe8f0eSfgsch  * UHCI_VFRAMELIST_COUNT should be a power of 2 and <= UHCI_FRAMELIST_COUNT.
4812fe8f0eSfgsch  */
4912fe8f0eSfgsch #define UHCI_VFRAMELIST_COUNT 128
5012fe8f0eSfgsch 
51ab0b1be7Smglocker struct uhci_soft_qh;
52ab0b1be7Smglocker struct uhci_soft_td;
5312fe8f0eSfgsch 
54f8958cb1Sfgsch typedef union {
55f8958cb1Sfgsch 	struct uhci_soft_qh *sqh;
56f8958cb1Sfgsch 	struct uhci_soft_td *std;
57f8958cb1Sfgsch } uhci_soft_td_qh_t;
58f8958cb1Sfgsch 
5912fe8f0eSfgsch /*
6012fe8f0eSfgsch  * An interrupt info struct contains the information needed to
6112fe8f0eSfgsch  * execute a requested routine when the controller generates an
6212fe8f0eSfgsch  * interrupt.  Since we cannot know which transfer generated
6312fe8f0eSfgsch  * the interrupt all structs are linked together so they can be
6412fe8f0eSfgsch  * searched at interrupt time.
6512fe8f0eSfgsch  */
665b152b0bSmpi struct uhci_xfer {
675b152b0bSmpi 	struct usbd_xfer xfer;
685b152b0bSmpi 	LIST_ENTRY(uhci_xfer) inext;
69ab0b1be7Smglocker 	struct uhci_soft_td *stdstart;
70ab0b1be7Smglocker 	struct uhci_soft_td *stdend;
715b152b0bSmpi 	int curframe;
7212fe8f0eSfgsch #ifdef DIAGNOSTIC
7312fe8f0eSfgsch 	int isdone;
7412fe8f0eSfgsch #endif
75ab0b1be7Smglocker };
7612fe8f0eSfgsch 
7712fe8f0eSfgsch /*
7812fe8f0eSfgsch  * Extra information that we need for a TD.
7912fe8f0eSfgsch  */
8012fe8f0eSfgsch struct uhci_soft_td {
81ab0b1be7Smglocker 	struct uhci_td td;		/* The real TD, must be first */
82f8958cb1Sfgsch 	uhci_soft_td_qh_t link; 	/* soft version of the td_link field */
83f8958cb1Sfgsch 	uhci_physaddr_t physaddr;	/* TD's physical address. */
8412fe8f0eSfgsch };
85f8958cb1Sfgsch /*
86f8958cb1Sfgsch  * Make the size such that it is a multiple of UHCI_TD_ALIGN.  This way
87eff3e1aaSaaron  * we can pack a number of soft TD together and have the real TD well
88f8958cb1Sfgsch  * aligned.
89f8958cb1Sfgsch  * NOTE: Minimum size is 32 bytes.
90f8958cb1Sfgsch  */
91f8958cb1Sfgsch #define UHCI_STD_SIZE ((sizeof (struct uhci_soft_td) + UHCI_TD_ALIGN - 1) / UHCI_TD_ALIGN * UHCI_TD_ALIGN)
92f8958cb1Sfgsch #define UHCI_STD_CHUNK 128 /*(PAGE_SIZE / UHCI_TD_SIZE)*/
9312fe8f0eSfgsch 
9412fe8f0eSfgsch /*
9512fe8f0eSfgsch  * Extra information that we need for a QH.
9612fe8f0eSfgsch  */
9712fe8f0eSfgsch struct uhci_soft_qh {
98ab0b1be7Smglocker 	struct uhci_qh qh;		/* The real QH, must be first */
99ab0b1be7Smglocker 	struct uhci_soft_qh *hlink;	/* soft version of qh_hlink */
100ab0b1be7Smglocker 	struct uhci_soft_td *elink;	/* soft version of qh_elink */
101f8958cb1Sfgsch 	uhci_physaddr_t physaddr;	/* QH's physical address. */
10212fe8f0eSfgsch 	int pos;			/* Timeslot position */
10312fe8f0eSfgsch };
104f8958cb1Sfgsch /* See comment about UHCI_STD_SIZE. */
105f8958cb1Sfgsch #define UHCI_SQH_SIZE ((sizeof (struct uhci_soft_qh) + UHCI_QH_ALIGN - 1) / UHCI_QH_ALIGN * UHCI_QH_ALIGN)
106f8958cb1Sfgsch #define UHCI_SQH_CHUNK 128 /*(PAGE_SIZE / UHCI_QH_SIZE)*/
10712fe8f0eSfgsch 
10812fe8f0eSfgsch /*
109eff3e1aaSaaron  * Information about an entry in the virtual frame list.
11012fe8f0eSfgsch  */
11112fe8f0eSfgsch struct uhci_vframe {
112ab0b1be7Smglocker 	struct uhci_soft_td *htd;	/* pointer to dummy TD */
113ab0b1be7Smglocker 	struct uhci_soft_td *etd;	/* pointer to last TD */
114ab0b1be7Smglocker 	struct uhci_soft_qh *hqh;	/* pointer to dummy QH */
115ab0b1be7Smglocker 	struct uhci_soft_qh *eqh;	/* pointer to last QH */
11612fe8f0eSfgsch 	u_int bandwidth;		/* max bandwidth used by this frame */
11712fe8f0eSfgsch };
11812fe8f0eSfgsch 
119ab0b1be7Smglocker struct uhci_softc {
12012fe8f0eSfgsch 	struct usbd_bus sc_bus;		/* base device */
12112fe8f0eSfgsch 	bus_space_tag_t iot;
12212fe8f0eSfgsch 	bus_space_handle_t ioh;
12382426cf3Sfgsch 	bus_size_t sc_size;
12412fe8f0eSfgsch 
12512fe8f0eSfgsch 	uhci_physaddr_t *sc_pframes;
126ab0b1be7Smglocker 	struct usb_dma sc_dma;
12712fe8f0eSfgsch 	struct uhci_vframe sc_vframes[UHCI_VFRAMELIST_COUNT];
12812fe8f0eSfgsch 
129ab0b1be7Smglocker 	struct uhci_soft_qh *sc_lctl_start; /* dummy QH for low speed control */
130ab0b1be7Smglocker 	struct uhci_soft_qh *sc_lctl_end; /* last control QH */
131ab0b1be7Smglocker 	struct uhci_soft_qh *sc_hctl_start;/* dummy QH for high speed control */
132ab0b1be7Smglocker 	struct uhci_soft_qh *sc_hctl_end; /* last control QH */
133ab0b1be7Smglocker 	struct uhci_soft_qh *sc_bulk_start; /* dummy QH for bulk */
134ab0b1be7Smglocker 	struct uhci_soft_qh *sc_bulk_end; /* last bulk transfer */
135ab0b1be7Smglocker 	struct uhci_soft_qh *sc_last_qh; /* dummy QH at the end */
136591e0ca7Saaron 	u_int32_t sc_loops;		/* number of QHs that wants looping */
13712fe8f0eSfgsch 
138ab0b1be7Smglocker 	struct uhci_soft_td *sc_freetds; /* TD free list */
139ab0b1be7Smglocker 	struct uhci_soft_qh *sc_freeqhs; /* QH free list */
140eff3e1aaSaaron 
14112fe8f0eSfgsch 	u_int8_t sc_conf;		/* device configuration */
14212fe8f0eSfgsch 
143eff3e1aaSaaron 	u_int8_t sc_saved_sof;
144eff3e1aaSaaron 	u_int16_t sc_saved_frnum;
14512fe8f0eSfgsch 
14672a11251Snate 	char sc_softwake;
14772a11251Snate 
148eff3e1aaSaaron 	char sc_isreset;
14912fe8f0eSfgsch 	char sc_suspend;
15012fe8f0eSfgsch 
1515b152b0bSmpi 	LIST_HEAD(, uhci_xfer) sc_intrhead;
15212fe8f0eSfgsch 
153bcc0e93aSaaron 	/* Info for the root hub interrupt "pipe". */
154*ca68072aSmpi 	struct usbd_xfer	*sc_intrxfer;
155*ca68072aSmpi 	struct timeout		 sc_root_intr;
15612fe8f0eSfgsch 
15772a11251Snate 	char sc_vendor[32];		/* vendor string for root hub */
158eff3e1aaSaaron 	int sc_id_vendor;		/* vendor ID for root hub */
159ab0b1be7Smglocker };
16012fe8f0eSfgsch 
161ab0b1be7Smglocker usbd_status	uhci_init(struct uhci_softc *);
162ab0b1be7Smglocker usbd_status	uhci_run(struct uhci_softc *, int run);
163591e0ca7Saaron int		uhci_intr(void *);
16444fe0a2dSmpi int		uhci_detach(struct device *, int);
165e78728c7Spirofti int		uhci_activate(struct device *, int);
166