3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * Thanks to Mentor Graphics for providing a reference driver for this USB chip
33 * This file contains the driver for the Mentor Graphics Inventra USB
34 * 2.0 High Speed Dual-Role controller.
36 * NOTE: The current implementation only supports Device Side Mode!
39 #include <sys/stdint.h>
40 #include <sys/stddef.h>
41 #include <sys/param.h>
42 #include <sys/queue.h>
43 #include <sys/types.h>
44 #include <sys/systm.h>
45 #include <sys/kernel.h>
47 #include <sys/linker_set.h>
48 #include <sys/module.h>
50 #include <sys/mutex.h>
51 #include <sys/condvar.h>
52 #include <sys/sysctl.h>
54 #include <sys/unistd.h>
55 #include <sys/callout.h>
56 #include <sys/malloc.h>
59 #include <dev/usb/usb.h>
60 #include <dev/usb/usbdi.h>
62 #define USB_DEBUG_VAR musbotgdebug
64 #include <dev/usb/usb_core.h>
65 #include <dev/usb/usb_debug.h>
66 #include <dev/usb/usb_busdma.h>
67 #include <dev/usb/usb_process.h>
68 #include <dev/usb/usb_transfer.h>
69 #include <dev/usb/usb_device.h>
70 #include <dev/usb/usb_hub.h>
71 #include <dev/usb/usb_util.h>
73 #include <dev/usb/usb_controller.h>
74 #include <dev/usb/usb_bus.h>
75 #include <dev/usb/controller/musb_otg.h>
77 #define MUSBOTG_INTR_ENDPT 1
79 #define MUSBOTG_BUS2SC(bus) \
80 ((struct musbotg_softc *)(((uint8_t *)(bus)) - \
81 USB_P2U(&(((struct musbotg_softc *)0)->sc_bus))))
83 #define MUSBOTG_PC2SC(pc) \
84 MUSBOTG_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus)
87 static int musbotgdebug = 0;
89 SYSCTL_NODE(_hw_usb, OID_AUTO, musbotg, CTLFLAG_RW, 0, "USB musbotg");
90 SYSCTL_INT(_hw_usb_musbotg, OID_AUTO, debug, CTLFLAG_RW,
91 &musbotgdebug, 0, "Debug level");
96 struct usb_bus_methods musbotg_bus_methods;
97 struct usb_pipe_methods musbotg_device_bulk_methods;
98 struct usb_pipe_methods musbotg_device_ctrl_methods;
99 struct usb_pipe_methods musbotg_device_intr_methods;
100 struct usb_pipe_methods musbotg_device_isoc_methods;
102 static musbotg_cmd_t musbotg_setup_rx;
103 static musbotg_cmd_t musbotg_setup_data_rx;
104 static musbotg_cmd_t musbotg_setup_data_tx;
105 static musbotg_cmd_t musbotg_setup_status;
106 static musbotg_cmd_t musbotg_data_rx;
107 static musbotg_cmd_t musbotg_data_tx;
108 static void musbotg_device_done(struct usb_xfer *, usb_error_t);
109 static void musbotg_do_poll(struct usb_bus *);
110 static void musbotg_standard_done(struct usb_xfer *);
111 static void musbotg_interrupt_poll(struct musbotg_softc *);
112 static void musbotg_root_intr(struct musbotg_softc *);
115 * Here is a configuration that the chip supports.
117 static const struct usb_hw_ep_profile musbotg_ep_profile[1] = {
120 .max_in_frame_size = 64,/* fixed */
121 .max_out_frame_size = 64, /* fixed */
123 .support_control = 1,
128 musbotg_get_hw_ep_profile(struct usb_device *udev,
129 const struct usb_hw_ep_profile **ppf, uint8_t ep_addr)
131 struct musbotg_softc *sc;
133 sc = MUSBOTG_BUS2SC(udev->bus);
136 /* control endpoint */
137 *ppf = musbotg_ep_profile;
138 } else if (ep_addr <= sc->sc_ep_max) {
139 /* other endpoints */
140 *ppf = sc->sc_hw_ep_profile + ep_addr;
147 musbotg_clocks_on(struct musbotg_softc *sc)
149 if (sc->sc_flags.clocks_off &&
150 sc->sc_flags.port_powered) {
154 if (sc->sc_clocks_on) {
155 (sc->sc_clocks_on) (sc->sc_clocks_arg);
157 sc->sc_flags.clocks_off = 0;
159 /* XXX enable Transceiver */
164 musbotg_clocks_off(struct musbotg_softc *sc)
166 if (!sc->sc_flags.clocks_off) {
170 /* XXX disable Transceiver */
172 if (sc->sc_clocks_off) {
173 (sc->sc_clocks_off) (sc->sc_clocks_arg);
175 sc->sc_flags.clocks_off = 1;
180 musbotg_pull_common(struct musbotg_softc *sc, uint8_t on)
184 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
186 temp |= MUSB2_MASK_SOFTC;
188 temp &= ~MUSB2_MASK_SOFTC;
190 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
194 musbotg_pull_up(struct musbotg_softc *sc)
196 /* pullup D+, if possible */
198 if (!sc->sc_flags.d_pulled_up &&
199 sc->sc_flags.port_powered) {
200 sc->sc_flags.d_pulled_up = 1;
201 musbotg_pull_common(sc, 1);
206 musbotg_pull_down(struct musbotg_softc *sc)
208 /* pulldown D+, if possible */
210 if (sc->sc_flags.d_pulled_up) {
211 sc->sc_flags.d_pulled_up = 0;
212 musbotg_pull_common(sc, 0);
217 musbotg_wakeup_peer(struct musbotg_softc *sc)
221 if (!(sc->sc_flags.status_suspend)) {
225 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
226 temp |= MUSB2_MASK_RESUME;
227 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
229 /* wait 8 milliseconds */
230 /* Wait for reset to complete. */
231 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 125);
233 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
234 temp &= ~MUSB2_MASK_RESUME;
235 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
239 musbotg_set_address(struct musbotg_softc *sc, uint8_t addr)
241 DPRINTFN(4, "addr=%d\n", addr);
243 MUSB2_WRITE_1(sc, MUSB2_REG_FADDR, addr);
247 musbotg_setup_rx(struct musbotg_td *td)
249 struct musbotg_softc *sc;
250 struct usb_device_request req;
254 /* get pointer to softc */
255 sc = MUSBOTG_PC2SC(td->pc);
257 /* select endpoint 0 */
258 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
260 /* read out FIFO status */
261 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
263 DPRINTFN(4, "csr=0x%02x\n", csr);
266 * NOTE: If DATAEND is set we should not call the
267 * callback, hence the status stage is not complete.
269 if (csr & MUSB2_MASK_CSR0L_DATAEND) {
270 /* do not stall at this point */
272 /* wait for interrupt */
275 if (csr & MUSB2_MASK_CSR0L_SENTSTALL) {
276 /* clear SENTSTALL */
277 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
278 /* get latest status */
279 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
280 /* update EP0 state */
283 if (csr & MUSB2_MASK_CSR0L_SETUPEND) {
285 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
286 MUSB2_MASK_CSR0L_SETUPEND_CLR);
287 /* get latest status */
288 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
289 /* update EP0 state */
292 if (sc->sc_ep0_busy) {
295 if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
298 /* clear did stall flag */
300 /* get the packet byte count */
301 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
303 /* verify data length */
304 if (count != td->remainder) {
305 DPRINTFN(0, "Invalid SETUP packet "
306 "length, %d bytes\n", count);
307 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
308 MUSB2_MASK_CSR0L_RXPKTRDY_CLR);
311 if (count != sizeof(req)) {
312 DPRINTFN(0, "Unsupported SETUP packet "
313 "length, %d bytes\n", count);
314 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
315 MUSB2_MASK_CSR0L_RXPKTRDY_CLR);
319 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
320 MUSB2_REG_EPFIFO(0), (void *)&req, sizeof(req));
322 /* copy data into real buffer */
323 usbd_copy_in(td->pc, 0, &req, sizeof(req));
325 td->offset = sizeof(req);
328 /* set pending command */
329 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_RXPKTRDY_CLR;
331 /* we need set stall or dataend after this */
334 /* sneak peek the set address */
335 if ((req.bmRequestType == UT_WRITE_DEVICE) &&
336 (req.bRequest == UR_SET_ADDRESS)) {
337 sc->sc_dv_addr = req.wValue[0] & 0x7F;
339 sc->sc_dv_addr = 0xFF;
341 return (0); /* complete */
344 /* abort any ongoing transfer */
345 if (!td->did_stall) {
346 DPRINTFN(4, "stalling\n");
347 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
348 MUSB2_MASK_CSR0L_SENDSTALL);
351 return (1); /* not complete */
354 /* Control endpoint only data handling functions (RX/TX/SYNC) */
357 musbotg_setup_data_rx(struct musbotg_td *td)
359 struct usb_page_search buf_res;
360 struct musbotg_softc *sc;
365 /* get pointer to softc */
366 sc = MUSBOTG_PC2SC(td->pc);
368 /* select endpoint 0 */
369 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
371 /* check if a command is pending */
372 if (sc->sc_ep0_cmd) {
373 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
376 /* read out FIFO status */
377 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
379 DPRINTFN(4, "csr=0x%02x\n", csr);
383 if (csr & (MUSB2_MASK_CSR0L_SETUPEND |
384 MUSB2_MASK_CSR0L_SENTSTALL)) {
385 if (td->remainder == 0) {
387 * We are actually complete and have
388 * received the next SETUP
390 DPRINTFN(4, "faking complete\n");
391 return (0); /* complete */
394 * USB Host Aborted the transfer.
397 return (0); /* complete */
399 if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
400 return (1); /* not complete */
402 /* get the packet byte count */
403 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
405 /* verify the packet byte count */
406 if (count != td->max_frame_size) {
407 if (count < td->max_frame_size) {
408 /* we have a short packet */
412 /* invalid USB packet */
414 return (0); /* we are complete */
417 /* verify the packet byte count */
418 if (count > td->remainder) {
419 /* invalid USB packet */
421 return (0); /* we are complete */
426 usbd_get_page(td->pc, td->offset, &buf_res);
428 /* get correct length */
429 if (buf_res.length > count) {
430 buf_res.length = count;
432 /* check for unaligned memory address */
433 if (USB_P2U(buf_res.buffer) & 3) {
438 /* receive data 4 bytes at a time */
439 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
440 MUSB2_REG_EPFIFO(0), sc->sc_bounce_buf,
445 /* receive data 1 byte at a time */
446 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
448 (void *)(&sc->sc_bounce_buf[count / 4]), temp);
450 usbd_copy_in(td->pc, td->offset,
451 sc->sc_bounce_buf, count);
453 /* update offset and remainder */
455 td->remainder -= count;
458 /* check if we can optimise */
459 if (buf_res.length >= 4) {
461 /* receive data 4 bytes at a time */
462 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
463 MUSB2_REG_EPFIFO(0), buf_res.buffer,
466 temp = buf_res.length & ~3;
468 /* update counters */
471 td->remainder -= temp;
475 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
476 MUSB2_REG_EPFIFO(0), buf_res.buffer, buf_res.length);
478 /* update counters */
479 count -= buf_res.length;
480 td->offset += buf_res.length;
481 td->remainder -= buf_res.length;
484 /* check if we are complete */
485 if ((td->remainder == 0) || got_short) {
487 /* we are complete */
488 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_RXPKTRDY_CLR;
491 /* else need to receive a zero length packet */
493 /* write command - need more data */
494 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
495 MUSB2_MASK_CSR0L_RXPKTRDY_CLR);
496 return (1); /* not complete */
500 musbotg_setup_data_tx(struct musbotg_td *td)
502 struct usb_page_search buf_res;
503 struct musbotg_softc *sc;
507 /* get pointer to softc */
508 sc = MUSBOTG_PC2SC(td->pc);
510 /* select endpoint 0 */
511 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
513 /* check if a command is pending */
514 if (sc->sc_ep0_cmd) {
515 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
518 /* read out FIFO status */
519 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
521 DPRINTFN(4, "csr=0x%02x\n", csr);
523 if (csr & (MUSB2_MASK_CSR0L_SETUPEND |
524 MUSB2_MASK_CSR0L_SENTSTALL)) {
526 * The current transfer was aborted
530 return (0); /* complete */
532 if (csr & MUSB2_MASK_CSR0L_TXPKTRDY) {
533 return (1); /* not complete */
535 count = td->max_frame_size;
536 if (td->remainder < count) {
537 /* we have a short packet */
539 count = td->remainder;
544 usbd_get_page(td->pc, td->offset, &buf_res);
546 /* get correct length */
547 if (buf_res.length > count) {
548 buf_res.length = count;
550 /* check for unaligned memory address */
551 if (USB_P2U(buf_res.buffer) & 3) {
553 usbd_copy_out(td->pc, td->offset,
554 sc->sc_bounce_buf, count);
559 /* transmit data 4 bytes at a time */
560 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
561 MUSB2_REG_EPFIFO(0), sc->sc_bounce_buf,
566 /* receive data 1 byte at a time */
567 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
569 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
571 /* update offset and remainder */
573 td->remainder -= count;
576 /* check if we can optimise */
577 if (buf_res.length >= 4) {
579 /* transmit data 4 bytes at a time */
580 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
581 MUSB2_REG_EPFIFO(0), buf_res.buffer,
584 temp = buf_res.length & ~3;
586 /* update counters */
589 td->remainder -= temp;
593 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
594 MUSB2_REG_EPFIFO(0), buf_res.buffer, buf_res.length);
596 /* update counters */
597 count -= buf_res.length;
598 td->offset += buf_res.length;
599 td->remainder -= buf_res.length;
602 /* check remainder */
603 if (td->remainder == 0) {
605 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_TXPKTRDY;
606 return (0); /* complete */
608 /* else we need to transmit a short packet */
611 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
612 MUSB2_MASK_CSR0L_TXPKTRDY);
614 return (1); /* not complete */
618 musbotg_setup_status(struct musbotg_td *td)
620 struct musbotg_softc *sc;
623 /* get pointer to softc */
624 sc = MUSBOTG_PC2SC(td->pc);
626 /* select endpoint 0 */
627 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
629 if (sc->sc_ep0_busy) {
631 sc->sc_ep0_cmd |= MUSB2_MASK_CSR0L_DATAEND;
632 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
635 /* read out FIFO status */
636 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
638 DPRINTFN(4, "csr=0x%02x\n", csr);
640 if (csr & MUSB2_MASK_CSR0L_DATAEND) {
641 /* wait for interrupt */
642 return (1); /* not complete */
644 if (sc->sc_dv_addr != 0xFF) {
645 /* write function address */
646 musbotg_set_address(sc, sc->sc_dv_addr);
648 return (0); /* complete */
652 musbotg_data_rx(struct musbotg_td *td)
654 struct usb_page_search buf_res;
655 struct musbotg_softc *sc;
661 to = 8; /* don't loop forever! */
664 /* get pointer to softc */
665 sc = MUSBOTG_PC2SC(td->pc);
667 /* select endpoint */
668 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->ep_no);
671 /* read out FIFO status */
672 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
674 DPRINTFN(4, "csr=0x%02x\n", csr);
677 if (csr & MUSB2_MASK_CSRL_RXOVERRUN) {
678 /* make sure we don't clear "RXPKTRDY" */
679 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
680 MUSB2_MASK_CSRL_RXPKTRDY);
683 if (!(csr & MUSB2_MASK_CSRL_RXPKTRDY)) {
684 return (1); /* not complete */
686 /* get the packet byte count */
687 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
689 DPRINTFN(4, "count=0x%04x\n", count);
692 * Check for short or invalid packet:
694 if (count != td->max_frame_size) {
695 if (count < td->max_frame_size) {
696 /* we have a short packet */
700 /* invalid USB packet */
702 return (0); /* we are complete */
705 /* verify the packet byte count */
706 if (count > td->remainder) {
707 /* invalid USB packet */
709 return (0); /* we are complete */
714 usbd_get_page(td->pc, td->offset, &buf_res);
716 /* get correct length */
717 if (buf_res.length > count) {
718 buf_res.length = count;
720 /* check for unaligned memory address */
721 if (USB_P2U(buf_res.buffer) & 3) {
726 /* receive data 4 bytes at a time */
727 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
728 MUSB2_REG_EPFIFO(td->ep_no), sc->sc_bounce_buf,
733 /* receive data 1 byte at a time */
734 bus_space_read_multi_1(sc->sc_io_tag,
735 sc->sc_io_hdl, MUSB2_REG_EPFIFO(td->ep_no),
736 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
738 usbd_copy_in(td->pc, td->offset,
739 sc->sc_bounce_buf, count);
741 /* update offset and remainder */
743 td->remainder -= count;
746 /* check if we can optimise */
747 if (buf_res.length >= 4) {
749 /* receive data 4 bytes at a time */
750 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
751 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
754 temp = buf_res.length & ~3;
756 /* update counters */
759 td->remainder -= temp;
763 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
764 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
767 /* update counters */
768 count -= buf_res.length;
769 td->offset += buf_res.length;
770 td->remainder -= buf_res.length;
773 /* clear status bits */
774 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
776 /* check if we are complete */
777 if ((td->remainder == 0) || got_short) {
779 /* we are complete */
782 /* else need to receive a zero length packet */
787 return (1); /* not complete */
791 musbotg_data_tx(struct musbotg_td *td)
793 struct usb_page_search buf_res;
794 struct musbotg_softc *sc;
799 to = 8; /* don't loop forever! */
801 /* get pointer to softc */
802 sc = MUSBOTG_PC2SC(td->pc);
804 /* select endpoint */
805 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->ep_no);
809 /* read out FIFO status */
810 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
812 DPRINTFN(4, "csr=0x%02x\n", csr);
814 if (csr & (MUSB2_MASK_CSRL_TXINCOMP |
815 MUSB2_MASK_CSRL_TXUNDERRUN)) {
816 /* clear status bits */
817 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
819 if (csr & MUSB2_MASK_CSRL_TXPKTRDY) {
820 return (1); /* not complete */
822 /* check for short packet */
823 count = td->max_frame_size;
824 if (td->remainder < count) {
825 /* we have a short packet */
827 count = td->remainder;
832 usbd_get_page(td->pc, td->offset, &buf_res);
834 /* get correct length */
835 if (buf_res.length > count) {
836 buf_res.length = count;
838 /* check for unaligned memory address */
839 if (USB_P2U(buf_res.buffer) & 3) {
841 usbd_copy_out(td->pc, td->offset,
842 sc->sc_bounce_buf, count);
847 /* transmit data 4 bytes at a time */
848 bus_space_write_multi_4(sc->sc_io_tag,
849 sc->sc_io_hdl, MUSB2_REG_EPFIFO(td->ep_no),
850 sc->sc_bounce_buf, temp / 4);
854 /* receive data 1 byte at a time */
855 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
856 MUSB2_REG_EPFIFO(td->ep_no),
857 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
859 /* update offset and remainder */
861 td->remainder -= count;
864 /* check if we can optimise */
865 if (buf_res.length >= 4) {
867 /* transmit data 4 bytes at a time */
868 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
869 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
872 temp = buf_res.length & ~3;
874 /* update counters */
877 td->remainder -= temp;
881 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
882 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
885 /* update counters */
886 count -= buf_res.length;
887 td->offset += buf_res.length;
888 td->remainder -= buf_res.length;
892 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
893 MUSB2_MASK_CSRL_TXPKTRDY);
895 /* check remainder */
896 if (td->remainder == 0) {
898 return (0); /* complete */
900 /* else we need to transmit a short packet */
905 return (1); /* not complete */
909 musbotg_xfer_do_fifo(struct usb_xfer *xfer)
911 struct musbotg_softc *sc;
912 struct musbotg_td *td;
916 td = xfer->td_transfer_cache;
918 if ((td->func) (td)) {
919 /* operation in progress */
922 if (((void *)td) == xfer->td_transfer_last) {
927 } else if (td->remainder > 0) {
929 * We had a short transfer. If there is no alternate
930 * next, stop processing !
937 * Fetch the next transfer descriptor and transfer
938 * some flags to the next transfer descriptor
941 xfer->td_transfer_cache = td;
943 return (1); /* not complete */
946 sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
948 /* compute all actual lengths */
950 musbotg_standard_done(xfer);
952 return (0); /* complete */
956 musbotg_interrupt_poll(struct musbotg_softc *sc)
958 struct usb_xfer *xfer;
961 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
962 if (!musbotg_xfer_do_fifo(xfer)) {
963 /* queue has been modified */
970 musbotg_vbus_interrupt(struct musbotg_softc *sc, uint8_t is_on)
972 DPRINTFN(4, "vbus = %u\n", is_on);
974 USB_BUS_LOCK(&sc->sc_bus);
976 if (!sc->sc_flags.status_vbus) {
977 sc->sc_flags.status_vbus = 1;
979 /* complete root HUB interrupt endpoint */
980 musbotg_root_intr(sc);
983 if (sc->sc_flags.status_vbus) {
984 sc->sc_flags.status_vbus = 0;
985 sc->sc_flags.status_bus_reset = 0;
986 sc->sc_flags.status_suspend = 0;
987 sc->sc_flags.change_suspend = 0;
988 sc->sc_flags.change_connect = 1;
990 /* complete root HUB interrupt endpoint */
991 musbotg_root_intr(sc);
995 USB_BUS_UNLOCK(&sc->sc_bus);
999 musbotg_interrupt(struct musbotg_softc *sc)
1007 USB_BUS_LOCK(&sc->sc_bus);
1011 /* read all interrupt registers */
1012 usb_status = MUSB2_READ_1(sc, MUSB2_REG_INTUSB);
1014 /* read all FIFO interrupts */
1015 rx_status = MUSB2_READ_2(sc, MUSB2_REG_INTRX);
1016 tx_status = MUSB2_READ_2(sc, MUSB2_REG_INTTX);
1018 /* check for any bus state change interrupts */
1020 if (usb_status & (MUSB2_MASK_IRESET |
1021 MUSB2_MASK_IRESUME | MUSB2_MASK_ISUSP)) {
1023 DPRINTFN(4, "real bus interrupt 0x%08x\n", usb_status);
1025 if (usb_status & MUSB2_MASK_IRESET) {
1027 /* set correct state */
1028 sc->sc_flags.status_bus_reset = 1;
1029 sc->sc_flags.status_suspend = 0;
1030 sc->sc_flags.change_suspend = 0;
1031 sc->sc_flags.change_connect = 1;
1033 /* determine line speed */
1034 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
1035 if (temp & MUSB2_MASK_HSMODE)
1036 sc->sc_flags.status_high_speed = 1;
1038 sc->sc_flags.status_high_speed = 0;
1041 * After reset all interrupts are on and we need to
1044 temp = MUSB2_MASK_IRESET;
1045 /* disable resume interrupt */
1046 temp &= ~MUSB2_MASK_IRESUME;
1047 /* enable suspend interrupt */
1048 temp |= MUSB2_MASK_ISUSP;
1049 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1050 /* disable TX and RX interrupts */
1051 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1052 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1055 * If RXRSM and RXSUSP is set at the same time we interpret
1056 * that like RESUME. Resume is set when there is at least 3
1057 * milliseconds of inactivity on the USB BUS.
1059 if (usb_status & MUSB2_MASK_IRESUME) {
1060 if (sc->sc_flags.status_suspend) {
1061 sc->sc_flags.status_suspend = 0;
1062 sc->sc_flags.change_suspend = 1;
1064 temp = MUSB2_READ_1(sc, MUSB2_REG_INTUSBE);
1065 /* disable resume interrupt */
1066 temp &= ~MUSB2_MASK_IRESUME;
1067 /* enable suspend interrupt */
1068 temp |= MUSB2_MASK_ISUSP;
1069 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1071 } else if (usb_status & MUSB2_MASK_ISUSP) {
1072 if (!sc->sc_flags.status_suspend) {
1073 sc->sc_flags.status_suspend = 1;
1074 sc->sc_flags.change_suspend = 1;
1076 temp = MUSB2_READ_1(sc, MUSB2_REG_INTUSBE);
1077 /* disable suspend interrupt */
1078 temp &= ~MUSB2_MASK_ISUSP;
1079 /* enable resume interrupt */
1080 temp |= MUSB2_MASK_IRESUME;
1081 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1084 /* complete root HUB interrupt endpoint */
1085 musbotg_root_intr(sc);
1087 /* check for any endpoint interrupts */
1089 if (rx_status || tx_status) {
1090 DPRINTFN(4, "real endpoint interrupt "
1091 "rx=0x%04x, tx=0x%04x\n", rx_status, tx_status);
1093 /* poll one time regardless of FIFO status */
1095 musbotg_interrupt_poll(sc);
1100 USB_BUS_UNLOCK(&sc->sc_bus);
1104 musbotg_setup_standard_chain_sub(struct musbotg_std_temp *temp)
1106 struct musbotg_td *td;
1108 /* get current Transfer Descriptor */
1112 /* prepare for next TD */
1113 temp->td_next = td->obj_next;
1115 /* fill out the Transfer Descriptor */
1116 td->func = temp->func;
1118 td->offset = temp->offset;
1119 td->remainder = temp->len;
1121 td->did_stall = temp->did_stall;
1122 td->short_pkt = temp->short_pkt;
1123 td->alt_next = temp->setup_alt_next;
1127 musbotg_setup_standard_chain(struct usb_xfer *xfer)
1129 struct musbotg_std_temp temp;
1130 struct musbotg_softc *sc;
1131 struct musbotg_td *td;
1135 DPRINTFN(8, "addr=%d endpt=%d sumlen=%d speed=%d\n",
1136 xfer->address, UE_GET_ADDR(xfer->endpointno),
1137 xfer->sumlen, usbd_get_speed(xfer->xroot->udev));
1139 temp.max_frame_size = xfer->max_frame_size;
1141 td = xfer->td_start[0];
1142 xfer->td_transfer_first = td;
1143 xfer->td_transfer_cache = td;
1148 temp.td_next = xfer->td_start[0];
1150 temp.setup_alt_next = xfer->flags_int.short_frames_ok;
1151 temp.did_stall = !xfer->flags_int.control_stall;
1153 sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
1154 ep_no = (xfer->endpointno & UE_ADDR);
1156 /* check if we should prepend a setup message */
1158 if (xfer->flags_int.control_xfr) {
1159 if (xfer->flags_int.control_hdr) {
1161 temp.func = &musbotg_setup_rx;
1162 temp.len = xfer->frlengths[0];
1163 temp.pc = xfer->frbuffers + 0;
1164 temp.short_pkt = temp.len ? 1 : 0;
1166 musbotg_setup_standard_chain_sub(&temp);
1173 if (x != xfer->nframes) {
1174 if (xfer->endpointno & UE_DIR_IN) {
1175 if (xfer->flags_int.control_xfr)
1176 temp.func = &musbotg_setup_data_tx;
1178 temp.func = &musbotg_data_tx;
1180 if (xfer->flags_int.control_xfr)
1181 temp.func = &musbotg_setup_data_rx;
1183 temp.func = &musbotg_data_rx;
1186 /* setup "pc" pointer */
1187 temp.pc = xfer->frbuffers + x;
1189 while (x != xfer->nframes) {
1191 /* DATA0 / DATA1 message */
1193 temp.len = xfer->frlengths[x];
1197 if (x == xfer->nframes) {
1198 if (xfer->flags_int.control_xfr) {
1199 if (xfer->flags_int.control_act) {
1200 temp.setup_alt_next = 0;
1203 temp.setup_alt_next = 0;
1206 if (temp.len == 0) {
1208 /* make sure that we send an USB packet */
1214 /* regular data transfer */
1216 temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
1219 musbotg_setup_standard_chain_sub(&temp);
1221 if (xfer->flags_int.isochronous_xfr) {
1222 temp.offset += temp.len;
1224 /* get next Page Cache pointer */
1225 temp.pc = xfer->frbuffers + x;
1229 /* check for control transfer */
1230 if (xfer->flags_int.control_xfr) {
1232 /* always setup a valid "pc" pointer for status and sync */
1233 temp.pc = xfer->frbuffers + 0;
1236 temp.setup_alt_next = 0;
1238 /* check if we should append a status stage */
1239 if (!xfer->flags_int.control_act) {
1241 * Send a DATA1 message and invert the current
1242 * endpoint direction.
1244 temp.func = &musbotg_setup_status;
1245 musbotg_setup_standard_chain_sub(&temp);
1248 /* must have at least one frame! */
1250 xfer->td_transfer_last = td;
1254 musbotg_timeout(void *arg)
1256 struct usb_xfer *xfer = arg;
1258 DPRINTFN(1, "xfer=%p\n", xfer);
1260 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1262 /* transfer is transferred */
1263 musbotg_device_done(xfer, USB_ERR_TIMEOUT);
1267 musbotg_ep_int_set(struct usb_xfer *xfer, uint8_t on)
1269 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
1271 uint8_t ep_no = xfer->endpointno & UE_ADDR;
1274 * Only enable the endpoint interrupt when we are
1275 * actually waiting for data, hence we are dealing
1276 * with level triggered interrupts !
1279 temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
1281 temp |= MUSB2_MASK_EPINT(0);
1283 temp &= ~MUSB2_MASK_EPINT(0);
1285 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
1287 if (USB_GET_DATA_ISREAD(xfer)) {
1288 temp = MUSB2_READ_2(sc, MUSB2_REG_INTRXE);
1290 temp |= MUSB2_MASK_EPINT(ep_no);
1292 temp &= ~MUSB2_MASK_EPINT(ep_no);
1293 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, temp);
1296 temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
1298 temp |= MUSB2_MASK_EPINT(ep_no);
1300 temp &= ~MUSB2_MASK_EPINT(ep_no);
1301 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
1307 musbotg_start_standard_chain(struct usb_xfer *xfer)
1312 if (musbotg_xfer_do_fifo(xfer)) {
1314 musbotg_ep_int_set(xfer, 1);
1316 DPRINTFN(14, "enabled interrupts on endpoint\n");
1318 /* put transfer on interrupt queue */
1319 usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
1321 /* start timeout, if any */
1322 if (xfer->timeout != 0) {
1323 usbd_transfer_timeout_ms(xfer,
1324 &musbotg_timeout, xfer->timeout);
1330 musbotg_root_intr(struct musbotg_softc *sc)
1334 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
1337 sc->sc_hub_idata[0] = 0x02; /* we only have one port */
1339 uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata,
1340 sizeof(sc->sc_hub_idata));
1344 musbotg_standard_done_sub(struct usb_xfer *xfer)
1346 struct musbotg_td *td;
1352 td = xfer->td_transfer_cache;
1355 len = td->remainder;
1357 if (xfer->aframes != xfer->nframes) {
1359 * Verify the length and subtract
1360 * the remainder from "frlengths[]":
1362 if (len > xfer->frlengths[xfer->aframes]) {
1365 xfer->frlengths[xfer->aframes] -= len;
1368 /* Check for transfer error */
1370 /* the transfer is finished */
1375 /* Check for short transfer */
1377 if (xfer->flags_int.short_frames_ok) {
1378 /* follow alt next */
1385 /* the transfer is finished */
1393 /* this USB frame is complete */
1399 /* update transfer cache */
1401 xfer->td_transfer_cache = td;
1404 USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
1408 musbotg_standard_done(struct usb_xfer *xfer)
1410 usb_error_t err = 0;
1412 DPRINTFN(12, "xfer=%p endpoint=%p transfer done\n",
1413 xfer, xfer->endpoint);
1417 xfer->td_transfer_cache = xfer->td_transfer_first;
1419 if (xfer->flags_int.control_xfr) {
1421 if (xfer->flags_int.control_hdr) {
1423 err = musbotg_standard_done_sub(xfer);
1427 if (xfer->td_transfer_cache == NULL) {
1431 while (xfer->aframes != xfer->nframes) {
1433 err = musbotg_standard_done_sub(xfer);
1436 if (xfer->td_transfer_cache == NULL) {
1441 if (xfer->flags_int.control_xfr &&
1442 !xfer->flags_int.control_act) {
1444 err = musbotg_standard_done_sub(xfer);
1447 musbotg_device_done(xfer, err);
1450 /*------------------------------------------------------------------------*
1451 * musbotg_device_done
1453 * NOTE: this function can be called more than one time on the
1454 * same USB transfer!
1455 *------------------------------------------------------------------------*/
1457 musbotg_device_done(struct usb_xfer *xfer, usb_error_t error)
1459 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1461 DPRINTFN(2, "xfer=%p, endpoint=%p, error=%d\n",
1462 xfer, xfer->endpoint, error);
1464 if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) {
1466 musbotg_ep_int_set(xfer, 0);
1468 DPRINTFN(14, "disabled interrupts on endpoint\n");
1470 /* dequeue transfer and start next transfer */
1471 usbd_transfer_done(xfer, error);
1475 musbotg_set_stall(struct usb_device *udev, struct usb_xfer *xfer,
1476 struct usb_endpoint *ep, uint8_t *did_stall)
1478 struct musbotg_softc *sc;
1481 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1483 DPRINTFN(4, "endpoint=%p\n", ep);
1486 /* cancel any ongoing transfers */
1487 musbotg_device_done(xfer, USB_ERR_STALLED);
1489 /* set FORCESTALL */
1490 sc = MUSBOTG_BUS2SC(udev->bus);
1492 ep_no = (ep->edesc->bEndpointAddress & UE_ADDR);
1494 /* select endpoint */
1495 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
1497 if (ep->edesc->bEndpointAddress & UE_DIR_IN) {
1498 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1499 MUSB2_MASK_CSRL_TXSENDSTALL);
1501 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1502 MUSB2_MASK_CSRL_RXSENDSTALL);
1507 musbotg_clear_stall_sub(struct musbotg_softc *sc, uint16_t wMaxPacket,
1508 uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
1514 if (ep_type == UE_CONTROL) {
1515 /* clearing stall is not needed */
1518 /* select endpoint */
1519 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
1521 /* compute max frame size */
1522 mps = wMaxPacket & 0x7FF;
1523 switch ((wMaxPacket >> 11) & 3) {
1534 if (ep_dir == UE_DIR_IN) {
1538 /* Configure endpoint */
1541 MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1542 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1543 MUSB2_MASK_CSRH_TXMODE | temp);
1545 case UE_ISOCHRONOUS:
1546 MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1547 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1548 MUSB2_MASK_CSRH_TXMODE |
1549 MUSB2_MASK_CSRH_TXISO | temp);
1552 MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1553 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1554 MUSB2_MASK_CSRH_TXMODE | temp);
1560 /* Need to flush twice in case of double bufring */
1561 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1562 if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
1563 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1564 MUSB2_MASK_CSRL_TXFFLUSH);
1565 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1566 if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
1567 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1568 MUSB2_MASK_CSRL_TXFFLUSH);
1569 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1572 /* reset data toggle */
1573 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1574 MUSB2_MASK_CSRL_TXDT_CLR);
1575 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
1576 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1578 /* set double/single buffering */
1579 temp = MUSB2_READ_2(sc, MUSB2_REG_TXDBDIS);
1580 if (mps <= (sc->sc_hw_ep_profile[ep_no].
1581 max_in_frame_size / 2)) {
1583 temp &= ~(1 << ep_no);
1586 temp |= (1 << ep_no);
1588 MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, temp);
1590 /* clear sent stall */
1591 if (csr & MUSB2_MASK_CSRL_TXSENTSTALL) {
1592 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
1593 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1599 /* Configure endpoint */
1602 MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1603 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
1604 MUSB2_MASK_CSRH_RXNYET | temp);
1606 case UE_ISOCHRONOUS:
1607 MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1608 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
1609 MUSB2_MASK_CSRH_RXNYET |
1610 MUSB2_MASK_CSRH_RXISO | temp);
1613 MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1614 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH, temp);
1620 /* Need to flush twice in case of double bufring */
1621 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1622 if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
1623 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1624 MUSB2_MASK_CSRL_RXFFLUSH);
1625 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1626 if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
1627 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1628 MUSB2_MASK_CSRL_RXFFLUSH);
1629 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1632 /* reset data toggle */
1633 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1634 MUSB2_MASK_CSRL_RXDT_CLR);
1635 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
1636 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1638 /* set double/single buffering */
1639 temp = MUSB2_READ_2(sc, MUSB2_REG_RXDBDIS);
1640 if (mps <= (sc->sc_hw_ep_profile[ep_no].
1641 max_out_frame_size / 2)) {
1643 temp &= ~(1 << ep_no);
1646 temp |= (1 << ep_no);
1648 MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, temp);
1650 /* clear sent stall */
1651 if (csr & MUSB2_MASK_CSRL_RXSENTSTALL) {
1652 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
1658 musbotg_clear_stall(struct usb_device *udev, struct usb_endpoint *ep)
1660 struct musbotg_softc *sc;
1661 struct usb_endpoint_descriptor *ed;
1663 DPRINTFN(4, "endpoint=%p\n", ep);
1665 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1668 if (udev->flags.usb_mode != USB_MODE_DEVICE) {
1673 sc = MUSBOTG_BUS2SC(udev->bus);
1675 /* get endpoint descriptor */
1678 /* reset endpoint */
1679 musbotg_clear_stall_sub(sc,
1680 UGETW(ed->wMaxPacketSize),
1681 (ed->bEndpointAddress & UE_ADDR),
1682 (ed->bmAttributes & UE_XFERTYPE),
1683 (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
1687 musbotg_init(struct musbotg_softc *sc)
1689 struct usb_hw_ep_profile *pf;
1697 DPRINTFN(1, "start\n");
1699 /* set up the bus structure */
1700 sc->sc_bus.usbrev = USB_REV_2_0;
1701 sc->sc_bus.methods = &musbotg_bus_methods;
1703 USB_BUS_LOCK(&sc->sc_bus);
1705 /* turn on clocks */
1707 if (sc->sc_clocks_on) {
1708 (sc->sc_clocks_on) (sc->sc_clocks_arg);
1710 /* wait a little for things to stabilise */
1711 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
1713 /* disable all interrupts */
1715 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
1716 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1717 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1719 /* disable pullup */
1721 musbotg_pull_common(sc, 0);
1723 /* wait a little bit (10ms) */
1724 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100);
1726 /* disable double packet buffering */
1727 MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, 0xFFFF);
1728 MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, 0xFFFF);
1730 /* enable HighSpeed and ISO Update flags */
1732 MUSB2_WRITE_1(sc, MUSB2_REG_POWER,
1733 MUSB2_MASK_HSENAB | MUSB2_MASK_ISOUPD);
1735 /* clear Session bit, if set */
1737 temp = MUSB2_READ_1(sc, MUSB2_REG_DEVCTL);
1738 temp &= ~MUSB2_MASK_SESS;
1739 MUSB2_WRITE_1(sc, MUSB2_REG_DEVCTL, temp);
1741 DPRINTF("DEVCTL=0x%02x\n", temp);
1743 /* disable testmode */
1745 MUSB2_WRITE_1(sc, MUSB2_REG_TESTMODE, 0);
1747 /* set default value */
1749 MUSB2_WRITE_1(sc, MUSB2_REG_MISC, 0);
1751 /* select endpoint index 0 */
1753 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
1755 /* read out number of endpoints */
1758 (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) / 16);
1761 (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) % 16);
1763 /* these numbers exclude the control endpoint */
1765 DPRINTFN(2, "RX/TX endpoints: %u/%u\n", nrx, ntx);
1767 sc->sc_ep_max = (nrx > ntx) ? nrx : ntx;
1768 if (sc->sc_ep_max == 0) {
1769 DPRINTFN(2, "ERROR: Looks like the clocks are off!\n");
1771 /* read out configuration data */
1773 sc->sc_conf_data = MUSB2_READ_1(sc, MUSB2_REG_CONFDATA);
1775 DPRINTFN(2, "Config Data: 0x%02x\n",
1778 DPRINTFN(2, "HW version: 0x%04x\n",
1779 MUSB2_READ_1(sc, MUSB2_REG_HWVERS));
1781 /* initialise endpoint profiles */
1783 for (temp = 1; temp <= sc->sc_ep_max; temp++) {
1784 pf = sc->sc_hw_ep_profile + temp;
1786 /* select endpoint */
1787 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, temp);
1789 fsize = MUSB2_READ_1(sc, MUSB2_REG_FSIZE);
1790 frx = (fsize & MUSB2_MASK_RX_FSIZE) / 16;;
1791 ftx = (fsize & MUSB2_MASK_TX_FSIZE);
1793 DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u\n",
1794 temp, pf->max_in_frame_size,
1795 pf->max_out_frame_size);
1797 if (frx && ftx && (temp <= nrx) && (temp <= ntx)) {
1798 pf->max_in_frame_size = 1 << ftx;
1799 pf->max_out_frame_size = 1 << frx;
1800 pf->is_simplex = 0; /* duplex */
1801 pf->support_multi_buffer = 1;
1802 pf->support_bulk = 1;
1803 pf->support_interrupt = 1;
1804 pf->support_isochronous = 1;
1806 pf->support_out = 1;
1807 } else if (frx && (temp <= nrx)) {
1808 pf->max_out_frame_size = 1 << frx;
1809 pf->is_simplex = 1; /* simplex */
1810 pf->support_multi_buffer = 1;
1811 pf->support_bulk = 1;
1812 pf->support_interrupt = 1;
1813 pf->support_isochronous = 1;
1814 pf->support_out = 1;
1815 } else if (ftx && (temp <= ntx)) {
1816 pf->max_in_frame_size = 1 << ftx;
1817 pf->is_simplex = 1; /* simplex */
1818 pf->support_multi_buffer = 1;
1819 pf->support_bulk = 1;
1820 pf->support_interrupt = 1;
1821 pf->support_isochronous = 1;
1826 /* turn on default interrupts */
1828 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE,
1831 musbotg_clocks_off(sc);
1833 USB_BUS_UNLOCK(&sc->sc_bus);
1835 /* catch any lost interrupts */
1837 musbotg_do_poll(&sc->sc_bus);
1839 return (0); /* success */
1843 musbotg_uninit(struct musbotg_softc *sc)
1845 USB_BUS_LOCK(&sc->sc_bus);
1847 /* disable all interrupts */
1848 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
1849 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1850 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1852 sc->sc_flags.port_powered = 0;
1853 sc->sc_flags.status_vbus = 0;
1854 sc->sc_flags.status_bus_reset = 0;
1855 sc->sc_flags.status_suspend = 0;
1856 sc->sc_flags.change_suspend = 0;
1857 sc->sc_flags.change_connect = 1;
1859 musbotg_pull_down(sc);
1860 musbotg_clocks_off(sc);
1861 USB_BUS_UNLOCK(&sc->sc_bus);
1865 musbotg_suspend(struct musbotg_softc *sc)
1871 musbotg_resume(struct musbotg_softc *sc)
1877 musbotg_do_poll(struct usb_bus *bus)
1879 struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
1881 USB_BUS_LOCK(&sc->sc_bus);
1882 musbotg_interrupt_poll(sc);
1883 USB_BUS_UNLOCK(&sc->sc_bus);
1886 /*------------------------------------------------------------------------*
1887 * musbotg bulk support
1888 *------------------------------------------------------------------------*/
1890 musbotg_device_bulk_open(struct usb_xfer *xfer)
1896 musbotg_device_bulk_close(struct usb_xfer *xfer)
1898 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1902 musbotg_device_bulk_enter(struct usb_xfer *xfer)
1908 musbotg_device_bulk_start(struct usb_xfer *xfer)
1911 musbotg_setup_standard_chain(xfer);
1912 musbotg_start_standard_chain(xfer);
1915 struct usb_pipe_methods musbotg_device_bulk_methods =
1917 .open = musbotg_device_bulk_open,
1918 .close = musbotg_device_bulk_close,
1919 .enter = musbotg_device_bulk_enter,
1920 .start = musbotg_device_bulk_start,
1923 /*------------------------------------------------------------------------*
1924 * musbotg control support
1925 *------------------------------------------------------------------------*/
1927 musbotg_device_ctrl_open(struct usb_xfer *xfer)
1933 musbotg_device_ctrl_close(struct usb_xfer *xfer)
1935 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1939 musbotg_device_ctrl_enter(struct usb_xfer *xfer)
1945 musbotg_device_ctrl_start(struct usb_xfer *xfer)
1948 musbotg_setup_standard_chain(xfer);
1949 musbotg_start_standard_chain(xfer);
1952 struct usb_pipe_methods musbotg_device_ctrl_methods =
1954 .open = musbotg_device_ctrl_open,
1955 .close = musbotg_device_ctrl_close,
1956 .enter = musbotg_device_ctrl_enter,
1957 .start = musbotg_device_ctrl_start,
1960 /*------------------------------------------------------------------------*
1961 * musbotg interrupt support
1962 *------------------------------------------------------------------------*/
1964 musbotg_device_intr_open(struct usb_xfer *xfer)
1970 musbotg_device_intr_close(struct usb_xfer *xfer)
1972 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1976 musbotg_device_intr_enter(struct usb_xfer *xfer)
1982 musbotg_device_intr_start(struct usb_xfer *xfer)
1985 musbotg_setup_standard_chain(xfer);
1986 musbotg_start_standard_chain(xfer);
1989 struct usb_pipe_methods musbotg_device_intr_methods =
1991 .open = musbotg_device_intr_open,
1992 .close = musbotg_device_intr_close,
1993 .enter = musbotg_device_intr_enter,
1994 .start = musbotg_device_intr_start,
1997 /*------------------------------------------------------------------------*
1998 * musbotg full speed isochronous support
1999 *------------------------------------------------------------------------*/
2001 musbotg_device_isoc_open(struct usb_xfer *xfer)
2007 musbotg_device_isoc_close(struct usb_xfer *xfer)
2009 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2013 musbotg_device_isoc_enter(struct usb_xfer *xfer)
2015 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
2020 DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
2021 xfer, xfer->endpoint->isoc_next, xfer->nframes);
2023 /* get the current frame index */
2025 nframes = MUSB2_READ_2(sc, MUSB2_REG_FRAME);
2028 * check if the frame index is within the window where the frames
2031 temp = (nframes - xfer->endpoint->isoc_next) & MUSB2_MASK_FRAME;
2033 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
2034 fs_frames = (xfer->nframes + 7) / 8;
2036 fs_frames = xfer->nframes;
2039 if ((xfer->endpoint->is_synced == 0) ||
2040 (temp < fs_frames)) {
2042 * If there is data underflow or the pipe queue is
2043 * empty we schedule the transfer a few frames ahead
2044 * of the current frame position. Else two isochronous
2045 * transfers might overlap.
2047 xfer->endpoint->isoc_next = (nframes + 3) & MUSB2_MASK_FRAME;
2048 xfer->endpoint->is_synced = 1;
2049 DPRINTFN(2, "start next=%d\n", xfer->endpoint->isoc_next);
2052 * compute how many milliseconds the insertion is ahead of the
2053 * current frame position:
2055 temp = (xfer->endpoint->isoc_next - nframes) & MUSB2_MASK_FRAME;
2058 * pre-compute when the isochronous transfer will be finished:
2060 xfer->isoc_time_complete =
2061 usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2064 /* compute frame number for next insertion */
2065 xfer->endpoint->isoc_next += fs_frames;
2068 musbotg_setup_standard_chain(xfer);
2072 musbotg_device_isoc_start(struct usb_xfer *xfer)
2074 /* start TD chain */
2075 musbotg_start_standard_chain(xfer);
2078 struct usb_pipe_methods musbotg_device_isoc_methods =
2080 .open = musbotg_device_isoc_open,
2081 .close = musbotg_device_isoc_close,
2082 .enter = musbotg_device_isoc_enter,
2083 .start = musbotg_device_isoc_start,
2086 /*------------------------------------------------------------------------*
2087 * musbotg root control support
2088 *------------------------------------------------------------------------*
2089 * Simulate a hardware HUB by handling all the necessary requests.
2090 *------------------------------------------------------------------------*/
2092 static const struct usb_device_descriptor musbotg_devd = {
2093 .bLength = sizeof(struct usb_device_descriptor),
2094 .bDescriptorType = UDESC_DEVICE,
2095 .bcdUSB = {0x00, 0x02},
2096 .bDeviceClass = UDCLASS_HUB,
2097 .bDeviceSubClass = UDSUBCLASS_HUB,
2098 .bDeviceProtocol = UDPROTO_HSHUBSTT,
2099 .bMaxPacketSize = 64,
2100 .bcdDevice = {0x00, 0x01},
2103 .bNumConfigurations = 1,
2106 static const struct usb_device_qualifier musbotg_odevd = {
2107 .bLength = sizeof(struct usb_device_qualifier),
2108 .bDescriptorType = UDESC_DEVICE_QUALIFIER,
2109 .bcdUSB = {0x00, 0x02},
2110 .bDeviceClass = UDCLASS_HUB,
2111 .bDeviceSubClass = UDSUBCLASS_HUB,
2112 .bDeviceProtocol = UDPROTO_FSHUB,
2113 .bMaxPacketSize0 = 0,
2114 .bNumConfigurations = 0,
2117 static const struct musbotg_config_desc musbotg_confd = {
2119 .bLength = sizeof(struct usb_config_descriptor),
2120 .bDescriptorType = UDESC_CONFIG,
2121 .wTotalLength[0] = sizeof(musbotg_confd),
2123 .bConfigurationValue = 1,
2124 .iConfiguration = 0,
2125 .bmAttributes = UC_SELF_POWERED,
2129 .bLength = sizeof(struct usb_interface_descriptor),
2130 .bDescriptorType = UDESC_INTERFACE,
2132 .bInterfaceClass = UICLASS_HUB,
2133 .bInterfaceSubClass = UISUBCLASS_HUB,
2134 .bInterfaceProtocol = UIPROTO_HSHUBSTT,
2137 .bLength = sizeof(struct usb_endpoint_descriptor),
2138 .bDescriptorType = UDESC_ENDPOINT,
2139 .bEndpointAddress = (UE_DIR_IN | MUSBOTG_INTR_ENDPT),
2140 .bmAttributes = UE_INTERRUPT,
2141 .wMaxPacketSize[0] = 8,
2146 static const struct usb_hub_descriptor_min musbotg_hubd = {
2147 .bDescLength = sizeof(musbotg_hubd),
2148 .bDescriptorType = UDESC_HUB,
2150 .wHubCharacteristics[0] =
2151 (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
2152 .wHubCharacteristics[1] =
2153 (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 16,
2154 .bPwrOn2PwrGood = 50,
2155 .bHubContrCurrent = 0,
2156 .DeviceRemovable = {0}, /* port is removable */
2159 #define STRING_LANG \
2160 0x09, 0x04, /* American English */
2162 #define STRING_VENDOR \
2163 'M', 0, 'e', 0, 'n', 0, 't', 0, 'o', 0, 'r', 0, ' ', 0, \
2164 'G', 0, 'r', 0, 'a', 0, 'p', 0, 'h', 0, 'i', 0, 'c', 0, 's', 0
2166 #define STRING_PRODUCT \
2167 'O', 0, 'T', 0, 'G', 0, ' ', 0, 'R', 0, \
2168 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
2171 USB_MAKE_STRING_DESC(STRING_LANG, musbotg_langtab);
2172 USB_MAKE_STRING_DESC(STRING_VENDOR, musbotg_vendor);
2173 USB_MAKE_STRING_DESC(STRING_PRODUCT, musbotg_product);
2176 musbotg_roothub_exec(struct usb_device *udev,
2177 struct usb_device_request *req, const void **pptr, uint16_t *plength)
2179 struct musbotg_softc *sc = MUSBOTG_BUS2SC(udev->bus);
2186 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
2189 ptr = (const void *)&sc->sc_hub_temp;
2193 value = UGETW(req->wValue);
2194 index = UGETW(req->wIndex);
2196 /* demultiplex the control request */
2198 switch (req->bmRequestType) {
2199 case UT_READ_DEVICE:
2200 switch (req->bRequest) {
2201 case UR_GET_DESCRIPTOR:
2202 goto tr_handle_get_descriptor;
2204 goto tr_handle_get_config;
2206 goto tr_handle_get_status;
2212 case UT_WRITE_DEVICE:
2213 switch (req->bRequest) {
2214 case UR_SET_ADDRESS:
2215 goto tr_handle_set_address;
2217 goto tr_handle_set_config;
2218 case UR_CLEAR_FEATURE:
2219 goto tr_valid; /* nop */
2220 case UR_SET_DESCRIPTOR:
2221 goto tr_valid; /* nop */
2222 case UR_SET_FEATURE:
2228 case UT_WRITE_ENDPOINT:
2229 switch (req->bRequest) {
2230 case UR_CLEAR_FEATURE:
2231 switch (UGETW(req->wValue)) {
2232 case UF_ENDPOINT_HALT:
2233 goto tr_handle_clear_halt;
2234 case UF_DEVICE_REMOTE_WAKEUP:
2235 goto tr_handle_clear_wakeup;
2240 case UR_SET_FEATURE:
2241 switch (UGETW(req->wValue)) {
2242 case UF_ENDPOINT_HALT:
2243 goto tr_handle_set_halt;
2244 case UF_DEVICE_REMOTE_WAKEUP:
2245 goto tr_handle_set_wakeup;
2250 case UR_SYNCH_FRAME:
2251 goto tr_valid; /* nop */
2257 case UT_READ_ENDPOINT:
2258 switch (req->bRequest) {
2260 goto tr_handle_get_ep_status;
2266 case UT_WRITE_INTERFACE:
2267 switch (req->bRequest) {
2268 case UR_SET_INTERFACE:
2269 goto tr_handle_set_interface;
2270 case UR_CLEAR_FEATURE:
2271 goto tr_valid; /* nop */
2272 case UR_SET_FEATURE:
2278 case UT_READ_INTERFACE:
2279 switch (req->bRequest) {
2280 case UR_GET_INTERFACE:
2281 goto tr_handle_get_interface;
2283 goto tr_handle_get_iface_status;
2289 case UT_WRITE_CLASS_INTERFACE:
2290 case UT_WRITE_VENDOR_INTERFACE:
2294 case UT_READ_CLASS_INTERFACE:
2295 case UT_READ_VENDOR_INTERFACE:
2299 case UT_WRITE_CLASS_DEVICE:
2300 switch (req->bRequest) {
2301 case UR_CLEAR_FEATURE:
2303 case UR_SET_DESCRIPTOR:
2304 case UR_SET_FEATURE:
2311 case UT_WRITE_CLASS_OTHER:
2312 switch (req->bRequest) {
2313 case UR_CLEAR_FEATURE:
2314 goto tr_handle_clear_port_feature;
2315 case UR_SET_FEATURE:
2316 goto tr_handle_set_port_feature;
2317 case UR_CLEAR_TT_BUFFER:
2327 case UT_READ_CLASS_OTHER:
2328 switch (req->bRequest) {
2329 case UR_GET_TT_STATE:
2330 goto tr_handle_get_tt_state;
2332 goto tr_handle_get_port_status;
2338 case UT_READ_CLASS_DEVICE:
2339 switch (req->bRequest) {
2340 case UR_GET_DESCRIPTOR:
2341 goto tr_handle_get_class_descriptor;
2343 goto tr_handle_get_class_status;
2354 tr_handle_get_descriptor:
2355 switch (value >> 8) {
2360 len = sizeof(musbotg_devd);
2361 ptr = (const void *)&musbotg_devd;
2367 len = sizeof(musbotg_confd);
2368 ptr = (const void *)&musbotg_confd;
2371 switch (value & 0xff) {
2372 case 0: /* Language table */
2373 len = sizeof(musbotg_langtab);
2374 ptr = (const void *)&musbotg_langtab;
2377 case 1: /* Vendor */
2378 len = sizeof(musbotg_vendor);
2379 ptr = (const void *)&musbotg_vendor;
2382 case 2: /* Product */
2383 len = sizeof(musbotg_product);
2384 ptr = (const void *)&musbotg_product;
2395 tr_handle_get_config:
2397 sc->sc_hub_temp.wValue[0] = sc->sc_conf;
2400 tr_handle_get_status:
2402 USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
2405 tr_handle_set_address:
2406 if (value & 0xFF00) {
2409 sc->sc_rt_addr = value;
2412 tr_handle_set_config:
2416 sc->sc_conf = value;
2419 tr_handle_get_interface:
2421 sc->sc_hub_temp.wValue[0] = 0;
2424 tr_handle_get_tt_state:
2425 tr_handle_get_class_status:
2426 tr_handle_get_iface_status:
2427 tr_handle_get_ep_status:
2429 USETW(sc->sc_hub_temp.wValue, 0);
2433 tr_handle_set_interface:
2434 tr_handle_set_wakeup:
2435 tr_handle_clear_wakeup:
2436 tr_handle_clear_halt:
2439 tr_handle_clear_port_feature:
2443 DPRINTFN(8, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
2446 case UHF_PORT_SUSPEND:
2447 musbotg_wakeup_peer(sc);
2450 case UHF_PORT_ENABLE:
2451 sc->sc_flags.port_enabled = 0;
2455 case UHF_PORT_INDICATOR:
2456 case UHF_C_PORT_ENABLE:
2457 case UHF_C_PORT_OVER_CURRENT:
2458 case UHF_C_PORT_RESET:
2461 case UHF_PORT_POWER:
2462 sc->sc_flags.port_powered = 0;
2463 musbotg_pull_down(sc);
2464 musbotg_clocks_off(sc);
2466 case UHF_C_PORT_CONNECTION:
2467 sc->sc_flags.change_connect = 0;
2469 case UHF_C_PORT_SUSPEND:
2470 sc->sc_flags.change_suspend = 0;
2473 err = USB_ERR_IOERROR;
2478 tr_handle_set_port_feature:
2482 DPRINTFN(8, "UR_SET_PORT_FEATURE\n");
2485 case UHF_PORT_ENABLE:
2486 sc->sc_flags.port_enabled = 1;
2488 case UHF_PORT_SUSPEND:
2489 case UHF_PORT_RESET:
2491 case UHF_PORT_INDICATOR:
2494 case UHF_PORT_POWER:
2495 sc->sc_flags.port_powered = 1;
2498 err = USB_ERR_IOERROR;
2503 tr_handle_get_port_status:
2505 DPRINTFN(8, "UR_GET_PORT_STATUS\n");
2510 if (sc->sc_flags.status_vbus) {
2511 musbotg_clocks_on(sc);
2512 musbotg_pull_up(sc);
2514 musbotg_pull_down(sc);
2515 musbotg_clocks_off(sc);
2518 /* Select Device Side Mode */
2519 value = UPS_PORT_MODE_DEVICE;
2521 if (sc->sc_flags.status_high_speed) {
2522 value |= UPS_HIGH_SPEED;
2524 if (sc->sc_flags.port_powered) {
2525 value |= UPS_PORT_POWER;
2527 if (sc->sc_flags.port_enabled) {
2528 value |= UPS_PORT_ENABLED;
2530 if (sc->sc_flags.status_vbus &&
2531 sc->sc_flags.status_bus_reset) {
2532 value |= UPS_CURRENT_CONNECT_STATUS;
2534 if (sc->sc_flags.status_suspend) {
2535 value |= UPS_SUSPEND;
2537 USETW(sc->sc_hub_temp.ps.wPortStatus, value);
2541 if (sc->sc_flags.change_connect) {
2542 value |= UPS_C_CONNECT_STATUS;
2544 if (sc->sc_flags.status_vbus &&
2545 sc->sc_flags.status_bus_reset) {
2546 /* reset EP0 state */
2547 sc->sc_ep0_busy = 0;
2551 if (sc->sc_flags.change_suspend) {
2552 value |= UPS_C_SUSPEND;
2554 USETW(sc->sc_hub_temp.ps.wPortChange, value);
2555 len = sizeof(sc->sc_hub_temp.ps);
2558 tr_handle_get_class_descriptor:
2562 ptr = (const void *)&musbotg_hubd;
2563 len = sizeof(musbotg_hubd);
2567 err = USB_ERR_STALLED;
2576 musbotg_xfer_setup(struct usb_setup_params *parm)
2578 const struct usb_hw_ep_profile *pf;
2579 struct musbotg_softc *sc;
2580 struct usb_xfer *xfer;
2586 sc = MUSBOTG_BUS2SC(parm->udev->bus);
2587 xfer = parm->curr_xfer;
2590 * NOTE: This driver does not use any of the parameters that
2591 * are computed from the following values. Just set some
2592 * reasonable dummies:
2594 parm->hc_max_packet_size = 0x400;
2595 parm->hc_max_frame_size = 0x400;
2597 if ((parm->methods == &musbotg_device_isoc_methods) ||
2598 (parm->methods == &musbotg_device_intr_methods))
2599 parm->hc_max_packet_count = 3;
2601 parm->hc_max_packet_count = 1;
2603 usbd_transfer_setup_sub(parm);
2606 * compute maximum number of TDs
2608 if (parm->methods == &musbotg_device_ctrl_methods) {
2610 ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
2612 } else if (parm->methods == &musbotg_device_bulk_methods) {
2614 ntd = xfer->nframes + 1 /* SYNC */ ;
2616 } else if (parm->methods == &musbotg_device_intr_methods) {
2618 ntd = xfer->nframes + 1 /* SYNC */ ;
2620 } else if (parm->methods == &musbotg_device_isoc_methods) {
2622 ntd = xfer->nframes + 1 /* SYNC */ ;
2630 * check if "usbd_transfer_setup_sub" set an error
2636 * allocate transfer descriptors
2645 ep_no = xfer->endpointno & UE_ADDR;
2646 musbotg_get_hw_ep_profile(parm->udev, &pf, ep_no);
2649 /* should not happen */
2650 parm->err = USB_ERR_INVAL;
2659 parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
2661 for (n = 0; n != ntd; n++) {
2663 struct musbotg_td *td;
2667 td = USB_ADD_BYTES(parm->buf, parm->size[0]);
2670 td->max_frame_size = xfer->max_frame_size;
2672 td->obj_next = last_obj;
2676 parm->size[0] += sizeof(*td);
2679 xfer->td_start[0] = last_obj;
2683 musbotg_xfer_unsetup(struct usb_xfer *xfer)
2689 musbotg_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
2690 struct usb_endpoint *ep)
2692 struct musbotg_softc *sc = MUSBOTG_BUS2SC(udev->bus);
2694 DPRINTFN(2, "endpoint=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
2696 edesc->bEndpointAddress, udev->flags.usb_mode,
2699 if (udev->device_index != sc->sc_rt_addr) {
2701 if (udev->flags.usb_mode != USB_MODE_DEVICE) {
2705 if ((udev->speed != USB_SPEED_FULL) &&
2706 (udev->speed != USB_SPEED_HIGH)) {
2710 switch (edesc->bmAttributes & UE_XFERTYPE) {
2712 ep->methods = &musbotg_device_ctrl_methods;
2715 ep->methods = &musbotg_device_intr_methods;
2717 case UE_ISOCHRONOUS:
2718 ep->methods = &musbotg_device_isoc_methods;
2721 ep->methods = &musbotg_device_bulk_methods;
2730 struct usb_bus_methods musbotg_bus_methods =
2732 .endpoint_init = &musbotg_ep_init,
2733 .xfer_setup = &musbotg_xfer_setup,
2734 .xfer_unsetup = &musbotg_xfer_unsetup,
2735 .get_hw_ep_profile = &musbotg_get_hw_ep_profile,
2736 .set_stall = &musbotg_set_stall,
2737 .clear_stall = &musbotg_clear_stall,
2738 .roothub_exec = &musbotg_roothub_exec,
2739 .xfer_poll = &musbotg_do_poll,