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