1 #include <sys/cdefs.h>
2 __FBSDID("$FreeBSD$");
3
4 /*-
5 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
6 *
7 * Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 /*
32 * This file contains the driver for Octeon Executive Library USB
33 * Controller driver API.
34 */
35
36 /* TODO: The root HUB port callback is not yet implemented. */
37
38 #include <sys/stdint.h>
39 #include <sys/stddef.h>
40 #include <sys/param.h>
41 #include <sys/queue.h>
42 #include <sys/types.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/bus.h>
46 #include <sys/module.h>
47 #include <sys/lock.h>
48 #include <sys/mutex.h>
49 #include <sys/condvar.h>
50 #include <sys/sysctl.h>
51 #include <sys/sx.h>
52 #include <sys/unistd.h>
53 #include <sys/callout.h>
54 #include <sys/malloc.h>
55 #include <sys/priv.h>
56
57 #include <dev/usb/usb.h>
58 #include <dev/usb/usbdi.h>
59
60 #define USB_DEBUG_VAR octusbdebug
61
62 #include <dev/usb/usb_core.h>
63 #include <dev/usb/usb_debug.h>
64 #include <dev/usb/usb_busdma.h>
65 #include <dev/usb/usb_process.h>
66 #include <dev/usb/usb_transfer.h>
67 #include <dev/usb/usb_device.h>
68 #include <dev/usb/usb_hub.h>
69 #include <dev/usb/usb_util.h>
70
71 #include <dev/usb/usb_controller.h>
72 #include <dev/usb/usb_bus.h>
73
74 #include <contrib/octeon-sdk/cvmx.h>
75 #include <contrib/octeon-sdk/cvmx-usb.h>
76
77 #include <mips/cavium/usb/octusb.h>
78
79 #define OCTUSB_BUS2SC(bus) \
80 ((struct octusb_softc *)(((uint8_t *)(bus)) - \
81 ((uint8_t *)&(((struct octusb_softc *)0)->sc_bus))))
82
83 #ifdef USB_DEBUG
84 static int octusbdebug = 0;
85
86 static SYSCTL_NODE(_hw_usb, OID_AUTO, octusb, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
87 "OCTUSB");
88 SYSCTL_INT(_hw_usb_octusb, OID_AUTO, debug, CTLFLAG_RWTUN,
89 &octusbdebug, 0, "OCTUSB debug level");
90 #endif
91
92 struct octusb_std_temp {
93 octusb_cmd_t *func;
94 struct octusb_td *td;
95 struct octusb_td *td_next;
96 struct usb_page_cache *pc;
97 uint32_t offset;
98 uint32_t len;
99 uint8_t short_pkt;
100 uint8_t setup_alt_next;
101 };
102
103 extern struct usb_bus_methods octusb_bus_methods;
104 extern struct usb_pipe_methods octusb_device_bulk_methods;
105 extern struct usb_pipe_methods octusb_device_ctrl_methods;
106 extern struct usb_pipe_methods octusb_device_intr_methods;
107 extern struct usb_pipe_methods octusb_device_isoc_methods;
108
109 static void octusb_standard_done(struct usb_xfer *);
110 static void octusb_device_done(struct usb_xfer *, usb_error_t);
111 static void octusb_timeout(void *);
112 static void octusb_do_poll(struct usb_bus *);
113
114 static cvmx_usb_speed_t
115 octusb_convert_speed(enum usb_dev_speed speed)
116 {
117 ; /* indent fix */
118 switch (speed) {
119 case USB_SPEED_HIGH:
120 return (CVMX_USB_SPEED_HIGH);
121 case USB_SPEED_FULL:
122 return (CVMX_USB_SPEED_FULL);
123 default:
124 return (CVMX_USB_SPEED_LOW);
125 }
126 }
127
128 static cvmx_usb_transfer_t
129 octusb_convert_ep_type(uint8_t ep_type)
130 {
131 ; /* indent fix */
132 switch (ep_type & UE_XFERTYPE) {
133 case UE_CONTROL:
134 return (CVMX_USB_TRANSFER_CONTROL);
135 case UE_INTERRUPT:
136 return (CVMX_USB_TRANSFER_INTERRUPT);
137 case UE_ISOCHRONOUS:
138 return (CVMX_USB_TRANSFER_ISOCHRONOUS);
139 case UE_BULK:
140 return (CVMX_USB_TRANSFER_BULK);
141 default:
142 return (0); /* should not happen */
143 }
144 }
145
146 static uint8_t
147 octusb_host_alloc_endpoint(struct octusb_td *td)
148 {
149 struct octusb_softc *sc;
150 int ep_handle;
151
152 if (td->qh->fixup_pending)
153 return (1); /* busy */
154
155 if (td->qh->ep_allocated)
156 return (0); /* success */
157
158 /* get softc */
159 sc = td->qh->sc;
160
161 ep_handle = cvmx_usb_open_pipe(
162 &sc->sc_port[td->qh->root_port_index].state,
163 0,
164 td->qh->dev_addr,
165 td->qh->ep_num & UE_ADDR,
166 octusb_convert_speed(td->qh->dev_speed),
167 td->qh->max_packet_size,
168 octusb_convert_ep_type(td->qh->ep_type),
169 (td->qh->ep_num & UE_DIR_IN) ? CVMX_USB_DIRECTION_IN :
170 CVMX_USB_DIRECTION_OUT,
171 td->qh->ep_interval,
172 (td->qh->dev_speed == USB_SPEED_HIGH) ? td->qh->ep_mult : 0,
173 td->qh->hs_hub_addr,
174 td->qh->hs_hub_port);
175
176 if (ep_handle < 0) {
177 DPRINTFN(1, "cvmx_usb_open_pipe failed: %d\n", ep_handle);
178 return (1); /* busy */
179 }
180
181 cvmx_usb_set_toggle(
182 &sc->sc_port[td->qh->root_port_index].state,
183 ep_handle, td->qh->ep_toggle_next);
184
185 td->qh->fixup_handle = -1;
186 td->qh->fixup_complete = 0;
187 td->qh->fixup_len = 0;
188 td->qh->fixup_off = 0;
189 td->qh->fixup_pending = 0;
190 td->qh->fixup_actlen = 0;
191
192 td->qh->ep_handle = ep_handle;
193 td->qh->ep_allocated = 1;
194
195 return (0); /* success */
196 }
197
198 static void
199 octusb_host_free_endpoint(struct octusb_td *td)
200 {
201 struct octusb_softc *sc;
202
203 if (td->qh->ep_allocated == 0)
204 return;
205
206 /* get softc */
207 sc = td->qh->sc;
208
209 if (td->qh->fixup_handle >= 0) {
210 /* cancel, if any */
211 cvmx_usb_cancel(&sc->sc_port[td->qh->root_port_index].state,
212 td->qh->ep_handle, td->qh->fixup_handle);
213 }
214 cvmx_usb_close_pipe(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle);
215
216 td->qh->ep_allocated = 0;
217 }
218
219 static void
220 octusb_complete_cb(cvmx_usb_state_t *state,
221 cvmx_usb_callback_t reason,
222 cvmx_usb_complete_t status,
223 int pipe_handle, int submit_handle,
224 int bytes_transferred, void *user_data)
225 {
226 struct octusb_td *td;
227
228 if (reason != CVMX_USB_CALLBACK_TRANSFER_COMPLETE)
229 return;
230
231 td = user_data;
232
233 td->qh->fixup_complete = 1;
234 td->qh->fixup_pending = 0;
235 td->qh->fixup_actlen = bytes_transferred;
236 td->qh->fixup_handle = -1;
237
238 switch (status) {
239 case CVMX_USB_COMPLETE_SUCCESS:
240 case CVMX_USB_COMPLETE_SHORT:
241 td->error_any = 0;
242 td->error_stall = 0;
243 break;
244 case CVMX_USB_COMPLETE_STALL:
245 td->error_stall = 1;
246 td->error_any = 1;
247 break;
248 default:
249 td->error_any = 1;
250 break;
251 }
252 }
253
254 static uint8_t
255 octusb_host_control_header_tx(struct octusb_td *td)
256 {
257 int status;
258
259 /* allocate endpoint and check pending */
260 if (octusb_host_alloc_endpoint(td))
261 return (1); /* busy */
262
263 /* check error */
264 if (td->error_any)
265 return (0); /* done */
266
267 if (td->qh->fixup_complete != 0) {
268 /* clear complete flag */
269 td->qh->fixup_complete = 0;
270
271 /* flush data */
272 usb_pc_cpu_invalidate(td->qh->fixup_pc);
273 return (0); /* done */
274 }
275 /* verify length */
276 if (td->remainder != 8) {
277 td->error_any = 1;
278 return (0); /* done */
279 }
280 usbd_copy_out(td->pc, td->offset, td->qh->fixup_buf, 8);
281
282 /* update offset and remainder */
283 td->offset += 8;
284 td->remainder -= 8;
285
286 /* setup data length and offset */
287 td->qh->fixup_len = UGETW(td->qh->fixup_buf + 6);
288 td->qh->fixup_off = 0;
289
290 if (td->qh->fixup_len > (OCTUSB_MAX_FIXUP - 8)) {
291 td->error_any = 1;
292 return (0); /* done */
293 }
294 /* do control IN request */
295 if (td->qh->fixup_buf[0] & UE_DIR_IN) {
296 struct octusb_softc *sc;
297
298 /* get softc */
299 sc = td->qh->sc;
300
301 /* flush data */
302 usb_pc_cpu_flush(td->qh->fixup_pc);
303
304 status = cvmx_usb_submit_control(
305 &sc->sc_port[td->qh->root_port_index].state,
306 td->qh->ep_handle, td->qh->fixup_phys,
307 td->qh->fixup_phys + 8, td->qh->fixup_len,
308 &octusb_complete_cb, td);
309 /* check status */
310 if (status < 0) {
311 td->error_any = 1;
312 return (0); /* done */
313 }
314 td->qh->fixup_handle = status;
315 td->qh->fixup_pending = 1;
316 td->qh->fixup_complete = 0;
317
318 return (1); /* busy */
319 }
320 return (0); /* done */
321 }
322
323 static uint8_t
324 octusb_host_control_data_tx(struct octusb_td *td)
325 {
326 uint32_t rem;
327
328 /* allocate endpoint and check pending */
329 if (octusb_host_alloc_endpoint(td))
330 return (1); /* busy */
331
332 /* check error */
333 if (td->error_any)
334 return (0); /* done */
335
336 rem = td->qh->fixup_len - td->qh->fixup_off;
337
338 if (td->remainder > rem) {
339 td->error_any = 1;
340 DPRINTFN(1, "Excess setup transmit data\n");
341 return (0); /* done */
342 }
343 usbd_copy_out(td->pc, td->offset, td->qh->fixup_buf +
344 td->qh->fixup_off + 8, td->remainder);
345
346 td->offset += td->remainder;
347 td->qh->fixup_off += td->remainder;
348 td->remainder = 0;
349
350 return (0); /* done */
351 }
352
353 static uint8_t
354 octusb_host_control_data_rx(struct octusb_td *td)
355 {
356 uint32_t rem;
357
358 /* allocate endpoint and check pending */
359 if (octusb_host_alloc_endpoint(td))
360 return (1); /* busy */
361
362 /* check error */
363 if (td->error_any)
364 return (0); /* done */
365
366 /* copy data from buffer */
367 rem = td->qh->fixup_actlen - td->qh->fixup_off;
368
369 if (rem > td->remainder)
370 rem = td->remainder;
371
372 usbd_copy_in(td->pc, td->offset, td->qh->fixup_buf +
373 td->qh->fixup_off + 8, rem);
374
375 td->offset += rem;
376 td->remainder -= rem;
377 td->qh->fixup_off += rem;
378
379 return (0); /* done */
380 }
381
382 static uint8_t
383 octusb_host_control_status_tx(struct octusb_td *td)
384 {
385 int status;
386
387 /* allocate endpoint and check pending */
388 if (octusb_host_alloc_endpoint(td))
389 return (1); /* busy */
390
391 /* check error */
392 if (td->error_any)
393 return (0); /* done */
394
395 if (td->qh->fixup_complete != 0) {
396 /* clear complete flag */
397 td->qh->fixup_complete = 0;
398 /* done */
399 return (0);
400 }
401 /* do control IN request */
402 if (!(td->qh->fixup_buf[0] & UE_DIR_IN)) {
403 struct octusb_softc *sc;
404
405 /* get softc */
406 sc = td->qh->sc;
407
408 /* flush data */
409 usb_pc_cpu_flush(td->qh->fixup_pc);
410
411 /* start USB transfer */
412 status = cvmx_usb_submit_control(
413 &sc->sc_port[td->qh->root_port_index].state,
414 td->qh->ep_handle, td->qh->fixup_phys,
415 td->qh->fixup_phys + 8, td->qh->fixup_len,
416 &octusb_complete_cb, td);
417
418 /* check status */
419 if (status < 0) {
420 td->error_any = 1;
421 return (0); /* done */
422 }
423 td->qh->fixup_handle = status;
424 td->qh->fixup_pending = 1;
425 td->qh->fixup_complete = 0;
426
427 return (1); /* busy */
428 }
429 return (0); /* done */
430 }
431
432 static uint8_t
433 octusb_non_control_data_tx(struct octusb_td *td)
434 {
435 struct octusb_softc *sc;
436 uint32_t rem;
437 int status;
438
439 /* allocate endpoint and check pending */
440 if (octusb_host_alloc_endpoint(td))
441 return (1); /* busy */
442
443 /* check error */
444 if (td->error_any)
445 return (0); /* done */
446
447 if ((td->qh->fixup_complete != 0) &&
448 ((td->qh->ep_type & UE_XFERTYPE) == UE_ISOCHRONOUS)) {
449 td->qh->fixup_complete = 0;
450 return (0); /* done */
451 }
452 /* check complete */
453 if (td->remainder == 0) {
454 if (td->short_pkt)
455 return (0); /* complete */
456 /* else need to send a zero length packet */
457 rem = 0;
458 td->short_pkt = 1;
459 } else {
460 /* get maximum length */
461 rem = OCTUSB_MAX_FIXUP % td->qh->max_frame_size;
462 rem = OCTUSB_MAX_FIXUP - rem;
463
464 if (rem == 0) {
465 /* should not happen */
466 DPRINTFN(1, "Fixup buffer is too small\n");
467 td->error_any = 1;
468 return (0); /* done */
469 }
470 /* get minimum length */
471 if (rem > td->remainder) {
472 rem = td->remainder;
473 if ((rem == 0) || (rem % td->qh->max_frame_size))
474 td->short_pkt = 1;
475 }
476 /* copy data into fixup buffer */
477 usbd_copy_out(td->pc, td->offset, td->qh->fixup_buf, rem);
478
479 /* flush data */
480 usb_pc_cpu_flush(td->qh->fixup_pc);
481
482 /* pre-increment TX buffer offset */
483 td->offset += rem;
484 td->remainder -= rem;
485 }
486
487 /* get softc */
488 sc = td->qh->sc;
489
490 switch (td->qh->ep_type & UE_XFERTYPE) {
491 case UE_ISOCHRONOUS:
492 td->qh->iso_pkt.offset = 0;
493 td->qh->iso_pkt.length = rem;
494 td->qh->iso_pkt.status = 0;
495 /* start USB transfer */
496 status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->root_port_index].state,
497 td->qh->ep_handle, 1, CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT |
498 CVMX_USB_ISOCHRONOUS_FLAGS_ASAP, 1, &td->qh->iso_pkt,
499 td->qh->fixup_phys, rem, &octusb_complete_cb, td);
500 break;
501 case UE_BULK:
502 /* start USB transfer */
503 status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->root_port_index].state,
504 td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td);
505 break;
506 case UE_INTERRUPT:
507 /* start USB transfer (interrupt or interrupt) */
508 status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->root_port_index].state,
509 td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td);
510 break;
511 default:
512 status = -1;
513 break;
514 }
515
516 /* check status */
517 if (status < 0) {
518 td->error_any = 1;
519 return (0); /* done */
520 }
521 td->qh->fixup_handle = status;
522 td->qh->fixup_len = rem;
523 td->qh->fixup_pending = 1;
524 td->qh->fixup_complete = 0;
525
526 return (1); /* busy */
527 }
528
529 static uint8_t
530 octusb_non_control_data_rx(struct octusb_td *td)
531 {
532 struct octusb_softc *sc;
533 uint32_t rem;
534 int status;
535 uint8_t got_short;
536
537 /* allocate endpoint and check pending */
538 if (octusb_host_alloc_endpoint(td))
539 return (1); /* busy */
540
541 /* check error */
542 if (td->error_any)
543 return (0); /* done */
544
545 got_short = 0;
546
547 if (td->qh->fixup_complete != 0) {
548 /* invalidate data */
549 usb_pc_cpu_invalidate(td->qh->fixup_pc);
550
551 rem = td->qh->fixup_actlen;
552
553 /* verify transfer length */
554 if (rem != td->qh->fixup_len) {
555 if (rem < td->qh->fixup_len) {
556 /* we have a short packet */
557 td->short_pkt = 1;
558 got_short = 1;
559 } else {
560 /* invalid USB packet */
561 td->error_any = 1;
562 return (0); /* we are complete */
563 }
564 }
565 /* copy data into fixup buffer */
566 usbd_copy_in(td->pc, td->offset, td->qh->fixup_buf, rem);
567
568 /* post-increment RX buffer offset */
569 td->offset += rem;
570 td->remainder -= rem;
571
572 td->qh->fixup_complete = 0;
573
574 if ((td->qh->ep_type & UE_XFERTYPE) == UE_ISOCHRONOUS)
575 return (0); /* done */
576 }
577 /* check if we are complete */
578 if ((td->remainder == 0) || got_short) {
579 if (td->short_pkt) {
580 /* we are complete */
581 return (0);
582 }
583 /* else need to receive a zero length packet */
584 rem = 0;
585 td->short_pkt = 1;
586 } else {
587 /* get maximum length */
588 rem = OCTUSB_MAX_FIXUP % td->qh->max_frame_size;
589 rem = OCTUSB_MAX_FIXUP - rem;
590
591 if (rem == 0) {
592 /* should not happen */
593 DPRINTFN(1, "Fixup buffer is too small\n");
594 td->error_any = 1;
595 return (0); /* done */
596 }
597 /* get minimum length */
598 if (rem > td->remainder)
599 rem = td->remainder;
600 }
601
602 /* invalidate data */
603 usb_pc_cpu_invalidate(td->qh->fixup_pc);
604
605 /* get softc */
606 sc = td->qh->sc;
607
608 switch (td->qh->ep_type & UE_XFERTYPE) {
609 case UE_ISOCHRONOUS:
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);
618 break;
619 case UE_BULK:
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);
623 break;
624 case UE_INTERRUPT:
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);
628 break;
629 default:
630 status = -1;
631 break;
632 }
633
634 /* check status */
635 if (status < 0) {
636 td->error_any = 1;
637 return (0); /* done */
638 }
639 td->qh->fixup_handle = status;
640 td->qh->fixup_len = rem;
641 td->qh->fixup_pending = 1;
642 td->qh->fixup_complete = 0;
643
644 return (1); /* busy */
645 }
646
647 static uint8_t
648 octusb_xfer_do_fifo(struct usb_xfer *xfer)
649 {
650 struct octusb_td *td;
651
652 DPRINTFN(8, "\n");
653
654 td = xfer->td_transfer_cache;
655
656 while (1) {
657 if ((td->func) (td)) {
658 /* operation in progress */
659 break;
660 }
661 if (((void *)td) == xfer->td_transfer_last) {
662 goto done;
663 }
664 if (td->error_any) {
665 goto done;
666 } else if (td->remainder > 0) {
667 /*
668 * We had a short transfer. If there is no
669 * alternate next, stop processing !
670 */
671 if (td->alt_next == 0)
672 goto done;
673 }
674 /*
675 * Fetch the next transfer descriptor and transfer
676 * some flags to the next transfer descriptor
677 */
678 td = td->obj_next;
679 xfer->td_transfer_cache = td;
680 }
681 return (1); /* not complete */
682
683 done:
684 /* compute all actual lengths */
685
686 octusb_standard_done(xfer);
687
688 return (0); /* complete */
689 }
690
691 static usb_error_t
692 octusb_standard_done_sub(struct usb_xfer *xfer)
693 {
694 struct octusb_td *td;
695 uint32_t len;
696 usb_error_t error;
697
698 DPRINTFN(8, "\n");
699
700 td = xfer->td_transfer_cache;
701
702 do {
703 len = td->remainder;
704
705 if (xfer->aframes != xfer->nframes) {
706 /*
707 * Verify the length and subtract
708 * the remainder from "frlengths[]":
709 */
710 if (len > xfer->frlengths[xfer->aframes]) {
711 td->error_any = 1;
712 } else {
713 xfer->frlengths[xfer->aframes] -= len;
714 }
715 }
716 /* Check for transfer error */
717 if (td->error_any) {
718 /* the transfer is finished */
719 error = td->error_stall ? USB_ERR_STALLED : USB_ERR_IOERROR;
720 td = NULL;
721 break;
722 }
723 /* Check for short transfer */
724 if (len > 0) {
725 if (xfer->flags_int.short_frames_ok) {
726 /* follow alt next */
727 if (td->alt_next) {
728 td = td->obj_next;
729 } else {
730 td = NULL;
731 }
732 } else {
733 /* the transfer is finished */
734 td = NULL;
735 }
736 error = 0;
737 break;
738 }
739 td = td->obj_next;
740
741 /* this USB frame is complete */
742 error = 0;
743 break;
744
745 } while (0);
746
747 /* update transfer cache */
748
749 xfer->td_transfer_cache = td;
750
751 return (error);
752 }
753
754 static void
755 octusb_standard_done(struct usb_xfer *xfer)
756 {
757 struct octusb_softc *sc;
758 struct octusb_qh *qh;
759 usb_error_t error = 0;
760
761 DPRINTFN(12, "xfer=%p endpoint=%p transfer done\n",
762 xfer, xfer->endpoint);
763
764 /* reset scanner */
765
766 xfer->td_transfer_cache = xfer->td_transfer_first;
767
768 if (xfer->flags_int.control_xfr) {
769 if (xfer->flags_int.control_hdr)
770 error = octusb_standard_done_sub(xfer);
771
772 xfer->aframes = 1;
773
774 if (xfer->td_transfer_cache == NULL)
775 goto done;
776 }
777 while (xfer->aframes != xfer->nframes) {
778 error = octusb_standard_done_sub(xfer);
779
780 xfer->aframes++;
781
782 if (xfer->td_transfer_cache == NULL)
783 goto done;
784 }
785
786 if (xfer->flags_int.control_xfr &&
787 !xfer->flags_int.control_act)
788 error = octusb_standard_done_sub(xfer);
789
790 done:
791 /* update data toggle */
792
793 qh = xfer->qh_start[0];
794 sc = qh->sc;
795
796 xfer->endpoint->toggle_next =
797 cvmx_usb_get_toggle(
798 &sc->sc_port[qh->root_port_index].state,
799 qh->ep_handle) ? 1 : 0;
800
801 octusb_device_done(xfer, error);
802 }
803
804 static void
805 octusb_interrupt_poll(struct octusb_softc *sc)
806 {
807 struct usb_xfer *xfer;
808 uint8_t x;
809
810 /* poll all ports */
811 for (x = 0; x != sc->sc_noport; x++)
812 cvmx_usb_poll(&sc->sc_port[x].state);
813
814 repeat:
815 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
816 if (!octusb_xfer_do_fifo(xfer)) {
817 /* queue has been modified */
818 goto repeat;
819 }
820 }
821 }
822
823 static void
824 octusb_start_standard_chain(struct usb_xfer *xfer)
825 {
826 DPRINTFN(8, "\n");
827
828 /* poll one time */
829 if (octusb_xfer_do_fifo(xfer)) {
830 /* put transfer on interrupt queue */
831 usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
832
833 /* start timeout, if any */
834 if (xfer->timeout != 0) {
835 usbd_transfer_timeout_ms(xfer,
836 &octusb_timeout, xfer->timeout);
837 }
838 }
839 }
840
841 void
842 octusb_iterate_hw_softc(struct usb_bus *bus, usb_bus_mem_sub_cb_t *cb)
843 {
844
845 }
846
847 usb_error_t
848 octusb_init(struct octusb_softc *sc)
849 {
850 cvmx_usb_initialize_flags_t flags;
851 int status;
852 uint8_t x;
853
854 /* flush all cache into memory */
855
856 usb_bus_mem_flush_all(&sc->sc_bus, &octusb_iterate_hw_softc);
857
858 /* set up the bus struct */
859 sc->sc_bus.methods = &octusb_bus_methods;
860
861 /* get number of ports */
862 sc->sc_noport = cvmx_usb_get_num_ports();
863
864 /* check number of ports */
865 if (sc->sc_noport > OCTUSB_MAX_PORTS)
866 sc->sc_noport = OCTUSB_MAX_PORTS;
867
868 /* set USB revision */
869 sc->sc_bus.usbrev = USB_REV_2_0;
870
871 /* flags for port initialization */
872 flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO;
873 #ifdef USB_DEBUG
874 if (octusbdebug > 100)
875 flags |= CVMX_USB_INITIALIZE_FLAGS_DEBUG_ALL;
876 #endif
877
878 USB_BUS_LOCK(&sc->sc_bus);
879
880 /* setup all ports */
881 for (x = 0; x != sc->sc_noport; x++) {
882 status = cvmx_usb_initialize(&sc->sc_port[x].state, x, flags);
883 if (status < 0)
884 sc->sc_port[x].disabled = 1;
885 }
886
887 USB_BUS_UNLOCK(&sc->sc_bus);
888
889 /* catch lost interrupts */
890 octusb_do_poll(&sc->sc_bus);
891
892 return (0);
893 }
894
895 usb_error_t
896 octusb_uninit(struct octusb_softc *sc)
897 {
898 uint8_t x;
899
900 USB_BUS_LOCK(&sc->sc_bus);
901
902 for (x = 0; x != sc->sc_noport; x++) {
903 if (sc->sc_port[x].disabled == 0)
904 cvmx_usb_shutdown(&sc->sc_port[x].state);
905 }
906 USB_BUS_UNLOCK(&sc->sc_bus);
907
908 return (0);
909
910 }
911
912 static void
913 octusb_suspend(struct octusb_softc *sc)
914 {
915 /* TODO */
916 }
917
918 static void
919 octusb_resume(struct octusb_softc *sc)
920 {
921 /* TODO */
922 }
923
924 /*------------------------------------------------------------------------*
925 * octusb_interrupt - OCTUSB interrupt handler
926 *------------------------------------------------------------------------*/
927 void
928 octusb_interrupt(struct octusb_softc *sc)
929 {
930 USB_BUS_LOCK(&sc->sc_bus);
931
932 DPRINTFN(16, "real interrupt\n");
933
934 /* poll all the USB transfers */
935 octusb_interrupt_poll(sc);
936
937 USB_BUS_UNLOCK(&sc->sc_bus);
938 }
939
940 /*------------------------------------------------------------------------*
941 * octusb_timeout - OCTUSB transfer timeout handler
942 *------------------------------------------------------------------------*/
943 static void
944 octusb_timeout(void *arg)
945 {
946 struct usb_xfer *xfer = arg;
947
948 DPRINTF("xfer=%p\n", xfer);
949
950 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
951
952 /* transfer is transferred */
953 octusb_device_done(xfer, USB_ERR_TIMEOUT);
954 }
955
956 /*------------------------------------------------------------------------*
957 * octusb_do_poll - OCTUSB poll transfers
958 *------------------------------------------------------------------------*/
959 static void
960 octusb_do_poll(struct usb_bus *bus)
961 {
962 struct octusb_softc *sc = OCTUSB_BUS2SC(bus);
963
964 USB_BUS_LOCK(&sc->sc_bus);
965 octusb_interrupt_poll(sc);
966 USB_BUS_UNLOCK(&sc->sc_bus);
967 }
968
969 static void
970 octusb_setup_standard_chain_sub(struct octusb_std_temp *temp)
971 {
972 struct octusb_td *td;
973
974 /* get current Transfer Descriptor */
975 td = temp->td_next;
976 temp->td = td;
977
978 /* prepare for next TD */
979 temp->td_next = td->obj_next;
980
981 /* fill out the Transfer Descriptor */
982 td->func = temp->func;
983 td->pc = temp->pc;
984 td->offset = temp->offset;
985 td->remainder = temp->len;
986 td->error_any = 0;
987 td->error_stall = 0;
988 td->short_pkt = temp->short_pkt;
989 td->alt_next = temp->setup_alt_next;
990 }
991
992 static void
993 octusb_setup_standard_chain(struct usb_xfer *xfer)
994 {
995 struct octusb_std_temp temp;
996 struct octusb_td *td;
997 uint32_t x;
998
999 DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
1000 xfer->address, UE_GET_ADDR(xfer->endpointno),
1001 xfer->sumlen, usbd_get_speed(xfer->xroot->udev));
1002
1003 /* setup starting point */
1004 td = xfer->td_start[0];
1005 xfer->td_transfer_first = td;
1006 xfer->td_transfer_cache = td;
1007
1008 temp.td = NULL;
1009 temp.td_next = td;
1010 temp.setup_alt_next = xfer->flags_int.short_frames_ok;
1011 temp.offset = 0;
1012
1013 /* check if we should prepend a setup message */
1014
1015 if (xfer->flags_int.control_xfr) {
1016 if (xfer->flags_int.control_hdr) {
1017 temp.func = &octusb_host_control_header_tx;
1018 temp.len = xfer->frlengths[0];
1019 temp.pc = xfer->frbuffers + 0;
1020 temp.short_pkt = temp.len ? 1 : 0;
1021
1022 /* check for last frame */
1023 if (xfer->nframes == 1) {
1024 /*
1025 * no STATUS stage yet, SETUP is
1026 * last
1027 */
1028 if (xfer->flags_int.control_act)
1029 temp.setup_alt_next = 0;
1030 }
1031 octusb_setup_standard_chain_sub(&temp);
1032 }
1033 x = 1;
1034 } else {
1035 x = 0;
1036 }
1037
1038 if (x != xfer->nframes) {
1039 if (xfer->endpointno & UE_DIR_IN) {
1040 if (xfer->flags_int.control_xfr)
1041 temp.func = &octusb_host_control_data_rx;
1042 else
1043 temp.func = &octusb_non_control_data_rx;
1044 } else {
1045 if (xfer->flags_int.control_xfr)
1046 temp.func = &octusb_host_control_data_tx;
1047 else
1048 temp.func = &octusb_non_control_data_tx;
1049 }
1050
1051 /* setup "pc" pointer */
1052 temp.pc = xfer->frbuffers + x;
1053 }
1054 while (x != xfer->nframes) {
1055 /* DATA0 or DATA1 message */
1056
1057 temp.len = xfer->frlengths[x];
1058
1059 x++;
1060
1061 if (x == xfer->nframes) {
1062 if (xfer->flags_int.control_xfr) {
1063 /* no STATUS stage yet, DATA is last */
1064 if (xfer->flags_int.control_act)
1065 temp.setup_alt_next = 0;
1066 } else {
1067 temp.setup_alt_next = 0;
1068 }
1069 }
1070 if (temp.len == 0) {
1071 /* make sure that we send an USB packet */
1072
1073 temp.short_pkt = 0;
1074
1075 } else {
1076 /* regular data transfer */
1077
1078 temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
1079 }
1080
1081 octusb_setup_standard_chain_sub(&temp);
1082
1083 if (xfer->flags_int.isochronous_xfr) {
1084 /* get next data offset */
1085 temp.offset += temp.len;
1086 } else {
1087 /* get next Page Cache pointer */
1088 temp.pc = xfer->frbuffers + x;
1089 }
1090 }
1091
1092 /* check if we should append a status stage */
1093
1094 if (xfer->flags_int.control_xfr &&
1095 !xfer->flags_int.control_act) {
1096 temp.func = &octusb_host_control_status_tx;
1097 temp.len = 0;
1098 temp.pc = NULL;
1099 temp.short_pkt = 0;
1100 temp.setup_alt_next = 0;
1101
1102 octusb_setup_standard_chain_sub(&temp);
1103 }
1104 /* must have at least one frame! */
1105 td = temp.td;
1106 xfer->td_transfer_last = td;
1107
1108 /* properly setup QH */
1109
1110 td->qh->ep_allocated = 0;
1111 td->qh->ep_toggle_next = xfer->endpoint->toggle_next ? 1 : 0;
1112 }
1113
1114 /*------------------------------------------------------------------------*
1115 * octusb_device_done - OCTUSB transfers done code
1116 *
1117 * NOTE: This function can be called more than one time in a row.
1118 *------------------------------------------------------------------------*/
1119 static void
1120 octusb_device_done(struct usb_xfer *xfer, usb_error_t error)
1121 {
1122 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1123
1124 DPRINTFN(2, "xfer=%p, endpoint=%p, error=%d\n",
1125 xfer, xfer->endpoint, error);
1126
1127 /*
1128 * 1) Free any endpoints.
1129 * 2) Control transfers can be split and we should not re-open
1130 * the data pipe between transactions unless there is an error.
1131 */
1132 if ((xfer->flags_int.control_act == 0) || (error != 0)) {
1133 struct octusb_td *td;
1134
1135 td = xfer->td_start[0];
1136
1137 octusb_host_free_endpoint(td);
1138 }
1139 /* dequeue transfer and start next transfer */
1140 usbd_transfer_done(xfer, error);
1141 }
1142
1143 /*------------------------------------------------------------------------*
1144 * octusb bulk support
1145 *------------------------------------------------------------------------*/
1146 static void
1147 octusb_device_bulk_open(struct usb_xfer *xfer)
1148 {
1149 return;
1150 }
1151
1152 static void
1153 octusb_device_bulk_close(struct usb_xfer *xfer)
1154 {
1155 octusb_device_done(xfer, USB_ERR_CANCELLED);
1156 }
1157
1158 static void
1159 octusb_device_bulk_enter(struct usb_xfer *xfer)
1160 {
1161 return;
1162 }
1163
1164 static void
1165 octusb_device_bulk_start(struct usb_xfer *xfer)
1166 {
1167 /* setup TDs */
1168 octusb_setup_standard_chain(xfer);
1169 octusb_start_standard_chain(xfer);
1170 }
1171
1172 struct usb_pipe_methods octusb_device_bulk_methods =
1173 {
1174 .open = octusb_device_bulk_open,
1175 .close = octusb_device_bulk_close,
1176 .enter = octusb_device_bulk_enter,
1177 .start = octusb_device_bulk_start,
1178 };
1179
1180 /*------------------------------------------------------------------------*
1181 * octusb control support
1182 *------------------------------------------------------------------------*/
1183 static void
1184 octusb_device_ctrl_open(struct usb_xfer *xfer)
1185 {
1186 return;
1187 }
1188
1189 static void
1190 octusb_device_ctrl_close(struct usb_xfer *xfer)
1191 {
1192 octusb_device_done(xfer, USB_ERR_CANCELLED);
1193 }
1194
1195 static void
1196 octusb_device_ctrl_enter(struct usb_xfer *xfer)
1197 {
1198 return;
1199 }
1200
1201 static void
1202 octusb_device_ctrl_start(struct usb_xfer *xfer)
1203 {
1204 /* setup TDs */
1205 octusb_setup_standard_chain(xfer);
1206 octusb_start_standard_chain(xfer);
1207 }
1208
1209 struct usb_pipe_methods octusb_device_ctrl_methods =
1210 {
1211 .open = octusb_device_ctrl_open,
1212 .close = octusb_device_ctrl_close,
1213 .enter = octusb_device_ctrl_enter,
1214 .start = octusb_device_ctrl_start,
1215 };
1216
1217 /*------------------------------------------------------------------------*
1218 * octusb interrupt support
1219 *------------------------------------------------------------------------*/
1220 static void
1221 octusb_device_intr_open(struct usb_xfer *xfer)
1222 {
1223 return;
1224 }
1225
1226 static void
1227 octusb_device_intr_close(struct usb_xfer *xfer)
1228 {
1229 octusb_device_done(xfer, USB_ERR_CANCELLED);
1230 }
1231
1232 static void
1233 octusb_device_intr_enter(struct usb_xfer *xfer)
1234 {
1235 return;
1236 }
1237
1238 static void
1239 octusb_device_intr_start(struct usb_xfer *xfer)
1240 {
1241 /* setup TDs */
1242 octusb_setup_standard_chain(xfer);
1243 octusb_start_standard_chain(xfer);
1244 }
1245
1246 struct usb_pipe_methods octusb_device_intr_methods =
1247 {
1248 .open = octusb_device_intr_open,
1249 .close = octusb_device_intr_close,
1250 .enter = octusb_device_intr_enter,
1251 .start = octusb_device_intr_start,
1252 };
1253
1254 /*------------------------------------------------------------------------*
1255 * octusb isochronous support
1256 *------------------------------------------------------------------------*/
1257 static void
1258 octusb_device_isoc_open(struct usb_xfer *xfer)
1259 {
1260 return;
1261 }
1262
1263 static void
1264 octusb_device_isoc_close(struct usb_xfer *xfer)
1265 {
1266 octusb_device_done(xfer, USB_ERR_CANCELLED);
1267 }
1268
1269 static void
1270 octusb_device_isoc_enter(struct usb_xfer *xfer)
1271 {
1272 struct octusb_softc *sc = OCTUSB_BUS2SC(xfer->xroot->bus);
1273 uint32_t temp;
1274 uint32_t frame_count;
1275 uint32_t fs_frames;
1276
1277 DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
1278 xfer, xfer->endpoint->isoc_next, xfer->nframes);
1279
1280 /* get the current frame index */
1281
1282 frame_count = cvmx_usb_get_frame_number(
1283 &sc->sc_port[xfer->xroot->udev->port_index].state);
1284
1285 /*
1286 * check if the frame index is within the window where the frames
1287 * will be inserted
1288 */
1289 temp = (frame_count - xfer->endpoint->isoc_next) & 0x7FF;
1290
1291 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
1292 fs_frames = (xfer->nframes + 7) / 8;
1293 } else {
1294 fs_frames = xfer->nframes;
1295 }
1296
1297 if ((xfer->endpoint->is_synced == 0) || (temp < fs_frames)) {
1298 /*
1299 * If there is data underflow or the pipe queue is
1300 * empty we schedule the transfer a few frames ahead
1301 * of the current frame position. Else two isochronous
1302 * transfers might overlap.
1303 */
1304 xfer->endpoint->isoc_next = (frame_count + 3) & 0x7FF;
1305 xfer->endpoint->is_synced = 1;
1306 DPRINTFN(2, "start next=%d\n", xfer->endpoint->isoc_next);
1307 }
1308 /*
1309 * compute how many milliseconds the insertion is ahead of the
1310 * current frame position:
1311 */
1312 temp = (xfer->endpoint->isoc_next - frame_count) & 0x7FF;
1313
1314 /*
1315 * pre-compute when the isochronous transfer will be finished:
1316 */
1317 xfer->isoc_time_complete =
1318 usb_isoc_time_expand(&sc->sc_bus, frame_count) + temp +
1319 fs_frames;
1320
1321 /* compute frame number for next insertion */
1322 xfer->endpoint->isoc_next += fs_frames;
1323 }
1324
1325 static void
1326 octusb_device_isoc_start(struct usb_xfer *xfer)
1327 {
1328 /* setup TDs */
1329 octusb_setup_standard_chain(xfer);
1330 octusb_start_standard_chain(xfer);
1331 }
1332
1333 struct usb_pipe_methods octusb_device_isoc_methods =
1334 {
1335 .open = octusb_device_isoc_open,
1336 .close = octusb_device_isoc_close,
1337 .enter = octusb_device_isoc_enter,
1338 .start = octusb_device_isoc_start,
1339 };
1340
1341 /*------------------------------------------------------------------------*
1342 * OCTUSB root HUB support
1343 *------------------------------------------------------------------------*
1344 * Simulate a hardware HUB by handling all the necessary requests.
1345 *------------------------------------------------------------------------*/
1346 static const
1347 struct usb_device_descriptor octusb_devd = {
1348 .bLength = sizeof(octusb_devd),
1349 .bDescriptorType = UDESC_DEVICE,
1350 .bcdUSB = {0x00, 0x02},
1351 .bDeviceClass = UDCLASS_HUB,
1352 .bDeviceSubClass = UDSUBCLASS_HUB,
1353 .bDeviceProtocol = UDPROTO_FSHUB,
1354 .bMaxPacketSize = 64,
1355 .idVendor = {0},
1356 .idProduct = {0},
1357 .bcdDevice = {0x00, 0x01},
1358 .iManufacturer = 1,
1359 .iProduct = 2,
1360 .iSerialNumber = 0,
1361 .bNumConfigurations = 1,
1362 };
1363
1364 static const
1365 struct usb_device_qualifier octusb_odevd = {
1366 .bLength = sizeof(octusb_odevd),
1367 .bDescriptorType = UDESC_DEVICE_QUALIFIER,
1368 .bcdUSB = {0x00, 0x02},
1369 .bDeviceClass = UDCLASS_HUB,
1370 .bDeviceSubClass = UDSUBCLASS_HUB,
1371 .bDeviceProtocol = UDPROTO_FSHUB,
1372 .bMaxPacketSize0 = 0,
1373 .bNumConfigurations = 0,
1374 .bReserved = 0,
1375 };
1376
1377 static const
1378 struct octusb_config_desc octusb_confd = {
1379 .confd = {
1380 .bLength = sizeof(struct usb_config_descriptor),
1381 .bDescriptorType = UDESC_CONFIG,
1382 .wTotalLength[0] = sizeof(octusb_confd),
1383 .bNumInterface = 1,
1384 .bConfigurationValue = 1,
1385 .iConfiguration = 0,
1386 .bmAttributes = UC_SELF_POWERED,
1387 .bMaxPower = 0 /* max power */
1388 },
1389 .ifcd = {
1390 .bLength = sizeof(struct usb_interface_descriptor),
1391 .bDescriptorType = UDESC_INTERFACE,
1392 .bNumEndpoints = 1,
1393 .bInterfaceClass = UICLASS_HUB,
1394 .bInterfaceSubClass = UISUBCLASS_HUB,
1395 .bInterfaceProtocol = UIPROTO_FSHUB,
1396 },
1397 .endpd = {
1398 .bLength = sizeof(struct usb_endpoint_descriptor),
1399 .bDescriptorType = UDESC_ENDPOINT,
1400 .bEndpointAddress = UE_DIR_IN | OCTUSB_INTR_ENDPT,
1401 .bmAttributes = UE_INTERRUPT,
1402 .wMaxPacketSize[0] = 8, /* max packet (63 ports) */
1403 .bInterval = 255,
1404 },
1405 };
1406
1407 static const
1408 struct usb_hub_descriptor_min octusb_hubd =
1409 {
1410 .bDescLength = sizeof(octusb_hubd),
1411 .bDescriptorType = UDESC_HUB,
1412 .bNbrPorts = 2,
1413 .wHubCharacteristics = {UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0},
1414 .bPwrOn2PwrGood = 50,
1415 .bHubContrCurrent = 0,
1416 .DeviceRemovable = {0x00}, /* all ports are removable */
1417 };
1418
1419 static usb_error_t
1420 octusb_roothub_exec(struct usb_device *udev,
1421 struct usb_device_request *req, const void **pptr, uint16_t *plength)
1422 {
1423 struct octusb_softc *sc = OCTUSB_BUS2SC(udev->bus);
1424 const void *ptr;
1425 const char *str_ptr;
1426 uint16_t value;
1427 uint16_t index;
1428 uint16_t status;
1429 uint16_t change;
1430 uint16_t len;
1431 usb_error_t err;
1432 cvmx_usb_port_status_t usb_port_status;
1433
1434 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
1435
1436 /* XXX disable power save mode, hence it is not supported */
1437 udev->power_mode = USB_POWER_MODE_ON;
1438
1439 /* buffer reset */
1440 ptr = (const void *)&sc->sc_hub_desc.temp;
1441 len = 0;
1442 err = 0;
1443
1444 value = UGETW(req->wValue);
1445 index = UGETW(req->wIndex);
1446
1447 DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
1448 "wValue=0x%04x wIndex=0x%04x\n",
1449 req->bmRequestType, req->bRequest,
1450 UGETW(req->wLength), value, index);
1451
1452 #define C(x,y) ((x) | ((y) << 8))
1453 switch (C(req->bRequest, req->bmRequestType)) {
1454 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
1455 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
1456 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
1457 break;
1458 case C(UR_GET_CONFIG, UT_READ_DEVICE):
1459 len = 1;
1460 sc->sc_hub_desc.temp[0] = sc->sc_conf;
1461 break;
1462 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
1463 switch (value >> 8) {
1464 case UDESC_DEVICE:
1465 if ((value & 0xff) != 0) {
1466 err = USB_ERR_IOERROR;
1467 goto done;
1468 }
1469 len = sizeof(octusb_devd);
1470
1471 ptr = (const void *)&octusb_devd;
1472 break;
1473
1474 case UDESC_DEVICE_QUALIFIER:
1475 if ((value & 0xff) != 0) {
1476 err = USB_ERR_IOERROR;
1477 goto done;
1478 }
1479 len = sizeof(octusb_odevd);
1480 ptr = (const void *)&octusb_odevd;
1481 break;
1482
1483 case UDESC_CONFIG:
1484 if ((value & 0xff) != 0) {
1485 err = USB_ERR_IOERROR;
1486 goto done;
1487 }
1488 len = sizeof(octusb_confd);
1489 ptr = (const void *)&octusb_confd;
1490 break;
1491
1492 case UDESC_STRING:
1493 switch (value & 0xff) {
1494 case 0: /* Language table */
1495 str_ptr = "\001";
1496 break;
1497
1498 case 1: /* Vendor */
1499 str_ptr = "Cavium Networks";
1500 break;
1501
1502 case 2: /* Product */
1503 str_ptr = "OCTUSB Root HUB";
1504 break;
1505
1506 default:
1507 str_ptr = "";
1508 break;
1509 }
1510
1511 len = usb_make_str_desc(sc->sc_hub_desc.temp,
1512 sizeof(sc->sc_hub_desc.temp), str_ptr);
1513 break;
1514
1515 default:
1516 err = USB_ERR_IOERROR;
1517 goto done;
1518 }
1519 break;
1520 case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
1521 len = 1;
1522 sc->sc_hub_desc.temp[0] = 0;
1523 break;
1524 case C(UR_GET_STATUS, UT_READ_DEVICE):
1525 len = 2;
1526 USETW(sc->sc_hub_desc.stat.wStatus, UDS_SELF_POWERED);
1527 break;
1528 case C(UR_GET_STATUS, UT_READ_INTERFACE):
1529 case C(UR_GET_STATUS, UT_READ_ENDPOINT):
1530 len = 2;
1531 USETW(sc->sc_hub_desc.stat.wStatus, 0);
1532 break;
1533 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
1534 if (value >= OCTUSB_MAX_DEVICES) {
1535 err = USB_ERR_IOERROR;
1536 goto done;
1537 }
1538 sc->sc_addr = value;
1539 break;
1540 case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
1541 if ((value != 0) && (value != 1)) {
1542 err = USB_ERR_IOERROR;
1543 goto done;
1544 }
1545 sc->sc_conf = value;
1546 break;
1547 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
1548 break;
1549 case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
1550 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
1551 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
1552 err = USB_ERR_IOERROR;
1553 goto done;
1554 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
1555 break;
1556 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
1557 break;
1558 /* Hub requests */
1559 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
1560 break;
1561 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
1562 DPRINTFN(4, "UR_CLEAR_PORT_FEATURE "
1563 "port=%d feature=%d\n",
1564 index, value);
1565 if ((index < 1) ||
1566 (index > sc->sc_noport) ||
1567 sc->sc_port[index - 1].disabled) {
1568 err = USB_ERR_IOERROR;
1569 goto done;
1570 }
1571 index--;
1572
1573 switch (value) {
1574 case UHF_PORT_ENABLE:
1575 cvmx_usb_disable(&sc->sc_port[index].state);
1576 break;
1577 case UHF_PORT_SUSPEND:
1578 case UHF_PORT_RESET:
1579 break;
1580 case UHF_C_PORT_CONNECTION:
1581 cvmx_usb_set_status(&sc->sc_port[index].state,
1582 cvmx_usb_get_status(&sc->sc_port[index].state));
1583 break;
1584 case UHF_C_PORT_ENABLE:
1585 cvmx_usb_set_status(&sc->sc_port[index].state,
1586 cvmx_usb_get_status(&sc->sc_port[index].state));
1587 break;
1588 case UHF_C_PORT_OVER_CURRENT:
1589 cvmx_usb_set_status(&sc->sc_port[index].state,
1590 cvmx_usb_get_status(&sc->sc_port[index].state));
1591 break;
1592 case UHF_C_PORT_RESET:
1593 sc->sc_isreset = 0;
1594 goto done;
1595 case UHF_C_PORT_SUSPEND:
1596 break;
1597 case UHF_PORT_CONNECTION:
1598 case UHF_PORT_OVER_CURRENT:
1599 case UHF_PORT_POWER:
1600 case UHF_PORT_LOW_SPEED:
1601 default:
1602 err = USB_ERR_IOERROR;
1603 goto done;
1604 }
1605 break;
1606 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
1607 if ((value & 0xff) != 0) {
1608 err = USB_ERR_IOERROR;
1609 goto done;
1610 }
1611 sc->sc_hubd = octusb_hubd;
1612 sc->sc_hubd.bNbrPorts = sc->sc_noport;
1613 len = sizeof(sc->sc_hubd);
1614 ptr = (const void *)&sc->sc_hubd;
1615 break;
1616 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
1617 len = 16;
1618 memset(sc->sc_hub_desc.temp, 0, 16);
1619 break;
1620 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
1621 if ((index < 1) ||
1622 (index > sc->sc_noport) ||
1623 sc->sc_port[index - 1].disabled) {
1624 err = USB_ERR_IOERROR;
1625 goto done;
1626 }
1627 index--;
1628
1629 usb_port_status = cvmx_usb_get_status(&sc->sc_port[index].state);
1630
1631 status = change = 0;
1632 if (usb_port_status.connected)
1633 status |= UPS_CURRENT_CONNECT_STATUS;
1634 if (usb_port_status.port_enabled)
1635 status |= UPS_PORT_ENABLED;
1636 if (usb_port_status.port_over_current)
1637 status |= UPS_OVERCURRENT_INDICATOR;
1638 if (usb_port_status.port_powered)
1639 status |= UPS_PORT_POWER;
1640
1641 switch (usb_port_status.port_speed) {
1642 case CVMX_USB_SPEED_HIGH:
1643 status |= UPS_HIGH_SPEED;
1644 break;
1645 case CVMX_USB_SPEED_FULL:
1646 break;
1647 default:
1648 status |= UPS_LOW_SPEED;
1649 break;
1650 }
1651
1652 if (usb_port_status.connect_change)
1653 change |= UPS_C_CONNECT_STATUS;
1654 if (sc->sc_isreset)
1655 change |= UPS_C_PORT_RESET;
1656
1657 USETW(sc->sc_hub_desc.ps.wPortStatus, status);
1658 USETW(sc->sc_hub_desc.ps.wPortChange, change);
1659
1660 len = sizeof(sc->sc_hub_desc.ps);
1661 break;
1662 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
1663 err = USB_ERR_IOERROR;
1664 goto done;
1665 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
1666 break;
1667 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
1668 if ((index < 1) ||
1669 (index > sc->sc_noport) ||
1670 sc->sc_port[index - 1].disabled) {
1671 err = USB_ERR_IOERROR;
1672 goto done;
1673 }
1674 index--;
1675
1676 switch (value) {
1677 case UHF_PORT_ENABLE:
1678 break;
1679 case UHF_PORT_RESET:
1680 cvmx_usb_disable(&sc->sc_port[index].state);
1681 if (cvmx_usb_enable(&sc->sc_port[index].state)) {
1682 err = USB_ERR_IOERROR;
1683 goto done;
1684 }
1685 sc->sc_isreset = 1;
1686 goto done;
1687 case UHF_PORT_POWER:
1688 /* pretend we turned on power */
1689 goto done;
1690 case UHF_PORT_SUSPEND:
1691 case UHF_C_PORT_CONNECTION:
1692 case UHF_C_PORT_ENABLE:
1693 case UHF_C_PORT_OVER_CURRENT:
1694 case UHF_PORT_CONNECTION:
1695 case UHF_PORT_OVER_CURRENT:
1696 case UHF_PORT_LOW_SPEED:
1697 case UHF_C_PORT_SUSPEND:
1698 case UHF_C_PORT_RESET:
1699 default:
1700 err = USB_ERR_IOERROR;
1701 goto done;
1702 }
1703 break;
1704 default:
1705 err = USB_ERR_IOERROR;
1706 goto done;
1707 }
1708 done:
1709 *plength = len;
1710 *pptr = ptr;
1711 return (err);
1712 }
1713
1714 static void
1715 octusb_xfer_setup(struct usb_setup_params *parm)
1716 {
1717 struct usb_page_search page_info;
1718 struct usb_page_cache *pc;
1719 struct octusb_softc *sc;
1720 struct octusb_qh *qh;
1721 struct usb_xfer *xfer;
1722 struct usb_device *hub;
1723 void *last_obj;
1724 uint32_t n;
1725 uint32_t ntd;
1726
1727 sc = OCTUSB_BUS2SC(parm->udev->bus);
1728 xfer = parm->curr_xfer;
1729 qh = NULL;
1730
1731 /*
1732 * NOTE: This driver does not use any of the parameters that
1733 * are computed from the following values. Just set some
1734 * reasonable dummies:
1735 */
1736
1737 parm->hc_max_packet_size = 0x400;
1738 parm->hc_max_packet_count = 3;
1739 parm->hc_max_frame_size = 0xC00;
1740
1741 usbd_transfer_setup_sub(parm);
1742
1743 if (parm->err)
1744 return;
1745
1746 /* Allocate a queue head */
1747
1748 if (usbd_transfer_setup_sub_malloc(
1749 parm, &pc, sizeof(struct octusb_qh),
1750 USB_HOST_ALIGN, 1)) {
1751 parm->err = USB_ERR_NOMEM;
1752 return;
1753 }
1754 if (parm->buf) {
1755 usbd_get_page(pc, 0, &page_info);
1756
1757 qh = page_info.buffer;
1758
1759 /* fill out QH */
1760
1761 qh->sc = OCTUSB_BUS2SC(xfer->xroot->bus);
1762 qh->max_frame_size = xfer->max_frame_size;
1763 qh->max_packet_size = xfer->max_packet_size;
1764 qh->ep_num = xfer->endpointno;
1765 qh->ep_type = xfer->endpoint->edesc->bmAttributes;
1766 qh->dev_addr = xfer->address;
1767 qh->dev_speed = usbd_get_speed(xfer->xroot->udev);
1768 qh->root_port_index = xfer->xroot->udev->port_index;
1769 /* We need Octeon USB HUB's port index, not the local port */
1770 hub = xfer->xroot->udev->parent_hub;
1771 while(hub && hub->parent_hub) {
1772 qh->root_port_index = hub->port_index;
1773 hub = hub->parent_hub;
1774 }
1775
1776 switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
1777 case UE_INTERRUPT:
1778 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH)
1779 qh->ep_interval = xfer->interval * 8;
1780 else
1781 qh->ep_interval = xfer->interval * 1;
1782 break;
1783 case UE_ISOCHRONOUS:
1784 qh->ep_interval = 1 << xfer->fps_shift;
1785 break;
1786 default:
1787 qh->ep_interval = 0;
1788 break;
1789 }
1790
1791 qh->ep_mult = xfer->max_packet_count & 3;
1792 qh->hs_hub_addr = xfer->xroot->udev->hs_hub_addr;
1793 qh->hs_hub_port = xfer->xroot->udev->hs_port_no;
1794 }
1795 xfer->qh_start[0] = qh;
1796
1797 /* Allocate a fixup buffer */
1798
1799 if (usbd_transfer_setup_sub_malloc(
1800 parm, &pc, OCTUSB_MAX_FIXUP,
1801 OCTUSB_MAX_FIXUP, 1)) {
1802 parm->err = USB_ERR_NOMEM;
1803 return;
1804 }
1805 if (parm->buf) {
1806 usbd_get_page(pc, 0, &page_info);
1807
1808 qh->fixup_phys = page_info.physaddr;
1809 qh->fixup_pc = pc;
1810 qh->fixup_buf = page_info.buffer;
1811 }
1812 /* Allocate transfer descriptors */
1813
1814 last_obj = NULL;
1815
1816 ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
1817
1818 if (usbd_transfer_setup_sub_malloc(
1819 parm, &pc, sizeof(struct octusb_td),
1820 USB_HOST_ALIGN, ntd)) {
1821 parm->err = USB_ERR_NOMEM;
1822 return;
1823 }
1824 if (parm->buf) {
1825 for (n = 0; n != ntd; n++) {
1826 struct octusb_td *td;
1827
1828 usbd_get_page(pc + n, 0, &page_info);
1829
1830 td = page_info.buffer;
1831
1832 td->qh = qh;
1833 td->obj_next = last_obj;
1834
1835 last_obj = td;
1836 }
1837 }
1838 xfer->td_start[0] = last_obj;
1839 }
1840
1841 static void
1842 octusb_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
1843 struct usb_endpoint *ep)
1844 {
1845 struct octusb_softc *sc = OCTUSB_BUS2SC(udev->bus);
1846
1847 DPRINTFN(2, "endpoint=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
1848 ep, udev->address, edesc->bEndpointAddress,
1849 udev->flags.usb_mode, sc->sc_addr);
1850
1851 if (udev->device_index != sc->sc_addr) {
1852 switch (edesc->bmAttributes & UE_XFERTYPE) {
1853 case UE_CONTROL:
1854 ep->methods = &octusb_device_ctrl_methods;
1855 break;
1856 case UE_INTERRUPT:
1857 ep->methods = &octusb_device_intr_methods;
1858 break;
1859 case UE_ISOCHRONOUS:
1860 if (udev->speed != USB_SPEED_LOW)
1861 ep->methods = &octusb_device_isoc_methods;
1862 break;
1863 case UE_BULK:
1864 ep->methods = &octusb_device_bulk_methods;
1865 break;
1866 default:
1867 /* do nothing */
1868 break;
1869 }
1870 }
1871 }
1872
1873 static void
1874 octusb_xfer_unsetup(struct usb_xfer *xfer)
1875 {
1876 DPRINTF("Nothing to do.\n");
1877 }
1878
1879 static void
1880 octusb_get_dma_delay(struct usb_device *udev, uint32_t *pus)
1881 {
1882 /* DMA delay - wait until any use of memory is finished */
1883 *pus = (2125); /* microseconds */
1884 }
1885
1886 static void
1887 octusb_device_resume(struct usb_device *udev)
1888 {
1889 DPRINTF("Nothing to do.\n");
1890 }
1891
1892 static void
1893 octusb_device_suspend(struct usb_device *udev)
1894 {
1895 DPRINTF("Nothing to do.\n");
1896 }
1897
1898 static void
1899 octusb_set_hw_power(struct usb_bus *bus)
1900 {
1901 DPRINTF("Nothing to do.\n");
1902 }
1903
1904 static void
1905 octusb_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
1906 {
1907 struct octusb_softc *sc = OCTUSB_BUS2SC(bus);
1908
1909 switch (state) {
1910 case USB_HW_POWER_SUSPEND:
1911 octusb_suspend(sc);
1912 break;
1913 case USB_HW_POWER_SHUTDOWN:
1914 octusb_uninit(sc);
1915 break;
1916 case USB_HW_POWER_RESUME:
1917 octusb_resume(sc);
1918 break;
1919 default:
1920 break;
1921 }
1922 }
1923
1924 struct usb_bus_methods octusb_bus_methods = {
1925 .endpoint_init = octusb_ep_init,
1926 .xfer_setup = octusb_xfer_setup,
1927 .xfer_unsetup = octusb_xfer_unsetup,
1928 .get_dma_delay = octusb_get_dma_delay,
1929 .device_resume = octusb_device_resume,
1930 .device_suspend = octusb_device_suspend,
1931 .set_hw_power = octusb_set_hw_power,
1932 .set_hw_power_sleep = octusb_set_hw_power_sleep,
1933 .roothub_exec = octusb_roothub_exec,
1934 .xfer_poll = octusb_do_poll,
1935 };
Cache object: a0da1d44a5d15745f14bb685b45af344
|