octusb.c revision 331722
1#include <sys/cdefs.h> 2__FBSDID("$FreeBSD: stable/11/sys/mips/cavium/usb/octusb.c 331722 2018-03-29 02:50:57Z eadler $"); 3 4/*- 5 * Copyright (c) 2010 Hans Petter Selasky. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29/* 30 * This file contains the driver for Octeon Executive Library USB 31 * Controller driver API. 32 */ 33 34/* TODO: The root HUB port callback is not yet implemented. */ 35 36#include <sys/stdint.h> 37#include <sys/stddef.h> 38#include <sys/param.h> 39#include <sys/queue.h> 40#include <sys/types.h> 41#include <sys/systm.h> 42#include <sys/kernel.h> 43#include <sys/bus.h> 44#include <sys/module.h> 45#include <sys/lock.h> 46#include <sys/mutex.h> 47#include <sys/condvar.h> 48#include <sys/sysctl.h> 49#include <sys/sx.h> 50#include <sys/unistd.h> 51#include <sys/callout.h> 52#include <sys/malloc.h> 53#include <sys/priv.h> 54 55#include <dev/usb/usb.h> 56#include <dev/usb/usbdi.h> 57 58#define USB_DEBUG_VAR octusbdebug 59 60#include <dev/usb/usb_core.h> 61#include <dev/usb/usb_debug.h> 62#include <dev/usb/usb_busdma.h> 63#include <dev/usb/usb_process.h> 64#include <dev/usb/usb_transfer.h> 65#include <dev/usb/usb_device.h> 66#include <dev/usb/usb_hub.h> 67#include <dev/usb/usb_util.h> 68 69#include <dev/usb/usb_controller.h> 70#include <dev/usb/usb_bus.h> 71 72#include <contrib/octeon-sdk/cvmx.h> 73#include <contrib/octeon-sdk/cvmx-usb.h> 74 75#include <mips/cavium/usb/octusb.h> 76 77#define OCTUSB_BUS2SC(bus) \ 78 ((struct octusb_softc *)(((uint8_t *)(bus)) - \ 79 ((uint8_t *)&(((struct octusb_softc *)0)->sc_bus)))) 80 81#ifdef USB_DEBUG 82static int octusbdebug = 0; 83 84static SYSCTL_NODE(_hw_usb, OID_AUTO, octusb, CTLFLAG_RW, 0, "OCTUSB"); 85SYSCTL_INT(_hw_usb_octusb, OID_AUTO, debug, CTLFLAG_RWTUN, 86 &octusbdebug, 0, "OCTUSB debug level"); 87#endif 88 89struct octusb_std_temp { 90 octusb_cmd_t *func; 91 struct octusb_td *td; 92 struct octusb_td *td_next; 93 struct usb_page_cache *pc; 94 uint32_t offset; 95 uint32_t len; 96 uint8_t short_pkt; 97 uint8_t setup_alt_next; 98}; 99 100extern struct usb_bus_methods octusb_bus_methods; 101extern struct usb_pipe_methods octusb_device_bulk_methods; 102extern struct usb_pipe_methods octusb_device_ctrl_methods; 103extern struct usb_pipe_methods octusb_device_intr_methods; 104extern struct usb_pipe_methods octusb_device_isoc_methods; 105 106static void octusb_standard_done(struct usb_xfer *); 107static void octusb_device_done(struct usb_xfer *, usb_error_t); 108static void octusb_timeout(void *); 109static void octusb_do_poll(struct usb_bus *); 110 111static cvmx_usb_speed_t 112octusb_convert_speed(enum usb_dev_speed speed) 113{ 114 ; /* indent fix */ 115 switch (speed) { 116 case USB_SPEED_HIGH: 117 return (CVMX_USB_SPEED_HIGH); 118 case USB_SPEED_FULL: 119 return (CVMX_USB_SPEED_FULL); 120 default: 121 return (CVMX_USB_SPEED_LOW); 122 } 123} 124 125static cvmx_usb_transfer_t 126octusb_convert_ep_type(uint8_t ep_type) 127{ 128 ; /* indent fix */ 129 switch (ep_type & UE_XFERTYPE) { 130 case UE_CONTROL: 131 return (CVMX_USB_TRANSFER_CONTROL); 132 case UE_INTERRUPT: 133 return (CVMX_USB_TRANSFER_INTERRUPT); 134 case UE_ISOCHRONOUS: 135 return (CVMX_USB_TRANSFER_ISOCHRONOUS); 136 case UE_BULK: 137 return (CVMX_USB_TRANSFER_BULK); 138 default: 139 return (0); /* should not happen */ 140 } 141} 142 143static uint8_t 144octusb_host_alloc_endpoint(struct octusb_td *td) 145{ 146 struct octusb_softc *sc; 147 int ep_handle; 148 149 if (td->qh->fixup_pending) 150 return (1); /* busy */ 151 152 if (td->qh->ep_allocated) 153 return (0); /* success */ 154 155 /* get softc */ 156 sc = td->qh->sc; 157 158 ep_handle = cvmx_usb_open_pipe( 159 &sc->sc_port[td->qh->root_port_index].state, 160 0, 161 td->qh->dev_addr, 162 td->qh->ep_num & UE_ADDR, 163 octusb_convert_speed(td->qh->dev_speed), 164 td->qh->max_packet_size, 165 octusb_convert_ep_type(td->qh->ep_type), 166 (td->qh->ep_num & UE_DIR_IN) ? CVMX_USB_DIRECTION_IN : 167 CVMX_USB_DIRECTION_OUT, 168 td->qh->ep_interval, 169 (td->qh->dev_speed == USB_SPEED_HIGH) ? td->qh->ep_mult : 0, 170 td->qh->hs_hub_addr, 171 td->qh->hs_hub_port); 172 173 if (ep_handle < 0) { 174 DPRINTFN(1, "cvmx_usb_open_pipe failed: %d\n", ep_handle); 175 return (1); /* busy */ 176 } 177 178 cvmx_usb_set_toggle( 179 &sc->sc_port[td->qh->root_port_index].state, 180 ep_handle, td->qh->ep_toggle_next); 181 182 td->qh->fixup_handle = -1; 183 td->qh->fixup_complete = 0; 184 td->qh->fixup_len = 0; 185 td->qh->fixup_off = 0; 186 td->qh->fixup_pending = 0; 187 td->qh->fixup_actlen = 0; 188 189 td->qh->ep_handle = ep_handle; 190 td->qh->ep_allocated = 1; 191 192 return (0); /* success */ 193} 194 195static void 196octusb_host_free_endpoint(struct octusb_td *td) 197{ 198 struct octusb_softc *sc; 199 200 if (td->qh->ep_allocated == 0) 201 return; 202 203 /* get softc */ 204 sc = td->qh->sc; 205 206 if (td->qh->fixup_handle >= 0) { 207 /* cancel, if any */ 208 cvmx_usb_cancel(&sc->sc_port[td->qh->root_port_index].state, 209 td->qh->ep_handle, td->qh->fixup_handle); 210 } 211 cvmx_usb_close_pipe(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle); 212 213 td->qh->ep_allocated = 0; 214} 215 216static void 217octusb_complete_cb(cvmx_usb_state_t *state, 218 cvmx_usb_callback_t reason, 219 cvmx_usb_complete_t status, 220 int pipe_handle, int submit_handle, 221 int bytes_transferred, void *user_data) 222{ 223 struct octusb_td *td; 224 225 if (reason != CVMX_USB_CALLBACK_TRANSFER_COMPLETE) 226 return; 227 228 td = user_data; 229 230 td->qh->fixup_complete = 1; 231 td->qh->fixup_pending = 0; 232 td->qh->fixup_actlen = bytes_transferred; 233 td->qh->fixup_handle = -1; 234 235 switch (status) { 236 case CVMX_USB_COMPLETE_SUCCESS: 237 case CVMX_USB_COMPLETE_SHORT: 238 td->error_any = 0; 239 td->error_stall = 0; 240 break; 241 case CVMX_USB_COMPLETE_STALL: 242 td->error_stall = 1; 243 td->error_any = 1; 244 break; 245 default: 246 td->error_any = 1; 247 break; 248 } 249} 250 251static uint8_t 252octusb_host_control_header_tx(struct octusb_td *td) 253{ 254 int status; 255 256 /* allocate endpoint and check pending */ 257 if (octusb_host_alloc_endpoint(td)) 258 return (1); /* busy */ 259 260 /* check error */ 261 if (td->error_any) 262 return (0); /* done */ 263 264 if (td->qh->fixup_complete != 0) { 265 /* clear complete flag */ 266 td->qh->fixup_complete = 0; 267 268 /* flush data */ 269 usb_pc_cpu_invalidate(td->qh->fixup_pc); 270 return (0); /* done */ 271 } 272 /* verify length */ 273 if (td->remainder != 8) { 274 td->error_any = 1; 275 return (0); /* done */ 276 } 277 usbd_copy_out(td->pc, td->offset, td->qh->fixup_buf, 8); 278 279 /* update offset and remainder */ 280 td->offset += 8; 281 td->remainder -= 8; 282 283 /* setup data length and offset */ 284 td->qh->fixup_len = UGETW(td->qh->fixup_buf + 6); 285 td->qh->fixup_off = 0; 286 287 if (td->qh->fixup_len > (OCTUSB_MAX_FIXUP - 8)) { 288 td->error_any = 1; 289 return (0); /* done */ 290 } 291 /* do control IN request */ 292 if (td->qh->fixup_buf[0] & UE_DIR_IN) { 293 294 struct octusb_softc *sc; 295 296 /* get softc */ 297 sc = td->qh->sc; 298 299 /* flush data */ 300 usb_pc_cpu_flush(td->qh->fixup_pc); 301 302 status = cvmx_usb_submit_control( 303 &sc->sc_port[td->qh->root_port_index].state, 304 td->qh->ep_handle, td->qh->fixup_phys, 305 td->qh->fixup_phys + 8, td->qh->fixup_len, 306 &octusb_complete_cb, td); 307 /* check status */ 308 if (status < 0) { 309 td->error_any = 1; 310 return (0); /* done */ 311 } 312 td->qh->fixup_handle = status; 313 td->qh->fixup_pending = 1; 314 td->qh->fixup_complete = 0; 315 316 return (1); /* busy */ 317 } 318 return (0); /* done */ 319} 320 321static uint8_t 322octusb_host_control_data_tx(struct octusb_td *td) 323{ 324 uint32_t rem; 325 326 /* allocate endpoint and check pending */ 327 if (octusb_host_alloc_endpoint(td)) 328 return (1); /* busy */ 329 330 /* check error */ 331 if (td->error_any) 332 return (0); /* done */ 333 334 rem = td->qh->fixup_len - td->qh->fixup_off; 335 336 if (td->remainder > rem) { 337 td->error_any = 1; 338 DPRINTFN(1, "Excess setup transmit data\n"); 339 return (0); /* done */ 340 } 341 usbd_copy_out(td->pc, td->offset, td->qh->fixup_buf + 342 td->qh->fixup_off + 8, td->remainder); 343 344 td->offset += td->remainder; 345 td->qh->fixup_off += td->remainder; 346 td->remainder = 0; 347 348 return (0); /* done */ 349} 350 351static uint8_t 352octusb_host_control_data_rx(struct octusb_td *td) 353{ 354 uint32_t rem; 355 356 /* allocate endpoint and check pending */ 357 if (octusb_host_alloc_endpoint(td)) 358 return (1); /* busy */ 359 360 /* check error */ 361 if (td->error_any) 362 return (0); /* done */ 363 364 /* copy data from buffer */ 365 rem = td->qh->fixup_actlen - td->qh->fixup_off; 366 367 if (rem > td->remainder) 368 rem = td->remainder; 369 370 usbd_copy_in(td->pc, td->offset, td->qh->fixup_buf + 371 td->qh->fixup_off + 8, rem); 372 373 td->offset += rem; 374 td->remainder -= rem; 375 td->qh->fixup_off += rem; 376 377 return (0); /* done */ 378} 379 380static uint8_t 381octusb_host_control_status_tx(struct octusb_td *td) 382{ 383 int status; 384 385 /* allocate endpoint and check pending */ 386 if (octusb_host_alloc_endpoint(td)) 387 return (1); /* busy */ 388 389 /* check error */ 390 if (td->error_any) 391 return (0); /* done */ 392 393 if (td->qh->fixup_complete != 0) { 394 /* clear complete flag */ 395 td->qh->fixup_complete = 0; 396 /* done */ 397 return (0); 398 } 399 /* do control IN request */ 400 if (!(td->qh->fixup_buf[0] & UE_DIR_IN)) { 401 402 struct octusb_softc *sc; 403 404 /* get softc */ 405 sc = td->qh->sc; 406 407 /* flush data */ 408 usb_pc_cpu_flush(td->qh->fixup_pc); 409 410 /* start USB transfer */ 411 status = cvmx_usb_submit_control( 412 &sc->sc_port[td->qh->root_port_index].state, 413 td->qh->ep_handle, td->qh->fixup_phys, 414 td->qh->fixup_phys + 8, td->qh->fixup_len, 415 &octusb_complete_cb, td); 416 417 /* check status */ 418 if (status < 0) { 419 td->error_any = 1; 420 return (0); /* done */ 421 } 422 td->qh->fixup_handle = status; 423 td->qh->fixup_pending = 1; 424 td->qh->fixup_complete = 0; 425 426 return (1); /* busy */ 427 } 428 return (0); /* done */ 429} 430 431static uint8_t 432octusb_non_control_data_tx(struct octusb_td *td) 433{ 434 struct octusb_softc *sc; 435 uint32_t rem; 436 int status; 437 438 /* allocate endpoint and check pending */ 439 if (octusb_host_alloc_endpoint(td)) 440 return (1); /* busy */ 441 442 /* check error */ 443 if (td->error_any) 444 return (0); /* done */ 445 446 if ((td->qh->fixup_complete != 0) && 447 ((td->qh->ep_type & UE_XFERTYPE) == UE_ISOCHRONOUS)) { 448 td->qh->fixup_complete = 0; 449 return (0); /* done */ 450 } 451 /* check complete */ 452 if (td->remainder == 0) { 453 if (td->short_pkt) 454 return (0); /* complete */ 455 /* else need to send a zero length packet */ 456 rem = 0; 457 td->short_pkt = 1; 458 } else { 459 /* get maximum length */ 460 rem = OCTUSB_MAX_FIXUP % td->qh->max_frame_size; 461 rem = OCTUSB_MAX_FIXUP - rem; 462 463 if (rem == 0) { 464 /* should not happen */ 465 DPRINTFN(1, "Fixup buffer is too small\n"); 466 td->error_any = 1; 467 return (0); /* done */ 468 } 469 /* get minimum length */ 470 if (rem > td->remainder) { 471 rem = td->remainder; 472 if ((rem == 0) || (rem % td->qh->max_frame_size)) 473 td->short_pkt = 1; 474 } 475 /* copy data into fixup buffer */ 476 usbd_copy_out(td->pc, td->offset, td->qh->fixup_buf, rem); 477 478 /* flush data */ 479 usb_pc_cpu_flush(td->qh->fixup_pc); 480 481 /* pre-increment TX buffer offset */ 482 td->offset += rem; 483 td->remainder -= rem; 484 } 485 486 /* get softc */ 487 sc = td->qh->sc; 488 489 switch (td->qh->ep_type & UE_XFERTYPE) { 490 case UE_ISOCHRONOUS: 491 td->qh->iso_pkt.offset = 0; 492 td->qh->iso_pkt.length = rem; 493 td->qh->iso_pkt.status = 0; 494 /* start USB transfer */ 495 status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->root_port_index].state, 496 td->qh->ep_handle, 1, CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT | 497 CVMX_USB_ISOCHRONOUS_FLAGS_ASAP, 1, &td->qh->iso_pkt, 498 td->qh->fixup_phys, rem, &octusb_complete_cb, td); 499 break; 500 case UE_BULK: 501 /* start USB transfer */ 502 status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->root_port_index].state, 503 td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td); 504 break; 505 case UE_INTERRUPT: 506 /* start USB transfer (interrupt or interrupt) */ 507 status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->root_port_index].state, 508 td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td); 509 break; 510 default: 511 status = -1; 512 break; 513 } 514 515 /* check status */ 516 if (status < 0) { 517 td->error_any = 1; 518 return (0); /* done */ 519 } 520 td->qh->fixup_handle = status; 521 td->qh->fixup_len = rem; 522 td->qh->fixup_pending = 1; 523 td->qh->fixup_complete = 0; 524 525 return (1); /* busy */ 526} 527 528static uint8_t 529octusb_non_control_data_rx(struct octusb_td *td) 530{ 531 struct octusb_softc *sc; 532 uint32_t rem; 533 int status; 534 uint8_t got_short; 535 536 /* allocate endpoint and check pending */ 537 if (octusb_host_alloc_endpoint(td)) 538 return (1); /* busy */ 539 540 /* check error */ 541 if (td->error_any) 542 return (0); /* done */ 543 544 got_short = 0; 545 546 if (td->qh->fixup_complete != 0) { 547 548 /* invalidate data */ 549 usb_pc_cpu_invalidate(td->qh->fixup_pc); 550 551 rem = td->qh->fixup_actlen; 552 553 /* verify transfer length */ 554 if (rem != td->qh->fixup_len) { 555 if (rem < td->qh->fixup_len) { 556 /* we have a short packet */ 557 td->short_pkt = 1; 558 got_short = 1; 559 } else { 560 /* invalid USB packet */ 561 td->error_any = 1; 562 return (0); /* we are complete */ 563 } 564 } 565 /* copy data into fixup buffer */ 566 usbd_copy_in(td->pc, td->offset, td->qh->fixup_buf, rem); 567 568 /* post-increment RX buffer offset */ 569 td->offset += rem; 570 td->remainder -= rem; 571 572 td->qh->fixup_complete = 0; 573 574 if ((td->qh->ep_type & UE_XFERTYPE) == UE_ISOCHRONOUS) 575 return (0); /* done */ 576 } 577 /* check if we are complete */ 578 if ((td->remainder == 0) || got_short) { 579 if (td->short_pkt) { 580 /* we are complete */ 581 return (0); 582 } 583 /* else need to receive a zero length packet */ 584 rem = 0; 585 td->short_pkt = 1; 586 } else { 587 /* get maximum length */ 588 rem = OCTUSB_MAX_FIXUP % td->qh->max_frame_size; 589 rem = OCTUSB_MAX_FIXUP - rem; 590 591 if (rem == 0) { 592 /* should not happen */ 593 DPRINTFN(1, "Fixup buffer is too small\n"); 594 td->error_any = 1; 595 return (0); /* done */ 596 } 597 /* get minimum length */ 598 if (rem > td->remainder) 599 rem = td->remainder; 600 } 601 602 /* invalidate data */ 603 usb_pc_cpu_invalidate(td->qh->fixup_pc); 604 605 /* get softc */ 606 sc = td->qh->sc; 607 608 switch (td->qh->ep_type & UE_XFERTYPE) { 609 case UE_ISOCHRONOUS: 610 td->qh->iso_pkt.offset = 0; 611 td->qh->iso_pkt.length = rem; 612 td->qh->iso_pkt.status = 0; 613 /* start USB transfer */ 614 status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->root_port_index].state, 615 td->qh->ep_handle, 1, CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT | 616 CVMX_USB_ISOCHRONOUS_FLAGS_ASAP, 1, &td->qh->iso_pkt, 617 td->qh->fixup_phys, rem, &octusb_complete_cb, td); 618 break; 619 case UE_BULK: 620 /* start USB transfer */ 621 status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->root_port_index].state, 622 td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td); 623 break; 624 case UE_INTERRUPT: 625 /* start USB transfer */ 626 status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->root_port_index].state, 627 td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td); 628 break; 629 default: 630 status = -1; 631 break; 632 } 633 634 /* check status */ 635 if (status < 0) { 636 td->error_any = 1; 637 return (0); /* done */ 638 } 639 td->qh->fixup_handle = status; 640 td->qh->fixup_len = rem; 641 td->qh->fixup_pending = 1; 642 td->qh->fixup_complete = 0; 643 644 return (1); /* busy */ 645} 646 647static uint8_t 648octusb_xfer_do_fifo(struct usb_xfer *xfer) 649{ 650 struct octusb_td *td; 651 652 DPRINTFN(8, "\n"); 653 654 td = xfer->td_transfer_cache; 655 656 while (1) { 657 if ((td->func) (td)) { 658 /* operation in progress */ 659 break; 660 } 661 if (((void *)td) == xfer->td_transfer_last) { 662 goto done; 663 } 664 if (td->error_any) { 665 goto done; 666 } else if (td->remainder > 0) { 667 /* 668 * We had a short transfer. If there is no 669 * alternate next, stop processing ! 670 */ 671 if (td->alt_next == 0) 672 goto done; 673 } 674 /* 675 * Fetch the next transfer descriptor and transfer 676 * some flags to the next transfer descriptor 677 */ 678 td = td->obj_next; 679 xfer->td_transfer_cache = td; 680 } 681 return (1); /* not complete */ 682 683done: 684 /* compute all actual lengths */ 685 686 octusb_standard_done(xfer); 687 688 return (0); /* complete */ 689} 690 691static usb_error_t 692octusb_standard_done_sub(struct usb_xfer *xfer) 693{ 694 struct octusb_td *td; 695 uint32_t len; 696 usb_error_t error; 697 698 DPRINTFN(8, "\n"); 699 700 td = xfer->td_transfer_cache; 701 702 do { 703 len = td->remainder; 704 705 if (xfer->aframes != xfer->nframes) { 706 /* 707 * Verify the length and subtract 708 * the remainder from "frlengths[]": 709 */ 710 if (len > xfer->frlengths[xfer->aframes]) { 711 td->error_any = 1; 712 } else { 713 xfer->frlengths[xfer->aframes] -= len; 714 } 715 } 716 /* Check for transfer error */ 717 if (td->error_any) { 718 /* the transfer is finished */ 719 error = td->error_stall ? USB_ERR_STALLED : USB_ERR_IOERROR; 720 td = NULL; 721 break; 722 } 723 /* Check for short transfer */ 724 if (len > 0) { 725 if (xfer->flags_int.short_frames_ok) { 726 /* follow alt next */ 727 if (td->alt_next) { 728 td = td->obj_next; 729 } else { 730 td = NULL; 731 } 732 } else { 733 /* the transfer is finished */ 734 td = NULL; 735 } 736 error = 0; 737 break; 738 } 739 td = td->obj_next; 740 741 /* this USB frame is complete */ 742 error = 0; 743 break; 744 745 } while (0); 746 747 /* update transfer cache */ 748 749 xfer->td_transfer_cache = td; 750 751 return (error); 752} 753 754static void 755octusb_standard_done(struct usb_xfer *xfer) 756{ 757 struct octusb_softc *sc; 758 struct octusb_qh *qh; 759 usb_error_t error = 0; 760 761 DPRINTFN(12, "xfer=%p endpoint=%p transfer done\n", 762 xfer, xfer->endpoint); 763 764 /* reset scanner */ 765 766 xfer->td_transfer_cache = xfer->td_transfer_first; 767 768 if (xfer->flags_int.control_xfr) { 769 770 if (xfer->flags_int.control_hdr) 771 error = octusb_standard_done_sub(xfer); 772 773 xfer->aframes = 1; 774 775 if (xfer->td_transfer_cache == NULL) 776 goto done; 777 } 778 while (xfer->aframes != xfer->nframes) { 779 780 error = octusb_standard_done_sub(xfer); 781 782 xfer->aframes++; 783 784 if (xfer->td_transfer_cache == NULL) 785 goto done; 786 } 787 788 if (xfer->flags_int.control_xfr && 789 !xfer->flags_int.control_act) 790 error = octusb_standard_done_sub(xfer); 791 792done: 793 /* update data toggle */ 794 795 qh = xfer->qh_start[0]; 796 sc = qh->sc; 797 798 xfer->endpoint->toggle_next = 799 cvmx_usb_get_toggle( 800 &sc->sc_port[qh->root_port_index].state, 801 qh->ep_handle) ? 1 : 0; 802 803 octusb_device_done(xfer, error); 804} 805 806static void 807octusb_interrupt_poll(struct octusb_softc *sc) 808{ 809 struct usb_xfer *xfer; 810 uint8_t x; 811 812 /* poll all ports */ 813 for (x = 0; x != sc->sc_noport; x++) 814 cvmx_usb_poll(&sc->sc_port[x].state); 815 816repeat: 817 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { 818 if (!octusb_xfer_do_fifo(xfer)) { 819 /* queue has been modified */ 820 goto repeat; 821 } 822 } 823} 824 825static void 826octusb_start_standard_chain(struct usb_xfer *xfer) 827{ 828 DPRINTFN(8, "\n"); 829 830 /* poll one time */ 831 if (octusb_xfer_do_fifo(xfer)) { 832 833 /* put transfer on interrupt queue */ 834 usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer); 835 836 /* start timeout, if any */ 837 if (xfer->timeout != 0) { 838 usbd_transfer_timeout_ms(xfer, 839 &octusb_timeout, xfer->timeout); 840 } 841 } 842} 843 844void 845octusb_iterate_hw_softc(struct usb_bus *bus, usb_bus_mem_sub_cb_t *cb) 846{ 847 848} 849 850usb_error_t 851octusb_init(struct octusb_softc *sc) 852{ 853 cvmx_usb_initialize_flags_t flags; 854 int status; 855 uint8_t x; 856 857 /* flush all cache into memory */ 858 859 usb_bus_mem_flush_all(&sc->sc_bus, &octusb_iterate_hw_softc); 860 861 /* set up the bus struct */ 862 sc->sc_bus.methods = &octusb_bus_methods; 863 864 /* get number of ports */ 865 sc->sc_noport = cvmx_usb_get_num_ports(); 866 867 /* check number of ports */ 868 if (sc->sc_noport > OCTUSB_MAX_PORTS) 869 sc->sc_noport = OCTUSB_MAX_PORTS; 870 871 /* set USB revision */ 872 sc->sc_bus.usbrev = USB_REV_2_0; 873 874 /* flags for port initialization */ 875 flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO; 876#ifdef USB_DEBUG 877 if (octusbdebug > 100) 878 flags |= CVMX_USB_INITIALIZE_FLAGS_DEBUG_ALL; 879#endif 880 881 USB_BUS_LOCK(&sc->sc_bus); 882 883 /* setup all ports */ 884 for (x = 0; x != sc->sc_noport; x++) { 885 status = cvmx_usb_initialize(&sc->sc_port[x].state, x, flags); 886 if (status < 0) 887 sc->sc_port[x].disabled = 1; 888 } 889 890 USB_BUS_UNLOCK(&sc->sc_bus); 891 892 /* catch lost interrupts */ 893 octusb_do_poll(&sc->sc_bus); 894 895 return (0); 896} 897 898usb_error_t 899octusb_uninit(struct octusb_softc *sc) 900{ 901 uint8_t x; 902 903 USB_BUS_LOCK(&sc->sc_bus); 904 905 for (x = 0; x != sc->sc_noport; x++) { 906 if (sc->sc_port[x].disabled == 0) 907 cvmx_usb_shutdown(&sc->sc_port[x].state); 908 } 909 USB_BUS_UNLOCK(&sc->sc_bus); 910 911 return (0); 912 913} 914 915static void 916octusb_suspend(struct octusb_softc *sc) 917{ 918 /* TODO */ 919} 920 921static void 922octusb_resume(struct octusb_softc *sc) 923{ 924 /* TODO */ 925} 926 927/*------------------------------------------------------------------------* 928 * octusb_interrupt - OCTUSB interrupt handler 929 *------------------------------------------------------------------------*/ 930void 931octusb_interrupt(struct octusb_softc *sc) 932{ 933 USB_BUS_LOCK(&sc->sc_bus); 934 935 DPRINTFN(16, "real interrupt\n"); 936 937 /* poll all the USB transfers */ 938 octusb_interrupt_poll(sc); 939 940 USB_BUS_UNLOCK(&sc->sc_bus); 941} 942 943/*------------------------------------------------------------------------* 944 * octusb_timeout - OCTUSB transfer timeout handler 945 *------------------------------------------------------------------------*/ 946static void 947octusb_timeout(void *arg) 948{ 949 struct usb_xfer *xfer = arg; 950 951 DPRINTF("xfer=%p\n", xfer); 952 953 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED); 954 955 /* transfer is transferred */ 956 octusb_device_done(xfer, USB_ERR_TIMEOUT); 957} 958 959/*------------------------------------------------------------------------* 960 * octusb_do_poll - OCTUSB poll transfers 961 *------------------------------------------------------------------------*/ 962static void 963octusb_do_poll(struct usb_bus *bus) 964{ 965 struct octusb_softc *sc = OCTUSB_BUS2SC(bus); 966 967 USB_BUS_LOCK(&sc->sc_bus); 968 octusb_interrupt_poll(sc); 969 USB_BUS_UNLOCK(&sc->sc_bus); 970} 971 972static void 973octusb_setup_standard_chain_sub(struct octusb_std_temp *temp) 974{ 975 struct octusb_td *td; 976 977 /* get current Transfer Descriptor */ 978 td = temp->td_next; 979 temp->td = td; 980 981 /* prepare for next TD */ 982 temp->td_next = td->obj_next; 983 984 /* fill out the Transfer Descriptor */ 985 td->func = temp->func; 986 td->pc = temp->pc; 987 td->offset = temp->offset; 988 td->remainder = temp->len; 989 td->error_any = 0; 990 td->error_stall = 0; 991 td->short_pkt = temp->short_pkt; 992 td->alt_next = temp->setup_alt_next; 993} 994 995static void 996octusb_setup_standard_chain(struct usb_xfer *xfer) 997{ 998 struct octusb_std_temp temp; 999 struct octusb_td *td; 1000 uint32_t x; 1001 1002 DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n", 1003 xfer->address, UE_GET_ADDR(xfer->endpointno), 1004 xfer->sumlen, usbd_get_speed(xfer->xroot->udev)); 1005 1006 /* setup starting point */ 1007 td = xfer->td_start[0]; 1008 xfer->td_transfer_first = td; 1009 xfer->td_transfer_cache = td; 1010 1011 temp.td = NULL; 1012 temp.td_next = td; 1013 temp.setup_alt_next = xfer->flags_int.short_frames_ok; 1014 temp.offset = 0; 1015 1016 /* check if we should prepend a setup message */ 1017 1018 if (xfer->flags_int.control_xfr) { 1019 1020 if (xfer->flags_int.control_hdr) { 1021 1022 temp.func = &octusb_host_control_header_tx; 1023 temp.len = xfer->frlengths[0]; 1024 temp.pc = xfer->frbuffers + 0; 1025 temp.short_pkt = temp.len ? 1 : 0; 1026 1027 /* check for last frame */ 1028 if (xfer->nframes == 1) { 1029 /* 1030 * no STATUS stage yet, SETUP is 1031 * last 1032 */ 1033 if (xfer->flags_int.control_act) 1034 temp.setup_alt_next = 0; 1035 } 1036 octusb_setup_standard_chain_sub(&temp); 1037 } 1038 x = 1; 1039 } else { 1040 x = 0; 1041 } 1042 1043 if (x != xfer->nframes) { 1044 if (xfer->endpointno & UE_DIR_IN) { 1045 if (xfer->flags_int.control_xfr) 1046 temp.func = &octusb_host_control_data_rx; 1047 else 1048 temp.func = &octusb_non_control_data_rx; 1049 } else { 1050 if (xfer->flags_int.control_xfr) 1051 temp.func = &octusb_host_control_data_tx; 1052 else 1053 temp.func = &octusb_non_control_data_tx; 1054 } 1055 1056 /* setup "pc" pointer */ 1057 temp.pc = xfer->frbuffers + x; 1058 } 1059 while (x != xfer->nframes) { 1060 1061 /* DATA0 or DATA1 message */ 1062 1063 temp.len = xfer->frlengths[x]; 1064 1065 x++; 1066 1067 if (x == xfer->nframes) { 1068 if (xfer->flags_int.control_xfr) { 1069 /* no STATUS stage yet, DATA is last */ 1070 if (xfer->flags_int.control_act) 1071 temp.setup_alt_next = 0; 1072 } else { 1073 temp.setup_alt_next = 0; 1074 } 1075 } 1076 if (temp.len == 0) { 1077 1078 /* make sure that we send an USB packet */ 1079 1080 temp.short_pkt = 0; 1081 1082 } else { 1083 1084 /* regular data transfer */ 1085 1086 temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1; 1087 } 1088 1089 octusb_setup_standard_chain_sub(&temp); 1090 1091 if (xfer->flags_int.isochronous_xfr) { 1092 /* get next data offset */ 1093 temp.offset += temp.len; 1094 } else { 1095 /* get next Page Cache pointer */ 1096 temp.pc = xfer->frbuffers + x; 1097 } 1098 } 1099 1100 /* check if we should append a status stage */ 1101 1102 if (xfer->flags_int.control_xfr && 1103 !xfer->flags_int.control_act) { 1104 1105 temp.func = &octusb_host_control_status_tx; 1106 temp.len = 0; 1107 temp.pc = NULL; 1108 temp.short_pkt = 0; 1109 temp.setup_alt_next = 0; 1110 1111 octusb_setup_standard_chain_sub(&temp); 1112 } 1113 /* must have at least one frame! */ 1114 td = temp.td; 1115 xfer->td_transfer_last = td; 1116 1117 /* properly setup QH */ 1118 1119 td->qh->ep_allocated = 0; 1120 td->qh->ep_toggle_next = xfer->endpoint->toggle_next ? 1 : 0; 1121} 1122 1123/*------------------------------------------------------------------------* 1124 * octusb_device_done - OCTUSB transfers done code 1125 * 1126 * NOTE: This function can be called more than one time in a row. 1127 *------------------------------------------------------------------------*/ 1128static void 1129octusb_device_done(struct usb_xfer *xfer, usb_error_t error) 1130{ 1131 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED); 1132 1133 DPRINTFN(2, "xfer=%p, endpoint=%p, error=%d\n", 1134 xfer, xfer->endpoint, error); 1135 1136 /* 1137 * 1) Free any endpoints. 1138 * 2) Control transfers can be split and we should not re-open 1139 * the data pipe between transactions unless there is an error. 1140 */ 1141 if ((xfer->flags_int.control_act == 0) || (error != 0)) { 1142 struct octusb_td *td; 1143 1144 td = xfer->td_start[0]; 1145 1146 octusb_host_free_endpoint(td); 1147 } 1148 /* dequeue transfer and start next transfer */ 1149 usbd_transfer_done(xfer, error); 1150} 1151 1152/*------------------------------------------------------------------------* 1153 * octusb bulk support 1154 *------------------------------------------------------------------------*/ 1155static void 1156octusb_device_bulk_open(struct usb_xfer *xfer) 1157{ 1158 return; 1159} 1160 1161static void 1162octusb_device_bulk_close(struct usb_xfer *xfer) 1163{ 1164 octusb_device_done(xfer, USB_ERR_CANCELLED); 1165} 1166 1167static void 1168octusb_device_bulk_enter(struct usb_xfer *xfer) 1169{ 1170 return; 1171} 1172 1173static void 1174octusb_device_bulk_start(struct usb_xfer *xfer) 1175{ 1176 /* setup TDs */ 1177 octusb_setup_standard_chain(xfer); 1178 octusb_start_standard_chain(xfer); 1179} 1180 1181struct usb_pipe_methods octusb_device_bulk_methods = 1182{ 1183 .open = octusb_device_bulk_open, 1184 .close = octusb_device_bulk_close, 1185 .enter = octusb_device_bulk_enter, 1186 .start = octusb_device_bulk_start, 1187}; 1188 1189/*------------------------------------------------------------------------* 1190 * octusb control support 1191 *------------------------------------------------------------------------*/ 1192static void 1193octusb_device_ctrl_open(struct usb_xfer *xfer) 1194{ 1195 return; 1196} 1197 1198static void 1199octusb_device_ctrl_close(struct usb_xfer *xfer) 1200{ 1201 octusb_device_done(xfer, USB_ERR_CANCELLED); 1202} 1203 1204static void 1205octusb_device_ctrl_enter(struct usb_xfer *xfer) 1206{ 1207 return; 1208} 1209 1210static void 1211octusb_device_ctrl_start(struct usb_xfer *xfer) 1212{ 1213 /* setup TDs */ 1214 octusb_setup_standard_chain(xfer); 1215 octusb_start_standard_chain(xfer); 1216} 1217 1218struct usb_pipe_methods octusb_device_ctrl_methods = 1219{ 1220 .open = octusb_device_ctrl_open, 1221 .close = octusb_device_ctrl_close, 1222 .enter = octusb_device_ctrl_enter, 1223 .start = octusb_device_ctrl_start, 1224}; 1225 1226/*------------------------------------------------------------------------* 1227 * octusb interrupt support 1228 *------------------------------------------------------------------------*/ 1229static void 1230octusb_device_intr_open(struct usb_xfer *xfer) 1231{ 1232 return; 1233} 1234 1235static void 1236octusb_device_intr_close(struct usb_xfer *xfer) 1237{ 1238 octusb_device_done(xfer, USB_ERR_CANCELLED); 1239} 1240 1241static void 1242octusb_device_intr_enter(struct usb_xfer *xfer) 1243{ 1244 return; 1245} 1246 1247static void 1248octusb_device_intr_start(struct usb_xfer *xfer) 1249{ 1250 /* setup TDs */ 1251 octusb_setup_standard_chain(xfer); 1252 octusb_start_standard_chain(xfer); 1253} 1254 1255struct usb_pipe_methods octusb_device_intr_methods = 1256{ 1257 .open = octusb_device_intr_open, 1258 .close = octusb_device_intr_close, 1259 .enter = octusb_device_intr_enter, 1260 .start = octusb_device_intr_start, 1261}; 1262 1263/*------------------------------------------------------------------------* 1264 * octusb isochronous support 1265 *------------------------------------------------------------------------*/ 1266static void 1267octusb_device_isoc_open(struct usb_xfer *xfer) 1268{ 1269 return; 1270} 1271 1272static void 1273octusb_device_isoc_close(struct usb_xfer *xfer) 1274{ 1275 octusb_device_done(xfer, USB_ERR_CANCELLED); 1276} 1277 1278static void 1279octusb_device_isoc_enter(struct usb_xfer *xfer) 1280{ 1281 struct octusb_softc *sc = OCTUSB_BUS2SC(xfer->xroot->bus); 1282 uint32_t temp; 1283 uint32_t frame_count; 1284 uint32_t fs_frames; 1285 1286 DPRINTFN(5, "xfer=%p next=%d nframes=%d\n", 1287 xfer, xfer->endpoint->isoc_next, xfer->nframes); 1288 1289 /* get the current frame index */ 1290 1291 frame_count = cvmx_usb_get_frame_number( 1292 &sc->sc_port[xfer->xroot->udev->port_index].state); 1293 1294 /* 1295 * check if the frame index is within the window where the frames 1296 * will be inserted 1297 */ 1298 temp = (frame_count - xfer->endpoint->isoc_next) & 0x7FF; 1299 1300 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) { 1301 fs_frames = (xfer->nframes + 7) / 8; 1302 } else { 1303 fs_frames = xfer->nframes; 1304 } 1305 1306 if ((xfer->endpoint->is_synced == 0) || (temp < fs_frames)) { 1307 /* 1308 * If there is data underflow or the pipe queue is 1309 * empty we schedule the transfer a few frames ahead 1310 * of the current frame position. Else two isochronous 1311 * transfers might overlap. 1312 */ 1313 xfer->endpoint->isoc_next = (frame_count + 3) & 0x7FF; 1314 xfer->endpoint->is_synced = 1; 1315 DPRINTFN(2, "start next=%d\n", xfer->endpoint->isoc_next); 1316 } 1317 /* 1318 * compute how many milliseconds the insertion is ahead of the 1319 * current frame position: 1320 */ 1321 temp = (xfer->endpoint->isoc_next - frame_count) & 0x7FF; 1322 1323 /* 1324 * pre-compute when the isochronous transfer will be finished: 1325 */ 1326 xfer->isoc_time_complete = 1327 usb_isoc_time_expand(&sc->sc_bus, frame_count) + temp + 1328 fs_frames; 1329 1330 /* compute frame number for next insertion */ 1331 xfer->endpoint->isoc_next += fs_frames; 1332} 1333 1334static void 1335octusb_device_isoc_start(struct usb_xfer *xfer) 1336{ 1337 /* setup TDs */ 1338 octusb_setup_standard_chain(xfer); 1339 octusb_start_standard_chain(xfer); 1340} 1341 1342struct usb_pipe_methods octusb_device_isoc_methods = 1343{ 1344 .open = octusb_device_isoc_open, 1345 .close = octusb_device_isoc_close, 1346 .enter = octusb_device_isoc_enter, 1347 .start = octusb_device_isoc_start, 1348}; 1349 1350/*------------------------------------------------------------------------* 1351 * OCTUSB root HUB support 1352 *------------------------------------------------------------------------* 1353 * Simulate a hardware HUB by handling all the necessary requests. 1354 *------------------------------------------------------------------------*/ 1355static const 1356struct usb_device_descriptor octusb_devd = { 1357 .bLength = sizeof(octusb_devd), 1358 .bDescriptorType = UDESC_DEVICE, 1359 .bcdUSB = {0x00, 0x02}, 1360 .bDeviceClass = UDCLASS_HUB, 1361 .bDeviceSubClass = UDSUBCLASS_HUB, 1362 .bDeviceProtocol = UDPROTO_FSHUB, 1363 .bMaxPacketSize = 64, 1364 .idVendor = {0}, 1365 .idProduct = {0}, 1366 .bcdDevice = {0x00, 0x01}, 1367 .iManufacturer = 1, 1368 .iProduct = 2, 1369 .iSerialNumber = 0, 1370 .bNumConfigurations = 1, 1371}; 1372 1373static const 1374struct usb_device_qualifier octusb_odevd = { 1375 .bLength = sizeof(octusb_odevd), 1376 .bDescriptorType = UDESC_DEVICE_QUALIFIER, 1377 .bcdUSB = {0x00, 0x02}, 1378 .bDeviceClass = UDCLASS_HUB, 1379 .bDeviceSubClass = UDSUBCLASS_HUB, 1380 .bDeviceProtocol = UDPROTO_FSHUB, 1381 .bMaxPacketSize0 = 0, 1382 .bNumConfigurations = 0, 1383 .bReserved = 0, 1384}; 1385 1386static const 1387struct octusb_config_desc octusb_confd = { 1388 .confd = { 1389 .bLength = sizeof(struct usb_config_descriptor), 1390 .bDescriptorType = UDESC_CONFIG, 1391 .wTotalLength[0] = sizeof(octusb_confd), 1392 .bNumInterface = 1, 1393 .bConfigurationValue = 1, 1394 .iConfiguration = 0, 1395 .bmAttributes = UC_SELF_POWERED, 1396 .bMaxPower = 0 /* max power */ 1397 }, 1398 .ifcd = { 1399 .bLength = sizeof(struct usb_interface_descriptor), 1400 .bDescriptorType = UDESC_INTERFACE, 1401 .bNumEndpoints = 1, 1402 .bInterfaceClass = UICLASS_HUB, 1403 .bInterfaceSubClass = UISUBCLASS_HUB, 1404 .bInterfaceProtocol = UIPROTO_FSHUB, 1405 }, 1406 .endpd = { 1407 .bLength = sizeof(struct usb_endpoint_descriptor), 1408 .bDescriptorType = UDESC_ENDPOINT, 1409 .bEndpointAddress = UE_DIR_IN | OCTUSB_INTR_ENDPT, 1410 .bmAttributes = UE_INTERRUPT, 1411 .wMaxPacketSize[0] = 8, /* max packet (63 ports) */ 1412 .bInterval = 255, 1413 }, 1414}; 1415 1416static const 1417struct usb_hub_descriptor_min octusb_hubd = 1418{ 1419 .bDescLength = sizeof(octusb_hubd), 1420 .bDescriptorType = UDESC_HUB, 1421 .bNbrPorts = 2, 1422 .wHubCharacteristics = {UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0}, 1423 .bPwrOn2PwrGood = 50, 1424 .bHubContrCurrent = 0, 1425 .DeviceRemovable = {0x00}, /* all ports are removable */ 1426}; 1427 1428static usb_error_t 1429octusb_roothub_exec(struct usb_device *udev, 1430 struct usb_device_request *req, const void **pptr, uint16_t *plength) 1431{ 1432 struct octusb_softc *sc = OCTUSB_BUS2SC(udev->bus); 1433 const void *ptr; 1434 const char *str_ptr; 1435 uint16_t value; 1436 uint16_t index; 1437 uint16_t status; 1438 uint16_t change; 1439 uint16_t len; 1440 usb_error_t err; 1441 cvmx_usb_port_status_t usb_port_status; 1442 1443 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); 1444 1445 /* XXX disable power save mode, hence it is not supported */ 1446 udev->power_mode = USB_POWER_MODE_ON; 1447 1448 /* buffer reset */ 1449 ptr = (const void *)&sc->sc_hub_desc.temp; 1450 len = 0; 1451 err = 0; 1452 1453 value = UGETW(req->wValue); 1454 index = UGETW(req->wIndex); 1455 1456 DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x " 1457 "wValue=0x%04x wIndex=0x%04x\n", 1458 req->bmRequestType, req->bRequest, 1459 UGETW(req->wLength), value, index); 1460 1461#define C(x,y) ((x) | ((y) << 8)) 1462 switch (C(req->bRequest, req->bmRequestType)) { 1463 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): 1464 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): 1465 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): 1466 break; 1467 case C(UR_GET_CONFIG, UT_READ_DEVICE): 1468 len = 1; 1469 sc->sc_hub_desc.temp[0] = sc->sc_conf; 1470 break; 1471 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 1472 switch (value >> 8) { 1473 case UDESC_DEVICE: 1474 if ((value & 0xff) != 0) { 1475 err = USB_ERR_IOERROR; 1476 goto done; 1477 } 1478 len = sizeof(octusb_devd); 1479 1480 ptr = (const void *)&octusb_devd; 1481 break; 1482 1483 case UDESC_DEVICE_QUALIFIER: 1484 if ((value & 0xff) != 0) { 1485 err = USB_ERR_IOERROR; 1486 goto done; 1487 } 1488 len = sizeof(octusb_odevd); 1489 ptr = (const void *)&octusb_odevd; 1490 break; 1491 1492 case UDESC_CONFIG: 1493 if ((value & 0xff) != 0) { 1494 err = USB_ERR_IOERROR; 1495 goto done; 1496 } 1497 len = sizeof(octusb_confd); 1498 ptr = (const void *)&octusb_confd; 1499 break; 1500 1501 case UDESC_STRING: 1502 switch (value & 0xff) { 1503 case 0: /* Language table */ 1504 str_ptr = "\001"; 1505 break; 1506 1507 case 1: /* Vendor */ 1508 str_ptr = "Cavium Networks"; 1509 break; 1510 1511 case 2: /* Product */ 1512 str_ptr = "OCTUSB Root HUB"; 1513 break; 1514 1515 default: 1516 str_ptr = ""; 1517 break; 1518 } 1519 1520 len = usb_make_str_desc(sc->sc_hub_desc.temp, 1521 sizeof(sc->sc_hub_desc.temp), str_ptr); 1522 break; 1523 1524 default: 1525 err = USB_ERR_IOERROR; 1526 goto done; 1527 } 1528 break; 1529 case C(UR_GET_INTERFACE, UT_READ_INTERFACE): 1530 len = 1; 1531 sc->sc_hub_desc.temp[0] = 0; 1532 break; 1533 case C(UR_GET_STATUS, UT_READ_DEVICE): 1534 len = 2; 1535 USETW(sc->sc_hub_desc.stat.wStatus, UDS_SELF_POWERED); 1536 break; 1537 case C(UR_GET_STATUS, UT_READ_INTERFACE): 1538 case C(UR_GET_STATUS, UT_READ_ENDPOINT): 1539 len = 2; 1540 USETW(sc->sc_hub_desc.stat.wStatus, 0); 1541 break; 1542 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): 1543 if (value >= OCTUSB_MAX_DEVICES) { 1544 err = USB_ERR_IOERROR; 1545 goto done; 1546 } 1547 sc->sc_addr = value; 1548 break; 1549 case C(UR_SET_CONFIG, UT_WRITE_DEVICE): 1550 if ((value != 0) && (value != 1)) { 1551 err = USB_ERR_IOERROR; 1552 goto done; 1553 } 1554 sc->sc_conf = value; 1555 break; 1556 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): 1557 break; 1558 case C(UR_SET_FEATURE, UT_WRITE_DEVICE): 1559 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE): 1560 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT): 1561 err = USB_ERR_IOERROR; 1562 goto done; 1563 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): 1564 break; 1565 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): 1566 break; 1567 /* Hub requests */ 1568 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): 1569 break; 1570 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): 1571 DPRINTFN(4, "UR_CLEAR_PORT_FEATURE " 1572 "port=%d feature=%d\n", 1573 index, value); 1574 if ((index < 1) || 1575 (index > sc->sc_noport) || 1576 sc->sc_port[index - 1].disabled) { 1577 err = USB_ERR_IOERROR; 1578 goto done; 1579 } 1580 index--; 1581 1582 switch (value) { 1583 case UHF_PORT_ENABLE: 1584 cvmx_usb_disable(&sc->sc_port[index].state); 1585 break; 1586 case UHF_PORT_SUSPEND: 1587 case UHF_PORT_RESET: 1588 break; 1589 case UHF_C_PORT_CONNECTION: 1590 cvmx_usb_set_status(&sc->sc_port[index].state, 1591 cvmx_usb_get_status(&sc->sc_port[index].state)); 1592 break; 1593 case UHF_C_PORT_ENABLE: 1594 cvmx_usb_set_status(&sc->sc_port[index].state, 1595 cvmx_usb_get_status(&sc->sc_port[index].state)); 1596 break; 1597 case UHF_C_PORT_OVER_CURRENT: 1598 cvmx_usb_set_status(&sc->sc_port[index].state, 1599 cvmx_usb_get_status(&sc->sc_port[index].state)); 1600 break; 1601 case UHF_C_PORT_RESET: 1602 sc->sc_isreset = 0; 1603 goto done; 1604 case UHF_C_PORT_SUSPEND: 1605 break; 1606 case UHF_PORT_CONNECTION: 1607 case UHF_PORT_OVER_CURRENT: 1608 case UHF_PORT_POWER: 1609 case UHF_PORT_LOW_SPEED: 1610 default: 1611 err = USB_ERR_IOERROR; 1612 goto done; 1613 } 1614 break; 1615 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): 1616 if ((value & 0xff) != 0) { 1617 err = USB_ERR_IOERROR; 1618 goto done; 1619 } 1620 sc->sc_hubd = octusb_hubd; 1621 sc->sc_hubd.bNbrPorts = sc->sc_noport; 1622 len = sizeof(sc->sc_hubd); 1623 ptr = (const void *)&sc->sc_hubd; 1624 break; 1625 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): 1626 len = 16; 1627 memset(sc->sc_hub_desc.temp, 0, 16); 1628 break; 1629 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): 1630 if ((index < 1) || 1631 (index > sc->sc_noport) || 1632 sc->sc_port[index - 1].disabled) { 1633 err = USB_ERR_IOERROR; 1634 goto done; 1635 } 1636 index--; 1637 1638 usb_port_status = cvmx_usb_get_status(&sc->sc_port[index].state); 1639 1640 status = change = 0; 1641 if (usb_port_status.connected) 1642 status |= UPS_CURRENT_CONNECT_STATUS; 1643 if (usb_port_status.port_enabled) 1644 status |= UPS_PORT_ENABLED; 1645 if (usb_port_status.port_over_current) 1646 status |= UPS_OVERCURRENT_INDICATOR; 1647 if (usb_port_status.port_powered) 1648 status |= UPS_PORT_POWER; 1649 1650 switch (usb_port_status.port_speed) { 1651 case CVMX_USB_SPEED_HIGH: 1652 status |= UPS_HIGH_SPEED; 1653 break; 1654 case CVMX_USB_SPEED_FULL: 1655 break; 1656 default: 1657 status |= UPS_LOW_SPEED; 1658 break; 1659 } 1660 1661 if (usb_port_status.connect_change) 1662 change |= UPS_C_CONNECT_STATUS; 1663 if (sc->sc_isreset) 1664 change |= UPS_C_PORT_RESET; 1665 1666 USETW(sc->sc_hub_desc.ps.wPortStatus, status); 1667 USETW(sc->sc_hub_desc.ps.wPortChange, change); 1668 1669 len = sizeof(sc->sc_hub_desc.ps); 1670 break; 1671 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): 1672 err = USB_ERR_IOERROR; 1673 goto done; 1674 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE): 1675 break; 1676 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): 1677 if ((index < 1) || 1678 (index > sc->sc_noport) || 1679 sc->sc_port[index - 1].disabled) { 1680 err = USB_ERR_IOERROR; 1681 goto done; 1682 } 1683 index--; 1684 1685 switch (value) { 1686 case UHF_PORT_ENABLE: 1687 break; 1688 case UHF_PORT_RESET: 1689 cvmx_usb_disable(&sc->sc_port[index].state); 1690 if (cvmx_usb_enable(&sc->sc_port[index].state)) { 1691 err = USB_ERR_IOERROR; 1692 goto done; 1693 } 1694 sc->sc_isreset = 1; 1695 goto done; 1696 case UHF_PORT_POWER: 1697 /* pretend we turned on power */ 1698 goto done; 1699 case UHF_PORT_SUSPEND: 1700 case UHF_C_PORT_CONNECTION: 1701 case UHF_C_PORT_ENABLE: 1702 case UHF_C_PORT_OVER_CURRENT: 1703 case UHF_PORT_CONNECTION: 1704 case UHF_PORT_OVER_CURRENT: 1705 case UHF_PORT_LOW_SPEED: 1706 case UHF_C_PORT_SUSPEND: 1707 case UHF_C_PORT_RESET: 1708 default: 1709 err = USB_ERR_IOERROR; 1710 goto done; 1711 } 1712 break; 1713 default: 1714 err = USB_ERR_IOERROR; 1715 goto done; 1716 } 1717done: 1718 *plength = len; 1719 *pptr = ptr; 1720 return (err); 1721} 1722 1723static void 1724octusb_xfer_setup(struct usb_setup_params *parm) 1725{ 1726 struct usb_page_search page_info; 1727 struct usb_page_cache *pc; 1728 struct octusb_softc *sc; 1729 struct octusb_qh *qh; 1730 struct usb_xfer *xfer; 1731 struct usb_device *hub; 1732 void *last_obj; 1733 uint32_t n; 1734 uint32_t ntd; 1735 1736 sc = OCTUSB_BUS2SC(parm->udev->bus); 1737 xfer = parm->curr_xfer; 1738 qh = NULL; 1739 1740 /* 1741 * NOTE: This driver does not use any of the parameters that 1742 * are computed from the following values. Just set some 1743 * reasonable dummies: 1744 */ 1745 1746 parm->hc_max_packet_size = 0x400; 1747 parm->hc_max_packet_count = 3; 1748 parm->hc_max_frame_size = 0xC00; 1749 1750 usbd_transfer_setup_sub(parm); 1751 1752 if (parm->err) 1753 return; 1754 1755 /* Allocate a queue head */ 1756 1757 if (usbd_transfer_setup_sub_malloc( 1758 parm, &pc, sizeof(struct octusb_qh), 1759 USB_HOST_ALIGN, 1)) { 1760 parm->err = USB_ERR_NOMEM; 1761 return; 1762 } 1763 if (parm->buf) { 1764 usbd_get_page(pc, 0, &page_info); 1765 1766 qh = page_info.buffer; 1767 1768 /* fill out QH */ 1769 1770 qh->sc = OCTUSB_BUS2SC(xfer->xroot->bus); 1771 qh->max_frame_size = xfer->max_frame_size; 1772 qh->max_packet_size = xfer->max_packet_size; 1773 qh->ep_num = xfer->endpointno; 1774 qh->ep_type = xfer->endpoint->edesc->bmAttributes; 1775 qh->dev_addr = xfer->address; 1776 qh->dev_speed = usbd_get_speed(xfer->xroot->udev); 1777 qh->root_port_index = xfer->xroot->udev->port_index; 1778 /* We need Octeon USB HUB's port index, not the local port */ 1779 hub = xfer->xroot->udev->parent_hub; 1780 while(hub && hub->parent_hub) { 1781 qh->root_port_index = hub->port_index; 1782 hub = hub->parent_hub; 1783 } 1784 1785 switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) { 1786 case UE_INTERRUPT: 1787 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) 1788 qh->ep_interval = xfer->interval * 8; 1789 else 1790 qh->ep_interval = xfer->interval * 1; 1791 break; 1792 case UE_ISOCHRONOUS: 1793 qh->ep_interval = 1 << xfer->fps_shift; 1794 break; 1795 default: 1796 qh->ep_interval = 0; 1797 break; 1798 } 1799 1800 qh->ep_mult = xfer->max_packet_count & 3; 1801 qh->hs_hub_addr = xfer->xroot->udev->hs_hub_addr; 1802 qh->hs_hub_port = xfer->xroot->udev->hs_port_no; 1803 } 1804 xfer->qh_start[0] = qh; 1805 1806 /* Allocate a fixup buffer */ 1807 1808 if (usbd_transfer_setup_sub_malloc( 1809 parm, &pc, OCTUSB_MAX_FIXUP, 1810 OCTUSB_MAX_FIXUP, 1)) { 1811 parm->err = USB_ERR_NOMEM; 1812 return; 1813 } 1814 if (parm->buf) { 1815 usbd_get_page(pc, 0, &page_info); 1816 1817 qh->fixup_phys = page_info.physaddr; 1818 qh->fixup_pc = pc; 1819 qh->fixup_buf = page_info.buffer; 1820 } 1821 /* Allocate transfer descriptors */ 1822 1823 last_obj = NULL; 1824 1825 ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ; 1826 1827 if (usbd_transfer_setup_sub_malloc( 1828 parm, &pc, sizeof(struct octusb_td), 1829 USB_HOST_ALIGN, ntd)) { 1830 parm->err = USB_ERR_NOMEM; 1831 return; 1832 } 1833 if (parm->buf) { 1834 for (n = 0; n != ntd; n++) { 1835 struct octusb_td *td; 1836 1837 usbd_get_page(pc + n, 0, &page_info); 1838 1839 td = page_info.buffer; 1840 1841 td->qh = qh; 1842 td->obj_next = last_obj; 1843 1844 last_obj = td; 1845 } 1846 } 1847 xfer->td_start[0] = last_obj; 1848} 1849 1850static void 1851octusb_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc, 1852 struct usb_endpoint *ep) 1853{ 1854 struct octusb_softc *sc = OCTUSB_BUS2SC(udev->bus); 1855 1856 DPRINTFN(2, "endpoint=%p, addr=%d, endpt=%d, mode=%d (%d)\n", 1857 ep, udev->address, edesc->bEndpointAddress, 1858 udev->flags.usb_mode, sc->sc_addr); 1859 1860 if (udev->device_index != sc->sc_addr) { 1861 switch (edesc->bmAttributes & UE_XFERTYPE) { 1862 case UE_CONTROL: 1863 ep->methods = &octusb_device_ctrl_methods; 1864 break; 1865 case UE_INTERRUPT: 1866 ep->methods = &octusb_device_intr_methods; 1867 break; 1868 case UE_ISOCHRONOUS: 1869 if (udev->speed != USB_SPEED_LOW) 1870 ep->methods = &octusb_device_isoc_methods; 1871 break; 1872 case UE_BULK: 1873 ep->methods = &octusb_device_bulk_methods; 1874 break; 1875 default: 1876 /* do nothing */ 1877 break; 1878 } 1879 } 1880} 1881 1882static void 1883octusb_xfer_unsetup(struct usb_xfer *xfer) 1884{ 1885 DPRINTF("Nothing to do.\n"); 1886} 1887 1888static void 1889octusb_get_dma_delay(struct usb_device *udev, uint32_t *pus) 1890{ 1891 /* DMA delay - wait until any use of memory is finished */ 1892 *pus = (2125); /* microseconds */ 1893} 1894 1895static void 1896octusb_device_resume(struct usb_device *udev) 1897{ 1898 DPRINTF("Nothing to do.\n"); 1899} 1900 1901static void 1902octusb_device_suspend(struct usb_device *udev) 1903{ 1904 DPRINTF("Nothing to do.\n"); 1905} 1906 1907static void 1908octusb_set_hw_power(struct usb_bus *bus) 1909{ 1910 DPRINTF("Nothing to do.\n"); 1911} 1912 1913static void 1914octusb_set_hw_power_sleep(struct usb_bus *bus, uint32_t state) 1915{ 1916 struct octusb_softc *sc = OCTUSB_BUS2SC(bus); 1917 1918 switch (state) { 1919 case USB_HW_POWER_SUSPEND: 1920 octusb_suspend(sc); 1921 break; 1922 case USB_HW_POWER_SHUTDOWN: 1923 octusb_uninit(sc); 1924 break; 1925 case USB_HW_POWER_RESUME: 1926 octusb_resume(sc); 1927 break; 1928 default: 1929 break; 1930 } 1931} 1932 1933struct usb_bus_methods octusb_bus_methods = { 1934 .endpoint_init = octusb_ep_init, 1935 .xfer_setup = octusb_xfer_setup, 1936 .xfer_unsetup = octusb_xfer_unsetup, 1937 .get_dma_delay = octusb_get_dma_delay, 1938 .device_resume = octusb_device_resume, 1939 .device_suspend = octusb_device_suspend, 1940 .set_hw_power = octusb_set_hw_power, 1941 .set_hw_power_sleep = octusb_set_hw_power_sleep, 1942 .roothub_exec = octusb_roothub_exec, 1943 .xfer_poll = octusb_do_poll, 1944}; 1945