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