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