dwc2.c revision 1.8 1 1.8 skrll /* $NetBSD: dwc2.c,v 1.8 2013/10/02 22:45:10 skrll Exp $ */
2 1.1 skrll
3 1.1 skrll /*-
4 1.1 skrll * Copyright (c) 2013 The NetBSD Foundation, Inc.
5 1.1 skrll * All rights reserved.
6 1.1 skrll *
7 1.1 skrll * This code is derived from software contributed to The NetBSD Foundation
8 1.1 skrll * by Nick Hudson
9 1.1 skrll *
10 1.1 skrll * Redistribution and use in source and binary forms, with or without
11 1.1 skrll * modification, are permitted provided that the following conditions
12 1.1 skrll * are met:
13 1.1 skrll * 1. Redistributions of source code must retain the above copyright
14 1.1 skrll * notice, this list of conditions and the following disclaimer.
15 1.1 skrll * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 skrll * notice, this list of conditions and the following disclaimer in the
17 1.1 skrll * documentation and/or other materials provided with the distribution.
18 1.1 skrll *
19 1.1 skrll * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 skrll * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 skrll * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 skrll * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 skrll * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 skrll * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 skrll * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 skrll * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 skrll * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 skrll * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 skrll * POSSIBILITY OF SUCH DAMAGE.
30 1.1 skrll */
31 1.1 skrll
32 1.1 skrll #include <sys/cdefs.h>
33 1.8 skrll __KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.8 2013/10/02 22:45:10 skrll Exp $");
34 1.1 skrll
35 1.1 skrll #include "opt_usb.h"
36 1.1 skrll
37 1.1 skrll #include <sys/param.h>
38 1.1 skrll #include <sys/systm.h>
39 1.1 skrll #include <sys/kmem.h>
40 1.1 skrll #include <sys/kernel.h>
41 1.1 skrll #include <sys/device.h>
42 1.1 skrll #include <sys/select.h>
43 1.1 skrll #include <sys/proc.h>
44 1.1 skrll #include <sys/queue.h>
45 1.1 skrll #include <sys/cpu.h>
46 1.1 skrll
47 1.1 skrll #include <machine/endian.h>
48 1.1 skrll
49 1.1 skrll #include <dev/usb/usb.h>
50 1.1 skrll #include <dev/usb/usbdi.h>
51 1.1 skrll #include <dev/usb/usbdivar.h>
52 1.1 skrll #include <dev/usb/usb_mem.h>
53 1.1 skrll
54 1.1 skrll #include <dev/usb/usbroothub_subr.h>
55 1.1 skrll
56 1.1 skrll #include <dwc2/dwc2.h>
57 1.1 skrll #include <dwc2/dwc2var.h>
58 1.1 skrll
59 1.1 skrll #include "dwc2_core.h"
60 1.1 skrll #include "dwc2_hcd.h"
61 1.1 skrll
62 1.1 skrll #ifdef DWC2_COUNTERS
63 1.1 skrll #define DWC2_EVCNT_ADD(a,b) ((void)((a).ev_count += (b)))
64 1.1 skrll #else
65 1.1 skrll #define DWC2_EVCNT_ADD(a,b) do { } while (/*CONSTCOND*/0)
66 1.1 skrll #endif
67 1.1 skrll #define DWC2_EVCNT_INCR(a) DWC2_EVCNT_ADD((a), 1)
68 1.1 skrll
69 1.1 skrll #define DWC2_DEBUG
70 1.1 skrll #ifdef DWC2_DEBUG
71 1.1 skrll #define DPRINTFN(n,fmt,...) do { \
72 1.1 skrll if (dwc2debug >= (n)) { \
73 1.1 skrll printf("%s: " fmt, \
74 1.1 skrll __FUNCTION__,## __VA_ARGS__); \
75 1.1 skrll } \
76 1.1 skrll } while (0)
77 1.1 skrll #define DPRINTF(...) DPRINTFN(1, __VA_ARGS__)
78 1.1 skrll int dwc2debug = 0;
79 1.1 skrll #else
80 1.1 skrll #define DPRINTF(...) do { } while (0)
81 1.1 skrll #define DPRINTFN(...) do { } while (0)
82 1.1 skrll #endif
83 1.1 skrll
84 1.1 skrll Static usbd_status dwc2_open(usbd_pipe_handle);
85 1.1 skrll Static void dwc2_poll(struct usbd_bus *);
86 1.1 skrll Static void dwc2_softintr(void *);
87 1.1 skrll Static void dwc2_waitintr(struct dwc2_softc *, usbd_xfer_handle);
88 1.1 skrll
89 1.1 skrll Static usbd_status dwc2_allocm(struct usbd_bus *, usb_dma_t *, uint32_t);
90 1.1 skrll Static void dwc2_freem(struct usbd_bus *, usb_dma_t *);
91 1.1 skrll
92 1.1 skrll Static usbd_xfer_handle dwc2_allocx(struct usbd_bus *);
93 1.1 skrll Static void dwc2_freex(struct usbd_bus *, usbd_xfer_handle);
94 1.1 skrll Static void dwc2_get_lock(struct usbd_bus *, kmutex_t **);
95 1.1 skrll
96 1.1 skrll Static usbd_status dwc2_root_ctrl_transfer(usbd_xfer_handle);
97 1.1 skrll Static usbd_status dwc2_root_ctrl_start(usbd_xfer_handle);
98 1.1 skrll Static void dwc2_root_ctrl_abort(usbd_xfer_handle);
99 1.1 skrll Static void dwc2_root_ctrl_close(usbd_pipe_handle);
100 1.1 skrll Static void dwc2_root_ctrl_done(usbd_xfer_handle);
101 1.1 skrll
102 1.1 skrll Static usbd_status dwc2_root_intr_transfer(usbd_xfer_handle);
103 1.1 skrll Static usbd_status dwc2_root_intr_start(usbd_xfer_handle);
104 1.1 skrll Static void dwc2_root_intr_abort(usbd_xfer_handle);
105 1.1 skrll Static void dwc2_root_intr_close(usbd_pipe_handle);
106 1.1 skrll Static void dwc2_root_intr_done(usbd_xfer_handle);
107 1.1 skrll
108 1.1 skrll Static usbd_status dwc2_device_ctrl_transfer(usbd_xfer_handle);
109 1.1 skrll Static usbd_status dwc2_device_ctrl_start(usbd_xfer_handle);
110 1.1 skrll Static void dwc2_device_ctrl_abort(usbd_xfer_handle);
111 1.1 skrll Static void dwc2_device_ctrl_close(usbd_pipe_handle);
112 1.1 skrll Static void dwc2_device_ctrl_done(usbd_xfer_handle);
113 1.1 skrll
114 1.1 skrll Static usbd_status dwc2_device_bulk_transfer(usbd_xfer_handle);
115 1.1 skrll Static usbd_status dwc2_device_bulk_start(usbd_xfer_handle);
116 1.1 skrll Static void dwc2_device_bulk_abort(usbd_xfer_handle);
117 1.1 skrll Static void dwc2_device_bulk_close(usbd_pipe_handle);
118 1.1 skrll Static void dwc2_device_bulk_done(usbd_xfer_handle);
119 1.1 skrll
120 1.1 skrll Static usbd_status dwc2_device_intr_transfer(usbd_xfer_handle);
121 1.1 skrll Static usbd_status dwc2_device_intr_start(usbd_xfer_handle);
122 1.1 skrll Static void dwc2_device_intr_abort(usbd_xfer_handle);
123 1.1 skrll Static void dwc2_device_intr_close(usbd_pipe_handle);
124 1.1 skrll Static void dwc2_device_intr_done(usbd_xfer_handle);
125 1.1 skrll
126 1.1 skrll Static usbd_status dwc2_device_isoc_transfer(usbd_xfer_handle);
127 1.1 skrll Static usbd_status dwc2_device_isoc_start(usbd_xfer_handle);
128 1.1 skrll Static void dwc2_device_isoc_abort(usbd_xfer_handle);
129 1.1 skrll Static void dwc2_device_isoc_close(usbd_pipe_handle);
130 1.1 skrll Static void dwc2_device_isoc_done(usbd_xfer_handle);
131 1.1 skrll
132 1.1 skrll Static usbd_status dwc2_device_start(usbd_xfer_handle);
133 1.1 skrll Static void dwc2_device_close(usbd_pipe_handle);
134 1.1 skrll
135 1.1 skrll Static void dwc2_close_pipe(usbd_pipe_handle);
136 1.1 skrll Static void dwc2_abort_xfer(usbd_xfer_handle, usbd_status);
137 1.1 skrll
138 1.1 skrll Static void dwc2_device_clear_toggle(usbd_pipe_handle);
139 1.1 skrll Static void dwc2_noop(usbd_pipe_handle pipe);
140 1.1 skrll
141 1.1 skrll Static int dwc2_interrupt(struct dwc2_softc *);
142 1.1 skrll Static void dwc2_rhc(void *);
143 1.1 skrll
144 1.1 skrll Static void dwc2_timeout(void *);
145 1.1 skrll Static void dwc2_timeout_task(void *);
146 1.1 skrll
147 1.7 skrll
148 1.7 skrll
149 1.7 skrll static inline void
150 1.7 skrll dwc2_allocate_bus_bandwidth(struct dwc2_hsotg *hsotg, u16 bw,
151 1.7 skrll usbd_xfer_handle xfer)
152 1.7 skrll {
153 1.7 skrll }
154 1.7 skrll
155 1.7 skrll static inline void
156 1.7 skrll dwc2_free_bus_bandwidth(struct dwc2_hsotg *hsotg, u16 bw,
157 1.7 skrll usbd_xfer_handle xfer)
158 1.7 skrll {
159 1.7 skrll }
160 1.7 skrll
161 1.1 skrll #define DWC2_INTR_ENDPT 1
162 1.1 skrll
163 1.1 skrll Static const struct usbd_bus_methods dwc2_bus_methods = {
164 1.1 skrll .open_pipe = dwc2_open,
165 1.1 skrll .soft_intr = dwc2_softintr,
166 1.1 skrll .do_poll = dwc2_poll,
167 1.1 skrll .allocm = dwc2_allocm,
168 1.1 skrll .freem = dwc2_freem,
169 1.1 skrll .allocx = dwc2_allocx,
170 1.1 skrll .freex = dwc2_freex,
171 1.1 skrll .get_lock = dwc2_get_lock,
172 1.1 skrll };
173 1.1 skrll
174 1.1 skrll Static const struct usbd_pipe_methods dwc2_root_ctrl_methods = {
175 1.1 skrll .transfer = dwc2_root_ctrl_transfer,
176 1.1 skrll .start = dwc2_root_ctrl_start,
177 1.1 skrll .abort = dwc2_root_ctrl_abort,
178 1.1 skrll .close = dwc2_root_ctrl_close,
179 1.1 skrll .cleartoggle = dwc2_noop,
180 1.1 skrll .done = dwc2_root_ctrl_done,
181 1.1 skrll };
182 1.1 skrll
183 1.1 skrll Static const struct usbd_pipe_methods dwc2_root_intr_methods = {
184 1.1 skrll .transfer = dwc2_root_intr_transfer,
185 1.1 skrll .start = dwc2_root_intr_start,
186 1.1 skrll .abort = dwc2_root_intr_abort,
187 1.1 skrll .close = dwc2_root_intr_close,
188 1.1 skrll .cleartoggle = dwc2_noop,
189 1.1 skrll .done = dwc2_root_intr_done,
190 1.1 skrll };
191 1.1 skrll
192 1.1 skrll Static const struct usbd_pipe_methods dwc2_device_ctrl_methods = {
193 1.1 skrll .transfer = dwc2_device_ctrl_transfer,
194 1.1 skrll .start = dwc2_device_ctrl_start,
195 1.1 skrll .abort = dwc2_device_ctrl_abort,
196 1.1 skrll .close = dwc2_device_ctrl_close,
197 1.1 skrll .cleartoggle = dwc2_noop,
198 1.1 skrll .done = dwc2_device_ctrl_done,
199 1.1 skrll };
200 1.1 skrll
201 1.1 skrll Static const struct usbd_pipe_methods dwc2_device_intr_methods = {
202 1.1 skrll .transfer = dwc2_device_intr_transfer,
203 1.1 skrll .start = dwc2_device_intr_start,
204 1.1 skrll .abort = dwc2_device_intr_abort,
205 1.1 skrll .close = dwc2_device_intr_close,
206 1.1 skrll .cleartoggle = dwc2_device_clear_toggle,
207 1.1 skrll .done = dwc2_device_intr_done,
208 1.1 skrll };
209 1.1 skrll
210 1.1 skrll Static const struct usbd_pipe_methods dwc2_device_bulk_methods = {
211 1.1 skrll .transfer = dwc2_device_bulk_transfer,
212 1.1 skrll .start = dwc2_device_bulk_start,
213 1.1 skrll .abort = dwc2_device_bulk_abort,
214 1.1 skrll .close = dwc2_device_bulk_close,
215 1.1 skrll .cleartoggle = dwc2_device_clear_toggle,
216 1.1 skrll .done = dwc2_device_bulk_done,
217 1.1 skrll };
218 1.1 skrll
219 1.1 skrll Static const struct usbd_pipe_methods dwc2_device_isoc_methods = {
220 1.1 skrll .transfer = dwc2_device_isoc_transfer,
221 1.1 skrll .start = dwc2_device_isoc_start,
222 1.1 skrll .abort = dwc2_device_isoc_abort,
223 1.1 skrll .close = dwc2_device_isoc_close,
224 1.1 skrll .cleartoggle = dwc2_noop,
225 1.1 skrll .done = dwc2_device_isoc_done,
226 1.1 skrll };
227 1.1 skrll
228 1.1 skrll Static usbd_status
229 1.1 skrll dwc2_allocm(struct usbd_bus *bus, usb_dma_t *dma, uint32_t size)
230 1.1 skrll {
231 1.1 skrll struct dwc2_softc *sc = DWC2_BUS2SC(bus);
232 1.1 skrll usbd_status status;
233 1.1 skrll
234 1.1 skrll DPRINTFN(10, "\n");
235 1.1 skrll
236 1.1 skrll status = usb_allocmem(&sc->sc_bus, size, 0, dma);
237 1.1 skrll if (status == USBD_NOMEM)
238 1.1 skrll status = usb_reserve_allocm(&sc->sc_dma_reserve, dma, size);
239 1.1 skrll return status;
240 1.1 skrll }
241 1.1 skrll
242 1.1 skrll Static void
243 1.1 skrll dwc2_freem(struct usbd_bus *bus, usb_dma_t *dma)
244 1.1 skrll {
245 1.1 skrll struct dwc2_softc *sc = DWC2_BUS2SC(bus);
246 1.1 skrll
247 1.1 skrll DPRINTFN(10, "\n");
248 1.1 skrll
249 1.1 skrll if (dma->block->flags & USB_DMA_RESERVE) {
250 1.1 skrll usb_reserve_freem(&sc->sc_dma_reserve, dma);
251 1.1 skrll return;
252 1.1 skrll }
253 1.1 skrll usb_freemem(&sc->sc_bus, dma);
254 1.1 skrll }
255 1.1 skrll
256 1.1 skrll usbd_xfer_handle
257 1.1 skrll dwc2_allocx(struct usbd_bus *bus)
258 1.1 skrll {
259 1.1 skrll struct dwc2_softc *sc = DWC2_BUS2SC(bus);
260 1.1 skrll struct dwc2_xfer *dxfer;
261 1.1 skrll
262 1.1 skrll DPRINTFN(10, "\n");
263 1.1 skrll
264 1.1 skrll DWC2_EVCNT_INCR(sc->sc_ev_xferpoolget);
265 1.1 skrll dxfer = pool_cache_get(sc->sc_xferpool, PR_NOWAIT);
266 1.1 skrll if (dxfer != NULL) {
267 1.1 skrll memset(dxfer, 0, sizeof(*dxfer));
268 1.1 skrll
269 1.1 skrll dxfer->urb = dwc2_hcd_urb_alloc(sc->sc_hsotg,
270 1.1 skrll DWC2_MAXISOCPACKETS, GFP_KERNEL);
271 1.1 skrll
272 1.1 skrll #ifdef DIAGNOSTIC
273 1.1 skrll dxfer->xfer.busy_free = XFER_BUSY;
274 1.1 skrll #endif
275 1.1 skrll }
276 1.1 skrll return (usbd_xfer_handle)dxfer;
277 1.1 skrll }
278 1.1 skrll
279 1.1 skrll void
280 1.1 skrll dwc2_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
281 1.1 skrll {
282 1.1 skrll struct dwc2_xfer *dxfer = DWC2_XFER2DXFER(xfer);
283 1.1 skrll struct dwc2_softc *sc = DWC2_BUS2SC(bus);
284 1.1 skrll
285 1.1 skrll DPRINTFN(10, "\n");
286 1.1 skrll
287 1.1 skrll #ifdef DIAGNOSTIC
288 1.1 skrll if (xfer->busy_free != XFER_BUSY) {
289 1.1 skrll DPRINTF("xfer=%p not busy, 0x%08x\n", xfer, xfer->busy_free);
290 1.1 skrll }
291 1.1 skrll xfer->busy_free = XFER_FREE;
292 1.1 skrll #endif
293 1.1 skrll DWC2_EVCNT_INCR(sc->sc_ev_xferpoolput);
294 1.1 skrll dwc2_hcd_urb_free(sc->sc_hsotg, dxfer->urb, DWC2_MAXISOCPACKETS);
295 1.1 skrll pool_cache_put(sc->sc_xferpool, xfer);
296 1.1 skrll }
297 1.1 skrll
298 1.1 skrll Static void
299 1.1 skrll dwc2_get_lock(struct usbd_bus *bus, kmutex_t **lock)
300 1.1 skrll {
301 1.1 skrll struct dwc2_softc *sc = DWC2_BUS2SC(bus);
302 1.1 skrll
303 1.1 skrll *lock = &sc->sc_lock;
304 1.1 skrll }
305 1.1 skrll
306 1.1 skrll Static void
307 1.1 skrll dwc2_rhc(void *addr)
308 1.1 skrll {
309 1.1 skrll struct dwc2_softc *sc = addr;
310 1.1 skrll usbd_xfer_handle xfer;
311 1.1 skrll usbd_pipe_handle pipe;
312 1.1 skrll u_char *p;
313 1.1 skrll
314 1.1 skrll DPRINTF("\n");
315 1.1 skrll mutex_enter(&sc->sc_lock);
316 1.1 skrll xfer = sc->sc_intrxfer;
317 1.1 skrll
318 1.1 skrll if (xfer == NULL) {
319 1.1 skrll /* Just ignore the change. */
320 1.1 skrll mutex_exit(&sc->sc_lock);
321 1.1 skrll return;
322 1.1 skrll
323 1.1 skrll }
324 1.1 skrll /* set port bit */
325 1.1 skrll pipe = xfer->pipe;
326 1.1 skrll
327 1.1 skrll p = KERNADDR(&xfer->dmabuf, 0);
328 1.1 skrll
329 1.1 skrll p[0] = 0x02; /* we only have one port (1 << 1) */
330 1.1 skrll
331 1.1 skrll xfer->actlen = xfer->length;
332 1.1 skrll xfer->status = USBD_NORMAL_COMPLETION;
333 1.1 skrll
334 1.1 skrll usb_transfer_complete(xfer);
335 1.1 skrll mutex_exit(&sc->sc_lock);
336 1.1 skrll }
337 1.1 skrll
338 1.1 skrll Static void
339 1.1 skrll dwc2_softintr(void *v)
340 1.1 skrll {
341 1.1 skrll struct usbd_bus *bus = v;
342 1.1 skrll struct dwc2_softc *sc = DWC2_BUS2SC(bus);
343 1.3 skrll struct dwc2_hsotg *hsotg = sc->sc_hsotg;
344 1.1 skrll struct dwc2_xfer *dxfer;
345 1.1 skrll
346 1.1 skrll KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock));
347 1.1 skrll
348 1.3 skrll mutex_spin_enter(&hsotg->lock);
349 1.1 skrll while ((dxfer = TAILQ_FIRST(&sc->sc_complete)) != NULL) {
350 1.1 skrll /*
351 1.1 skrll * dwc2_abort_xfer will remove this transfer from the
352 1.1 skrll * sc_complete queue
353 1.1 skrll */
354 1.1 skrll /*XXXNH not tested */
355 1.1 skrll if (dxfer->xfer.hcflags & UXFER_ABORTING) {
356 1.1 skrll cv_broadcast(&dxfer->xfer.hccv);
357 1.1 skrll continue;
358 1.1 skrll }
359 1.1 skrll
360 1.1 skrll TAILQ_REMOVE(&sc->sc_complete, dxfer, xnext);
361 1.1 skrll /* XXXNH Already done - can I assert this? */
362 1.1 skrll callout_stop(&dxfer->xfer.timeout_handle);
363 1.1 skrll
364 1.3 skrll mutex_spin_exit(&hsotg->lock);
365 1.1 skrll usb_transfer_complete(&dxfer->xfer);
366 1.3 skrll mutex_spin_enter(&hsotg->lock);
367 1.1 skrll }
368 1.3 skrll mutex_spin_exit(&hsotg->lock);
369 1.1 skrll }
370 1.1 skrll
371 1.1 skrll Static void
372 1.1 skrll dwc2_waitintr(struct dwc2_softc *sc, usbd_xfer_handle xfer)
373 1.1 skrll {
374 1.1 skrll struct dwc2_hsotg *hsotg = sc->sc_hsotg;
375 1.1 skrll uint32_t intrs;
376 1.1 skrll int timo;
377 1.1 skrll
378 1.1 skrll xfer->status = USBD_IN_PROGRESS;
379 1.1 skrll for (timo = xfer->timeout; timo >= 0; timo--) {
380 1.1 skrll usb_delay_ms(&sc->sc_bus, 1);
381 1.1 skrll if (sc->sc_dying)
382 1.1 skrll break;
383 1.1 skrll intrs = dwc2_read_core_intr(hsotg);
384 1.1 skrll
385 1.1 skrll DPRINTFN(15, "0x%08x\n", intrs);
386 1.1 skrll
387 1.1 skrll if (intrs) {
388 1.3 skrll mutex_spin_enter(&hsotg->lock);
389 1.1 skrll dwc2_interrupt(sc);
390 1.3 skrll mutex_spin_exit(&hsotg->lock);
391 1.1 skrll if (xfer->status != USBD_IN_PROGRESS)
392 1.1 skrll return;
393 1.1 skrll }
394 1.1 skrll }
395 1.1 skrll
396 1.1 skrll /* Timeout */
397 1.1 skrll DPRINTF("timeout\n");
398 1.1 skrll
399 1.1 skrll mutex_enter(&sc->sc_lock);
400 1.1 skrll xfer->status = USBD_TIMEOUT;
401 1.1 skrll usb_transfer_complete(xfer);
402 1.1 skrll mutex_exit(&sc->sc_lock);
403 1.1 skrll }
404 1.1 skrll
405 1.1 skrll Static void
406 1.1 skrll dwc2_timeout(void *addr)
407 1.1 skrll {
408 1.1 skrll usbd_xfer_handle xfer = addr;
409 1.1 skrll struct dwc2_xfer *dxfer = DWC2_XFER2DXFER(xfer);
410 1.1 skrll // struct dwc2_pipe *dpipe = DWC2_XFER2DPIPE(xfer);
411 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
412 1.1 skrll
413 1.1 skrll DPRINTF("dxfer=%p\n", dxfer);
414 1.1 skrll
415 1.1 skrll if (sc->sc_dying) {
416 1.1 skrll mutex_enter(&sc->sc_lock);
417 1.1 skrll dwc2_abort_xfer(&dxfer->xfer, USBD_TIMEOUT);
418 1.1 skrll mutex_exit(&sc->sc_lock);
419 1.1 skrll return;
420 1.1 skrll }
421 1.1 skrll
422 1.1 skrll /* Execute the abort in a process context. */
423 1.1 skrll usb_init_task(&dxfer->abort_task, dwc2_timeout_task, addr,
424 1.1 skrll USB_TASKQ_MPSAFE);
425 1.1 skrll usb_add_task(dxfer->xfer.pipe->device, &dxfer->abort_task,
426 1.1 skrll USB_TASKQ_HC);
427 1.1 skrll }
428 1.1 skrll
429 1.1 skrll Static void
430 1.1 skrll dwc2_timeout_task(void *addr)
431 1.1 skrll {
432 1.1 skrll usbd_xfer_handle xfer = addr;
433 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
434 1.1 skrll
435 1.1 skrll DPRINTF("xfer=%p\n", xfer);
436 1.1 skrll
437 1.1 skrll mutex_enter(&sc->sc_lock);
438 1.1 skrll dwc2_abort_xfer(xfer, USBD_TIMEOUT);
439 1.1 skrll mutex_exit(&sc->sc_lock);
440 1.1 skrll }
441 1.1 skrll
442 1.1 skrll usbd_status
443 1.1 skrll dwc2_open(usbd_pipe_handle pipe)
444 1.1 skrll {
445 1.1 skrll usbd_device_handle dev = pipe->device;
446 1.1 skrll struct dwc2_softc *sc = DWC2_PIPE2SC(pipe);
447 1.1 skrll struct dwc2_pipe *dpipe = DWC2_PIPE2DPIPE(pipe);
448 1.1 skrll usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
449 1.1 skrll uint8_t addr = dev->address;
450 1.1 skrll uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes);
451 1.1 skrll usbd_status err;
452 1.1 skrll
453 1.1 skrll DPRINTF("pipe %p addr %d xfertype %d dir %s\n", pipe, addr, xfertype,
454 1.1 skrll UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? "in" : "out");
455 1.1 skrll
456 1.1 skrll if (sc->sc_dying) {
457 1.1 skrll return USBD_IOERROR;
458 1.1 skrll }
459 1.1 skrll
460 1.1 skrll if (addr == sc->sc_addr) {
461 1.1 skrll switch (ed->bEndpointAddress) {
462 1.1 skrll case USB_CONTROL_ENDPOINT:
463 1.1 skrll pipe->methods = &dwc2_root_ctrl_methods;
464 1.1 skrll break;
465 1.1 skrll case UE_DIR_IN | DWC2_INTR_ENDPT:
466 1.1 skrll pipe->methods = &dwc2_root_intr_methods;
467 1.1 skrll break;
468 1.1 skrll default:
469 1.1 skrll DPRINTF("bad bEndpointAddress 0x%02x\n",
470 1.1 skrll ed->bEndpointAddress);
471 1.1 skrll return USBD_INVAL;
472 1.1 skrll }
473 1.1 skrll DPRINTF("root hub pipe open\n");
474 1.1 skrll return USBD_NORMAL_COMPLETION;
475 1.1 skrll }
476 1.1 skrll
477 1.1 skrll switch (xfertype) {
478 1.1 skrll case UE_CONTROL:
479 1.1 skrll pipe->methods = &dwc2_device_ctrl_methods;
480 1.1 skrll err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t),
481 1.1 skrll 0, &dpipe->req_dma);
482 1.1 skrll if (err)
483 1.1 skrll return err;
484 1.1 skrll break;
485 1.1 skrll case UE_INTERRUPT:
486 1.1 skrll pipe->methods = &dwc2_device_intr_methods;
487 1.1 skrll break;
488 1.1 skrll case UE_ISOCHRONOUS:
489 1.1 skrll pipe->methods = &dwc2_device_isoc_methods;
490 1.1 skrll break;
491 1.1 skrll case UE_BULK:
492 1.1 skrll pipe->methods = &dwc2_device_bulk_methods;
493 1.1 skrll break;
494 1.1 skrll default:
495 1.1 skrll DPRINTF("bad xfer type %d\n", xfertype);
496 1.1 skrll return USBD_INVAL;
497 1.1 skrll }
498 1.1 skrll
499 1.1 skrll dpipe->priv = NULL; /* QH */
500 1.1 skrll dpipe->xfer = NULL; /* dwc2_urb */
501 1.1 skrll
502 1.1 skrll return USBD_NORMAL_COMPLETION;
503 1.1 skrll }
504 1.1 skrll
505 1.1 skrll Static void
506 1.1 skrll dwc2_poll(struct usbd_bus *bus)
507 1.1 skrll {
508 1.1 skrll struct dwc2_softc *sc = DWC2_BUS2SC(bus);
509 1.3 skrll struct dwc2_hsotg *hsotg = sc->sc_hsotg;
510 1.1 skrll
511 1.3 skrll mutex_spin_enter(&hsotg->lock);
512 1.1 skrll dwc2_interrupt(sc);
513 1.3 skrll mutex_spin_exit(&hsotg->lock);
514 1.1 skrll }
515 1.1 skrll
516 1.1 skrll /*
517 1.1 skrll * Close a reqular pipe.
518 1.1 skrll * Assumes that there are no pending transactions.
519 1.1 skrll */
520 1.1 skrll Static void
521 1.1 skrll dwc2_close_pipe(usbd_pipe_handle pipe)
522 1.1 skrll {
523 1.1 skrll struct dwc2_pipe *dpipe = (struct dwc2_pipe *)pipe;
524 1.1 skrll struct dwc2_softc *sc = pipe->device->bus->hci_private;
525 1.1 skrll
526 1.1 skrll dpipe = dpipe;
527 1.1 skrll
528 1.1 skrll KASSERT(mutex_owned(&sc->sc_lock));
529 1.1 skrll }
530 1.1 skrll
531 1.1 skrll /*
532 1.1 skrll * Abort a device request.
533 1.1 skrll */
534 1.1 skrll Static void
535 1.1 skrll dwc2_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
536 1.1 skrll {
537 1.1 skrll struct dwc2_xfer *dxfer = DWC2_XFER2DXFER(xfer);
538 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
539 1.1 skrll struct dwc2_hsotg *hsotg = sc->sc_hsotg;
540 1.1 skrll struct dwc2_xfer *d, *tmp;
541 1.1 skrll bool wake;
542 1.1 skrll int err;
543 1.1 skrll
544 1.1 skrll DPRINTF("xfer=%p\n", xfer);
545 1.1 skrll
546 1.1 skrll KASSERT(mutex_owned(&sc->sc_lock));
547 1.1 skrll KASSERT(!cpu_intr_p() && !cpu_softintr_p());
548 1.1 skrll
549 1.1 skrll if (sc->sc_dying) {
550 1.1 skrll xfer->status = status;
551 1.1 skrll callout_stop(&xfer->timeout_handle);
552 1.1 skrll usb_transfer_complete(xfer);
553 1.1 skrll return;
554 1.1 skrll }
555 1.1 skrll
556 1.1 skrll /*
557 1.1 skrll * If an abort is already in progress then just wait for it to
558 1.1 skrll * complete and return.
559 1.1 skrll */
560 1.1 skrll if (xfer->hcflags & UXFER_ABORTING) {
561 1.1 skrll xfer->status = status;
562 1.1 skrll xfer->hcflags |= UXFER_ABORTWAIT;
563 1.1 skrll while (xfer->hcflags & UXFER_ABORTING)
564 1.1 skrll cv_wait(&xfer->hccv, &sc->sc_lock);
565 1.1 skrll return;
566 1.1 skrll }
567 1.1 skrll
568 1.1 skrll /*
569 1.1 skrll * Step 1: Make the stack ignore it and stop the callout.
570 1.1 skrll */
571 1.3 skrll mutex_spin_enter(&hsotg->lock);
572 1.1 skrll xfer->hcflags |= UXFER_ABORTING;
573 1.1 skrll
574 1.1 skrll xfer->status = status; /* make software ignore it */
575 1.1 skrll callout_stop(&xfer->timeout_handle);
576 1.1 skrll
577 1.1 skrll /* XXXNH suboptimal */
578 1.1 skrll TAILQ_FOREACH_SAFE(d, &sc->sc_complete, xnext, tmp) {
579 1.1 skrll if (d == dxfer) {
580 1.1 skrll TAILQ_REMOVE(&sc->sc_complete, dxfer, xnext);
581 1.1 skrll }
582 1.1 skrll }
583 1.1 skrll
584 1.1 skrll err = dwc2_hcd_urb_dequeue(hsotg, dxfer->urb);
585 1.1 skrll if (err) {
586 1.1 skrll DPRINTF("dwc2_hcd_urb_dequeue failed\n");
587 1.1 skrll }
588 1.1 skrll
589 1.3 skrll mutex_spin_exit(&hsotg->lock);
590 1.1 skrll
591 1.1 skrll /*
592 1.1 skrll * Step 2: Execute callback.
593 1.1 skrll */
594 1.1 skrll wake = xfer->hcflags & UXFER_ABORTWAIT;
595 1.1 skrll xfer->hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT);
596 1.1 skrll
597 1.1 skrll usb_transfer_complete(xfer);
598 1.1 skrll if (wake) {
599 1.1 skrll cv_broadcast(&xfer->hccv);
600 1.1 skrll }
601 1.1 skrll }
602 1.1 skrll
603 1.1 skrll Static void
604 1.1 skrll dwc2_noop(usbd_pipe_handle pipe)
605 1.1 skrll {
606 1.1 skrll
607 1.1 skrll }
608 1.1 skrll
609 1.1 skrll Static void
610 1.1 skrll dwc2_device_clear_toggle(usbd_pipe_handle pipe)
611 1.1 skrll {
612 1.1 skrll
613 1.1 skrll DPRINTF("toggle %d -> 0", pipe->endpoint->datatoggle);
614 1.1 skrll }
615 1.1 skrll
616 1.1 skrll /***********************************************************************/
617 1.1 skrll
618 1.1 skrll /*
619 1.1 skrll * Data structures and routines to emulate the root hub.
620 1.1 skrll */
621 1.1 skrll
622 1.1 skrll Static const usb_device_descriptor_t dwc2_devd = {
623 1.1 skrll .bLength = sizeof(usb_device_descriptor_t),
624 1.1 skrll .bDescriptorType = UDESC_DEVICE,
625 1.1 skrll .bcdUSB = {0x00, 0x02},
626 1.1 skrll .bDeviceClass = UDCLASS_HUB,
627 1.1 skrll .bDeviceSubClass = UDSUBCLASS_HUB,
628 1.1 skrll .bDeviceProtocol = UDPROTO_HSHUBSTT,
629 1.1 skrll .bMaxPacketSize = 64,
630 1.1 skrll .bcdDevice = {0x00, 0x01},
631 1.1 skrll .iManufacturer = 1,
632 1.1 skrll .iProduct = 2,
633 1.1 skrll .bNumConfigurations = 1,
634 1.1 skrll };
635 1.1 skrll
636 1.1 skrll struct dwc2_config_desc {
637 1.1 skrll usb_config_descriptor_t confd;
638 1.1 skrll usb_interface_descriptor_t ifcd;
639 1.1 skrll usb_endpoint_descriptor_t endpd;
640 1.1 skrll } __packed;
641 1.1 skrll
642 1.1 skrll Static const struct dwc2_config_desc dwc2_confd = {
643 1.1 skrll .confd = {
644 1.1 skrll .bLength = USB_CONFIG_DESCRIPTOR_SIZE,
645 1.1 skrll .bDescriptorType = UDESC_CONFIG,
646 1.1 skrll .wTotalLength[0] = sizeof(dwc2_confd),
647 1.1 skrll .bNumInterface = 1,
648 1.1 skrll .bConfigurationValue = 1,
649 1.1 skrll .iConfiguration = 0,
650 1.1 skrll .bmAttributes = UC_SELF_POWERED,
651 1.1 skrll .bMaxPower = 0,
652 1.1 skrll },
653 1.1 skrll .ifcd = {
654 1.1 skrll .bLength = USB_INTERFACE_DESCRIPTOR_SIZE,
655 1.1 skrll .bDescriptorType = UDESC_INTERFACE,
656 1.1 skrll .bInterfaceNumber = 0,
657 1.1 skrll .bAlternateSetting = 0,
658 1.1 skrll .bNumEndpoints = 1,
659 1.1 skrll .bInterfaceClass = UICLASS_HUB,
660 1.1 skrll .bInterfaceSubClass = UISUBCLASS_HUB,
661 1.1 skrll .bInterfaceProtocol = UIPROTO_HSHUBSTT,
662 1.1 skrll .iInterface = 0
663 1.1 skrll },
664 1.1 skrll .endpd = {
665 1.1 skrll .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE,
666 1.1 skrll .bDescriptorType = UDESC_ENDPOINT,
667 1.1 skrll .bEndpointAddress = UE_DIR_IN | DWC2_INTR_ENDPT,
668 1.1 skrll .bmAttributes = UE_INTERRUPT,
669 1.1 skrll .wMaxPacketSize = {8, 0}, /* max packet */
670 1.1 skrll .bInterval = 255,
671 1.1 skrll },
672 1.1 skrll };
673 1.1 skrll
674 1.1 skrll #define HSETW(ptr, val) ptr = { (uint8_t)(val), (uint8_t)((val) >> 8) }
675 1.1 skrll Static const usb_hub_descriptor_t dwc2_hubd = {
676 1.1 skrll .bDescLength = USB_HUB_DESCRIPTOR_SIZE,
677 1.1 skrll .bDescriptorType = UDESC_HUB,
678 1.1 skrll .bNbrPorts = 1,
679 1.1 skrll HSETW(.wHubCharacteristics, (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL)),
680 1.1 skrll .bPwrOn2PwrGood = 50,
681 1.1 skrll .bHubContrCurrent = 0,
682 1.1 skrll .DeviceRemovable = {0}, /* port is removable */
683 1.1 skrll };
684 1.1 skrll
685 1.1 skrll Static usbd_status
686 1.1 skrll dwc2_root_ctrl_transfer(usbd_xfer_handle xfer)
687 1.1 skrll {
688 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
689 1.1 skrll usbd_status err;
690 1.1 skrll
691 1.1 skrll mutex_enter(&sc->sc_lock);
692 1.1 skrll err = usb_insert_transfer(xfer);
693 1.1 skrll mutex_exit(&sc->sc_lock);
694 1.1 skrll if (err)
695 1.1 skrll return err;
696 1.1 skrll
697 1.1 skrll return dwc2_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
698 1.1 skrll }
699 1.1 skrll
700 1.1 skrll Static usbd_status
701 1.1 skrll dwc2_root_ctrl_start(usbd_xfer_handle xfer)
702 1.1 skrll {
703 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
704 1.1 skrll usb_device_request_t *req;
705 1.1 skrll uint8_t *buf;
706 1.1 skrll uint16_t len;
707 1.1 skrll int value, index, l, totlen;
708 1.1 skrll usbd_status err = USBD_IOERROR;
709 1.1 skrll
710 1.1 skrll if (sc->sc_dying)
711 1.1 skrll return USBD_IOERROR;
712 1.1 skrll
713 1.1 skrll req = &xfer->request;
714 1.1 skrll
715 1.1 skrll DPRINTFN(4, "type=0x%02x request=%02x\n",
716 1.1 skrll req->bmRequestType, req->bRequest);
717 1.1 skrll
718 1.1 skrll len = UGETW(req->wLength);
719 1.1 skrll value = UGETW(req->wValue);
720 1.1 skrll index = UGETW(req->wIndex);
721 1.1 skrll
722 1.1 skrll buf = len ? KERNADDR(&xfer->dmabuf, 0) : NULL;
723 1.1 skrll
724 1.1 skrll totlen = 0;
725 1.1 skrll
726 1.1 skrll #define C(x,y) ((x) | ((y) << 8))
727 1.1 skrll switch (C(req->bRequest, req->bmRequestType)) {
728 1.1 skrll case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
729 1.1 skrll case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
730 1.1 skrll case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
731 1.1 skrll /*
732 1.1 skrll * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
733 1.1 skrll * for the integrated root hub.
734 1.1 skrll */
735 1.1 skrll break;
736 1.1 skrll case C(UR_GET_CONFIG, UT_READ_DEVICE):
737 1.1 skrll if (len > 0) {
738 1.1 skrll *buf = sc->sc_conf;
739 1.1 skrll totlen = 1;
740 1.1 skrll }
741 1.1 skrll break;
742 1.1 skrll case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
743 1.1 skrll DPRINTFN(8, "wValue=0x%04x\n", value);
744 1.1 skrll
745 1.1 skrll if (len == 0)
746 1.1 skrll break;
747 1.1 skrll switch (value) {
748 1.1 skrll case C(0, UDESC_DEVICE):
749 1.1 skrll l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
750 1.1 skrll // USETW(dwc2_devd.idVendor, sc->sc_id_vendor);
751 1.1 skrll memcpy(buf, &dwc2_devd, l);
752 1.1 skrll buf += l;
753 1.1 skrll len -= l;
754 1.1 skrll totlen += l;
755 1.1 skrll
756 1.1 skrll break;
757 1.1 skrll case C(0, UDESC_CONFIG):
758 1.1 skrll l = min(len, sizeof(dwc2_confd));
759 1.1 skrll memcpy(buf, &dwc2_confd, l);
760 1.1 skrll buf += l;
761 1.1 skrll len -= l;
762 1.1 skrll totlen += l;
763 1.1 skrll
764 1.1 skrll break;
765 1.1 skrll #define sd ((usb_string_descriptor_t *)buf)
766 1.1 skrll case C(0, UDESC_STRING):
767 1.1 skrll totlen = usb_makelangtbl(sd, len);
768 1.1 skrll break;
769 1.1 skrll case C(1, UDESC_STRING):
770 1.1 skrll totlen = usb_makestrdesc(sd, len, sc->sc_vendor);
771 1.1 skrll break;
772 1.1 skrll case C(2, UDESC_STRING):
773 1.1 skrll totlen = usb_makestrdesc(sd, len, "DWC2 root hub");
774 1.1 skrll break;
775 1.1 skrll #undef sd
776 1.1 skrll default:
777 1.1 skrll goto fail;
778 1.1 skrll }
779 1.1 skrll break;
780 1.1 skrll case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
781 1.1 skrll if (len > 0) {
782 1.1 skrll *buf = 0;
783 1.1 skrll totlen = 1;
784 1.1 skrll }
785 1.1 skrll break;
786 1.1 skrll case C(UR_GET_STATUS, UT_READ_DEVICE):
787 1.1 skrll if (len > 1) {
788 1.1 skrll USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
789 1.1 skrll totlen = 2;
790 1.1 skrll }
791 1.1 skrll break;
792 1.1 skrll case C(UR_GET_STATUS, UT_READ_INTERFACE):
793 1.1 skrll case C(UR_GET_STATUS, UT_READ_ENDPOINT):
794 1.1 skrll if (len > 1) {
795 1.1 skrll USETW(((usb_status_t *)buf)->wStatus, 0);
796 1.1 skrll totlen = 2;
797 1.1 skrll }
798 1.1 skrll break;
799 1.1 skrll case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
800 1.1 skrll DPRINTF("UR_SET_ADDRESS, UT_WRITE_DEVICE: addr %d\n",
801 1.1 skrll value);
802 1.1 skrll if (value >= USB_MAX_DEVICES)
803 1.1 skrll goto fail;
804 1.1 skrll
805 1.1 skrll sc->sc_addr = value;
806 1.1 skrll break;
807 1.1 skrll case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
808 1.1 skrll if (value != 0 && value != 1)
809 1.1 skrll goto fail;
810 1.1 skrll
811 1.1 skrll sc->sc_conf = value;
812 1.1 skrll break;
813 1.1 skrll case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
814 1.1 skrll break;
815 1.1 skrll case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
816 1.1 skrll case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
817 1.1 skrll case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
818 1.1 skrll err = USBD_IOERROR;
819 1.1 skrll goto fail;
820 1.1 skrll case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
821 1.1 skrll break;
822 1.1 skrll case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
823 1.1 skrll break;
824 1.1 skrll default:
825 1.1 skrll /* Hub requests - XXXNH len check? */
826 1.1 skrll err = dwc2_hcd_hub_control(sc->sc_hsotg,
827 1.1 skrll C(req->bRequest, req->bmRequestType), value, index,
828 1.1 skrll buf, len);
829 1.1 skrll if (err) {
830 1.1 skrll err = USBD_IOERROR;
831 1.1 skrll goto fail;
832 1.1 skrll }
833 1.1 skrll totlen = len;
834 1.1 skrll }
835 1.1 skrll xfer->actlen = totlen;
836 1.1 skrll err = USBD_NORMAL_COMPLETION;
837 1.1 skrll
838 1.1 skrll fail:
839 1.1 skrll mutex_enter(&sc->sc_lock);
840 1.1 skrll xfer->status = err;
841 1.1 skrll usb_transfer_complete(xfer);
842 1.1 skrll mutex_exit(&sc->sc_lock);
843 1.1 skrll
844 1.1 skrll return USBD_IN_PROGRESS;
845 1.1 skrll }
846 1.1 skrll
847 1.1 skrll Static void
848 1.1 skrll dwc2_root_ctrl_abort(usbd_xfer_handle xfer)
849 1.1 skrll {
850 1.1 skrll DPRINTFN(10, "\n");
851 1.1 skrll
852 1.1 skrll /* Nothing to do, all transfers are synchronous. */
853 1.1 skrll }
854 1.1 skrll
855 1.1 skrll Static void
856 1.1 skrll dwc2_root_ctrl_close(usbd_pipe_handle pipe)
857 1.1 skrll {
858 1.1 skrll DPRINTFN(10, "\n");
859 1.1 skrll
860 1.1 skrll /* Nothing to do. */
861 1.1 skrll }
862 1.1 skrll
863 1.1 skrll Static void
864 1.1 skrll dwc2_root_ctrl_done(usbd_xfer_handle xfer)
865 1.1 skrll {
866 1.1 skrll DPRINTFN(10, "\n");
867 1.1 skrll
868 1.1 skrll /* Nothing to do. */
869 1.1 skrll }
870 1.1 skrll
871 1.1 skrll Static usbd_status
872 1.1 skrll dwc2_root_intr_transfer(usbd_xfer_handle xfer)
873 1.1 skrll {
874 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
875 1.1 skrll usbd_status err;
876 1.1 skrll
877 1.1 skrll DPRINTF("\n");
878 1.1 skrll
879 1.1 skrll /* Insert last in queue. */
880 1.1 skrll mutex_enter(&sc->sc_lock);
881 1.1 skrll err = usb_insert_transfer(xfer);
882 1.1 skrll mutex_exit(&sc->sc_lock);
883 1.1 skrll if (err)
884 1.1 skrll return err;
885 1.1 skrll
886 1.1 skrll /* Pipe isn't running, start first */
887 1.1 skrll return dwc2_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
888 1.1 skrll }
889 1.1 skrll
890 1.1 skrll Static usbd_status
891 1.1 skrll dwc2_root_intr_start(usbd_xfer_handle xfer)
892 1.1 skrll {
893 1.1 skrll struct dwc2_softc *sc = DWC2_PIPE2SC(xfer);
894 1.1 skrll
895 1.1 skrll DPRINTF("\n");
896 1.1 skrll
897 1.1 skrll if (sc->sc_dying)
898 1.1 skrll return USBD_IOERROR;
899 1.1 skrll
900 1.1 skrll mutex_enter(&sc->sc_lock);
901 1.1 skrll KASSERT(sc->sc_intrxfer == NULL);
902 1.1 skrll sc->sc_intrxfer = xfer;
903 1.1 skrll mutex_exit(&sc->sc_lock);
904 1.1 skrll
905 1.1 skrll return USBD_IN_PROGRESS;
906 1.1 skrll }
907 1.1 skrll
908 1.1 skrll /* Abort a root interrupt request. */
909 1.1 skrll Static void
910 1.1 skrll dwc2_root_intr_abort(usbd_xfer_handle xfer)
911 1.1 skrll {
912 1.1 skrll #ifdef DIAGNOSTIC
913 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
914 1.1 skrll #endif
915 1.1 skrll DPRINTF("xfer=%p\n", xfer);
916 1.1 skrll
917 1.1 skrll KASSERT(mutex_owned(&sc->sc_lock));
918 1.1 skrll
919 1.1 skrll if (xfer->pipe->intrxfer == xfer) {
920 1.1 skrll DPRINTF("remove\n");
921 1.1 skrll xfer->pipe->intrxfer = NULL;
922 1.1 skrll }
923 1.1 skrll xfer->status = USBD_CANCELLED;
924 1.1 skrll usb_transfer_complete(xfer);
925 1.1 skrll }
926 1.1 skrll
927 1.1 skrll Static void
928 1.1 skrll dwc2_root_intr_close(usbd_pipe_handle pipe)
929 1.1 skrll {
930 1.1 skrll struct dwc2_softc *sc = DWC2_PIPE2SC(pipe);
931 1.1 skrll
932 1.1 skrll DPRINTF("\n");
933 1.1 skrll
934 1.1 skrll KASSERT(mutex_owned(&sc->sc_lock));
935 1.1 skrll
936 1.1 skrll sc->sc_intrxfer = NULL;
937 1.1 skrll }
938 1.1 skrll
939 1.1 skrll Static void
940 1.1 skrll dwc2_root_intr_done(usbd_xfer_handle xfer)
941 1.1 skrll {
942 1.1 skrll
943 1.1 skrll DPRINTF("\n");
944 1.1 skrll }
945 1.1 skrll
946 1.1 skrll /***********************************************************************/
947 1.1 skrll
948 1.1 skrll Static usbd_status
949 1.1 skrll dwc2_device_ctrl_transfer(usbd_xfer_handle xfer)
950 1.1 skrll {
951 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
952 1.1 skrll usbd_status err;
953 1.1 skrll
954 1.1 skrll DPRINTF("\n");
955 1.1 skrll
956 1.1 skrll /* Insert last in queue. */
957 1.1 skrll mutex_enter(&sc->sc_lock);
958 1.1 skrll err = usb_insert_transfer(xfer);
959 1.1 skrll mutex_exit(&sc->sc_lock);
960 1.1 skrll if (err)
961 1.1 skrll return err;
962 1.1 skrll
963 1.1 skrll /* Pipe isn't running, start first */
964 1.1 skrll return dwc2_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
965 1.1 skrll }
966 1.1 skrll
967 1.1 skrll Static usbd_status
968 1.1 skrll dwc2_device_ctrl_start(usbd_xfer_handle xfer)
969 1.1 skrll {
970 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
971 1.8 skrll usbd_status err;
972 1.1 skrll
973 1.1 skrll DPRINTF("\n");
974 1.1 skrll
975 1.1 skrll mutex_enter(&sc->sc_lock);
976 1.1 skrll xfer->status = USBD_IN_PROGRESS;
977 1.8 skrll err = dwc2_device_start(xfer);
978 1.1 skrll mutex_exit(&sc->sc_lock);
979 1.1 skrll
980 1.8 skrll if (err)
981 1.8 skrll return err;
982 1.8 skrll
983 1.1 skrll if (sc->sc_bus.use_polling)
984 1.1 skrll dwc2_waitintr(sc, xfer);
985 1.1 skrll
986 1.1 skrll return USBD_IN_PROGRESS;
987 1.1 skrll }
988 1.1 skrll
989 1.1 skrll Static void
990 1.1 skrll dwc2_device_ctrl_abort(usbd_xfer_handle xfer)
991 1.1 skrll {
992 1.1 skrll #ifdef DIAGNOSTIC
993 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
994 1.1 skrll #endif
995 1.1 skrll KASSERT(mutex_owned(&sc->sc_lock));
996 1.1 skrll
997 1.1 skrll DPRINTF("xfer=%p\n", xfer);
998 1.1 skrll dwc2_abort_xfer(xfer, USBD_CANCELLED);
999 1.1 skrll }
1000 1.1 skrll
1001 1.1 skrll Static void
1002 1.1 skrll dwc2_device_ctrl_close(usbd_pipe_handle pipe)
1003 1.1 skrll {
1004 1.1 skrll
1005 1.1 skrll DPRINTF("pipe=%p\n", pipe);
1006 1.1 skrll dwc2_close_pipe(pipe);
1007 1.1 skrll }
1008 1.1 skrll
1009 1.1 skrll Static void
1010 1.1 skrll dwc2_device_ctrl_done(usbd_xfer_handle xfer)
1011 1.1 skrll {
1012 1.1 skrll
1013 1.1 skrll DPRINTF("xfer=%p\n", xfer);
1014 1.1 skrll }
1015 1.1 skrll
1016 1.1 skrll /***********************************************************************/
1017 1.1 skrll
1018 1.1 skrll Static usbd_status
1019 1.1 skrll dwc2_device_bulk_transfer(usbd_xfer_handle xfer)
1020 1.1 skrll {
1021 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
1022 1.1 skrll usbd_status err;
1023 1.1 skrll
1024 1.1 skrll DPRINTF("xfer=%p\n", xfer);
1025 1.1 skrll
1026 1.1 skrll /* Insert last in queue. */
1027 1.1 skrll mutex_enter(&sc->sc_lock);
1028 1.1 skrll err = usb_insert_transfer(xfer);
1029 1.1 skrll mutex_exit(&sc->sc_lock);
1030 1.1 skrll if (err)
1031 1.1 skrll return err;
1032 1.1 skrll
1033 1.1 skrll /* Pipe isn't running, start first */
1034 1.1 skrll return dwc2_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
1035 1.1 skrll }
1036 1.1 skrll
1037 1.1 skrll Static usbd_status
1038 1.1 skrll dwc2_device_bulk_start(usbd_xfer_handle xfer)
1039 1.1 skrll {
1040 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
1041 1.8 skrll usbd_status err;
1042 1.1 skrll
1043 1.1 skrll DPRINTF("xfer=%p\n", xfer);
1044 1.1 skrll mutex_enter(&sc->sc_lock);
1045 1.1 skrll xfer->status = USBD_IN_PROGRESS;
1046 1.8 skrll err = dwc2_device_start(xfer);
1047 1.1 skrll mutex_exit(&sc->sc_lock);
1048 1.1 skrll
1049 1.8 skrll return err;
1050 1.1 skrll }
1051 1.1 skrll
1052 1.1 skrll Static void
1053 1.1 skrll dwc2_device_bulk_abort(usbd_xfer_handle xfer)
1054 1.1 skrll {
1055 1.1 skrll #ifdef DIAGNOSTIC
1056 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
1057 1.1 skrll #endif
1058 1.1 skrll KASSERT(mutex_owned(&sc->sc_lock));
1059 1.1 skrll
1060 1.1 skrll DPRINTF("xfer=%p\n", xfer);
1061 1.1 skrll dwc2_abort_xfer(xfer, USBD_CANCELLED);
1062 1.1 skrll }
1063 1.1 skrll
1064 1.1 skrll Static void
1065 1.1 skrll dwc2_device_bulk_close(usbd_pipe_handle pipe)
1066 1.1 skrll {
1067 1.1 skrll
1068 1.1 skrll DPRINTF("pipe=%p\n", pipe);
1069 1.1 skrll
1070 1.1 skrll dwc2_close_pipe(pipe);
1071 1.1 skrll }
1072 1.1 skrll
1073 1.1 skrll Static void
1074 1.1 skrll dwc2_device_bulk_done(usbd_xfer_handle xfer)
1075 1.1 skrll {
1076 1.1 skrll
1077 1.1 skrll DPRINTF("xfer=%p\n", xfer);
1078 1.1 skrll }
1079 1.1 skrll
1080 1.1 skrll /***********************************************************************/
1081 1.1 skrll
1082 1.1 skrll Static usbd_status
1083 1.1 skrll dwc2_device_intr_transfer(usbd_xfer_handle xfer)
1084 1.1 skrll {
1085 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
1086 1.1 skrll usbd_status err;
1087 1.1 skrll
1088 1.1 skrll DPRINTF("xfer=%p\n", xfer);
1089 1.1 skrll
1090 1.1 skrll /* Insert last in queue. */
1091 1.1 skrll mutex_enter(&sc->sc_lock);
1092 1.1 skrll err = usb_insert_transfer(xfer);
1093 1.1 skrll mutex_exit(&sc->sc_lock);
1094 1.1 skrll if (err)
1095 1.1 skrll return err;
1096 1.1 skrll
1097 1.1 skrll /* Pipe isn't running, start first */
1098 1.1 skrll return dwc2_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
1099 1.1 skrll }
1100 1.1 skrll
1101 1.1 skrll Static usbd_status
1102 1.1 skrll dwc2_device_intr_start(usbd_xfer_handle xfer)
1103 1.1 skrll {
1104 1.1 skrll struct dwc2_pipe *dpipe = (struct dwc2_pipe *)xfer->pipe;
1105 1.1 skrll usbd_device_handle dev = dpipe->pipe.device;
1106 1.1 skrll struct dwc2_softc *sc = dev->bus->hci_private;
1107 1.8 skrll usbd_status err;
1108 1.1 skrll
1109 1.1 skrll mutex_enter(&sc->sc_lock);
1110 1.1 skrll xfer->status = USBD_IN_PROGRESS;
1111 1.8 skrll err = dwc2_device_start(xfer);
1112 1.1 skrll mutex_exit(&sc->sc_lock);
1113 1.1 skrll
1114 1.8 skrll if (err)
1115 1.8 skrll return err;
1116 1.8 skrll
1117 1.1 skrll if (sc->sc_bus.use_polling)
1118 1.1 skrll dwc2_waitintr(sc, xfer);
1119 1.1 skrll
1120 1.1 skrll return USBD_IN_PROGRESS;
1121 1.1 skrll }
1122 1.1 skrll
1123 1.1 skrll /* Abort a device interrupt request. */
1124 1.1 skrll Static void
1125 1.1 skrll dwc2_device_intr_abort(usbd_xfer_handle xfer)
1126 1.1 skrll {
1127 1.1 skrll #ifdef DIAGNOSTIC
1128 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
1129 1.1 skrll #endif
1130 1.1 skrll
1131 1.1 skrll KASSERT(mutex_owned(&sc->sc_lock));
1132 1.1 skrll
1133 1.1 skrll if (xfer->pipe->intrxfer == xfer) {
1134 1.1 skrll DPRINTF("remove\n");
1135 1.1 skrll xfer->pipe->intrxfer = NULL;
1136 1.1 skrll }
1137 1.1 skrll DPRINTF("xfer=%p\n", xfer);
1138 1.1 skrll dwc2_abort_xfer(xfer, USBD_CANCELLED);
1139 1.1 skrll }
1140 1.1 skrll
1141 1.1 skrll Static void
1142 1.1 skrll dwc2_device_intr_close(usbd_pipe_handle pipe)
1143 1.1 skrll {
1144 1.1 skrll
1145 1.1 skrll DPRINTF("pipe=%p\n", pipe);
1146 1.1 skrll
1147 1.1 skrll dwc2_close_pipe(pipe);
1148 1.1 skrll }
1149 1.1 skrll
1150 1.1 skrll Static void
1151 1.1 skrll dwc2_device_intr_done(usbd_xfer_handle xfer)
1152 1.1 skrll {
1153 1.1 skrll
1154 1.1 skrll DPRINTF("\n");
1155 1.1 skrll
1156 1.1 skrll if (xfer->pipe->repeat) {
1157 1.1 skrll xfer->status = USBD_IN_PROGRESS;
1158 1.1 skrll dwc2_device_start(xfer);
1159 1.1 skrll }
1160 1.1 skrll }
1161 1.1 skrll
1162 1.1 skrll /***********************************************************************/
1163 1.1 skrll
1164 1.1 skrll usbd_status
1165 1.1 skrll dwc2_device_isoc_transfer(usbd_xfer_handle xfer)
1166 1.1 skrll {
1167 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
1168 1.1 skrll usbd_status err;
1169 1.1 skrll
1170 1.1 skrll DPRINTF("xfer=%p\n", xfer);
1171 1.1 skrll
1172 1.1 skrll /* Insert last in queue. */
1173 1.1 skrll mutex_enter(&sc->sc_lock);
1174 1.1 skrll err = usb_insert_transfer(xfer);
1175 1.1 skrll mutex_exit(&sc->sc_lock);
1176 1.1 skrll if (err)
1177 1.1 skrll return err;
1178 1.1 skrll
1179 1.1 skrll /* Pipe isn't running, start first */
1180 1.1 skrll return dwc2_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
1181 1.1 skrll }
1182 1.1 skrll
1183 1.1 skrll usbd_status
1184 1.1 skrll dwc2_device_isoc_start(usbd_xfer_handle xfer)
1185 1.1 skrll {
1186 1.1 skrll struct dwc2_pipe *dpipe = (struct dwc2_pipe *)xfer->pipe;
1187 1.1 skrll usbd_device_handle dev = dpipe->pipe.device;
1188 1.1 skrll struct dwc2_softc *sc = dev->bus->hci_private;
1189 1.8 skrll usbd_status err;
1190 1.1 skrll
1191 1.1 skrll mutex_enter(&sc->sc_lock);
1192 1.1 skrll xfer->status = USBD_IN_PROGRESS;
1193 1.8 skrll err = dwc2_device_start(xfer);
1194 1.1 skrll mutex_exit(&sc->sc_lock);
1195 1.1 skrll
1196 1.1 skrll if (sc->sc_bus.use_polling)
1197 1.1 skrll dwc2_waitintr(sc, xfer);
1198 1.1 skrll
1199 1.8 skrll return err;
1200 1.1 skrll }
1201 1.1 skrll
1202 1.1 skrll void
1203 1.1 skrll dwc2_device_isoc_abort(usbd_xfer_handle xfer)
1204 1.1 skrll {
1205 1.7 skrll #ifdef DIAGNOSTIC
1206 1.7 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
1207 1.7 skrll #endif
1208 1.7 skrll KASSERT(mutex_owned(&sc->sc_lock));
1209 1.7 skrll
1210 1.7 skrll DPRINTF("xfer=%p\n", xfer);
1211 1.7 skrll dwc2_abort_xfer(xfer, USBD_CANCELLED);
1212 1.1 skrll }
1213 1.1 skrll
1214 1.1 skrll void
1215 1.1 skrll dwc2_device_isoc_close(usbd_pipe_handle pipe)
1216 1.1 skrll {
1217 1.1 skrll DPRINTF("\n");
1218 1.1 skrll
1219 1.1 skrll dwc2_close_pipe(pipe);
1220 1.1 skrll }
1221 1.1 skrll
1222 1.1 skrll void
1223 1.1 skrll dwc2_device_isoc_done(usbd_xfer_handle xfer)
1224 1.1 skrll {
1225 1.1 skrll
1226 1.1 skrll DPRINTF("\n");
1227 1.1 skrll }
1228 1.1 skrll
1229 1.1 skrll
1230 1.1 skrll usbd_status
1231 1.1 skrll dwc2_device_start(usbd_xfer_handle xfer)
1232 1.1 skrll {
1233 1.1 skrll struct dwc2_xfer *dxfer = DWC2_XFER2DXFER(xfer);
1234 1.1 skrll struct dwc2_pipe *dpipe = DWC2_XFER2DPIPE(xfer);
1235 1.1 skrll struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
1236 1.1 skrll struct dwc2_hsotg *hsotg = sc->sc_hsotg;
1237 1.1 skrll struct dwc2_hcd_urb *dwc2_urb;
1238 1.1 skrll
1239 1.1 skrll usbd_device_handle dev = xfer->pipe->device;
1240 1.1 skrll usb_endpoint_descriptor_t *ed = xfer->pipe->endpoint->edesc;
1241 1.1 skrll uint8_t addr = dev->address;
1242 1.1 skrll uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes);
1243 1.1 skrll uint8_t epnum = UE_GET_ADDR(ed->bEndpointAddress);
1244 1.1 skrll uint8_t dir = UE_GET_DIR(ed->bEndpointAddress);
1245 1.1 skrll uint16_t mps = UE_GET_SIZE(UGETW(ed->wMaxPacketSize));
1246 1.1 skrll uint32_t len;
1247 1.1 skrll
1248 1.1 skrll uint32_t flags = 0;
1249 1.7 skrll uint32_t off = 0;
1250 1.1 skrll int retval, err = USBD_IN_PROGRESS;
1251 1.1 skrll int alloc_bandwidth = 0;
1252 1.7 skrll int i;
1253 1.1 skrll
1254 1.1 skrll DPRINTFN(1, "xfer=%p pipe=%p\n", xfer, xfer->pipe);
1255 1.1 skrll
1256 1.1 skrll if (xfertype == UE_ISOCHRONOUS ||
1257 1.1 skrll xfertype == UE_INTERRUPT) {
1258 1.3 skrll mutex_spin_enter(&hsotg->lock);
1259 1.1 skrll if (!dwc2_hcd_is_bandwidth_allocated(hsotg, xfer))
1260 1.1 skrll alloc_bandwidth = 1;
1261 1.3 skrll mutex_spin_exit(&hsotg->lock);
1262 1.1 skrll }
1263 1.1 skrll
1264 1.1 skrll /*
1265 1.1 skrll * For Control pipe the direction is from the request, all other
1266 1.1 skrll * transfers have been set correctly at pipe open time.
1267 1.1 skrll */
1268 1.1 skrll if (xfertype == UE_CONTROL) {
1269 1.1 skrll usb_device_request_t *req = &xfer->request;
1270 1.1 skrll
1271 1.4 skrll DPRINTFN(3, "xfer=%p type=0x%02x request=0x%02x wValue=0x%04x "
1272 1.4 skrll "wIndex=0x%04x len=%d addr=%d endpt=%d dir=%s speed=%d "
1273 1.2 skrll "mps=%d\n",
1274 1.1 skrll xfer, req->bmRequestType, req->bRequest, UGETW(req->wValue),
1275 1.1 skrll UGETW(req->wIndex), UGETW(req->wLength), dev->address,
1276 1.2 skrll epnum, dir == UT_READ ? "in" :"out", dev->speed, mps);
1277 1.1 skrll
1278 1.1 skrll /* Copy request packet to our DMA buffer */
1279 1.1 skrll memcpy(KERNADDR(&dpipe->req_dma, 0), req, sizeof(*req));
1280 1.1 skrll usb_syncmem(&dpipe->req_dma, 0, sizeof(*req),
1281 1.1 skrll BUS_DMASYNC_PREWRITE);
1282 1.1 skrll len = UGETW(req->wLength);
1283 1.1 skrll if ((req->bmRequestType & UT_READ) == UT_READ) {
1284 1.1 skrll dir = UE_DIR_IN;
1285 1.1 skrll } else {
1286 1.1 skrll dir = UE_DIR_OUT;
1287 1.1 skrll }
1288 1.1 skrll
1289 1.1 skrll DPRINTFN(3, "req = %p dma = %lx len %d dir %s\n",
1290 1.1 skrll KERNADDR(&dpipe->req_dma, 0), DMAADDR(&dpipe->req_dma, 0),
1291 1.1 skrll len, dir == UE_DIR_IN ? "in" : "out");
1292 1.1 skrll } else {
1293 1.4 skrll DPRINTFN(3, "xfer=%p len=%d flags=%d addr=%d endpt=%d,"
1294 1.2 skrll " mps=%d dir %s\n", xfer, xfer->length, xfer->flags, addr,
1295 1.2 skrll epnum, mps, dir == UT_READ ? "in" :"out");
1296 1.1 skrll
1297 1.1 skrll len = xfer->length;
1298 1.1 skrll }
1299 1.1 skrll
1300 1.1 skrll dwc2_urb = dxfer->urb;
1301 1.1 skrll if (!dwc2_urb)
1302 1.1 skrll return USBD_NOMEM;
1303 1.1 skrll
1304 1.1 skrll memset(dwc2_urb, 0, sizeof(*dwc2_urb));
1305 1.1 skrll
1306 1.1 skrll dwc2_urb->priv = xfer;
1307 1.1 skrll dwc2_hcd_urb_set_pipeinfo(hsotg, dwc2_urb, addr, epnum, xfertype, dir,
1308 1.1 skrll mps);
1309 1.1 skrll
1310 1.1 skrll if (xfertype == UE_CONTROL) {
1311 1.1 skrll dwc2_urb->setup_usbdma = &dpipe->req_dma;
1312 1.1 skrll dwc2_urb->setup_packet = KERNADDR(&dpipe->req_dma, 0);
1313 1.1 skrll dwc2_urb->setup_dma = DMAADDR(&dpipe->req_dma, 0);
1314 1.1 skrll } else {
1315 1.1 skrll /* XXXNH - % mps required? */
1316 1.1 skrll if ((xfer->flags & USBD_FORCE_SHORT_XFER) && (len % mps) == 0)
1317 1.1 skrll flags |= URB_SEND_ZERO_PACKET;
1318 1.1 skrll }
1319 1.1 skrll flags |= URB_GIVEBACK_ASAP;
1320 1.1 skrll
1321 1.7 skrll /* XXXNH this shouldn't be required */
1322 1.7 skrll if (xfertype == UE_CONTROL && len == 0) {
1323 1.7 skrll KASSERT(xfertype == UE_CONTROL);
1324 1.7 skrll dwc2_urb->usbdma = &dpipe->req_dma;
1325 1.7 skrll } else {
1326 1.7 skrll KASSERT(xfertype != UE_CONTROL || len != 0);
1327 1.1 skrll dwc2_urb->usbdma = &xfer->dmabuf;
1328 1.1 skrll }
1329 1.7 skrll dwc2_urb->buf = KERNADDR(dwc2_urb->usbdma, 0);
1330 1.7 skrll dwc2_urb->dma = DMAADDR(dwc2_urb->usbdma, 0);
1331 1.7 skrll dwc2_urb->length = len;
1332 1.1 skrll dwc2_urb->flags = flags;
1333 1.1 skrll dwc2_urb->status = -EINPROGRESS;
1334 1.7 skrll dwc2_urb->packet_count = xfer->nframes;
1335 1.7 skrll
1336 1.7 skrll if (xfertype == UE_INTERRUPT)
1337 1.7 skrll dwc2_urb->interval = dpipe->pipe.interval;
1338 1.7 skrll else if (xfertype == UE_ISOCHRONOUS)
1339 1.7 skrll dwc2_urb->interval = dpipe->pipe.endpoint->edesc->bInterval;
1340 1.1 skrll
1341 1.1 skrll /* XXXNH bring down from callers?? */
1342 1.1 skrll // mutex_enter(&sc->sc_lock);
1343 1.1 skrll
1344 1.1 skrll xfer->actlen = 0;
1345 1.1 skrll
1346 1.7 skrll KASSERT(xfertype != UE_ISOCHRONOUS ||
1347 1.7 skrll xfer->nframes < DWC2_MAXISOCPACKETS);
1348 1.7 skrll KASSERTMSG(xfer->nframes == 0 || xfertype == UE_ISOCHRONOUS,
1349 1.7 skrll "nframes %d xfertype %d\n", xfer->nframes, xfertype);
1350 1.7 skrll
1351 1.7 skrll for (off = i = 0; i < xfer->nframes; ++i) {
1352 1.7 skrll DPRINTFN(3, "xfer=%p frame=%d offset=%d length=%d\n", xfer, i,
1353 1.7 skrll off, xfer->frlengths[i]);
1354 1.7 skrll
1355 1.7 skrll dwc2_hcd_urb_set_iso_desc_params(dwc2_urb, i, off,
1356 1.7 skrll xfer->frlengths[i]);
1357 1.7 skrll off += xfer->frlengths[i];
1358 1.7 skrll }
1359 1.7 skrll
1360 1.1 skrll /* might need to check cpu_intr_p */
1361 1.1 skrll retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, &dpipe->priv, 0);
1362 1.1 skrll if (retval)
1363 1.1 skrll goto fail2;
1364 1.1 skrll
1365 1.1 skrll if (xfer->timeout && !sc->sc_bus.use_polling) {
1366 1.1 skrll callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout),
1367 1.1 skrll dwc2_timeout, xfer);
1368 1.1 skrll }
1369 1.1 skrll
1370 1.1 skrll if (alloc_bandwidth) {
1371 1.7 skrll mutex_spin_enter(&hsotg->lock);
1372 1.7 skrll dwc2_allocate_bus_bandwidth(hsotg,
1373 1.7 skrll dwc2_hcd_get_ep_bandwidth(hsotg, dpipe),
1374 1.7 skrll xfer);
1375 1.7 skrll mutex_spin_exit(&hsotg->lock);
1376 1.1 skrll }
1377 1.1 skrll
1378 1.1 skrll fail2:
1379 1.1 skrll // mutex_exit(&sc->sc_lock);
1380 1.1 skrll
1381 1.1 skrll switch (retval) {
1382 1.1 skrll case 0:
1383 1.1 skrll break;
1384 1.1 skrll case -ENODEV:
1385 1.1 skrll err = USBD_NOMEM;
1386 1.1 skrll break;
1387 1.1 skrll case -ENOMEM:
1388 1.1 skrll err = USBD_NOMEM;
1389 1.1 skrll break;
1390 1.1 skrll default:
1391 1.1 skrll err = USBD_IOERROR;
1392 1.1 skrll }
1393 1.1 skrll
1394 1.1 skrll // fail1:
1395 1.1 skrll if (err) {
1396 1.1 skrll dpipe->xfer = NULL;
1397 1.1 skrll }
1398 1.1 skrll
1399 1.1 skrll return err;
1400 1.1 skrll
1401 1.1 skrll }
1402 1.1 skrll
1403 1.1 skrll void
1404 1.1 skrll dwc2_worker(struct work *wk, void *priv)
1405 1.1 skrll {
1406 1.1 skrll struct dwc2_softc *sc = priv;
1407 1.1 skrll struct dwc2_hsotg *hsotg = sc->sc_hsotg;
1408 1.1 skrll
1409 1.1 skrll Debugger();
1410 1.1 skrll #if 0
1411 1.1 skrll usbd_xfer_handle xfer = dwork->xfer;
1412 1.1 skrll struct dwc2_xfer *dxfer = DWC2_XFER2DXFER(xfer);
1413 1.1 skrll
1414 1.1 skrll dwc2_hcd_endpoint_disable(sc->dwc_dev.hcd, dpipe->priv, 250);
1415 1.1 skrll dwc_free(NULL, dpipe->urb);
1416 1.1 skrll #endif
1417 1.1 skrll
1418 1.1 skrll mutex_enter(&sc->sc_lock);
1419 1.1 skrll if (wk == &hsotg->wf_otg) {
1420 1.1 skrll dwc2_conn_id_status_change(wk);
1421 1.1 skrll } else if (wk == &hsotg->start_work.work) {
1422 1.1 skrll dwc2_hcd_start_func(wk);
1423 1.1 skrll } else if (wk == &hsotg->reset_work.work) {
1424 1.1 skrll dwc2_hcd_reset_func(wk);
1425 1.1 skrll } else {
1426 1.1 skrll #if 0
1427 1.1 skrll KASSERT(dwork->xfer != NULL);
1428 1.1 skrll KASSERT(dxfer->queued == true);
1429 1.1 skrll
1430 1.1 skrll if (!(xfer->hcflags & UXFER_ABORTING)) {
1431 1.1 skrll dwc2_start_standard_chain(xfer);
1432 1.1 skrll }
1433 1.1 skrll dxfer->queued = false;
1434 1.1 skrll cv_broadcast(&xfer->hccv);
1435 1.1 skrll #endif
1436 1.1 skrll }
1437 1.1 skrll mutex_exit(&sc->sc_lock);
1438 1.1 skrll }
1439 1.1 skrll
1440 1.1 skrll int dwc2_intr(void *p)
1441 1.1 skrll {
1442 1.1 skrll struct dwc2_softc *sc = p;
1443 1.3 skrll struct dwc2_hsotg *hsotg;
1444 1.1 skrll int ret = 0;
1445 1.1 skrll
1446 1.1 skrll if (sc == NULL)
1447 1.1 skrll return 0;
1448 1.1 skrll
1449 1.3 skrll hsotg = sc->sc_hsotg;
1450 1.3 skrll mutex_spin_enter(&hsotg->lock);
1451 1.1 skrll
1452 1.1 skrll if (sc->sc_dying || !device_has_power(sc->sc_dev))
1453 1.1 skrll goto done;
1454 1.1 skrll
1455 1.1 skrll if (sc->sc_bus.use_polling) {
1456 1.1 skrll uint32_t intrs;
1457 1.1 skrll
1458 1.1 skrll intrs = dwc2_read_core_intr(hsotg);
1459 1.1 skrll DWC2_WRITE_4(hsotg, GINTSTS, intrs);
1460 1.1 skrll } else {
1461 1.1 skrll ret = dwc2_interrupt(sc);
1462 1.1 skrll }
1463 1.1 skrll
1464 1.1 skrll done:
1465 1.3 skrll mutex_spin_exit(&hsotg->lock);
1466 1.1 skrll
1467 1.1 skrll return ret;
1468 1.1 skrll }
1469 1.1 skrll
1470 1.1 skrll int
1471 1.1 skrll dwc2_interrupt(struct dwc2_softc *sc)
1472 1.1 skrll {
1473 1.1 skrll int ret = 0;
1474 1.1 skrll
1475 1.1 skrll if (sc->sc_hcdenabled) {
1476 1.1 skrll ret |= dwc2_handle_hcd_intr(sc->sc_hsotg);
1477 1.1 skrll }
1478 1.1 skrll
1479 1.1 skrll ret |= dwc2_handle_common_intr(sc->sc_hsotg);
1480 1.1 skrll
1481 1.1 skrll return ret;
1482 1.1 skrll }
1483 1.1 skrll
1484 1.1 skrll /***********************************************************************/
1485 1.1 skrll
1486 1.1 skrll int
1487 1.1 skrll dwc2_detach(struct dwc2_softc *sc, int flags)
1488 1.1 skrll {
1489 1.1 skrll int rv = 0;
1490 1.1 skrll
1491 1.1 skrll if (sc->sc_child != NULL)
1492 1.1 skrll rv = config_detach(sc->sc_child, flags);
1493 1.1 skrll
1494 1.1 skrll return rv;
1495 1.1 skrll }
1496 1.1 skrll
1497 1.1 skrll bool
1498 1.1 skrll dwc2_shutdown(device_t self, int flags)
1499 1.1 skrll {
1500 1.1 skrll struct dwc2_softc *sc = device_private(self);
1501 1.1 skrll
1502 1.1 skrll sc = sc;
1503 1.1 skrll
1504 1.1 skrll return true;
1505 1.1 skrll }
1506 1.1 skrll
1507 1.1 skrll void
1508 1.1 skrll dwc2_childdet(device_t self, device_t child)
1509 1.1 skrll {
1510 1.1 skrll struct dwc2_softc *sc = device_private(self);
1511 1.1 skrll
1512 1.1 skrll sc = sc;
1513 1.1 skrll }
1514 1.1 skrll
1515 1.1 skrll int
1516 1.1 skrll dwc2_activate(device_t self, enum devact act)
1517 1.1 skrll {
1518 1.1 skrll struct dwc2_softc *sc = device_private(self);
1519 1.1 skrll
1520 1.1 skrll sc = sc;
1521 1.1 skrll
1522 1.1 skrll return 0;
1523 1.1 skrll }
1524 1.1 skrll
1525 1.1 skrll bool
1526 1.1 skrll dwc2_resume(device_t dv, const pmf_qual_t *qual)
1527 1.1 skrll {
1528 1.1 skrll struct dwc2_softc *sc = device_private(dv);
1529 1.1 skrll
1530 1.1 skrll sc = sc;
1531 1.1 skrll
1532 1.1 skrll return true;
1533 1.1 skrll }
1534 1.1 skrll
1535 1.1 skrll bool
1536 1.1 skrll dwc2_suspend(device_t dv, const pmf_qual_t *qual)
1537 1.1 skrll {
1538 1.1 skrll struct dwc2_softc *sc = device_private(dv);
1539 1.1 skrll
1540 1.1 skrll sc = sc;
1541 1.1 skrll
1542 1.1 skrll return true;
1543 1.1 skrll }
1544 1.1 skrll
1545 1.1 skrll /***********************************************************************/
1546 1.1 skrll Static int
1547 1.1 skrll dwc2_init(struct dwc2_softc *sc)
1548 1.1 skrll {
1549 1.1 skrll int err = 0;
1550 1.1 skrll
1551 1.1 skrll sc->sc_bus.hci_private = sc;
1552 1.1 skrll sc->sc_bus.usbrev = USBREV_2_0;
1553 1.1 skrll sc->sc_bus.methods = &dwc2_bus_methods;
1554 1.1 skrll sc->sc_bus.pipe_size = sizeof(struct dwc2_pipe);
1555 1.1 skrll sc->sc_hcdenabled = false;
1556 1.1 skrll
1557 1.1 skrll mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
1558 1.1 skrll
1559 1.1 skrll TAILQ_INIT(&sc->sc_complete);
1560 1.1 skrll
1561 1.1 skrll sc->sc_rhc_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
1562 1.1 skrll dwc2_rhc, sc);
1563 1.1 skrll
1564 1.1 skrll usb_setup_reserve(sc->sc_dev, &sc->sc_dma_reserve, sc->sc_bus.dmatag,
1565 1.1 skrll USB_MEM_RESERVE);
1566 1.1 skrll
1567 1.1 skrll sc->sc_xferpool = pool_cache_init(sizeof(struct dwc2_xfer), 0, 0, 0,
1568 1.1 skrll "dwc2xfer", NULL, IPL_USB, NULL, NULL, NULL);
1569 1.1 skrll sc->sc_qhpool = pool_cache_init(sizeof(struct dwc2_qh), 0, 0, 0,
1570 1.1 skrll "dwc2qh", NULL, IPL_USB, NULL, NULL, NULL);
1571 1.1 skrll sc->sc_qtdpool = pool_cache_init(sizeof(struct dwc2_qtd), 0, 0, 0,
1572 1.1 skrll "dwc2qtd", NULL, IPL_USB, NULL, NULL, NULL);
1573 1.1 skrll
1574 1.1 skrll sc->sc_hsotg = kmem_zalloc(sizeof(struct dwc2_hsotg), KM_SLEEP);
1575 1.1 skrll if (sc->sc_hsotg == NULL) {
1576 1.1 skrll err = ENOMEM;
1577 1.1 skrll goto fail1;
1578 1.1 skrll }
1579 1.1 skrll
1580 1.1 skrll sc->sc_hsotg->hsotg_sc = sc;
1581 1.1 skrll sc->sc_hsotg->dev = sc->sc_dev;
1582 1.1 skrll sc->sc_hcdenabled = true;
1583 1.1 skrll
1584 1.1 skrll err = dwc2_hcd_init(sc->sc_hsotg, sc->sc_params);
1585 1.1 skrll if (err) {
1586 1.1 skrll err = -err;
1587 1.1 skrll goto fail2;
1588 1.1 skrll }
1589 1.1 skrll
1590 1.1 skrll return 0;
1591 1.1 skrll
1592 1.1 skrll fail2:
1593 1.1 skrll kmem_free(sc->sc_hsotg, sizeof(struct dwc2_hsotg));
1594 1.1 skrll fail1:
1595 1.1 skrll softint_disestablish(sc->sc_rhc_si);
1596 1.1 skrll
1597 1.1 skrll return err;
1598 1.1 skrll }
1599 1.1 skrll
1600 1.1 skrll #if 0
1601 1.1 skrll /*
1602 1.1 skrll * curmode is a mode indication bit 0 = device, 1 = host
1603 1.1 skrll */
1604 1.1 skrll static const char * const intnames[32] = {
1605 1.1 skrll "curmode", "modemis", "otgint", "sof",
1606 1.1 skrll "rxflvl", "nptxfemp", "ginnakeff", "goutnakeff",
1607 1.1 skrll "ulpickint", "i2cint", "erlysusp", "usbsusp",
1608 1.1 skrll "usbrst", "enumdone", "isooutdrop", "eopf",
1609 1.1 skrll "restore_done", "epmis", "iepint", "oepint",
1610 1.1 skrll "incompisoin", "incomplp", "fetsusp", "resetdet",
1611 1.1 skrll "prtint", "hchint", "ptxfemp", "lpm",
1612 1.1 skrll "conidstschng", "disconnint", "sessreqint", "wkupint"
1613 1.1 skrll };
1614 1.1 skrll
1615 1.1 skrll
1616 1.1 skrll /***********************************************************************/
1617 1.1 skrll
1618 1.1 skrll #endif
1619 1.1 skrll
1620 1.1 skrll
1621 1.1 skrll void
1622 1.1 skrll dw_callout(void *arg)
1623 1.1 skrll {
1624 1.1 skrll struct delayed_work *dw = arg;
1625 1.1 skrll
1626 1.1 skrll workqueue_enqueue(dw->dw_wq, &dw->work, NULL);
1627 1.1 skrll }
1628 1.1 skrll
1629 1.1 skrll void dwc2_host_hub_info(struct dwc2_hsotg *hsotg, void *context, int *hub_addr,
1630 1.1 skrll int *hub_port)
1631 1.1 skrll {
1632 1.1 skrll usbd_xfer_handle xfer = context;
1633 1.1 skrll struct dwc2_pipe *dpipe = DWC2_XFER2DPIPE(xfer);
1634 1.1 skrll usbd_device_handle dev = dpipe->pipe.device;
1635 1.1 skrll
1636 1.1 skrll *hub_addr = dev->myhsport->parent->address;
1637 1.1 skrll *hub_port = dev->myhsport->portno;
1638 1.1 skrll }
1639 1.1 skrll
1640 1.1 skrll int dwc2_host_get_speed(struct dwc2_hsotg *hsotg, void *context)
1641 1.1 skrll {
1642 1.1 skrll usbd_xfer_handle xfer = context;
1643 1.1 skrll struct dwc2_pipe *dpipe = DWC2_XFER2DPIPE(xfer);
1644 1.1 skrll usbd_device_handle dev = dpipe->pipe.device;
1645 1.1 skrll
1646 1.1 skrll return dev->speed;
1647 1.1 skrll }
1648 1.1 skrll
1649 1.1 skrll /*
1650 1.1 skrll * Sets the final status of an URB and returns it to the upper layer. Any
1651 1.1 skrll * required cleanup of the URB is performed.
1652 1.1 skrll *
1653 1.1 skrll * Must be called with interrupt disabled and spinlock held
1654 1.1 skrll */
1655 1.1 skrll void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
1656 1.1 skrll int status)
1657 1.1 skrll {
1658 1.1 skrll usbd_xfer_handle xfer;
1659 1.1 skrll struct dwc2_xfer *dxfer;
1660 1.1 skrll struct dwc2_softc *sc;
1661 1.1 skrll usb_endpoint_descriptor_t *ed;
1662 1.1 skrll uint8_t xfertype;
1663 1.1 skrll
1664 1.1 skrll if (!qtd) {
1665 1.1 skrll dev_dbg(hsotg->dev, "## %s: qtd is NULL ##\n", __func__);
1666 1.1 skrll return;
1667 1.1 skrll }
1668 1.1 skrll
1669 1.1 skrll if (!qtd->urb) {
1670 1.1 skrll dev_dbg(hsotg->dev, "## %s: qtd->urb is NULL ##\n", __func__);
1671 1.1 skrll return;
1672 1.1 skrll }
1673 1.1 skrll
1674 1.1 skrll xfer = qtd->urb->priv;
1675 1.1 skrll if (!xfer) {
1676 1.1 skrll dev_dbg(hsotg->dev, "## %s: urb->priv is NULL ##\n", __func__);
1677 1.1 skrll return;
1678 1.1 skrll }
1679 1.1 skrll
1680 1.1 skrll dxfer = DWC2_XFER2DXFER(xfer);
1681 1.1 skrll sc = DWC2_XFER2SC(xfer);
1682 1.1 skrll ed = xfer->pipe->endpoint->edesc;
1683 1.1 skrll xfertype = UE_GET_XFERTYPE(ed->bmAttributes);
1684 1.1 skrll
1685 1.1 skrll xfer->actlen = dwc2_hcd_urb_get_actual_length(qtd->urb);
1686 1.1 skrll
1687 1.1 skrll if (xfertype == UE_ISOCHRONOUS && dbg_perio()) {
1688 1.1 skrll int i;
1689 1.1 skrll
1690 1.7 skrll for (i = 0; i < xfer->nframes; i++)
1691 1.1 skrll dev_vdbg(hsotg->dev, " ISO Desc %d status %d\n",
1692 1.7 skrll i, qtd->urb->iso_descs[i].status);
1693 1.1 skrll }
1694 1.1 skrll
1695 1.1 skrll if (xfertype == UE_ISOCHRONOUS) {
1696 1.7 skrll int i;
1697 1.7 skrll
1698 1.7 skrll xfer->actlen = 0;
1699 1.7 skrll for (i = 0; i < xfer->nframes; ++i) {
1700 1.7 skrll xfer->frlengths[i] =
1701 1.1 skrll dwc2_hcd_urb_get_iso_desc_actual_length(
1702 1.1 skrll qtd->urb, i);
1703 1.7 skrll xfer->actlen += xfer->frlengths[i];
1704 1.1 skrll }
1705 1.1 skrll }
1706 1.7 skrll
1707 1.1 skrll if (!status) {
1708 1.1 skrll if (!(xfer->flags & USBD_SHORT_XFER_OK) &&
1709 1.1 skrll xfer->actlen < xfer->length)
1710 1.1 skrll status = -EIO;
1711 1.1 skrll }
1712 1.1 skrll
1713 1.1 skrll switch (status) {
1714 1.1 skrll case 0:
1715 1.1 skrll xfer->status = USBD_NORMAL_COMPLETION;
1716 1.1 skrll break;
1717 1.1 skrll case -EPIPE:
1718 1.1 skrll xfer->status = USBD_STALLED;
1719 1.1 skrll break;
1720 1.1 skrll case -ETIMEDOUT:
1721 1.1 skrll xfer->status = USBD_TIMEOUT;
1722 1.1 skrll break;
1723 1.1 skrll case -EPROTO:
1724 1.1 skrll xfer->status = USBD_INVAL;
1725 1.1 skrll break;
1726 1.1 skrll case -EIO:
1727 1.1 skrll xfer->status = USBD_IOERROR;
1728 1.1 skrll break;
1729 1.1 skrll case -EOVERFLOW:
1730 1.1 skrll xfer->status = USBD_IOERROR;
1731 1.1 skrll break;
1732 1.1 skrll default:
1733 1.1 skrll printf("%s: unknown error status %d\n", __func__, status);
1734 1.1 skrll }
1735 1.1 skrll
1736 1.1 skrll if (xfertype == UE_ISOCHRONOUS ||
1737 1.1 skrll xfertype == UE_INTERRUPT) {
1738 1.7 skrll struct dwc2_pipe *dpipe = DWC2_XFER2DPIPE(xfer);
1739 1.1 skrll
1740 1.7 skrll dwc2_free_bus_bandwidth(hsotg,
1741 1.7 skrll dwc2_hcd_get_ep_bandwidth(hsotg, dpipe),
1742 1.7 skrll xfer);
1743 1.1 skrll }
1744 1.1 skrll
1745 1.1 skrll qtd->urb = NULL;
1746 1.1 skrll callout_stop(&xfer->timeout_handle);
1747 1.1 skrll
1748 1.5 skrll KASSERT(mutex_owned(&hsotg->lock));
1749 1.1 skrll
1750 1.1 skrll TAILQ_INSERT_TAIL(&sc->sc_complete, dxfer, xnext);
1751 1.1 skrll
1752 1.1 skrll usb_schedsoftintr(&sc->sc_bus);
1753 1.1 skrll }
1754 1.1 skrll
1755 1.1 skrll
1756 1.1 skrll int
1757 1.1 skrll _dwc2_hcd_start(struct dwc2_hsotg *hsotg)
1758 1.1 skrll {
1759 1.1 skrll dev_dbg(hsotg->dev, "DWC OTG HCD START\n");
1760 1.1 skrll
1761 1.3 skrll mutex_spin_enter(&hsotg->lock);
1762 1.1 skrll
1763 1.1 skrll hsotg->op_state = OTG_STATE_A_HOST;
1764 1.1 skrll
1765 1.1 skrll dwc2_hcd_reinit(hsotg);
1766 1.1 skrll
1767 1.1 skrll /*XXXNH*/
1768 1.1 skrll delay(50);
1769 1.1 skrll
1770 1.3 skrll mutex_spin_exit(&hsotg->lock);
1771 1.1 skrll return 0;
1772 1.1 skrll }
1773 1.6 skrll
1774 1.6 skrll int dwc2_host_is_b_hnp_enabled(struct dwc2_hsotg *hsotg)
1775 1.6 skrll {
1776 1.6 skrll
1777 1.6 skrll return false;
1778 1.6 skrll }
1779