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