1/*	$NetBSD: ohcivar.h,v 1.62 2020/12/09 07:10:01 skrll Exp $	*/
2
3/*
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef _OHCIVAR_H_
34#define _OHCIVAR_H_
35
36#include <sys/pool.h>
37
38typedef struct ohci_soft_ed {
39	ohci_ed_t ed;
40	struct ohci_soft_ed *next;
41	ohci_physaddr_t physaddr;
42	usb_dma_t dma;
43	int offs;
44} ohci_soft_ed_t;
45#define OHCI_SED_SIZE (roundup(sizeof(struct ohci_soft_ed), OHCI_ED_ALIGN))
46#define OHCI_SED_CHUNK 128
47
48
49typedef struct ohci_soft_td {
50	ohci_td_t td;
51	struct ohci_soft_td *nexttd;	/* mirrors nexttd in TD */
52	struct ohci_soft_td *dnext;	/* next in done list */
53	struct ohci_soft_td **held;	/* where the ref to this std is held */
54	ohci_physaddr_t physaddr;
55	usb_dma_t dma;
56	int offs;
57	LIST_ENTRY(ohci_soft_td) hnext;	/* next on hash list */
58	struct usbd_xfer *xfer;
59	uint16_t len;
60	uint16_t flags;
61#define OHCI_CALL_DONE	0x0001
62#define OHCI_ADD_LEN	0x0002
63} ohci_soft_td_t;
64#define OHCI_STD_SIZE (roundup(sizeof(struct ohci_soft_td), OHCI_TD_ALIGN))
65#define OHCI_STD_CHUNK 128
66
67
68typedef struct ohci_soft_itd {
69	ohci_itd_t itd;
70	struct ohci_soft_itd *nextitd;	/* mirrors nexttd in ITD */
71	struct ohci_soft_itd *dnext;	/* next in done list */
72	struct ohci_soft_itd **held;	/* where the ref to this sitd is held */
73	ohci_physaddr_t physaddr;
74	usb_dma_t dma;
75	int offs;
76	LIST_ENTRY(ohci_soft_itd) hnext;/* next on hash list */
77	struct usbd_xfer *xfer;
78	uint16_t flags;
79	bool isdone;	/* used only when DIAGNOSTIC is defined */
80} ohci_soft_itd_t;
81#define OHCI_SITD_SIZE (roundup(sizeof(struct ohci_soft_itd), OHCI_ITD_ALIGN))
82#define OHCI_SITD_CHUNK 64
83
84
85#define OHCI_NO_EDS (2*OHCI_NO_INTRS-1)
86
87#define OHCI_HASH_SIZE 128
88
89typedef struct ohci_softc {
90	device_t sc_dev;
91	struct usbd_bus sc_bus;
92	bus_space_tag_t iot;
93	bus_space_handle_t ioh;
94	bus_size_t sc_size;
95
96	kmutex_t sc_lock;
97	kmutex_t sc_intr_lock;
98	void *sc_rhsc_si;
99
100	usb_dma_t sc_hccadma;
101	struct ohci_hcca *sc_hcca;
102	ohci_soft_ed_t *sc_eds[OHCI_NO_EDS];
103	u_int sc_bws[OHCI_NO_INTRS];
104
105	uint32_t sc_eintrs;
106	ohci_soft_ed_t *sc_isoc_head;
107	ohci_soft_ed_t *sc_ctrl_head;
108	ohci_soft_ed_t *sc_bulk_head;
109
110	LIST_HEAD(, ohci_soft_td)  sc_hash_tds[OHCI_HASH_SIZE];
111	LIST_HEAD(, ohci_soft_itd) sc_hash_itds[OHCI_HASH_SIZE];
112
113	TAILQ_HEAD(, ohci_xfer)	sc_abortingxfers;
114
115	int sc_noport;
116
117	int sc_endian;
118#define	OHCI_LITTLE_ENDIAN	0	/* typical (uninitialized default) */
119#define	OHCI_BIG_ENDIAN		1	/* big endian OHCI? never seen it */
120#define	OHCI_HOST_ENDIAN	2	/* if OHCI always matches CPU */
121
122	int sc_flags;
123#define OHCIF_SUPERIO		0x0001
124
125	kcondvar_t sc_abort_cv;
126
127	ohci_soft_ed_t *sc_freeeds;
128	ohci_soft_td_t *sc_freetds;
129	ohci_soft_itd_t *sc_freeitds;
130
131	pool_cache_t sc_xferpool;	/* free xfer pool */
132
133	struct usbd_xfer *sc_intrxfer;
134
135	uint32_t sc_control;		/* Preserved during suspend/standby */
136	uint32_t sc_intre;
137
138	u_int sc_overrun_cnt;
139	struct timeval sc_overrun_ntc;
140
141	struct callout sc_tmo_rhsc;
142	device_t sc_child;
143	char sc_dying;
144} ohci_softc_t;
145
146struct ohci_xfer {
147	struct usbd_xfer xfer;
148	uint32_t ox_abintrs;
149	TAILQ_ENTRY(ohci_xfer) ox_abnext;
150
151	/* ctrl */
152	ohci_soft_td_t *ox_setup;
153	ohci_soft_td_t *ox_stat;
154	union {
155		/* ctrl/bulk/intr */
156		struct {
157			ohci_soft_td_t **ox_stds;
158			size_t ox_nstd;
159		};
160		/* isoc */
161		struct {
162			ohci_soft_itd_t **ox_sitds;
163			size_t ox_nsitd;
164		};
165	};
166};
167
168#define OHCI_BUS2SC(bus)	((bus)->ub_hcpriv)
169#define OHCI_PIPE2SC(pipe)	OHCI_BUS2SC((pipe)->up_dev->ud_bus)
170#define OHCI_XFER2SC(xfer)	OHCI_BUS2SC((xfer)->ux_bus)
171
172#define OHCI_XFER2OXFER(xfer)	((struct ohci_xfer *)(xfer))
173#define OHCI_PIPE2OPIPE(pipe)	((struct ohci_pipe *)(pipe))
174
175int		ohci_init(ohci_softc_t *);
176int		ohci_intr(void *);
177int		ohci_detach(ohci_softc_t *, int);
178bool		ohci_shutdown(device_t, int);
179void		ohci_childdet(device_t, device_t);
180int		ohci_activate(device_t, enum devact);
181bool		ohci_resume(device_t, const pmf_qual_t *);
182bool		ohci_suspend(device_t, const pmf_qual_t *);
183
184#endif /* _OHCIVAR_H_ */
185