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