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