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