Deleted Added
full compact
musb_otg.c (246122) musb_otg.c (246123)
1/* $FreeBSD: head/sys/dev/usb/controller/musb_otg.c 246122 2013-01-30 15:26:04Z hselasky $ */
1/* $FreeBSD: head/sys/dev/usb/controller/musb_otg.c 246123 2013-01-30 15:46:26Z hselasky $ */
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Thanks to Mentor Graphics for providing a reference driver for this USB chip
29 * at their homepage.
30 */
31
32/*
33 * This file contains the driver for the Mentor Graphics Inventra USB
34 * 2.0 High Speed Dual-Role controller.
35 *
36 * NOTE: The current implementation only supports Device Side Mode!
37 */
38
39#ifdef USB_GLOBAL_INCLUDE_FILE
40#include USB_GLOBAL_INCLUDE_FILE
41#else
42#include <sys/stdint.h>
43#include <sys/stddef.h>
44#include <sys/param.h>
45#include <sys/queue.h>
46#include <sys/types.h>
47#include <sys/systm.h>
48#include <sys/kernel.h>
49#include <sys/bus.h>
50#include <sys/module.h>
51#include <sys/lock.h>
52#include <sys/mutex.h>
53#include <sys/condvar.h>
54#include <sys/sysctl.h>
55#include <sys/sx.h>
56#include <sys/unistd.h>
57#include <sys/callout.h>
58#include <sys/malloc.h>
59#include <sys/priv.h>
60
61#include <dev/usb/usb.h>
62#include <dev/usb/usbdi.h>
63
64#define USB_DEBUG_VAR musbotgdebug
65
66#include <dev/usb/usb_core.h>
67#include <dev/usb/usb_debug.h>
68#include <dev/usb/usb_busdma.h>
69#include <dev/usb/usb_process.h>
70#include <dev/usb/usb_transfer.h>
71#include <dev/usb/usb_device.h>
72#include <dev/usb/usb_hub.h>
73#include <dev/usb/usb_util.h>
74
75#include <dev/usb/usb_controller.h>
76#include <dev/usb/usb_bus.h>
77#endif /* USB_GLOBAL_INCLUDE_FILE */
78
79#include <dev/usb/controller/musb_otg.h>
80
81#define MUSBOTG_INTR_ENDPT 1
82
83#define MUSBOTG_BUS2SC(bus) \
84 ((struct musbotg_softc *)(((uint8_t *)(bus)) - \
85 USB_P2U(&(((struct musbotg_softc *)0)->sc_bus))))
86
87#define MUSBOTG_PC2SC(pc) \
88 MUSBOTG_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus)
89
90#ifdef USB_DEBUG
91static int musbotgdebug = 0;
92
93static SYSCTL_NODE(_hw_usb, OID_AUTO, musbotg, CTLFLAG_RW, 0, "USB musbotg");
94SYSCTL_INT(_hw_usb_musbotg, OID_AUTO, debug, CTLFLAG_RW,
95 &musbotgdebug, 0, "Debug level");
96#endif
97
98/* prototypes */
99
100struct usb_bus_methods musbotg_bus_methods;
101struct usb_pipe_methods musbotg_device_bulk_methods;
102struct usb_pipe_methods musbotg_device_ctrl_methods;
103struct usb_pipe_methods musbotg_device_intr_methods;
104struct usb_pipe_methods musbotg_device_isoc_methods;
105
106static musbotg_cmd_t musbotg_setup_rx;
107static musbotg_cmd_t musbotg_setup_data_rx;
108static musbotg_cmd_t musbotg_setup_data_tx;
109static musbotg_cmd_t musbotg_setup_status;
110static musbotg_cmd_t musbotg_data_rx;
111static musbotg_cmd_t musbotg_data_tx;
112static void musbotg_device_done(struct usb_xfer *, usb_error_t);
113static void musbotg_do_poll(struct usb_bus *);
114static void musbotg_standard_done(struct usb_xfer *);
115static void musbotg_interrupt_poll(struct musbotg_softc *);
116static void musbotg_root_intr(struct musbotg_softc *);
117
118/*
119 * Here is a configuration that the chip supports.
120 */
121static const struct usb_hw_ep_profile musbotg_ep_profile[1] = {
122
123 [0] = {
124 .max_in_frame_size = 64,/* fixed */
125 .max_out_frame_size = 64, /* fixed */
126 .is_simplex = 1,
127 .support_control = 1,
128 }
129};
130
131static void
132musbotg_get_hw_ep_profile(struct usb_device *udev,
133 const struct usb_hw_ep_profile **ppf, uint8_t ep_addr)
134{
135 struct musbotg_softc *sc;
136
137 sc = MUSBOTG_BUS2SC(udev->bus);
138
139 if (ep_addr == 0) {
140 /* control endpoint */
141 *ppf = musbotg_ep_profile;
142 } else if (ep_addr <= sc->sc_ep_max) {
143 /* other endpoints */
144 *ppf = sc->sc_hw_ep_profile + ep_addr;
145 } else {
146 *ppf = NULL;
147 }
148}
149
150static void
151musbotg_clocks_on(struct musbotg_softc *sc)
152{
153 if (sc->sc_flags.clocks_off &&
154 sc->sc_flags.port_powered) {
155
156 DPRINTFN(4, "\n");
157
158 if (sc->sc_clocks_on) {
159 (sc->sc_clocks_on) (sc->sc_clocks_arg);
160 }
161 sc->sc_flags.clocks_off = 0;
162
163 /* XXX enable Transceiver */
164 }
165}
166
167static void
168musbotg_clocks_off(struct musbotg_softc *sc)
169{
170 if (!sc->sc_flags.clocks_off) {
171
172 DPRINTFN(4, "\n");
173
174 /* XXX disable Transceiver */
175
176 if (sc->sc_clocks_off) {
177 (sc->sc_clocks_off) (sc->sc_clocks_arg);
178 }
179 sc->sc_flags.clocks_off = 1;
180 }
181}
182
183static void
184musbotg_pull_common(struct musbotg_softc *sc, uint8_t on)
185{
186 uint8_t temp;
187
188 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
189 if (on)
190 temp |= MUSB2_MASK_SOFTC;
191 else
192 temp &= ~MUSB2_MASK_SOFTC;
193
194 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
195}
196
197static void
198musbotg_pull_up(struct musbotg_softc *sc)
199{
200 /* pullup D+, if possible */
201
202 if (!sc->sc_flags.d_pulled_up &&
203 sc->sc_flags.port_powered) {
204 sc->sc_flags.d_pulled_up = 1;
205 musbotg_pull_common(sc, 1);
206 }
207}
208
209static void
210musbotg_pull_down(struct musbotg_softc *sc)
211{
212 /* pulldown D+, if possible */
213
214 if (sc->sc_flags.d_pulled_up) {
215 sc->sc_flags.d_pulled_up = 0;
216 musbotg_pull_common(sc, 0);
217 }
218}
219
220static void
221musbotg_wakeup_peer(struct musbotg_softc *sc)
222{
223 uint8_t temp;
224
225 if (!(sc->sc_flags.status_suspend)) {
226 return;
227 }
228
229 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
230 temp |= MUSB2_MASK_RESUME;
231 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
232
233 /* wait 8 milliseconds */
234 /* Wait for reset to complete. */
235 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 125);
236
237 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
238 temp &= ~MUSB2_MASK_RESUME;
239 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
240}
241
242static void
243musbotg_set_address(struct musbotg_softc *sc, uint8_t addr)
244{
245 DPRINTFN(4, "addr=%d\n", addr);
246 addr &= 0x7F;
247 MUSB2_WRITE_1(sc, MUSB2_REG_FADDR, addr);
248}
249
250static uint8_t
251musbotg_setup_rx(struct musbotg_td *td)
252{
253 struct musbotg_softc *sc;
254 struct usb_device_request req;
255 uint16_t count;
256 uint8_t csr;
257
258 /* get pointer to softc */
259 sc = MUSBOTG_PC2SC(td->pc);
260
261 /* select endpoint 0 */
262 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
263
264 /* read out FIFO status */
265 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
266
267 DPRINTFN(4, "csr=0x%02x\n", csr);
268
269 /*
270 * NOTE: If DATAEND is set we should not call the
271 * callback, hence the status stage is not complete.
272 */
273 if (csr & MUSB2_MASK_CSR0L_DATAEND) {
274 /* do not stall at this point */
275 td->did_stall = 1;
276 /* wait for interrupt */
277 goto not_complete;
278 }
279 if (csr & MUSB2_MASK_CSR0L_SENTSTALL) {
280 /* clear SENTSTALL */
281 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
282 /* get latest status */
283 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
284 /* update EP0 state */
285 sc->sc_ep0_busy = 0;
286 }
287 if (csr & MUSB2_MASK_CSR0L_SETUPEND) {
288 /* clear SETUPEND */
289 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
290 MUSB2_MASK_CSR0L_SETUPEND_CLR);
291 /* get latest status */
292 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
293 /* update EP0 state */
294 sc->sc_ep0_busy = 0;
295 }
296 if (sc->sc_ep0_busy) {
297 goto not_complete;
298 }
299 if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
300 goto not_complete;
301 }
302 /* clear did stall flag */
303 td->did_stall = 0;
304 /* get the packet byte count */
305 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
306
307 /* verify data length */
308 if (count != td->remainder) {
309 DPRINTFN(0, "Invalid SETUP packet "
310 "length, %d bytes\n", count);
311 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
312 MUSB2_MASK_CSR0L_RXPKTRDY_CLR);
313 goto not_complete;
314 }
315 if (count != sizeof(req)) {
316 DPRINTFN(0, "Unsupported SETUP packet "
317 "length, %d bytes\n", count);
318 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
319 MUSB2_MASK_CSR0L_RXPKTRDY_CLR);
320 goto not_complete;
321 }
322 /* receive data */
323 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
324 MUSB2_REG_EPFIFO(0), (void *)&req, sizeof(req));
325
326 /* copy data into real buffer */
327 usbd_copy_in(td->pc, 0, &req, sizeof(req));
328
329 td->offset = sizeof(req);
330 td->remainder = 0;
331
332 /* set pending command */
333 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_RXPKTRDY_CLR;
334
335 /* we need set stall or dataend after this */
336 sc->sc_ep0_busy = 1;
337
338 /* sneak peek the set address */
339 if ((req.bmRequestType == UT_WRITE_DEVICE) &&
340 (req.bRequest == UR_SET_ADDRESS)) {
341 sc->sc_dv_addr = req.wValue[0] & 0x7F;
342 } else {
343 sc->sc_dv_addr = 0xFF;
344 }
345 return (0); /* complete */
346
347not_complete:
348 /* abort any ongoing transfer */
349 if (!td->did_stall) {
350 DPRINTFN(4, "stalling\n");
351 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
352 MUSB2_MASK_CSR0L_SENDSTALL);
353 td->did_stall = 1;
354 }
355 return (1); /* not complete */
356}
357
358/* Control endpoint only data handling functions (RX/TX/SYNC) */
359
360static uint8_t
361musbotg_setup_data_rx(struct musbotg_td *td)
362{
363 struct usb_page_search buf_res;
364 struct musbotg_softc *sc;
365 uint16_t count;
366 uint8_t csr;
367 uint8_t got_short;
368
369 /* get pointer to softc */
370 sc = MUSBOTG_PC2SC(td->pc);
371
372 /* select endpoint 0 */
373 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
374
375 /* check if a command is pending */
376 if (sc->sc_ep0_cmd) {
377 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
378 sc->sc_ep0_cmd = 0;
379 }
380 /* read out FIFO status */
381 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
382
383 DPRINTFN(4, "csr=0x%02x\n", csr);
384
385 got_short = 0;
386
387 if (csr & (MUSB2_MASK_CSR0L_SETUPEND |
388 MUSB2_MASK_CSR0L_SENTSTALL)) {
389 if (td->remainder == 0) {
390 /*
391 * We are actually complete and have
392 * received the next SETUP
393 */
394 DPRINTFN(4, "faking complete\n");
395 return (0); /* complete */
396 }
397 /*
398 * USB Host Aborted the transfer.
399 */
400 td->error = 1;
401 return (0); /* complete */
402 }
403 if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
404 return (1); /* not complete */
405 }
406 /* get the packet byte count */
407 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
408
409 /* verify the packet byte count */
410 if (count != td->max_frame_size) {
411 if (count < td->max_frame_size) {
412 /* we have a short packet */
413 td->short_pkt = 1;
414 got_short = 1;
415 } else {
416 /* invalid USB packet */
417 td->error = 1;
418 return (0); /* we are complete */
419 }
420 }
421 /* verify the packet byte count */
422 if (count > td->remainder) {
423 /* invalid USB packet */
424 td->error = 1;
425 return (0); /* we are complete */
426 }
427 while (count > 0) {
428 uint32_t temp;
429
430 usbd_get_page(td->pc, td->offset, &buf_res);
431
432 /* get correct length */
433 if (buf_res.length > count) {
434 buf_res.length = count;
435 }
436 /* check for unaligned memory address */
437 if (USB_P2U(buf_res.buffer) & 3) {
438
439 temp = count & ~3;
440
441 if (temp) {
442 /* receive data 4 bytes at a time */
443 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
444 MUSB2_REG_EPFIFO(0), sc->sc_bounce_buf,
445 temp / 4);
446 }
447 temp = count & 3;
448 if (temp) {
449 /* receive data 1 byte at a time */
450 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
451 MUSB2_REG_EPFIFO(0),
452 (void *)(&sc->sc_bounce_buf[count / 4]), temp);
453 }
454 usbd_copy_in(td->pc, td->offset,
455 sc->sc_bounce_buf, count);
456
457 /* update offset and remainder */
458 td->offset += count;
459 td->remainder -= count;
460 break;
461 }
462 /* check if we can optimise */
463 if (buf_res.length >= 4) {
464
465 /* receive data 4 bytes at a time */
466 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
467 MUSB2_REG_EPFIFO(0), buf_res.buffer,
468 buf_res.length / 4);
469
470 temp = buf_res.length & ~3;
471
472 /* update counters */
473 count -= temp;
474 td->offset += temp;
475 td->remainder -= temp;
476 continue;
477 }
478 /* receive data */
479 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
480 MUSB2_REG_EPFIFO(0), buf_res.buffer, buf_res.length);
481
482 /* update counters */
483 count -= buf_res.length;
484 td->offset += buf_res.length;
485 td->remainder -= buf_res.length;
486 }
487
488 /* check if we are complete */
489 if ((td->remainder == 0) || got_short) {
490 if (td->short_pkt) {
491 /* we are complete */
492 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_RXPKTRDY_CLR;
493 return (0);
494 }
495 /* else need to receive a zero length packet */
496 }
497 /* write command - need more data */
498 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
499 MUSB2_MASK_CSR0L_RXPKTRDY_CLR);
500 return (1); /* not complete */
501}
502
503static uint8_t
504musbotg_setup_data_tx(struct musbotg_td *td)
505{
506 struct usb_page_search buf_res;
507 struct musbotg_softc *sc;
508 uint16_t count;
509 uint8_t csr;
510
511 /* get pointer to softc */
512 sc = MUSBOTG_PC2SC(td->pc);
513
514 /* select endpoint 0 */
515 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
516
517 /* check if a command is pending */
518 if (sc->sc_ep0_cmd) {
519 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
520 sc->sc_ep0_cmd = 0;
521 }
522 /* read out FIFO status */
523 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
524
525 DPRINTFN(4, "csr=0x%02x\n", csr);
526
527 if (csr & (MUSB2_MASK_CSR0L_SETUPEND |
528 MUSB2_MASK_CSR0L_SENTSTALL)) {
529 /*
530 * The current transfer was aborted
531 * by the USB Host
532 */
533 td->error = 1;
534 return (0); /* complete */
535 }
536 if (csr & MUSB2_MASK_CSR0L_TXPKTRDY) {
537 return (1); /* not complete */
538 }
539 count = td->max_frame_size;
540 if (td->remainder < count) {
541 /* we have a short packet */
542 td->short_pkt = 1;
543 count = td->remainder;
544 }
545 while (count > 0) {
546 uint32_t temp;
547
548 usbd_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 /* check for unaligned memory address */
555 if (USB_P2U(buf_res.buffer) & 3) {
556
557 usbd_copy_out(td->pc, td->offset,
558 sc->sc_bounce_buf, count);
559
560 temp = count & ~3;
561
562 if (temp) {
563 /* transmit data 4 bytes at a time */
564 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
565 MUSB2_REG_EPFIFO(0), sc->sc_bounce_buf,
566 temp / 4);
567 }
568 temp = count & 3;
569 if (temp) {
570 /* receive data 1 byte at a time */
571 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
572 MUSB2_REG_EPFIFO(0),
573 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
574 }
575 /* update offset and remainder */
576 td->offset += count;
577 td->remainder -= count;
578 break;
579 }
580 /* check if we can optimise */
581 if (buf_res.length >= 4) {
582
583 /* transmit data 4 bytes at a time */
584 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
585 MUSB2_REG_EPFIFO(0), buf_res.buffer,
586 buf_res.length / 4);
587
588 temp = buf_res.length & ~3;
589
590 /* update counters */
591 count -= temp;
592 td->offset += temp;
593 td->remainder -= temp;
594 continue;
595 }
596 /* transmit data */
597 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
598 MUSB2_REG_EPFIFO(0), buf_res.buffer, buf_res.length);
599
600 /* update counters */
601 count -= buf_res.length;
602 td->offset += buf_res.length;
603 td->remainder -= buf_res.length;
604 }
605
606 /* check remainder */
607 if (td->remainder == 0) {
608 if (td->short_pkt) {
609 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_TXPKTRDY;
610 return (0); /* complete */
611 }
612 /* else we need to transmit a short packet */
613 }
614 /* write command */
615 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
616 MUSB2_MASK_CSR0L_TXPKTRDY);
617
618 return (1); /* not complete */
619}
620
621static uint8_t
622musbotg_setup_status(struct musbotg_td *td)
623{
624 struct musbotg_softc *sc;
625 uint8_t csr;
626
627 /* get pointer to softc */
628 sc = MUSBOTG_PC2SC(td->pc);
629
630 /* select endpoint 0 */
631 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
632
633 if (sc->sc_ep0_busy) {
634 sc->sc_ep0_busy = 0;
635 sc->sc_ep0_cmd |= MUSB2_MASK_CSR0L_DATAEND;
636 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
637 sc->sc_ep0_cmd = 0;
638 }
639 /* read out FIFO status */
640 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
641
642 DPRINTFN(4, "csr=0x%02x\n", csr);
643
644 if (csr & MUSB2_MASK_CSR0L_DATAEND) {
645 /* wait for interrupt */
646 return (1); /* not complete */
647 }
648 if (sc->sc_dv_addr != 0xFF) {
649 /* write function address */
650 musbotg_set_address(sc, sc->sc_dv_addr);
651 }
652 return (0); /* complete */
653}
654
655static uint8_t
656musbotg_data_rx(struct musbotg_td *td)
657{
658 struct usb_page_search buf_res;
659 struct musbotg_softc *sc;
660 uint16_t count;
661 uint8_t csr;
662 uint8_t to;
663 uint8_t got_short;
664
665 to = 8; /* don't loop forever! */
666 got_short = 0;
667
668 /* get pointer to softc */
669 sc = MUSBOTG_PC2SC(td->pc);
670
671 /* select endpoint */
672 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->ep_no);
673
674repeat:
675 /* read out FIFO status */
676 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
677
678 DPRINTFN(4, "csr=0x%02x\n", csr);
679
680 /* clear overrun */
681 if (csr & MUSB2_MASK_CSRL_RXOVERRUN) {
682 /* make sure we don't clear "RXPKTRDY" */
683 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
684 MUSB2_MASK_CSRL_RXPKTRDY);
685 }
686 /* check status */
687 if (!(csr & MUSB2_MASK_CSRL_RXPKTRDY)) {
688 return (1); /* not complete */
689 }
690 /* get the packet byte count */
691 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
692
693 DPRINTFN(4, "count=0x%04x\n", count);
694
695 /*
696 * Check for short or invalid packet:
697 */
698 if (count != td->max_frame_size) {
699 if (count < td->max_frame_size) {
700 /* we have a short packet */
701 td->short_pkt = 1;
702 got_short = 1;
703 } else {
704 /* invalid USB packet */
705 td->error = 1;
706 return (0); /* we are complete */
707 }
708 }
709 /* verify the packet byte count */
710 if (count > td->remainder) {
711 /* invalid USB packet */
712 td->error = 1;
713 return (0); /* we are complete */
714 }
715 while (count > 0) {
716 uint32_t temp;
717
718 usbd_get_page(td->pc, td->offset, &buf_res);
719
720 /* get correct length */
721 if (buf_res.length > count) {
722 buf_res.length = count;
723 }
724 /* check for unaligned memory address */
725 if (USB_P2U(buf_res.buffer) & 3) {
726
727 temp = count & ~3;
728
729 if (temp) {
730 /* receive data 4 bytes at a time */
731 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
732 MUSB2_REG_EPFIFO(td->ep_no), sc->sc_bounce_buf,
733 temp / 4);
734 }
735 temp = count & 3;
736 if (temp) {
737 /* receive data 1 byte at a time */
738 bus_space_read_multi_1(sc->sc_io_tag,
739 sc->sc_io_hdl, MUSB2_REG_EPFIFO(td->ep_no),
740 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
741 }
742 usbd_copy_in(td->pc, td->offset,
743 sc->sc_bounce_buf, count);
744
745 /* update offset and remainder */
746 td->offset += count;
747 td->remainder -= count;
748 break;
749 }
750 /* check if we can optimise */
751 if (buf_res.length >= 4) {
752
753 /* receive data 4 bytes at a time */
754 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
755 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
756 buf_res.length / 4);
757
758 temp = buf_res.length & ~3;
759
760 /* update counters */
761 count -= temp;
762 td->offset += temp;
763 td->remainder -= temp;
764 continue;
765 }
766 /* receive data */
767 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
768 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
769 buf_res.length);
770
771 /* update counters */
772 count -= buf_res.length;
773 td->offset += buf_res.length;
774 td->remainder -= buf_res.length;
775 }
776
777 /* clear status bits */
778 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
779
780 /* check if we are complete */
781 if ((td->remainder == 0) || got_short) {
782 if (td->short_pkt) {
783 /* we are complete */
784 return (0);
785 }
786 /* else need to receive a zero length packet */
787 }
788 if (--to) {
789 goto repeat;
790 }
791 return (1); /* not complete */
792}
793
794static uint8_t
795musbotg_data_tx(struct musbotg_td *td)
796{
797 struct usb_page_search buf_res;
798 struct musbotg_softc *sc;
799 uint16_t count;
800 uint8_t csr;
801 uint8_t to;
802
803 to = 8; /* don't loop forever! */
804
805 /* get pointer to softc */
806 sc = MUSBOTG_PC2SC(td->pc);
807
808 /* select endpoint */
809 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->ep_no);
810
811repeat:
812
813 /* read out FIFO status */
814 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
815
816 DPRINTFN(4, "csr=0x%02x\n", csr);
817
818 if (csr & (MUSB2_MASK_CSRL_TXINCOMP |
819 MUSB2_MASK_CSRL_TXUNDERRUN)) {
820 /* clear status bits */
821 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
822 }
823 if (csr & MUSB2_MASK_CSRL_TXPKTRDY) {
824 return (1); /* not complete */
825 }
826 /* check for short packet */
827 count = td->max_frame_size;
828 if (td->remainder < count) {
829 /* we have a short packet */
830 td->short_pkt = 1;
831 count = td->remainder;
832 }
833 while (count > 0) {
834 uint32_t temp;
835
836 usbd_get_page(td->pc, td->offset, &buf_res);
837
838 /* get correct length */
839 if (buf_res.length > count) {
840 buf_res.length = count;
841 }
842 /* check for unaligned memory address */
843 if (USB_P2U(buf_res.buffer) & 3) {
844
845 usbd_copy_out(td->pc, td->offset,
846 sc->sc_bounce_buf, count);
847
848 temp = count & ~3;
849
850 if (temp) {
851 /* transmit data 4 bytes at a time */
852 bus_space_write_multi_4(sc->sc_io_tag,
853 sc->sc_io_hdl, MUSB2_REG_EPFIFO(td->ep_no),
854 sc->sc_bounce_buf, temp / 4);
855 }
856 temp = count & 3;
857 if (temp) {
858 /* receive data 1 byte at a time */
859 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
860 MUSB2_REG_EPFIFO(td->ep_no),
861 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
862 }
863 /* update offset and remainder */
864 td->offset += count;
865 td->remainder -= count;
866 break;
867 }
868 /* check if we can optimise */
869 if (buf_res.length >= 4) {
870
871 /* transmit data 4 bytes at a time */
872 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
873 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
874 buf_res.length / 4);
875
876 temp = buf_res.length & ~3;
877
878 /* update counters */
879 count -= temp;
880 td->offset += temp;
881 td->remainder -= temp;
882 continue;
883 }
884 /* transmit data */
885 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
886 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
887 buf_res.length);
888
889 /* update counters */
890 count -= buf_res.length;
891 td->offset += buf_res.length;
892 td->remainder -= buf_res.length;
893 }
894
895 /* write command */
896 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
897 MUSB2_MASK_CSRL_TXPKTRDY);
898
899 /* check remainder */
900 if (td->remainder == 0) {
901 if (td->short_pkt) {
902 return (0); /* complete */
903 }
904 /* else we need to transmit a short packet */
905 }
906 if (--to) {
907 goto repeat;
908 }
909 return (1); /* not complete */
910}
911
912static uint8_t
913musbotg_xfer_do_fifo(struct usb_xfer *xfer)
914{
915 struct musbotg_softc *sc;
916 struct musbotg_td *td;
917
918 DPRINTFN(8, "\n");
919
920 td = xfer->td_transfer_cache;
921 while (1) {
922 if ((td->func) (td)) {
923 /* operation in progress */
924 break;
925 }
926 if (((void *)td) == xfer->td_transfer_last) {
927 goto done;
928 }
929 if (td->error) {
930 goto done;
931 } else if (td->remainder > 0) {
932 /*
933 * We had a short transfer. If there is no alternate
934 * next, stop processing !
935 */
936 if (!td->alt_next) {
937 goto done;
938 }
939 }
940 /*
941 * Fetch the next transfer descriptor and transfer
942 * some flags to the next transfer descriptor
943 */
944 td = td->obj_next;
945 xfer->td_transfer_cache = td;
946 }
947 return (1); /* not complete */
948
949done:
950 sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
951
952 /* compute all actual lengths */
953
954 musbotg_standard_done(xfer);
955
956 return (0); /* complete */
957}
958
959static void
960musbotg_interrupt_poll(struct musbotg_softc *sc)
961{
962 struct usb_xfer *xfer;
963
964repeat:
965 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
966 if (!musbotg_xfer_do_fifo(xfer)) {
967 /* queue has been modified */
968 goto repeat;
969 }
970 }
971}
972
973void
974musbotg_vbus_interrupt(struct musbotg_softc *sc, uint8_t is_on)
975{
976 DPRINTFN(4, "vbus = %u\n", is_on);
977
978 USB_BUS_LOCK(&sc->sc_bus);
979 if (is_on) {
980 if (!sc->sc_flags.status_vbus) {
981 sc->sc_flags.status_vbus = 1;
982
983 /* complete root HUB interrupt endpoint */
984 musbotg_root_intr(sc);
985 }
986 } else {
987 if (sc->sc_flags.status_vbus) {
988 sc->sc_flags.status_vbus = 0;
989 sc->sc_flags.status_bus_reset = 0;
990 sc->sc_flags.status_suspend = 0;
991 sc->sc_flags.change_suspend = 0;
992 sc->sc_flags.change_connect = 1;
993
994 /* complete root HUB interrupt endpoint */
995 musbotg_root_intr(sc);
996 }
997 }
998
999 USB_BUS_UNLOCK(&sc->sc_bus);
1000}
1001
1002void
1003musbotg_interrupt(struct musbotg_softc *sc)
1004{
1005 uint16_t rx_status;
1006 uint16_t tx_status;
1007 uint8_t usb_status;
1008 uint8_t temp;
1009 uint8_t to = 2;
1010
1011 USB_BUS_LOCK(&sc->sc_bus);
1012
1013repeat:
1014
1015 /* read all interrupt registers */
1016 usb_status = MUSB2_READ_1(sc, MUSB2_REG_INTUSB);
1017
1018 /* read all FIFO interrupts */
1019 rx_status = MUSB2_READ_2(sc, MUSB2_REG_INTRX);
1020 tx_status = MUSB2_READ_2(sc, MUSB2_REG_INTTX);
1021
1022 /* check for any bus state change interrupts */
1023
1024 if (usb_status & (MUSB2_MASK_IRESET |
1025 MUSB2_MASK_IRESUME | MUSB2_MASK_ISUSP)) {
1026
1027 DPRINTFN(4, "real bus interrupt 0x%08x\n", usb_status);
1028
1029 if (usb_status & MUSB2_MASK_IRESET) {
1030
1031 /* set correct state */
1032 sc->sc_flags.status_bus_reset = 1;
1033 sc->sc_flags.status_suspend = 0;
1034 sc->sc_flags.change_suspend = 0;
1035 sc->sc_flags.change_connect = 1;
1036
1037 /* determine line speed */
1038 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
1039 if (temp & MUSB2_MASK_HSMODE)
1040 sc->sc_flags.status_high_speed = 1;
1041 else
1042 sc->sc_flags.status_high_speed = 0;
1043
1044 /*
1045 * After reset all interrupts are on and we need to
1046 * turn them off!
1047 */
1048 temp = MUSB2_MASK_IRESET;
1049 /* disable resume interrupt */
1050 temp &= ~MUSB2_MASK_IRESUME;
1051 /* enable suspend interrupt */
1052 temp |= MUSB2_MASK_ISUSP;
1053 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1054 /* disable TX and RX interrupts */
1055 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1056 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1057 }
1058 /*
1059 * If RXRSM and RXSUSP is set at the same time we interpret
1060 * that like RESUME. Resume is set when there is at least 3
1061 * milliseconds of inactivity on the USB BUS.
1062 */
1063 if (usb_status & MUSB2_MASK_IRESUME) {
1064 if (sc->sc_flags.status_suspend) {
1065 sc->sc_flags.status_suspend = 0;
1066 sc->sc_flags.change_suspend = 1;
1067
1068 temp = MUSB2_READ_1(sc, MUSB2_REG_INTUSBE);
1069 /* disable resume interrupt */
1070 temp &= ~MUSB2_MASK_IRESUME;
1071 /* enable suspend interrupt */
1072 temp |= MUSB2_MASK_ISUSP;
1073 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1074 }
1075 } else if (usb_status & MUSB2_MASK_ISUSP) {
1076 if (!sc->sc_flags.status_suspend) {
1077 sc->sc_flags.status_suspend = 1;
1078 sc->sc_flags.change_suspend = 1;
1079
1080 temp = MUSB2_READ_1(sc, MUSB2_REG_INTUSBE);
1081 /* disable suspend interrupt */
1082 temp &= ~MUSB2_MASK_ISUSP;
1083 /* enable resume interrupt */
1084 temp |= MUSB2_MASK_IRESUME;
1085 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1086 }
1087 }
1088 /* complete root HUB interrupt endpoint */
1089 musbotg_root_intr(sc);
1090 }
1091 /* check for any endpoint interrupts */
1092
1093 if (rx_status || tx_status) {
1094 DPRINTFN(4, "real endpoint interrupt "
1095 "rx=0x%04x, tx=0x%04x\n", rx_status, tx_status);
1096 }
1097 /* poll one time regardless of FIFO status */
1098
1099 musbotg_interrupt_poll(sc);
1100
1101 if (--to)
1102 goto repeat;
1103
1104 USB_BUS_UNLOCK(&sc->sc_bus);
1105}
1106
1107static void
1108musbotg_setup_standard_chain_sub(struct musbotg_std_temp *temp)
1109{
1110 struct musbotg_td *td;
1111
1112 /* get current Transfer Descriptor */
1113 td = temp->td_next;
1114 temp->td = td;
1115
1116 /* prepare for next TD */
1117 temp->td_next = td->obj_next;
1118
1119 /* fill out the Transfer Descriptor */
1120 td->func = temp->func;
1121 td->pc = temp->pc;
1122 td->offset = temp->offset;
1123 td->remainder = temp->len;
1124 td->error = 0;
1125 td->did_stall = temp->did_stall;
1126 td->short_pkt = temp->short_pkt;
1127 td->alt_next = temp->setup_alt_next;
1128}
1129
1130static void
1131musbotg_setup_standard_chain(struct usb_xfer *xfer)
1132{
1133 struct musbotg_std_temp temp;
1134 struct musbotg_softc *sc;
1135 struct musbotg_td *td;
1136 uint32_t x;
1137 uint8_t ep_no;
1138
1139 DPRINTFN(8, "addr=%d endpt=%d sumlen=%d speed=%d\n",
1140 xfer->address, UE_GET_ADDR(xfer->endpointno),
1141 xfer->sumlen, usbd_get_speed(xfer->xroot->udev));
1142
1143 temp.max_frame_size = xfer->max_frame_size;
1144
1145 td = xfer->td_start[0];
1146 xfer->td_transfer_first = td;
1147 xfer->td_transfer_cache = td;
1148
1149 /* setup temp */
1150
1151 temp.pc = NULL;
1152 temp.td = NULL;
1153 temp.td_next = xfer->td_start[0];
1154 temp.offset = 0;
1155 temp.setup_alt_next = xfer->flags_int.short_frames_ok;
1156 temp.did_stall = !xfer->flags_int.control_stall;
1157
1158 sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
1159 ep_no = (xfer->endpointno & UE_ADDR);
1160
1161 /* check if we should prepend a setup message */
1162
1163 if (xfer->flags_int.control_xfr) {
1164 if (xfer->flags_int.control_hdr) {
1165
1166 temp.func = &musbotg_setup_rx;
1167 temp.len = xfer->frlengths[0];
1168 temp.pc = xfer->frbuffers + 0;
1169 temp.short_pkt = temp.len ? 1 : 0;
1170
1171 musbotg_setup_standard_chain_sub(&temp);
1172 }
1173 x = 1;
1174 } else {
1175 x = 0;
1176 }
1177
1178 if (x != xfer->nframes) {
1179 if (xfer->endpointno & UE_DIR_IN) {
1180 if (xfer->flags_int.control_xfr)
1181 temp.func = &musbotg_setup_data_tx;
1182 else
1183 temp.func = &musbotg_data_tx;
1184 } else {
1185 if (xfer->flags_int.control_xfr)
1186 temp.func = &musbotg_setup_data_rx;
1187 else
1188 temp.func = &musbotg_data_rx;
1189 }
1190
1191 /* setup "pc" pointer */
1192 temp.pc = xfer->frbuffers + x;
1193 }
1194 while (x != xfer->nframes) {
1195
1196 /* DATA0 / DATA1 message */
1197
1198 temp.len = xfer->frlengths[x];
1199
1200 x++;
1201
1202 if (x == xfer->nframes) {
1203 if (xfer->flags_int.control_xfr) {
1204 if (xfer->flags_int.control_act) {
1205 temp.setup_alt_next = 0;
1206 }
1207 } else {
1208 temp.setup_alt_next = 0;
1209 }
1210 }
1211 if (temp.len == 0) {
1212
1213 /* make sure that we send an USB packet */
1214
1215 temp.short_pkt = 0;
1216
1217 } else {
1218
1219 /* regular data transfer */
1220
1221 temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
1222 }
1223
1224 musbotg_setup_standard_chain_sub(&temp);
1225
1226 if (xfer->flags_int.isochronous_xfr) {
1227 temp.offset += temp.len;
1228 } else {
1229 /* get next Page Cache pointer */
1230 temp.pc = xfer->frbuffers + x;
1231 }
1232 }
1233
1234 /* check for control transfer */
1235 if (xfer->flags_int.control_xfr) {
1236
1237 /* always setup a valid "pc" pointer for status and sync */
1238 temp.pc = xfer->frbuffers + 0;
1239 temp.len = 0;
1240 temp.short_pkt = 0;
1241 temp.setup_alt_next = 0;
1242
1243 /* check if we should append a status stage */
1244 if (!xfer->flags_int.control_act) {
1245 /*
1246 * Send a DATA1 message and invert the current
1247 * endpoint direction.
1248 */
1249 temp.func = &musbotg_setup_status;
1250 musbotg_setup_standard_chain_sub(&temp);
1251 }
1252 }
1253 /* must have at least one frame! */
1254 td = temp.td;
1255 xfer->td_transfer_last = td;
1256}
1257
1258static void
1259musbotg_timeout(void *arg)
1260{
1261 struct usb_xfer *xfer = arg;
1262
1263 DPRINTFN(1, "xfer=%p\n", xfer);
1264
1265 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1266
1267 /* transfer is transferred */
1268 musbotg_device_done(xfer, USB_ERR_TIMEOUT);
1269}
1270
1271static void
1272musbotg_ep_int_set(struct usb_xfer *xfer, uint8_t on)
1273{
1274 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
1275 uint16_t temp;
1276 uint8_t ep_no = xfer->endpointno & UE_ADDR;
1277
1278 /*
1279 * Only enable the endpoint interrupt when we are
1280 * actually waiting for data, hence we are dealing
1281 * with level triggered interrupts !
1282 */
1283 if (ep_no == 0) {
1284 temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
1285 if (on)
1286 temp |= MUSB2_MASK_EPINT(0);
1287 else
1288 temp &= ~MUSB2_MASK_EPINT(0);
1289
1290 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
1291 } else {
1292 if (USB_GET_DATA_ISREAD(xfer)) {
1293 temp = MUSB2_READ_2(sc, MUSB2_REG_INTRXE);
1294 if (on)
1295 temp |= MUSB2_MASK_EPINT(ep_no);
1296 else
1297 temp &= ~MUSB2_MASK_EPINT(ep_no);
1298 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, temp);
1299
1300 } else {
1301 temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
1302 if (on)
1303 temp |= MUSB2_MASK_EPINT(ep_no);
1304 else
1305 temp &= ~MUSB2_MASK_EPINT(ep_no);
1306 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
1307 }
1308 }
1309}
1310
1311static void
1312musbotg_start_standard_chain(struct usb_xfer *xfer)
1313{
1314 DPRINTFN(8, "\n");
1315
1316 /* poll one time */
1317 if (musbotg_xfer_do_fifo(xfer)) {
1318
1319 musbotg_ep_int_set(xfer, 1);
1320
1321 DPRINTFN(14, "enabled interrupts on endpoint\n");
1322
1323 /* put transfer on interrupt queue */
1324 usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
1325
1326 /* start timeout, if any */
1327 if (xfer->timeout != 0) {
1328 usbd_transfer_timeout_ms(xfer,
1329 &musbotg_timeout, xfer->timeout);
1330 }
1331 }
1332}
1333
1334static void
1335musbotg_root_intr(struct musbotg_softc *sc)
1336{
1337 DPRINTFN(8, "\n");
1338
1339 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
1340
1341 /* set port bit */
1342 sc->sc_hub_idata[0] = 0x02; /* we only have one port */
1343
1344 uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata,
1345 sizeof(sc->sc_hub_idata));
1346}
1347
1348static usb_error_t
1349musbotg_standard_done_sub(struct usb_xfer *xfer)
1350{
1351 struct musbotg_td *td;
1352 uint32_t len;
1353 uint8_t error;
1354
1355 DPRINTFN(8, "\n");
1356
1357 td = xfer->td_transfer_cache;
1358
1359 do {
1360 len = td->remainder;
1361
1362 if (xfer->aframes != xfer->nframes) {
1363 /*
1364 * Verify the length and subtract
1365 * the remainder from "frlengths[]":
1366 */
1367 if (len > xfer->frlengths[xfer->aframes]) {
1368 td->error = 1;
1369 } else {
1370 xfer->frlengths[xfer->aframes] -= len;
1371 }
1372 }
1373 /* Check for transfer error */
1374 if (td->error) {
1375 /* the transfer is finished */
1376 error = 1;
1377 td = NULL;
1378 break;
1379 }
1380 /* Check for short transfer */
1381 if (len > 0) {
1382 if (xfer->flags_int.short_frames_ok) {
1383 /* follow alt next */
1384 if (td->alt_next) {
1385 td = td->obj_next;
1386 } else {
1387 td = NULL;
1388 }
1389 } else {
1390 /* the transfer is finished */
1391 td = NULL;
1392 }
1393 error = 0;
1394 break;
1395 }
1396 td = td->obj_next;
1397
1398 /* this USB frame is complete */
1399 error = 0;
1400 break;
1401
1402 } while (0);
1403
1404 /* update transfer cache */
1405
1406 xfer->td_transfer_cache = td;
1407
1408 return (error ?
1409 USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
1410}
1411
1412static void
1413musbotg_standard_done(struct usb_xfer *xfer)
1414{
1415 usb_error_t err = 0;
1416
1417 DPRINTFN(12, "xfer=%p endpoint=%p transfer done\n",
1418 xfer, xfer->endpoint);
1419
1420 /* reset scanner */
1421
1422 xfer->td_transfer_cache = xfer->td_transfer_first;
1423
1424 if (xfer->flags_int.control_xfr) {
1425
1426 if (xfer->flags_int.control_hdr) {
1427
1428 err = musbotg_standard_done_sub(xfer);
1429 }
1430 xfer->aframes = 1;
1431
1432 if (xfer->td_transfer_cache == NULL) {
1433 goto done;
1434 }
1435 }
1436 while (xfer->aframes != xfer->nframes) {
1437
1438 err = musbotg_standard_done_sub(xfer);
1439 xfer->aframes++;
1440
1441 if (xfer->td_transfer_cache == NULL) {
1442 goto done;
1443 }
1444 }
1445
1446 if (xfer->flags_int.control_xfr &&
1447 !xfer->flags_int.control_act) {
1448
1449 err = musbotg_standard_done_sub(xfer);
1450 }
1451done:
1452 musbotg_device_done(xfer, err);
1453}
1454
1455/*------------------------------------------------------------------------*
1456 * musbotg_device_done
1457 *
1458 * NOTE: this function can be called more than one time on the
1459 * same USB transfer!
1460 *------------------------------------------------------------------------*/
1461static void
1462musbotg_device_done(struct usb_xfer *xfer, usb_error_t error)
1463{
1464 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1465
1466 DPRINTFN(2, "xfer=%p, endpoint=%p, error=%d\n",
1467 xfer, xfer->endpoint, error);
1468
1469 if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) {
1470
1471 musbotg_ep_int_set(xfer, 0);
1472
1473 DPRINTFN(14, "disabled interrupts on endpoint\n");
1474 }
1475 /* dequeue transfer and start next transfer */
1476 usbd_transfer_done(xfer, error);
1477}
1478
1479static void
1480musbotg_xfer_stall(struct usb_xfer *xfer)
1481{
1482 musbotg_device_done(xfer, USB_ERR_STALLED);
1483}
1484
1485static void
1486musbotg_set_stall(struct usb_device *udev,
1487 struct usb_endpoint *ep, uint8_t *did_stall)
1488{
1489 struct musbotg_softc *sc;
1490 uint8_t ep_no;
1491
1492 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1493
1494 DPRINTFN(4, "endpoint=%p\n", ep);
1495
1496 /* set FORCESTALL */
1497 sc = MUSBOTG_BUS2SC(udev->bus);
1498
1499 ep_no = (ep->edesc->bEndpointAddress & UE_ADDR);
1500
1501 /* select endpoint */
1502 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
1503
1504 if (ep->edesc->bEndpointAddress & UE_DIR_IN) {
1505 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1506 MUSB2_MASK_CSRL_TXSENDSTALL);
1507 } else {
1508 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1509 MUSB2_MASK_CSRL_RXSENDSTALL);
1510 }
1511}
1512
1513static void
1514musbotg_clear_stall_sub(struct musbotg_softc *sc, uint16_t wMaxPacket,
1515 uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
1516{
1517 uint16_t mps;
1518 uint16_t temp;
1519 uint8_t csr;
1520
1521 if (ep_type == UE_CONTROL) {
1522 /* clearing stall is not needed */
1523 return;
1524 }
1525 /* select endpoint */
1526 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
1527
1528 /* compute max frame size */
1529 mps = wMaxPacket & 0x7FF;
1530 switch ((wMaxPacket >> 11) & 3) {
1531 case 1:
1532 mps *= 2;
1533 break;
1534 case 2:
1535 mps *= 3;
1536 break;
1537 default:
1538 break;
1539 }
1540
1541 if (ep_dir == UE_DIR_IN) {
1542
1543 temp = 0;
1544
1545 /* Configure endpoint */
1546 switch (ep_type) {
1547 case UE_INTERRUPT:
1548 MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1549 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1550 MUSB2_MASK_CSRH_TXMODE | temp);
1551 break;
1552 case UE_ISOCHRONOUS:
1553 MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1554 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1555 MUSB2_MASK_CSRH_TXMODE |
1556 MUSB2_MASK_CSRH_TXISO | temp);
1557 break;
1558 case UE_BULK:
1559 MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1560 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1561 MUSB2_MASK_CSRH_TXMODE | temp);
1562 break;
1563 default:
1564 break;
1565 }
1566
1567 /* Need to flush twice in case of double bufring */
1568 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1569 if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
1570 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1571 MUSB2_MASK_CSRL_TXFFLUSH);
1572 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1573 if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
1574 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1575 MUSB2_MASK_CSRL_TXFFLUSH);
1576 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1577 }
1578 }
1579 /* reset data toggle */
1580 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1581 MUSB2_MASK_CSRL_TXDT_CLR);
1582 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
1583 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1584
1585 /* set double/single buffering */
1586 temp = MUSB2_READ_2(sc, MUSB2_REG_TXDBDIS);
1587 if (mps <= (sc->sc_hw_ep_profile[ep_no].
1588 max_in_frame_size / 2)) {
1589 /* double buffer */
1590 temp &= ~(1 << ep_no);
1591 } else {
1592 /* single buffer */
1593 temp |= (1 << ep_no);
1594 }
1595 MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, temp);
1596
1597 /* clear sent stall */
1598 if (csr & MUSB2_MASK_CSRL_TXSENTSTALL) {
1599 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
1600 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1601 }
1602 } else {
1603
1604 temp = 0;
1605
1606 /* Configure endpoint */
1607 switch (ep_type) {
1608 case UE_INTERRUPT:
1609 MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1610 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
1611 MUSB2_MASK_CSRH_RXNYET | temp);
1612 break;
1613 case UE_ISOCHRONOUS:
1614 MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1615 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
1616 MUSB2_MASK_CSRH_RXNYET |
1617 MUSB2_MASK_CSRH_RXISO | temp);
1618 break;
1619 case UE_BULK:
1620 MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1621 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH, temp);
1622 break;
1623 default:
1624 break;
1625 }
1626
1627 /* Need to flush twice in case of double bufring */
1628 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1629 if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
1630 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1631 MUSB2_MASK_CSRL_RXFFLUSH);
1632 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1633 if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
1634 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1635 MUSB2_MASK_CSRL_RXFFLUSH);
1636 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1637 }
1638 }
1639 /* reset data toggle */
1640 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1641 MUSB2_MASK_CSRL_RXDT_CLR);
1642 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
1643 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1644
1645 /* set double/single buffering */
1646 temp = MUSB2_READ_2(sc, MUSB2_REG_RXDBDIS);
1647 if (mps <= (sc->sc_hw_ep_profile[ep_no].
1648 max_out_frame_size / 2)) {
1649 /* double buffer */
1650 temp &= ~(1 << ep_no);
1651 } else {
1652 /* single buffer */
1653 temp |= (1 << ep_no);
1654 }
1655 MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, temp);
1656
1657 /* clear sent stall */
1658 if (csr & MUSB2_MASK_CSRL_RXSENTSTALL) {
1659 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
1660 }
1661 }
1662}
1663
1664static void
1665musbotg_clear_stall(struct usb_device *udev, struct usb_endpoint *ep)
1666{
1667 struct musbotg_softc *sc;
1668 struct usb_endpoint_descriptor *ed;
1669
1670 DPRINTFN(4, "endpoint=%p\n", ep);
1671
1672 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1673
1674 /* check mode */
1675 if (udev->flags.usb_mode != USB_MODE_DEVICE) {
1676 /* not supported */
1677 return;
1678 }
1679 /* get softc */
1680 sc = MUSBOTG_BUS2SC(udev->bus);
1681
1682 /* get endpoint descriptor */
1683 ed = ep->edesc;
1684
1685 /* reset endpoint */
1686 musbotg_clear_stall_sub(sc,
1687 UGETW(ed->wMaxPacketSize),
1688 (ed->bEndpointAddress & UE_ADDR),
1689 (ed->bmAttributes & UE_XFERTYPE),
1690 (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
1691}
1692
1693usb_error_t
1694musbotg_init(struct musbotg_softc *sc)
1695{
1696 struct usb_hw_ep_profile *pf;
1697 uint16_t offset;
1698 uint8_t nrx;
1699 uint8_t ntx;
1700 uint8_t temp;
1701 uint8_t fsize;
1702 uint8_t frx;
1703 uint8_t ftx;
1704 uint8_t dynfifo;
1705
1706 DPRINTFN(1, "start\n");
1707
1708 /* set up the bus structure */
1709 sc->sc_bus.usbrev = USB_REV_2_0;
1710 sc->sc_bus.methods = &musbotg_bus_methods;
1711
1712 USB_BUS_LOCK(&sc->sc_bus);
1713
1714 /* turn on clocks */
1715
1716 if (sc->sc_clocks_on) {
1717 (sc->sc_clocks_on) (sc->sc_clocks_arg);
1718 }
1719 /* wait a little for things to stabilise */
1720 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
1721
1722 /* disable all interrupts */
1723
1724 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
1725 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1726 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1727
1728 /* disable pullup */
1729
1730 musbotg_pull_common(sc, 0);
1731
1732 /* wait a little bit (10ms) */
1733 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100);
1734
1735 /* disable double packet buffering */
1736 MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, 0xFFFF);
1737 MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, 0xFFFF);
1738
1739 /* enable HighSpeed and ISO Update flags */
1740
1741 MUSB2_WRITE_1(sc, MUSB2_REG_POWER,
1742 MUSB2_MASK_HSENAB | MUSB2_MASK_ISOUPD);
1743
1744 /* clear Session bit, if set */
1745
1746 temp = MUSB2_READ_1(sc, MUSB2_REG_DEVCTL);
1747 temp &= ~MUSB2_MASK_SESS;
1748 MUSB2_WRITE_1(sc, MUSB2_REG_DEVCTL, temp);
1749
1750 DPRINTF("DEVCTL=0x%02x\n", temp);
1751
1752 /* disable testmode */
1753
1754 MUSB2_WRITE_1(sc, MUSB2_REG_TESTMODE, 0);
1755
1756 /* set default value */
1757
1758 MUSB2_WRITE_1(sc, MUSB2_REG_MISC, 0);
1759
1760 /* select endpoint index 0 */
1761
1762 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
1763
1764 /* read out number of endpoints */
1765
1766 nrx =
1767 (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) / 16);
1768
1769 ntx =
1770 (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) % 16);
1771
1772 /* these numbers exclude the control endpoint */
1773
1774 DPRINTFN(2, "RX/TX endpoints: %u/%u\n", nrx, ntx);
1775
1776 sc->sc_ep_max = (nrx > ntx) ? nrx : ntx;
1777 if (sc->sc_ep_max == 0) {
1778 DPRINTFN(2, "ERROR: Looks like the clocks are off!\n");
1779 }
1780 /* read out configuration data */
1781
1782 sc->sc_conf_data = MUSB2_READ_1(sc, MUSB2_REG_CONFDATA);
1783
1784 DPRINTFN(2, "Config Data: 0x%02x\n",
1785 sc->sc_conf_data);
1786
1787 dynfifo = (sc->sc_conf_data & MUSB2_MASK_CD_DYNFIFOSZ) ? 1 : 0;
1788
1789 if (dynfifo) {
1790 device_printf(sc->sc_bus.bdev, "Dynamic FIFO sizing detected, "
1791 "assuming 16Kbytes of FIFO RAM\n");
1792 }
1793
1794 DPRINTFN(2, "HW version: 0x%04x\n",
1795 MUSB2_READ_1(sc, MUSB2_REG_HWVERS));
1796
1797 /* initialise endpoint profiles */
1798
1799 offset = 0;
1800
1801 for (temp = 1; temp <= sc->sc_ep_max; temp++) {
1802 pf = sc->sc_hw_ep_profile + temp;
1803
1804 /* select endpoint */
1805 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, temp);
1806
1807 fsize = MUSB2_READ_1(sc, MUSB2_REG_FSIZE);
1808 frx = (fsize & MUSB2_MASK_RX_FSIZE) / 16;
1809 ftx = (fsize & MUSB2_MASK_TX_FSIZE);
1810
1811 DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u, DYN=%d\n",
1812 temp, ftx, frx, dynfifo);
1813
1814 if (dynfifo) {
1815 if (frx && (temp <= nrx)) {
1816 if (temp < 8) {
1817 frx = 10; /* 1K */
1818 MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ,
1819 MUSB2_VAL_FIFOSZ_512 |
1820 MUSB2_MASK_FIFODB);
1821 } else {
1822 frx = 7; /* 128 bytes */
1823 MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ,
1824 MUSB2_VAL_FIFOSZ_128);
1825 }
1826
1827 MUSB2_WRITE_2(sc, MUSB2_REG_RXFIFOADD,
1828 offset >> 3);
1829
1830 offset += (1 << frx);
1831 }
1832 if (ftx && (temp <= ntx)) {
1833 if (temp < 8) {
1834 ftx = 10; /* 1K */
1835 MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ,
1836 MUSB2_VAL_FIFOSZ_512 |
1837 MUSB2_MASK_FIFODB);
1838 } else {
1839 ftx = 7; /* 128 bytes */
1840 MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ,
1841 MUSB2_VAL_FIFOSZ_128);
1842 }
1843
1844 MUSB2_WRITE_2(sc, MUSB2_REG_TXFIFOADD,
1845 offset >> 3);
1846
1847 offset += (1 << ftx);
1848 }
1849 }
1850
1851 if (frx && ftx && (temp <= nrx) && (temp <= ntx)) {
1852 pf->max_in_frame_size = 1 << ftx;
1853 pf->max_out_frame_size = 1 << frx;
1854 pf->is_simplex = 0; /* duplex */
1855 pf->support_multi_buffer = 1;
1856 pf->support_bulk = 1;
1857 pf->support_interrupt = 1;
1858 pf->support_isochronous = 1;
1859 pf->support_in = 1;
1860 pf->support_out = 1;
1861 } else if (frx && (temp <= nrx)) {
1862 pf->max_out_frame_size = 1 << frx;
1863 pf->is_simplex = 1; /* simplex */
1864 pf->support_multi_buffer = 1;
1865 pf->support_bulk = 1;
1866 pf->support_interrupt = 1;
1867 pf->support_isochronous = 1;
1868 pf->support_out = 1;
1869 } else if (ftx && (temp <= ntx)) {
1870 pf->max_in_frame_size = 1 << ftx;
1871 pf->is_simplex = 1; /* simplex */
1872 pf->support_multi_buffer = 1;
1873 pf->support_bulk = 1;
1874 pf->support_interrupt = 1;
1875 pf->support_isochronous = 1;
1876 pf->support_in = 1;
1877 }
1878 }
1879
1880 DPRINTFN(2, "Dynamic FIFO size = %d bytes\n", offset);
1881
1882 /* turn on default interrupts */
1883
1884 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE,
1885 MUSB2_MASK_IRESET);
1886
1887 musbotg_clocks_off(sc);
1888
1889 USB_BUS_UNLOCK(&sc->sc_bus);
1890
1891 /* catch any lost interrupts */
1892
1893 musbotg_do_poll(&sc->sc_bus);
1894
1895 return (0); /* success */
1896}
1897
1898void
1899musbotg_uninit(struct musbotg_softc *sc)
1900{
1901 USB_BUS_LOCK(&sc->sc_bus);
1902
1903 /* disable all interrupts */
1904 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
1905 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1906 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1907
1908 sc->sc_flags.port_powered = 0;
1909 sc->sc_flags.status_vbus = 0;
1910 sc->sc_flags.status_bus_reset = 0;
1911 sc->sc_flags.status_suspend = 0;
1912 sc->sc_flags.change_suspend = 0;
1913 sc->sc_flags.change_connect = 1;
1914
1915 musbotg_pull_down(sc);
1916 musbotg_clocks_off(sc);
1917 USB_BUS_UNLOCK(&sc->sc_bus);
1918}
1919
1920static void
1921musbotg_suspend(struct musbotg_softc *sc)
1922{
1923 /* TODO */
1924}
1925
1926static void
1927musbotg_resume(struct musbotg_softc *sc)
1928{
1929 /* TODO */
1930}
1931
1932static void
1933musbotg_do_poll(struct usb_bus *bus)
1934{
1935 struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
1936
1937 USB_BUS_LOCK(&sc->sc_bus);
1938 musbotg_interrupt_poll(sc);
1939 USB_BUS_UNLOCK(&sc->sc_bus);
1940}
1941
1942/*------------------------------------------------------------------------*
1943 * musbotg bulk support
1944 *------------------------------------------------------------------------*/
1945static void
1946musbotg_device_bulk_open(struct usb_xfer *xfer)
1947{
1948 return;
1949}
1950
1951static void
1952musbotg_device_bulk_close(struct usb_xfer *xfer)
1953{
1954 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1955}
1956
1957static void
1958musbotg_device_bulk_enter(struct usb_xfer *xfer)
1959{
1960 return;
1961}
1962
1963static void
1964musbotg_device_bulk_start(struct usb_xfer *xfer)
1965{
1966 /* setup TDs */
1967 musbotg_setup_standard_chain(xfer);
1968 musbotg_start_standard_chain(xfer);
1969}
1970
1971struct usb_pipe_methods musbotg_device_bulk_methods =
1972{
1973 .open = musbotg_device_bulk_open,
1974 .close = musbotg_device_bulk_close,
1975 .enter = musbotg_device_bulk_enter,
1976 .start = musbotg_device_bulk_start,
1977};
1978
1979/*------------------------------------------------------------------------*
1980 * musbotg control support
1981 *------------------------------------------------------------------------*/
1982static void
1983musbotg_device_ctrl_open(struct usb_xfer *xfer)
1984{
1985 return;
1986}
1987
1988static void
1989musbotg_device_ctrl_close(struct usb_xfer *xfer)
1990{
1991 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1992}
1993
1994static void
1995musbotg_device_ctrl_enter(struct usb_xfer *xfer)
1996{
1997 return;
1998}
1999
2000static void
2001musbotg_device_ctrl_start(struct usb_xfer *xfer)
2002{
2003 /* setup TDs */
2004 musbotg_setup_standard_chain(xfer);
2005 musbotg_start_standard_chain(xfer);
2006}
2007
2008struct usb_pipe_methods musbotg_device_ctrl_methods =
2009{
2010 .open = musbotg_device_ctrl_open,
2011 .close = musbotg_device_ctrl_close,
2012 .enter = musbotg_device_ctrl_enter,
2013 .start = musbotg_device_ctrl_start,
2014};
2015
2016/*------------------------------------------------------------------------*
2017 * musbotg interrupt support
2018 *------------------------------------------------------------------------*/
2019static void
2020musbotg_device_intr_open(struct usb_xfer *xfer)
2021{
2022 return;
2023}
2024
2025static void
2026musbotg_device_intr_close(struct usb_xfer *xfer)
2027{
2028 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2029}
2030
2031static void
2032musbotg_device_intr_enter(struct usb_xfer *xfer)
2033{
2034 return;
2035}
2036
2037static void
2038musbotg_device_intr_start(struct usb_xfer *xfer)
2039{
2040 /* setup TDs */
2041 musbotg_setup_standard_chain(xfer);
2042 musbotg_start_standard_chain(xfer);
2043}
2044
2045struct usb_pipe_methods musbotg_device_intr_methods =
2046{
2047 .open = musbotg_device_intr_open,
2048 .close = musbotg_device_intr_close,
2049 .enter = musbotg_device_intr_enter,
2050 .start = musbotg_device_intr_start,
2051};
2052
2053/*------------------------------------------------------------------------*
2054 * musbotg full speed isochronous support
2055 *------------------------------------------------------------------------*/
2056static void
2057musbotg_device_isoc_open(struct usb_xfer *xfer)
2058{
2059 return;
2060}
2061
2062static void
2063musbotg_device_isoc_close(struct usb_xfer *xfer)
2064{
2065 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2066}
2067
2068static void
2069musbotg_device_isoc_enter(struct usb_xfer *xfer)
2070{
2071 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
2072 uint32_t temp;
2073 uint32_t nframes;
2074 uint32_t fs_frames;
2075
2076 DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
2077 xfer, xfer->endpoint->isoc_next, xfer->nframes);
2078
2079 /* get the current frame index */
2080
2081 nframes = MUSB2_READ_2(sc, MUSB2_REG_FRAME);
2082
2083 /*
2084 * check if the frame index is within the window where the frames
2085 * will be inserted
2086 */
2087 temp = (nframes - xfer->endpoint->isoc_next) & MUSB2_MASK_FRAME;
2088
2089 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
2090 fs_frames = (xfer->nframes + 7) / 8;
2091 } else {
2092 fs_frames = xfer->nframes;
2093 }
2094
2095 if ((xfer->endpoint->is_synced == 0) ||
2096 (temp < fs_frames)) {
2097 /*
2098 * If there is data underflow or the pipe queue is
2099 * empty we schedule the transfer a few frames ahead
2100 * of the current frame position. Else two isochronous
2101 * transfers might overlap.
2102 */
2103 xfer->endpoint->isoc_next = (nframes + 3) & MUSB2_MASK_FRAME;
2104 xfer->endpoint->is_synced = 1;
2105 DPRINTFN(2, "start next=%d\n", xfer->endpoint->isoc_next);
2106 }
2107 /*
2108 * compute how many milliseconds the insertion is ahead of the
2109 * current frame position:
2110 */
2111 temp = (xfer->endpoint->isoc_next - nframes) & MUSB2_MASK_FRAME;
2112
2113 /*
2114 * pre-compute when the isochronous transfer will be finished:
2115 */
2116 xfer->isoc_time_complete =
2117 usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2118 fs_frames;
2119
2120 /* compute frame number for next insertion */
2121 xfer->endpoint->isoc_next += fs_frames;
2122
2123 /* setup TDs */
2124 musbotg_setup_standard_chain(xfer);
2125}
2126
2127static void
2128musbotg_device_isoc_start(struct usb_xfer *xfer)
2129{
2130 /* start TD chain */
2131 musbotg_start_standard_chain(xfer);
2132}
2133
2134struct usb_pipe_methods musbotg_device_isoc_methods =
2135{
2136 .open = musbotg_device_isoc_open,
2137 .close = musbotg_device_isoc_close,
2138 .enter = musbotg_device_isoc_enter,
2139 .start = musbotg_device_isoc_start,
2140};
2141
2142/*------------------------------------------------------------------------*
2143 * musbotg root control support
2144 *------------------------------------------------------------------------*
2145 * Simulate a hardware HUB by handling all the necessary requests.
2146 *------------------------------------------------------------------------*/
2147
2148static const struct usb_device_descriptor musbotg_devd = {
2149 .bLength = sizeof(struct usb_device_descriptor),
2150 .bDescriptorType = UDESC_DEVICE,
2151 .bcdUSB = {0x00, 0x02},
2152 .bDeviceClass = UDCLASS_HUB,
2153 .bDeviceSubClass = UDSUBCLASS_HUB,
2154 .bDeviceProtocol = UDPROTO_HSHUBSTT,
2155 .bMaxPacketSize = 64,
2156 .bcdDevice = {0x00, 0x01},
2157 .iManufacturer = 1,
2158 .iProduct = 2,
2159 .bNumConfigurations = 1,
2160};
2161
2162static const struct usb_device_qualifier musbotg_odevd = {
2163 .bLength = sizeof(struct usb_device_qualifier),
2164 .bDescriptorType = UDESC_DEVICE_QUALIFIER,
2165 .bcdUSB = {0x00, 0x02},
2166 .bDeviceClass = UDCLASS_HUB,
2167 .bDeviceSubClass = UDSUBCLASS_HUB,
2168 .bDeviceProtocol = UDPROTO_FSHUB,
2169 .bMaxPacketSize0 = 0,
2170 .bNumConfigurations = 0,
2171};
2172
2173static const struct musbotg_config_desc musbotg_confd = {
2174 .confd = {
2175 .bLength = sizeof(struct usb_config_descriptor),
2176 .bDescriptorType = UDESC_CONFIG,
2177 .wTotalLength[0] = sizeof(musbotg_confd),
2178 .bNumInterface = 1,
2179 .bConfigurationValue = 1,
2180 .iConfiguration = 0,
2181 .bmAttributes = UC_SELF_POWERED,
2182 .bMaxPower = 0,
2183 },
2184 .ifcd = {
2185 .bLength = sizeof(struct usb_interface_descriptor),
2186 .bDescriptorType = UDESC_INTERFACE,
2187 .bNumEndpoints = 1,
2188 .bInterfaceClass = UICLASS_HUB,
2189 .bInterfaceSubClass = UISUBCLASS_HUB,
2190 .bInterfaceProtocol = 0,
2191 },
2192 .endpd = {
2193 .bLength = sizeof(struct usb_endpoint_descriptor),
2194 .bDescriptorType = UDESC_ENDPOINT,
2195 .bEndpointAddress = (UE_DIR_IN | MUSBOTG_INTR_ENDPT),
2196 .bmAttributes = UE_INTERRUPT,
2197 .wMaxPacketSize[0] = 8,
2198 .bInterval = 255,
2199 },
2200};
2201
2202#define HSETW(ptr, val) ptr = { (uint8_t)(val), (uint8_t)((val) >> 8) }
2203
2204static const struct usb_hub_descriptor_min musbotg_hubd = {
2205 .bDescLength = sizeof(musbotg_hubd),
2206 .bDescriptorType = UDESC_HUB,
2207 .bNbrPorts = 1,
2208 HSETW(.wHubCharacteristics, (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL)),
2209 .bPwrOn2PwrGood = 50,
2210 .bHubContrCurrent = 0,
2211 .DeviceRemovable = {0}, /* port is removable */
2212};
2213
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Thanks to Mentor Graphics for providing a reference driver for this USB chip
29 * at their homepage.
30 */
31
32/*
33 * This file contains the driver for the Mentor Graphics Inventra USB
34 * 2.0 High Speed Dual-Role controller.
35 *
36 * NOTE: The current implementation only supports Device Side Mode!
37 */
38
39#ifdef USB_GLOBAL_INCLUDE_FILE
40#include USB_GLOBAL_INCLUDE_FILE
41#else
42#include <sys/stdint.h>
43#include <sys/stddef.h>
44#include <sys/param.h>
45#include <sys/queue.h>
46#include <sys/types.h>
47#include <sys/systm.h>
48#include <sys/kernel.h>
49#include <sys/bus.h>
50#include <sys/module.h>
51#include <sys/lock.h>
52#include <sys/mutex.h>
53#include <sys/condvar.h>
54#include <sys/sysctl.h>
55#include <sys/sx.h>
56#include <sys/unistd.h>
57#include <sys/callout.h>
58#include <sys/malloc.h>
59#include <sys/priv.h>
60
61#include <dev/usb/usb.h>
62#include <dev/usb/usbdi.h>
63
64#define USB_DEBUG_VAR musbotgdebug
65
66#include <dev/usb/usb_core.h>
67#include <dev/usb/usb_debug.h>
68#include <dev/usb/usb_busdma.h>
69#include <dev/usb/usb_process.h>
70#include <dev/usb/usb_transfer.h>
71#include <dev/usb/usb_device.h>
72#include <dev/usb/usb_hub.h>
73#include <dev/usb/usb_util.h>
74
75#include <dev/usb/usb_controller.h>
76#include <dev/usb/usb_bus.h>
77#endif /* USB_GLOBAL_INCLUDE_FILE */
78
79#include <dev/usb/controller/musb_otg.h>
80
81#define MUSBOTG_INTR_ENDPT 1
82
83#define MUSBOTG_BUS2SC(bus) \
84 ((struct musbotg_softc *)(((uint8_t *)(bus)) - \
85 USB_P2U(&(((struct musbotg_softc *)0)->sc_bus))))
86
87#define MUSBOTG_PC2SC(pc) \
88 MUSBOTG_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus)
89
90#ifdef USB_DEBUG
91static int musbotgdebug = 0;
92
93static SYSCTL_NODE(_hw_usb, OID_AUTO, musbotg, CTLFLAG_RW, 0, "USB musbotg");
94SYSCTL_INT(_hw_usb_musbotg, OID_AUTO, debug, CTLFLAG_RW,
95 &musbotgdebug, 0, "Debug level");
96#endif
97
98/* prototypes */
99
100struct usb_bus_methods musbotg_bus_methods;
101struct usb_pipe_methods musbotg_device_bulk_methods;
102struct usb_pipe_methods musbotg_device_ctrl_methods;
103struct usb_pipe_methods musbotg_device_intr_methods;
104struct usb_pipe_methods musbotg_device_isoc_methods;
105
106static musbotg_cmd_t musbotg_setup_rx;
107static musbotg_cmd_t musbotg_setup_data_rx;
108static musbotg_cmd_t musbotg_setup_data_tx;
109static musbotg_cmd_t musbotg_setup_status;
110static musbotg_cmd_t musbotg_data_rx;
111static musbotg_cmd_t musbotg_data_tx;
112static void musbotg_device_done(struct usb_xfer *, usb_error_t);
113static void musbotg_do_poll(struct usb_bus *);
114static void musbotg_standard_done(struct usb_xfer *);
115static void musbotg_interrupt_poll(struct musbotg_softc *);
116static void musbotg_root_intr(struct musbotg_softc *);
117
118/*
119 * Here is a configuration that the chip supports.
120 */
121static const struct usb_hw_ep_profile musbotg_ep_profile[1] = {
122
123 [0] = {
124 .max_in_frame_size = 64,/* fixed */
125 .max_out_frame_size = 64, /* fixed */
126 .is_simplex = 1,
127 .support_control = 1,
128 }
129};
130
131static void
132musbotg_get_hw_ep_profile(struct usb_device *udev,
133 const struct usb_hw_ep_profile **ppf, uint8_t ep_addr)
134{
135 struct musbotg_softc *sc;
136
137 sc = MUSBOTG_BUS2SC(udev->bus);
138
139 if (ep_addr == 0) {
140 /* control endpoint */
141 *ppf = musbotg_ep_profile;
142 } else if (ep_addr <= sc->sc_ep_max) {
143 /* other endpoints */
144 *ppf = sc->sc_hw_ep_profile + ep_addr;
145 } else {
146 *ppf = NULL;
147 }
148}
149
150static void
151musbotg_clocks_on(struct musbotg_softc *sc)
152{
153 if (sc->sc_flags.clocks_off &&
154 sc->sc_flags.port_powered) {
155
156 DPRINTFN(4, "\n");
157
158 if (sc->sc_clocks_on) {
159 (sc->sc_clocks_on) (sc->sc_clocks_arg);
160 }
161 sc->sc_flags.clocks_off = 0;
162
163 /* XXX enable Transceiver */
164 }
165}
166
167static void
168musbotg_clocks_off(struct musbotg_softc *sc)
169{
170 if (!sc->sc_flags.clocks_off) {
171
172 DPRINTFN(4, "\n");
173
174 /* XXX disable Transceiver */
175
176 if (sc->sc_clocks_off) {
177 (sc->sc_clocks_off) (sc->sc_clocks_arg);
178 }
179 sc->sc_flags.clocks_off = 1;
180 }
181}
182
183static void
184musbotg_pull_common(struct musbotg_softc *sc, uint8_t on)
185{
186 uint8_t temp;
187
188 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
189 if (on)
190 temp |= MUSB2_MASK_SOFTC;
191 else
192 temp &= ~MUSB2_MASK_SOFTC;
193
194 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
195}
196
197static void
198musbotg_pull_up(struct musbotg_softc *sc)
199{
200 /* pullup D+, if possible */
201
202 if (!sc->sc_flags.d_pulled_up &&
203 sc->sc_flags.port_powered) {
204 sc->sc_flags.d_pulled_up = 1;
205 musbotg_pull_common(sc, 1);
206 }
207}
208
209static void
210musbotg_pull_down(struct musbotg_softc *sc)
211{
212 /* pulldown D+, if possible */
213
214 if (sc->sc_flags.d_pulled_up) {
215 sc->sc_flags.d_pulled_up = 0;
216 musbotg_pull_common(sc, 0);
217 }
218}
219
220static void
221musbotg_wakeup_peer(struct musbotg_softc *sc)
222{
223 uint8_t temp;
224
225 if (!(sc->sc_flags.status_suspend)) {
226 return;
227 }
228
229 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
230 temp |= MUSB2_MASK_RESUME;
231 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
232
233 /* wait 8 milliseconds */
234 /* Wait for reset to complete. */
235 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 125);
236
237 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
238 temp &= ~MUSB2_MASK_RESUME;
239 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
240}
241
242static void
243musbotg_set_address(struct musbotg_softc *sc, uint8_t addr)
244{
245 DPRINTFN(4, "addr=%d\n", addr);
246 addr &= 0x7F;
247 MUSB2_WRITE_1(sc, MUSB2_REG_FADDR, addr);
248}
249
250static uint8_t
251musbotg_setup_rx(struct musbotg_td *td)
252{
253 struct musbotg_softc *sc;
254 struct usb_device_request req;
255 uint16_t count;
256 uint8_t csr;
257
258 /* get pointer to softc */
259 sc = MUSBOTG_PC2SC(td->pc);
260
261 /* select endpoint 0 */
262 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
263
264 /* read out FIFO status */
265 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
266
267 DPRINTFN(4, "csr=0x%02x\n", csr);
268
269 /*
270 * NOTE: If DATAEND is set we should not call the
271 * callback, hence the status stage is not complete.
272 */
273 if (csr & MUSB2_MASK_CSR0L_DATAEND) {
274 /* do not stall at this point */
275 td->did_stall = 1;
276 /* wait for interrupt */
277 goto not_complete;
278 }
279 if (csr & MUSB2_MASK_CSR0L_SENTSTALL) {
280 /* clear SENTSTALL */
281 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
282 /* get latest status */
283 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
284 /* update EP0 state */
285 sc->sc_ep0_busy = 0;
286 }
287 if (csr & MUSB2_MASK_CSR0L_SETUPEND) {
288 /* clear SETUPEND */
289 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
290 MUSB2_MASK_CSR0L_SETUPEND_CLR);
291 /* get latest status */
292 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
293 /* update EP0 state */
294 sc->sc_ep0_busy = 0;
295 }
296 if (sc->sc_ep0_busy) {
297 goto not_complete;
298 }
299 if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
300 goto not_complete;
301 }
302 /* clear did stall flag */
303 td->did_stall = 0;
304 /* get the packet byte count */
305 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
306
307 /* verify data length */
308 if (count != td->remainder) {
309 DPRINTFN(0, "Invalid SETUP packet "
310 "length, %d bytes\n", count);
311 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
312 MUSB2_MASK_CSR0L_RXPKTRDY_CLR);
313 goto not_complete;
314 }
315 if (count != sizeof(req)) {
316 DPRINTFN(0, "Unsupported SETUP packet "
317 "length, %d bytes\n", count);
318 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
319 MUSB2_MASK_CSR0L_RXPKTRDY_CLR);
320 goto not_complete;
321 }
322 /* receive data */
323 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
324 MUSB2_REG_EPFIFO(0), (void *)&req, sizeof(req));
325
326 /* copy data into real buffer */
327 usbd_copy_in(td->pc, 0, &req, sizeof(req));
328
329 td->offset = sizeof(req);
330 td->remainder = 0;
331
332 /* set pending command */
333 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_RXPKTRDY_CLR;
334
335 /* we need set stall or dataend after this */
336 sc->sc_ep0_busy = 1;
337
338 /* sneak peek the set address */
339 if ((req.bmRequestType == UT_WRITE_DEVICE) &&
340 (req.bRequest == UR_SET_ADDRESS)) {
341 sc->sc_dv_addr = req.wValue[0] & 0x7F;
342 } else {
343 sc->sc_dv_addr = 0xFF;
344 }
345 return (0); /* complete */
346
347not_complete:
348 /* abort any ongoing transfer */
349 if (!td->did_stall) {
350 DPRINTFN(4, "stalling\n");
351 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
352 MUSB2_MASK_CSR0L_SENDSTALL);
353 td->did_stall = 1;
354 }
355 return (1); /* not complete */
356}
357
358/* Control endpoint only data handling functions (RX/TX/SYNC) */
359
360static uint8_t
361musbotg_setup_data_rx(struct musbotg_td *td)
362{
363 struct usb_page_search buf_res;
364 struct musbotg_softc *sc;
365 uint16_t count;
366 uint8_t csr;
367 uint8_t got_short;
368
369 /* get pointer to softc */
370 sc = MUSBOTG_PC2SC(td->pc);
371
372 /* select endpoint 0 */
373 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
374
375 /* check if a command is pending */
376 if (sc->sc_ep0_cmd) {
377 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
378 sc->sc_ep0_cmd = 0;
379 }
380 /* read out FIFO status */
381 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
382
383 DPRINTFN(4, "csr=0x%02x\n", csr);
384
385 got_short = 0;
386
387 if (csr & (MUSB2_MASK_CSR0L_SETUPEND |
388 MUSB2_MASK_CSR0L_SENTSTALL)) {
389 if (td->remainder == 0) {
390 /*
391 * We are actually complete and have
392 * received the next SETUP
393 */
394 DPRINTFN(4, "faking complete\n");
395 return (0); /* complete */
396 }
397 /*
398 * USB Host Aborted the transfer.
399 */
400 td->error = 1;
401 return (0); /* complete */
402 }
403 if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
404 return (1); /* not complete */
405 }
406 /* get the packet byte count */
407 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
408
409 /* verify the packet byte count */
410 if (count != td->max_frame_size) {
411 if (count < td->max_frame_size) {
412 /* we have a short packet */
413 td->short_pkt = 1;
414 got_short = 1;
415 } else {
416 /* invalid USB packet */
417 td->error = 1;
418 return (0); /* we are complete */
419 }
420 }
421 /* verify the packet byte count */
422 if (count > td->remainder) {
423 /* invalid USB packet */
424 td->error = 1;
425 return (0); /* we are complete */
426 }
427 while (count > 0) {
428 uint32_t temp;
429
430 usbd_get_page(td->pc, td->offset, &buf_res);
431
432 /* get correct length */
433 if (buf_res.length > count) {
434 buf_res.length = count;
435 }
436 /* check for unaligned memory address */
437 if (USB_P2U(buf_res.buffer) & 3) {
438
439 temp = count & ~3;
440
441 if (temp) {
442 /* receive data 4 bytes at a time */
443 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
444 MUSB2_REG_EPFIFO(0), sc->sc_bounce_buf,
445 temp / 4);
446 }
447 temp = count & 3;
448 if (temp) {
449 /* receive data 1 byte at a time */
450 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
451 MUSB2_REG_EPFIFO(0),
452 (void *)(&sc->sc_bounce_buf[count / 4]), temp);
453 }
454 usbd_copy_in(td->pc, td->offset,
455 sc->sc_bounce_buf, count);
456
457 /* update offset and remainder */
458 td->offset += count;
459 td->remainder -= count;
460 break;
461 }
462 /* check if we can optimise */
463 if (buf_res.length >= 4) {
464
465 /* receive data 4 bytes at a time */
466 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
467 MUSB2_REG_EPFIFO(0), buf_res.buffer,
468 buf_res.length / 4);
469
470 temp = buf_res.length & ~3;
471
472 /* update counters */
473 count -= temp;
474 td->offset += temp;
475 td->remainder -= temp;
476 continue;
477 }
478 /* receive data */
479 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
480 MUSB2_REG_EPFIFO(0), buf_res.buffer, buf_res.length);
481
482 /* update counters */
483 count -= buf_res.length;
484 td->offset += buf_res.length;
485 td->remainder -= buf_res.length;
486 }
487
488 /* check if we are complete */
489 if ((td->remainder == 0) || got_short) {
490 if (td->short_pkt) {
491 /* we are complete */
492 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_RXPKTRDY_CLR;
493 return (0);
494 }
495 /* else need to receive a zero length packet */
496 }
497 /* write command - need more data */
498 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
499 MUSB2_MASK_CSR0L_RXPKTRDY_CLR);
500 return (1); /* not complete */
501}
502
503static uint8_t
504musbotg_setup_data_tx(struct musbotg_td *td)
505{
506 struct usb_page_search buf_res;
507 struct musbotg_softc *sc;
508 uint16_t count;
509 uint8_t csr;
510
511 /* get pointer to softc */
512 sc = MUSBOTG_PC2SC(td->pc);
513
514 /* select endpoint 0 */
515 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
516
517 /* check if a command is pending */
518 if (sc->sc_ep0_cmd) {
519 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
520 sc->sc_ep0_cmd = 0;
521 }
522 /* read out FIFO status */
523 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
524
525 DPRINTFN(4, "csr=0x%02x\n", csr);
526
527 if (csr & (MUSB2_MASK_CSR0L_SETUPEND |
528 MUSB2_MASK_CSR0L_SENTSTALL)) {
529 /*
530 * The current transfer was aborted
531 * by the USB Host
532 */
533 td->error = 1;
534 return (0); /* complete */
535 }
536 if (csr & MUSB2_MASK_CSR0L_TXPKTRDY) {
537 return (1); /* not complete */
538 }
539 count = td->max_frame_size;
540 if (td->remainder < count) {
541 /* we have a short packet */
542 td->short_pkt = 1;
543 count = td->remainder;
544 }
545 while (count > 0) {
546 uint32_t temp;
547
548 usbd_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 /* check for unaligned memory address */
555 if (USB_P2U(buf_res.buffer) & 3) {
556
557 usbd_copy_out(td->pc, td->offset,
558 sc->sc_bounce_buf, count);
559
560 temp = count & ~3;
561
562 if (temp) {
563 /* transmit data 4 bytes at a time */
564 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
565 MUSB2_REG_EPFIFO(0), sc->sc_bounce_buf,
566 temp / 4);
567 }
568 temp = count & 3;
569 if (temp) {
570 /* receive data 1 byte at a time */
571 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
572 MUSB2_REG_EPFIFO(0),
573 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
574 }
575 /* update offset and remainder */
576 td->offset += count;
577 td->remainder -= count;
578 break;
579 }
580 /* check if we can optimise */
581 if (buf_res.length >= 4) {
582
583 /* transmit data 4 bytes at a time */
584 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
585 MUSB2_REG_EPFIFO(0), buf_res.buffer,
586 buf_res.length / 4);
587
588 temp = buf_res.length & ~3;
589
590 /* update counters */
591 count -= temp;
592 td->offset += temp;
593 td->remainder -= temp;
594 continue;
595 }
596 /* transmit data */
597 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
598 MUSB2_REG_EPFIFO(0), buf_res.buffer, buf_res.length);
599
600 /* update counters */
601 count -= buf_res.length;
602 td->offset += buf_res.length;
603 td->remainder -= buf_res.length;
604 }
605
606 /* check remainder */
607 if (td->remainder == 0) {
608 if (td->short_pkt) {
609 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_TXPKTRDY;
610 return (0); /* complete */
611 }
612 /* else we need to transmit a short packet */
613 }
614 /* write command */
615 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
616 MUSB2_MASK_CSR0L_TXPKTRDY);
617
618 return (1); /* not complete */
619}
620
621static uint8_t
622musbotg_setup_status(struct musbotg_td *td)
623{
624 struct musbotg_softc *sc;
625 uint8_t csr;
626
627 /* get pointer to softc */
628 sc = MUSBOTG_PC2SC(td->pc);
629
630 /* select endpoint 0 */
631 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
632
633 if (sc->sc_ep0_busy) {
634 sc->sc_ep0_busy = 0;
635 sc->sc_ep0_cmd |= MUSB2_MASK_CSR0L_DATAEND;
636 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
637 sc->sc_ep0_cmd = 0;
638 }
639 /* read out FIFO status */
640 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
641
642 DPRINTFN(4, "csr=0x%02x\n", csr);
643
644 if (csr & MUSB2_MASK_CSR0L_DATAEND) {
645 /* wait for interrupt */
646 return (1); /* not complete */
647 }
648 if (sc->sc_dv_addr != 0xFF) {
649 /* write function address */
650 musbotg_set_address(sc, sc->sc_dv_addr);
651 }
652 return (0); /* complete */
653}
654
655static uint8_t
656musbotg_data_rx(struct musbotg_td *td)
657{
658 struct usb_page_search buf_res;
659 struct musbotg_softc *sc;
660 uint16_t count;
661 uint8_t csr;
662 uint8_t to;
663 uint8_t got_short;
664
665 to = 8; /* don't loop forever! */
666 got_short = 0;
667
668 /* get pointer to softc */
669 sc = MUSBOTG_PC2SC(td->pc);
670
671 /* select endpoint */
672 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->ep_no);
673
674repeat:
675 /* read out FIFO status */
676 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
677
678 DPRINTFN(4, "csr=0x%02x\n", csr);
679
680 /* clear overrun */
681 if (csr & MUSB2_MASK_CSRL_RXOVERRUN) {
682 /* make sure we don't clear "RXPKTRDY" */
683 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
684 MUSB2_MASK_CSRL_RXPKTRDY);
685 }
686 /* check status */
687 if (!(csr & MUSB2_MASK_CSRL_RXPKTRDY)) {
688 return (1); /* not complete */
689 }
690 /* get the packet byte count */
691 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
692
693 DPRINTFN(4, "count=0x%04x\n", count);
694
695 /*
696 * Check for short or invalid packet:
697 */
698 if (count != td->max_frame_size) {
699 if (count < td->max_frame_size) {
700 /* we have a short packet */
701 td->short_pkt = 1;
702 got_short = 1;
703 } else {
704 /* invalid USB packet */
705 td->error = 1;
706 return (0); /* we are complete */
707 }
708 }
709 /* verify the packet byte count */
710 if (count > td->remainder) {
711 /* invalid USB packet */
712 td->error = 1;
713 return (0); /* we are complete */
714 }
715 while (count > 0) {
716 uint32_t temp;
717
718 usbd_get_page(td->pc, td->offset, &buf_res);
719
720 /* get correct length */
721 if (buf_res.length > count) {
722 buf_res.length = count;
723 }
724 /* check for unaligned memory address */
725 if (USB_P2U(buf_res.buffer) & 3) {
726
727 temp = count & ~3;
728
729 if (temp) {
730 /* receive data 4 bytes at a time */
731 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
732 MUSB2_REG_EPFIFO(td->ep_no), sc->sc_bounce_buf,
733 temp / 4);
734 }
735 temp = count & 3;
736 if (temp) {
737 /* receive data 1 byte at a time */
738 bus_space_read_multi_1(sc->sc_io_tag,
739 sc->sc_io_hdl, MUSB2_REG_EPFIFO(td->ep_no),
740 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
741 }
742 usbd_copy_in(td->pc, td->offset,
743 sc->sc_bounce_buf, count);
744
745 /* update offset and remainder */
746 td->offset += count;
747 td->remainder -= count;
748 break;
749 }
750 /* check if we can optimise */
751 if (buf_res.length >= 4) {
752
753 /* receive data 4 bytes at a time */
754 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
755 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
756 buf_res.length / 4);
757
758 temp = buf_res.length & ~3;
759
760 /* update counters */
761 count -= temp;
762 td->offset += temp;
763 td->remainder -= temp;
764 continue;
765 }
766 /* receive data */
767 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
768 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
769 buf_res.length);
770
771 /* update counters */
772 count -= buf_res.length;
773 td->offset += buf_res.length;
774 td->remainder -= buf_res.length;
775 }
776
777 /* clear status bits */
778 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
779
780 /* check if we are complete */
781 if ((td->remainder == 0) || got_short) {
782 if (td->short_pkt) {
783 /* we are complete */
784 return (0);
785 }
786 /* else need to receive a zero length packet */
787 }
788 if (--to) {
789 goto repeat;
790 }
791 return (1); /* not complete */
792}
793
794static uint8_t
795musbotg_data_tx(struct musbotg_td *td)
796{
797 struct usb_page_search buf_res;
798 struct musbotg_softc *sc;
799 uint16_t count;
800 uint8_t csr;
801 uint8_t to;
802
803 to = 8; /* don't loop forever! */
804
805 /* get pointer to softc */
806 sc = MUSBOTG_PC2SC(td->pc);
807
808 /* select endpoint */
809 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->ep_no);
810
811repeat:
812
813 /* read out FIFO status */
814 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
815
816 DPRINTFN(4, "csr=0x%02x\n", csr);
817
818 if (csr & (MUSB2_MASK_CSRL_TXINCOMP |
819 MUSB2_MASK_CSRL_TXUNDERRUN)) {
820 /* clear status bits */
821 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
822 }
823 if (csr & MUSB2_MASK_CSRL_TXPKTRDY) {
824 return (1); /* not complete */
825 }
826 /* check for short packet */
827 count = td->max_frame_size;
828 if (td->remainder < count) {
829 /* we have a short packet */
830 td->short_pkt = 1;
831 count = td->remainder;
832 }
833 while (count > 0) {
834 uint32_t temp;
835
836 usbd_get_page(td->pc, td->offset, &buf_res);
837
838 /* get correct length */
839 if (buf_res.length > count) {
840 buf_res.length = count;
841 }
842 /* check for unaligned memory address */
843 if (USB_P2U(buf_res.buffer) & 3) {
844
845 usbd_copy_out(td->pc, td->offset,
846 sc->sc_bounce_buf, count);
847
848 temp = count & ~3;
849
850 if (temp) {
851 /* transmit data 4 bytes at a time */
852 bus_space_write_multi_4(sc->sc_io_tag,
853 sc->sc_io_hdl, MUSB2_REG_EPFIFO(td->ep_no),
854 sc->sc_bounce_buf, temp / 4);
855 }
856 temp = count & 3;
857 if (temp) {
858 /* receive data 1 byte at a time */
859 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
860 MUSB2_REG_EPFIFO(td->ep_no),
861 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
862 }
863 /* update offset and remainder */
864 td->offset += count;
865 td->remainder -= count;
866 break;
867 }
868 /* check if we can optimise */
869 if (buf_res.length >= 4) {
870
871 /* transmit data 4 bytes at a time */
872 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
873 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
874 buf_res.length / 4);
875
876 temp = buf_res.length & ~3;
877
878 /* update counters */
879 count -= temp;
880 td->offset += temp;
881 td->remainder -= temp;
882 continue;
883 }
884 /* transmit data */
885 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
886 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
887 buf_res.length);
888
889 /* update counters */
890 count -= buf_res.length;
891 td->offset += buf_res.length;
892 td->remainder -= buf_res.length;
893 }
894
895 /* write command */
896 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
897 MUSB2_MASK_CSRL_TXPKTRDY);
898
899 /* check remainder */
900 if (td->remainder == 0) {
901 if (td->short_pkt) {
902 return (0); /* complete */
903 }
904 /* else we need to transmit a short packet */
905 }
906 if (--to) {
907 goto repeat;
908 }
909 return (1); /* not complete */
910}
911
912static uint8_t
913musbotg_xfer_do_fifo(struct usb_xfer *xfer)
914{
915 struct musbotg_softc *sc;
916 struct musbotg_td *td;
917
918 DPRINTFN(8, "\n");
919
920 td = xfer->td_transfer_cache;
921 while (1) {
922 if ((td->func) (td)) {
923 /* operation in progress */
924 break;
925 }
926 if (((void *)td) == xfer->td_transfer_last) {
927 goto done;
928 }
929 if (td->error) {
930 goto done;
931 } else if (td->remainder > 0) {
932 /*
933 * We had a short transfer. If there is no alternate
934 * next, stop processing !
935 */
936 if (!td->alt_next) {
937 goto done;
938 }
939 }
940 /*
941 * Fetch the next transfer descriptor and transfer
942 * some flags to the next transfer descriptor
943 */
944 td = td->obj_next;
945 xfer->td_transfer_cache = td;
946 }
947 return (1); /* not complete */
948
949done:
950 sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
951
952 /* compute all actual lengths */
953
954 musbotg_standard_done(xfer);
955
956 return (0); /* complete */
957}
958
959static void
960musbotg_interrupt_poll(struct musbotg_softc *sc)
961{
962 struct usb_xfer *xfer;
963
964repeat:
965 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
966 if (!musbotg_xfer_do_fifo(xfer)) {
967 /* queue has been modified */
968 goto repeat;
969 }
970 }
971}
972
973void
974musbotg_vbus_interrupt(struct musbotg_softc *sc, uint8_t is_on)
975{
976 DPRINTFN(4, "vbus = %u\n", is_on);
977
978 USB_BUS_LOCK(&sc->sc_bus);
979 if (is_on) {
980 if (!sc->sc_flags.status_vbus) {
981 sc->sc_flags.status_vbus = 1;
982
983 /* complete root HUB interrupt endpoint */
984 musbotg_root_intr(sc);
985 }
986 } else {
987 if (sc->sc_flags.status_vbus) {
988 sc->sc_flags.status_vbus = 0;
989 sc->sc_flags.status_bus_reset = 0;
990 sc->sc_flags.status_suspend = 0;
991 sc->sc_flags.change_suspend = 0;
992 sc->sc_flags.change_connect = 1;
993
994 /* complete root HUB interrupt endpoint */
995 musbotg_root_intr(sc);
996 }
997 }
998
999 USB_BUS_UNLOCK(&sc->sc_bus);
1000}
1001
1002void
1003musbotg_interrupt(struct musbotg_softc *sc)
1004{
1005 uint16_t rx_status;
1006 uint16_t tx_status;
1007 uint8_t usb_status;
1008 uint8_t temp;
1009 uint8_t to = 2;
1010
1011 USB_BUS_LOCK(&sc->sc_bus);
1012
1013repeat:
1014
1015 /* read all interrupt registers */
1016 usb_status = MUSB2_READ_1(sc, MUSB2_REG_INTUSB);
1017
1018 /* read all FIFO interrupts */
1019 rx_status = MUSB2_READ_2(sc, MUSB2_REG_INTRX);
1020 tx_status = MUSB2_READ_2(sc, MUSB2_REG_INTTX);
1021
1022 /* check for any bus state change interrupts */
1023
1024 if (usb_status & (MUSB2_MASK_IRESET |
1025 MUSB2_MASK_IRESUME | MUSB2_MASK_ISUSP)) {
1026
1027 DPRINTFN(4, "real bus interrupt 0x%08x\n", usb_status);
1028
1029 if (usb_status & MUSB2_MASK_IRESET) {
1030
1031 /* set correct state */
1032 sc->sc_flags.status_bus_reset = 1;
1033 sc->sc_flags.status_suspend = 0;
1034 sc->sc_flags.change_suspend = 0;
1035 sc->sc_flags.change_connect = 1;
1036
1037 /* determine line speed */
1038 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
1039 if (temp & MUSB2_MASK_HSMODE)
1040 sc->sc_flags.status_high_speed = 1;
1041 else
1042 sc->sc_flags.status_high_speed = 0;
1043
1044 /*
1045 * After reset all interrupts are on and we need to
1046 * turn them off!
1047 */
1048 temp = MUSB2_MASK_IRESET;
1049 /* disable resume interrupt */
1050 temp &= ~MUSB2_MASK_IRESUME;
1051 /* enable suspend interrupt */
1052 temp |= MUSB2_MASK_ISUSP;
1053 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1054 /* disable TX and RX interrupts */
1055 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1056 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1057 }
1058 /*
1059 * If RXRSM and RXSUSP is set at the same time we interpret
1060 * that like RESUME. Resume is set when there is at least 3
1061 * milliseconds of inactivity on the USB BUS.
1062 */
1063 if (usb_status & MUSB2_MASK_IRESUME) {
1064 if (sc->sc_flags.status_suspend) {
1065 sc->sc_flags.status_suspend = 0;
1066 sc->sc_flags.change_suspend = 1;
1067
1068 temp = MUSB2_READ_1(sc, MUSB2_REG_INTUSBE);
1069 /* disable resume interrupt */
1070 temp &= ~MUSB2_MASK_IRESUME;
1071 /* enable suspend interrupt */
1072 temp |= MUSB2_MASK_ISUSP;
1073 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1074 }
1075 } else if (usb_status & MUSB2_MASK_ISUSP) {
1076 if (!sc->sc_flags.status_suspend) {
1077 sc->sc_flags.status_suspend = 1;
1078 sc->sc_flags.change_suspend = 1;
1079
1080 temp = MUSB2_READ_1(sc, MUSB2_REG_INTUSBE);
1081 /* disable suspend interrupt */
1082 temp &= ~MUSB2_MASK_ISUSP;
1083 /* enable resume interrupt */
1084 temp |= MUSB2_MASK_IRESUME;
1085 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1086 }
1087 }
1088 /* complete root HUB interrupt endpoint */
1089 musbotg_root_intr(sc);
1090 }
1091 /* check for any endpoint interrupts */
1092
1093 if (rx_status || tx_status) {
1094 DPRINTFN(4, "real endpoint interrupt "
1095 "rx=0x%04x, tx=0x%04x\n", rx_status, tx_status);
1096 }
1097 /* poll one time regardless of FIFO status */
1098
1099 musbotg_interrupt_poll(sc);
1100
1101 if (--to)
1102 goto repeat;
1103
1104 USB_BUS_UNLOCK(&sc->sc_bus);
1105}
1106
1107static void
1108musbotg_setup_standard_chain_sub(struct musbotg_std_temp *temp)
1109{
1110 struct musbotg_td *td;
1111
1112 /* get current Transfer Descriptor */
1113 td = temp->td_next;
1114 temp->td = td;
1115
1116 /* prepare for next TD */
1117 temp->td_next = td->obj_next;
1118
1119 /* fill out the Transfer Descriptor */
1120 td->func = temp->func;
1121 td->pc = temp->pc;
1122 td->offset = temp->offset;
1123 td->remainder = temp->len;
1124 td->error = 0;
1125 td->did_stall = temp->did_stall;
1126 td->short_pkt = temp->short_pkt;
1127 td->alt_next = temp->setup_alt_next;
1128}
1129
1130static void
1131musbotg_setup_standard_chain(struct usb_xfer *xfer)
1132{
1133 struct musbotg_std_temp temp;
1134 struct musbotg_softc *sc;
1135 struct musbotg_td *td;
1136 uint32_t x;
1137 uint8_t ep_no;
1138
1139 DPRINTFN(8, "addr=%d endpt=%d sumlen=%d speed=%d\n",
1140 xfer->address, UE_GET_ADDR(xfer->endpointno),
1141 xfer->sumlen, usbd_get_speed(xfer->xroot->udev));
1142
1143 temp.max_frame_size = xfer->max_frame_size;
1144
1145 td = xfer->td_start[0];
1146 xfer->td_transfer_first = td;
1147 xfer->td_transfer_cache = td;
1148
1149 /* setup temp */
1150
1151 temp.pc = NULL;
1152 temp.td = NULL;
1153 temp.td_next = xfer->td_start[0];
1154 temp.offset = 0;
1155 temp.setup_alt_next = xfer->flags_int.short_frames_ok;
1156 temp.did_stall = !xfer->flags_int.control_stall;
1157
1158 sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
1159 ep_no = (xfer->endpointno & UE_ADDR);
1160
1161 /* check if we should prepend a setup message */
1162
1163 if (xfer->flags_int.control_xfr) {
1164 if (xfer->flags_int.control_hdr) {
1165
1166 temp.func = &musbotg_setup_rx;
1167 temp.len = xfer->frlengths[0];
1168 temp.pc = xfer->frbuffers + 0;
1169 temp.short_pkt = temp.len ? 1 : 0;
1170
1171 musbotg_setup_standard_chain_sub(&temp);
1172 }
1173 x = 1;
1174 } else {
1175 x = 0;
1176 }
1177
1178 if (x != xfer->nframes) {
1179 if (xfer->endpointno & UE_DIR_IN) {
1180 if (xfer->flags_int.control_xfr)
1181 temp.func = &musbotg_setup_data_tx;
1182 else
1183 temp.func = &musbotg_data_tx;
1184 } else {
1185 if (xfer->flags_int.control_xfr)
1186 temp.func = &musbotg_setup_data_rx;
1187 else
1188 temp.func = &musbotg_data_rx;
1189 }
1190
1191 /* setup "pc" pointer */
1192 temp.pc = xfer->frbuffers + x;
1193 }
1194 while (x != xfer->nframes) {
1195
1196 /* DATA0 / DATA1 message */
1197
1198 temp.len = xfer->frlengths[x];
1199
1200 x++;
1201
1202 if (x == xfer->nframes) {
1203 if (xfer->flags_int.control_xfr) {
1204 if (xfer->flags_int.control_act) {
1205 temp.setup_alt_next = 0;
1206 }
1207 } else {
1208 temp.setup_alt_next = 0;
1209 }
1210 }
1211 if (temp.len == 0) {
1212
1213 /* make sure that we send an USB packet */
1214
1215 temp.short_pkt = 0;
1216
1217 } else {
1218
1219 /* regular data transfer */
1220
1221 temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
1222 }
1223
1224 musbotg_setup_standard_chain_sub(&temp);
1225
1226 if (xfer->flags_int.isochronous_xfr) {
1227 temp.offset += temp.len;
1228 } else {
1229 /* get next Page Cache pointer */
1230 temp.pc = xfer->frbuffers + x;
1231 }
1232 }
1233
1234 /* check for control transfer */
1235 if (xfer->flags_int.control_xfr) {
1236
1237 /* always setup a valid "pc" pointer for status and sync */
1238 temp.pc = xfer->frbuffers + 0;
1239 temp.len = 0;
1240 temp.short_pkt = 0;
1241 temp.setup_alt_next = 0;
1242
1243 /* check if we should append a status stage */
1244 if (!xfer->flags_int.control_act) {
1245 /*
1246 * Send a DATA1 message and invert the current
1247 * endpoint direction.
1248 */
1249 temp.func = &musbotg_setup_status;
1250 musbotg_setup_standard_chain_sub(&temp);
1251 }
1252 }
1253 /* must have at least one frame! */
1254 td = temp.td;
1255 xfer->td_transfer_last = td;
1256}
1257
1258static void
1259musbotg_timeout(void *arg)
1260{
1261 struct usb_xfer *xfer = arg;
1262
1263 DPRINTFN(1, "xfer=%p\n", xfer);
1264
1265 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1266
1267 /* transfer is transferred */
1268 musbotg_device_done(xfer, USB_ERR_TIMEOUT);
1269}
1270
1271static void
1272musbotg_ep_int_set(struct usb_xfer *xfer, uint8_t on)
1273{
1274 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
1275 uint16_t temp;
1276 uint8_t ep_no = xfer->endpointno & UE_ADDR;
1277
1278 /*
1279 * Only enable the endpoint interrupt when we are
1280 * actually waiting for data, hence we are dealing
1281 * with level triggered interrupts !
1282 */
1283 if (ep_no == 0) {
1284 temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
1285 if (on)
1286 temp |= MUSB2_MASK_EPINT(0);
1287 else
1288 temp &= ~MUSB2_MASK_EPINT(0);
1289
1290 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
1291 } else {
1292 if (USB_GET_DATA_ISREAD(xfer)) {
1293 temp = MUSB2_READ_2(sc, MUSB2_REG_INTRXE);
1294 if (on)
1295 temp |= MUSB2_MASK_EPINT(ep_no);
1296 else
1297 temp &= ~MUSB2_MASK_EPINT(ep_no);
1298 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, temp);
1299
1300 } else {
1301 temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
1302 if (on)
1303 temp |= MUSB2_MASK_EPINT(ep_no);
1304 else
1305 temp &= ~MUSB2_MASK_EPINT(ep_no);
1306 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
1307 }
1308 }
1309}
1310
1311static void
1312musbotg_start_standard_chain(struct usb_xfer *xfer)
1313{
1314 DPRINTFN(8, "\n");
1315
1316 /* poll one time */
1317 if (musbotg_xfer_do_fifo(xfer)) {
1318
1319 musbotg_ep_int_set(xfer, 1);
1320
1321 DPRINTFN(14, "enabled interrupts on endpoint\n");
1322
1323 /* put transfer on interrupt queue */
1324 usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
1325
1326 /* start timeout, if any */
1327 if (xfer->timeout != 0) {
1328 usbd_transfer_timeout_ms(xfer,
1329 &musbotg_timeout, xfer->timeout);
1330 }
1331 }
1332}
1333
1334static void
1335musbotg_root_intr(struct musbotg_softc *sc)
1336{
1337 DPRINTFN(8, "\n");
1338
1339 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
1340
1341 /* set port bit */
1342 sc->sc_hub_idata[0] = 0x02; /* we only have one port */
1343
1344 uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata,
1345 sizeof(sc->sc_hub_idata));
1346}
1347
1348static usb_error_t
1349musbotg_standard_done_sub(struct usb_xfer *xfer)
1350{
1351 struct musbotg_td *td;
1352 uint32_t len;
1353 uint8_t error;
1354
1355 DPRINTFN(8, "\n");
1356
1357 td = xfer->td_transfer_cache;
1358
1359 do {
1360 len = td->remainder;
1361
1362 if (xfer->aframes != xfer->nframes) {
1363 /*
1364 * Verify the length and subtract
1365 * the remainder from "frlengths[]":
1366 */
1367 if (len > xfer->frlengths[xfer->aframes]) {
1368 td->error = 1;
1369 } else {
1370 xfer->frlengths[xfer->aframes] -= len;
1371 }
1372 }
1373 /* Check for transfer error */
1374 if (td->error) {
1375 /* the transfer is finished */
1376 error = 1;
1377 td = NULL;
1378 break;
1379 }
1380 /* Check for short transfer */
1381 if (len > 0) {
1382 if (xfer->flags_int.short_frames_ok) {
1383 /* follow alt next */
1384 if (td->alt_next) {
1385 td = td->obj_next;
1386 } else {
1387 td = NULL;
1388 }
1389 } else {
1390 /* the transfer is finished */
1391 td = NULL;
1392 }
1393 error = 0;
1394 break;
1395 }
1396 td = td->obj_next;
1397
1398 /* this USB frame is complete */
1399 error = 0;
1400 break;
1401
1402 } while (0);
1403
1404 /* update transfer cache */
1405
1406 xfer->td_transfer_cache = td;
1407
1408 return (error ?
1409 USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
1410}
1411
1412static void
1413musbotg_standard_done(struct usb_xfer *xfer)
1414{
1415 usb_error_t err = 0;
1416
1417 DPRINTFN(12, "xfer=%p endpoint=%p transfer done\n",
1418 xfer, xfer->endpoint);
1419
1420 /* reset scanner */
1421
1422 xfer->td_transfer_cache = xfer->td_transfer_first;
1423
1424 if (xfer->flags_int.control_xfr) {
1425
1426 if (xfer->flags_int.control_hdr) {
1427
1428 err = musbotg_standard_done_sub(xfer);
1429 }
1430 xfer->aframes = 1;
1431
1432 if (xfer->td_transfer_cache == NULL) {
1433 goto done;
1434 }
1435 }
1436 while (xfer->aframes != xfer->nframes) {
1437
1438 err = musbotg_standard_done_sub(xfer);
1439 xfer->aframes++;
1440
1441 if (xfer->td_transfer_cache == NULL) {
1442 goto done;
1443 }
1444 }
1445
1446 if (xfer->flags_int.control_xfr &&
1447 !xfer->flags_int.control_act) {
1448
1449 err = musbotg_standard_done_sub(xfer);
1450 }
1451done:
1452 musbotg_device_done(xfer, err);
1453}
1454
1455/*------------------------------------------------------------------------*
1456 * musbotg_device_done
1457 *
1458 * NOTE: this function can be called more than one time on the
1459 * same USB transfer!
1460 *------------------------------------------------------------------------*/
1461static void
1462musbotg_device_done(struct usb_xfer *xfer, usb_error_t error)
1463{
1464 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1465
1466 DPRINTFN(2, "xfer=%p, endpoint=%p, error=%d\n",
1467 xfer, xfer->endpoint, error);
1468
1469 if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) {
1470
1471 musbotg_ep_int_set(xfer, 0);
1472
1473 DPRINTFN(14, "disabled interrupts on endpoint\n");
1474 }
1475 /* dequeue transfer and start next transfer */
1476 usbd_transfer_done(xfer, error);
1477}
1478
1479static void
1480musbotg_xfer_stall(struct usb_xfer *xfer)
1481{
1482 musbotg_device_done(xfer, USB_ERR_STALLED);
1483}
1484
1485static void
1486musbotg_set_stall(struct usb_device *udev,
1487 struct usb_endpoint *ep, uint8_t *did_stall)
1488{
1489 struct musbotg_softc *sc;
1490 uint8_t ep_no;
1491
1492 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1493
1494 DPRINTFN(4, "endpoint=%p\n", ep);
1495
1496 /* set FORCESTALL */
1497 sc = MUSBOTG_BUS2SC(udev->bus);
1498
1499 ep_no = (ep->edesc->bEndpointAddress & UE_ADDR);
1500
1501 /* select endpoint */
1502 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
1503
1504 if (ep->edesc->bEndpointAddress & UE_DIR_IN) {
1505 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1506 MUSB2_MASK_CSRL_TXSENDSTALL);
1507 } else {
1508 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1509 MUSB2_MASK_CSRL_RXSENDSTALL);
1510 }
1511}
1512
1513static void
1514musbotg_clear_stall_sub(struct musbotg_softc *sc, uint16_t wMaxPacket,
1515 uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
1516{
1517 uint16_t mps;
1518 uint16_t temp;
1519 uint8_t csr;
1520
1521 if (ep_type == UE_CONTROL) {
1522 /* clearing stall is not needed */
1523 return;
1524 }
1525 /* select endpoint */
1526 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
1527
1528 /* compute max frame size */
1529 mps = wMaxPacket & 0x7FF;
1530 switch ((wMaxPacket >> 11) & 3) {
1531 case 1:
1532 mps *= 2;
1533 break;
1534 case 2:
1535 mps *= 3;
1536 break;
1537 default:
1538 break;
1539 }
1540
1541 if (ep_dir == UE_DIR_IN) {
1542
1543 temp = 0;
1544
1545 /* Configure endpoint */
1546 switch (ep_type) {
1547 case UE_INTERRUPT:
1548 MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1549 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1550 MUSB2_MASK_CSRH_TXMODE | temp);
1551 break;
1552 case UE_ISOCHRONOUS:
1553 MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1554 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1555 MUSB2_MASK_CSRH_TXMODE |
1556 MUSB2_MASK_CSRH_TXISO | temp);
1557 break;
1558 case UE_BULK:
1559 MUSB2_WRITE_2(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1560 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1561 MUSB2_MASK_CSRH_TXMODE | temp);
1562 break;
1563 default:
1564 break;
1565 }
1566
1567 /* Need to flush twice in case of double bufring */
1568 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1569 if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
1570 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1571 MUSB2_MASK_CSRL_TXFFLUSH);
1572 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1573 if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
1574 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1575 MUSB2_MASK_CSRL_TXFFLUSH);
1576 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1577 }
1578 }
1579 /* reset data toggle */
1580 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1581 MUSB2_MASK_CSRL_TXDT_CLR);
1582 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
1583 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1584
1585 /* set double/single buffering */
1586 temp = MUSB2_READ_2(sc, MUSB2_REG_TXDBDIS);
1587 if (mps <= (sc->sc_hw_ep_profile[ep_no].
1588 max_in_frame_size / 2)) {
1589 /* double buffer */
1590 temp &= ~(1 << ep_no);
1591 } else {
1592 /* single buffer */
1593 temp |= (1 << ep_no);
1594 }
1595 MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, temp);
1596
1597 /* clear sent stall */
1598 if (csr & MUSB2_MASK_CSRL_TXSENTSTALL) {
1599 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
1600 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1601 }
1602 } else {
1603
1604 temp = 0;
1605
1606 /* Configure endpoint */
1607 switch (ep_type) {
1608 case UE_INTERRUPT:
1609 MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1610 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
1611 MUSB2_MASK_CSRH_RXNYET | temp);
1612 break;
1613 case UE_ISOCHRONOUS:
1614 MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1615 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
1616 MUSB2_MASK_CSRH_RXNYET |
1617 MUSB2_MASK_CSRH_RXISO | temp);
1618 break;
1619 case UE_BULK:
1620 MUSB2_WRITE_2(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1621 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH, temp);
1622 break;
1623 default:
1624 break;
1625 }
1626
1627 /* Need to flush twice in case of double bufring */
1628 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1629 if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
1630 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1631 MUSB2_MASK_CSRL_RXFFLUSH);
1632 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1633 if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
1634 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1635 MUSB2_MASK_CSRL_RXFFLUSH);
1636 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1637 }
1638 }
1639 /* reset data toggle */
1640 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1641 MUSB2_MASK_CSRL_RXDT_CLR);
1642 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
1643 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1644
1645 /* set double/single buffering */
1646 temp = MUSB2_READ_2(sc, MUSB2_REG_RXDBDIS);
1647 if (mps <= (sc->sc_hw_ep_profile[ep_no].
1648 max_out_frame_size / 2)) {
1649 /* double buffer */
1650 temp &= ~(1 << ep_no);
1651 } else {
1652 /* single buffer */
1653 temp |= (1 << ep_no);
1654 }
1655 MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, temp);
1656
1657 /* clear sent stall */
1658 if (csr & MUSB2_MASK_CSRL_RXSENTSTALL) {
1659 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
1660 }
1661 }
1662}
1663
1664static void
1665musbotg_clear_stall(struct usb_device *udev, struct usb_endpoint *ep)
1666{
1667 struct musbotg_softc *sc;
1668 struct usb_endpoint_descriptor *ed;
1669
1670 DPRINTFN(4, "endpoint=%p\n", ep);
1671
1672 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1673
1674 /* check mode */
1675 if (udev->flags.usb_mode != USB_MODE_DEVICE) {
1676 /* not supported */
1677 return;
1678 }
1679 /* get softc */
1680 sc = MUSBOTG_BUS2SC(udev->bus);
1681
1682 /* get endpoint descriptor */
1683 ed = ep->edesc;
1684
1685 /* reset endpoint */
1686 musbotg_clear_stall_sub(sc,
1687 UGETW(ed->wMaxPacketSize),
1688 (ed->bEndpointAddress & UE_ADDR),
1689 (ed->bmAttributes & UE_XFERTYPE),
1690 (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
1691}
1692
1693usb_error_t
1694musbotg_init(struct musbotg_softc *sc)
1695{
1696 struct usb_hw_ep_profile *pf;
1697 uint16_t offset;
1698 uint8_t nrx;
1699 uint8_t ntx;
1700 uint8_t temp;
1701 uint8_t fsize;
1702 uint8_t frx;
1703 uint8_t ftx;
1704 uint8_t dynfifo;
1705
1706 DPRINTFN(1, "start\n");
1707
1708 /* set up the bus structure */
1709 sc->sc_bus.usbrev = USB_REV_2_0;
1710 sc->sc_bus.methods = &musbotg_bus_methods;
1711
1712 USB_BUS_LOCK(&sc->sc_bus);
1713
1714 /* turn on clocks */
1715
1716 if (sc->sc_clocks_on) {
1717 (sc->sc_clocks_on) (sc->sc_clocks_arg);
1718 }
1719 /* wait a little for things to stabilise */
1720 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000);
1721
1722 /* disable all interrupts */
1723
1724 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
1725 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1726 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1727
1728 /* disable pullup */
1729
1730 musbotg_pull_common(sc, 0);
1731
1732 /* wait a little bit (10ms) */
1733 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100);
1734
1735 /* disable double packet buffering */
1736 MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, 0xFFFF);
1737 MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, 0xFFFF);
1738
1739 /* enable HighSpeed and ISO Update flags */
1740
1741 MUSB2_WRITE_1(sc, MUSB2_REG_POWER,
1742 MUSB2_MASK_HSENAB | MUSB2_MASK_ISOUPD);
1743
1744 /* clear Session bit, if set */
1745
1746 temp = MUSB2_READ_1(sc, MUSB2_REG_DEVCTL);
1747 temp &= ~MUSB2_MASK_SESS;
1748 MUSB2_WRITE_1(sc, MUSB2_REG_DEVCTL, temp);
1749
1750 DPRINTF("DEVCTL=0x%02x\n", temp);
1751
1752 /* disable testmode */
1753
1754 MUSB2_WRITE_1(sc, MUSB2_REG_TESTMODE, 0);
1755
1756 /* set default value */
1757
1758 MUSB2_WRITE_1(sc, MUSB2_REG_MISC, 0);
1759
1760 /* select endpoint index 0 */
1761
1762 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
1763
1764 /* read out number of endpoints */
1765
1766 nrx =
1767 (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) / 16);
1768
1769 ntx =
1770 (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) % 16);
1771
1772 /* these numbers exclude the control endpoint */
1773
1774 DPRINTFN(2, "RX/TX endpoints: %u/%u\n", nrx, ntx);
1775
1776 sc->sc_ep_max = (nrx > ntx) ? nrx : ntx;
1777 if (sc->sc_ep_max == 0) {
1778 DPRINTFN(2, "ERROR: Looks like the clocks are off!\n");
1779 }
1780 /* read out configuration data */
1781
1782 sc->sc_conf_data = MUSB2_READ_1(sc, MUSB2_REG_CONFDATA);
1783
1784 DPRINTFN(2, "Config Data: 0x%02x\n",
1785 sc->sc_conf_data);
1786
1787 dynfifo = (sc->sc_conf_data & MUSB2_MASK_CD_DYNFIFOSZ) ? 1 : 0;
1788
1789 if (dynfifo) {
1790 device_printf(sc->sc_bus.bdev, "Dynamic FIFO sizing detected, "
1791 "assuming 16Kbytes of FIFO RAM\n");
1792 }
1793
1794 DPRINTFN(2, "HW version: 0x%04x\n",
1795 MUSB2_READ_1(sc, MUSB2_REG_HWVERS));
1796
1797 /* initialise endpoint profiles */
1798
1799 offset = 0;
1800
1801 for (temp = 1; temp <= sc->sc_ep_max; temp++) {
1802 pf = sc->sc_hw_ep_profile + temp;
1803
1804 /* select endpoint */
1805 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, temp);
1806
1807 fsize = MUSB2_READ_1(sc, MUSB2_REG_FSIZE);
1808 frx = (fsize & MUSB2_MASK_RX_FSIZE) / 16;
1809 ftx = (fsize & MUSB2_MASK_TX_FSIZE);
1810
1811 DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u, DYN=%d\n",
1812 temp, ftx, frx, dynfifo);
1813
1814 if (dynfifo) {
1815 if (frx && (temp <= nrx)) {
1816 if (temp < 8) {
1817 frx = 10; /* 1K */
1818 MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ,
1819 MUSB2_VAL_FIFOSZ_512 |
1820 MUSB2_MASK_FIFODB);
1821 } else {
1822 frx = 7; /* 128 bytes */
1823 MUSB2_WRITE_1(sc, MUSB2_REG_RXFIFOSZ,
1824 MUSB2_VAL_FIFOSZ_128);
1825 }
1826
1827 MUSB2_WRITE_2(sc, MUSB2_REG_RXFIFOADD,
1828 offset >> 3);
1829
1830 offset += (1 << frx);
1831 }
1832 if (ftx && (temp <= ntx)) {
1833 if (temp < 8) {
1834 ftx = 10; /* 1K */
1835 MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ,
1836 MUSB2_VAL_FIFOSZ_512 |
1837 MUSB2_MASK_FIFODB);
1838 } else {
1839 ftx = 7; /* 128 bytes */
1840 MUSB2_WRITE_1(sc, MUSB2_REG_TXFIFOSZ,
1841 MUSB2_VAL_FIFOSZ_128);
1842 }
1843
1844 MUSB2_WRITE_2(sc, MUSB2_REG_TXFIFOADD,
1845 offset >> 3);
1846
1847 offset += (1 << ftx);
1848 }
1849 }
1850
1851 if (frx && ftx && (temp <= nrx) && (temp <= ntx)) {
1852 pf->max_in_frame_size = 1 << ftx;
1853 pf->max_out_frame_size = 1 << frx;
1854 pf->is_simplex = 0; /* duplex */
1855 pf->support_multi_buffer = 1;
1856 pf->support_bulk = 1;
1857 pf->support_interrupt = 1;
1858 pf->support_isochronous = 1;
1859 pf->support_in = 1;
1860 pf->support_out = 1;
1861 } else if (frx && (temp <= nrx)) {
1862 pf->max_out_frame_size = 1 << frx;
1863 pf->is_simplex = 1; /* simplex */
1864 pf->support_multi_buffer = 1;
1865 pf->support_bulk = 1;
1866 pf->support_interrupt = 1;
1867 pf->support_isochronous = 1;
1868 pf->support_out = 1;
1869 } else if (ftx && (temp <= ntx)) {
1870 pf->max_in_frame_size = 1 << ftx;
1871 pf->is_simplex = 1; /* simplex */
1872 pf->support_multi_buffer = 1;
1873 pf->support_bulk = 1;
1874 pf->support_interrupt = 1;
1875 pf->support_isochronous = 1;
1876 pf->support_in = 1;
1877 }
1878 }
1879
1880 DPRINTFN(2, "Dynamic FIFO size = %d bytes\n", offset);
1881
1882 /* turn on default interrupts */
1883
1884 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE,
1885 MUSB2_MASK_IRESET);
1886
1887 musbotg_clocks_off(sc);
1888
1889 USB_BUS_UNLOCK(&sc->sc_bus);
1890
1891 /* catch any lost interrupts */
1892
1893 musbotg_do_poll(&sc->sc_bus);
1894
1895 return (0); /* success */
1896}
1897
1898void
1899musbotg_uninit(struct musbotg_softc *sc)
1900{
1901 USB_BUS_LOCK(&sc->sc_bus);
1902
1903 /* disable all interrupts */
1904 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
1905 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1906 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1907
1908 sc->sc_flags.port_powered = 0;
1909 sc->sc_flags.status_vbus = 0;
1910 sc->sc_flags.status_bus_reset = 0;
1911 sc->sc_flags.status_suspend = 0;
1912 sc->sc_flags.change_suspend = 0;
1913 sc->sc_flags.change_connect = 1;
1914
1915 musbotg_pull_down(sc);
1916 musbotg_clocks_off(sc);
1917 USB_BUS_UNLOCK(&sc->sc_bus);
1918}
1919
1920static void
1921musbotg_suspend(struct musbotg_softc *sc)
1922{
1923 /* TODO */
1924}
1925
1926static void
1927musbotg_resume(struct musbotg_softc *sc)
1928{
1929 /* TODO */
1930}
1931
1932static void
1933musbotg_do_poll(struct usb_bus *bus)
1934{
1935 struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
1936
1937 USB_BUS_LOCK(&sc->sc_bus);
1938 musbotg_interrupt_poll(sc);
1939 USB_BUS_UNLOCK(&sc->sc_bus);
1940}
1941
1942/*------------------------------------------------------------------------*
1943 * musbotg bulk support
1944 *------------------------------------------------------------------------*/
1945static void
1946musbotg_device_bulk_open(struct usb_xfer *xfer)
1947{
1948 return;
1949}
1950
1951static void
1952musbotg_device_bulk_close(struct usb_xfer *xfer)
1953{
1954 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1955}
1956
1957static void
1958musbotg_device_bulk_enter(struct usb_xfer *xfer)
1959{
1960 return;
1961}
1962
1963static void
1964musbotg_device_bulk_start(struct usb_xfer *xfer)
1965{
1966 /* setup TDs */
1967 musbotg_setup_standard_chain(xfer);
1968 musbotg_start_standard_chain(xfer);
1969}
1970
1971struct usb_pipe_methods musbotg_device_bulk_methods =
1972{
1973 .open = musbotg_device_bulk_open,
1974 .close = musbotg_device_bulk_close,
1975 .enter = musbotg_device_bulk_enter,
1976 .start = musbotg_device_bulk_start,
1977};
1978
1979/*------------------------------------------------------------------------*
1980 * musbotg control support
1981 *------------------------------------------------------------------------*/
1982static void
1983musbotg_device_ctrl_open(struct usb_xfer *xfer)
1984{
1985 return;
1986}
1987
1988static void
1989musbotg_device_ctrl_close(struct usb_xfer *xfer)
1990{
1991 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1992}
1993
1994static void
1995musbotg_device_ctrl_enter(struct usb_xfer *xfer)
1996{
1997 return;
1998}
1999
2000static void
2001musbotg_device_ctrl_start(struct usb_xfer *xfer)
2002{
2003 /* setup TDs */
2004 musbotg_setup_standard_chain(xfer);
2005 musbotg_start_standard_chain(xfer);
2006}
2007
2008struct usb_pipe_methods musbotg_device_ctrl_methods =
2009{
2010 .open = musbotg_device_ctrl_open,
2011 .close = musbotg_device_ctrl_close,
2012 .enter = musbotg_device_ctrl_enter,
2013 .start = musbotg_device_ctrl_start,
2014};
2015
2016/*------------------------------------------------------------------------*
2017 * musbotg interrupt support
2018 *------------------------------------------------------------------------*/
2019static void
2020musbotg_device_intr_open(struct usb_xfer *xfer)
2021{
2022 return;
2023}
2024
2025static void
2026musbotg_device_intr_close(struct usb_xfer *xfer)
2027{
2028 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2029}
2030
2031static void
2032musbotg_device_intr_enter(struct usb_xfer *xfer)
2033{
2034 return;
2035}
2036
2037static void
2038musbotg_device_intr_start(struct usb_xfer *xfer)
2039{
2040 /* setup TDs */
2041 musbotg_setup_standard_chain(xfer);
2042 musbotg_start_standard_chain(xfer);
2043}
2044
2045struct usb_pipe_methods musbotg_device_intr_methods =
2046{
2047 .open = musbotg_device_intr_open,
2048 .close = musbotg_device_intr_close,
2049 .enter = musbotg_device_intr_enter,
2050 .start = musbotg_device_intr_start,
2051};
2052
2053/*------------------------------------------------------------------------*
2054 * musbotg full speed isochronous support
2055 *------------------------------------------------------------------------*/
2056static void
2057musbotg_device_isoc_open(struct usb_xfer *xfer)
2058{
2059 return;
2060}
2061
2062static void
2063musbotg_device_isoc_close(struct usb_xfer *xfer)
2064{
2065 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2066}
2067
2068static void
2069musbotg_device_isoc_enter(struct usb_xfer *xfer)
2070{
2071 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
2072 uint32_t temp;
2073 uint32_t nframes;
2074 uint32_t fs_frames;
2075
2076 DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
2077 xfer, xfer->endpoint->isoc_next, xfer->nframes);
2078
2079 /* get the current frame index */
2080
2081 nframes = MUSB2_READ_2(sc, MUSB2_REG_FRAME);
2082
2083 /*
2084 * check if the frame index is within the window where the frames
2085 * will be inserted
2086 */
2087 temp = (nframes - xfer->endpoint->isoc_next) & MUSB2_MASK_FRAME;
2088
2089 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
2090 fs_frames = (xfer->nframes + 7) / 8;
2091 } else {
2092 fs_frames = xfer->nframes;
2093 }
2094
2095 if ((xfer->endpoint->is_synced == 0) ||
2096 (temp < fs_frames)) {
2097 /*
2098 * If there is data underflow or the pipe queue is
2099 * empty we schedule the transfer a few frames ahead
2100 * of the current frame position. Else two isochronous
2101 * transfers might overlap.
2102 */
2103 xfer->endpoint->isoc_next = (nframes + 3) & MUSB2_MASK_FRAME;
2104 xfer->endpoint->is_synced = 1;
2105 DPRINTFN(2, "start next=%d\n", xfer->endpoint->isoc_next);
2106 }
2107 /*
2108 * compute how many milliseconds the insertion is ahead of the
2109 * current frame position:
2110 */
2111 temp = (xfer->endpoint->isoc_next - nframes) & MUSB2_MASK_FRAME;
2112
2113 /*
2114 * pre-compute when the isochronous transfer will be finished:
2115 */
2116 xfer->isoc_time_complete =
2117 usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2118 fs_frames;
2119
2120 /* compute frame number for next insertion */
2121 xfer->endpoint->isoc_next += fs_frames;
2122
2123 /* setup TDs */
2124 musbotg_setup_standard_chain(xfer);
2125}
2126
2127static void
2128musbotg_device_isoc_start(struct usb_xfer *xfer)
2129{
2130 /* start TD chain */
2131 musbotg_start_standard_chain(xfer);
2132}
2133
2134struct usb_pipe_methods musbotg_device_isoc_methods =
2135{
2136 .open = musbotg_device_isoc_open,
2137 .close = musbotg_device_isoc_close,
2138 .enter = musbotg_device_isoc_enter,
2139 .start = musbotg_device_isoc_start,
2140};
2141
2142/*------------------------------------------------------------------------*
2143 * musbotg root control support
2144 *------------------------------------------------------------------------*
2145 * Simulate a hardware HUB by handling all the necessary requests.
2146 *------------------------------------------------------------------------*/
2147
2148static const struct usb_device_descriptor musbotg_devd = {
2149 .bLength = sizeof(struct usb_device_descriptor),
2150 .bDescriptorType = UDESC_DEVICE,
2151 .bcdUSB = {0x00, 0x02},
2152 .bDeviceClass = UDCLASS_HUB,
2153 .bDeviceSubClass = UDSUBCLASS_HUB,
2154 .bDeviceProtocol = UDPROTO_HSHUBSTT,
2155 .bMaxPacketSize = 64,
2156 .bcdDevice = {0x00, 0x01},
2157 .iManufacturer = 1,
2158 .iProduct = 2,
2159 .bNumConfigurations = 1,
2160};
2161
2162static const struct usb_device_qualifier musbotg_odevd = {
2163 .bLength = sizeof(struct usb_device_qualifier),
2164 .bDescriptorType = UDESC_DEVICE_QUALIFIER,
2165 .bcdUSB = {0x00, 0x02},
2166 .bDeviceClass = UDCLASS_HUB,
2167 .bDeviceSubClass = UDSUBCLASS_HUB,
2168 .bDeviceProtocol = UDPROTO_FSHUB,
2169 .bMaxPacketSize0 = 0,
2170 .bNumConfigurations = 0,
2171};
2172
2173static const struct musbotg_config_desc musbotg_confd = {
2174 .confd = {
2175 .bLength = sizeof(struct usb_config_descriptor),
2176 .bDescriptorType = UDESC_CONFIG,
2177 .wTotalLength[0] = sizeof(musbotg_confd),
2178 .bNumInterface = 1,
2179 .bConfigurationValue = 1,
2180 .iConfiguration = 0,
2181 .bmAttributes = UC_SELF_POWERED,
2182 .bMaxPower = 0,
2183 },
2184 .ifcd = {
2185 .bLength = sizeof(struct usb_interface_descriptor),
2186 .bDescriptorType = UDESC_INTERFACE,
2187 .bNumEndpoints = 1,
2188 .bInterfaceClass = UICLASS_HUB,
2189 .bInterfaceSubClass = UISUBCLASS_HUB,
2190 .bInterfaceProtocol = 0,
2191 },
2192 .endpd = {
2193 .bLength = sizeof(struct usb_endpoint_descriptor),
2194 .bDescriptorType = UDESC_ENDPOINT,
2195 .bEndpointAddress = (UE_DIR_IN | MUSBOTG_INTR_ENDPT),
2196 .bmAttributes = UE_INTERRUPT,
2197 .wMaxPacketSize[0] = 8,
2198 .bInterval = 255,
2199 },
2200};
2201
2202#define HSETW(ptr, val) ptr = { (uint8_t)(val), (uint8_t)((val) >> 8) }
2203
2204static const struct usb_hub_descriptor_min musbotg_hubd = {
2205 .bDescLength = sizeof(musbotg_hubd),
2206 .bDescriptorType = UDESC_HUB,
2207 .bNbrPorts = 1,
2208 HSETW(.wHubCharacteristics, (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL)),
2209 .bPwrOn2PwrGood = 50,
2210 .bHubContrCurrent = 0,
2211 .DeviceRemovable = {0}, /* port is removable */
2212};
2213
2214#define STRING_LANG \
2215 0x09, 0x04, /* American English */
2216
2217#define STRING_VENDOR \
2218 'M', 0, 'e', 0, 'n', 0, 't', 0, 'o', 0, 'r', 0, ' ', 0, \
2219 'G', 0, 'r', 0, 'a', 0, 'p', 0, 'h', 0, 'i', 0, 'c', 0, 's', 0
2220
2221#define STRING_PRODUCT \
2222 'O', 0, 'T', 0, 'G', 0, ' ', 0, 'R', 0, \
2223 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
2224 'U', 0, 'B', 0,
2225
2214#define STRING_VENDOR \
2215 'M', 0, 'e', 0, 'n', 0, 't', 0, 'o', 0, 'r', 0, ' ', 0, \
2216 'G', 0, 'r', 0, 'a', 0, 'p', 0, 'h', 0, 'i', 0, 'c', 0, 's', 0
2217
2218#define STRING_PRODUCT \
2219 'O', 0, 'T', 0, 'G', 0, ' ', 0, 'R', 0, \
2220 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
2221 'U', 0, 'B', 0,
2222
2226USB_MAKE_STRING_DESC(STRING_LANG, musbotg_langtab);
2227USB_MAKE_STRING_DESC(STRING_VENDOR, musbotg_vendor);
2228USB_MAKE_STRING_DESC(STRING_PRODUCT, musbotg_product);
2229
2230static usb_error_t
2231musbotg_roothub_exec(struct usb_device *udev,
2232 struct usb_device_request *req, const void **pptr, uint16_t *plength)
2233{
2234 struct musbotg_softc *sc = MUSBOTG_BUS2SC(udev->bus);
2235 const void *ptr;
2236 uint16_t len;
2237 uint16_t value;
2238 uint16_t index;
2239 usb_error_t err;
2240
2241 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
2242
2243 /* buffer reset */
2244 ptr = (const void *)&sc->sc_hub_temp;
2245 len = 0;
2246 err = 0;
2247
2248 value = UGETW(req->wValue);
2249 index = UGETW(req->wIndex);
2250
2251 /* demultiplex the control request */
2252
2253 switch (req->bmRequestType) {
2254 case UT_READ_DEVICE:
2255 switch (req->bRequest) {
2256 case UR_GET_DESCRIPTOR:
2257 goto tr_handle_get_descriptor;
2258 case UR_GET_CONFIG:
2259 goto tr_handle_get_config;
2260 case UR_GET_STATUS:
2261 goto tr_handle_get_status;
2262 default:
2263 goto tr_stalled;
2264 }
2265 break;
2266
2267 case UT_WRITE_DEVICE:
2268 switch (req->bRequest) {
2269 case UR_SET_ADDRESS:
2270 goto tr_handle_set_address;
2271 case UR_SET_CONFIG:
2272 goto tr_handle_set_config;
2273 case UR_CLEAR_FEATURE:
2274 goto tr_valid; /* nop */
2275 case UR_SET_DESCRIPTOR:
2276 goto tr_valid; /* nop */
2277 case UR_SET_FEATURE:
2278 default:
2279 goto tr_stalled;
2280 }
2281 break;
2282
2283 case UT_WRITE_ENDPOINT:
2284 switch (req->bRequest) {
2285 case UR_CLEAR_FEATURE:
2286 switch (UGETW(req->wValue)) {
2287 case UF_ENDPOINT_HALT:
2288 goto tr_handle_clear_halt;
2289 case UF_DEVICE_REMOTE_WAKEUP:
2290 goto tr_handle_clear_wakeup;
2291 default:
2292 goto tr_stalled;
2293 }
2294 break;
2295 case UR_SET_FEATURE:
2296 switch (UGETW(req->wValue)) {
2297 case UF_ENDPOINT_HALT:
2298 goto tr_handle_set_halt;
2299 case UF_DEVICE_REMOTE_WAKEUP:
2300 goto tr_handle_set_wakeup;
2301 default:
2302 goto tr_stalled;
2303 }
2304 break;
2305 case UR_SYNCH_FRAME:
2306 goto tr_valid; /* nop */
2307 default:
2308 goto tr_stalled;
2309 }
2310 break;
2311
2312 case UT_READ_ENDPOINT:
2313 switch (req->bRequest) {
2314 case UR_GET_STATUS:
2315 goto tr_handle_get_ep_status;
2316 default:
2317 goto tr_stalled;
2318 }
2319 break;
2320
2321 case UT_WRITE_INTERFACE:
2322 switch (req->bRequest) {
2323 case UR_SET_INTERFACE:
2324 goto tr_handle_set_interface;
2325 case UR_CLEAR_FEATURE:
2326 goto tr_valid; /* nop */
2327 case UR_SET_FEATURE:
2328 default:
2329 goto tr_stalled;
2330 }
2331 break;
2332
2333 case UT_READ_INTERFACE:
2334 switch (req->bRequest) {
2335 case UR_GET_INTERFACE:
2336 goto tr_handle_get_interface;
2337 case UR_GET_STATUS:
2338 goto tr_handle_get_iface_status;
2339 default:
2340 goto tr_stalled;
2341 }
2342 break;
2343
2344 case UT_WRITE_CLASS_INTERFACE:
2345 case UT_WRITE_VENDOR_INTERFACE:
2346 /* XXX forward */
2347 break;
2348
2349 case UT_READ_CLASS_INTERFACE:
2350 case UT_READ_VENDOR_INTERFACE:
2351 /* XXX forward */
2352 break;
2353
2354 case UT_WRITE_CLASS_DEVICE:
2355 switch (req->bRequest) {
2356 case UR_CLEAR_FEATURE:
2357 goto tr_valid;
2358 case UR_SET_DESCRIPTOR:
2359 case UR_SET_FEATURE:
2360 break;
2361 default:
2362 goto tr_stalled;
2363 }
2364 break;
2365
2366 case UT_WRITE_CLASS_OTHER:
2367 switch (req->bRequest) {
2368 case UR_CLEAR_FEATURE:
2369 goto tr_handle_clear_port_feature;
2370 case UR_SET_FEATURE:
2371 goto tr_handle_set_port_feature;
2372 case UR_CLEAR_TT_BUFFER:
2373 case UR_RESET_TT:
2374 case UR_STOP_TT:
2375 goto tr_valid;
2376
2377 default:
2378 goto tr_stalled;
2379 }
2380 break;
2381
2382 case UT_READ_CLASS_OTHER:
2383 switch (req->bRequest) {
2384 case UR_GET_TT_STATE:
2385 goto tr_handle_get_tt_state;
2386 case UR_GET_STATUS:
2387 goto tr_handle_get_port_status;
2388 default:
2389 goto tr_stalled;
2390 }
2391 break;
2392
2393 case UT_READ_CLASS_DEVICE:
2394 switch (req->bRequest) {
2395 case UR_GET_DESCRIPTOR:
2396 goto tr_handle_get_class_descriptor;
2397 case UR_GET_STATUS:
2398 goto tr_handle_get_class_status;
2399
2400 default:
2401 goto tr_stalled;
2402 }
2403 break;
2404 default:
2405 goto tr_stalled;
2406 }
2407 goto tr_valid;
2408
2409tr_handle_get_descriptor:
2410 switch (value >> 8) {
2411 case UDESC_DEVICE:
2412 if (value & 0xff) {
2413 goto tr_stalled;
2414 }
2415 len = sizeof(musbotg_devd);
2416 ptr = (const void *)&musbotg_devd;
2417 goto tr_valid;
2418 case UDESC_CONFIG:
2419 if (value & 0xff) {
2420 goto tr_stalled;
2421 }
2422 len = sizeof(musbotg_confd);
2423 ptr = (const void *)&musbotg_confd;
2424 goto tr_valid;
2425 case UDESC_STRING:
2426 switch (value & 0xff) {
2427 case 0: /* Language table */
2223USB_MAKE_STRING_DESC(STRING_VENDOR, musbotg_vendor);
2224USB_MAKE_STRING_DESC(STRING_PRODUCT, musbotg_product);
2225
2226static usb_error_t
2227musbotg_roothub_exec(struct usb_device *udev,
2228 struct usb_device_request *req, const void **pptr, uint16_t *plength)
2229{
2230 struct musbotg_softc *sc = MUSBOTG_BUS2SC(udev->bus);
2231 const void *ptr;
2232 uint16_t len;
2233 uint16_t value;
2234 uint16_t index;
2235 usb_error_t err;
2236
2237 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
2238
2239 /* buffer reset */
2240 ptr = (const void *)&sc->sc_hub_temp;
2241 len = 0;
2242 err = 0;
2243
2244 value = UGETW(req->wValue);
2245 index = UGETW(req->wIndex);
2246
2247 /* demultiplex the control request */
2248
2249 switch (req->bmRequestType) {
2250 case UT_READ_DEVICE:
2251 switch (req->bRequest) {
2252 case UR_GET_DESCRIPTOR:
2253 goto tr_handle_get_descriptor;
2254 case UR_GET_CONFIG:
2255 goto tr_handle_get_config;
2256 case UR_GET_STATUS:
2257 goto tr_handle_get_status;
2258 default:
2259 goto tr_stalled;
2260 }
2261 break;
2262
2263 case UT_WRITE_DEVICE:
2264 switch (req->bRequest) {
2265 case UR_SET_ADDRESS:
2266 goto tr_handle_set_address;
2267 case UR_SET_CONFIG:
2268 goto tr_handle_set_config;
2269 case UR_CLEAR_FEATURE:
2270 goto tr_valid; /* nop */
2271 case UR_SET_DESCRIPTOR:
2272 goto tr_valid; /* nop */
2273 case UR_SET_FEATURE:
2274 default:
2275 goto tr_stalled;
2276 }
2277 break;
2278
2279 case UT_WRITE_ENDPOINT:
2280 switch (req->bRequest) {
2281 case UR_CLEAR_FEATURE:
2282 switch (UGETW(req->wValue)) {
2283 case UF_ENDPOINT_HALT:
2284 goto tr_handle_clear_halt;
2285 case UF_DEVICE_REMOTE_WAKEUP:
2286 goto tr_handle_clear_wakeup;
2287 default:
2288 goto tr_stalled;
2289 }
2290 break;
2291 case UR_SET_FEATURE:
2292 switch (UGETW(req->wValue)) {
2293 case UF_ENDPOINT_HALT:
2294 goto tr_handle_set_halt;
2295 case UF_DEVICE_REMOTE_WAKEUP:
2296 goto tr_handle_set_wakeup;
2297 default:
2298 goto tr_stalled;
2299 }
2300 break;
2301 case UR_SYNCH_FRAME:
2302 goto tr_valid; /* nop */
2303 default:
2304 goto tr_stalled;
2305 }
2306 break;
2307
2308 case UT_READ_ENDPOINT:
2309 switch (req->bRequest) {
2310 case UR_GET_STATUS:
2311 goto tr_handle_get_ep_status;
2312 default:
2313 goto tr_stalled;
2314 }
2315 break;
2316
2317 case UT_WRITE_INTERFACE:
2318 switch (req->bRequest) {
2319 case UR_SET_INTERFACE:
2320 goto tr_handle_set_interface;
2321 case UR_CLEAR_FEATURE:
2322 goto tr_valid; /* nop */
2323 case UR_SET_FEATURE:
2324 default:
2325 goto tr_stalled;
2326 }
2327 break;
2328
2329 case UT_READ_INTERFACE:
2330 switch (req->bRequest) {
2331 case UR_GET_INTERFACE:
2332 goto tr_handle_get_interface;
2333 case UR_GET_STATUS:
2334 goto tr_handle_get_iface_status;
2335 default:
2336 goto tr_stalled;
2337 }
2338 break;
2339
2340 case UT_WRITE_CLASS_INTERFACE:
2341 case UT_WRITE_VENDOR_INTERFACE:
2342 /* XXX forward */
2343 break;
2344
2345 case UT_READ_CLASS_INTERFACE:
2346 case UT_READ_VENDOR_INTERFACE:
2347 /* XXX forward */
2348 break;
2349
2350 case UT_WRITE_CLASS_DEVICE:
2351 switch (req->bRequest) {
2352 case UR_CLEAR_FEATURE:
2353 goto tr_valid;
2354 case UR_SET_DESCRIPTOR:
2355 case UR_SET_FEATURE:
2356 break;
2357 default:
2358 goto tr_stalled;
2359 }
2360 break;
2361
2362 case UT_WRITE_CLASS_OTHER:
2363 switch (req->bRequest) {
2364 case UR_CLEAR_FEATURE:
2365 goto tr_handle_clear_port_feature;
2366 case UR_SET_FEATURE:
2367 goto tr_handle_set_port_feature;
2368 case UR_CLEAR_TT_BUFFER:
2369 case UR_RESET_TT:
2370 case UR_STOP_TT:
2371 goto tr_valid;
2372
2373 default:
2374 goto tr_stalled;
2375 }
2376 break;
2377
2378 case UT_READ_CLASS_OTHER:
2379 switch (req->bRequest) {
2380 case UR_GET_TT_STATE:
2381 goto tr_handle_get_tt_state;
2382 case UR_GET_STATUS:
2383 goto tr_handle_get_port_status;
2384 default:
2385 goto tr_stalled;
2386 }
2387 break;
2388
2389 case UT_READ_CLASS_DEVICE:
2390 switch (req->bRequest) {
2391 case UR_GET_DESCRIPTOR:
2392 goto tr_handle_get_class_descriptor;
2393 case UR_GET_STATUS:
2394 goto tr_handle_get_class_status;
2395
2396 default:
2397 goto tr_stalled;
2398 }
2399 break;
2400 default:
2401 goto tr_stalled;
2402 }
2403 goto tr_valid;
2404
2405tr_handle_get_descriptor:
2406 switch (value >> 8) {
2407 case UDESC_DEVICE:
2408 if (value & 0xff) {
2409 goto tr_stalled;
2410 }
2411 len = sizeof(musbotg_devd);
2412 ptr = (const void *)&musbotg_devd;
2413 goto tr_valid;
2414 case UDESC_CONFIG:
2415 if (value & 0xff) {
2416 goto tr_stalled;
2417 }
2418 len = sizeof(musbotg_confd);
2419 ptr = (const void *)&musbotg_confd;
2420 goto tr_valid;
2421 case UDESC_STRING:
2422 switch (value & 0xff) {
2423 case 0: /* Language table */
2428 len = sizeof(musbotg_langtab);
2429 ptr = (const void *)&musbotg_langtab;
2424 len = sizeof(usb_string_lang_en);
2425 ptr = (const void *)&usb_string_lang_en;
2430 goto tr_valid;
2431
2432 case 1: /* Vendor */
2433 len = sizeof(musbotg_vendor);
2434 ptr = (const void *)&musbotg_vendor;
2435 goto tr_valid;
2436
2437 case 2: /* Product */
2438 len = sizeof(musbotg_product);
2439 ptr = (const void *)&musbotg_product;
2440 goto tr_valid;
2441 default:
2442 break;
2443 }
2444 break;
2445 default:
2446 goto tr_stalled;
2447 }
2448 goto tr_stalled;
2449
2450tr_handle_get_config:
2451 len = 1;
2452 sc->sc_hub_temp.wValue[0] = sc->sc_conf;
2453 goto tr_valid;
2454
2455tr_handle_get_status:
2456 len = 2;
2457 USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
2458 goto tr_valid;
2459
2460tr_handle_set_address:
2461 if (value & 0xFF00) {
2462 goto tr_stalled;
2463 }
2464 sc->sc_rt_addr = value;
2465 goto tr_valid;
2466
2467tr_handle_set_config:
2468 if (value >= 2) {
2469 goto tr_stalled;
2470 }
2471 sc->sc_conf = value;
2472 goto tr_valid;
2473
2474tr_handle_get_interface:
2475 len = 1;
2476 sc->sc_hub_temp.wValue[0] = 0;
2477 goto tr_valid;
2478
2479tr_handle_get_tt_state:
2480tr_handle_get_class_status:
2481tr_handle_get_iface_status:
2482tr_handle_get_ep_status:
2483 len = 2;
2484 USETW(sc->sc_hub_temp.wValue, 0);
2485 goto tr_valid;
2486
2487tr_handle_set_halt:
2488tr_handle_set_interface:
2489tr_handle_set_wakeup:
2490tr_handle_clear_wakeup:
2491tr_handle_clear_halt:
2492 goto tr_valid;
2493
2494tr_handle_clear_port_feature:
2495 if (index != 1) {
2496 goto tr_stalled;
2497 }
2498 DPRINTFN(8, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
2499
2500 switch (value) {
2501 case UHF_PORT_SUSPEND:
2502 musbotg_wakeup_peer(sc);
2503 break;
2504
2505 case UHF_PORT_ENABLE:
2506 sc->sc_flags.port_enabled = 0;
2507 break;
2508
2509 case UHF_PORT_TEST:
2510 case UHF_PORT_INDICATOR:
2511 case UHF_C_PORT_ENABLE:
2512 case UHF_C_PORT_OVER_CURRENT:
2513 case UHF_C_PORT_RESET:
2514 /* nops */
2515 break;
2516 case UHF_PORT_POWER:
2517 sc->sc_flags.port_powered = 0;
2518 musbotg_pull_down(sc);
2519 musbotg_clocks_off(sc);
2520 break;
2521 case UHF_C_PORT_CONNECTION:
2522 sc->sc_flags.change_connect = 0;
2523 break;
2524 case UHF_C_PORT_SUSPEND:
2525 sc->sc_flags.change_suspend = 0;
2526 break;
2527 default:
2528 err = USB_ERR_IOERROR;
2529 goto done;
2530 }
2531 goto tr_valid;
2532
2533tr_handle_set_port_feature:
2534 if (index != 1) {
2535 goto tr_stalled;
2536 }
2537 DPRINTFN(8, "UR_SET_PORT_FEATURE\n");
2538
2539 switch (value) {
2540 case UHF_PORT_ENABLE:
2541 sc->sc_flags.port_enabled = 1;
2542 break;
2543 case UHF_PORT_SUSPEND:
2544 case UHF_PORT_RESET:
2545 case UHF_PORT_TEST:
2546 case UHF_PORT_INDICATOR:
2547 /* nops */
2548 break;
2549 case UHF_PORT_POWER:
2550 sc->sc_flags.port_powered = 1;
2551 break;
2552 default:
2553 err = USB_ERR_IOERROR;
2554 goto done;
2555 }
2556 goto tr_valid;
2557
2558tr_handle_get_port_status:
2559
2560 DPRINTFN(8, "UR_GET_PORT_STATUS\n");
2561
2562 if (index != 1) {
2563 goto tr_stalled;
2564 }
2565 if (sc->sc_flags.status_vbus) {
2566 musbotg_clocks_on(sc);
2567 musbotg_pull_up(sc);
2568 } else {
2569 musbotg_pull_down(sc);
2570 musbotg_clocks_off(sc);
2571 }
2572
2573 /* Select Device Side Mode */
2574 value = UPS_PORT_MODE_DEVICE;
2575
2576 if (sc->sc_flags.status_high_speed) {
2577 value |= UPS_HIGH_SPEED;
2578 }
2579 if (sc->sc_flags.port_powered) {
2580 value |= UPS_PORT_POWER;
2581 }
2582 if (sc->sc_flags.port_enabled) {
2583 value |= UPS_PORT_ENABLED;
2584 }
2585 if (sc->sc_flags.status_vbus &&
2586 sc->sc_flags.status_bus_reset) {
2587 value |= UPS_CURRENT_CONNECT_STATUS;
2588 }
2589 if (sc->sc_flags.status_suspend) {
2590 value |= UPS_SUSPEND;
2591 }
2592 USETW(sc->sc_hub_temp.ps.wPortStatus, value);
2593
2594 value = 0;
2595
2596 if (sc->sc_flags.change_connect) {
2597 value |= UPS_C_CONNECT_STATUS;
2598
2599 if (sc->sc_flags.status_vbus &&
2600 sc->sc_flags.status_bus_reset) {
2601 /* reset EP0 state */
2602 sc->sc_ep0_busy = 0;
2603 sc->sc_ep0_cmd = 0;
2604 }
2605 }
2606 if (sc->sc_flags.change_suspend) {
2607 value |= UPS_C_SUSPEND;
2608 }
2609 USETW(sc->sc_hub_temp.ps.wPortChange, value);
2610 len = sizeof(sc->sc_hub_temp.ps);
2611 goto tr_valid;
2612
2613tr_handle_get_class_descriptor:
2614 if (value & 0xFF) {
2615 goto tr_stalled;
2616 }
2617 ptr = (const void *)&musbotg_hubd;
2618 len = sizeof(musbotg_hubd);
2619 goto tr_valid;
2620
2621tr_stalled:
2622 err = USB_ERR_STALLED;
2623tr_valid:
2624done:
2625 *plength = len;
2626 *pptr = ptr;
2627 return (err);
2628}
2629
2630static void
2631musbotg_xfer_setup(struct usb_setup_params *parm)
2632{
2633 const struct usb_hw_ep_profile *pf;
2634 struct musbotg_softc *sc;
2635 struct usb_xfer *xfer;
2636 void *last_obj;
2637 uint32_t ntd;
2638 uint32_t n;
2639 uint8_t ep_no;
2640
2641 sc = MUSBOTG_BUS2SC(parm->udev->bus);
2642 xfer = parm->curr_xfer;
2643
2644 /*
2645 * NOTE: This driver does not use any of the parameters that
2646 * are computed from the following values. Just set some
2647 * reasonable dummies:
2648 */
2649 parm->hc_max_packet_size = 0x400;
2650 parm->hc_max_frame_size = 0x400;
2651
2652 if ((parm->methods == &musbotg_device_isoc_methods) ||
2653 (parm->methods == &musbotg_device_intr_methods))
2654 parm->hc_max_packet_count = 3;
2655 else
2656 parm->hc_max_packet_count = 1;
2657
2658 usbd_transfer_setup_sub(parm);
2659
2660 /*
2661 * compute maximum number of TDs
2662 */
2663 if (parm->methods == &musbotg_device_ctrl_methods) {
2664
2665 ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
2666
2667 } else if (parm->methods == &musbotg_device_bulk_methods) {
2668
2669 ntd = xfer->nframes + 1 /* SYNC */ ;
2670
2671 } else if (parm->methods == &musbotg_device_intr_methods) {
2672
2673 ntd = xfer->nframes + 1 /* SYNC */ ;
2674
2675 } else if (parm->methods == &musbotg_device_isoc_methods) {
2676
2677 ntd = xfer->nframes + 1 /* SYNC */ ;
2678
2679 } else {
2680
2681 ntd = 0;
2682 }
2683
2684 /*
2685 * check if "usbd_transfer_setup_sub" set an error
2686 */
2687 if (parm->err) {
2688 return;
2689 }
2690 /*
2691 * allocate transfer descriptors
2692 */
2693 last_obj = NULL;
2694
2695 /*
2696 * get profile stuff
2697 */
2698 if (ntd) {
2699
2700 ep_no = xfer->endpointno & UE_ADDR;
2701 musbotg_get_hw_ep_profile(parm->udev, &pf, ep_no);
2702
2703 if (pf == NULL) {
2704 /* should not happen */
2705 parm->err = USB_ERR_INVAL;
2706 return;
2707 }
2708 } else {
2709 ep_no = 0;
2710 pf = NULL;
2711 }
2712
2713 /* align data */
2714 parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
2715
2716 for (n = 0; n != ntd; n++) {
2717
2718 struct musbotg_td *td;
2719
2720 if (parm->buf) {
2721
2722 td = USB_ADD_BYTES(parm->buf, parm->size[0]);
2723
2724 /* init TD */
2725 td->max_frame_size = xfer->max_frame_size;
2726 td->ep_no = ep_no;
2727 td->obj_next = last_obj;
2728
2729 last_obj = td;
2730 }
2731 parm->size[0] += sizeof(*td);
2732 }
2733
2734 xfer->td_start[0] = last_obj;
2735}
2736
2737static void
2738musbotg_xfer_unsetup(struct usb_xfer *xfer)
2739{
2740 return;
2741}
2742
2743static void
2744musbotg_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
2745 struct usb_endpoint *ep)
2746{
2747 struct musbotg_softc *sc = MUSBOTG_BUS2SC(udev->bus);
2748
2749 DPRINTFN(2, "endpoint=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
2750 ep, udev->address,
2751 edesc->bEndpointAddress, udev->flags.usb_mode,
2752 sc->sc_rt_addr);
2753
2754 if (udev->device_index != sc->sc_rt_addr) {
2755
2756 if ((udev->speed != USB_SPEED_FULL) &&
2757 (udev->speed != USB_SPEED_HIGH)) {
2758 /* not supported */
2759 return;
2760 }
2761 switch (edesc->bmAttributes & UE_XFERTYPE) {
2762 case UE_CONTROL:
2763 ep->methods = &musbotg_device_ctrl_methods;
2764 break;
2765 case UE_INTERRUPT:
2766 ep->methods = &musbotg_device_intr_methods;
2767 break;
2768 case UE_ISOCHRONOUS:
2769 ep->methods = &musbotg_device_isoc_methods;
2770 break;
2771 case UE_BULK:
2772 ep->methods = &musbotg_device_bulk_methods;
2773 break;
2774 default:
2775 /* do nothing */
2776 break;
2777 }
2778 }
2779}
2780
2781static void
2782musbotg_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
2783{
2784 struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
2785
2786 switch (state) {
2787 case USB_HW_POWER_SUSPEND:
2788 musbotg_suspend(sc);
2789 break;
2790 case USB_HW_POWER_SHUTDOWN:
2791 musbotg_uninit(sc);
2792 break;
2793 case USB_HW_POWER_RESUME:
2794 musbotg_resume(sc);
2795 break;
2796 default:
2797 break;
2798 }
2799}
2800
2801struct usb_bus_methods musbotg_bus_methods =
2802{
2803 .endpoint_init = &musbotg_ep_init,
2804 .xfer_setup = &musbotg_xfer_setup,
2805 .xfer_unsetup = &musbotg_xfer_unsetup,
2806 .get_hw_ep_profile = &musbotg_get_hw_ep_profile,
2807 .xfer_stall = &musbotg_xfer_stall,
2808 .set_stall = &musbotg_set_stall,
2809 .clear_stall = &musbotg_clear_stall,
2810 .roothub_exec = &musbotg_roothub_exec,
2811 .xfer_poll = &musbotg_do_poll,
2812 .set_hw_power_sleep = &musbotg_set_hw_power_sleep,
2813};
2426 goto tr_valid;
2427
2428 case 1: /* Vendor */
2429 len = sizeof(musbotg_vendor);
2430 ptr = (const void *)&musbotg_vendor;
2431 goto tr_valid;
2432
2433 case 2: /* Product */
2434 len = sizeof(musbotg_product);
2435 ptr = (const void *)&musbotg_product;
2436 goto tr_valid;
2437 default:
2438 break;
2439 }
2440 break;
2441 default:
2442 goto tr_stalled;
2443 }
2444 goto tr_stalled;
2445
2446tr_handle_get_config:
2447 len = 1;
2448 sc->sc_hub_temp.wValue[0] = sc->sc_conf;
2449 goto tr_valid;
2450
2451tr_handle_get_status:
2452 len = 2;
2453 USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
2454 goto tr_valid;
2455
2456tr_handle_set_address:
2457 if (value & 0xFF00) {
2458 goto tr_stalled;
2459 }
2460 sc->sc_rt_addr = value;
2461 goto tr_valid;
2462
2463tr_handle_set_config:
2464 if (value >= 2) {
2465 goto tr_stalled;
2466 }
2467 sc->sc_conf = value;
2468 goto tr_valid;
2469
2470tr_handle_get_interface:
2471 len = 1;
2472 sc->sc_hub_temp.wValue[0] = 0;
2473 goto tr_valid;
2474
2475tr_handle_get_tt_state:
2476tr_handle_get_class_status:
2477tr_handle_get_iface_status:
2478tr_handle_get_ep_status:
2479 len = 2;
2480 USETW(sc->sc_hub_temp.wValue, 0);
2481 goto tr_valid;
2482
2483tr_handle_set_halt:
2484tr_handle_set_interface:
2485tr_handle_set_wakeup:
2486tr_handle_clear_wakeup:
2487tr_handle_clear_halt:
2488 goto tr_valid;
2489
2490tr_handle_clear_port_feature:
2491 if (index != 1) {
2492 goto tr_stalled;
2493 }
2494 DPRINTFN(8, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
2495
2496 switch (value) {
2497 case UHF_PORT_SUSPEND:
2498 musbotg_wakeup_peer(sc);
2499 break;
2500
2501 case UHF_PORT_ENABLE:
2502 sc->sc_flags.port_enabled = 0;
2503 break;
2504
2505 case UHF_PORT_TEST:
2506 case UHF_PORT_INDICATOR:
2507 case UHF_C_PORT_ENABLE:
2508 case UHF_C_PORT_OVER_CURRENT:
2509 case UHF_C_PORT_RESET:
2510 /* nops */
2511 break;
2512 case UHF_PORT_POWER:
2513 sc->sc_flags.port_powered = 0;
2514 musbotg_pull_down(sc);
2515 musbotg_clocks_off(sc);
2516 break;
2517 case UHF_C_PORT_CONNECTION:
2518 sc->sc_flags.change_connect = 0;
2519 break;
2520 case UHF_C_PORT_SUSPEND:
2521 sc->sc_flags.change_suspend = 0;
2522 break;
2523 default:
2524 err = USB_ERR_IOERROR;
2525 goto done;
2526 }
2527 goto tr_valid;
2528
2529tr_handle_set_port_feature:
2530 if (index != 1) {
2531 goto tr_stalled;
2532 }
2533 DPRINTFN(8, "UR_SET_PORT_FEATURE\n");
2534
2535 switch (value) {
2536 case UHF_PORT_ENABLE:
2537 sc->sc_flags.port_enabled = 1;
2538 break;
2539 case UHF_PORT_SUSPEND:
2540 case UHF_PORT_RESET:
2541 case UHF_PORT_TEST:
2542 case UHF_PORT_INDICATOR:
2543 /* nops */
2544 break;
2545 case UHF_PORT_POWER:
2546 sc->sc_flags.port_powered = 1;
2547 break;
2548 default:
2549 err = USB_ERR_IOERROR;
2550 goto done;
2551 }
2552 goto tr_valid;
2553
2554tr_handle_get_port_status:
2555
2556 DPRINTFN(8, "UR_GET_PORT_STATUS\n");
2557
2558 if (index != 1) {
2559 goto tr_stalled;
2560 }
2561 if (sc->sc_flags.status_vbus) {
2562 musbotg_clocks_on(sc);
2563 musbotg_pull_up(sc);
2564 } else {
2565 musbotg_pull_down(sc);
2566 musbotg_clocks_off(sc);
2567 }
2568
2569 /* Select Device Side Mode */
2570 value = UPS_PORT_MODE_DEVICE;
2571
2572 if (sc->sc_flags.status_high_speed) {
2573 value |= UPS_HIGH_SPEED;
2574 }
2575 if (sc->sc_flags.port_powered) {
2576 value |= UPS_PORT_POWER;
2577 }
2578 if (sc->sc_flags.port_enabled) {
2579 value |= UPS_PORT_ENABLED;
2580 }
2581 if (sc->sc_flags.status_vbus &&
2582 sc->sc_flags.status_bus_reset) {
2583 value |= UPS_CURRENT_CONNECT_STATUS;
2584 }
2585 if (sc->sc_flags.status_suspend) {
2586 value |= UPS_SUSPEND;
2587 }
2588 USETW(sc->sc_hub_temp.ps.wPortStatus, value);
2589
2590 value = 0;
2591
2592 if (sc->sc_flags.change_connect) {
2593 value |= UPS_C_CONNECT_STATUS;
2594
2595 if (sc->sc_flags.status_vbus &&
2596 sc->sc_flags.status_bus_reset) {
2597 /* reset EP0 state */
2598 sc->sc_ep0_busy = 0;
2599 sc->sc_ep0_cmd = 0;
2600 }
2601 }
2602 if (sc->sc_flags.change_suspend) {
2603 value |= UPS_C_SUSPEND;
2604 }
2605 USETW(sc->sc_hub_temp.ps.wPortChange, value);
2606 len = sizeof(sc->sc_hub_temp.ps);
2607 goto tr_valid;
2608
2609tr_handle_get_class_descriptor:
2610 if (value & 0xFF) {
2611 goto tr_stalled;
2612 }
2613 ptr = (const void *)&musbotg_hubd;
2614 len = sizeof(musbotg_hubd);
2615 goto tr_valid;
2616
2617tr_stalled:
2618 err = USB_ERR_STALLED;
2619tr_valid:
2620done:
2621 *plength = len;
2622 *pptr = ptr;
2623 return (err);
2624}
2625
2626static void
2627musbotg_xfer_setup(struct usb_setup_params *parm)
2628{
2629 const struct usb_hw_ep_profile *pf;
2630 struct musbotg_softc *sc;
2631 struct usb_xfer *xfer;
2632 void *last_obj;
2633 uint32_t ntd;
2634 uint32_t n;
2635 uint8_t ep_no;
2636
2637 sc = MUSBOTG_BUS2SC(parm->udev->bus);
2638 xfer = parm->curr_xfer;
2639
2640 /*
2641 * NOTE: This driver does not use any of the parameters that
2642 * are computed from the following values. Just set some
2643 * reasonable dummies:
2644 */
2645 parm->hc_max_packet_size = 0x400;
2646 parm->hc_max_frame_size = 0x400;
2647
2648 if ((parm->methods == &musbotg_device_isoc_methods) ||
2649 (parm->methods == &musbotg_device_intr_methods))
2650 parm->hc_max_packet_count = 3;
2651 else
2652 parm->hc_max_packet_count = 1;
2653
2654 usbd_transfer_setup_sub(parm);
2655
2656 /*
2657 * compute maximum number of TDs
2658 */
2659 if (parm->methods == &musbotg_device_ctrl_methods) {
2660
2661 ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
2662
2663 } else if (parm->methods == &musbotg_device_bulk_methods) {
2664
2665 ntd = xfer->nframes + 1 /* SYNC */ ;
2666
2667 } else if (parm->methods == &musbotg_device_intr_methods) {
2668
2669 ntd = xfer->nframes + 1 /* SYNC */ ;
2670
2671 } else if (parm->methods == &musbotg_device_isoc_methods) {
2672
2673 ntd = xfer->nframes + 1 /* SYNC */ ;
2674
2675 } else {
2676
2677 ntd = 0;
2678 }
2679
2680 /*
2681 * check if "usbd_transfer_setup_sub" set an error
2682 */
2683 if (parm->err) {
2684 return;
2685 }
2686 /*
2687 * allocate transfer descriptors
2688 */
2689 last_obj = NULL;
2690
2691 /*
2692 * get profile stuff
2693 */
2694 if (ntd) {
2695
2696 ep_no = xfer->endpointno & UE_ADDR;
2697 musbotg_get_hw_ep_profile(parm->udev, &pf, ep_no);
2698
2699 if (pf == NULL) {
2700 /* should not happen */
2701 parm->err = USB_ERR_INVAL;
2702 return;
2703 }
2704 } else {
2705 ep_no = 0;
2706 pf = NULL;
2707 }
2708
2709 /* align data */
2710 parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
2711
2712 for (n = 0; n != ntd; n++) {
2713
2714 struct musbotg_td *td;
2715
2716 if (parm->buf) {
2717
2718 td = USB_ADD_BYTES(parm->buf, parm->size[0]);
2719
2720 /* init TD */
2721 td->max_frame_size = xfer->max_frame_size;
2722 td->ep_no = ep_no;
2723 td->obj_next = last_obj;
2724
2725 last_obj = td;
2726 }
2727 parm->size[0] += sizeof(*td);
2728 }
2729
2730 xfer->td_start[0] = last_obj;
2731}
2732
2733static void
2734musbotg_xfer_unsetup(struct usb_xfer *xfer)
2735{
2736 return;
2737}
2738
2739static void
2740musbotg_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
2741 struct usb_endpoint *ep)
2742{
2743 struct musbotg_softc *sc = MUSBOTG_BUS2SC(udev->bus);
2744
2745 DPRINTFN(2, "endpoint=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
2746 ep, udev->address,
2747 edesc->bEndpointAddress, udev->flags.usb_mode,
2748 sc->sc_rt_addr);
2749
2750 if (udev->device_index != sc->sc_rt_addr) {
2751
2752 if ((udev->speed != USB_SPEED_FULL) &&
2753 (udev->speed != USB_SPEED_HIGH)) {
2754 /* not supported */
2755 return;
2756 }
2757 switch (edesc->bmAttributes & UE_XFERTYPE) {
2758 case UE_CONTROL:
2759 ep->methods = &musbotg_device_ctrl_methods;
2760 break;
2761 case UE_INTERRUPT:
2762 ep->methods = &musbotg_device_intr_methods;
2763 break;
2764 case UE_ISOCHRONOUS:
2765 ep->methods = &musbotg_device_isoc_methods;
2766 break;
2767 case UE_BULK:
2768 ep->methods = &musbotg_device_bulk_methods;
2769 break;
2770 default:
2771 /* do nothing */
2772 break;
2773 }
2774 }
2775}
2776
2777static void
2778musbotg_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
2779{
2780 struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
2781
2782 switch (state) {
2783 case USB_HW_POWER_SUSPEND:
2784 musbotg_suspend(sc);
2785 break;
2786 case USB_HW_POWER_SHUTDOWN:
2787 musbotg_uninit(sc);
2788 break;
2789 case USB_HW_POWER_RESUME:
2790 musbotg_resume(sc);
2791 break;
2792 default:
2793 break;
2794 }
2795}
2796
2797struct usb_bus_methods musbotg_bus_methods =
2798{
2799 .endpoint_init = &musbotg_ep_init,
2800 .xfer_setup = &musbotg_xfer_setup,
2801 .xfer_unsetup = &musbotg_xfer_unsetup,
2802 .get_hw_ep_profile = &musbotg_get_hw_ep_profile,
2803 .xfer_stall = &musbotg_xfer_stall,
2804 .set_stall = &musbotg_set_stall,
2805 .clear_stall = &musbotg_clear_stall,
2806 .roothub_exec = &musbotg_roothub_exec,
2807 .xfer_poll = &musbotg_do_poll,
2808 .set_hw_power_sleep = &musbotg_set_hw_power_sleep,
2809};