5 * Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * This file contains the driver for Octeon Executive Library USB
31 * Controller driver API.
34 /* TODO: The root HUB port callback is not yet implemented. */
36 #include <sys/stdint.h>
37 #include <sys/stddef.h>
38 #include <sys/param.h>
39 #include <sys/queue.h>
40 #include <sys/types.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
44 #include <sys/module.h>
46 #include <sys/mutex.h>
47 #include <sys/condvar.h>
48 #include <sys/sysctl.h>
50 #include <sys/unistd.h>
51 #include <sys/callout.h>
52 #include <sys/malloc.h>
55 #include <dev/usb/usb.h>
56 #include <dev/usb/usbdi.h>
58 #define USB_DEBUG_VAR octusbdebug
60 #include <dev/usb/usb_core.h>
61 #include <dev/usb/usb_debug.h>
62 #include <dev/usb/usb_busdma.h>
63 #include <dev/usb/usb_process.h>
64 #include <dev/usb/usb_transfer.h>
65 #include <dev/usb/usb_device.h>
66 #include <dev/usb/usb_hub.h>
67 #include <dev/usb/usb_util.h>
69 #include <dev/usb/usb_controller.h>
70 #include <dev/usb/usb_bus.h>
72 #include <contrib/octeon-sdk/cvmx.h>
73 #include <contrib/octeon-sdk/cvmx-usb.h>
75 #include <mips/cavium/usb/octusb.h>
77 #define OCTUSB_BUS2SC(bus) \
78 ((struct octusb_softc *)(((uint8_t *)(bus)) - \
79 ((uint8_t *)&(((struct octusb_softc *)0)->sc_bus))))
82 static int octusbdebug = 0;
84 static SYSCTL_NODE(_hw_usb, OID_AUTO, octusb, CTLFLAG_RW, 0, "OCTUSB");
85 SYSCTL_INT(_hw_usb_octusb, OID_AUTO, debug, CTLFLAG_RWTUN,
86 &octusbdebug, 0, "OCTUSB debug level");
89 struct octusb_std_temp {
92 struct octusb_td *td_next;
93 struct usb_page_cache *pc;
97 uint8_t setup_alt_next;
100 extern struct usb_bus_methods octusb_bus_methods;
101 extern struct usb_pipe_methods octusb_device_bulk_methods;
102 extern struct usb_pipe_methods octusb_device_ctrl_methods;
103 extern struct usb_pipe_methods octusb_device_intr_methods;
104 extern struct usb_pipe_methods octusb_device_isoc_methods;
106 static void octusb_standard_done(struct usb_xfer *);
107 static void octusb_device_done(struct usb_xfer *, usb_error_t);
108 static void octusb_timeout(void *);
109 static void octusb_do_poll(struct usb_bus *);
111 static cvmx_usb_speed_t
112 octusb_convert_speed(enum usb_dev_speed speed)
117 return (CVMX_USB_SPEED_HIGH);
119 return (CVMX_USB_SPEED_FULL);
121 return (CVMX_USB_SPEED_LOW);
125 static cvmx_usb_transfer_t
126 octusb_convert_ep_type(uint8_t ep_type)
129 switch (ep_type & UE_XFERTYPE) {
131 return (CVMX_USB_TRANSFER_CONTROL);
133 return (CVMX_USB_TRANSFER_INTERRUPT);
135 return (CVMX_USB_TRANSFER_ISOCHRONOUS);
137 return (CVMX_USB_TRANSFER_BULK);
139 return (0); /* should not happen */
144 octusb_host_alloc_endpoint(struct octusb_td *td)
146 struct octusb_softc *sc;
149 if (td->qh->fixup_pending)
150 return (1); /* busy */
152 if (td->qh->ep_allocated)
153 return (0); /* success */
158 ep_handle = cvmx_usb_open_pipe(
159 &sc->sc_port[td->qh->root_port_index].state,
162 td->qh->ep_num & UE_ADDR,
163 octusb_convert_speed(td->qh->dev_speed),
164 td->qh->max_packet_size,
165 octusb_convert_ep_type(td->qh->ep_type),
166 (td->qh->ep_num & UE_DIR_IN) ? CVMX_USB_DIRECTION_IN :
167 CVMX_USB_DIRECTION_OUT,
169 (td->qh->dev_speed == USB_SPEED_HIGH) ? td->qh->ep_mult : 0,
171 td->qh->hs_hub_port);
174 DPRINTFN(1, "cvmx_usb_open_pipe failed: %d\n", ep_handle);
175 return (1); /* busy */
179 &sc->sc_port[td->qh->root_port_index].state,
180 ep_handle, td->qh->ep_toggle_next);
182 td->qh->fixup_handle = -1;
183 td->qh->fixup_complete = 0;
184 td->qh->fixup_len = 0;
185 td->qh->fixup_off = 0;
186 td->qh->fixup_pending = 0;
187 td->qh->fixup_actlen = 0;
189 td->qh->ep_handle = ep_handle;
190 td->qh->ep_allocated = 1;
192 return (0); /* success */
196 octusb_host_free_endpoint(struct octusb_td *td)
198 struct octusb_softc *sc;
200 if (td->qh->ep_allocated == 0)
206 if (td->qh->fixup_handle >= 0) {
208 cvmx_usb_cancel(&sc->sc_port[td->qh->root_port_index].state,
209 td->qh->ep_handle, td->qh->fixup_handle);
211 cvmx_usb_close_pipe(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle);
213 td->qh->ep_allocated = 0;
217 octusb_complete_cb(cvmx_usb_state_t *state,
218 cvmx_usb_callback_t reason,
219 cvmx_usb_complete_t status,
220 int pipe_handle, int submit_handle,
221 int bytes_transferred, void *user_data)
223 struct octusb_td *td;
225 if (reason != CVMX_USB_CALLBACK_TRANSFER_COMPLETE)
230 td->qh->fixup_complete = 1;
231 td->qh->fixup_pending = 0;
232 td->qh->fixup_actlen = bytes_transferred;
233 td->qh->fixup_handle = -1;
236 case CVMX_USB_COMPLETE_SUCCESS:
237 case CVMX_USB_COMPLETE_SHORT:
241 case CVMX_USB_COMPLETE_STALL:
252 octusb_host_control_header_tx(struct octusb_td *td)
256 /* allocate endpoint and check pending */
257 if (octusb_host_alloc_endpoint(td))
258 return (1); /* busy */
262 return (0); /* done */
264 if (td->qh->fixup_complete != 0) {
265 /* clear complete flag */
266 td->qh->fixup_complete = 0;
269 usb_pc_cpu_invalidate(td->qh->fixup_pc);
270 return (0); /* done */
273 if (td->remainder != 8) {
275 return (0); /* done */
277 usbd_copy_out(td->pc, td->offset, td->qh->fixup_buf, 8);
279 /* update offset and remainder */
283 /* setup data length and offset */
284 td->qh->fixup_len = UGETW(td->qh->fixup_buf + 6);
285 td->qh->fixup_off = 0;
287 if (td->qh->fixup_len > (OCTUSB_MAX_FIXUP - 8)) {
289 return (0); /* done */
291 /* do control IN request */
292 if (td->qh->fixup_buf[0] & UE_DIR_IN) {
294 struct octusb_softc *sc;
300 usb_pc_cpu_flush(td->qh->fixup_pc);
302 status = cvmx_usb_submit_control(
303 &sc->sc_port[td->qh->root_port_index].state,
304 td->qh->ep_handle, td->qh->fixup_phys,
305 td->qh->fixup_phys + 8, td->qh->fixup_len,
306 &octusb_complete_cb, td);
310 return (0); /* done */
312 td->qh->fixup_handle = status;
313 td->qh->fixup_pending = 1;
314 td->qh->fixup_complete = 0;
316 return (1); /* busy */
318 return (0); /* done */
322 octusb_host_control_data_tx(struct octusb_td *td)
326 /* allocate endpoint and check pending */
327 if (octusb_host_alloc_endpoint(td))
328 return (1); /* busy */
332 return (0); /* done */
334 rem = td->qh->fixup_len - td->qh->fixup_off;
336 if (td->remainder > rem) {
338 DPRINTFN(1, "Excess setup transmit data\n");
339 return (0); /* done */
341 usbd_copy_out(td->pc, td->offset, td->qh->fixup_buf +
342 td->qh->fixup_off + 8, td->remainder);
344 td->offset += td->remainder;
345 td->qh->fixup_off += td->remainder;
348 return (0); /* done */
352 octusb_host_control_data_rx(struct octusb_td *td)
356 /* allocate endpoint and check pending */
357 if (octusb_host_alloc_endpoint(td))
358 return (1); /* busy */
362 return (0); /* done */
364 /* copy data from buffer */
365 rem = td->qh->fixup_actlen - td->qh->fixup_off;
367 if (rem > td->remainder)
370 usbd_copy_in(td->pc, td->offset, td->qh->fixup_buf +
371 td->qh->fixup_off + 8, rem);
374 td->remainder -= rem;
375 td->qh->fixup_off += rem;
377 return (0); /* done */
381 octusb_host_control_status_tx(struct octusb_td *td)
385 /* allocate endpoint and check pending */
386 if (octusb_host_alloc_endpoint(td))
387 return (1); /* busy */
391 return (0); /* done */
393 if (td->qh->fixup_complete != 0) {
394 /* clear complete flag */
395 td->qh->fixup_complete = 0;
399 /* do control IN request */
400 if (!(td->qh->fixup_buf[0] & UE_DIR_IN)) {
402 struct octusb_softc *sc;
408 usb_pc_cpu_flush(td->qh->fixup_pc);
410 /* start USB transfer */
411 status = cvmx_usb_submit_control(
412 &sc->sc_port[td->qh->root_port_index].state,
413 td->qh->ep_handle, td->qh->fixup_phys,
414 td->qh->fixup_phys + 8, td->qh->fixup_len,
415 &octusb_complete_cb, td);
420 return (0); /* done */
422 td->qh->fixup_handle = status;
423 td->qh->fixup_pending = 1;
424 td->qh->fixup_complete = 0;
426 return (1); /* busy */
428 return (0); /* done */
432 octusb_non_control_data_tx(struct octusb_td *td)
434 struct octusb_softc *sc;
438 /* allocate endpoint and check pending */
439 if (octusb_host_alloc_endpoint(td))
440 return (1); /* busy */
444 return (0); /* done */
446 if ((td->qh->fixup_complete != 0) &&
447 ((td->qh->ep_type & UE_XFERTYPE) == UE_ISOCHRONOUS)) {
448 td->qh->fixup_complete = 0;
449 return (0); /* done */
452 if (td->remainder == 0) {
454 return (0); /* complete */
455 /* else need to send a zero length packet */
459 /* get maximum length */
460 rem = OCTUSB_MAX_FIXUP % td->qh->max_frame_size;
461 rem = OCTUSB_MAX_FIXUP - rem;
464 /* should not happen */
465 DPRINTFN(1, "Fixup buffer is too small\n");
467 return (0); /* done */
469 /* get minimum length */
470 if (rem > td->remainder) {
472 if ((rem == 0) || (rem % td->qh->max_frame_size))
475 /* copy data into fixup buffer */
476 usbd_copy_out(td->pc, td->offset, td->qh->fixup_buf, rem);
479 usb_pc_cpu_flush(td->qh->fixup_pc);
481 /* pre-increment TX buffer offset */
483 td->remainder -= rem;
489 switch (td->qh->ep_type & UE_XFERTYPE) {
491 td->qh->iso_pkt.offset = 0;
492 td->qh->iso_pkt.length = rem;
493 td->qh->iso_pkt.status = 0;
494 /* start USB transfer */
495 status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->root_port_index].state,
496 td->qh->ep_handle, 1, CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT |
497 CVMX_USB_ISOCHRONOUS_FLAGS_ASAP, 1, &td->qh->iso_pkt,
498 td->qh->fixup_phys, rem, &octusb_complete_cb, td);
501 /* start USB transfer */
502 status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->root_port_index].state,
503 td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td);
506 /* start USB transfer (interrupt or interrupt) */
507 status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->root_port_index].state,
508 td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td);
518 return (0); /* done */
520 td->qh->fixup_handle = status;
521 td->qh->fixup_len = rem;
522 td->qh->fixup_pending = 1;
523 td->qh->fixup_complete = 0;
525 return (1); /* busy */
529 octusb_non_control_data_rx(struct octusb_td *td)
531 struct octusb_softc *sc;
536 /* allocate endpoint and check pending */
537 if (octusb_host_alloc_endpoint(td))
538 return (1); /* busy */
542 return (0); /* done */
546 if (td->qh->fixup_complete != 0) {
548 /* invalidate data */
549 usb_pc_cpu_invalidate(td->qh->fixup_pc);
551 rem = td->qh->fixup_actlen;
553 /* verify transfer length */
554 if (rem != td->qh->fixup_len) {
555 if (rem < td->qh->fixup_len) {
556 /* we have a short packet */
560 /* invalid USB packet */
562 return (0); /* we are complete */
565 /* copy data into fixup buffer */
566 usbd_copy_in(td->pc, td->offset, td->qh->fixup_buf, rem);
568 /* post-increment RX buffer offset */
570 td->remainder -= rem;
572 td->qh->fixup_complete = 0;
574 if ((td->qh->ep_type & UE_XFERTYPE) == UE_ISOCHRONOUS)
575 return (0); /* done */
577 /* check if we are complete */
578 if ((td->remainder == 0) || got_short) {
580 /* we are complete */
583 /* else need to receive a zero length packet */
587 /* get maximum length */
588 rem = OCTUSB_MAX_FIXUP % td->qh->max_frame_size;
589 rem = OCTUSB_MAX_FIXUP - rem;
592 /* should not happen */
593 DPRINTFN(1, "Fixup buffer is too small\n");
595 return (0); /* done */
597 /* get minimum length */
598 if (rem > td->remainder)
602 /* invalidate data */
603 usb_pc_cpu_invalidate(td->qh->fixup_pc);
608 switch (td->qh->ep_type & UE_XFERTYPE) {
610 td->qh->iso_pkt.offset = 0;
611 td->qh->iso_pkt.length = rem;
612 td->qh->iso_pkt.status = 0;
613 /* start USB transfer */
614 status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->root_port_index].state,
615 td->qh->ep_handle, 1, CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT |
616 CVMX_USB_ISOCHRONOUS_FLAGS_ASAP, 1, &td->qh->iso_pkt,
617 td->qh->fixup_phys, rem, &octusb_complete_cb, td);
620 /* start USB transfer */
621 status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->root_port_index].state,
622 td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td);
625 /* start USB transfer */
626 status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->root_port_index].state,
627 td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td);
637 return (0); /* done */
639 td->qh->fixup_handle = status;
640 td->qh->fixup_len = rem;
641 td->qh->fixup_pending = 1;
642 td->qh->fixup_complete = 0;
644 return (1); /* busy */
648 octusb_xfer_do_fifo(struct usb_xfer *xfer)
650 struct octusb_td *td;
654 td = xfer->td_transfer_cache;
657 if ((td->func) (td)) {
658 /* operation in progress */
661 if (((void *)td) == xfer->td_transfer_last) {
666 } else if (td->remainder > 0) {
668 * We had a short transfer. If there is no
669 * alternate next, stop processing !
671 if (td->alt_next == 0)
675 * Fetch the next transfer descriptor and transfer
676 * some flags to the next transfer descriptor
679 xfer->td_transfer_cache = td;
681 return (1); /* not complete */
684 /* compute all actual lengths */
686 octusb_standard_done(xfer);
688 return (0); /* complete */
692 octusb_standard_done_sub(struct usb_xfer *xfer)
694 struct octusb_td *td;
700 td = xfer->td_transfer_cache;
705 if (xfer->aframes != xfer->nframes) {
707 * Verify the length and subtract
708 * the remainder from "frlengths[]":
710 if (len > xfer->frlengths[xfer->aframes]) {
713 xfer->frlengths[xfer->aframes] -= len;
716 /* Check for transfer error */
718 /* the transfer is finished */
719 error = td->error_stall ? USB_ERR_STALLED : USB_ERR_IOERROR;
723 /* Check for short transfer */
725 if (xfer->flags_int.short_frames_ok) {
726 /* follow alt next */
733 /* the transfer is finished */
741 /* this USB frame is complete */
747 /* update transfer cache */
749 xfer->td_transfer_cache = td;
755 octusb_standard_done(struct usb_xfer *xfer)
757 struct octusb_softc *sc;
758 struct octusb_qh *qh;
759 usb_error_t error = 0;
761 DPRINTFN(12, "xfer=%p endpoint=%p transfer done\n",
762 xfer, xfer->endpoint);
766 xfer->td_transfer_cache = xfer->td_transfer_first;
768 if (xfer->flags_int.control_xfr) {
770 if (xfer->flags_int.control_hdr)
771 error = octusb_standard_done_sub(xfer);
775 if (xfer->td_transfer_cache == NULL)
778 while (xfer->aframes != xfer->nframes) {
780 error = octusb_standard_done_sub(xfer);
784 if (xfer->td_transfer_cache == NULL)
788 if (xfer->flags_int.control_xfr &&
789 !xfer->flags_int.control_act)
790 error = octusb_standard_done_sub(xfer);
793 /* update data toggle */
795 qh = xfer->qh_start[0];
798 xfer->endpoint->toggle_next =
800 &sc->sc_port[qh->root_port_index].state,
801 qh->ep_handle) ? 1 : 0;
803 octusb_device_done(xfer, error);
807 octusb_interrupt_poll(struct octusb_softc *sc)
809 struct usb_xfer *xfer;
813 for (x = 0; x != sc->sc_noport; x++)
814 cvmx_usb_poll(&sc->sc_port[x].state);
817 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
818 if (!octusb_xfer_do_fifo(xfer)) {
819 /* queue has been modified */
826 octusb_start_standard_chain(struct usb_xfer *xfer)
831 if (octusb_xfer_do_fifo(xfer)) {
833 /* put transfer on interrupt queue */
834 usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
836 /* start timeout, if any */
837 if (xfer->timeout != 0) {
838 usbd_transfer_timeout_ms(xfer,
839 &octusb_timeout, xfer->timeout);
845 octusb_iterate_hw_softc(struct usb_bus *bus, usb_bus_mem_sub_cb_t *cb)
851 octusb_init(struct octusb_softc *sc)
853 cvmx_usb_initialize_flags_t flags;
857 /* flush all cache into memory */
859 usb_bus_mem_flush_all(&sc->sc_bus, &octusb_iterate_hw_softc);
861 /* set up the bus struct */
862 sc->sc_bus.methods = &octusb_bus_methods;
864 /* get number of ports */
865 sc->sc_noport = cvmx_usb_get_num_ports();
867 /* check number of ports */
868 if (sc->sc_noport > OCTUSB_MAX_PORTS)
869 sc->sc_noport = OCTUSB_MAX_PORTS;
871 /* set USB revision */
872 sc->sc_bus.usbrev = USB_REV_2_0;
874 /* flags for port initialization */
875 flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO;
877 if (octusbdebug > 100)
878 flags |= CVMX_USB_INITIALIZE_FLAGS_DEBUG_ALL;
881 USB_BUS_LOCK(&sc->sc_bus);
883 /* setup all ports */
884 for (x = 0; x != sc->sc_noport; x++) {
885 status = cvmx_usb_initialize(&sc->sc_port[x].state, x, flags);
887 sc->sc_port[x].disabled = 1;
890 USB_BUS_UNLOCK(&sc->sc_bus);
892 /* catch lost interrupts */
893 octusb_do_poll(&sc->sc_bus);
899 octusb_uninit(struct octusb_softc *sc)
903 USB_BUS_LOCK(&sc->sc_bus);
905 for (x = 0; x != sc->sc_noport; x++) {
906 if (sc->sc_port[x].disabled == 0)
907 cvmx_usb_shutdown(&sc->sc_port[x].state);
909 USB_BUS_UNLOCK(&sc->sc_bus);
916 octusb_suspend(struct octusb_softc *sc)
922 octusb_resume(struct octusb_softc *sc)
927 /*------------------------------------------------------------------------*
928 * octusb_interrupt - OCTUSB interrupt handler
929 *------------------------------------------------------------------------*/
931 octusb_interrupt(struct octusb_softc *sc)
933 USB_BUS_LOCK(&sc->sc_bus);
935 DPRINTFN(16, "real interrupt\n");
937 /* poll all the USB transfers */
938 octusb_interrupt_poll(sc);
940 USB_BUS_UNLOCK(&sc->sc_bus);
943 /*------------------------------------------------------------------------*
944 * octusb_timeout - OCTUSB transfer timeout handler
945 *------------------------------------------------------------------------*/
947 octusb_timeout(void *arg)
949 struct usb_xfer *xfer = arg;
951 DPRINTF("xfer=%p\n", xfer);
953 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
955 /* transfer is transferred */
956 octusb_device_done(xfer, USB_ERR_TIMEOUT);
959 /*------------------------------------------------------------------------*
960 * octusb_do_poll - OCTUSB poll transfers
961 *------------------------------------------------------------------------*/
963 octusb_do_poll(struct usb_bus *bus)
965 struct octusb_softc *sc = OCTUSB_BUS2SC(bus);
967 USB_BUS_LOCK(&sc->sc_bus);
968 octusb_interrupt_poll(sc);
969 USB_BUS_UNLOCK(&sc->sc_bus);
973 octusb_setup_standard_chain_sub(struct octusb_std_temp *temp)
975 struct octusb_td *td;
977 /* get current Transfer Descriptor */
981 /* prepare for next TD */
982 temp->td_next = td->obj_next;
984 /* fill out the Transfer Descriptor */
985 td->func = temp->func;
987 td->offset = temp->offset;
988 td->remainder = temp->len;
991 td->short_pkt = temp->short_pkt;
992 td->alt_next = temp->setup_alt_next;
996 octusb_setup_standard_chain(struct usb_xfer *xfer)
998 struct octusb_std_temp temp;
999 struct octusb_td *td;
1002 DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
1003 xfer->address, UE_GET_ADDR(xfer->endpointno),
1004 xfer->sumlen, usbd_get_speed(xfer->xroot->udev));
1006 /* setup starting point */
1007 td = xfer->td_start[0];
1008 xfer->td_transfer_first = td;
1009 xfer->td_transfer_cache = td;
1013 temp.setup_alt_next = xfer->flags_int.short_frames_ok;
1016 /* check if we should prepend a setup message */
1018 if (xfer->flags_int.control_xfr) {
1020 if (xfer->flags_int.control_hdr) {
1022 temp.func = &octusb_host_control_header_tx;
1023 temp.len = xfer->frlengths[0];
1024 temp.pc = xfer->frbuffers + 0;
1025 temp.short_pkt = temp.len ? 1 : 0;
1027 /* check for last frame */
1028 if (xfer->nframes == 1) {
1030 * no STATUS stage yet, SETUP is
1033 if (xfer->flags_int.control_act)
1034 temp.setup_alt_next = 0;
1036 octusb_setup_standard_chain_sub(&temp);
1043 if (x != xfer->nframes) {
1044 if (xfer->endpointno & UE_DIR_IN) {
1045 if (xfer->flags_int.control_xfr)
1046 temp.func = &octusb_host_control_data_rx;
1048 temp.func = &octusb_non_control_data_rx;
1050 if (xfer->flags_int.control_xfr)
1051 temp.func = &octusb_host_control_data_tx;
1053 temp.func = &octusb_non_control_data_tx;
1056 /* setup "pc" pointer */
1057 temp.pc = xfer->frbuffers + x;
1059 while (x != xfer->nframes) {
1061 /* DATA0 or DATA1 message */
1063 temp.len = xfer->frlengths[x];
1067 if (x == xfer->nframes) {
1068 if (xfer->flags_int.control_xfr) {
1069 /* no STATUS stage yet, DATA is last */
1070 if (xfer->flags_int.control_act)
1071 temp.setup_alt_next = 0;
1073 temp.setup_alt_next = 0;
1076 if (temp.len == 0) {
1078 /* make sure that we send an USB packet */
1084 /* regular data transfer */
1086 temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
1089 octusb_setup_standard_chain_sub(&temp);
1091 if (xfer->flags_int.isochronous_xfr) {
1092 /* get next data offset */
1093 temp.offset += temp.len;
1095 /* get next Page Cache pointer */
1096 temp.pc = xfer->frbuffers + x;
1100 /* check if we should append a status stage */
1102 if (xfer->flags_int.control_xfr &&
1103 !xfer->flags_int.control_act) {
1105 temp.func = &octusb_host_control_status_tx;
1109 temp.setup_alt_next = 0;
1111 octusb_setup_standard_chain_sub(&temp);
1113 /* must have at least one frame! */
1115 xfer->td_transfer_last = td;
1117 /* properly setup QH */
1119 td->qh->ep_allocated = 0;
1120 td->qh->ep_toggle_next = xfer->endpoint->toggle_next ? 1 : 0;
1123 /*------------------------------------------------------------------------*
1124 * octusb_device_done - OCTUSB transfers done code
1126 * NOTE: This function can be called more than one time in a row.
1127 *------------------------------------------------------------------------*/
1129 octusb_device_done(struct usb_xfer *xfer, usb_error_t error)
1131 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1133 DPRINTFN(2, "xfer=%p, endpoint=%p, error=%d\n",
1134 xfer, xfer->endpoint, error);
1137 * 1) Free any endpoints.
1138 * 2) Control transfers can be split and we should not re-open
1139 * the data pipe between transactions unless there is an error.
1141 if ((xfer->flags_int.control_act == 0) || (error != 0)) {
1142 struct octusb_td *td;
1144 td = xfer->td_start[0];
1146 octusb_host_free_endpoint(td);
1148 /* dequeue transfer and start next transfer */
1149 usbd_transfer_done(xfer, error);
1152 /*------------------------------------------------------------------------*
1153 * octusb bulk support
1154 *------------------------------------------------------------------------*/
1156 octusb_device_bulk_open(struct usb_xfer *xfer)
1162 octusb_device_bulk_close(struct usb_xfer *xfer)
1164 octusb_device_done(xfer, USB_ERR_CANCELLED);
1168 octusb_device_bulk_enter(struct usb_xfer *xfer)
1174 octusb_device_bulk_start(struct usb_xfer *xfer)
1177 octusb_setup_standard_chain(xfer);
1178 octusb_start_standard_chain(xfer);
1181 struct usb_pipe_methods octusb_device_bulk_methods =
1183 .open = octusb_device_bulk_open,
1184 .close = octusb_device_bulk_close,
1185 .enter = octusb_device_bulk_enter,
1186 .start = octusb_device_bulk_start,
1189 /*------------------------------------------------------------------------*
1190 * octusb control support
1191 *------------------------------------------------------------------------*/
1193 octusb_device_ctrl_open(struct usb_xfer *xfer)
1199 octusb_device_ctrl_close(struct usb_xfer *xfer)
1201 octusb_device_done(xfer, USB_ERR_CANCELLED);
1205 octusb_device_ctrl_enter(struct usb_xfer *xfer)
1211 octusb_device_ctrl_start(struct usb_xfer *xfer)
1214 octusb_setup_standard_chain(xfer);
1215 octusb_start_standard_chain(xfer);
1218 struct usb_pipe_methods octusb_device_ctrl_methods =
1220 .open = octusb_device_ctrl_open,
1221 .close = octusb_device_ctrl_close,
1222 .enter = octusb_device_ctrl_enter,
1223 .start = octusb_device_ctrl_start,
1226 /*------------------------------------------------------------------------*
1227 * octusb interrupt support
1228 *------------------------------------------------------------------------*/
1230 octusb_device_intr_open(struct usb_xfer *xfer)
1236 octusb_device_intr_close(struct usb_xfer *xfer)
1238 octusb_device_done(xfer, USB_ERR_CANCELLED);
1242 octusb_device_intr_enter(struct usb_xfer *xfer)
1248 octusb_device_intr_start(struct usb_xfer *xfer)
1251 octusb_setup_standard_chain(xfer);
1252 octusb_start_standard_chain(xfer);
1255 struct usb_pipe_methods octusb_device_intr_methods =
1257 .open = octusb_device_intr_open,
1258 .close = octusb_device_intr_close,
1259 .enter = octusb_device_intr_enter,
1260 .start = octusb_device_intr_start,
1263 /*------------------------------------------------------------------------*
1264 * octusb isochronous support
1265 *------------------------------------------------------------------------*/
1267 octusb_device_isoc_open(struct usb_xfer *xfer)
1273 octusb_device_isoc_close(struct usb_xfer *xfer)
1275 octusb_device_done(xfer, USB_ERR_CANCELLED);
1279 octusb_device_isoc_enter(struct usb_xfer *xfer)
1281 struct octusb_softc *sc = OCTUSB_BUS2SC(xfer->xroot->bus);
1283 uint32_t frame_count;
1286 DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
1287 xfer, xfer->endpoint->isoc_next, xfer->nframes);
1289 /* get the current frame index */
1291 frame_count = cvmx_usb_get_frame_number(
1292 &sc->sc_port[xfer->xroot->udev->port_index].state);
1295 * check if the frame index is within the window where the frames
1298 temp = (frame_count - xfer->endpoint->isoc_next) & 0x7FF;
1300 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
1301 fs_frames = (xfer->nframes + 7) / 8;
1303 fs_frames = xfer->nframes;
1306 if ((xfer->endpoint->is_synced == 0) || (temp < fs_frames)) {
1308 * If there is data underflow or the pipe queue is
1309 * empty we schedule the transfer a few frames ahead
1310 * of the current frame position. Else two isochronous
1311 * transfers might overlap.
1313 xfer->endpoint->isoc_next = (frame_count + 3) & 0x7FF;
1314 xfer->endpoint->is_synced = 1;
1315 DPRINTFN(2, "start next=%d\n", xfer->endpoint->isoc_next);
1318 * compute how many milliseconds the insertion is ahead of the
1319 * current frame position:
1321 temp = (xfer->endpoint->isoc_next - frame_count) & 0x7FF;
1324 * pre-compute when the isochronous transfer will be finished:
1326 xfer->isoc_time_complete =
1327 usb_isoc_time_expand(&sc->sc_bus, frame_count) + temp +
1330 /* compute frame number for next insertion */
1331 xfer->endpoint->isoc_next += fs_frames;
1335 octusb_device_isoc_start(struct usb_xfer *xfer)
1338 octusb_setup_standard_chain(xfer);
1339 octusb_start_standard_chain(xfer);
1342 struct usb_pipe_methods octusb_device_isoc_methods =
1344 .open = octusb_device_isoc_open,
1345 .close = octusb_device_isoc_close,
1346 .enter = octusb_device_isoc_enter,
1347 .start = octusb_device_isoc_start,
1350 /*------------------------------------------------------------------------*
1351 * OCTUSB root HUB support
1352 *------------------------------------------------------------------------*
1353 * Simulate a hardware HUB by handling all the necessary requests.
1354 *------------------------------------------------------------------------*/
1356 struct usb_device_descriptor octusb_devd = {
1357 .bLength = sizeof(octusb_devd),
1358 .bDescriptorType = UDESC_DEVICE,
1359 .bcdUSB = {0x00, 0x02},
1360 .bDeviceClass = UDCLASS_HUB,
1361 .bDeviceSubClass = UDSUBCLASS_HUB,
1362 .bDeviceProtocol = UDPROTO_FSHUB,
1363 .bMaxPacketSize = 64,
1366 .bcdDevice = {0x00, 0x01},
1370 .bNumConfigurations = 1,
1374 struct usb_device_qualifier octusb_odevd = {
1375 .bLength = sizeof(octusb_odevd),
1376 .bDescriptorType = UDESC_DEVICE_QUALIFIER,
1377 .bcdUSB = {0x00, 0x02},
1378 .bDeviceClass = UDCLASS_HUB,
1379 .bDeviceSubClass = UDSUBCLASS_HUB,
1380 .bDeviceProtocol = UDPROTO_FSHUB,
1381 .bMaxPacketSize0 = 0,
1382 .bNumConfigurations = 0,
1387 struct octusb_config_desc octusb_confd = {
1389 .bLength = sizeof(struct usb_config_descriptor),
1390 .bDescriptorType = UDESC_CONFIG,
1391 .wTotalLength[0] = sizeof(octusb_confd),
1393 .bConfigurationValue = 1,
1394 .iConfiguration = 0,
1395 .bmAttributes = UC_SELF_POWERED,
1396 .bMaxPower = 0 /* max power */
1399 .bLength = sizeof(struct usb_interface_descriptor),
1400 .bDescriptorType = UDESC_INTERFACE,
1402 .bInterfaceClass = UICLASS_HUB,
1403 .bInterfaceSubClass = UISUBCLASS_HUB,
1404 .bInterfaceProtocol = UIPROTO_FSHUB,
1407 .bLength = sizeof(struct usb_endpoint_descriptor),
1408 .bDescriptorType = UDESC_ENDPOINT,
1409 .bEndpointAddress = UE_DIR_IN | OCTUSB_INTR_ENDPT,
1410 .bmAttributes = UE_INTERRUPT,
1411 .wMaxPacketSize[0] = 8, /* max packet (63 ports) */
1417 struct usb_hub_descriptor_min octusb_hubd =
1419 .bDescLength = sizeof(octusb_hubd),
1420 .bDescriptorType = UDESC_HUB,
1422 .wHubCharacteristics = {UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0},
1423 .bPwrOn2PwrGood = 50,
1424 .bHubContrCurrent = 0,
1425 .DeviceRemovable = {0x00}, /* all ports are removable */
1429 octusb_roothub_exec(struct usb_device *udev,
1430 struct usb_device_request *req, const void **pptr, uint16_t *plength)
1432 struct octusb_softc *sc = OCTUSB_BUS2SC(udev->bus);
1434 const char *str_ptr;
1441 cvmx_usb_port_status_t usb_port_status;
1443 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
1445 /* XXX disable power save mode, hence it is not supported */
1446 udev->power_mode = USB_POWER_MODE_ON;
1449 ptr = (const void *)&sc->sc_hub_desc.temp;
1453 value = UGETW(req->wValue);
1454 index = UGETW(req->wIndex);
1456 DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
1457 "wValue=0x%04x wIndex=0x%04x\n",
1458 req->bmRequestType, req->bRequest,
1459 UGETW(req->wLength), value, index);
1461 #define C(x,y) ((x) | ((y) << 8))
1462 switch (C(req->bRequest, req->bmRequestType)) {
1463 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
1464 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
1465 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
1467 case C(UR_GET_CONFIG, UT_READ_DEVICE):
1469 sc->sc_hub_desc.temp[0] = sc->sc_conf;
1471 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
1472 switch (value >> 8) {
1474 if ((value & 0xff) != 0) {
1475 err = USB_ERR_IOERROR;
1478 len = sizeof(octusb_devd);
1480 ptr = (const void *)&octusb_devd;
1483 case UDESC_DEVICE_QUALIFIER:
1484 if ((value & 0xff) != 0) {
1485 err = USB_ERR_IOERROR;
1488 len = sizeof(octusb_odevd);
1489 ptr = (const void *)&octusb_odevd;
1493 if ((value & 0xff) != 0) {
1494 err = USB_ERR_IOERROR;
1497 len = sizeof(octusb_confd);
1498 ptr = (const void *)&octusb_confd;
1502 switch (value & 0xff) {
1503 case 0: /* Language table */
1507 case 1: /* Vendor */
1508 str_ptr = "Cavium Networks";
1511 case 2: /* Product */
1512 str_ptr = "OCTUSB Root HUB";
1520 len = usb_make_str_desc(sc->sc_hub_desc.temp,
1521 sizeof(sc->sc_hub_desc.temp), str_ptr);
1525 err = USB_ERR_IOERROR;
1529 case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
1531 sc->sc_hub_desc.temp[0] = 0;
1533 case C(UR_GET_STATUS, UT_READ_DEVICE):
1535 USETW(sc->sc_hub_desc.stat.wStatus, UDS_SELF_POWERED);
1537 case C(UR_GET_STATUS, UT_READ_INTERFACE):
1538 case C(UR_GET_STATUS, UT_READ_ENDPOINT):
1540 USETW(sc->sc_hub_desc.stat.wStatus, 0);
1542 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
1543 if (value >= OCTUSB_MAX_DEVICES) {
1544 err = USB_ERR_IOERROR;
1547 sc->sc_addr = value;
1549 case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
1550 if ((value != 0) && (value != 1)) {
1551 err = USB_ERR_IOERROR;
1554 sc->sc_conf = value;
1556 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
1558 case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
1559 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
1560 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
1561 err = USB_ERR_IOERROR;
1563 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
1565 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
1568 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
1570 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
1571 DPRINTFN(4, "UR_CLEAR_PORT_FEATURE "
1572 "port=%d feature=%d\n",
1575 (index > sc->sc_noport) ||
1576 sc->sc_port[index - 1].disabled) {
1577 err = USB_ERR_IOERROR;
1583 case UHF_PORT_ENABLE:
1584 cvmx_usb_disable(&sc->sc_port[index].state);
1586 case UHF_PORT_SUSPEND:
1587 case UHF_PORT_RESET:
1589 case UHF_C_PORT_CONNECTION:
1590 cvmx_usb_set_status(&sc->sc_port[index].state,
1591 cvmx_usb_get_status(&sc->sc_port[index].state));
1593 case UHF_C_PORT_ENABLE:
1594 cvmx_usb_set_status(&sc->sc_port[index].state,
1595 cvmx_usb_get_status(&sc->sc_port[index].state));
1597 case UHF_C_PORT_OVER_CURRENT:
1598 cvmx_usb_set_status(&sc->sc_port[index].state,
1599 cvmx_usb_get_status(&sc->sc_port[index].state));
1601 case UHF_C_PORT_RESET:
1604 case UHF_C_PORT_SUSPEND:
1606 case UHF_PORT_CONNECTION:
1607 case UHF_PORT_OVER_CURRENT:
1608 case UHF_PORT_POWER:
1609 case UHF_PORT_LOW_SPEED:
1611 err = USB_ERR_IOERROR;
1615 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
1616 if ((value & 0xff) != 0) {
1617 err = USB_ERR_IOERROR;
1620 sc->sc_hubd = octusb_hubd;
1621 sc->sc_hubd.bNbrPorts = sc->sc_noport;
1622 len = sizeof(sc->sc_hubd);
1623 ptr = (const void *)&sc->sc_hubd;
1625 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
1627 memset(sc->sc_hub_desc.temp, 0, 16);
1629 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
1631 (index > sc->sc_noport) ||
1632 sc->sc_port[index - 1].disabled) {
1633 err = USB_ERR_IOERROR;
1638 usb_port_status = cvmx_usb_get_status(&sc->sc_port[index].state);
1640 status = change = 0;
1641 if (usb_port_status.connected)
1642 status |= UPS_CURRENT_CONNECT_STATUS;
1643 if (usb_port_status.port_enabled)
1644 status |= UPS_PORT_ENABLED;
1645 if (usb_port_status.port_over_current)
1646 status |= UPS_OVERCURRENT_INDICATOR;
1647 if (usb_port_status.port_powered)
1648 status |= UPS_PORT_POWER;
1650 switch (usb_port_status.port_speed) {
1651 case CVMX_USB_SPEED_HIGH:
1652 status |= UPS_HIGH_SPEED;
1654 case CVMX_USB_SPEED_FULL:
1657 status |= UPS_LOW_SPEED;
1661 if (usb_port_status.connect_change)
1662 change |= UPS_C_CONNECT_STATUS;
1664 change |= UPS_C_PORT_RESET;
1666 USETW(sc->sc_hub_desc.ps.wPortStatus, status);
1667 USETW(sc->sc_hub_desc.ps.wPortChange, change);
1669 len = sizeof(sc->sc_hub_desc.ps);
1671 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
1672 err = USB_ERR_IOERROR;
1674 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
1676 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
1678 (index > sc->sc_noport) ||
1679 sc->sc_port[index - 1].disabled) {
1680 err = USB_ERR_IOERROR;
1686 case UHF_PORT_ENABLE:
1688 case UHF_PORT_RESET:
1689 cvmx_usb_disable(&sc->sc_port[index].state);
1690 if (cvmx_usb_enable(&sc->sc_port[index].state)) {
1691 err = USB_ERR_IOERROR;
1696 case UHF_PORT_POWER:
1697 /* pretend we turned on power */
1699 case UHF_PORT_SUSPEND:
1700 case UHF_C_PORT_CONNECTION:
1701 case UHF_C_PORT_ENABLE:
1702 case UHF_C_PORT_OVER_CURRENT:
1703 case UHF_PORT_CONNECTION:
1704 case UHF_PORT_OVER_CURRENT:
1705 case UHF_PORT_LOW_SPEED:
1706 case UHF_C_PORT_SUSPEND:
1707 case UHF_C_PORT_RESET:
1709 err = USB_ERR_IOERROR;
1714 err = USB_ERR_IOERROR;
1724 octusb_xfer_setup(struct usb_setup_params *parm)
1726 struct usb_page_search page_info;
1727 struct usb_page_cache *pc;
1728 struct octusb_softc *sc;
1729 struct octusb_qh *qh;
1730 struct usb_xfer *xfer;
1731 struct usb_device *hub;
1736 sc = OCTUSB_BUS2SC(parm->udev->bus);
1737 xfer = parm->curr_xfer;
1741 * NOTE: This driver does not use any of the parameters that
1742 * are computed from the following values. Just set some
1743 * reasonable dummies:
1746 parm->hc_max_packet_size = 0x400;
1747 parm->hc_max_packet_count = 3;
1748 parm->hc_max_frame_size = 0xC00;
1750 usbd_transfer_setup_sub(parm);
1755 /* Allocate a queue head */
1757 if (usbd_transfer_setup_sub_malloc(
1758 parm, &pc, sizeof(struct octusb_qh),
1759 USB_HOST_ALIGN, 1)) {
1760 parm->err = USB_ERR_NOMEM;
1764 usbd_get_page(pc, 0, &page_info);
1766 qh = page_info.buffer;
1770 qh->sc = OCTUSB_BUS2SC(xfer->xroot->bus);
1771 qh->max_frame_size = xfer->max_frame_size;
1772 qh->max_packet_size = xfer->max_packet_size;
1773 qh->ep_num = xfer->endpointno;
1774 qh->ep_type = xfer->endpoint->edesc->bmAttributes;
1775 qh->dev_addr = xfer->address;
1776 qh->dev_speed = usbd_get_speed(xfer->xroot->udev);
1777 qh->root_port_index = xfer->xroot->udev->port_index;
1778 /* We need Octeon USB HUB's port index, not the local port */
1779 hub = xfer->xroot->udev->parent_hub;
1780 while(hub && hub->parent_hub) {
1781 qh->root_port_index = hub->port_index;
1782 hub = hub->parent_hub;
1785 switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
1787 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH)
1788 qh->ep_interval = xfer->interval * 8;
1790 qh->ep_interval = xfer->interval * 1;
1792 case UE_ISOCHRONOUS:
1793 qh->ep_interval = 1 << xfer->fps_shift;
1796 qh->ep_interval = 0;
1800 qh->ep_mult = xfer->max_packet_count & 3;
1801 qh->hs_hub_addr = xfer->xroot->udev->hs_hub_addr;
1802 qh->hs_hub_port = xfer->xroot->udev->hs_port_no;
1804 xfer->qh_start[0] = qh;
1806 /* Allocate a fixup buffer */
1808 if (usbd_transfer_setup_sub_malloc(
1809 parm, &pc, OCTUSB_MAX_FIXUP,
1810 OCTUSB_MAX_FIXUP, 1)) {
1811 parm->err = USB_ERR_NOMEM;
1815 usbd_get_page(pc, 0, &page_info);
1817 qh->fixup_phys = page_info.physaddr;
1819 qh->fixup_buf = page_info.buffer;
1821 /* Allocate transfer descriptors */
1825 ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
1827 if (usbd_transfer_setup_sub_malloc(
1828 parm, &pc, sizeof(struct octusb_td),
1829 USB_HOST_ALIGN, ntd)) {
1830 parm->err = USB_ERR_NOMEM;
1834 for (n = 0; n != ntd; n++) {
1835 struct octusb_td *td;
1837 usbd_get_page(pc + n, 0, &page_info);
1839 td = page_info.buffer;
1842 td->obj_next = last_obj;
1847 xfer->td_start[0] = last_obj;
1851 octusb_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
1852 struct usb_endpoint *ep)
1854 struct octusb_softc *sc = OCTUSB_BUS2SC(udev->bus);
1856 DPRINTFN(2, "endpoint=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
1857 ep, udev->address, edesc->bEndpointAddress,
1858 udev->flags.usb_mode, sc->sc_addr);
1860 if (udev->device_index != sc->sc_addr) {
1861 switch (edesc->bmAttributes & UE_XFERTYPE) {
1863 ep->methods = &octusb_device_ctrl_methods;
1866 ep->methods = &octusb_device_intr_methods;
1868 case UE_ISOCHRONOUS:
1869 if (udev->speed != USB_SPEED_LOW)
1870 ep->methods = &octusb_device_isoc_methods;
1873 ep->methods = &octusb_device_bulk_methods;
1883 octusb_xfer_unsetup(struct usb_xfer *xfer)
1885 DPRINTF("Nothing to do.\n");
1889 octusb_get_dma_delay(struct usb_device *udev, uint32_t *pus)
1891 /* DMA delay - wait until any use of memory is finished */
1892 *pus = (2125); /* microseconds */
1896 octusb_device_resume(struct usb_device *udev)
1898 DPRINTF("Nothing to do.\n");
1902 octusb_device_suspend(struct usb_device *udev)
1904 DPRINTF("Nothing to do.\n");
1908 octusb_set_hw_power(struct usb_bus *bus)
1910 DPRINTF("Nothing to do.\n");
1914 octusb_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
1916 struct octusb_softc *sc = OCTUSB_BUS2SC(bus);
1919 case USB_HW_POWER_SUSPEND:
1922 case USB_HW_POWER_SHUTDOWN:
1925 case USB_HW_POWER_RESUME:
1933 struct usb_bus_methods octusb_bus_methods = {
1934 .endpoint_init = octusb_ep_init,
1935 .xfer_setup = octusb_xfer_setup,
1936 .xfer_unsetup = octusb_xfer_unsetup,
1937 .get_dma_delay = octusb_get_dma_delay,
1938 .device_resume = octusb_device_resume,
1939 .device_suspend = octusb_device_suspend,
1940 .set_hw_power = octusb_set_hw_power,
1941 .set_hw_power_sleep = octusb_set_hw_power_sleep,
1942 .roothub_exec = octusb_roothub_exec,
1943 .xfer_poll = octusb_do_poll,