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