xref: /freebsd/sys/dev/usb/controller/uss820dci.c (revision d2b2128a286a00ee53d79cb88b4e59bf42525cf9)
1 /* $FreeBSD$ */
2 /*-
3  * Copyright (c) 2008 Hans Petter Selasky <hselasky@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 /*
29  * This file contains the driver for the USS820 series USB Device
30  * Controller
31  *
32  * NOTE: The datasheet does not document everything!
33  */
34 
35 #include <dev/usb/usb.h>
36 #include <dev/usb/usb_mfunc.h>
37 #include <dev/usb/usb_revision.h>
38 #include <dev/usb/usb_error.h>
39 
40 #define	USB_DEBUG_VAR uss820dcidebug
41 
42 #include <dev/usb/usb_core.h>
43 #include <dev/usb/usb_debug.h>
44 #include <dev/usb/usb_busdma.h>
45 #include <dev/usb/usb_process.h>
46 #include <dev/usb/usb_sw_transfer.h>
47 #include <dev/usb/usb_transfer.h>
48 #include <dev/usb/usb_device.h>
49 #include <dev/usb/usb_hub.h>
50 #include <dev/usb/usb_util.h>
51 
52 #include <dev/usb/usb_controller.h>
53 #include <dev/usb/usb_bus.h>
54 #include <dev/usb/controller/uss820dci.h>
55 
56 #define	USS820_DCI_BUS2SC(bus) \
57    ((struct uss820dci_softc *)(((uint8_t *)(bus)) - \
58     ((uint8_t *)&(((struct uss820dci_softc *)0)->sc_bus))))
59 
60 #define	USS820_DCI_PC2SC(pc) \
61    USS820_DCI_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus)
62 
63 #if USB_DEBUG
64 static int uss820dcidebug = 0;
65 
66 SYSCTL_NODE(_hw_usb2, OID_AUTO, uss820dci, CTLFLAG_RW, 0, "USB uss820dci");
67 SYSCTL_INT(_hw_usb2_uss820dci, OID_AUTO, debug, CTLFLAG_RW,
68     &uss820dcidebug, 0, "uss820dci debug level");
69 #endif
70 
71 #define	USS820_DCI_INTR_ENDPT 1
72 
73 /* prototypes */
74 
75 struct usb2_bus_methods uss820dci_bus_methods;
76 struct usb2_pipe_methods uss820dci_device_bulk_methods;
77 struct usb2_pipe_methods uss820dci_device_ctrl_methods;
78 struct usb2_pipe_methods uss820dci_device_intr_methods;
79 struct usb2_pipe_methods uss820dci_device_isoc_fs_methods;
80 struct usb2_pipe_methods uss820dci_root_ctrl_methods;
81 struct usb2_pipe_methods uss820dci_root_intr_methods;
82 
83 static uss820dci_cmd_t uss820dci_setup_rx;
84 static uss820dci_cmd_t uss820dci_data_rx;
85 static uss820dci_cmd_t uss820dci_data_tx;
86 static uss820dci_cmd_t uss820dci_data_tx_sync;
87 static void	uss820dci_device_done(struct usb2_xfer *, usb2_error_t);
88 static void	uss820dci_do_poll(struct usb2_bus *);
89 static void	uss820dci_root_ctrl_poll(struct uss820dci_softc *);
90 static void	uss820dci_standard_done(struct usb2_xfer *);
91 static void	uss820dci_intr_set(struct usb2_xfer *, uint8_t);
92 static void	uss820dci_update_shared_1(struct uss820dci_softc *, uint8_t,
93 		    uint8_t, uint8_t);
94 
95 static usb2_sw_transfer_func_t uss820dci_root_intr_done;
96 static usb2_sw_transfer_func_t uss820dci_root_ctrl_done;
97 
98 /*
99  * Here is a list of what the USS820D chip can support. The main
100  * limitation is that the sum of the buffer sizes must be less than
101  * 1120 bytes.
102  */
103 static const struct usb2_hw_ep_profile
104 	uss820dci_ep_profile[] = {
105 
106 	[0] = {
107 		.max_in_frame_size = 32,
108 		.max_out_frame_size = 32,
109 		.is_simplex = 0,
110 		.support_control = 1,
111 	},
112 	[1] = {
113 		.max_in_frame_size = 64,
114 		.max_out_frame_size = 64,
115 		.is_simplex = 0,
116 		.support_multi_buffer = 1,
117 		.support_bulk = 1,
118 		.support_interrupt = 1,
119 		.support_in = 1,
120 		.support_out = 1,
121 	},
122 	[2] = {
123 		.max_in_frame_size = 8,
124 		.max_out_frame_size = 8,
125 		.is_simplex = 0,
126 		.support_multi_buffer = 1,
127 		.support_bulk = 1,
128 		.support_interrupt = 1,
129 		.support_in = 1,
130 		.support_out = 1,
131 	},
132 	[3] = {
133 		.max_in_frame_size = 256,
134 		.max_out_frame_size = 256,
135 		.is_simplex = 0,
136 		.support_multi_buffer = 1,
137 		.support_isochronous = 1,
138 		.support_in = 1,
139 		.support_out = 1,
140 	},
141 };
142 
143 static void
144 uss820dci_update_shared_1(struct uss820dci_softc *sc, uint8_t reg,
145     uint8_t keep_mask, uint8_t set_mask)
146 {
147 	uint8_t temp;
148 
149 	USS820_WRITE_1(sc, USS820_PEND, 1);
150 	temp = USS820_READ_1(sc, reg);
151 	temp &= (keep_mask);
152 	temp |= (set_mask);
153 	USS820_WRITE_1(sc, reg, temp);
154 	USS820_WRITE_1(sc, USS820_PEND, 0);
155 }
156 
157 static void
158 uss820dci_get_hw_ep_profile(struct usb2_device *udev,
159     const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr)
160 {
161 	if (ep_addr == 0) {
162 		*ppf = uss820dci_ep_profile + 0;
163 	} else if (ep_addr < 5) {
164 		*ppf = uss820dci_ep_profile + 1;
165 	} else if (ep_addr < 7) {
166 		*ppf = uss820dci_ep_profile + 2;
167 	} else if (ep_addr == 7) {
168 		*ppf = uss820dci_ep_profile + 3;
169 	} else {
170 		*ppf = NULL;
171 	}
172 }
173 
174 static void
175 uss820dci_pull_up(struct uss820dci_softc *sc)
176 {
177 	uint8_t temp;
178 
179 	/* pullup D+, if possible */
180 
181 	if (!sc->sc_flags.d_pulled_up &&
182 	    sc->sc_flags.port_powered) {
183 		sc->sc_flags.d_pulled_up = 1;
184 
185 		DPRINTF("\n");
186 
187 		temp = USS820_READ_1(sc, USS820_MCSR);
188 		temp |= USS820_MCSR_DPEN;
189 		USS820_WRITE_1(sc, USS820_MCSR, temp);
190 	}
191 }
192 
193 static void
194 uss820dci_pull_down(struct uss820dci_softc *sc)
195 {
196 	uint8_t temp;
197 
198 	/* pulldown D+, if possible */
199 
200 	if (sc->sc_flags.d_pulled_up) {
201 		sc->sc_flags.d_pulled_up = 0;
202 
203 		DPRINTF("\n");
204 
205 		temp = USS820_READ_1(sc, USS820_MCSR);
206 		temp &= ~USS820_MCSR_DPEN;
207 		USS820_WRITE_1(sc, USS820_MCSR, temp);
208 	}
209 }
210 
211 static void
212 uss820dci_wakeup_peer(struct uss820dci_softc *sc)
213 {
214 	if (!(sc->sc_flags.status_suspend)) {
215 		return;
216 	}
217 	DPRINTFN(0, "not supported\n");
218 }
219 
220 static void
221 uss820dci_set_address(struct uss820dci_softc *sc, uint8_t addr)
222 {
223 	DPRINTFN(5, "addr=%d\n", addr);
224 
225 	USS820_WRITE_1(sc, USS820_FADDR, addr);
226 }
227 
228 static uint8_t
229 uss820dci_setup_rx(struct uss820dci_td *td)
230 {
231 	struct uss820dci_softc *sc;
232 	struct usb2_device_request req;
233 	uint16_t count;
234 	uint8_t rx_stat;
235 	uint8_t temp;
236 
237 	/* select the correct endpoint */
238 	bus_space_write_1(td->io_tag, td->io_hdl,
239 	    td->ep_reg, td->ep_index);
240 
241 	/* read out FIFO status */
242 	rx_stat = bus_space_read_1(td->io_tag, td->io_hdl,
243 	    td->rx_stat_reg);
244 
245 	/* get pointer to softc */
246 	sc = USS820_DCI_PC2SC(td->pc);
247 
248 	DPRINTFN(5, "rx_stat=0x%02x rem=%u\n", rx_stat, td->remainder);
249 
250 	if (!(rx_stat & USS820_RXSTAT_RXSETUP)) {
251 		/* abort any ongoing transfer */
252 		if (!td->did_stall) {
253 			DPRINTFN(5, "stalling\n");
254 
255 			/* set stall */
256 
257 			uss820dci_update_shared_1(sc, USS820_EPCON, 0xFF,
258 			    (USS820_EPCON_TXSTL | USS820_EPCON_RXSTL));
259 
260 			td->did_stall = 1;
261 		}
262 		goto not_complete;
263 	}
264 	/* clear stall and all I/O */
265 	uss820dci_update_shared_1(sc, USS820_EPCON,
266 	    0xFF ^ (USS820_EPCON_TXSTL |
267 	    USS820_EPCON_RXSTL |
268 	    USS820_EPCON_RXIE |
269 	    USS820_EPCON_TXOE), 0);
270 
271 	/* clear end overwrite flag */
272 	uss820dci_update_shared_1(sc, USS820_RXSTAT,
273 	    0xFF ^ USS820_RXSTAT_EDOVW, 0);
274 
275 	/* get the packet byte count */
276 	count = bus_space_read_1(td->io_tag, td->io_hdl,
277 	    td->rx_count_low_reg);
278 	count |= (bus_space_read_1(td->io_tag, td->io_hdl,
279 	    td->rx_count_high_reg) << 8);
280 	count &= 0x3FF;
281 
282 	/* verify data length */
283 	if (count != td->remainder) {
284 		DPRINTFN(0, "Invalid SETUP packet "
285 		    "length, %d bytes\n", count);
286 		goto not_complete;
287 	}
288 	if (count != sizeof(req)) {
289 		DPRINTFN(0, "Unsupported SETUP packet "
290 		    "length, %d bytes\n", count);
291 		goto not_complete;
292 	}
293 	/* receive data */
294 	bus_space_read_multi_1(td->io_tag, td->io_hdl,
295 	    td->rx_fifo_reg, (void *)&req, sizeof(req));
296 
297 	/* read out FIFO status */
298 	rx_stat = bus_space_read_1(td->io_tag, td->io_hdl,
299 	    td->rx_stat_reg);
300 
301 	if (rx_stat & (USS820_RXSTAT_EDOVW |
302 	    USS820_RXSTAT_STOVW)) {
303 		DPRINTF("new SETUP packet received\n");
304 		return (1);		/* not complete */
305 	}
306 	/* clear receive setup bit */
307 	uss820dci_update_shared_1(sc, USS820_RXSTAT,
308 	    0xFF ^ (USS820_RXSTAT_RXSETUP |
309 	    USS820_RXSTAT_EDOVW |
310 	    USS820_RXSTAT_STOVW), 0);
311 
312 	/* set RXFFRC bit */
313 	temp = bus_space_read_1(td->io_tag, td->io_hdl,
314 	    td->rx_cntl_reg);
315 	temp |= USS820_RXCON_RXFFRC;
316 	bus_space_write_1(td->io_tag, td->io_hdl,
317 	    td->rx_cntl_reg, temp);
318 
319 	/* copy data into real buffer */
320 	usb2_copy_in(td->pc, 0, &req, sizeof(req));
321 
322 	td->offset = sizeof(req);
323 	td->remainder = 0;
324 
325 	/* sneak peek the set address */
326 	if ((req.bmRequestType == UT_WRITE_DEVICE) &&
327 	    (req.bRequest == UR_SET_ADDRESS)) {
328 		sc->sc_dv_addr = req.wValue[0] & 0x7F;
329 	} else {
330 		sc->sc_dv_addr = 0xFF;
331 	}
332 	return (0);			/* complete */
333 
334 not_complete:
335 	/* clear end overwrite flag, if any */
336 	if (rx_stat & USS820_RXSTAT_RXSETUP) {
337 		uss820dci_update_shared_1(sc, USS820_RXSTAT,
338 		    0xFF ^ (USS820_RXSTAT_EDOVW |
339 		    USS820_RXSTAT_STOVW |
340 		    USS820_RXSTAT_RXSETUP), 0);
341 	}
342 	return (1);			/* not complete */
343 
344 }
345 
346 static uint8_t
347 uss820dci_data_rx(struct uss820dci_td *td)
348 {
349 	struct usb2_page_search buf_res;
350 	uint16_t count;
351 	uint8_t rx_flag;
352 	uint8_t rx_stat;
353 	uint8_t rx_cntl;
354 	uint8_t to;
355 	uint8_t got_short;
356 
357 	to = 2;				/* don't loop forever! */
358 	got_short = 0;
359 
360 	/* select the correct endpoint */
361 	bus_space_write_1(td->io_tag, td->io_hdl, td->ep_reg, td->ep_index);
362 
363 	/* check if any of the FIFO banks have data */
364 repeat:
365 	/* read out FIFO flag */
366 	rx_flag = bus_space_read_1(td->io_tag, td->io_hdl,
367 	    td->rx_flag_reg);
368 	/* read out FIFO status */
369 	rx_stat = bus_space_read_1(td->io_tag, td->io_hdl,
370 	    td->rx_stat_reg);
371 
372 	DPRINTFN(5, "rx_stat=0x%02x rx_flag=0x%02x rem=%u\n",
373 	    rx_stat, rx_flag, td->remainder);
374 
375 	if (rx_stat & (USS820_RXSTAT_RXSETUP |
376 	    USS820_RXSTAT_RXSOVW |
377 	    USS820_RXSTAT_EDOVW)) {
378 		if (td->remainder == 0) {
379 			/*
380 			 * We are actually complete and have
381 			 * received the next SETUP
382 			 */
383 			DPRINTFN(5, "faking complete\n");
384 			return (0);	/* complete */
385 		}
386 		/*
387 	         * USB Host Aborted the transfer.
388 	         */
389 		td->error = 1;
390 		return (0);		/* complete */
391 	}
392 	/* check for errors */
393 	if (rx_flag & (USS820_RXFLG_RXOVF |
394 	    USS820_RXFLG_RXURF)) {
395 		DPRINTFN(5, "overflow or underflow\n");
396 		/* should not happen */
397 		td->error = 1;
398 		return (0);		/* complete */
399 	}
400 	/* check status */
401 	if (!(rx_flag & (USS820_RXFLG_RXFIF0 |
402 	    USS820_RXFLG_RXFIF1))) {
403 
404 		/* read out EPCON register */
405 		/* enable RX input */
406 		if (!td->did_stall) {
407 			uss820dci_update_shared_1(USS820_DCI_PC2SC(td->pc),
408 			    USS820_EPCON, 0xFF, USS820_EPCON_RXIE);
409 			td->did_stall = 1;
410 		}
411 		return (1);		/* not complete */
412 	}
413 	/* get the packet byte count */
414 	count = bus_space_read_1(td->io_tag, td->io_hdl,
415 	    td->rx_count_low_reg);
416 
417 	count |= (bus_space_read_1(td->io_tag, td->io_hdl,
418 	    td->rx_count_high_reg) << 8);
419 	count &= 0x3FF;
420 
421 	DPRINTFN(5, "count=0x%04x\n", count);
422 
423 	/* verify the packet byte count */
424 	if (count != td->max_packet_size) {
425 		if (count < td->max_packet_size) {
426 			/* we have a short packet */
427 			td->short_pkt = 1;
428 			got_short = 1;
429 		} else {
430 			/* invalid USB packet */
431 			td->error = 1;
432 			return (0);	/* we are complete */
433 		}
434 	}
435 	/* verify the packet byte count */
436 	if (count > td->remainder) {
437 		/* invalid USB packet */
438 		td->error = 1;
439 		return (0);		/* we are complete */
440 	}
441 	while (count > 0) {
442 		usb2_get_page(td->pc, td->offset, &buf_res);
443 
444 		/* get correct length */
445 		if (buf_res.length > count) {
446 			buf_res.length = count;
447 		}
448 		/* receive data */
449 		bus_space_read_multi_1(td->io_tag, td->io_hdl,
450 		    td->rx_fifo_reg, buf_res.buffer, buf_res.length);
451 
452 		/* update counters */
453 		count -= buf_res.length;
454 		td->offset += buf_res.length;
455 		td->remainder -= buf_res.length;
456 	}
457 
458 	/* set RXFFRC bit */
459 	rx_cntl = bus_space_read_1(td->io_tag, td->io_hdl,
460 	    td->rx_cntl_reg);
461 	rx_cntl |= USS820_RXCON_RXFFRC;
462 	bus_space_write_1(td->io_tag, td->io_hdl,
463 	    td->rx_cntl_reg, rx_cntl);
464 
465 	/* check if we are complete */
466 	if ((td->remainder == 0) || got_short) {
467 		if (td->short_pkt) {
468 			/* we are complete */
469 			return (0);
470 		}
471 		/* else need to receive a zero length packet */
472 	}
473 	if (--to) {
474 		goto repeat;
475 	}
476 	return (1);			/* not complete */
477 }
478 
479 static uint8_t
480 uss820dci_data_tx(struct uss820dci_td *td)
481 {
482 	struct usb2_page_search buf_res;
483 	uint16_t count;
484 	uint16_t count_copy;
485 	uint8_t rx_stat;
486 	uint8_t tx_flag;
487 	uint8_t to;
488 
489 	/* select the correct endpoint */
490 	bus_space_write_1(td->io_tag, td->io_hdl,
491 	    td->ep_reg, td->ep_index);
492 
493 	to = 2;				/* don't loop forever! */
494 
495 repeat:
496 	/* read out TX FIFO flags */
497 	tx_flag = bus_space_read_1(td->io_tag, td->io_hdl,
498 	    td->tx_flag_reg);
499 
500 	/* read out RX FIFO status last */
501 	rx_stat = bus_space_read_1(td->io_tag, td->io_hdl,
502 	    td->rx_stat_reg);
503 
504 	DPRINTFN(5, "rx_stat=0x%02x tx_flag=0x%02x rem=%u\n",
505 	    rx_stat, tx_flag, td->remainder);
506 
507 	if (rx_stat & (USS820_RXSTAT_RXSETUP |
508 	    USS820_RXSTAT_RXSOVW |
509 	    USS820_RXSTAT_EDOVW)) {
510 		/*
511 	         * The current transfer was aborted
512 	         * by the USB Host
513 	         */
514 		td->error = 1;
515 		return (0);		/* complete */
516 	}
517 	if (tx_flag & (USS820_TXFLG_TXOVF |
518 	    USS820_TXFLG_TXURF)) {
519 		td->error = 1;
520 		return (0);		/* complete */
521 	}
522 	if (tx_flag & USS820_TXFLG_TXFIF0) {
523 		if (tx_flag & USS820_TXFLG_TXFIF1) {
524 			return (1);	/* not complete */
525 		}
526 	}
527 	if ((!td->support_multi_buffer) &&
528 	    (tx_flag & (USS820_TXFLG_TXFIF0 |
529 	    USS820_TXFLG_TXFIF1))) {
530 		return (1);		/* not complete */
531 	}
532 	count = td->max_packet_size;
533 	if (td->remainder < count) {
534 		/* we have a short packet */
535 		td->short_pkt = 1;
536 		count = td->remainder;
537 	}
538 	count_copy = count;
539 	while (count > 0) {
540 
541 		usb2_get_page(td->pc, td->offset, &buf_res);
542 
543 		/* get correct length */
544 		if (buf_res.length > count) {
545 			buf_res.length = count;
546 		}
547 		/* transmit data */
548 		bus_space_write_multi_1(td->io_tag, td->io_hdl,
549 		    td->tx_fifo_reg, buf_res.buffer, buf_res.length);
550 
551 		/* update counters */
552 		count -= buf_res.length;
553 		td->offset += buf_res.length;
554 		td->remainder -= buf_res.length;
555 	}
556 
557 	/* post-write high packet byte count first */
558 	bus_space_write_1(td->io_tag, td->io_hdl,
559 	    td->tx_count_high_reg, count_copy >> 8);
560 
561 	/* post-write low packet byte count last */
562 	bus_space_write_1(td->io_tag, td->io_hdl,
563 	    td->tx_count_low_reg, count_copy);
564 
565 	/*
566 	 * Enable TX output, which must happen after that we have written
567 	 * data into the FIFO. This is undocumented.
568 	 */
569 	if (!td->did_stall) {
570 		uss820dci_update_shared_1(USS820_DCI_PC2SC(td->pc),
571 		    USS820_EPCON, 0xFF, USS820_EPCON_TXOE);
572 		td->did_stall = 1;
573 	}
574 	/* check remainder */
575 	if (td->remainder == 0) {
576 		if (td->short_pkt) {
577 			return (0);	/* complete */
578 		}
579 		/* else we need to transmit a short packet */
580 	}
581 	if (--to) {
582 		goto repeat;
583 	}
584 	return (1);			/* not complete */
585 }
586 
587 static uint8_t
588 uss820dci_data_tx_sync(struct uss820dci_td *td)
589 {
590 	struct uss820dci_softc *sc;
591 	uint8_t rx_stat;
592 	uint8_t tx_flag;
593 
594 	/* select the correct endpoint */
595 	bus_space_write_1(td->io_tag, td->io_hdl,
596 	    td->ep_reg, td->ep_index);
597 
598 	/* read out TX FIFO flag */
599 	tx_flag = bus_space_read_1(td->io_tag, td->io_hdl,
600 	    td->tx_flag_reg);
601 
602 	/* read out RX FIFO status last */
603 	rx_stat = bus_space_read_1(td->io_tag, td->io_hdl,
604 	    td->rx_stat_reg);
605 
606 	DPRINTFN(5, "rx_stat=0x%02x rem=%u\n", rx_stat, td->remainder);
607 
608 	if (rx_stat & (USS820_RXSTAT_RXSETUP |
609 	    USS820_RXSTAT_RXSOVW |
610 	    USS820_RXSTAT_EDOVW)) {
611 		DPRINTFN(5, "faking complete\n");
612 		/* Race condition */
613 		return (0);		/* complete */
614 	}
615 	DPRINTFN(5, "tx_flag=0x%02x rem=%u\n",
616 	    tx_flag, td->remainder);
617 
618 	if (tx_flag & (USS820_TXFLG_TXOVF |
619 	    USS820_TXFLG_TXURF)) {
620 		td->error = 1;
621 		return (0);		/* complete */
622 	}
623 	if (tx_flag & (USS820_TXFLG_TXFIF0 |
624 	    USS820_TXFLG_TXFIF1)) {
625 		return (1);		/* not complete */
626 	}
627 	sc = USS820_DCI_PC2SC(td->pc);
628 	if (sc->sc_dv_addr != 0xFF) {
629 		/* write function address */
630 		uss820dci_set_address(sc, sc->sc_dv_addr);
631 	}
632 	return (0);			/* complete */
633 }
634 
635 static uint8_t
636 uss820dci_xfer_do_fifo(struct usb2_xfer *xfer)
637 {
638 	struct uss820dci_td *td;
639 
640 	DPRINTFN(9, "\n");
641 
642 	td = xfer->td_transfer_cache;
643 	while (1) {
644 		if ((td->func) (td)) {
645 			/* operation in progress */
646 			break;
647 		}
648 		if (((void *)td) == xfer->td_transfer_last) {
649 			goto done;
650 		}
651 		if (td->error) {
652 			goto done;
653 		} else if (td->remainder > 0) {
654 			/*
655 			 * We had a short transfer. If there is no alternate
656 			 * next, stop processing !
657 			 */
658 			if (!td->alt_next) {
659 				goto done;
660 			}
661 		}
662 		/*
663 		 * Fetch the next transfer descriptor.
664 		 */
665 		td = td->obj_next;
666 		xfer->td_transfer_cache = td;
667 	}
668 	return (1);			/* not complete */
669 
670 done:
671 	/* compute all actual lengths */
672 
673 	uss820dci_standard_done(xfer);
674 
675 	return (0);			/* complete */
676 }
677 
678 static void
679 uss820dci_interrupt_poll(struct uss820dci_softc *sc)
680 {
681 	struct usb2_xfer *xfer;
682 
683 repeat:
684 	TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
685 		if (!uss820dci_xfer_do_fifo(xfer)) {
686 			/* queue has been modified */
687 			goto repeat;
688 		}
689 	}
690 }
691 
692 static void
693 uss820dci_wait_suspend(struct uss820dci_softc *sc, uint8_t on)
694 {
695 	uint8_t scr;
696 	uint8_t scratch;
697 
698 	scr = USS820_READ_1(sc, USS820_SCR);
699 	scratch = USS820_READ_1(sc, USS820_SCRATCH);
700 
701 	if (on) {
702 		scr |= USS820_SCR_IE_SUSP;
703 		scratch &= ~USS820_SCRATCH_IE_RESUME;
704 	} else {
705 		scr &= ~USS820_SCR_IE_SUSP;
706 		scratch |= USS820_SCRATCH_IE_RESUME;
707 	}
708 
709 	USS820_WRITE_1(sc, USS820_SCR, scr);
710 	USS820_WRITE_1(sc, USS820_SCRATCH, scratch);
711 }
712 
713 void
714 uss820dci_interrupt(struct uss820dci_softc *sc)
715 {
716 	uint8_t ssr;
717 	uint8_t event;
718 
719 	USB_BUS_LOCK(&sc->sc_bus);
720 
721 	ssr = USS820_READ_1(sc, USS820_SSR);
722 
723 	ssr &= (USS820_SSR_SUSPEND |
724 	    USS820_SSR_RESUME |
725 	    USS820_SSR_RESET);
726 
727 	/* acknowledge all interrupts */
728 
729 	uss820dci_update_shared_1(sc, USS820_SSR, 0, 0);
730 
731 	/* check for any bus state change interrupts */
732 
733 	if (ssr) {
734 
735 		event = 0;
736 
737 		if (ssr & USS820_SSR_RESET) {
738 			sc->sc_flags.status_bus_reset = 1;
739 			sc->sc_flags.status_suspend = 0;
740 			sc->sc_flags.change_suspend = 0;
741 			sc->sc_flags.change_connect = 1;
742 
743 			/* disable resume interrupt */
744 			uss820dci_wait_suspend(sc, 1);
745 
746 			event = 1;
747 		}
748 		/*
749 	         * If "RESUME" and "SUSPEND" is set at the same time
750 	         * we interpret that like "RESUME". Resume is set when
751 	         * there is at least 3 milliseconds of inactivity on
752 	         * the USB BUS.
753 	         */
754 		if (ssr & USS820_SSR_RESUME) {
755 			if (sc->sc_flags.status_suspend) {
756 				sc->sc_flags.status_suspend = 0;
757 				sc->sc_flags.change_suspend = 1;
758 				/* disable resume interrupt */
759 				uss820dci_wait_suspend(sc, 1);
760 				event = 1;
761 			}
762 		} else if (ssr & USS820_SSR_SUSPEND) {
763 			if (!sc->sc_flags.status_suspend) {
764 				sc->sc_flags.status_suspend = 1;
765 				sc->sc_flags.change_suspend = 1;
766 				/* enable resume interrupt */
767 				uss820dci_wait_suspend(sc, 0);
768 				event = 1;
769 			}
770 		}
771 		if (event) {
772 
773 			DPRINTF("real bus interrupt 0x%02x\n", ssr);
774 
775 			/* complete root HUB interrupt endpoint */
776 
777 			usb2_sw_transfer(&sc->sc_root_intr,
778 			    &uss820dci_root_intr_done);
779 		}
780 	}
781 	/* acknowledge all SBI interrupts */
782 	uss820dci_update_shared_1(sc, USS820_SBI, 0, 0);
783 
784 	/* acknowledge all SBI1 interrupts */
785 	uss820dci_update_shared_1(sc, USS820_SBI1, 0, 0);
786 
787 	/* poll all active transfers */
788 	uss820dci_interrupt_poll(sc);
789 
790 	USB_BUS_UNLOCK(&sc->sc_bus);
791 }
792 
793 static void
794 uss820dci_setup_standard_chain_sub(struct uss820_std_temp *temp)
795 {
796 	struct uss820dci_td *td;
797 
798 	/* get current Transfer Descriptor */
799 	td = temp->td_next;
800 	temp->td = td;
801 
802 	/* prepare for next TD */
803 	temp->td_next = td->obj_next;
804 
805 	/* fill out the Transfer Descriptor */
806 	td->func = temp->func;
807 	td->pc = temp->pc;
808 	td->offset = temp->offset;
809 	td->remainder = temp->len;
810 	td->error = 0;
811 	td->did_stall = 0;
812 	td->short_pkt = temp->short_pkt;
813 	td->alt_next = temp->setup_alt_next;
814 }
815 
816 static void
817 uss820dci_setup_standard_chain(struct usb2_xfer *xfer)
818 {
819 	struct uss820_std_temp temp;
820 	struct uss820dci_softc *sc;
821 	struct uss820dci_td *td;
822 	uint32_t x;
823 	uint8_t ep_no;
824 
825 	DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
826 	    xfer->address, UE_GET_ADDR(xfer->endpoint),
827 	    xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
828 
829 	temp.max_frame_size = xfer->max_frame_size;
830 
831 	td = xfer->td_start[0];
832 	xfer->td_transfer_first = td;
833 	xfer->td_transfer_cache = td;
834 
835 	/* setup temp */
836 
837 	temp.td = NULL;
838 	temp.td_next = xfer->td_start[0];
839 	temp.offset = 0;
840 	temp.setup_alt_next = xfer->flags_int.short_frames_ok;
841 
842 	sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
843 	ep_no = (xfer->endpoint & UE_ADDR);
844 
845 	/* check if we should prepend a setup message */
846 
847 	if (xfer->flags_int.control_xfr) {
848 		if (xfer->flags_int.control_hdr) {
849 
850 			temp.func = &uss820dci_setup_rx;
851 			temp.len = xfer->frlengths[0];
852 			temp.pc = xfer->frbuffers + 0;
853 			temp.short_pkt = temp.len ? 1 : 0;
854 			/* check for last frame */
855 			if (xfer->nframes == 1) {
856 				/* no STATUS stage yet, SETUP is last */
857 				if (xfer->flags_int.control_act)
858 					temp.setup_alt_next = 0;
859 			}
860 
861 			uss820dci_setup_standard_chain_sub(&temp);
862 		}
863 		x = 1;
864 	} else {
865 		x = 0;
866 	}
867 
868 	if (x != xfer->nframes) {
869 		if (xfer->endpoint & UE_DIR_IN) {
870 			temp.func = &uss820dci_data_tx;
871 		} else {
872 			temp.func = &uss820dci_data_rx;
873 		}
874 
875 		/* setup "pc" pointer */
876 		temp.pc = xfer->frbuffers + x;
877 	}
878 	while (x != xfer->nframes) {
879 
880 		/* DATA0 / DATA1 message */
881 
882 		temp.len = xfer->frlengths[x];
883 
884 		x++;
885 
886 		if (x == xfer->nframes) {
887 			if (xfer->flags_int.control_xfr) {
888 				if (xfer->flags_int.control_act) {
889 					temp.setup_alt_next = 0;
890 				}
891 			} else {
892 				temp.setup_alt_next = 0;
893 			}
894 		}
895 		if (temp.len == 0) {
896 
897 			/* make sure that we send an USB packet */
898 
899 			temp.short_pkt = 0;
900 
901 		} else {
902 
903 			/* regular data transfer */
904 
905 			temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
906 		}
907 
908 		uss820dci_setup_standard_chain_sub(&temp);
909 
910 		if (xfer->flags_int.isochronous_xfr) {
911 			temp.offset += temp.len;
912 		} else {
913 			/* get next Page Cache pointer */
914 			temp.pc = xfer->frbuffers + x;
915 		}
916 	}
917 
918 	/* check for control transfer */
919 	if (xfer->flags_int.control_xfr) {
920 		uint8_t need_sync;
921 
922 		/* always setup a valid "pc" pointer for status and sync */
923 		temp.pc = xfer->frbuffers + 0;
924 		temp.len = 0;
925 		temp.short_pkt = 0;
926 		temp.setup_alt_next = 0;
927 
928 		/* check if we should append a status stage */
929 		if (!xfer->flags_int.control_act) {
930 
931 			/*
932 			 * Send a DATA1 message and invert the current
933 			 * endpoint direction.
934 			 */
935 			if (xfer->endpoint & UE_DIR_IN) {
936 				temp.func = &uss820dci_data_rx;
937 				need_sync = 0;
938 			} else {
939 				temp.func = &uss820dci_data_tx;
940 				need_sync = 1;
941 			}
942 			temp.len = 0;
943 			temp.short_pkt = 0;
944 
945 			uss820dci_setup_standard_chain_sub(&temp);
946 			if (need_sync) {
947 				/* we need a SYNC point after TX */
948 				temp.func = &uss820dci_data_tx_sync;
949 				uss820dci_setup_standard_chain_sub(&temp);
950 			}
951 		}
952 	}
953 	/* must have at least one frame! */
954 	td = temp.td;
955 	xfer->td_transfer_last = td;
956 }
957 
958 static void
959 uss820dci_timeout(void *arg)
960 {
961 	struct usb2_xfer *xfer = arg;
962 
963 	DPRINTF("xfer=%p\n", xfer);
964 
965 	USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
966 
967 	/* transfer is transferred */
968 	uss820dci_device_done(xfer, USB_ERR_TIMEOUT);
969 }
970 
971 static void
972 uss820dci_intr_set(struct usb2_xfer *xfer, uint8_t set)
973 {
974 	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
975 	uint8_t ep_no = (xfer->endpoint & UE_ADDR);
976 	uint8_t ep_reg;
977 	uint8_t temp;
978 
979 	DPRINTFN(15, "endpoint 0x%02x\n", xfer->endpoint);
980 
981 	if (ep_no > 3) {
982 		ep_reg = USS820_SBIE1;
983 	} else {
984 		ep_reg = USS820_SBIE;
985 	}
986 
987 	ep_no &= 3;
988 	ep_no = 1 << (2 * ep_no);
989 
990 	if (xfer->flags_int.control_xfr) {
991 		if (xfer->flags_int.control_hdr) {
992 			ep_no <<= 1;	/* RX interrupt only */
993 		} else {
994 			ep_no |= (ep_no << 1);	/* RX and TX interrupt */
995 		}
996 	} else {
997 		if (!(xfer->endpoint & UE_DIR_IN)) {
998 			ep_no <<= 1;
999 		}
1000 	}
1001 	temp = USS820_READ_1(sc, ep_reg);
1002 	if (set) {
1003 		temp |= ep_no;
1004 	} else {
1005 		temp &= ~ep_no;
1006 	}
1007 	USS820_WRITE_1(sc, ep_reg, temp);
1008 }
1009 
1010 static void
1011 uss820dci_start_standard_chain(struct usb2_xfer *xfer)
1012 {
1013 	DPRINTFN(9, "\n");
1014 
1015 	/* poll one time */
1016 	if (uss820dci_xfer_do_fifo(xfer)) {
1017 
1018 		/*
1019 		 * Only enable the endpoint interrupt when we are
1020 		 * actually waiting for data, hence we are dealing
1021 		 * with level triggered interrupts !
1022 		 */
1023 		uss820dci_intr_set(xfer, 1);
1024 
1025 		/* put transfer on interrupt queue */
1026 		usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
1027 
1028 		/* start timeout, if any */
1029 		if (xfer->timeout != 0) {
1030 			usb2_transfer_timeout_ms(xfer,
1031 			    &uss820dci_timeout, xfer->timeout);
1032 		}
1033 	}
1034 }
1035 
1036 static void
1037 uss820dci_root_intr_done(struct usb2_xfer *xfer,
1038     struct usb2_sw_transfer *std)
1039 {
1040 	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
1041 
1042 	DPRINTFN(9, "\n");
1043 
1044 	USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
1045 
1046 	if (std->state != USB_SW_TR_PRE_DATA) {
1047 		if (std->state == USB_SW_TR_PRE_CALLBACK) {
1048 			/* transfer transferred */
1049 			uss820dci_device_done(xfer, std->err);
1050 		}
1051 		goto done;
1052 	}
1053 	/* setup buffer */
1054 	std->ptr = sc->sc_hub_idata;
1055 	std->len = sizeof(sc->sc_hub_idata);
1056 
1057 	/* set port bit */
1058 	sc->sc_hub_idata[0] = 0x02;	/* we only have one port */
1059 
1060 done:
1061 	return;
1062 }
1063 
1064 static usb2_error_t
1065 uss820dci_standard_done_sub(struct usb2_xfer *xfer)
1066 {
1067 	struct uss820dci_td *td;
1068 	uint32_t len;
1069 	uint8_t error;
1070 
1071 	DPRINTFN(9, "\n");
1072 
1073 	td = xfer->td_transfer_cache;
1074 
1075 	do {
1076 		len = td->remainder;
1077 
1078 		if (xfer->aframes != xfer->nframes) {
1079 			/*
1080 		         * Verify the length and subtract
1081 		         * the remainder from "frlengths[]":
1082 		         */
1083 			if (len > xfer->frlengths[xfer->aframes]) {
1084 				td->error = 1;
1085 			} else {
1086 				xfer->frlengths[xfer->aframes] -= len;
1087 			}
1088 		}
1089 		/* Check for transfer error */
1090 		if (td->error) {
1091 			/* the transfer is finished */
1092 			error = 1;
1093 			td = NULL;
1094 			break;
1095 		}
1096 		/* Check for short transfer */
1097 		if (len > 0) {
1098 			if (xfer->flags_int.short_frames_ok) {
1099 				/* follow alt next */
1100 				if (td->alt_next) {
1101 					td = td->obj_next;
1102 				} else {
1103 					td = NULL;
1104 				}
1105 			} else {
1106 				/* the transfer is finished */
1107 				td = NULL;
1108 			}
1109 			error = 0;
1110 			break;
1111 		}
1112 		td = td->obj_next;
1113 
1114 		/* this USB frame is complete */
1115 		error = 0;
1116 		break;
1117 
1118 	} while (0);
1119 
1120 	/* update transfer cache */
1121 
1122 	xfer->td_transfer_cache = td;
1123 
1124 	return (error ?
1125 	    USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
1126 }
1127 
1128 static void
1129 uss820dci_standard_done(struct usb2_xfer *xfer)
1130 {
1131 	usb2_error_t err = 0;
1132 
1133 	DPRINTFN(13, "xfer=%p pipe=%p transfer done\n",
1134 	    xfer, xfer->pipe);
1135 
1136 	/* reset scanner */
1137 
1138 	xfer->td_transfer_cache = xfer->td_transfer_first;
1139 
1140 	if (xfer->flags_int.control_xfr) {
1141 
1142 		if (xfer->flags_int.control_hdr) {
1143 
1144 			err = uss820dci_standard_done_sub(xfer);
1145 		}
1146 		xfer->aframes = 1;
1147 
1148 		if (xfer->td_transfer_cache == NULL) {
1149 			goto done;
1150 		}
1151 	}
1152 	while (xfer->aframes != xfer->nframes) {
1153 
1154 		err = uss820dci_standard_done_sub(xfer);
1155 		xfer->aframes++;
1156 
1157 		if (xfer->td_transfer_cache == NULL) {
1158 			goto done;
1159 		}
1160 	}
1161 
1162 	if (xfer->flags_int.control_xfr &&
1163 	    !xfer->flags_int.control_act) {
1164 
1165 		err = uss820dci_standard_done_sub(xfer);
1166 	}
1167 done:
1168 	uss820dci_device_done(xfer, err);
1169 }
1170 
1171 /*------------------------------------------------------------------------*
1172  *	uss820dci_device_done
1173  *
1174  * NOTE: this function can be called more than one time on the
1175  * same USB transfer!
1176  *------------------------------------------------------------------------*/
1177 static void
1178 uss820dci_device_done(struct usb2_xfer *xfer, usb2_error_t error)
1179 {
1180 	USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1181 
1182 	DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
1183 	    xfer, xfer->pipe, error);
1184 
1185 	if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
1186 		uss820dci_intr_set(xfer, 0);
1187 	}
1188 	/* dequeue transfer and start next transfer */
1189 	usb2_transfer_done(xfer, error);
1190 }
1191 
1192 static void
1193 uss820dci_set_stall(struct usb2_device *udev, struct usb2_xfer *xfer,
1194     struct usb2_pipe *pipe)
1195 {
1196 	struct uss820dci_softc *sc;
1197 	uint8_t ep_no;
1198 	uint8_t ep_type;
1199 	uint8_t ep_dir;
1200 	uint8_t temp;
1201 
1202 	USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1203 
1204 	DPRINTFN(5, "pipe=%p\n", pipe);
1205 
1206 	if (xfer) {
1207 		/* cancel any ongoing transfers */
1208 		uss820dci_device_done(xfer, USB_ERR_STALLED);
1209 	}
1210 	/* set FORCESTALL */
1211 	sc = USS820_DCI_BUS2SC(udev->bus);
1212 	ep_no = (pipe->edesc->bEndpointAddress & UE_ADDR);
1213 	ep_dir = (pipe->edesc->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT));
1214 	ep_type = (pipe->edesc->bmAttributes & UE_XFERTYPE);
1215 
1216 	if (ep_type == UE_CONTROL) {
1217 		/* should not happen */
1218 		return;
1219 	}
1220 	USS820_WRITE_1(sc, USS820_EPINDEX, ep_no);
1221 
1222 	if (ep_dir == UE_DIR_IN) {
1223 		temp = USS820_EPCON_TXSTL;
1224 	} else {
1225 		temp = USS820_EPCON_RXSTL;
1226 	}
1227 	uss820dci_update_shared_1(sc, USS820_EPCON, 0xFF, temp);
1228 }
1229 
1230 static void
1231 uss820dci_clear_stall_sub(struct uss820dci_softc *sc,
1232     uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
1233 {
1234 	uint8_t temp;
1235 
1236 	if (ep_type == UE_CONTROL) {
1237 		/* clearing stall is not needed */
1238 		return;
1239 	}
1240 	/* select endpoint index */
1241 	USS820_WRITE_1(sc, USS820_EPINDEX, ep_no);
1242 
1243 	/* clear stall and disable I/O transfers */
1244 	if (ep_dir == UE_DIR_IN) {
1245 		temp = 0xFF ^ (USS820_EPCON_TXOE |
1246 		    USS820_EPCON_TXSTL);
1247 	} else {
1248 		temp = 0xFF ^ (USS820_EPCON_RXIE |
1249 		    USS820_EPCON_RXSTL);
1250 	}
1251 	uss820dci_update_shared_1(sc, USS820_EPCON, temp, 0);
1252 
1253 	if (ep_dir == UE_DIR_IN) {
1254 		/* reset data toggle */
1255 		USS820_WRITE_1(sc, USS820_TXSTAT,
1256 		    USS820_TXSTAT_TXSOVW);
1257 
1258 		/* reset FIFO */
1259 		temp = USS820_READ_1(sc, USS820_TXCON);
1260 		temp |= USS820_TXCON_TXCLR;
1261 		USS820_WRITE_1(sc, USS820_TXCON, temp);
1262 		temp &= ~USS820_TXCON_TXCLR;
1263 		USS820_WRITE_1(sc, USS820_TXCON, temp);
1264 	} else {
1265 
1266 		/* reset data toggle */
1267 		uss820dci_update_shared_1(sc, USS820_RXSTAT,
1268 		    0, USS820_RXSTAT_RXSOVW);
1269 
1270 		/* reset FIFO */
1271 		temp = USS820_READ_1(sc, USS820_RXCON);
1272 		temp |= USS820_RXCON_RXCLR;
1273 		temp &= ~USS820_RXCON_RXFFRC;
1274 		USS820_WRITE_1(sc, USS820_RXCON, temp);
1275 		temp &= ~USS820_RXCON_RXCLR;
1276 		USS820_WRITE_1(sc, USS820_RXCON, temp);
1277 	}
1278 }
1279 
1280 static void
1281 uss820dci_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe)
1282 {
1283 	struct uss820dci_softc *sc;
1284 	struct usb2_endpoint_descriptor *ed;
1285 
1286 	USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1287 
1288 	DPRINTFN(5, "pipe=%p\n", pipe);
1289 
1290 	/* check mode */
1291 	if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
1292 		/* not supported */
1293 		return;
1294 	}
1295 	/* get softc */
1296 	sc = USS820_DCI_BUS2SC(udev->bus);
1297 
1298 	/* get endpoint descriptor */
1299 	ed = pipe->edesc;
1300 
1301 	/* reset endpoint */
1302 	uss820dci_clear_stall_sub(sc,
1303 	    (ed->bEndpointAddress & UE_ADDR),
1304 	    (ed->bmAttributes & UE_XFERTYPE),
1305 	    (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
1306 }
1307 
1308 usb2_error_t
1309 uss820dci_init(struct uss820dci_softc *sc)
1310 {
1311 	const struct usb2_hw_ep_profile *pf;
1312 	uint8_t n;
1313 	uint8_t temp;
1314 
1315 	DPRINTF("start\n");
1316 
1317 	/* set up the bus structure */
1318 	sc->sc_bus.usbrev = USB_REV_1_1;
1319 	sc->sc_bus.methods = &uss820dci_bus_methods;
1320 
1321 	USB_BUS_LOCK(&sc->sc_bus);
1322 
1323 	/* we always have VBUS */
1324 	sc->sc_flags.status_vbus = 1;
1325 
1326 	/* reset the chip */
1327 	USS820_WRITE_1(sc, USS820_SCR, USS820_SCR_SRESET);
1328 	DELAY(100);
1329 	USS820_WRITE_1(sc, USS820_SCR, 0);
1330 
1331 	/* wait for reset to complete */
1332 	for (n = 0;; n++) {
1333 
1334 		temp = USS820_READ_1(sc, USS820_MCSR);
1335 
1336 		if (temp & USS820_MCSR_INIT) {
1337 			break;
1338 		}
1339 		if (n == 100) {
1340 			USB_BUS_UNLOCK(&sc->sc_bus);
1341 			return (USB_ERR_INVAL);
1342 		}
1343 		/* wait a little for things to stabilise */
1344 		DELAY(100);
1345 	}
1346 
1347 	/* do a pulldown */
1348 	uss820dci_pull_down(sc);
1349 
1350 	/* wait 10ms for pulldown to stabilise */
1351 	usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100);
1352 
1353 	/* check hardware revision */
1354 	temp = USS820_READ_1(sc, USS820_REV);
1355 
1356 	if (temp < 0x13) {
1357 		USB_BUS_UNLOCK(&sc->sc_bus);
1358 		return (USB_ERR_INVAL);
1359 	}
1360 	/* enable interrupts */
1361 	USS820_WRITE_1(sc, USS820_SCR,
1362 	    USS820_SCR_T_IRQ |
1363 	    USS820_SCR_IE_RESET |
1364 	/* USS820_SCR_RWUPE | */
1365 	    USS820_SCR_IE_SUSP |
1366 	    USS820_SCR_IRQPOL);
1367 
1368 	/* enable interrupts */
1369 	USS820_WRITE_1(sc, USS820_SCRATCH,
1370 	    USS820_SCRATCH_IE_RESUME);
1371 
1372 	/* enable features */
1373 	USS820_WRITE_1(sc, USS820_MCSR,
1374 	    USS820_MCSR_BDFEAT |
1375 	    USS820_MCSR_FEAT);
1376 
1377 	sc->sc_flags.mcsr_feat = 1;
1378 
1379 	/* disable interrupts */
1380 	USS820_WRITE_1(sc, USS820_SBIE, 0);
1381 
1382 	/* disable interrupts */
1383 	USS820_WRITE_1(sc, USS820_SBIE1, 0);
1384 
1385 	/* disable all endpoints */
1386 	for (n = 0; n != USS820_EP_MAX; n++) {
1387 
1388 		/* select endpoint */
1389 		USS820_WRITE_1(sc, USS820_EPINDEX, n);
1390 
1391 		/* disable endpoint */
1392 		uss820dci_update_shared_1(sc, USS820_EPCON, 0, 0);
1393 	}
1394 
1395 	/*
1396 	 * Initialise default values for some registers that cannot be
1397 	 * changed during operation!
1398 	 */
1399 	for (n = 0; n != USS820_EP_MAX; n++) {
1400 
1401 		uss820dci_get_hw_ep_profile(NULL, &pf, n);
1402 
1403 		/* the maximum frame sizes should be the same */
1404 		if (pf->max_in_frame_size != pf->max_out_frame_size) {
1405 			DPRINTF("Max frame size mismatch %u != %u\n",
1406 			    pf->max_in_frame_size, pf->max_out_frame_size);
1407 		}
1408 		if (pf->support_isochronous) {
1409 			if (pf->max_in_frame_size <= 64) {
1410 				temp = (USS820_TXCON_FFSZ_16_64 |
1411 				    USS820_TXCON_TXISO |
1412 				    USS820_TXCON_ATM);
1413 			} else if (pf->max_in_frame_size <= 256) {
1414 				temp = (USS820_TXCON_FFSZ_64_256 |
1415 				    USS820_TXCON_TXISO |
1416 				    USS820_TXCON_ATM);
1417 			} else if (pf->max_in_frame_size <= 512) {
1418 				temp = (USS820_TXCON_FFSZ_8_512 |
1419 				    USS820_TXCON_TXISO |
1420 				    USS820_TXCON_ATM);
1421 			} else {	/* 1024 bytes */
1422 				temp = (USS820_TXCON_FFSZ_32_1024 |
1423 				    USS820_TXCON_TXISO |
1424 				    USS820_TXCON_ATM);
1425 			}
1426 		} else {
1427 			if ((pf->max_in_frame_size <= 8) &&
1428 			    (sc->sc_flags.mcsr_feat)) {
1429 				temp = (USS820_TXCON_FFSZ_8_512 |
1430 				    USS820_TXCON_ATM);
1431 			} else if (pf->max_in_frame_size <= 16) {
1432 				temp = (USS820_TXCON_FFSZ_16_64 |
1433 				    USS820_TXCON_ATM);
1434 			} else if ((pf->max_in_frame_size <= 32) &&
1435 			    (sc->sc_flags.mcsr_feat)) {
1436 				temp = (USS820_TXCON_FFSZ_32_1024 |
1437 				    USS820_TXCON_ATM);
1438 			} else {	/* 64 bytes */
1439 				temp = (USS820_TXCON_FFSZ_64_256 |
1440 				    USS820_TXCON_ATM);
1441 			}
1442 		}
1443 
1444 		/* need to configure the chip early */
1445 
1446 		USS820_WRITE_1(sc, USS820_EPINDEX, n);
1447 		USS820_WRITE_1(sc, USS820_TXCON, temp);
1448 		USS820_WRITE_1(sc, USS820_RXCON, temp);
1449 
1450 		if (pf->support_control) {
1451 			temp = USS820_EPCON_CTLEP |
1452 			    USS820_EPCON_RXSPM |
1453 			    USS820_EPCON_RXIE |
1454 			    USS820_EPCON_RXEPEN |
1455 			    USS820_EPCON_TXOE |
1456 			    USS820_EPCON_TXEPEN;
1457 		} else {
1458 			temp = USS820_EPCON_RXEPEN | USS820_EPCON_TXEPEN;
1459 		}
1460 
1461 		uss820dci_update_shared_1(sc, USS820_EPCON, 0xFF, temp);
1462 	}
1463 
1464 	USB_BUS_UNLOCK(&sc->sc_bus);
1465 
1466 	/* catch any lost interrupts */
1467 
1468 	uss820dci_do_poll(&sc->sc_bus);
1469 
1470 	return (0);			/* success */
1471 }
1472 
1473 void
1474 uss820dci_uninit(struct uss820dci_softc *sc)
1475 {
1476 	uint8_t temp;
1477 
1478 	USB_BUS_LOCK(&sc->sc_bus);
1479 
1480 	/* disable all interrupts */
1481 	temp = USS820_READ_1(sc, USS820_SCR);
1482 	temp &= ~USS820_SCR_T_IRQ;
1483 	USS820_WRITE_1(sc, USS820_SCR, temp);
1484 
1485 	sc->sc_flags.port_powered = 0;
1486 	sc->sc_flags.status_vbus = 0;
1487 	sc->sc_flags.status_bus_reset = 0;
1488 	sc->sc_flags.status_suspend = 0;
1489 	sc->sc_flags.change_suspend = 0;
1490 	sc->sc_flags.change_connect = 1;
1491 
1492 	uss820dci_pull_down(sc);
1493 	USB_BUS_UNLOCK(&sc->sc_bus);
1494 }
1495 
1496 void
1497 uss820dci_suspend(struct uss820dci_softc *sc)
1498 {
1499 	return;
1500 }
1501 
1502 void
1503 uss820dci_resume(struct uss820dci_softc *sc)
1504 {
1505 	return;
1506 }
1507 
1508 static void
1509 uss820dci_do_poll(struct usb2_bus *bus)
1510 {
1511 	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(bus);
1512 
1513 	USB_BUS_LOCK(&sc->sc_bus);
1514 	uss820dci_interrupt_poll(sc);
1515 	uss820dci_root_ctrl_poll(sc);
1516 	USB_BUS_UNLOCK(&sc->sc_bus);
1517 }
1518 
1519 /*------------------------------------------------------------------------*
1520  * at91dci bulk support
1521  *------------------------------------------------------------------------*/
1522 static void
1523 uss820dci_device_bulk_open(struct usb2_xfer *xfer)
1524 {
1525 	return;
1526 }
1527 
1528 static void
1529 uss820dci_device_bulk_close(struct usb2_xfer *xfer)
1530 {
1531 	uss820dci_device_done(xfer, USB_ERR_CANCELLED);
1532 }
1533 
1534 static void
1535 uss820dci_device_bulk_enter(struct usb2_xfer *xfer)
1536 {
1537 	return;
1538 }
1539 
1540 static void
1541 uss820dci_device_bulk_start(struct usb2_xfer *xfer)
1542 {
1543 	/* setup TDs */
1544 	uss820dci_setup_standard_chain(xfer);
1545 	uss820dci_start_standard_chain(xfer);
1546 }
1547 
1548 struct usb2_pipe_methods uss820dci_device_bulk_methods =
1549 {
1550 	.open = uss820dci_device_bulk_open,
1551 	.close = uss820dci_device_bulk_close,
1552 	.enter = uss820dci_device_bulk_enter,
1553 	.start = uss820dci_device_bulk_start,
1554 	.enter_is_cancelable = 1,
1555 	.start_is_cancelable = 1,
1556 };
1557 
1558 /*------------------------------------------------------------------------*
1559  * at91dci control support
1560  *------------------------------------------------------------------------*/
1561 static void
1562 uss820dci_device_ctrl_open(struct usb2_xfer *xfer)
1563 {
1564 	return;
1565 }
1566 
1567 static void
1568 uss820dci_device_ctrl_close(struct usb2_xfer *xfer)
1569 {
1570 	uss820dci_device_done(xfer, USB_ERR_CANCELLED);
1571 }
1572 
1573 static void
1574 uss820dci_device_ctrl_enter(struct usb2_xfer *xfer)
1575 {
1576 	return;
1577 }
1578 
1579 static void
1580 uss820dci_device_ctrl_start(struct usb2_xfer *xfer)
1581 {
1582 	/* setup TDs */
1583 	uss820dci_setup_standard_chain(xfer);
1584 	uss820dci_start_standard_chain(xfer);
1585 }
1586 
1587 struct usb2_pipe_methods uss820dci_device_ctrl_methods =
1588 {
1589 	.open = uss820dci_device_ctrl_open,
1590 	.close = uss820dci_device_ctrl_close,
1591 	.enter = uss820dci_device_ctrl_enter,
1592 	.start = uss820dci_device_ctrl_start,
1593 	.enter_is_cancelable = 1,
1594 	.start_is_cancelable = 1,
1595 };
1596 
1597 /*------------------------------------------------------------------------*
1598  * at91dci interrupt support
1599  *------------------------------------------------------------------------*/
1600 static void
1601 uss820dci_device_intr_open(struct usb2_xfer *xfer)
1602 {
1603 	return;
1604 }
1605 
1606 static void
1607 uss820dci_device_intr_close(struct usb2_xfer *xfer)
1608 {
1609 	uss820dci_device_done(xfer, USB_ERR_CANCELLED);
1610 }
1611 
1612 static void
1613 uss820dci_device_intr_enter(struct usb2_xfer *xfer)
1614 {
1615 	return;
1616 }
1617 
1618 static void
1619 uss820dci_device_intr_start(struct usb2_xfer *xfer)
1620 {
1621 	/* setup TDs */
1622 	uss820dci_setup_standard_chain(xfer);
1623 	uss820dci_start_standard_chain(xfer);
1624 }
1625 
1626 struct usb2_pipe_methods uss820dci_device_intr_methods =
1627 {
1628 	.open = uss820dci_device_intr_open,
1629 	.close = uss820dci_device_intr_close,
1630 	.enter = uss820dci_device_intr_enter,
1631 	.start = uss820dci_device_intr_start,
1632 	.enter_is_cancelable = 1,
1633 	.start_is_cancelable = 1,
1634 };
1635 
1636 /*------------------------------------------------------------------------*
1637  * at91dci full speed isochronous support
1638  *------------------------------------------------------------------------*/
1639 static void
1640 uss820dci_device_isoc_fs_open(struct usb2_xfer *xfer)
1641 {
1642 	return;
1643 }
1644 
1645 static void
1646 uss820dci_device_isoc_fs_close(struct usb2_xfer *xfer)
1647 {
1648 	uss820dci_device_done(xfer, USB_ERR_CANCELLED);
1649 }
1650 
1651 static void
1652 uss820dci_device_isoc_fs_enter(struct usb2_xfer *xfer)
1653 {
1654 	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
1655 	uint32_t temp;
1656 	uint32_t nframes;
1657 
1658 	DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
1659 	    xfer, xfer->pipe->isoc_next, xfer->nframes);
1660 
1661 	/* get the current frame index - we don't need the high bits */
1662 
1663 	nframes = USS820_READ_1(sc, USS820_SOFL);
1664 
1665 	/*
1666 	 * check if the frame index is within the window where the
1667 	 * frames will be inserted
1668 	 */
1669 	temp = (nframes - xfer->pipe->isoc_next) & USS820_SOFL_MASK;
1670 
1671 	if ((xfer->pipe->is_synced == 0) ||
1672 	    (temp < xfer->nframes)) {
1673 		/*
1674 		 * If there is data underflow or the pipe queue is
1675 		 * empty we schedule the transfer a few frames ahead
1676 		 * of the current frame position. Else two isochronous
1677 		 * transfers might overlap.
1678 		 */
1679 		xfer->pipe->isoc_next = (nframes + 3) & USS820_SOFL_MASK;
1680 		xfer->pipe->is_synced = 1;
1681 		DPRINTFN(3, "start next=%d\n", xfer->pipe->isoc_next);
1682 	}
1683 	/*
1684 	 * compute how many milliseconds the insertion is ahead of the
1685 	 * current frame position:
1686 	 */
1687 	temp = (xfer->pipe->isoc_next - nframes) & USS820_SOFL_MASK;
1688 
1689 	/*
1690 	 * pre-compute when the isochronous transfer will be finished:
1691 	 */
1692 	xfer->isoc_time_complete =
1693 	    usb2_isoc_time_expand(&sc->sc_bus, nframes) + temp +
1694 	    xfer->nframes;
1695 
1696 	/* compute frame number for next insertion */
1697 	xfer->pipe->isoc_next += xfer->nframes;
1698 
1699 	/* setup TDs */
1700 	uss820dci_setup_standard_chain(xfer);
1701 }
1702 
1703 static void
1704 uss820dci_device_isoc_fs_start(struct usb2_xfer *xfer)
1705 {
1706 	/* start TD chain */
1707 	uss820dci_start_standard_chain(xfer);
1708 }
1709 
1710 struct usb2_pipe_methods uss820dci_device_isoc_fs_methods =
1711 {
1712 	.open = uss820dci_device_isoc_fs_open,
1713 	.close = uss820dci_device_isoc_fs_close,
1714 	.enter = uss820dci_device_isoc_fs_enter,
1715 	.start = uss820dci_device_isoc_fs_start,
1716 	.enter_is_cancelable = 1,
1717 	.start_is_cancelable = 1,
1718 };
1719 
1720 /*------------------------------------------------------------------------*
1721  * at91dci root control support
1722  *------------------------------------------------------------------------*
1723  * simulate a hardware HUB by handling
1724  * all the necessary requests
1725  *------------------------------------------------------------------------*/
1726 
1727 static void
1728 uss820dci_root_ctrl_open(struct usb2_xfer *xfer)
1729 {
1730 	return;
1731 }
1732 
1733 static void
1734 uss820dci_root_ctrl_close(struct usb2_xfer *xfer)
1735 {
1736 	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
1737 
1738 	if (sc->sc_root_ctrl.xfer == xfer) {
1739 		sc->sc_root_ctrl.xfer = NULL;
1740 	}
1741 	uss820dci_device_done(xfer, USB_ERR_CANCELLED);
1742 }
1743 
1744 /*
1745  * USB descriptors for the virtual Root HUB:
1746  */
1747 
1748 static const struct usb2_device_descriptor uss820dci_devd = {
1749 	.bLength = sizeof(struct usb2_device_descriptor),
1750 	.bDescriptorType = UDESC_DEVICE,
1751 	.bcdUSB = {0x00, 0x02},
1752 	.bDeviceClass = UDCLASS_HUB,
1753 	.bDeviceSubClass = UDSUBCLASS_HUB,
1754 	.bDeviceProtocol = UDPROTO_HSHUBSTT,
1755 	.bMaxPacketSize = 64,
1756 	.bcdDevice = {0x00, 0x01},
1757 	.iManufacturer = 1,
1758 	.iProduct = 2,
1759 	.bNumConfigurations = 1,
1760 };
1761 
1762 static const struct usb2_device_qualifier uss820dci_odevd = {
1763 	.bLength = sizeof(struct usb2_device_qualifier),
1764 	.bDescriptorType = UDESC_DEVICE_QUALIFIER,
1765 	.bcdUSB = {0x00, 0x02},
1766 	.bDeviceClass = UDCLASS_HUB,
1767 	.bDeviceSubClass = UDSUBCLASS_HUB,
1768 	.bDeviceProtocol = UDPROTO_FSHUB,
1769 	.bMaxPacketSize0 = 0,
1770 	.bNumConfigurations = 0,
1771 };
1772 
1773 static const struct uss820dci_config_desc uss820dci_confd = {
1774 	.confd = {
1775 		.bLength = sizeof(struct usb2_config_descriptor),
1776 		.bDescriptorType = UDESC_CONFIG,
1777 		.wTotalLength[0] = sizeof(uss820dci_confd),
1778 		.bNumInterface = 1,
1779 		.bConfigurationValue = 1,
1780 		.iConfiguration = 0,
1781 		.bmAttributes = UC_SELF_POWERED,
1782 		.bMaxPower = 0,
1783 	},
1784 	.ifcd = {
1785 		.bLength = sizeof(struct usb2_interface_descriptor),
1786 		.bDescriptorType = UDESC_INTERFACE,
1787 		.bNumEndpoints = 1,
1788 		.bInterfaceClass = UICLASS_HUB,
1789 		.bInterfaceSubClass = UISUBCLASS_HUB,
1790 		.bInterfaceProtocol = UIPROTO_HSHUBSTT,
1791 	},
1792 
1793 	.endpd = {
1794 		.bLength = sizeof(struct usb2_endpoint_descriptor),
1795 		.bDescriptorType = UDESC_ENDPOINT,
1796 		.bEndpointAddress = (UE_DIR_IN | USS820_DCI_INTR_ENDPT),
1797 		.bmAttributes = UE_INTERRUPT,
1798 		.wMaxPacketSize[0] = 8,
1799 		.bInterval = 255,
1800 	},
1801 };
1802 
1803 static const struct usb2_hub_descriptor_min uss820dci_hubd = {
1804 	.bDescLength = sizeof(uss820dci_hubd),
1805 	.bDescriptorType = UDESC_HUB,
1806 	.bNbrPorts = 1,
1807 	.wHubCharacteristics[0] =
1808 	(UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
1809 	.wHubCharacteristics[1] =
1810 	(UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 8,
1811 	.bPwrOn2PwrGood = 50,
1812 	.bHubContrCurrent = 0,
1813 	.DeviceRemovable = {0},		/* port is removable */
1814 };
1815 
1816 #define	STRING_LANG \
1817   0x09, 0x04,				/* American English */
1818 
1819 #define	STRING_VENDOR \
1820   'A', 0, 'G', 0, 'E', 0, 'R', 0, 'E', 0
1821 
1822 #define	STRING_PRODUCT \
1823   'D', 0, 'C', 0, 'I', 0, ' ', 0, 'R', 0, \
1824   'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
1825   'U', 0, 'B', 0,
1826 
1827 USB_MAKE_STRING_DESC(STRING_LANG, uss820dci_langtab);
1828 USB_MAKE_STRING_DESC(STRING_VENDOR, uss820dci_vendor);
1829 USB_MAKE_STRING_DESC(STRING_PRODUCT, uss820dci_product);
1830 
1831 static void
1832 uss820dci_root_ctrl_enter(struct usb2_xfer *xfer)
1833 {
1834 	return;
1835 }
1836 
1837 static void
1838 uss820dci_root_ctrl_start(struct usb2_xfer *xfer)
1839 {
1840 	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
1841 
1842 	sc->sc_root_ctrl.xfer = xfer;
1843 
1844 	usb2_bus_roothub_exec(xfer->xroot->bus);
1845 }
1846 
1847 static void
1848 uss820dci_root_ctrl_task(struct usb2_bus *bus)
1849 {
1850 	uss820dci_root_ctrl_poll(USS820_DCI_BUS2SC(bus));
1851 }
1852 
1853 static void
1854 uss820dci_root_ctrl_done(struct usb2_xfer *xfer,
1855     struct usb2_sw_transfer *std)
1856 {
1857 	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
1858 	uint16_t value;
1859 	uint16_t index;
1860 
1861 	USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
1862 
1863 	if (std->state != USB_SW_TR_SETUP) {
1864 		if (std->state == USB_SW_TR_PRE_CALLBACK) {
1865 			/* transfer transferred */
1866 			uss820dci_device_done(xfer, std->err);
1867 		}
1868 		goto done;
1869 	}
1870 	/* buffer reset */
1871 	std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0);
1872 	std->len = 0;
1873 
1874 	value = UGETW(std->req.wValue);
1875 	index = UGETW(std->req.wIndex);
1876 
1877 	/* demultiplex the control request */
1878 
1879 	switch (std->req.bmRequestType) {
1880 	case UT_READ_DEVICE:
1881 		switch (std->req.bRequest) {
1882 		case UR_GET_DESCRIPTOR:
1883 			goto tr_handle_get_descriptor;
1884 		case UR_GET_CONFIG:
1885 			goto tr_handle_get_config;
1886 		case UR_GET_STATUS:
1887 			goto tr_handle_get_status;
1888 		default:
1889 			goto tr_stalled;
1890 		}
1891 		break;
1892 
1893 	case UT_WRITE_DEVICE:
1894 		switch (std->req.bRequest) {
1895 		case UR_SET_ADDRESS:
1896 			goto tr_handle_set_address;
1897 		case UR_SET_CONFIG:
1898 			goto tr_handle_set_config;
1899 		case UR_CLEAR_FEATURE:
1900 			goto tr_valid;	/* nop */
1901 		case UR_SET_DESCRIPTOR:
1902 			goto tr_valid;	/* nop */
1903 		case UR_SET_FEATURE:
1904 		default:
1905 			goto tr_stalled;
1906 		}
1907 		break;
1908 
1909 	case UT_WRITE_ENDPOINT:
1910 		switch (std->req.bRequest) {
1911 		case UR_CLEAR_FEATURE:
1912 			switch (UGETW(std->req.wValue)) {
1913 			case UF_ENDPOINT_HALT:
1914 				goto tr_handle_clear_halt;
1915 			case UF_DEVICE_REMOTE_WAKEUP:
1916 				goto tr_handle_clear_wakeup;
1917 			default:
1918 				goto tr_stalled;
1919 			}
1920 			break;
1921 		case UR_SET_FEATURE:
1922 			switch (UGETW(std->req.wValue)) {
1923 			case UF_ENDPOINT_HALT:
1924 				goto tr_handle_set_halt;
1925 			case UF_DEVICE_REMOTE_WAKEUP:
1926 				goto tr_handle_set_wakeup;
1927 			default:
1928 				goto tr_stalled;
1929 			}
1930 			break;
1931 		case UR_SYNCH_FRAME:
1932 			goto tr_valid;	/* nop */
1933 		default:
1934 			goto tr_stalled;
1935 		}
1936 		break;
1937 
1938 	case UT_READ_ENDPOINT:
1939 		switch (std->req.bRequest) {
1940 		case UR_GET_STATUS:
1941 			goto tr_handle_get_ep_status;
1942 		default:
1943 			goto tr_stalled;
1944 		}
1945 		break;
1946 
1947 	case UT_WRITE_INTERFACE:
1948 		switch (std->req.bRequest) {
1949 		case UR_SET_INTERFACE:
1950 			goto tr_handle_set_interface;
1951 		case UR_CLEAR_FEATURE:
1952 			goto tr_valid;	/* nop */
1953 		case UR_SET_FEATURE:
1954 		default:
1955 			goto tr_stalled;
1956 		}
1957 		break;
1958 
1959 	case UT_READ_INTERFACE:
1960 		switch (std->req.bRequest) {
1961 		case UR_GET_INTERFACE:
1962 			goto tr_handle_get_interface;
1963 		case UR_GET_STATUS:
1964 			goto tr_handle_get_iface_status;
1965 		default:
1966 			goto tr_stalled;
1967 		}
1968 		break;
1969 
1970 	case UT_WRITE_CLASS_INTERFACE:
1971 	case UT_WRITE_VENDOR_INTERFACE:
1972 		/* XXX forward */
1973 		break;
1974 
1975 	case UT_READ_CLASS_INTERFACE:
1976 	case UT_READ_VENDOR_INTERFACE:
1977 		/* XXX forward */
1978 		break;
1979 
1980 	case UT_WRITE_CLASS_DEVICE:
1981 		switch (std->req.bRequest) {
1982 		case UR_CLEAR_FEATURE:
1983 			goto tr_valid;
1984 		case UR_SET_DESCRIPTOR:
1985 		case UR_SET_FEATURE:
1986 			break;
1987 		default:
1988 			goto tr_stalled;
1989 		}
1990 		break;
1991 
1992 	case UT_WRITE_CLASS_OTHER:
1993 		switch (std->req.bRequest) {
1994 		case UR_CLEAR_FEATURE:
1995 			goto tr_handle_clear_port_feature;
1996 		case UR_SET_FEATURE:
1997 			goto tr_handle_set_port_feature;
1998 		case UR_CLEAR_TT_BUFFER:
1999 		case UR_RESET_TT:
2000 		case UR_STOP_TT:
2001 			goto tr_valid;
2002 
2003 		default:
2004 			goto tr_stalled;
2005 		}
2006 		break;
2007 
2008 	case UT_READ_CLASS_OTHER:
2009 		switch (std->req.bRequest) {
2010 		case UR_GET_TT_STATE:
2011 			goto tr_handle_get_tt_state;
2012 		case UR_GET_STATUS:
2013 			goto tr_handle_get_port_status;
2014 		default:
2015 			goto tr_stalled;
2016 		}
2017 		break;
2018 
2019 	case UT_READ_CLASS_DEVICE:
2020 		switch (std->req.bRequest) {
2021 		case UR_GET_DESCRIPTOR:
2022 			goto tr_handle_get_class_descriptor;
2023 		case UR_GET_STATUS:
2024 			goto tr_handle_get_class_status;
2025 
2026 		default:
2027 			goto tr_stalled;
2028 		}
2029 		break;
2030 	default:
2031 		goto tr_stalled;
2032 	}
2033 	goto tr_valid;
2034 
2035 tr_handle_get_descriptor:
2036 	switch (value >> 8) {
2037 	case UDESC_DEVICE:
2038 		if (value & 0xff) {
2039 			goto tr_stalled;
2040 		}
2041 		std->len = sizeof(uss820dci_devd);
2042 		std->ptr = USB_ADD_BYTES(&uss820dci_devd, 0);
2043 		goto tr_valid;
2044 	case UDESC_CONFIG:
2045 		if (value & 0xff) {
2046 			goto tr_stalled;
2047 		}
2048 		std->len = sizeof(uss820dci_confd);
2049 		std->ptr = USB_ADD_BYTES(&uss820dci_confd, 0);
2050 		goto tr_valid;
2051 	case UDESC_STRING:
2052 		switch (value & 0xff) {
2053 		case 0:		/* Language table */
2054 			std->len = sizeof(uss820dci_langtab);
2055 			std->ptr = USB_ADD_BYTES(&uss820dci_langtab, 0);
2056 			goto tr_valid;
2057 
2058 		case 1:		/* Vendor */
2059 			std->len = sizeof(uss820dci_vendor);
2060 			std->ptr = USB_ADD_BYTES(&uss820dci_vendor, 0);
2061 			goto tr_valid;
2062 
2063 		case 2:		/* Product */
2064 			std->len = sizeof(uss820dci_product);
2065 			std->ptr = USB_ADD_BYTES(&uss820dci_product, 0);
2066 			goto tr_valid;
2067 		default:
2068 			break;
2069 		}
2070 		break;
2071 	default:
2072 		goto tr_stalled;
2073 	}
2074 	goto tr_stalled;
2075 
2076 tr_handle_get_config:
2077 	std->len = 1;
2078 	sc->sc_hub_temp.wValue[0] = sc->sc_conf;
2079 	goto tr_valid;
2080 
2081 tr_handle_get_status:
2082 	std->len = 2;
2083 	USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
2084 	goto tr_valid;
2085 
2086 tr_handle_set_address:
2087 	if (value & 0xFF00) {
2088 		goto tr_stalled;
2089 	}
2090 	sc->sc_rt_addr = value;
2091 	goto tr_valid;
2092 
2093 tr_handle_set_config:
2094 	if (value >= 2) {
2095 		goto tr_stalled;
2096 	}
2097 	sc->sc_conf = value;
2098 	goto tr_valid;
2099 
2100 tr_handle_get_interface:
2101 	std->len = 1;
2102 	sc->sc_hub_temp.wValue[0] = 0;
2103 	goto tr_valid;
2104 
2105 tr_handle_get_tt_state:
2106 tr_handle_get_class_status:
2107 tr_handle_get_iface_status:
2108 tr_handle_get_ep_status:
2109 	std->len = 2;
2110 	USETW(sc->sc_hub_temp.wValue, 0);
2111 	goto tr_valid;
2112 
2113 tr_handle_set_halt:
2114 tr_handle_set_interface:
2115 tr_handle_set_wakeup:
2116 tr_handle_clear_wakeup:
2117 tr_handle_clear_halt:
2118 	goto tr_valid;
2119 
2120 tr_handle_clear_port_feature:
2121 	if (index != 1) {
2122 		goto tr_stalled;
2123 	}
2124 	DPRINTFN(9, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
2125 
2126 	switch (value) {
2127 	case UHF_PORT_SUSPEND:
2128 		uss820dci_wakeup_peer(sc);
2129 		break;
2130 
2131 	case UHF_PORT_ENABLE:
2132 		sc->sc_flags.port_enabled = 0;
2133 		break;
2134 
2135 	case UHF_PORT_TEST:
2136 	case UHF_PORT_INDICATOR:
2137 	case UHF_C_PORT_ENABLE:
2138 	case UHF_C_PORT_OVER_CURRENT:
2139 	case UHF_C_PORT_RESET:
2140 		/* nops */
2141 		break;
2142 	case UHF_PORT_POWER:
2143 		sc->sc_flags.port_powered = 0;
2144 		uss820dci_pull_down(sc);
2145 		break;
2146 	case UHF_C_PORT_CONNECTION:
2147 		sc->sc_flags.change_connect = 0;
2148 		break;
2149 	case UHF_C_PORT_SUSPEND:
2150 		sc->sc_flags.change_suspend = 0;
2151 		break;
2152 	default:
2153 		std->err = USB_ERR_IOERROR;
2154 		goto done;
2155 	}
2156 	goto tr_valid;
2157 
2158 tr_handle_set_port_feature:
2159 	if (index != 1) {
2160 		goto tr_stalled;
2161 	}
2162 	DPRINTFN(9, "UR_SET_PORT_FEATURE\n");
2163 
2164 	switch (value) {
2165 	case UHF_PORT_ENABLE:
2166 		sc->sc_flags.port_enabled = 1;
2167 		break;
2168 	case UHF_PORT_SUSPEND:
2169 	case UHF_PORT_RESET:
2170 	case UHF_PORT_TEST:
2171 	case UHF_PORT_INDICATOR:
2172 		/* nops */
2173 		break;
2174 	case UHF_PORT_POWER:
2175 		sc->sc_flags.port_powered = 1;
2176 		break;
2177 	default:
2178 		std->err = USB_ERR_IOERROR;
2179 		goto done;
2180 	}
2181 	goto tr_valid;
2182 
2183 tr_handle_get_port_status:
2184 
2185 	DPRINTFN(9, "UR_GET_PORT_STATUS\n");
2186 
2187 	if (index != 1) {
2188 		goto tr_stalled;
2189 	}
2190 	if (sc->sc_flags.status_vbus) {
2191 		uss820dci_pull_up(sc);
2192 	} else {
2193 		uss820dci_pull_down(sc);
2194 	}
2195 
2196 	/* Select FULL-speed and Device Side Mode */
2197 
2198 	value = UPS_PORT_MODE_DEVICE;
2199 
2200 	if (sc->sc_flags.port_powered) {
2201 		value |= UPS_PORT_POWER;
2202 	}
2203 	if (sc->sc_flags.port_enabled) {
2204 		value |= UPS_PORT_ENABLED;
2205 	}
2206 	if (sc->sc_flags.status_vbus &&
2207 	    sc->sc_flags.status_bus_reset) {
2208 		value |= UPS_CURRENT_CONNECT_STATUS;
2209 	}
2210 	if (sc->sc_flags.status_suspend) {
2211 		value |= UPS_SUSPEND;
2212 	}
2213 	USETW(sc->sc_hub_temp.ps.wPortStatus, value);
2214 
2215 	value = 0;
2216 
2217 	if (sc->sc_flags.change_connect) {
2218 		value |= UPS_C_CONNECT_STATUS;
2219 	}
2220 	if (sc->sc_flags.change_suspend) {
2221 		value |= UPS_C_SUSPEND;
2222 	}
2223 	USETW(sc->sc_hub_temp.ps.wPortChange, value);
2224 	std->len = sizeof(sc->sc_hub_temp.ps);
2225 	goto tr_valid;
2226 
2227 tr_handle_get_class_descriptor:
2228 	if (value & 0xFF) {
2229 		goto tr_stalled;
2230 	}
2231 	std->ptr = USB_ADD_BYTES(&uss820dci_hubd, 0);
2232 	std->len = sizeof(uss820dci_hubd);
2233 	goto tr_valid;
2234 
2235 tr_stalled:
2236 	std->err = USB_ERR_STALLED;
2237 tr_valid:
2238 done:
2239 	return;
2240 }
2241 
2242 static void
2243 uss820dci_root_ctrl_poll(struct uss820dci_softc *sc)
2244 {
2245 	usb2_sw_transfer(&sc->sc_root_ctrl,
2246 	    &uss820dci_root_ctrl_done);
2247 }
2248 
2249 struct usb2_pipe_methods uss820dci_root_ctrl_methods =
2250 {
2251 	.open = uss820dci_root_ctrl_open,
2252 	.close = uss820dci_root_ctrl_close,
2253 	.enter = uss820dci_root_ctrl_enter,
2254 	.start = uss820dci_root_ctrl_start,
2255 	.enter_is_cancelable = 1,
2256 	.start_is_cancelable = 0,
2257 };
2258 
2259 /*------------------------------------------------------------------------*
2260  * at91dci root interrupt support
2261  *------------------------------------------------------------------------*/
2262 static void
2263 uss820dci_root_intr_open(struct usb2_xfer *xfer)
2264 {
2265 	return;
2266 }
2267 
2268 static void
2269 uss820dci_root_intr_close(struct usb2_xfer *xfer)
2270 {
2271 	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
2272 
2273 	if (sc->sc_root_intr.xfer == xfer) {
2274 		sc->sc_root_intr.xfer = NULL;
2275 	}
2276 	uss820dci_device_done(xfer, USB_ERR_CANCELLED);
2277 }
2278 
2279 static void
2280 uss820dci_root_intr_enter(struct usb2_xfer *xfer)
2281 {
2282 	return;
2283 }
2284 
2285 static void
2286 uss820dci_root_intr_start(struct usb2_xfer *xfer)
2287 {
2288 	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus);
2289 
2290 	sc->sc_root_intr.xfer = xfer;
2291 }
2292 
2293 struct usb2_pipe_methods uss820dci_root_intr_methods =
2294 {
2295 	.open = uss820dci_root_intr_open,
2296 	.close = uss820dci_root_intr_close,
2297 	.enter = uss820dci_root_intr_enter,
2298 	.start = uss820dci_root_intr_start,
2299 	.enter_is_cancelable = 1,
2300 	.start_is_cancelable = 1,
2301 };
2302 
2303 static void
2304 uss820dci_xfer_setup(struct usb2_setup_params *parm)
2305 {
2306 	const struct usb2_hw_ep_profile *pf;
2307 	struct uss820dci_softc *sc;
2308 	struct usb2_xfer *xfer;
2309 	void *last_obj;
2310 	uint32_t ntd;
2311 	uint32_t n;
2312 	uint8_t ep_no;
2313 
2314 	sc = USS820_DCI_BUS2SC(parm->udev->bus);
2315 	xfer = parm->curr_xfer;
2316 
2317 	/*
2318 	 * NOTE: This driver does not use any of the parameters that
2319 	 * are computed from the following values. Just set some
2320 	 * reasonable dummies:
2321 	 */
2322 	parm->hc_max_packet_size = 0x500;
2323 	parm->hc_max_packet_count = 1;
2324 	parm->hc_max_frame_size = 0x500;
2325 
2326 	usb2_transfer_setup_sub(parm);
2327 
2328 	/*
2329 	 * compute maximum number of TDs
2330 	 */
2331 	if (parm->methods == &uss820dci_device_ctrl_methods) {
2332 
2333 		ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
2334 
2335 	} else if (parm->methods == &uss820dci_device_bulk_methods) {
2336 
2337 		ntd = xfer->nframes + 1 /* SYNC */ ;
2338 
2339 	} else if (parm->methods == &uss820dci_device_intr_methods) {
2340 
2341 		ntd = xfer->nframes + 1 /* SYNC */ ;
2342 
2343 	} else if (parm->methods == &uss820dci_device_isoc_fs_methods) {
2344 
2345 		ntd = xfer->nframes + 1 /* SYNC */ ;
2346 
2347 	} else {
2348 
2349 		ntd = 0;
2350 	}
2351 
2352 	/*
2353 	 * check if "usb2_transfer_setup_sub" set an error
2354 	 */
2355 	if (parm->err) {
2356 		return;
2357 	}
2358 	/*
2359 	 * allocate transfer descriptors
2360 	 */
2361 	last_obj = NULL;
2362 
2363 	/*
2364 	 * get profile stuff
2365 	 */
2366 	if (ntd) {
2367 
2368 		ep_no = xfer->endpoint & UE_ADDR;
2369 		uss820dci_get_hw_ep_profile(parm->udev, &pf, ep_no);
2370 
2371 		if (pf == NULL) {
2372 			/* should not happen */
2373 			parm->err = USB_ERR_INVAL;
2374 			return;
2375 		}
2376 	} else {
2377 		ep_no = 0;
2378 		pf = NULL;
2379 	}
2380 
2381 	/* align data */
2382 	parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
2383 
2384 	for (n = 0; n != ntd; n++) {
2385 
2386 		struct uss820dci_td *td;
2387 
2388 		if (parm->buf) {
2389 
2390 			td = USB_ADD_BYTES(parm->buf, parm->size[0]);
2391 
2392 			/* init TD */
2393 			td->io_tag = sc->sc_io_tag;
2394 			td->io_hdl = sc->sc_io_hdl;
2395 			td->max_packet_size = xfer->max_packet_size;
2396 			td->rx_stat_reg = USS820_GET_REG(sc, USS820_RXSTAT);
2397 			td->tx_stat_reg = USS820_GET_REG(sc, USS820_TXSTAT);
2398 			td->rx_flag_reg = USS820_GET_REG(sc, USS820_RXFLG);
2399 			td->tx_flag_reg = USS820_GET_REG(sc, USS820_TXFLG);
2400 			td->rx_fifo_reg = USS820_GET_REG(sc, USS820_RXDAT);
2401 			td->tx_fifo_reg = USS820_GET_REG(sc, USS820_TXDAT);
2402 			td->rx_count_low_reg = USS820_GET_REG(sc, USS820_RXCNTL);
2403 			td->rx_count_high_reg = USS820_GET_REG(sc, USS820_RXCNTH);
2404 			td->tx_count_low_reg = USS820_GET_REG(sc, USS820_TXCNTL);
2405 			td->tx_count_high_reg = USS820_GET_REG(sc, USS820_TXCNTH);
2406 			td->rx_cntl_reg = USS820_GET_REG(sc, USS820_RXCON);
2407 			td->tx_cntl_reg = USS820_GET_REG(sc, USS820_TXCON);
2408 			td->pend_reg = USS820_GET_REG(sc, USS820_PEND);
2409 			td->ep_reg = USS820_GET_REG(sc, USS820_EPINDEX);
2410 			td->ep_index = ep_no;
2411 			if (pf->support_multi_buffer &&
2412 			    (parm->methods != &uss820dci_device_ctrl_methods)) {
2413 				td->support_multi_buffer = 1;
2414 			}
2415 			td->obj_next = last_obj;
2416 
2417 			last_obj = td;
2418 		}
2419 		parm->size[0] += sizeof(*td);
2420 	}
2421 
2422 	xfer->td_start[0] = last_obj;
2423 }
2424 
2425 static void
2426 uss820dci_xfer_unsetup(struct usb2_xfer *xfer)
2427 {
2428 	return;
2429 }
2430 
2431 static void
2432 uss820dci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc,
2433     struct usb2_pipe *pipe)
2434 {
2435 	struct uss820dci_softc *sc = USS820_DCI_BUS2SC(udev->bus);
2436 
2437 	DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
2438 	    pipe, udev->address,
2439 	    edesc->bEndpointAddress, udev->flags.usb2_mode,
2440 	    sc->sc_rt_addr);
2441 
2442 	if (udev->device_index == sc->sc_rt_addr) {
2443 
2444 		if (udev->flags.usb2_mode != USB_MODE_HOST) {
2445 			/* not supported */
2446 			return;
2447 		}
2448 		switch (edesc->bEndpointAddress) {
2449 		case USB_CONTROL_ENDPOINT:
2450 			pipe->methods = &uss820dci_root_ctrl_methods;
2451 			break;
2452 		case UE_DIR_IN | USS820_DCI_INTR_ENDPT:
2453 			pipe->methods = &uss820dci_root_intr_methods;
2454 			break;
2455 		default:
2456 			/* do nothing */
2457 			break;
2458 		}
2459 	} else {
2460 
2461 		if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
2462 			/* not supported */
2463 			return;
2464 		}
2465 		if (udev->speed != USB_SPEED_FULL) {
2466 			/* not supported */
2467 			return;
2468 		}
2469 		switch (edesc->bmAttributes & UE_XFERTYPE) {
2470 		case UE_CONTROL:
2471 			pipe->methods = &uss820dci_device_ctrl_methods;
2472 			break;
2473 		case UE_INTERRUPT:
2474 			pipe->methods = &uss820dci_device_intr_methods;
2475 			break;
2476 		case UE_ISOCHRONOUS:
2477 			pipe->methods = &uss820dci_device_isoc_fs_methods;
2478 			break;
2479 		case UE_BULK:
2480 			pipe->methods = &uss820dci_device_bulk_methods;
2481 			break;
2482 		default:
2483 			/* do nothing */
2484 			break;
2485 		}
2486 	}
2487 }
2488 
2489 struct usb2_bus_methods uss820dci_bus_methods =
2490 {
2491 	.pipe_init = &uss820dci_pipe_init,
2492 	.xfer_setup = &uss820dci_xfer_setup,
2493 	.xfer_unsetup = &uss820dci_xfer_unsetup,
2494 	.get_hw_ep_profile = &uss820dci_get_hw_ep_profile,
2495 	.set_stall = &uss820dci_set_stall,
2496 	.clear_stall = &uss820dci_clear_stall,
2497 	.roothub_exec = &uss820dci_root_ctrl_task,
2498 };
2499