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