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