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