1 #include <sys/cdefs.h>
2 __FBSDID("$FreeBSD: releng/11.0/sys/mips/cavium/usb/octusb.c 267992 2014-06-28 03:56:17Z hselasky $");
3
4 /*-
5 * Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
15 *
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
26 * SUCH DAMAGE.
27 */
28
29 /*
30 * This file contains the driver for Octeon Executive Library USB
31 * Controller driver API.
32 */
33
34 /* TODO: The root HUB port callback is not yet implemented. */
35
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>
43 #include <sys/bus.h>
44 #include <sys/module.h>
45 #include <sys/lock.h>
46 #include <sys/mutex.h>
47 #include <sys/condvar.h>
48 #include <sys/sysctl.h>
49 #include <sys/sx.h>
50 #include <sys/unistd.h>
51 #include <sys/callout.h>
52 #include <sys/malloc.h>
53 #include <sys/priv.h>
54
55 #include <dev/usb/usb.h>
56 #include <dev/usb/usbdi.h>
57
58 #define USB_DEBUG_VAR octusbdebug
59
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>
68
69 #include <dev/usb/usb_controller.h>
70 #include <dev/usb/usb_bus.h>
71
72 #include <contrib/octeon-sdk/cvmx.h>
73 #include <contrib/octeon-sdk/cvmx-usb.h>
74
75 #include <mips/cavium/usb/octusb.h>
76
77 #define OCTUSB_BUS2SC(bus) \
78 ((struct octusb_softc *)(((uint8_t *)(bus)) - \
79 ((uint8_t *)&(((struct octusb_softc *)0)->sc_bus))))
80
81 #ifdef USB_DEBUG
82 static int octusbdebug = 0;
83
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");
87 #endif
88
89 struct octusb_std_temp {
90 octusb_cmd_t *func;
91 struct octusb_td *td;
92 struct octusb_td *td_next;
93 struct usb_page_cache *pc;
94 uint32_t offset;
95 uint32_t len;
96 uint8_t short_pkt;
97 uint8_t setup_alt_next;
98 };
99
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;
105
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 *);
110
111 static cvmx_usb_speed_t
112 octusb_convert_speed(enum usb_dev_speed speed)
113 {
114 ; /* indent fix */
115 switch (speed) {
116 case USB_SPEED_HIGH:
117 return (CVMX_USB_SPEED_HIGH);
118 case USB_SPEED_FULL:
119 return (CVMX_USB_SPEED_FULL);
120 default:
121 return (CVMX_USB_SPEED_LOW);
122 }
123 }
124
125 static cvmx_usb_transfer_t
126 octusb_convert_ep_type(uint8_t ep_type)
127 {
128 ; /* indent fix */
129 switch (ep_type & UE_XFERTYPE) {
130 case UE_CONTROL:
131 return (CVMX_USB_TRANSFER_CONTROL);
132 case UE_INTERRUPT:
133 return (CVMX_USB_TRANSFER_INTERRUPT);
134 case UE_ISOCHRONOUS:
135 return (CVMX_USB_TRANSFER_ISOCHRONOUS);
136 case UE_BULK:
137 return (CVMX_USB_TRANSFER_BULK);
138 default:
139 return (0); /* should not happen */
140 }
141 }
142
143 static uint8_t
144 octusb_host_alloc_endpoint(struct octusb_td *td)
145 {
146 struct octusb_softc *sc;
147 int ep_handle;
148
149 if (td->qh->fixup_pending)
150 return (1); /* busy */
151
152 if (td->qh->ep_allocated)
153 return (0); /* success */
154
155 /* get softc */
156 sc = td->qh->sc;
157
158 ep_handle = cvmx_usb_open_pipe(
159 &sc->sc_port[td->qh->root_port_index].state,
160 0,
161 td->qh->dev_addr,
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,
168 td->qh->ep_interval,
169 (td->qh->dev_speed == USB_SPEED_HIGH) ? td->qh->ep_mult : 0,
170 td->qh->hs_hub_addr,
171 td->qh->hs_hub_port);
172
173 if (ep_handle < 0) {
174 DPRINTFN(1, "cvmx_usb_open_pipe failed: %d\n", ep_handle);
175 return (1); /* busy */
176 }
177
178 cvmx_usb_set_toggle(
179 &sc->sc_port[td->qh->root_port_index].state,
180 ep_handle, td->qh->ep_toggle_next);
181
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;
188
189 td->qh->ep_handle = ep_handle;
190 td->qh->ep_allocated = 1;
191
192 return (0); /* success */
193 }
194
195 static void
196 octusb_host_free_endpoint(struct octusb_td *td)
197 {
198 struct octusb_softc *sc;
199
200 if (td->qh->ep_allocated == 0)
201 return;
202
203 /* get softc */
204 sc = td->qh->sc;
205
206 if (td->qh->fixup_handle >= 0) {
207 /* cancel, if any */
208 cvmx_usb_cancel(&sc->sc_port[td->qh->root_port_index].state,
209 td->qh->ep_handle, td->qh->fixup_handle);
210 }
211 cvmx_usb_close_pipe(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle);
212
213 td->qh->ep_allocated = 0;
214 }
215
216 static void
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)
222 {
223 struct octusb_td *td;
224
225 if (reason != CVMX_USB_CALLBACK_TRANSFER_COMPLETE)
226 return;
227
228 td = user_data;
229
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;
234
235 switch (status) {
236 case CVMX_USB_COMPLETE_SUCCESS:
237 case CVMX_USB_COMPLETE_SHORT:
238 td->error_any = 0;
239 td->error_stall = 0;
240 break;
241 case CVMX_USB_COMPLETE_STALL:
242 td->error_stall = 1;
243 td->error_any = 1;
244 break;
245 default:
246 td->error_any = 1;
247 break;
248 }
249 }
250
251 static uint8_t
252 octusb_host_control_header_tx(struct octusb_td *td)
253 {
254 int status;
255
256 /* allocate endpoint and check pending */
257 if (octusb_host_alloc_endpoint(td))
258 return (1); /* busy */
259
260 /* check error */
261 if (td->error_any)
262 return (0); /* done */
263
264 if (td->qh->fixup_complete != 0) {
265 /* clear complete flag */
266 td->qh->fixup_complete = 0;
267
268 /* flush data */
269 usb_pc_cpu_invalidate(td->qh->fixup_pc);
270 return (0); /* done */
271 }
272 /* verify length */
273 if (td->remainder != 8) {
274 td->error_any = 1;
275 return (0); /* done */
276 }
277 usbd_copy_out(td->pc, td->offset, td->qh->fixup_buf, 8);
278
279 /* update offset and remainder */
280 td->offset += 8;
281 td->remainder -= 8;
282
283 /* setup data length and offset */
284 td->qh->fixup_len = UGETW(td->qh->fixup_buf + 6);
285 td->qh->fixup_off = 0;
286
287 if (td->qh->fixup_len > (OCTUSB_MAX_FIXUP - 8)) {
288 td->error_any = 1;
289 return (0); /* done */
290 }
291 /* do control IN request */
292 if (td->qh->fixup_buf[0] & UE_DIR_IN) {
293
294 struct octusb_softc *sc;
295
296 /* get softc */
297 sc = td->qh->sc;
298
299 /* flush data */
300 usb_pc_cpu_flush(td->qh->fixup_pc);
301
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);
307 /* check status */
308 if (status < 0) {
309 td->error_any = 1;
310 return (0); /* done */
311 }
312 td->qh->fixup_handle = status;
313 td->qh->fixup_pending = 1;
314 td->qh->fixup_complete = 0;
315
316 return (1); /* busy */
317 }
318 return (0); /* done */
319 }
320
321 static uint8_t
322 octusb_host_control_data_tx(struct octusb_td *td)
323 {
324 uint32_t rem;
325
326 /* allocate endpoint and check pending */
327 if (octusb_host_alloc_endpoint(td))
328 return (1); /* busy */
329
330 /* check error */
331 if (td->error_any)
332 return (0); /* done */
333
334 rem = td->qh->fixup_len - td->qh->fixup_off;
335
336 if (td->remainder > rem) {
337 td->error_any = 1;
338 DPRINTFN(1, "Excess setup transmit data\n");
339 return (0); /* done */
340 }
341 usbd_copy_out(td->pc, td->offset, td->qh->fixup_buf +
342 td->qh->fixup_off + 8, td->remainder);
343
344 td->offset += td->remainder;
345 td->qh->fixup_off += td->remainder;
346 td->remainder = 0;
347
348 return (0); /* done */
349 }
350
351 static uint8_t
352 octusb_host_control_data_rx(struct octusb_td *td)
353 {
354 uint32_t rem;
355
356 /* allocate endpoint and check pending */
357 if (octusb_host_alloc_endpoint(td))
358 return (1); /* busy */
359
360 /* check error */
361 if (td->error_any)
362 return (0); /* done */
363
364 /* copy data from buffer */
365 rem = td->qh->fixup_actlen - td->qh->fixup_off;
366
367 if (rem > td->remainder)
368 rem = td->remainder;
369
370 usbd_copy_in(td->pc, td->offset, td->qh->fixup_buf +
371 td->qh->fixup_off + 8, rem);
372
373 td->offset += rem;
374 td->remainder -= rem;
375 td->qh->fixup_off += rem;
376
377 return (0); /* done */
378 }
379
380 static uint8_t
381 octusb_host_control_status_tx(struct octusb_td *td)
382 {
383 int status;
384
385 /* allocate endpoint and check pending */
386 if (octusb_host_alloc_endpoint(td))
387 return (1); /* busy */
388
389 /* check error */
390 if (td->error_any)
391 return (0); /* done */
392
393 if (td->qh->fixup_complete != 0) {
394 /* clear complete flag */
395 td->qh->fixup_complete = 0;
396 /* done */
397 return (0);
398 }
399 /* do control IN request */
400 if (!(td->qh->fixup_buf[0] & UE_DIR_IN)) {
401
402 struct octusb_softc *sc;
403
404 /* get softc */
405 sc = td->qh->sc;
406
407 /* flush data */
408 usb_pc_cpu_flush(td->qh->fixup_pc);
409
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);
416
417 /* check status */
418 if (status < 0) {
419 td->error_any = 1;
420 return (0); /* done */
421 }
422 td->qh->fixup_handle = status;
423 td->qh->fixup_pending = 1;
424 td->qh->fixup_complete = 0;
425
426 return (1); /* busy */
427 }
428 return (0); /* done */
429 }
430
431 static uint8_t
432 octusb_non_control_data_tx(struct octusb_td *td)
433 {
434 struct octusb_softc *sc;
435 uint32_t rem;
436 int status;
437
438 /* allocate endpoint and check pending */
439 if (octusb_host_alloc_endpoint(td))
440 return (1); /* busy */
441
442 /* check error */
443 if (td->error_any)
444 return (0); /* done */
445
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 */
450 }
451 /* check complete */
452 if (td->remainder == 0) {
453 if (td->short_pkt)
454 return (0); /* complete */
455 /* else need to send a zero length packet */
456 rem = 0;
457 td->short_pkt = 1;
458 } else {
459 /* get maximum length */
460 rem = OCTUSB_MAX_FIXUP % td->qh->max_frame_size;
461 rem = OCTUSB_MAX_FIXUP - rem;
462
463 if (rem == 0) {
464 /* should not happen */
465 DPRINTFN(1, "Fixup buffer is too small\n");
466 td->error_any = 1;
467 return (0); /* done */
468 }
469 /* get minimum length */
470 if (rem > td->remainder) {
471 rem = td->remainder;
472 if ((rem == 0) || (rem % td->qh->max_frame_size))
473 td->short_pkt = 1;
474 }
475 /* copy data into fixup buffer */
476 usbd_copy_out(td->pc, td->offset, td->qh->fixup_buf, rem);
477
478 /* flush data */
479 usb_pc_cpu_flush(td->qh->fixup_pc);
480
481 /* pre-increment TX buffer offset */
482 td->offset += rem;
483 td->remainder -= rem;
484 }
485
486 /* get softc */
487 sc = td->qh->sc;
488
489 switch (td->qh->ep_type & UE_XFERTYPE) {
490 case UE_ISOCHRONOUS:
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);
499 break;
500 case UE_BULK:
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);
504 break;
505 case UE_INTERRUPT:
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);
509 break;
510 default:
511 status = -1;
512 break;
513 }
514
515 /* check status */
516 if (status < 0) {
517 td->error_any = 1;
518 return (0); /* done */
519 }
520 td->qh->fixup_handle = status;
521 td->qh->fixup_len = rem;
522 td->qh->fixup_pending = 1;
523 td->qh->fixup_complete = 0;
524
525 return (1); /* busy */
526 }
527
528 static uint8_t
529 octusb_non_control_data_rx(struct octusb_td *td)
530 {
531 struct octusb_softc *sc;
532 uint32_t rem;
533 int status;
534 uint8_t got_short;
535
536 /* allocate endpoint and check pending */
537 if (octusb_host_alloc_endpoint(td))
538 return (1); /* busy */
539
540 /* check error */
541 if (td->error_any)
542 return (0); /* done */
543
544 got_short = 0;
545
546 if (td->qh->fixup_complete != 0) {
547
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
770 if (xfer->flags_int.control_hdr)
771 error = octusb_standard_done_sub(xfer);
772
773 xfer->aframes = 1;
774
775 if (xfer->td_transfer_cache == NULL)
776 goto done;
777 }
778 while (xfer->aframes != xfer->nframes) {
779
780 error = octusb_standard_done_sub(xfer);
781
782 xfer->aframes++;
783
784 if (xfer->td_transfer_cache == NULL)
785 goto done;
786 }
787
788 if (xfer->flags_int.control_xfr &&
789 !xfer->flags_int.control_act)
790 error = octusb_standard_done_sub(xfer);
791
792 done:
793 /* update data toggle */
794
795 qh = xfer->qh_start[0];
796 sc = qh->sc;
797
798 xfer->endpoint->toggle_next =
799 cvmx_usb_get_toggle(
800 &sc->sc_port[qh->root_port_index].state,
801 qh->ep_handle) ? 1 : 0;
802
803 octusb_device_done(xfer, error);
804 }
805
806 static void
807 octusb_interrupt_poll(struct octusb_softc *sc)
808 {
809 struct usb_xfer *xfer;
810 uint8_t x;
811
812 /* poll all ports */
813 for (x = 0; x != sc->sc_noport; x++)
814 cvmx_usb_poll(&sc->sc_port[x].state);
815
816 repeat:
817 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
818 if (!octusb_xfer_do_fifo(xfer)) {
819 /* queue has been modified */
820 goto repeat;
821 }
822 }
823 }
824
825 static void
826 octusb_start_standard_chain(struct usb_xfer *xfer)
827 {
828 DPRINTFN(8, "\n");
829
830 /* poll one time */
831 if (octusb_xfer_do_fifo(xfer)) {
832
833 /* put transfer on interrupt queue */
834 usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
835
836 /* start timeout, if any */
837 if (xfer->timeout != 0) {
838 usbd_transfer_timeout_ms(xfer,
839 &octusb_timeout, xfer->timeout);
840 }
841 }
842 }
843
844 void
845 octusb_iterate_hw_softc(struct usb_bus *bus, usb_bus_mem_sub_cb_t *cb)
846 {
847
848 }
849
850 usb_error_t
851 octusb_init(struct octusb_softc *sc)
852 {
853 cvmx_usb_initialize_flags_t flags;
854 int status;
855 uint8_t x;
856
857 /* flush all cache into memory */
858
859 usb_bus_mem_flush_all(&sc->sc_bus, &octusb_iterate_hw_softc);
860
861 /* set up the bus struct */
862 sc->sc_bus.methods = &octusb_bus_methods;
863
864 /* get number of ports */
865 sc->sc_noport = cvmx_usb_get_num_ports();
866
867 /* check number of ports */
868 if (sc->sc_noport > OCTUSB_MAX_PORTS)
869 sc->sc_noport = OCTUSB_MAX_PORTS;
870
871 /* set USB revision */
872 sc->sc_bus.usbrev = USB_REV_2_0;
873
874 /* flags for port initialization */
875 flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO;
876 #ifdef USB_DEBUG
877 if (octusbdebug > 100)
878 flags |= CVMX_USB_INITIALIZE_FLAGS_DEBUG_ALL;
879 #endif
880
881 USB_BUS_LOCK(&sc->sc_bus);
882
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);
886 if (status < 0)
887 sc->sc_port[x].disabled = 1;
888 }
889
890 USB_BUS_UNLOCK(&sc->sc_bus);
891
892 /* catch lost interrupts */
893 octusb_do_poll(&sc->sc_bus);
894
895 return (0);
896 }
897
898 usb_error_t
899 octusb_uninit(struct octusb_softc *sc)
900 {
901 uint8_t x;
902
903 USB_BUS_LOCK(&sc->sc_bus);
904
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);
908 }
909 USB_BUS_UNLOCK(&sc->sc_bus);
910
911 return (0);
912
913 }
914
915 static void
916 octusb_suspend(struct octusb_softc *sc)
917 {
918 /* TODO */
919 }
920
921 static void
922 octusb_resume(struct octusb_softc *sc)
923 {
924 /* TODO */
925 }
926
927 /*------------------------------------------------------------------------*
928 * octusb_interrupt - OCTUSB interrupt handler
929 *------------------------------------------------------------------------*/
930 void
931 octusb_interrupt(struct octusb_softc *sc)
932 {
933 USB_BUS_LOCK(&sc->sc_bus);
934
935 DPRINTFN(16, "real interrupt\n");
936
937 /* poll all the USB transfers */
938 octusb_interrupt_poll(sc);
939
940 USB_BUS_UNLOCK(&sc->sc_bus);
941 }
942
943 /*------------------------------------------------------------------------*
944 * octusb_timeout - OCTUSB transfer timeout handler
945 *------------------------------------------------------------------------*/
946 static void
947 octusb_timeout(void *arg)
948 {
949 struct usb_xfer *xfer = arg;
950
951 DPRINTF("xfer=%p\n", xfer);
952
953 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
954
955 /* transfer is transferred */
956 octusb_device_done(xfer, USB_ERR_TIMEOUT);
957 }
958
959 /*------------------------------------------------------------------------*
960 * octusb_do_poll - OCTUSB poll transfers
961 *------------------------------------------------------------------------*/
962 static void
963 octusb_do_poll(struct usb_bus *bus)
964 {
965 struct octusb_softc *sc = OCTUSB_BUS2SC(bus);
966
967 USB_BUS_LOCK(&sc->sc_bus);
968 octusb_interrupt_poll(sc);
969 USB_BUS_UNLOCK(&sc->sc_bus);
970 }
971
972 static void
973 octusb_setup_standard_chain_sub(struct octusb_std_temp *temp)
974 {
975 struct octusb_td *td;
976
977 /* get current Transfer Descriptor */
978 td = temp->td_next;
979 temp->td = td;
980
981 /* prepare for next TD */
982 temp->td_next = td->obj_next;
983
984 /* fill out the Transfer Descriptor */
985 td->func = temp->func;
986 td->pc = temp->pc;
987 td->offset = temp->offset;
988 td->remainder = temp->len;
989 td->error_any = 0;
990 td->error_stall = 0;
991 td->short_pkt = temp->short_pkt;
992 td->alt_next = temp->setup_alt_next;
993 }
994
995 static void
996 octusb_setup_standard_chain(struct usb_xfer *xfer)
997 {
998 struct octusb_std_temp temp;
999 struct octusb_td *td;
1000 uint32_t x;
1001
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));
1005
1006 /* setup starting point */
1007 td = xfer->td_start[0];
1008 xfer->td_transfer_first = td;
1009 xfer->td_transfer_cache = td;
1010
1011 temp.td = NULL;
1012 temp.td_next = td;
1013 temp.setup_alt_next = xfer->flags_int.short_frames_ok;
1014 temp.offset = 0;
1015
1016 /* check if we should prepend a setup message */
1017
1018 if (xfer->flags_int.control_xfr) {
1019
1020 if (xfer->flags_int.control_hdr) {
1021
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;
1026
1027 /* check for last frame */
1028 if (xfer->nframes == 1) {
1029 /*
1030 * no STATUS stage yet, SETUP is
1031 * last
1032 */
1033 if (xfer->flags_int.control_act)
1034 temp.setup_alt_next = 0;
1035 }
1036 octusb_setup_standard_chain_sub(&temp);
1037 }
1038 x = 1;
1039 } else {
1040 x = 0;
1041 }
1042
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;
1047 else
1048 temp.func = &octusb_non_control_data_rx;
1049 } else {
1050 if (xfer->flags_int.control_xfr)
1051 temp.func = &octusb_host_control_data_tx;
1052 else
1053 temp.func = &octusb_non_control_data_tx;
1054 }
1055
1056 /* setup "pc" pointer */
1057 temp.pc = xfer->frbuffers + x;
1058 }
1059 while (x != xfer->nframes) {
1060
1061 /* DATA0 or DATA1 message */
1062
1063 temp.len = xfer->frlengths[x];
1064
1065 x++;
1066
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;
1072 } else {
1073 temp.setup_alt_next = 0;
1074 }
1075 }
1076 if (temp.len == 0) {
1077
1078 /* make sure that we send an USB packet */
1079
1080 temp.short_pkt = 0;
1081
1082 } else {
1083
1084 /* regular data transfer */
1085
1086 temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
1087 }
1088
1089 octusb_setup_standard_chain_sub(&temp);
1090
1091 if (xfer->flags_int.isochronous_xfr) {
1092 /* get next data offset */
1093 temp.offset += temp.len;
1094 } else {
1095 /* get next Page Cache pointer */
1096 temp.pc = xfer->frbuffers + x;
1097 }
1098 }
1099
1100 /* check if we should append a status stage */
1101
1102 if (xfer->flags_int.control_xfr &&
1103 !xfer->flags_int.control_act) {
1104
1105 temp.func = &octusb_host_control_status_tx;
1106 temp.len = 0;
1107 temp.pc = NULL;
1108 temp.short_pkt = 0;
1109 temp.setup_alt_next = 0;
1110
1111 octusb_setup_standard_chain_sub(&temp);
1112 }
1113 /* must have at least one frame! */
1114 td = temp.td;
1115 xfer->td_transfer_last = td;
1116
1117 /* properly setup QH */
1118
1119 td->qh->ep_allocated = 0;
1120 td->qh->ep_toggle_next = xfer->endpoint->toggle_next ? 1 : 0;
1121 }
1122
1123 /*------------------------------------------------------------------------*
1124 * octusb_device_done - OCTUSB transfers done code
1125 *
1126 * NOTE: This function can be called more than one time in a row.
1127 *------------------------------------------------------------------------*/
1128 static void
1129 octusb_device_done(struct usb_xfer *xfer, usb_error_t error)
1130 {
1131 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1132
1133 DPRINTFN(2, "xfer=%p, endpoint=%p, error=%d\n",
1134 xfer, xfer->endpoint, error);
1135
1136 /*
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.
1140 */
1141 if ((xfer->flags_int.control_act == 0) || (error != 0)) {
1142 struct octusb_td *td;
1143
1144 td = xfer->td_start[0];
1145
1146 octusb_host_free_endpoint(td);
1147 }
1148 /* dequeue transfer and start next transfer */
1149 usbd_transfer_done(xfer, error);
1150 }
1151
1152 /*------------------------------------------------------------------------*
1153 * octusb bulk support
1154 *------------------------------------------------------------------------*/
1155 static void
1156 octusb_device_bulk_open(struct usb_xfer *xfer)
1157 {
1158 return;
1159 }
1160
1161 static void
1162 octusb_device_bulk_close(struct usb_xfer *xfer)
1163 {
1164 octusb_device_done(xfer, USB_ERR_CANCELLED);
1165 }
1166
1167 static void
1168 octusb_device_bulk_enter(struct usb_xfer *xfer)
1169 {
1170 return;
1171 }
1172
1173 static void
1174 octusb_device_bulk_start(struct usb_xfer *xfer)
1175 {
1176 /* setup TDs */
1177 octusb_setup_standard_chain(xfer);
1178 octusb_start_standard_chain(xfer);
1179 }
1180
1181 struct usb_pipe_methods octusb_device_bulk_methods =
1182 {
1183 .open = octusb_device_bulk_open,
1184 .close = octusb_device_bulk_close,
1185 .enter = octusb_device_bulk_enter,
1186 .start = octusb_device_bulk_start,
1187 };
1188
1189 /*------------------------------------------------------------------------*
1190 * octusb control support
1191 *------------------------------------------------------------------------*/
1192 static void
1193 octusb_device_ctrl_open(struct usb_xfer *xfer)
1194 {
1195 return;
1196 }
1197
1198 static void
1199 octusb_device_ctrl_close(struct usb_xfer *xfer)
1200 {
1201 octusb_device_done(xfer, USB_ERR_CANCELLED);
1202 }
1203
1204 static void
1205 octusb_device_ctrl_enter(struct usb_xfer *xfer)
1206 {
1207 return;
1208 }
1209
1210 static void
1211 octusb_device_ctrl_start(struct usb_xfer *xfer)
1212 {
1213 /* setup TDs */
1214 octusb_setup_standard_chain(xfer);
1215 octusb_start_standard_chain(xfer);
1216 }
1217
1218 struct usb_pipe_methods octusb_device_ctrl_methods =
1219 {
1220 .open = octusb_device_ctrl_open,
1221 .close = octusb_device_ctrl_close,
1222 .enter = octusb_device_ctrl_enter,
1223 .start = octusb_device_ctrl_start,
1224 };
1225
1226 /*------------------------------------------------------------------------*
1227 * octusb interrupt support
1228 *------------------------------------------------------------------------*/
1229 static void
1230 octusb_device_intr_open(struct usb_xfer *xfer)
1231 {
1232 return;
1233 }
1234
1235 static void
1236 octusb_device_intr_close(struct usb_xfer *xfer)
1237 {
1238 octusb_device_done(xfer, USB_ERR_CANCELLED);
1239 }
1240
1241 static void
1242 octusb_device_intr_enter(struct usb_xfer *xfer)
1243 {
1244 return;
1245 }
1246
1247 static void
1248 octusb_device_intr_start(struct usb_xfer *xfer)
1249 {
1250 /* setup TDs */
1251 octusb_setup_standard_chain(xfer);
1252 octusb_start_standard_chain(xfer);
1253 }
1254
1255 struct usb_pipe_methods octusb_device_intr_methods =
1256 {
1257 .open = octusb_device_intr_open,
1258 .close = octusb_device_intr_close,
1259 .enter = octusb_device_intr_enter,
1260 .start = octusb_device_intr_start,
1261 };
1262
1263 /*------------------------------------------------------------------------*
1264 * octusb isochronous support
1265 *------------------------------------------------------------------------*/
1266 static void
1267 octusb_device_isoc_open(struct usb_xfer *xfer)
1268 {
1269 return;
1270 }
1271
1272 static void
1273 octusb_device_isoc_close(struct usb_xfer *xfer)
1274 {
1275 octusb_device_done(xfer, USB_ERR_CANCELLED);
1276 }
1277
1278 static void
1279 octusb_device_isoc_enter(struct usb_xfer *xfer)
1280 {
1281 struct octusb_softc *sc = OCTUSB_BUS2SC(xfer->xroot->bus);
1282 uint32_t temp;
1283 uint32_t frame_count;
1284 uint32_t fs_frames;
1285
1286 DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
1287 xfer, xfer->endpoint->isoc_next, xfer->nframes);
1288
1289 /* get the current frame index */
1290
1291 frame_count = cvmx_usb_get_frame_number(
1292 &sc->sc_port[xfer->xroot->udev->port_index].state);
1293
1294 /*
1295 * check if the frame index is within the window where the frames
1296 * will be inserted
1297 */
1298 temp = (frame_count - xfer->endpoint->isoc_next) & 0x7FF;
1299
1300 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
1301 fs_frames = (xfer->nframes + 7) / 8;
1302 } else {
1303 fs_frames = xfer->nframes;
1304 }
1305
1306 if ((xfer->endpoint->is_synced == 0) || (temp < fs_frames)) {
1307 /*
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.
1312 */
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);
1316 }
1317 /*
1318 * compute how many milliseconds the insertion is ahead of the
1319 * current frame position:
1320 */
1321 temp = (xfer->endpoint->isoc_next - frame_count) & 0x7FF;
1322
1323 /*
1324 * pre-compute when the isochronous transfer will be finished:
1325 */
1326 xfer->isoc_time_complete =
1327 usb_isoc_time_expand(&sc->sc_bus, frame_count) + temp +
1328 fs_frames;
1329
1330 /* compute frame number for next insertion */
1331 xfer->endpoint->isoc_next += fs_frames;
1332 }
1333
1334 static void
1335 octusb_device_isoc_start(struct usb_xfer *xfer)
1336 {
1337 /* setup TDs */
1338 octusb_setup_standard_chain(xfer);
1339 octusb_start_standard_chain(xfer);
1340 }
1341
1342 struct usb_pipe_methods octusb_device_isoc_methods =
1343 {
1344 .open = octusb_device_isoc_open,
1345 .close = octusb_device_isoc_close,
1346 .enter = octusb_device_isoc_enter,
1347 .start = octusb_device_isoc_start,
1348 };
1349
1350 /*------------------------------------------------------------------------*
1351 * OCTUSB root HUB support
1352 *------------------------------------------------------------------------*
1353 * Simulate a hardware HUB by handling all the necessary requests.
1354 *------------------------------------------------------------------------*/
1355 static const
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,
1364 .idVendor = {0},
1365 .idProduct = {0},
1366 .bcdDevice = {0x00, 0x01},
1367 .iManufacturer = 1,
1368 .iProduct = 2,
1369 .iSerialNumber = 0,
1370 .bNumConfigurations = 1,
1371 };
1372
1373 static const
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,
1383 .bReserved = 0,
1384 };
1385
1386 static const
1387 struct octusb_config_desc octusb_confd = {
1388 .confd = {
1389 .bLength = sizeof(struct usb_config_descriptor),
1390 .bDescriptorType = UDESC_CONFIG,
1391 .wTotalLength[0] = sizeof(octusb_confd),
1392 .bNumInterface = 1,
1393 .bConfigurationValue = 1,
1394 .iConfiguration = 0,
1395 .bmAttributes = UC_SELF_POWERED,
1396 .bMaxPower = 0 /* max power */
1397 },
1398 .ifcd = {
1399 .bLength = sizeof(struct usb_interface_descriptor),
1400 .bDescriptorType = UDESC_INTERFACE,
1401 .bNumEndpoints = 1,
1402 .bInterfaceClass = UICLASS_HUB,
1403 .bInterfaceSubClass = UISUBCLASS_HUB,
1404 .bInterfaceProtocol = UIPROTO_FSHUB,
1405 },
1406 .endpd = {
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) */
1412 .bInterval = 255,
1413 },
1414 };
1415
1416 static const
1417 struct usb_hub_descriptor_min octusb_hubd =
1418 {
1419 .bDescLength = sizeof(octusb_hubd),
1420 .bDescriptorType = UDESC_HUB,
1421 .bNbrPorts = 2,
1422 .wHubCharacteristics = {UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0},
1423 .bPwrOn2PwrGood = 50,
1424 .bHubContrCurrent = 0,
1425 .DeviceRemovable = {0x00}, /* all ports are removable */
1426 };
1427
1428 static usb_error_t
1429 octusb_roothub_exec(struct usb_device *udev,
1430 struct usb_device_request *req, const void **pptr, uint16_t *plength)
1431 {
1432 struct octusb_softc *sc = OCTUSB_BUS2SC(udev->bus);
1433 const void *ptr;
1434 const char *str_ptr;
1435 uint16_t value;
1436 uint16_t index;
1437 uint16_t status;
1438 uint16_t change;
1439 uint16_t len;
1440 usb_error_t err;
1441 cvmx_usb_port_status_t usb_port_status;
1442
1443 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
1444
1445 /* XXX disable power save mode, hence it is not supported */
1446 udev->power_mode = USB_POWER_MODE_ON;
1447
1448 /* buffer reset */
1449 ptr = (const void *)&sc->sc_hub_desc.temp;
1450 len = 0;
1451 err = 0;
1452
1453 value = UGETW(req->wValue);
1454 index = UGETW(req->wIndex);
1455
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);
1460
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):
1466 break;
1467 case C(UR_GET_CONFIG, UT_READ_DEVICE):
1468 len = 1;
1469 sc->sc_hub_desc.temp[0] = sc->sc_conf;
1470 break;
1471 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
1472 switch (value >> 8) {
1473 case UDESC_DEVICE:
1474 if ((value & 0xff) != 0) {
1475 err = USB_ERR_IOERROR;
1476 goto done;
1477 }
1478 len = sizeof(octusb_devd);
1479
1480 ptr = (const void *)&octusb_devd;
1481 break;
1482
1483 case UDESC_DEVICE_QUALIFIER:
1484 if ((value & 0xff) != 0) {
1485 err = USB_ERR_IOERROR;
1486 goto done;
1487 }
1488 len = sizeof(octusb_odevd);
1489 ptr = (const void *)&octusb_odevd;
1490 break;
1491
1492 case UDESC_CONFIG:
1493 if ((value & 0xff) != 0) {
1494 err = USB_ERR_IOERROR;
1495 goto done;
1496 }
1497 len = sizeof(octusb_confd);
1498 ptr = (const void *)&octusb_confd;
1499 break;
1500
1501 case UDESC_STRING:
1502 switch (value & 0xff) {
1503 case 0: /* Language table */
1504 str_ptr = "\001";
1505 break;
1506
1507 case 1: /* Vendor */
1508 str_ptr = "Cavium Networks";
1509 break;
1510
1511 case 2: /* Product */
1512 str_ptr = "OCTUSB Root HUB";
1513 break;
1514
1515 default:
1516 str_ptr = "";
1517 break;
1518 }
1519
1520 len = usb_make_str_desc(sc->sc_hub_desc.temp,
1521 sizeof(sc->sc_hub_desc.temp), str_ptr);
1522 break;
1523
1524 default:
1525 err = USB_ERR_IOERROR;
1526 goto done;
1527 }
1528 break;
1529 case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
1530 len = 1;
1531 sc->sc_hub_desc.temp[0] = 0;
1532 break;
1533 case C(UR_GET_STATUS, UT_READ_DEVICE):
1534 len = 2;
1535 USETW(sc->sc_hub_desc.stat.wStatus, UDS_SELF_POWERED);
1536 break;
1537 case C(UR_GET_STATUS, UT_READ_INTERFACE):
1538 case C(UR_GET_STATUS, UT_READ_ENDPOINT):
1539 len = 2;
1540 USETW(sc->sc_hub_desc.stat.wStatus, 0);
1541 break;
1542 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
1543 if (value >= OCTUSB_MAX_DEVICES) {
1544 err = USB_ERR_IOERROR;
1545 goto done;
1546 }
1547 sc->sc_addr = value;
1548 break;
1549 case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
1550 if ((value != 0) && (value != 1)) {
1551 err = USB_ERR_IOERROR;
1552 goto done;
1553 }
1554 sc->sc_conf = value;
1555 break;
1556 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
1557 break;
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;
1562 goto done;
1563 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
1564 break;
1565 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
1566 break;
1567 /* Hub requests */
1568 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
1569 break;
1570 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
1571 DPRINTFN(4, "UR_CLEAR_PORT_FEATURE "
1572 "port=%d feature=%d\n",
1573 index, value);
1574 if ((index < 1) ||
1575 (index > sc->sc_noport) ||
1576 sc->sc_port[index - 1].disabled) {
1577 err = USB_ERR_IOERROR;
1578 goto done;
1579 }
1580 index--;
1581
1582 switch (value) {
1583 case UHF_PORT_ENABLE:
1584 cvmx_usb_disable(&sc->sc_port[index].state);
1585 break;
1586 case UHF_PORT_SUSPEND:
1587 case UHF_PORT_RESET:
1588 break;
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));
1592 break;
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));
1596 break;
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));
1600 break;
1601 case UHF_C_PORT_RESET:
1602 sc->sc_isreset = 0;
1603 goto done;
1604 case UHF_C_PORT_SUSPEND:
1605 break;
1606 case UHF_PORT_CONNECTION:
1607 case UHF_PORT_OVER_CURRENT:
1608 case UHF_PORT_POWER:
1609 case UHF_PORT_LOW_SPEED:
1610 default:
1611 err = USB_ERR_IOERROR;
1612 goto done;
1613 }
1614 break;
1615 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
1616 if ((value & 0xff) != 0) {
1617 err = USB_ERR_IOERROR;
1618 goto done;
1619 }
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;
1624 break;
1625 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
1626 len = 16;
1627 memset(sc->sc_hub_desc.temp, 0, 16);
1628 break;
1629 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
1630 if ((index < 1) ||
1631 (index > sc->sc_noport) ||
1632 sc->sc_port[index - 1].disabled) {
1633 err = USB_ERR_IOERROR;
1634 goto done;
1635 }
1636 index--;
1637
1638 usb_port_status = cvmx_usb_get_status(&sc->sc_port[index].state);
1639
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;
1649
1650 switch (usb_port_status.port_speed) {
1651 case CVMX_USB_SPEED_HIGH:
1652 status |= UPS_HIGH_SPEED;
1653 break;
1654 case CVMX_USB_SPEED_FULL:
1655 break;
1656 default:
1657 status |= UPS_LOW_SPEED;
1658 break;
1659 }
1660
1661 if (usb_port_status.connect_change)
1662 change |= UPS_C_CONNECT_STATUS;
1663 if (sc->sc_isreset)
1664 change |= UPS_C_PORT_RESET;
1665
1666 USETW(sc->sc_hub_desc.ps.wPortStatus, status);
1667 USETW(sc->sc_hub_desc.ps.wPortChange, change);
1668
1669 len = sizeof(sc->sc_hub_desc.ps);
1670 break;
1671 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
1672 err = USB_ERR_IOERROR;
1673 goto done;
1674 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
1675 break;
1676 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
1677 if ((index < 1) ||
1678 (index > sc->sc_noport) ||
1679 sc->sc_port[index - 1].disabled) {
1680 err = USB_ERR_IOERROR;
1681 goto done;
1682 }
1683 index--;
1684
1685 switch (value) {
1686 case UHF_PORT_ENABLE:
1687 break;
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;
1692 goto done;
1693 }
1694 sc->sc_isreset = 1;
1695 goto done;
1696 case UHF_PORT_POWER:
1697 /* pretend we turned on power */
1698 goto done;
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:
1708 default:
1709 err = USB_ERR_IOERROR;
1710 goto done;
1711 }
1712 break;
1713 default:
1714 err = USB_ERR_IOERROR;
1715 goto done;
1716 }
1717 done:
1718 *plength = len;
1719 *pptr = ptr;
1720 return (err);
1721 }
1722
1723 static void
1724 octusb_xfer_setup(struct usb_setup_params *parm)
1725 {
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;
1732 void *last_obj;
1733 uint32_t n;
1734 uint32_t ntd;
1735
1736 sc = OCTUSB_BUS2SC(parm->udev->bus);
1737 xfer = parm->curr_xfer;
1738 qh = NULL;
1739
1740 /*
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:
1744 */
1745
1746 parm->hc_max_packet_size = 0x400;
1747 parm->hc_max_packet_count = 3;
1748 parm->hc_max_frame_size = 0xC00;
1749
1750 usbd_transfer_setup_sub(parm);
1751
1752 if (parm->err)
1753 return;
1754
1755 /* Allocate a queue head */
1756
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;
1761 return;
1762 }
1763 if (parm->buf) {
1764 usbd_get_page(pc, 0, &page_info);
1765
1766 qh = page_info.buffer;
1767
1768 /* fill out QH */
1769
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;
1783 }
1784
1785 switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
1786 case UE_INTERRUPT:
1787 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH)
1788 qh->ep_interval = xfer->interval * 8;
1789 else
1790 qh->ep_interval = xfer->interval * 1;
1791 break;
1792 case UE_ISOCHRONOUS:
1793 qh->ep_interval = 1 << xfer->fps_shift;
1794 break;
1795 default:
1796 qh->ep_interval = 0;
1797 break;
1798 }
1799
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;
1803 }
1804 xfer->qh_start[0] = qh;
1805
1806 /* Allocate a fixup buffer */
1807
1808 if (usbd_transfer_setup_sub_malloc(
1809 parm, &pc, OCTUSB_MAX_FIXUP,
1810 OCTUSB_MAX_FIXUP, 1)) {
1811 parm->err = USB_ERR_NOMEM;
1812 return;
1813 }
1814 if (parm->buf) {
1815 usbd_get_page(pc, 0, &page_info);
1816
1817 qh->fixup_phys = page_info.physaddr;
1818 qh->fixup_pc = pc;
1819 qh->fixup_buf = page_info.buffer;
1820 }
1821 /* Allocate transfer descriptors */
1822
1823 last_obj = NULL;
1824
1825 ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
1826
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;
1831 return;
1832 }
1833 if (parm->buf) {
1834 for (n = 0; n != ntd; n++) {
1835 struct octusb_td *td;
1836
1837 usbd_get_page(pc + n, 0, &page_info);
1838
1839 td = page_info.buffer;
1840
1841 td->qh = qh;
1842 td->obj_next = last_obj;
1843
1844 last_obj = td;
1845 }
1846 }
1847 xfer->td_start[0] = last_obj;
1848 }
1849
1850 static void
1851 octusb_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
1852 struct usb_endpoint *ep)
1853 {
1854 struct octusb_softc *sc = OCTUSB_BUS2SC(udev->bus);
1855
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);
1859
1860 if (udev->device_index != sc->sc_addr) {
1861 switch (edesc->bmAttributes & UE_XFERTYPE) {
1862 case UE_CONTROL:
1863 ep->methods = &octusb_device_ctrl_methods;
1864 break;
1865 case UE_INTERRUPT:
1866 ep->methods = &octusb_device_intr_methods;
1867 break;
1868 case UE_ISOCHRONOUS:
1869 if (udev->speed != USB_SPEED_LOW)
1870 ep->methods = &octusb_device_isoc_methods;
1871 break;
1872 case UE_BULK:
1873 ep->methods = &octusb_device_bulk_methods;
1874 break;
1875 default:
1876 /* do nothing */
1877 break;
1878 }
1879 }
1880 }
1881
1882 static void
1883 octusb_xfer_unsetup(struct usb_xfer *xfer)
1884 {
1885 DPRINTF("Nothing to do.\n");
1886 }
1887
1888 static void
1889 octusb_get_dma_delay(struct usb_device *udev, uint32_t *pus)
1890 {
1891 /* DMA delay - wait until any use of memory is finished */
1892 *pus = (2125); /* microseconds */
1893 }
1894
1895 static void
1896 octusb_device_resume(struct usb_device *udev)
1897 {
1898 DPRINTF("Nothing to do.\n");
1899 }
1900
1901 static void
1902 octusb_device_suspend(struct usb_device *udev)
1903 {
1904 DPRINTF("Nothing to do.\n");
1905 }
1906
1907 static void
1908 octusb_set_hw_power(struct usb_bus *bus)
1909 {
1910 DPRINTF("Nothing to do.\n");
1911 }
1912
1913 static void
1914 octusb_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
1915 {
1916 struct octusb_softc *sc = OCTUSB_BUS2SC(bus);
1917
1918 switch (state) {
1919 case USB_HW_POWER_SUSPEND:
1920 octusb_suspend(sc);
1921 break;
1922 case USB_HW_POWER_SHUTDOWN:
1923 octusb_uninit(sc);
1924 break;
1925 case USB_HW_POWER_RESUME:
1926 octusb_resume(sc);
1927 break;
1928 default:
1929 break;
1930 }
1931 }
1932
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,
1944 };
Cache object: fb701b2b3ceffd5769385cdc11e3941b
|