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