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;
1149 temp.td_next = xfer->td_start[0];
1151 temp.setup_alt_next = xfer->flags_int.short_frames_ok;
1152 temp.did_stall = !xfer->flags_int.control_stall;
1154 sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
1155 ep_no = (xfer->endpointno & UE_ADDR);
1157 /* check if we should prepend a setup message */
1159 if (xfer->flags_int.control_xfr) {
1160 if (xfer->flags_int.control_hdr) {
1162 temp.func = &musbotg_setup_rx;
1163 temp.len = xfer->frlengths[0];
1164 temp.pc = xfer->frbuffers + 0;
1165 temp.short_pkt = temp.len ? 1 : 0;
1167 musbotg_setup_standard_chain_sub(&temp);
1174 if (x != xfer->nframes) {
1175 if (xfer->endpointno & UE_DIR_IN) {
1176 if (xfer->flags_int.control_xfr)
1177 temp.func = &musbotg_setup_data_tx;
1179 temp.func = &musbotg_data_tx;
1181 if (xfer->flags_int.control_xfr)
1182 temp.func = &musbotg_setup_data_rx;
1184 temp.func = &musbotg_data_rx;
1187 /* setup "pc" pointer */
1188 temp.pc = xfer->frbuffers + x;
1190 while (x != xfer->nframes) {
1192 /* DATA0 / DATA1 message */
1194 temp.len = xfer->frlengths[x];
1198 if (x == xfer->nframes) {
1199 if (xfer->flags_int.control_xfr) {
1200 if (xfer->flags_int.control_act) {
1201 temp.setup_alt_next = 0;
1204 temp.setup_alt_next = 0;
1207 if (temp.len == 0) {
1209 /* make sure that we send an USB packet */
1215 /* regular data transfer */
1217 temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
1220 musbotg_setup_standard_chain_sub(&temp);
1222 if (xfer->flags_int.isochronous_xfr) {
1223 temp.offset += temp.len;
1225 /* get next Page Cache pointer */
1226 temp.pc = xfer->frbuffers + x;
1230 /* check for control transfer */
1231 if (xfer->flags_int.control_xfr) {
1233 /* always setup a valid "pc" pointer for status and sync */
1234 temp.pc = xfer->frbuffers + 0;
1237 temp.setup_alt_next = 0;
1239 /* check if we should append a status stage */
1240 if (!xfer->flags_int.control_act) {
1242 * Send a DATA1 message and invert the current
1243 * endpoint direction.
1245 temp.func = &musbotg_setup_status;
1246 musbotg_setup_standard_chain_sub(&temp);
1249 /* must have at least one frame! */
1251 xfer->td_transfer_last = td;
1255 musbotg_timeout(void *arg)
1257 struct usb_xfer *xfer = arg;
1259 DPRINTFN(1, "xfer=%p\n", xfer);
1261 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1263 /* transfer is transferred */
1264 musbotg_device_done(xfer, USB_ERR_TIMEOUT);
1268 musbotg_ep_int_set(struct usb_xfer *xfer, uint8_t on)
1270 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
1272 uint8_t ep_no = xfer->endpointno & UE_ADDR;
1275 * Only enable the endpoint interrupt when we are
1276 * actually waiting for data, hence we are dealing
1277 * with level triggered interrupts !
1280 temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
1282 temp |= MUSB2_MASK_EPINT(0);
1284 temp &= ~MUSB2_MASK_EPINT(0);
1286 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
1288 if (USB_GET_DATA_ISREAD(xfer)) {
1289 temp = MUSB2_READ_2(sc, MUSB2_REG_INTRXE);
1291 temp |= MUSB2_MASK_EPINT(ep_no);
1293 temp &= ~MUSB2_MASK_EPINT(ep_no);
1294 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, temp);
1297 temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
1299 temp |= MUSB2_MASK_EPINT(ep_no);
1301 temp &= ~MUSB2_MASK_EPINT(ep_no);
1302 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
1308 musbotg_start_standard_chain(struct usb_xfer *xfer)
1313 if (musbotg_xfer_do_fifo(xfer)) {
1315 musbotg_ep_int_set(xfer, 1);
1317 DPRINTFN(14, "enabled interrupts on endpoint\n");
1319 /* put transfer on interrupt queue */
1320 usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
1322 /* start timeout, if any */
1323 if (xfer->timeout != 0) {
1324 usbd_transfer_timeout_ms(xfer,
1325 &musbotg_timeout, xfer->timeout);
1331 musbotg_root_intr(struct musbotg_softc *sc)
1335 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
1338 sc->sc_hub_idata[0] = 0x02; /* we only have one port */
1340 uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata,
1341 sizeof(sc->sc_hub_idata));
1345 musbotg_standard_done_sub(struct usb_xfer *xfer)
1347 struct musbotg_td *td;
1353 td = xfer->td_transfer_cache;
1356 len = td->remainder;
1358 if (xfer->aframes != xfer->nframes) {
1360 * Verify the length and subtract
1361 * the remainder from "frlengths[]":
1363 if (len > xfer->frlengths[xfer->aframes]) {
1366 xfer->frlengths[xfer->aframes] -= len;
1369 /* Check for transfer error */
1371 /* the transfer is finished */
1376 /* Check for short transfer */
1378 if (xfer->flags_int.short_frames_ok) {
1379 /* follow alt next */
1386 /* the transfer is finished */
1394 /* this USB frame is complete */
1400 /* update transfer cache */
1402 xfer->td_transfer_cache = td;
1405 USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
1409 musbotg_standard_done(struct usb_xfer *xfer)
1411 usb_error_t err = 0;
1413 DPRINTFN(12, "xfer=%p endpoint=%p transfer done\n",
1414 xfer, xfer->endpoint);
1418 xfer->td_transfer_cache = xfer->td_transfer_first;
1420 if (xfer->flags_int.control_xfr) {
1422 if (xfer->flags_int.control_hdr) {
1424 err = musbotg_standard_done_sub(xfer);
1428 if (xfer->td_transfer_cache == NULL) {
1432 while (xfer->aframes != xfer->nframes) {
1434 err = musbotg_standard_done_sub(xfer);
1437 if (xfer->td_transfer_cache == NULL) {
1442 if (xfer->flags_int.control_xfr &&
1443 !xfer->flags_int.control_act) {
1445 err = musbotg_standard_done_sub(xfer);
1448 musbotg_device_done(xfer, err);
1451 /*------------------------------------------------------------------------*
1452 * musbotg_device_done
1454 * NOTE: this function can be called more than one time on the
1455 * same USB transfer!
1456 *------------------------------------------------------------------------*/
1458 musbotg_device_done(struct usb_xfer *xfer, usb_error_t error)
1460 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1462 DPRINTFN(2, "xfer=%p, endpoint=%p, error=%d\n",
1463 xfer, xfer->endpoint, error);
1465 if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) {
1467 musbotg_ep_int_set(xfer, 0);
1469 DPRINTFN(14, "disabled interrupts on endpoint\n");
1471 /* dequeue transfer and start next transfer */
1472 usbd_transfer_done(xfer, error);
1476 musbotg_set_stall(struct usb_device *udev, struct usb_xfer *xfer,
1477 struct usb_endpoint *ep, uint8_t *did_stall)
1479 struct musbotg_softc *sc;
1482 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1484 DPRINTFN(4, "endpoint=%p\n", ep);
1487 /* cancel any ongoing transfers */
1488 musbotg_device_done(xfer, USB_ERR_STALLED);
1490 /* set FORCESTALL */
1491 sc = MUSBOTG_BUS2SC(udev->bus);
1493 ep_no = (ep->edesc->bEndpointAddress & UE_ADDR);
1495 /* select endpoint */
1496 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
1498 if (ep->edesc->bEndpointAddress & UE_DIR_IN) {
1499 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1500 MUSB2_MASK_CSRL_TXSENDSTALL);
1502 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1503 MUSB2_MASK_CSRL_RXSENDSTALL);
1508 musbotg_clear_stall_sub(struct musbotg_softc *sc, uint16_t wMaxPacket,
1509 uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
1515 if (ep_type == UE_CONTROL) {
1516 /* clearing stall is not needed */
1519 /* select endpoint */
1520 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
1522 /* compute max frame size */
1523 mps = wMaxPacket & 0x7FF;
1524 switch ((wMaxPacket >> 11) & 3) {
1535 if (ep_dir == UE_DIR_IN) {
1539 /* Configure endpoint */
1542 MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1543 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1544 MUSB2_MASK_CSRH_TXMODE | temp);
1546 case UE_ISOCHRONOUS:
1547 MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1548 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1549 MUSB2_MASK_CSRH_TXMODE |
1550 MUSB2_MASK_CSRH_TXISO | temp);
1553 MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1554 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1555 MUSB2_MASK_CSRH_TXMODE | temp);
1561 /* Need to flush twice in case of double bufring */
1562 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1563 if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
1564 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1565 MUSB2_MASK_CSRL_TXFFLUSH);
1566 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1567 if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
1568 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1569 MUSB2_MASK_CSRL_TXFFLUSH);
1570 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1573 /* reset data toggle */
1574 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1575 MUSB2_MASK_CSRL_TXDT_CLR);
1576 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
1577 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1579 /* set double/single buffering */
1580 temp = MUSB2_READ_2(sc, MUSB2_REG_TXDBDIS);
1581 if (mps <= (sc->sc_hw_ep_profile[ep_no].
1582 max_in_frame_size / 2)) {
1584 temp &= ~(1 << ep_no);
1587 temp |= (1 << ep_no);
1589 MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, temp);
1591 /* clear sent stall */
1592 if (csr & MUSB2_MASK_CSRL_TXSENTSTALL) {
1593 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
1594 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1600 /* Configure endpoint */
1603 MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1604 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
1605 MUSB2_MASK_CSRH_RXNYET | temp);
1607 case UE_ISOCHRONOUS:
1608 MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1609 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
1610 MUSB2_MASK_CSRH_RXNYET |
1611 MUSB2_MASK_CSRH_RXISO | temp);
1614 MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1615 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH, temp);
1621 /* Need to flush twice in case of double bufring */
1622 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1623 if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
1624 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1625 MUSB2_MASK_CSRL_RXFFLUSH);
1626 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1627 if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
1628 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1629 MUSB2_MASK_CSRL_RXFFLUSH);
1630 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1633 /* reset data toggle */
1634 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1635 MUSB2_MASK_CSRL_RXDT_CLR);
1636 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
1637 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1639 /* set double/single buffering */
1640 temp = MUSB2_READ_2(sc, MUSB2_REG_RXDBDIS);
1641 if (mps <= (sc->sc_hw_ep_profile[ep_no].
1642 max_out_frame_size / 2)) {
1644 temp &= ~(1 << ep_no);
1647 temp |= (1 << ep_no);
1649 MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, temp);
1651 /* clear sent stall */
1652 if (csr & MUSB2_MASK_CSRL_RXSENTSTALL) {
1653 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
1659 musbotg_clear_stall(struct usb_device *udev, struct usb_endpoint *ep)
1661 struct musbotg_softc *sc;
1662 struct usb_endpoint_descriptor *ed;
1664 DPRINTFN(4, "endpoint=%p\n", ep);
1666 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1669 if (udev->flags.usb_mode != USB_MODE_DEVICE) {
1674 sc = MUSBOTG_BUS2SC(udev->bus);
1676 /* get endpoint descriptor */
1679 /* reset endpoint */
1680 musbotg_clear_stall_sub(sc,
1681 UGETW(ed->wMaxPacketSize),
1682 (ed->bEndpointAddress & UE_ADDR),
1683 (ed->bmAttributes & UE_XFERTYPE),
1684 (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
1688 musbotg_init(struct musbotg_softc *sc)
1690 struct usb_hw_ep_profile *pf;
1700 DPRINTFN(1, "start\n");
1702 /* set up the bus structure */
1703 sc->sc_bus.usbrev = USB_REV_2_0;
1704 sc->sc_bus.methods = &musbotg_bus_methods;
1706 USB_BUS_LOCK(&sc->sc_bus);
1708 /* turn on clocks */
1710 if (sc->sc_clocks_on) {
1711 (sc->sc_clocks_on) (sc->sc_clocks_arg);
1713 /* wait a little for things to stabilise */
1714 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
1716 /* disable all interrupts */
1718 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
1719 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1720 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1722 /* disable pullup */
1724 musbotg_pull_common(sc, 0);
1726 /* wait a little bit (10ms) */
1727 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100);
1729 /* disable double packet buffering */
1730 MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, 0xFFFF);
1731 MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, 0xFFFF);
1733 /* enable HighSpeed and ISO Update flags */
1735 MUSB2_WRITE_1(sc, MUSB2_REG_POWER,
1736 MUSB2_MASK_HSENAB | MUSB2_MASK_ISOUPD);
1738 /* clear Session bit, if set */
1740 temp = MUSB2_READ_1(sc, MUSB2_REG_DEVCTL);
1741 temp &= ~MUSB2_MASK_SESS;
1742 MUSB2_WRITE_1(sc, MUSB2_REG_DEVCTL, temp);
1744 DPRINTF("DEVCTL=0x%02x\n", temp);
1746 /* disable testmode */
1748 MUSB2_WRITE_1(sc, MUSB2_REG_TESTMODE, 0);
1750 /* set default value */
1752 MUSB2_WRITE_1(sc, MUSB2_REG_MISC, 0);
1754 /* select endpoint index 0 */
1756 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
1758 /* read out number of endpoints */
1761 (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) / 16);
1764 (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) % 16);
1766 /* these numbers exclude the control endpoint */
1768 DPRINTFN(2, "RX/TX endpoints: %u/%u\n", nrx, ntx);
1770 sc->sc_ep_max = (nrx > ntx) ? nrx : ntx;
1771 if (sc->sc_ep_max == 0) {
1772 DPRINTFN(2, "ERROR: Looks like the clocks are off!\n");
1774 /* read out configuration data */
1776 sc->sc_conf_data = MUSB2_READ_1(sc, MUSB2_REG_CONFDATA);
1778 DPRINTFN(2, "Config Data: 0x%02x\n",
1781 dynfifo = (sc->sc_conf_data & MUSB2_MASK_CD_DYNFIFOSZ) ? 1 : 0;
1784 device_printf(sc->sc_bus.bdev, "Dynamic FIFO sizing detected, "
1785 "assuming 16Kbytes of FIFO RAM\n");
1788 DPRINTFN(2, "HW version: 0x%04x\n",
1789 MUSB2_READ_1(sc, MUSB2_REG_HWVERS));
1791 /* initialise endpoint profiles */
1795 for (temp = 1; temp <= sc->sc_ep_max; temp++) {
1796 pf = sc->sc_hw_ep_profile + temp;
1798 /* select endpoint */
1799 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, temp);
1801 fsize = MUSB2_READ_1(sc, MUSB2_REG_FSIZE);
1802 frx = (fsize & MUSB2_MASK_RX_FSIZE) / 16;
1803 ftx = (fsize & MUSB2_MASK_TX_FSIZE);
1805 DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u, DYN=%d\n",
1806 temp, ftx, frx, dynfifo);
1809 if (frx && (temp <= nrx)) {
1812 MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ,
1813 MUSB2_VAL_FIFOSZ_512 |
1816 frx = 7; /* 128 bytes */
1817 MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ,
1818 MUSB2_VAL_FIFOSZ_128);
1821 MUSB2_WRITE_2(sc, MUSB2_REG_RXFIFOADD,
1824 offset += (1 << frx);
1826 if (ftx && (temp <= ntx)) {
1829 MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ,
1830 MUSB2_VAL_FIFOSZ_512 |
1833 ftx = 7; /* 128 bytes */
1834 MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ,
1835 MUSB2_VAL_FIFOSZ_128);
1838 MUSB2_WRITE_2(sc, MUSB2_REG_TXFIFOADD,
1841 offset += (1 << ftx);
1845 if (frx && ftx && (temp <= nrx) && (temp <= ntx)) {
1846 pf->max_in_frame_size = 1 << ftx;
1847 pf->max_out_frame_size = 1 << frx;
1848 pf->is_simplex = 0; /* duplex */
1849 pf->support_multi_buffer = 1;
1850 pf->support_bulk = 1;
1851 pf->support_interrupt = 1;
1852 pf->support_isochronous = 1;
1854 pf->support_out = 1;
1855 } else if (frx && (temp <= nrx)) {
1856 pf->max_out_frame_size = 1 << frx;
1857 pf->is_simplex = 1; /* simplex */
1858 pf->support_multi_buffer = 1;
1859 pf->support_bulk = 1;
1860 pf->support_interrupt = 1;
1861 pf->support_isochronous = 1;
1862 pf->support_out = 1;
1863 } else if (ftx && (temp <= ntx)) {
1864 pf->max_in_frame_size = 1 << ftx;
1865 pf->is_simplex = 1; /* simplex */
1866 pf->support_multi_buffer = 1;
1867 pf->support_bulk = 1;
1868 pf->support_interrupt = 1;
1869 pf->support_isochronous = 1;
1874 DPRINTFN(2, "Dynamic FIFO size = %d bytes\n", offset);
1876 /* turn on default interrupts */
1878 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE,
1881 musbotg_clocks_off(sc);
1883 USB_BUS_UNLOCK(&sc->sc_bus);
1885 /* catch any lost interrupts */
1887 musbotg_do_poll(&sc->sc_bus);
1889 return (0); /* success */
1893 musbotg_uninit(struct musbotg_softc *sc)
1895 USB_BUS_LOCK(&sc->sc_bus);
1897 /* disable all interrupts */
1898 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
1899 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1900 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1902 sc->sc_flags.port_powered = 0;
1903 sc->sc_flags.status_vbus = 0;
1904 sc->sc_flags.status_bus_reset = 0;
1905 sc->sc_flags.status_suspend = 0;
1906 sc->sc_flags.change_suspend = 0;
1907 sc->sc_flags.change_connect = 1;
1909 musbotg_pull_down(sc);
1910 musbotg_clocks_off(sc);
1911 USB_BUS_UNLOCK(&sc->sc_bus);
1915 musbotg_suspend(struct musbotg_softc *sc)
1921 musbotg_resume(struct musbotg_softc *sc)
1927 musbotg_do_poll(struct usb_bus *bus)
1929 struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
1931 USB_BUS_LOCK(&sc->sc_bus);
1932 musbotg_interrupt_poll(sc);
1933 USB_BUS_UNLOCK(&sc->sc_bus);
1936 /*------------------------------------------------------------------------*
1937 * musbotg bulk support
1938 *------------------------------------------------------------------------*/
1940 musbotg_device_bulk_open(struct usb_xfer *xfer)
1946 musbotg_device_bulk_close(struct usb_xfer *xfer)
1948 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1952 musbotg_device_bulk_enter(struct usb_xfer *xfer)
1958 musbotg_device_bulk_start(struct usb_xfer *xfer)
1961 musbotg_setup_standard_chain(xfer);
1962 musbotg_start_standard_chain(xfer);
1965 struct usb_pipe_methods musbotg_device_bulk_methods =
1967 .open = musbotg_device_bulk_open,
1968 .close = musbotg_device_bulk_close,
1969 .enter = musbotg_device_bulk_enter,
1970 .start = musbotg_device_bulk_start,
1973 /*------------------------------------------------------------------------*
1974 * musbotg control support
1975 *------------------------------------------------------------------------*/
1977 musbotg_device_ctrl_open(struct usb_xfer *xfer)
1983 musbotg_device_ctrl_close(struct usb_xfer *xfer)
1985 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1989 musbotg_device_ctrl_enter(struct usb_xfer *xfer)
1995 musbotg_device_ctrl_start(struct usb_xfer *xfer)
1998 musbotg_setup_standard_chain(xfer);
1999 musbotg_start_standard_chain(xfer);
2002 struct usb_pipe_methods musbotg_device_ctrl_methods =
2004 .open = musbotg_device_ctrl_open,
2005 .close = musbotg_device_ctrl_close,
2006 .enter = musbotg_device_ctrl_enter,
2007 .start = musbotg_device_ctrl_start,
2010 /*------------------------------------------------------------------------*
2011 * musbotg interrupt support
2012 *------------------------------------------------------------------------*/
2014 musbotg_device_intr_open(struct usb_xfer *xfer)
2020 musbotg_device_intr_close(struct usb_xfer *xfer)
2022 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2026 musbotg_device_intr_enter(struct usb_xfer *xfer)
2032 musbotg_device_intr_start(struct usb_xfer *xfer)
2035 musbotg_setup_standard_chain(xfer);
2036 musbotg_start_standard_chain(xfer);
2039 struct usb_pipe_methods musbotg_device_intr_methods =
2041 .open = musbotg_device_intr_open,
2042 .close = musbotg_device_intr_close,
2043 .enter = musbotg_device_intr_enter,
2044 .start = musbotg_device_intr_start,
2047 /*------------------------------------------------------------------------*
2048 * musbotg full speed isochronous support
2049 *------------------------------------------------------------------------*/
2051 musbotg_device_isoc_open(struct usb_xfer *xfer)
2057 musbotg_device_isoc_close(struct usb_xfer *xfer)
2059 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2063 musbotg_device_isoc_enter(struct usb_xfer *xfer)
2065 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
2070 DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
2071 xfer, xfer->endpoint->isoc_next, xfer->nframes);
2073 /* get the current frame index */
2075 nframes = MUSB2_READ_2(sc, MUSB2_REG_FRAME);
2078 * check if the frame index is within the window where the frames
2081 temp = (nframes - xfer->endpoint->isoc_next) & MUSB2_MASK_FRAME;
2083 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
2084 fs_frames = (xfer->nframes + 7) / 8;
2086 fs_frames = xfer->nframes;
2089 if ((xfer->endpoint->is_synced == 0) ||
2090 (temp < fs_frames)) {
2092 * If there is data underflow or the pipe queue is
2093 * empty we schedule the transfer a few frames ahead
2094 * of the current frame position. Else two isochronous
2095 * transfers might overlap.
2097 xfer->endpoint->isoc_next = (nframes + 3) & MUSB2_MASK_FRAME;
2098 xfer->endpoint->is_synced = 1;
2099 DPRINTFN(2, "start next=%d\n", xfer->endpoint->isoc_next);
2102 * compute how many milliseconds the insertion is ahead of the
2103 * current frame position:
2105 temp = (xfer->endpoint->isoc_next - nframes) & MUSB2_MASK_FRAME;
2108 * pre-compute when the isochronous transfer will be finished:
2110 xfer->isoc_time_complete =
2111 usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2114 /* compute frame number for next insertion */
2115 xfer->endpoint->isoc_next += fs_frames;
2118 musbotg_setup_standard_chain(xfer);
2122 musbotg_device_isoc_start(struct usb_xfer *xfer)
2124 /* start TD chain */
2125 musbotg_start_standard_chain(xfer);
2128 struct usb_pipe_methods musbotg_device_isoc_methods =
2130 .open = musbotg_device_isoc_open,
2131 .close = musbotg_device_isoc_close,
2132 .enter = musbotg_device_isoc_enter,
2133 .start = musbotg_device_isoc_start,
2136 /*------------------------------------------------------------------------*
2137 * musbotg root control support
2138 *------------------------------------------------------------------------*
2139 * Simulate a hardware HUB by handling all the necessary requests.
2140 *------------------------------------------------------------------------*/
2142 static const struct usb_device_descriptor musbotg_devd = {
2143 .bLength = sizeof(struct usb_device_descriptor),
2144 .bDescriptorType = UDESC_DEVICE,
2145 .bcdUSB = {0x00, 0x02},
2146 .bDeviceClass = UDCLASS_HUB,
2147 .bDeviceSubClass = UDSUBCLASS_HUB,
2148 .bDeviceProtocol = UDPROTO_HSHUBSTT,
2149 .bMaxPacketSize = 64,
2150 .bcdDevice = {0x00, 0x01},
2153 .bNumConfigurations = 1,
2156 static const struct usb_device_qualifier musbotg_odevd = {
2157 .bLength = sizeof(struct usb_device_qualifier),
2158 .bDescriptorType = UDESC_DEVICE_QUALIFIER,
2159 .bcdUSB = {0x00, 0x02},
2160 .bDeviceClass = UDCLASS_HUB,
2161 .bDeviceSubClass = UDSUBCLASS_HUB,
2162 .bDeviceProtocol = UDPROTO_FSHUB,
2163 .bMaxPacketSize0 = 0,
2164 .bNumConfigurations = 0,
2167 static const struct musbotg_config_desc musbotg_confd = {
2169 .bLength = sizeof(struct usb_config_descriptor),
2170 .bDescriptorType = UDESC_CONFIG,
2171 .wTotalLength[0] = sizeof(musbotg_confd),
2173 .bConfigurationValue = 1,
2174 .iConfiguration = 0,
2175 .bmAttributes = UC_SELF_POWERED,
2179 .bLength = sizeof(struct usb_interface_descriptor),
2180 .bDescriptorType = UDESC_INTERFACE,
2182 .bInterfaceClass = UICLASS_HUB,
2183 .bInterfaceSubClass = UISUBCLASS_HUB,
2184 .bInterfaceProtocol = 0,
2187 .bLength = sizeof(struct usb_endpoint_descriptor),
2188 .bDescriptorType = UDESC_ENDPOINT,
2189 .bEndpointAddress = (UE_DIR_IN | MUSBOTG_INTR_ENDPT),
2190 .bmAttributes = UE_INTERRUPT,
2191 .wMaxPacketSize[0] = 8,
2196 static const struct usb_hub_descriptor_min musbotg_hubd = {
2197 .bDescLength = sizeof(musbotg_hubd),
2198 .bDescriptorType = UDESC_HUB,
2200 .wHubCharacteristics[0] =
2201 (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
2202 .wHubCharacteristics[1] =
2203 (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 16,
2204 .bPwrOn2PwrGood = 50,
2205 .bHubContrCurrent = 0,
2206 .DeviceRemovable = {0}, /* port is removable */
2209 #define STRING_LANG \
2210 0x09, 0x04, /* American English */
2212 #define STRING_VENDOR \
2213 'M', 0, 'e', 0, 'n', 0, 't', 0, 'o', 0, 'r', 0, ' ', 0, \
2214 'G', 0, 'r', 0, 'a', 0, 'p', 0, 'h', 0, 'i', 0, 'c', 0, 's', 0
2216 #define STRING_PRODUCT \
2217 'O', 0, 'T', 0, 'G', 0, ' ', 0, 'R', 0, \
2218 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
2221 USB_MAKE_STRING_DESC(STRING_LANG, musbotg_langtab);
2222 USB_MAKE_STRING_DESC(STRING_VENDOR, musbotg_vendor);
2223 USB_MAKE_STRING_DESC(STRING_PRODUCT, musbotg_product);
2226 musbotg_roothub_exec(struct usb_device *udev,
2227 struct usb_device_request *req, const void **pptr, uint16_t *plength)
2229 struct musbotg_softc *sc = MUSBOTG_BUS2SC(udev->bus);
2236 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
2239 ptr = (const void *)&sc->sc_hub_temp;
2243 value = UGETW(req->wValue);
2244 index = UGETW(req->wIndex);
2246 /* demultiplex the control request */
2248 switch (req->bmRequestType) {
2249 case UT_READ_DEVICE:
2250 switch (req->bRequest) {
2251 case UR_GET_DESCRIPTOR:
2252 goto tr_handle_get_descriptor;
2254 goto tr_handle_get_config;
2256 goto tr_handle_get_status;
2262 case UT_WRITE_DEVICE:
2263 switch (req->bRequest) {
2264 case UR_SET_ADDRESS:
2265 goto tr_handle_set_address;
2267 goto tr_handle_set_config;
2268 case UR_CLEAR_FEATURE:
2269 goto tr_valid; /* nop */
2270 case UR_SET_DESCRIPTOR:
2271 goto tr_valid; /* nop */
2272 case UR_SET_FEATURE:
2278 case UT_WRITE_ENDPOINT:
2279 switch (req->bRequest) {
2280 case UR_CLEAR_FEATURE:
2281 switch (UGETW(req->wValue)) {
2282 case UF_ENDPOINT_HALT:
2283 goto tr_handle_clear_halt;
2284 case UF_DEVICE_REMOTE_WAKEUP:
2285 goto tr_handle_clear_wakeup;
2290 case UR_SET_FEATURE:
2291 switch (UGETW(req->wValue)) {
2292 case UF_ENDPOINT_HALT:
2293 goto tr_handle_set_halt;
2294 case UF_DEVICE_REMOTE_WAKEUP:
2295 goto tr_handle_set_wakeup;
2300 case UR_SYNCH_FRAME:
2301 goto tr_valid; /* nop */
2307 case UT_READ_ENDPOINT:
2308 switch (req->bRequest) {
2310 goto tr_handle_get_ep_status;
2316 case UT_WRITE_INTERFACE:
2317 switch (req->bRequest) {
2318 case UR_SET_INTERFACE:
2319 goto tr_handle_set_interface;
2320 case UR_CLEAR_FEATURE:
2321 goto tr_valid; /* nop */
2322 case UR_SET_FEATURE:
2328 case UT_READ_INTERFACE:
2329 switch (req->bRequest) {
2330 case UR_GET_INTERFACE:
2331 goto tr_handle_get_interface;
2333 goto tr_handle_get_iface_status;
2339 case UT_WRITE_CLASS_INTERFACE:
2340 case UT_WRITE_VENDOR_INTERFACE:
2344 case UT_READ_CLASS_INTERFACE:
2345 case UT_READ_VENDOR_INTERFACE:
2349 case UT_WRITE_CLASS_DEVICE:
2350 switch (req->bRequest) {
2351 case UR_CLEAR_FEATURE:
2353 case UR_SET_DESCRIPTOR:
2354 case UR_SET_FEATURE:
2361 case UT_WRITE_CLASS_OTHER:
2362 switch (req->bRequest) {
2363 case UR_CLEAR_FEATURE:
2364 goto tr_handle_clear_port_feature;
2365 case UR_SET_FEATURE:
2366 goto tr_handle_set_port_feature;
2367 case UR_CLEAR_TT_BUFFER:
2377 case UT_READ_CLASS_OTHER:
2378 switch (req->bRequest) {
2379 case UR_GET_TT_STATE:
2380 goto tr_handle_get_tt_state;
2382 goto tr_handle_get_port_status;
2388 case UT_READ_CLASS_DEVICE:
2389 switch (req->bRequest) {
2390 case UR_GET_DESCRIPTOR:
2391 goto tr_handle_get_class_descriptor;
2393 goto tr_handle_get_class_status;
2404 tr_handle_get_descriptor:
2405 switch (value >> 8) {
2410 len = sizeof(musbotg_devd);
2411 ptr = (const void *)&musbotg_devd;
2417 len = sizeof(musbotg_confd);
2418 ptr = (const void *)&musbotg_confd;
2421 switch (value & 0xff) {
2422 case 0: /* Language table */
2423 len = sizeof(musbotg_langtab);
2424 ptr = (const void *)&musbotg_langtab;
2427 case 1: /* Vendor */
2428 len = sizeof(musbotg_vendor);
2429 ptr = (const void *)&musbotg_vendor;
2432 case 2: /* Product */
2433 len = sizeof(musbotg_product);
2434 ptr = (const void *)&musbotg_product;
2445 tr_handle_get_config:
2447 sc->sc_hub_temp.wValue[0] = sc->sc_conf;
2450 tr_handle_get_status:
2452 USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
2455 tr_handle_set_address:
2456 if (value & 0xFF00) {
2459 sc->sc_rt_addr = value;
2462 tr_handle_set_config:
2466 sc->sc_conf = value;
2469 tr_handle_get_interface:
2471 sc->sc_hub_temp.wValue[0] = 0;
2474 tr_handle_get_tt_state:
2475 tr_handle_get_class_status:
2476 tr_handle_get_iface_status:
2477 tr_handle_get_ep_status:
2479 USETW(sc->sc_hub_temp.wValue, 0);
2483 tr_handle_set_interface:
2484 tr_handle_set_wakeup:
2485 tr_handle_clear_wakeup:
2486 tr_handle_clear_halt:
2489 tr_handle_clear_port_feature:
2493 DPRINTFN(8, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
2496 case UHF_PORT_SUSPEND:
2497 musbotg_wakeup_peer(sc);
2500 case UHF_PORT_ENABLE:
2501 sc->sc_flags.port_enabled = 0;
2505 case UHF_PORT_INDICATOR:
2506 case UHF_C_PORT_ENABLE:
2507 case UHF_C_PORT_OVER_CURRENT:
2508 case UHF_C_PORT_RESET:
2511 case UHF_PORT_POWER:
2512 sc->sc_flags.port_powered = 0;
2513 musbotg_pull_down(sc);
2514 musbotg_clocks_off(sc);
2516 case UHF_C_PORT_CONNECTION:
2517 sc->sc_flags.change_connect = 0;
2519 case UHF_C_PORT_SUSPEND:
2520 sc->sc_flags.change_suspend = 0;
2523 err = USB_ERR_IOERROR;
2528 tr_handle_set_port_feature:
2532 DPRINTFN(8, "UR_SET_PORT_FEATURE\n");
2535 case UHF_PORT_ENABLE:
2536 sc->sc_flags.port_enabled = 1;
2538 case UHF_PORT_SUSPEND:
2539 case UHF_PORT_RESET:
2541 case UHF_PORT_INDICATOR:
2544 case UHF_PORT_POWER:
2545 sc->sc_flags.port_powered = 1;
2548 err = USB_ERR_IOERROR;
2553 tr_handle_get_port_status:
2555 DPRINTFN(8, "UR_GET_PORT_STATUS\n");
2560 if (sc->sc_flags.status_vbus) {
2561 musbotg_clocks_on(sc);
2562 musbotg_pull_up(sc);
2564 musbotg_pull_down(sc);
2565 musbotg_clocks_off(sc);
2568 /* Select Device Side Mode */
2569 value = UPS_PORT_MODE_DEVICE;
2571 if (sc->sc_flags.status_high_speed) {
2572 value |= UPS_HIGH_SPEED;
2574 if (sc->sc_flags.port_powered) {
2575 value |= UPS_PORT_POWER;
2577 if (sc->sc_flags.port_enabled) {
2578 value |= UPS_PORT_ENABLED;
2580 if (sc->sc_flags.status_vbus &&
2581 sc->sc_flags.status_bus_reset) {
2582 value |= UPS_CURRENT_CONNECT_STATUS;
2584 if (sc->sc_flags.status_suspend) {
2585 value |= UPS_SUSPEND;
2587 USETW(sc->sc_hub_temp.ps.wPortStatus, value);
2591 if (sc->sc_flags.change_connect) {
2592 value |= UPS_C_CONNECT_STATUS;
2594 if (sc->sc_flags.status_vbus &&
2595 sc->sc_flags.status_bus_reset) {
2596 /* reset EP0 state */
2597 sc->sc_ep0_busy = 0;
2601 if (sc->sc_flags.change_suspend) {
2602 value |= UPS_C_SUSPEND;
2604 USETW(sc->sc_hub_temp.ps.wPortChange, value);
2605 len = sizeof(sc->sc_hub_temp.ps);
2608 tr_handle_get_class_descriptor:
2612 ptr = (const void *)&musbotg_hubd;
2613 len = sizeof(musbotg_hubd);
2617 err = USB_ERR_STALLED;
2626 musbotg_xfer_setup(struct usb_setup_params *parm)
2628 const struct usb_hw_ep_profile *pf;
2629 struct musbotg_softc *sc;
2630 struct usb_xfer *xfer;
2636 sc = MUSBOTG_BUS2SC(parm->udev->bus);
2637 xfer = parm->curr_xfer;
2640 * NOTE: This driver does not use any of the parameters that
2641 * are computed from the following values. Just set some
2642 * reasonable dummies:
2644 parm->hc_max_packet_size = 0x400;
2645 parm->hc_max_frame_size = 0x400;
2647 if ((parm->methods == &musbotg_device_isoc_methods) ||
2648 (parm->methods == &musbotg_device_intr_methods))
2649 parm->hc_max_packet_count = 3;
2651 parm->hc_max_packet_count = 1;
2653 usbd_transfer_setup_sub(parm);
2656 * compute maximum number of TDs
2658 if (parm->methods == &musbotg_device_ctrl_methods) {
2660 ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
2662 } else if (parm->methods == &musbotg_device_bulk_methods) {
2664 ntd = xfer->nframes + 1 /* SYNC */ ;
2666 } else if (parm->methods == &musbotg_device_intr_methods) {
2668 ntd = xfer->nframes + 1 /* SYNC */ ;
2670 } else if (parm->methods == &musbotg_device_isoc_methods) {
2672 ntd = xfer->nframes + 1 /* SYNC */ ;
2680 * check if "usbd_transfer_setup_sub" set an error
2686 * allocate transfer descriptors
2695 ep_no = xfer->endpointno & UE_ADDR;
2696 musbotg_get_hw_ep_profile(parm->udev, &pf, ep_no);
2699 /* should not happen */
2700 parm->err = USB_ERR_INVAL;
2709 parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
2711 for (n = 0; n != ntd; n++) {
2713 struct musbotg_td *td;
2717 td = USB_ADD_BYTES(parm->buf, parm->size[0]);
2720 td->max_frame_size = xfer->max_frame_size;
2722 td->obj_next = last_obj;
2726 parm->size[0] += sizeof(*td);
2729 xfer->td_start[0] = last_obj;
2733 musbotg_xfer_unsetup(struct usb_xfer *xfer)
2739 musbotg_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
2740 struct usb_endpoint *ep)
2742 struct musbotg_softc *sc = MUSBOTG_BUS2SC(udev->bus);
2744 DPRINTFN(2, "endpoint=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
2746 edesc->bEndpointAddress, udev->flags.usb_mode,
2749 if (udev->device_index != sc->sc_rt_addr) {
2751 if (udev->flags.usb_mode != USB_MODE_DEVICE) {
2755 if ((udev->speed != USB_SPEED_FULL) &&
2756 (udev->speed != USB_SPEED_HIGH)) {
2760 switch (edesc->bmAttributes & UE_XFERTYPE) {
2762 ep->methods = &musbotg_device_ctrl_methods;
2765 ep->methods = &musbotg_device_intr_methods;
2767 case UE_ISOCHRONOUS:
2768 ep->methods = &musbotg_device_isoc_methods;
2771 ep->methods = &musbotg_device_bulk_methods;
2780 struct usb_bus_methods musbotg_bus_methods =
2782 .endpoint_init = &musbotg_ep_init,
2783 .xfer_setup = &musbotg_xfer_setup,
2784 .xfer_unsetup = &musbotg_xfer_unsetup,
2785 .get_hw_ep_profile = &musbotg_get_hw_ep_profile,
2786 .set_stall = &musbotg_set_stall,
2787 .clear_stall = &musbotg_clear_stall,
2788 .roothub_exec = &musbotg_roothub_exec,
2789 .xfer_poll = &musbotg_do_poll,