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