1 /* $FreeBSD$ */ 2 /*- 3 * Copyright (c) 2008 Hans Petter Selasky <hselasky@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 /* 29 * This file contains the driver for the USS820 series USB Device 30 * Controller 31 * 32 * NOTE: The datasheet does not document everything! 33 */ 34 35 #include <dev/usb/usb.h> 36 #include <dev/usb/usb_mfunc.h> 37 #include <dev/usb/usb_revision.h> 38 #include <dev/usb/usb_error.h> 39 40 #define USB_DEBUG_VAR uss820dcidebug 41 42 #include <dev/usb/usb_core.h> 43 #include <dev/usb/usb_debug.h> 44 #include <dev/usb/usb_busdma.h> 45 #include <dev/usb/usb_process.h> 46 #include <dev/usb/usb_sw_transfer.h> 47 #include <dev/usb/usb_transfer.h> 48 #include <dev/usb/usb_device.h> 49 #include <dev/usb/usb_hub.h> 50 #include <dev/usb/usb_util.h> 51 52 #include <dev/usb/usb_controller.h> 53 #include <dev/usb/usb_bus.h> 54 #include <dev/usb/controller/uss820dci.h> 55 56 #define USS820_DCI_BUS2SC(bus) \ 57 ((struct uss820dci_softc *)(((uint8_t *)(bus)) - \ 58 ((uint8_t *)&(((struct uss820dci_softc *)0)->sc_bus)))) 59 60 #define USS820_DCI_PC2SC(pc) \ 61 USS820_DCI_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus) 62 63 #if USB_DEBUG 64 static int uss820dcidebug = 0; 65 66 SYSCTL_NODE(_hw_usb2, OID_AUTO, uss820dci, CTLFLAG_RW, 0, "USB uss820dci"); 67 SYSCTL_INT(_hw_usb2_uss820dci, OID_AUTO, debug, CTLFLAG_RW, 68 &uss820dcidebug, 0, "uss820dci debug level"); 69 #endif 70 71 #define USS820_DCI_INTR_ENDPT 1 72 73 /* prototypes */ 74 75 struct usb2_bus_methods uss820dci_bus_methods; 76 struct usb2_pipe_methods uss820dci_device_bulk_methods; 77 struct usb2_pipe_methods uss820dci_device_ctrl_methods; 78 struct usb2_pipe_methods uss820dci_device_intr_methods; 79 struct usb2_pipe_methods uss820dci_device_isoc_fs_methods; 80 struct usb2_pipe_methods uss820dci_root_ctrl_methods; 81 struct usb2_pipe_methods uss820dci_root_intr_methods; 82 83 static uss820dci_cmd_t uss820dci_setup_rx; 84 static uss820dci_cmd_t uss820dci_data_rx; 85 static uss820dci_cmd_t uss820dci_data_tx; 86 static uss820dci_cmd_t uss820dci_data_tx_sync; 87 static void uss820dci_device_done(struct usb2_xfer *, usb2_error_t); 88 static void uss820dci_do_poll(struct usb2_bus *); 89 static void uss820dci_root_ctrl_poll(struct uss820dci_softc *); 90 static void uss820dci_standard_done(struct usb2_xfer *); 91 static void uss820dci_intr_set(struct usb2_xfer *, uint8_t); 92 static void uss820dci_update_shared_1(struct uss820dci_softc *, uint8_t, 93 uint8_t, uint8_t); 94 95 static usb2_sw_transfer_func_t uss820dci_root_intr_done; 96 static usb2_sw_transfer_func_t uss820dci_root_ctrl_done; 97 98 /* 99 * Here is a list of what the USS820D chip can support. The main 100 * limitation is that the sum of the buffer sizes must be less than 101 * 1120 bytes. 102 */ 103 static const struct usb2_hw_ep_profile 104 uss820dci_ep_profile[] = { 105 106 [0] = { 107 .max_in_frame_size = 32, 108 .max_out_frame_size = 32, 109 .is_simplex = 0, 110 .support_control = 1, 111 }, 112 [1] = { 113 .max_in_frame_size = 64, 114 .max_out_frame_size = 64, 115 .is_simplex = 0, 116 .support_multi_buffer = 1, 117 .support_bulk = 1, 118 .support_interrupt = 1, 119 .support_in = 1, 120 .support_out = 1, 121 }, 122 [2] = { 123 .max_in_frame_size = 8, 124 .max_out_frame_size = 8, 125 .is_simplex = 0, 126 .support_multi_buffer = 1, 127 .support_bulk = 1, 128 .support_interrupt = 1, 129 .support_in = 1, 130 .support_out = 1, 131 }, 132 [3] = { 133 .max_in_frame_size = 256, 134 .max_out_frame_size = 256, 135 .is_simplex = 0, 136 .support_multi_buffer = 1, 137 .support_isochronous = 1, 138 .support_in = 1, 139 .support_out = 1, 140 }, 141 }; 142 143 static void 144 uss820dci_update_shared_1(struct uss820dci_softc *sc, uint8_t reg, 145 uint8_t keep_mask, uint8_t set_mask) 146 { 147 uint8_t temp; 148 149 USS820_WRITE_1(sc, USS820_PEND, 1); 150 temp = USS820_READ_1(sc, reg); 151 temp &= (keep_mask); 152 temp |= (set_mask); 153 USS820_WRITE_1(sc, reg, temp); 154 USS820_WRITE_1(sc, USS820_PEND, 0); 155 } 156 157 static void 158 uss820dci_get_hw_ep_profile(struct usb2_device *udev, 159 const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr) 160 { 161 if (ep_addr == 0) { 162 *ppf = uss820dci_ep_profile + 0; 163 } else if (ep_addr < 5) { 164 *ppf = uss820dci_ep_profile + 1; 165 } else if (ep_addr < 7) { 166 *ppf = uss820dci_ep_profile + 2; 167 } else if (ep_addr == 7) { 168 *ppf = uss820dci_ep_profile + 3; 169 } else { 170 *ppf = NULL; 171 } 172 } 173 174 static void 175 uss820dci_pull_up(struct uss820dci_softc *sc) 176 { 177 uint8_t temp; 178 179 /* pullup D+, if possible */ 180 181 if (!sc->sc_flags.d_pulled_up && 182 sc->sc_flags.port_powered) { 183 sc->sc_flags.d_pulled_up = 1; 184 185 DPRINTF("\n"); 186 187 temp = USS820_READ_1(sc, USS820_MCSR); 188 temp |= USS820_MCSR_DPEN; 189 USS820_WRITE_1(sc, USS820_MCSR, temp); 190 } 191 } 192 193 static void 194 uss820dci_pull_down(struct uss820dci_softc *sc) 195 { 196 uint8_t temp; 197 198 /* pulldown D+, if possible */ 199 200 if (sc->sc_flags.d_pulled_up) { 201 sc->sc_flags.d_pulled_up = 0; 202 203 DPRINTF("\n"); 204 205 temp = USS820_READ_1(sc, USS820_MCSR); 206 temp &= ~USS820_MCSR_DPEN; 207 USS820_WRITE_1(sc, USS820_MCSR, temp); 208 } 209 } 210 211 static void 212 uss820dci_wakeup_peer(struct uss820dci_softc *sc) 213 { 214 if (!(sc->sc_flags.status_suspend)) { 215 return; 216 } 217 DPRINTFN(0, "not supported\n"); 218 } 219 220 static void 221 uss820dci_set_address(struct uss820dci_softc *sc, uint8_t addr) 222 { 223 DPRINTFN(5, "addr=%d\n", addr); 224 225 USS820_WRITE_1(sc, USS820_FADDR, addr); 226 } 227 228 static uint8_t 229 uss820dci_setup_rx(struct uss820dci_td *td) 230 { 231 struct uss820dci_softc *sc; 232 struct usb2_device_request req; 233 uint16_t count; 234 uint8_t rx_stat; 235 uint8_t temp; 236 237 /* select the correct endpoint */ 238 bus_space_write_1(td->io_tag, td->io_hdl, 239 td->ep_reg, td->ep_index); 240 241 /* read out FIFO status */ 242 rx_stat = bus_space_read_1(td->io_tag, td->io_hdl, 243 td->rx_stat_reg); 244 245 /* get pointer to softc */ 246 sc = USS820_DCI_PC2SC(td->pc); 247 248 DPRINTFN(5, "rx_stat=0x%02x rem=%u\n", rx_stat, td->remainder); 249 250 if (!(rx_stat & USS820_RXSTAT_RXSETUP)) { 251 /* abort any ongoing transfer */ 252 if (!td->did_stall) { 253 DPRINTFN(5, "stalling\n"); 254 255 /* set stall */ 256 257 uss820dci_update_shared_1(sc, USS820_EPCON, 0xFF, 258 (USS820_EPCON_TXSTL | USS820_EPCON_RXSTL)); 259 260 td->did_stall = 1; 261 } 262 goto not_complete; 263 } 264 /* clear stall and all I/O */ 265 uss820dci_update_shared_1(sc, USS820_EPCON, 266 0xFF ^ (USS820_EPCON_TXSTL | 267 USS820_EPCON_RXSTL | 268 USS820_EPCON_RXIE | 269 USS820_EPCON_TXOE), 0); 270 271 /* clear end overwrite flag */ 272 uss820dci_update_shared_1(sc, USS820_RXSTAT, 273 0xFF ^ USS820_RXSTAT_EDOVW, 0); 274 275 /* get the packet byte count */ 276 count = bus_space_read_1(td->io_tag, td->io_hdl, 277 td->rx_count_low_reg); 278 count |= (bus_space_read_1(td->io_tag, td->io_hdl, 279 td->rx_count_high_reg) << 8); 280 count &= 0x3FF; 281 282 /* verify data length */ 283 if (count != td->remainder) { 284 DPRINTFN(0, "Invalid SETUP packet " 285 "length, %d bytes\n", count); 286 goto not_complete; 287 } 288 if (count != sizeof(req)) { 289 DPRINTFN(0, "Unsupported SETUP packet " 290 "length, %d bytes\n", count); 291 goto not_complete; 292 } 293 /* receive data */ 294 bus_space_read_multi_1(td->io_tag, td->io_hdl, 295 td->rx_fifo_reg, (void *)&req, sizeof(req)); 296 297 /* read out FIFO status */ 298 rx_stat = bus_space_read_1(td->io_tag, td->io_hdl, 299 td->rx_stat_reg); 300 301 if (rx_stat & (USS820_RXSTAT_EDOVW | 302 USS820_RXSTAT_STOVW)) { 303 DPRINTF("new SETUP packet received\n"); 304 return (1); /* not complete */ 305 } 306 /* clear receive setup bit */ 307 uss820dci_update_shared_1(sc, USS820_RXSTAT, 308 0xFF ^ (USS820_RXSTAT_RXSETUP | 309 USS820_RXSTAT_EDOVW | 310 USS820_RXSTAT_STOVW), 0); 311 312 /* set RXFFRC bit */ 313 temp = bus_space_read_1(td->io_tag, td->io_hdl, 314 td->rx_cntl_reg); 315 temp |= USS820_RXCON_RXFFRC; 316 bus_space_write_1(td->io_tag, td->io_hdl, 317 td->rx_cntl_reg, temp); 318 319 /* copy data into real buffer */ 320 usb2_copy_in(td->pc, 0, &req, sizeof(req)); 321 322 td->offset = sizeof(req); 323 td->remainder = 0; 324 325 /* sneak peek the set address */ 326 if ((req.bmRequestType == UT_WRITE_DEVICE) && 327 (req.bRequest == UR_SET_ADDRESS)) { 328 sc->sc_dv_addr = req.wValue[0] & 0x7F; 329 } else { 330 sc->sc_dv_addr = 0xFF; 331 } 332 return (0); /* complete */ 333 334 not_complete: 335 /* clear end overwrite flag, if any */ 336 if (rx_stat & USS820_RXSTAT_RXSETUP) { 337 uss820dci_update_shared_1(sc, USS820_RXSTAT, 338 0xFF ^ (USS820_RXSTAT_EDOVW | 339 USS820_RXSTAT_STOVW | 340 USS820_RXSTAT_RXSETUP), 0); 341 } 342 return (1); /* not complete */ 343 344 } 345 346 static uint8_t 347 uss820dci_data_rx(struct uss820dci_td *td) 348 { 349 struct usb2_page_search buf_res; 350 uint16_t count; 351 uint8_t rx_flag; 352 uint8_t rx_stat; 353 uint8_t rx_cntl; 354 uint8_t to; 355 uint8_t got_short; 356 357 to = 2; /* don't loop forever! */ 358 got_short = 0; 359 360 /* select the correct endpoint */ 361 bus_space_write_1(td->io_tag, td->io_hdl, td->ep_reg, td->ep_index); 362 363 /* check if any of the FIFO banks have data */ 364 repeat: 365 /* read out FIFO flag */ 366 rx_flag = bus_space_read_1(td->io_tag, td->io_hdl, 367 td->rx_flag_reg); 368 /* read out FIFO status */ 369 rx_stat = bus_space_read_1(td->io_tag, td->io_hdl, 370 td->rx_stat_reg); 371 372 DPRINTFN(5, "rx_stat=0x%02x rx_flag=0x%02x rem=%u\n", 373 rx_stat, rx_flag, td->remainder); 374 375 if (rx_stat & (USS820_RXSTAT_RXSETUP | 376 USS820_RXSTAT_RXSOVW | 377 USS820_RXSTAT_EDOVW)) { 378 if (td->remainder == 0) { 379 /* 380 * We are actually complete and have 381 * received the next SETUP 382 */ 383 DPRINTFN(5, "faking complete\n"); 384 return (0); /* complete */ 385 } 386 /* 387 * USB Host Aborted the transfer. 388 */ 389 td->error = 1; 390 return (0); /* complete */ 391 } 392 /* check for errors */ 393 if (rx_flag & (USS820_RXFLG_RXOVF | 394 USS820_RXFLG_RXURF)) { 395 DPRINTFN(5, "overflow or underflow\n"); 396 /* should not happen */ 397 td->error = 1; 398 return (0); /* complete */ 399 } 400 /* check status */ 401 if (!(rx_flag & (USS820_RXFLG_RXFIF0 | 402 USS820_RXFLG_RXFIF1))) { 403 404 /* read out EPCON register */ 405 /* enable RX input */ 406 if (!td->did_stall) { 407 uss820dci_update_shared_1(USS820_DCI_PC2SC(td->pc), 408 USS820_EPCON, 0xFF, USS820_EPCON_RXIE); 409 td->did_stall = 1; 410 } 411 return (1); /* not complete */ 412 } 413 /* get the packet byte count */ 414 count = bus_space_read_1(td->io_tag, td->io_hdl, 415 td->rx_count_low_reg); 416 417 count |= (bus_space_read_1(td->io_tag, td->io_hdl, 418 td->rx_count_high_reg) << 8); 419 count &= 0x3FF; 420 421 DPRINTFN(5, "count=0x%04x\n", count); 422 423 /* verify the packet byte count */ 424 if (count != td->max_packet_size) { 425 if (count < td->max_packet_size) { 426 /* we have a short packet */ 427 td->short_pkt = 1; 428 got_short = 1; 429 } else { 430 /* invalid USB packet */ 431 td->error = 1; 432 return (0); /* we are complete */ 433 } 434 } 435 /* verify the packet byte count */ 436 if (count > td->remainder) { 437 /* invalid USB packet */ 438 td->error = 1; 439 return (0); /* we are complete */ 440 } 441 while (count > 0) { 442 usb2_get_page(td->pc, td->offset, &buf_res); 443 444 /* get correct length */ 445 if (buf_res.length > count) { 446 buf_res.length = count; 447 } 448 /* receive data */ 449 bus_space_read_multi_1(td->io_tag, td->io_hdl, 450 td->rx_fifo_reg, buf_res.buffer, buf_res.length); 451 452 /* update counters */ 453 count -= buf_res.length; 454 td->offset += buf_res.length; 455 td->remainder -= buf_res.length; 456 } 457 458 /* set RXFFRC bit */ 459 rx_cntl = bus_space_read_1(td->io_tag, td->io_hdl, 460 td->rx_cntl_reg); 461 rx_cntl |= USS820_RXCON_RXFFRC; 462 bus_space_write_1(td->io_tag, td->io_hdl, 463 td->rx_cntl_reg, rx_cntl); 464 465 /* check if we are complete */ 466 if ((td->remainder == 0) || got_short) { 467 if (td->short_pkt) { 468 /* we are complete */ 469 return (0); 470 } 471 /* else need to receive a zero length packet */ 472 } 473 if (--to) { 474 goto repeat; 475 } 476 return (1); /* not complete */ 477 } 478 479 static uint8_t 480 uss820dci_data_tx(struct uss820dci_td *td) 481 { 482 struct usb2_page_search buf_res; 483 uint16_t count; 484 uint16_t count_copy; 485 uint8_t rx_stat; 486 uint8_t tx_flag; 487 uint8_t to; 488 489 /* select the correct endpoint */ 490 bus_space_write_1(td->io_tag, td->io_hdl, 491 td->ep_reg, td->ep_index); 492 493 to = 2; /* don't loop forever! */ 494 495 repeat: 496 /* read out TX FIFO flags */ 497 tx_flag = bus_space_read_1(td->io_tag, td->io_hdl, 498 td->tx_flag_reg); 499 500 /* read out RX FIFO status last */ 501 rx_stat = bus_space_read_1(td->io_tag, td->io_hdl, 502 td->rx_stat_reg); 503 504 DPRINTFN(5, "rx_stat=0x%02x tx_flag=0x%02x rem=%u\n", 505 rx_stat, tx_flag, td->remainder); 506 507 if (rx_stat & (USS820_RXSTAT_RXSETUP | 508 USS820_RXSTAT_RXSOVW | 509 USS820_RXSTAT_EDOVW)) { 510 /* 511 * The current transfer was aborted 512 * by the USB Host 513 */ 514 td->error = 1; 515 return (0); /* complete */ 516 } 517 if (tx_flag & (USS820_TXFLG_TXOVF | 518 USS820_TXFLG_TXURF)) { 519 td->error = 1; 520 return (0); /* complete */ 521 } 522 if (tx_flag & USS820_TXFLG_TXFIF0) { 523 if (tx_flag & USS820_TXFLG_TXFIF1) { 524 return (1); /* not complete */ 525 } 526 } 527 if ((!td->support_multi_buffer) && 528 (tx_flag & (USS820_TXFLG_TXFIF0 | 529 USS820_TXFLG_TXFIF1))) { 530 return (1); /* not complete */ 531 } 532 count = td->max_packet_size; 533 if (td->remainder < count) { 534 /* we have a short packet */ 535 td->short_pkt = 1; 536 count = td->remainder; 537 } 538 count_copy = count; 539 while (count > 0) { 540 541 usb2_get_page(td->pc, td->offset, &buf_res); 542 543 /* get correct length */ 544 if (buf_res.length > count) { 545 buf_res.length = count; 546 } 547 /* transmit data */ 548 bus_space_write_multi_1(td->io_tag, td->io_hdl, 549 td->tx_fifo_reg, buf_res.buffer, buf_res.length); 550 551 /* update counters */ 552 count -= buf_res.length; 553 td->offset += buf_res.length; 554 td->remainder -= buf_res.length; 555 } 556 557 /* post-write high packet byte count first */ 558 bus_space_write_1(td->io_tag, td->io_hdl, 559 td->tx_count_high_reg, count_copy >> 8); 560 561 /* post-write low packet byte count last */ 562 bus_space_write_1(td->io_tag, td->io_hdl, 563 td->tx_count_low_reg, count_copy); 564 565 /* 566 * Enable TX output, which must happen after that we have written 567 * data into the FIFO. This is undocumented. 568 */ 569 if (!td->did_stall) { 570 uss820dci_update_shared_1(USS820_DCI_PC2SC(td->pc), 571 USS820_EPCON, 0xFF, USS820_EPCON_TXOE); 572 td->did_stall = 1; 573 } 574 /* check remainder */ 575 if (td->remainder == 0) { 576 if (td->short_pkt) { 577 return (0); /* complete */ 578 } 579 /* else we need to transmit a short packet */ 580 } 581 if (--to) { 582 goto repeat; 583 } 584 return (1); /* not complete */ 585 } 586 587 static uint8_t 588 uss820dci_data_tx_sync(struct uss820dci_td *td) 589 { 590 struct uss820dci_softc *sc; 591 uint8_t rx_stat; 592 uint8_t tx_flag; 593 594 /* select the correct endpoint */ 595 bus_space_write_1(td->io_tag, td->io_hdl, 596 td->ep_reg, td->ep_index); 597 598 /* read out TX FIFO flag */ 599 tx_flag = bus_space_read_1(td->io_tag, td->io_hdl, 600 td->tx_flag_reg); 601 602 /* read out RX FIFO status last */ 603 rx_stat = bus_space_read_1(td->io_tag, td->io_hdl, 604 td->rx_stat_reg); 605 606 DPRINTFN(5, "rx_stat=0x%02x rem=%u\n", rx_stat, td->remainder); 607 608 if (rx_stat & (USS820_RXSTAT_RXSETUP | 609 USS820_RXSTAT_RXSOVW | 610 USS820_RXSTAT_EDOVW)) { 611 DPRINTFN(5, "faking complete\n"); 612 /* Race condition */ 613 return (0); /* complete */ 614 } 615 DPRINTFN(5, "tx_flag=0x%02x rem=%u\n", 616 tx_flag, td->remainder); 617 618 if (tx_flag & (USS820_TXFLG_TXOVF | 619 USS820_TXFLG_TXURF)) { 620 td->error = 1; 621 return (0); /* complete */ 622 } 623 if (tx_flag & (USS820_TXFLG_TXFIF0 | 624 USS820_TXFLG_TXFIF1)) { 625 return (1); /* not complete */ 626 } 627 sc = USS820_DCI_PC2SC(td->pc); 628 if (sc->sc_dv_addr != 0xFF) { 629 /* write function address */ 630 uss820dci_set_address(sc, sc->sc_dv_addr); 631 } 632 return (0); /* complete */ 633 } 634 635 static uint8_t 636 uss820dci_xfer_do_fifo(struct usb2_xfer *xfer) 637 { 638 struct uss820dci_td *td; 639 640 DPRINTFN(9, "\n"); 641 642 td = xfer->td_transfer_cache; 643 while (1) { 644 if ((td->func) (td)) { 645 /* operation in progress */ 646 break; 647 } 648 if (((void *)td) == xfer->td_transfer_last) { 649 goto done; 650 } 651 if (td->error) { 652 goto done; 653 } else if (td->remainder > 0) { 654 /* 655 * We had a short transfer. If there is no alternate 656 * next, stop processing ! 657 */ 658 if (!td->alt_next) { 659 goto done; 660 } 661 } 662 /* 663 * Fetch the next transfer descriptor. 664 */ 665 td = td->obj_next; 666 xfer->td_transfer_cache = td; 667 } 668 return (1); /* not complete */ 669 670 done: 671 /* compute all actual lengths */ 672 673 uss820dci_standard_done(xfer); 674 675 return (0); /* complete */ 676 } 677 678 static void 679 uss820dci_interrupt_poll(struct uss820dci_softc *sc) 680 { 681 struct usb2_xfer *xfer; 682 683 repeat: 684 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { 685 if (!uss820dci_xfer_do_fifo(xfer)) { 686 /* queue has been modified */ 687 goto repeat; 688 } 689 } 690 } 691 692 static void 693 uss820dci_wait_suspend(struct uss820dci_softc *sc, uint8_t on) 694 { 695 uint8_t scr; 696 uint8_t scratch; 697 698 scr = USS820_READ_1(sc, USS820_SCR); 699 scratch = USS820_READ_1(sc, USS820_SCRATCH); 700 701 if (on) { 702 scr |= USS820_SCR_IE_SUSP; 703 scratch &= ~USS820_SCRATCH_IE_RESUME; 704 } else { 705 scr &= ~USS820_SCR_IE_SUSP; 706 scratch |= USS820_SCRATCH_IE_RESUME; 707 } 708 709 USS820_WRITE_1(sc, USS820_SCR, scr); 710 USS820_WRITE_1(sc, USS820_SCRATCH, scratch); 711 } 712 713 void 714 uss820dci_interrupt(struct uss820dci_softc *sc) 715 { 716 uint8_t ssr; 717 uint8_t event; 718 719 USB_BUS_LOCK(&sc->sc_bus); 720 721 ssr = USS820_READ_1(sc, USS820_SSR); 722 723 ssr &= (USS820_SSR_SUSPEND | 724 USS820_SSR_RESUME | 725 USS820_SSR_RESET); 726 727 /* acknowledge all interrupts */ 728 729 uss820dci_update_shared_1(sc, USS820_SSR, 0, 0); 730 731 /* check for any bus state change interrupts */ 732 733 if (ssr) { 734 735 event = 0; 736 737 if (ssr & USS820_SSR_RESET) { 738 sc->sc_flags.status_bus_reset = 1; 739 sc->sc_flags.status_suspend = 0; 740 sc->sc_flags.change_suspend = 0; 741 sc->sc_flags.change_connect = 1; 742 743 /* disable resume interrupt */ 744 uss820dci_wait_suspend(sc, 1); 745 746 event = 1; 747 } 748 /* 749 * If "RESUME" and "SUSPEND" is set at the same time 750 * we interpret that like "RESUME". Resume is set when 751 * there is at least 3 milliseconds of inactivity on 752 * the USB BUS. 753 */ 754 if (ssr & USS820_SSR_RESUME) { 755 if (sc->sc_flags.status_suspend) { 756 sc->sc_flags.status_suspend = 0; 757 sc->sc_flags.change_suspend = 1; 758 /* disable resume interrupt */ 759 uss820dci_wait_suspend(sc, 1); 760 event = 1; 761 } 762 } else if (ssr & USS820_SSR_SUSPEND) { 763 if (!sc->sc_flags.status_suspend) { 764 sc->sc_flags.status_suspend = 1; 765 sc->sc_flags.change_suspend = 1; 766 /* enable resume interrupt */ 767 uss820dci_wait_suspend(sc, 0); 768 event = 1; 769 } 770 } 771 if (event) { 772 773 DPRINTF("real bus interrupt 0x%02x\n", ssr); 774 775 /* complete root HUB interrupt endpoint */ 776 777 usb2_sw_transfer(&sc->sc_root_intr, 778 &uss820dci_root_intr_done); 779 } 780 } 781 /* acknowledge all SBI interrupts */ 782 uss820dci_update_shared_1(sc, USS820_SBI, 0, 0); 783 784 /* acknowledge all SBI1 interrupts */ 785 uss820dci_update_shared_1(sc, USS820_SBI1, 0, 0); 786 787 /* poll all active transfers */ 788 uss820dci_interrupt_poll(sc); 789 790 USB_BUS_UNLOCK(&sc->sc_bus); 791 } 792 793 static void 794 uss820dci_setup_standard_chain_sub(struct uss820_std_temp *temp) 795 { 796 struct uss820dci_td *td; 797 798 /* get current Transfer Descriptor */ 799 td = temp->td_next; 800 temp->td = td; 801 802 /* prepare for next TD */ 803 temp->td_next = td->obj_next; 804 805 /* fill out the Transfer Descriptor */ 806 td->func = temp->func; 807 td->pc = temp->pc; 808 td->offset = temp->offset; 809 td->remainder = temp->len; 810 td->error = 0; 811 td->did_stall = 0; 812 td->short_pkt = temp->short_pkt; 813 td->alt_next = temp->setup_alt_next; 814 } 815 816 static void 817 uss820dci_setup_standard_chain(struct usb2_xfer *xfer) 818 { 819 struct uss820_std_temp temp; 820 struct uss820dci_softc *sc; 821 struct uss820dci_td *td; 822 uint32_t x; 823 uint8_t ep_no; 824 825 DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n", 826 xfer->address, UE_GET_ADDR(xfer->endpoint), 827 xfer->sumlen, usb2_get_speed(xfer->xroot->udev)); 828 829 temp.max_frame_size = xfer->max_frame_size; 830 831 td = xfer->td_start[0]; 832 xfer->td_transfer_first = td; 833 xfer->td_transfer_cache = td; 834 835 /* setup temp */ 836 837 temp.td = NULL; 838 temp.td_next = xfer->td_start[0]; 839 temp.offset = 0; 840 temp.setup_alt_next = xfer->flags_int.short_frames_ok; 841 842 sc = USS820_DCI_BUS2SC(xfer->xroot->bus); 843 ep_no = (xfer->endpoint & UE_ADDR); 844 845 /* check if we should prepend a setup message */ 846 847 if (xfer->flags_int.control_xfr) { 848 if (xfer->flags_int.control_hdr) { 849 850 temp.func = &uss820dci_setup_rx; 851 temp.len = xfer->frlengths[0]; 852 temp.pc = xfer->frbuffers + 0; 853 temp.short_pkt = temp.len ? 1 : 0; 854 /* check for last frame */ 855 if (xfer->nframes == 1) { 856 /* no STATUS stage yet, SETUP is last */ 857 if (xfer->flags_int.control_act) 858 temp.setup_alt_next = 0; 859 } 860 861 uss820dci_setup_standard_chain_sub(&temp); 862 } 863 x = 1; 864 } else { 865 x = 0; 866 } 867 868 if (x != xfer->nframes) { 869 if (xfer->endpoint & UE_DIR_IN) { 870 temp.func = &uss820dci_data_tx; 871 } else { 872 temp.func = &uss820dci_data_rx; 873 } 874 875 /* setup "pc" pointer */ 876 temp.pc = xfer->frbuffers + x; 877 } 878 while (x != xfer->nframes) { 879 880 /* DATA0 / DATA1 message */ 881 882 temp.len = xfer->frlengths[x]; 883 884 x++; 885 886 if (x == xfer->nframes) { 887 if (xfer->flags_int.control_xfr) { 888 if (xfer->flags_int.control_act) { 889 temp.setup_alt_next = 0; 890 } 891 } else { 892 temp.setup_alt_next = 0; 893 } 894 } 895 if (temp.len == 0) { 896 897 /* make sure that we send an USB packet */ 898 899 temp.short_pkt = 0; 900 901 } else { 902 903 /* regular data transfer */ 904 905 temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1; 906 } 907 908 uss820dci_setup_standard_chain_sub(&temp); 909 910 if (xfer->flags_int.isochronous_xfr) { 911 temp.offset += temp.len; 912 } else { 913 /* get next Page Cache pointer */ 914 temp.pc = xfer->frbuffers + x; 915 } 916 } 917 918 /* check for control transfer */ 919 if (xfer->flags_int.control_xfr) { 920 uint8_t need_sync; 921 922 /* always setup a valid "pc" pointer for status and sync */ 923 temp.pc = xfer->frbuffers + 0; 924 temp.len = 0; 925 temp.short_pkt = 0; 926 temp.setup_alt_next = 0; 927 928 /* check if we should append a status stage */ 929 if (!xfer->flags_int.control_act) { 930 931 /* 932 * Send a DATA1 message and invert the current 933 * endpoint direction. 934 */ 935 if (xfer->endpoint & UE_DIR_IN) { 936 temp.func = &uss820dci_data_rx; 937 need_sync = 0; 938 } else { 939 temp.func = &uss820dci_data_tx; 940 need_sync = 1; 941 } 942 temp.len = 0; 943 temp.short_pkt = 0; 944 945 uss820dci_setup_standard_chain_sub(&temp); 946 if (need_sync) { 947 /* we need a SYNC point after TX */ 948 temp.func = &uss820dci_data_tx_sync; 949 uss820dci_setup_standard_chain_sub(&temp); 950 } 951 } 952 } 953 /* must have at least one frame! */ 954 td = temp.td; 955 xfer->td_transfer_last = td; 956 } 957 958 static void 959 uss820dci_timeout(void *arg) 960 { 961 struct usb2_xfer *xfer = arg; 962 963 DPRINTF("xfer=%p\n", xfer); 964 965 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED); 966 967 /* transfer is transferred */ 968 uss820dci_device_done(xfer, USB_ERR_TIMEOUT); 969 } 970 971 static void 972 uss820dci_intr_set(struct usb2_xfer *xfer, uint8_t set) 973 { 974 struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); 975 uint8_t ep_no = (xfer->endpoint & UE_ADDR); 976 uint8_t ep_reg; 977 uint8_t temp; 978 979 DPRINTFN(15, "endpoint 0x%02x\n", xfer->endpoint); 980 981 if (ep_no > 3) { 982 ep_reg = USS820_SBIE1; 983 } else { 984 ep_reg = USS820_SBIE; 985 } 986 987 ep_no &= 3; 988 ep_no = 1 << (2 * ep_no); 989 990 if (xfer->flags_int.control_xfr) { 991 if (xfer->flags_int.control_hdr) { 992 ep_no <<= 1; /* RX interrupt only */ 993 } else { 994 ep_no |= (ep_no << 1); /* RX and TX interrupt */ 995 } 996 } else { 997 if (!(xfer->endpoint & UE_DIR_IN)) { 998 ep_no <<= 1; 999 } 1000 } 1001 temp = USS820_READ_1(sc, ep_reg); 1002 if (set) { 1003 temp |= ep_no; 1004 } else { 1005 temp &= ~ep_no; 1006 } 1007 USS820_WRITE_1(sc, ep_reg, temp); 1008 } 1009 1010 static void 1011 uss820dci_start_standard_chain(struct usb2_xfer *xfer) 1012 { 1013 DPRINTFN(9, "\n"); 1014 1015 /* poll one time */ 1016 if (uss820dci_xfer_do_fifo(xfer)) { 1017 1018 /* 1019 * Only enable the endpoint interrupt when we are 1020 * actually waiting for data, hence we are dealing 1021 * with level triggered interrupts ! 1022 */ 1023 uss820dci_intr_set(xfer, 1); 1024 1025 /* put transfer on interrupt queue */ 1026 usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer); 1027 1028 /* start timeout, if any */ 1029 if (xfer->timeout != 0) { 1030 usb2_transfer_timeout_ms(xfer, 1031 &uss820dci_timeout, xfer->timeout); 1032 } 1033 } 1034 } 1035 1036 static void 1037 uss820dci_root_intr_done(struct usb2_xfer *xfer, 1038 struct usb2_sw_transfer *std) 1039 { 1040 struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); 1041 1042 DPRINTFN(9, "\n"); 1043 1044 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); 1045 1046 if (std->state != USB_SW_TR_PRE_DATA) { 1047 if (std->state == USB_SW_TR_PRE_CALLBACK) { 1048 /* transfer transferred */ 1049 uss820dci_device_done(xfer, std->err); 1050 } 1051 goto done; 1052 } 1053 /* setup buffer */ 1054 std->ptr = sc->sc_hub_idata; 1055 std->len = sizeof(sc->sc_hub_idata); 1056 1057 /* set port bit */ 1058 sc->sc_hub_idata[0] = 0x02; /* we only have one port */ 1059 1060 done: 1061 return; 1062 } 1063 1064 static usb2_error_t 1065 uss820dci_standard_done_sub(struct usb2_xfer *xfer) 1066 { 1067 struct uss820dci_td *td; 1068 uint32_t len; 1069 uint8_t error; 1070 1071 DPRINTFN(9, "\n"); 1072 1073 td = xfer->td_transfer_cache; 1074 1075 do { 1076 len = td->remainder; 1077 1078 if (xfer->aframes != xfer->nframes) { 1079 /* 1080 * Verify the length and subtract 1081 * the remainder from "frlengths[]": 1082 */ 1083 if (len > xfer->frlengths[xfer->aframes]) { 1084 td->error = 1; 1085 } else { 1086 xfer->frlengths[xfer->aframes] -= len; 1087 } 1088 } 1089 /* Check for transfer error */ 1090 if (td->error) { 1091 /* the transfer is finished */ 1092 error = 1; 1093 td = NULL; 1094 break; 1095 } 1096 /* Check for short transfer */ 1097 if (len > 0) { 1098 if (xfer->flags_int.short_frames_ok) { 1099 /* follow alt next */ 1100 if (td->alt_next) { 1101 td = td->obj_next; 1102 } else { 1103 td = NULL; 1104 } 1105 } else { 1106 /* the transfer is finished */ 1107 td = NULL; 1108 } 1109 error = 0; 1110 break; 1111 } 1112 td = td->obj_next; 1113 1114 /* this USB frame is complete */ 1115 error = 0; 1116 break; 1117 1118 } while (0); 1119 1120 /* update transfer cache */ 1121 1122 xfer->td_transfer_cache = td; 1123 1124 return (error ? 1125 USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION); 1126 } 1127 1128 static void 1129 uss820dci_standard_done(struct usb2_xfer *xfer) 1130 { 1131 usb2_error_t err = 0; 1132 1133 DPRINTFN(13, "xfer=%p pipe=%p transfer done\n", 1134 xfer, xfer->pipe); 1135 1136 /* reset scanner */ 1137 1138 xfer->td_transfer_cache = xfer->td_transfer_first; 1139 1140 if (xfer->flags_int.control_xfr) { 1141 1142 if (xfer->flags_int.control_hdr) { 1143 1144 err = uss820dci_standard_done_sub(xfer); 1145 } 1146 xfer->aframes = 1; 1147 1148 if (xfer->td_transfer_cache == NULL) { 1149 goto done; 1150 } 1151 } 1152 while (xfer->aframes != xfer->nframes) { 1153 1154 err = uss820dci_standard_done_sub(xfer); 1155 xfer->aframes++; 1156 1157 if (xfer->td_transfer_cache == NULL) { 1158 goto done; 1159 } 1160 } 1161 1162 if (xfer->flags_int.control_xfr && 1163 !xfer->flags_int.control_act) { 1164 1165 err = uss820dci_standard_done_sub(xfer); 1166 } 1167 done: 1168 uss820dci_device_done(xfer, err); 1169 } 1170 1171 /*------------------------------------------------------------------------* 1172 * uss820dci_device_done 1173 * 1174 * NOTE: this function can be called more than one time on the 1175 * same USB transfer! 1176 *------------------------------------------------------------------------*/ 1177 static void 1178 uss820dci_device_done(struct usb2_xfer *xfer, usb2_error_t error) 1179 { 1180 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED); 1181 1182 DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n", 1183 xfer, xfer->pipe, error); 1184 1185 if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) { 1186 uss820dci_intr_set(xfer, 0); 1187 } 1188 /* dequeue transfer and start next transfer */ 1189 usb2_transfer_done(xfer, error); 1190 } 1191 1192 static void 1193 uss820dci_set_stall(struct usb2_device *udev, struct usb2_xfer *xfer, 1194 struct usb2_pipe *pipe) 1195 { 1196 struct uss820dci_softc *sc; 1197 uint8_t ep_no; 1198 uint8_t ep_type; 1199 uint8_t ep_dir; 1200 uint8_t temp; 1201 1202 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED); 1203 1204 DPRINTFN(5, "pipe=%p\n", pipe); 1205 1206 if (xfer) { 1207 /* cancel any ongoing transfers */ 1208 uss820dci_device_done(xfer, USB_ERR_STALLED); 1209 } 1210 /* set FORCESTALL */ 1211 sc = USS820_DCI_BUS2SC(udev->bus); 1212 ep_no = (pipe->edesc->bEndpointAddress & UE_ADDR); 1213 ep_dir = (pipe->edesc->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)); 1214 ep_type = (pipe->edesc->bmAttributes & UE_XFERTYPE); 1215 1216 if (ep_type == UE_CONTROL) { 1217 /* should not happen */ 1218 return; 1219 } 1220 USS820_WRITE_1(sc, USS820_EPINDEX, ep_no); 1221 1222 if (ep_dir == UE_DIR_IN) { 1223 temp = USS820_EPCON_TXSTL; 1224 } else { 1225 temp = USS820_EPCON_RXSTL; 1226 } 1227 uss820dci_update_shared_1(sc, USS820_EPCON, 0xFF, temp); 1228 } 1229 1230 static void 1231 uss820dci_clear_stall_sub(struct uss820dci_softc *sc, 1232 uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir) 1233 { 1234 uint8_t temp; 1235 1236 if (ep_type == UE_CONTROL) { 1237 /* clearing stall is not needed */ 1238 return; 1239 } 1240 /* select endpoint index */ 1241 USS820_WRITE_1(sc, USS820_EPINDEX, ep_no); 1242 1243 /* clear stall and disable I/O transfers */ 1244 if (ep_dir == UE_DIR_IN) { 1245 temp = 0xFF ^ (USS820_EPCON_TXOE | 1246 USS820_EPCON_TXSTL); 1247 } else { 1248 temp = 0xFF ^ (USS820_EPCON_RXIE | 1249 USS820_EPCON_RXSTL); 1250 } 1251 uss820dci_update_shared_1(sc, USS820_EPCON, temp, 0); 1252 1253 if (ep_dir == UE_DIR_IN) { 1254 /* reset data toggle */ 1255 USS820_WRITE_1(sc, USS820_TXSTAT, 1256 USS820_TXSTAT_TXSOVW); 1257 1258 /* reset FIFO */ 1259 temp = USS820_READ_1(sc, USS820_TXCON); 1260 temp |= USS820_TXCON_TXCLR; 1261 USS820_WRITE_1(sc, USS820_TXCON, temp); 1262 temp &= ~USS820_TXCON_TXCLR; 1263 USS820_WRITE_1(sc, USS820_TXCON, temp); 1264 } else { 1265 1266 /* reset data toggle */ 1267 uss820dci_update_shared_1(sc, USS820_RXSTAT, 1268 0, USS820_RXSTAT_RXSOVW); 1269 1270 /* reset FIFO */ 1271 temp = USS820_READ_1(sc, USS820_RXCON); 1272 temp |= USS820_RXCON_RXCLR; 1273 temp &= ~USS820_RXCON_RXFFRC; 1274 USS820_WRITE_1(sc, USS820_RXCON, temp); 1275 temp &= ~USS820_RXCON_RXCLR; 1276 USS820_WRITE_1(sc, USS820_RXCON, temp); 1277 } 1278 } 1279 1280 static void 1281 uss820dci_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe) 1282 { 1283 struct uss820dci_softc *sc; 1284 struct usb2_endpoint_descriptor *ed; 1285 1286 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED); 1287 1288 DPRINTFN(5, "pipe=%p\n", pipe); 1289 1290 /* check mode */ 1291 if (udev->flags.usb2_mode != USB_MODE_DEVICE) { 1292 /* not supported */ 1293 return; 1294 } 1295 /* get softc */ 1296 sc = USS820_DCI_BUS2SC(udev->bus); 1297 1298 /* get endpoint descriptor */ 1299 ed = pipe->edesc; 1300 1301 /* reset endpoint */ 1302 uss820dci_clear_stall_sub(sc, 1303 (ed->bEndpointAddress & UE_ADDR), 1304 (ed->bmAttributes & UE_XFERTYPE), 1305 (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT))); 1306 } 1307 1308 usb2_error_t 1309 uss820dci_init(struct uss820dci_softc *sc) 1310 { 1311 const struct usb2_hw_ep_profile *pf; 1312 uint8_t n; 1313 uint8_t temp; 1314 1315 DPRINTF("start\n"); 1316 1317 /* set up the bus structure */ 1318 sc->sc_bus.usbrev = USB_REV_1_1; 1319 sc->sc_bus.methods = &uss820dci_bus_methods; 1320 1321 USB_BUS_LOCK(&sc->sc_bus); 1322 1323 /* we always have VBUS */ 1324 sc->sc_flags.status_vbus = 1; 1325 1326 /* reset the chip */ 1327 USS820_WRITE_1(sc, USS820_SCR, USS820_SCR_SRESET); 1328 DELAY(100); 1329 USS820_WRITE_1(sc, USS820_SCR, 0); 1330 1331 /* wait for reset to complete */ 1332 for (n = 0;; n++) { 1333 1334 temp = USS820_READ_1(sc, USS820_MCSR); 1335 1336 if (temp & USS820_MCSR_INIT) { 1337 break; 1338 } 1339 if (n == 100) { 1340 USB_BUS_UNLOCK(&sc->sc_bus); 1341 return (USB_ERR_INVAL); 1342 } 1343 /* wait a little for things to stabilise */ 1344 DELAY(100); 1345 } 1346 1347 /* do a pulldown */ 1348 uss820dci_pull_down(sc); 1349 1350 /* wait 10ms for pulldown to stabilise */ 1351 usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100); 1352 1353 /* check hardware revision */ 1354 temp = USS820_READ_1(sc, USS820_REV); 1355 1356 if (temp < 0x13) { 1357 USB_BUS_UNLOCK(&sc->sc_bus); 1358 return (USB_ERR_INVAL); 1359 } 1360 /* enable interrupts */ 1361 USS820_WRITE_1(sc, USS820_SCR, 1362 USS820_SCR_T_IRQ | 1363 USS820_SCR_IE_RESET | 1364 /* USS820_SCR_RWUPE | */ 1365 USS820_SCR_IE_SUSP | 1366 USS820_SCR_IRQPOL); 1367 1368 /* enable interrupts */ 1369 USS820_WRITE_1(sc, USS820_SCRATCH, 1370 USS820_SCRATCH_IE_RESUME); 1371 1372 /* enable features */ 1373 USS820_WRITE_1(sc, USS820_MCSR, 1374 USS820_MCSR_BDFEAT | 1375 USS820_MCSR_FEAT); 1376 1377 sc->sc_flags.mcsr_feat = 1; 1378 1379 /* disable interrupts */ 1380 USS820_WRITE_1(sc, USS820_SBIE, 0); 1381 1382 /* disable interrupts */ 1383 USS820_WRITE_1(sc, USS820_SBIE1, 0); 1384 1385 /* disable all endpoints */ 1386 for (n = 0; n != USS820_EP_MAX; n++) { 1387 1388 /* select endpoint */ 1389 USS820_WRITE_1(sc, USS820_EPINDEX, n); 1390 1391 /* disable endpoint */ 1392 uss820dci_update_shared_1(sc, USS820_EPCON, 0, 0); 1393 } 1394 1395 /* 1396 * Initialise default values for some registers that cannot be 1397 * changed during operation! 1398 */ 1399 for (n = 0; n != USS820_EP_MAX; n++) { 1400 1401 uss820dci_get_hw_ep_profile(NULL, &pf, n); 1402 1403 /* the maximum frame sizes should be the same */ 1404 if (pf->max_in_frame_size != pf->max_out_frame_size) { 1405 DPRINTF("Max frame size mismatch %u != %u\n", 1406 pf->max_in_frame_size, pf->max_out_frame_size); 1407 } 1408 if (pf->support_isochronous) { 1409 if (pf->max_in_frame_size <= 64) { 1410 temp = (USS820_TXCON_FFSZ_16_64 | 1411 USS820_TXCON_TXISO | 1412 USS820_TXCON_ATM); 1413 } else if (pf->max_in_frame_size <= 256) { 1414 temp = (USS820_TXCON_FFSZ_64_256 | 1415 USS820_TXCON_TXISO | 1416 USS820_TXCON_ATM); 1417 } else if (pf->max_in_frame_size <= 512) { 1418 temp = (USS820_TXCON_FFSZ_8_512 | 1419 USS820_TXCON_TXISO | 1420 USS820_TXCON_ATM); 1421 } else { /* 1024 bytes */ 1422 temp = (USS820_TXCON_FFSZ_32_1024 | 1423 USS820_TXCON_TXISO | 1424 USS820_TXCON_ATM); 1425 } 1426 } else { 1427 if ((pf->max_in_frame_size <= 8) && 1428 (sc->sc_flags.mcsr_feat)) { 1429 temp = (USS820_TXCON_FFSZ_8_512 | 1430 USS820_TXCON_ATM); 1431 } else if (pf->max_in_frame_size <= 16) { 1432 temp = (USS820_TXCON_FFSZ_16_64 | 1433 USS820_TXCON_ATM); 1434 } else if ((pf->max_in_frame_size <= 32) && 1435 (sc->sc_flags.mcsr_feat)) { 1436 temp = (USS820_TXCON_FFSZ_32_1024 | 1437 USS820_TXCON_ATM); 1438 } else { /* 64 bytes */ 1439 temp = (USS820_TXCON_FFSZ_64_256 | 1440 USS820_TXCON_ATM); 1441 } 1442 } 1443 1444 /* need to configure the chip early */ 1445 1446 USS820_WRITE_1(sc, USS820_EPINDEX, n); 1447 USS820_WRITE_1(sc, USS820_TXCON, temp); 1448 USS820_WRITE_1(sc, USS820_RXCON, temp); 1449 1450 if (pf->support_control) { 1451 temp = USS820_EPCON_CTLEP | 1452 USS820_EPCON_RXSPM | 1453 USS820_EPCON_RXIE | 1454 USS820_EPCON_RXEPEN | 1455 USS820_EPCON_TXOE | 1456 USS820_EPCON_TXEPEN; 1457 } else { 1458 temp = USS820_EPCON_RXEPEN | USS820_EPCON_TXEPEN; 1459 } 1460 1461 uss820dci_update_shared_1(sc, USS820_EPCON, 0xFF, temp); 1462 } 1463 1464 USB_BUS_UNLOCK(&sc->sc_bus); 1465 1466 /* catch any lost interrupts */ 1467 1468 uss820dci_do_poll(&sc->sc_bus); 1469 1470 return (0); /* success */ 1471 } 1472 1473 void 1474 uss820dci_uninit(struct uss820dci_softc *sc) 1475 { 1476 uint8_t temp; 1477 1478 USB_BUS_LOCK(&sc->sc_bus); 1479 1480 /* disable all interrupts */ 1481 temp = USS820_READ_1(sc, USS820_SCR); 1482 temp &= ~USS820_SCR_T_IRQ; 1483 USS820_WRITE_1(sc, USS820_SCR, temp); 1484 1485 sc->sc_flags.port_powered = 0; 1486 sc->sc_flags.status_vbus = 0; 1487 sc->sc_flags.status_bus_reset = 0; 1488 sc->sc_flags.status_suspend = 0; 1489 sc->sc_flags.change_suspend = 0; 1490 sc->sc_flags.change_connect = 1; 1491 1492 uss820dci_pull_down(sc); 1493 USB_BUS_UNLOCK(&sc->sc_bus); 1494 } 1495 1496 void 1497 uss820dci_suspend(struct uss820dci_softc *sc) 1498 { 1499 return; 1500 } 1501 1502 void 1503 uss820dci_resume(struct uss820dci_softc *sc) 1504 { 1505 return; 1506 } 1507 1508 static void 1509 uss820dci_do_poll(struct usb2_bus *bus) 1510 { 1511 struct uss820dci_softc *sc = USS820_DCI_BUS2SC(bus); 1512 1513 USB_BUS_LOCK(&sc->sc_bus); 1514 uss820dci_interrupt_poll(sc); 1515 uss820dci_root_ctrl_poll(sc); 1516 USB_BUS_UNLOCK(&sc->sc_bus); 1517 } 1518 1519 /*------------------------------------------------------------------------* 1520 * at91dci bulk support 1521 *------------------------------------------------------------------------*/ 1522 static void 1523 uss820dci_device_bulk_open(struct usb2_xfer *xfer) 1524 { 1525 return; 1526 } 1527 1528 static void 1529 uss820dci_device_bulk_close(struct usb2_xfer *xfer) 1530 { 1531 uss820dci_device_done(xfer, USB_ERR_CANCELLED); 1532 } 1533 1534 static void 1535 uss820dci_device_bulk_enter(struct usb2_xfer *xfer) 1536 { 1537 return; 1538 } 1539 1540 static void 1541 uss820dci_device_bulk_start(struct usb2_xfer *xfer) 1542 { 1543 /* setup TDs */ 1544 uss820dci_setup_standard_chain(xfer); 1545 uss820dci_start_standard_chain(xfer); 1546 } 1547 1548 struct usb2_pipe_methods uss820dci_device_bulk_methods = 1549 { 1550 .open = uss820dci_device_bulk_open, 1551 .close = uss820dci_device_bulk_close, 1552 .enter = uss820dci_device_bulk_enter, 1553 .start = uss820dci_device_bulk_start, 1554 .enter_is_cancelable = 1, 1555 .start_is_cancelable = 1, 1556 }; 1557 1558 /*------------------------------------------------------------------------* 1559 * at91dci control support 1560 *------------------------------------------------------------------------*/ 1561 static void 1562 uss820dci_device_ctrl_open(struct usb2_xfer *xfer) 1563 { 1564 return; 1565 } 1566 1567 static void 1568 uss820dci_device_ctrl_close(struct usb2_xfer *xfer) 1569 { 1570 uss820dci_device_done(xfer, USB_ERR_CANCELLED); 1571 } 1572 1573 static void 1574 uss820dci_device_ctrl_enter(struct usb2_xfer *xfer) 1575 { 1576 return; 1577 } 1578 1579 static void 1580 uss820dci_device_ctrl_start(struct usb2_xfer *xfer) 1581 { 1582 /* setup TDs */ 1583 uss820dci_setup_standard_chain(xfer); 1584 uss820dci_start_standard_chain(xfer); 1585 } 1586 1587 struct usb2_pipe_methods uss820dci_device_ctrl_methods = 1588 { 1589 .open = uss820dci_device_ctrl_open, 1590 .close = uss820dci_device_ctrl_close, 1591 .enter = uss820dci_device_ctrl_enter, 1592 .start = uss820dci_device_ctrl_start, 1593 .enter_is_cancelable = 1, 1594 .start_is_cancelable = 1, 1595 }; 1596 1597 /*------------------------------------------------------------------------* 1598 * at91dci interrupt support 1599 *------------------------------------------------------------------------*/ 1600 static void 1601 uss820dci_device_intr_open(struct usb2_xfer *xfer) 1602 { 1603 return; 1604 } 1605 1606 static void 1607 uss820dci_device_intr_close(struct usb2_xfer *xfer) 1608 { 1609 uss820dci_device_done(xfer, USB_ERR_CANCELLED); 1610 } 1611 1612 static void 1613 uss820dci_device_intr_enter(struct usb2_xfer *xfer) 1614 { 1615 return; 1616 } 1617 1618 static void 1619 uss820dci_device_intr_start(struct usb2_xfer *xfer) 1620 { 1621 /* setup TDs */ 1622 uss820dci_setup_standard_chain(xfer); 1623 uss820dci_start_standard_chain(xfer); 1624 } 1625 1626 struct usb2_pipe_methods uss820dci_device_intr_methods = 1627 { 1628 .open = uss820dci_device_intr_open, 1629 .close = uss820dci_device_intr_close, 1630 .enter = uss820dci_device_intr_enter, 1631 .start = uss820dci_device_intr_start, 1632 .enter_is_cancelable = 1, 1633 .start_is_cancelable = 1, 1634 }; 1635 1636 /*------------------------------------------------------------------------* 1637 * at91dci full speed isochronous support 1638 *------------------------------------------------------------------------*/ 1639 static void 1640 uss820dci_device_isoc_fs_open(struct usb2_xfer *xfer) 1641 { 1642 return; 1643 } 1644 1645 static void 1646 uss820dci_device_isoc_fs_close(struct usb2_xfer *xfer) 1647 { 1648 uss820dci_device_done(xfer, USB_ERR_CANCELLED); 1649 } 1650 1651 static void 1652 uss820dci_device_isoc_fs_enter(struct usb2_xfer *xfer) 1653 { 1654 struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); 1655 uint32_t temp; 1656 uint32_t nframes; 1657 1658 DPRINTFN(6, "xfer=%p next=%d nframes=%d\n", 1659 xfer, xfer->pipe->isoc_next, xfer->nframes); 1660 1661 /* get the current frame index - we don't need the high bits */ 1662 1663 nframes = USS820_READ_1(sc, USS820_SOFL); 1664 1665 /* 1666 * check if the frame index is within the window where the 1667 * frames will be inserted 1668 */ 1669 temp = (nframes - xfer->pipe->isoc_next) & USS820_SOFL_MASK; 1670 1671 if ((xfer->pipe->is_synced == 0) || 1672 (temp < xfer->nframes)) { 1673 /* 1674 * If there is data underflow or the pipe queue is 1675 * empty we schedule the transfer a few frames ahead 1676 * of the current frame position. Else two isochronous 1677 * transfers might overlap. 1678 */ 1679 xfer->pipe->isoc_next = (nframes + 3) & USS820_SOFL_MASK; 1680 xfer->pipe->is_synced = 1; 1681 DPRINTFN(3, "start next=%d\n", xfer->pipe->isoc_next); 1682 } 1683 /* 1684 * compute how many milliseconds the insertion is ahead of the 1685 * current frame position: 1686 */ 1687 temp = (xfer->pipe->isoc_next - nframes) & USS820_SOFL_MASK; 1688 1689 /* 1690 * pre-compute when the isochronous transfer will be finished: 1691 */ 1692 xfer->isoc_time_complete = 1693 usb2_isoc_time_expand(&sc->sc_bus, nframes) + temp + 1694 xfer->nframes; 1695 1696 /* compute frame number for next insertion */ 1697 xfer->pipe->isoc_next += xfer->nframes; 1698 1699 /* setup TDs */ 1700 uss820dci_setup_standard_chain(xfer); 1701 } 1702 1703 static void 1704 uss820dci_device_isoc_fs_start(struct usb2_xfer *xfer) 1705 { 1706 /* start TD chain */ 1707 uss820dci_start_standard_chain(xfer); 1708 } 1709 1710 struct usb2_pipe_methods uss820dci_device_isoc_fs_methods = 1711 { 1712 .open = uss820dci_device_isoc_fs_open, 1713 .close = uss820dci_device_isoc_fs_close, 1714 .enter = uss820dci_device_isoc_fs_enter, 1715 .start = uss820dci_device_isoc_fs_start, 1716 .enter_is_cancelable = 1, 1717 .start_is_cancelable = 1, 1718 }; 1719 1720 /*------------------------------------------------------------------------* 1721 * at91dci root control support 1722 *------------------------------------------------------------------------* 1723 * simulate a hardware HUB by handling 1724 * all the necessary requests 1725 *------------------------------------------------------------------------*/ 1726 1727 static void 1728 uss820dci_root_ctrl_open(struct usb2_xfer *xfer) 1729 { 1730 return; 1731 } 1732 1733 static void 1734 uss820dci_root_ctrl_close(struct usb2_xfer *xfer) 1735 { 1736 struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); 1737 1738 if (sc->sc_root_ctrl.xfer == xfer) { 1739 sc->sc_root_ctrl.xfer = NULL; 1740 } 1741 uss820dci_device_done(xfer, USB_ERR_CANCELLED); 1742 } 1743 1744 /* 1745 * USB descriptors for the virtual Root HUB: 1746 */ 1747 1748 static const struct usb2_device_descriptor uss820dci_devd = { 1749 .bLength = sizeof(struct usb2_device_descriptor), 1750 .bDescriptorType = UDESC_DEVICE, 1751 .bcdUSB = {0x00, 0x02}, 1752 .bDeviceClass = UDCLASS_HUB, 1753 .bDeviceSubClass = UDSUBCLASS_HUB, 1754 .bDeviceProtocol = UDPROTO_HSHUBSTT, 1755 .bMaxPacketSize = 64, 1756 .bcdDevice = {0x00, 0x01}, 1757 .iManufacturer = 1, 1758 .iProduct = 2, 1759 .bNumConfigurations = 1, 1760 }; 1761 1762 static const struct usb2_device_qualifier uss820dci_odevd = { 1763 .bLength = sizeof(struct usb2_device_qualifier), 1764 .bDescriptorType = UDESC_DEVICE_QUALIFIER, 1765 .bcdUSB = {0x00, 0x02}, 1766 .bDeviceClass = UDCLASS_HUB, 1767 .bDeviceSubClass = UDSUBCLASS_HUB, 1768 .bDeviceProtocol = UDPROTO_FSHUB, 1769 .bMaxPacketSize0 = 0, 1770 .bNumConfigurations = 0, 1771 }; 1772 1773 static const struct uss820dci_config_desc uss820dci_confd = { 1774 .confd = { 1775 .bLength = sizeof(struct usb2_config_descriptor), 1776 .bDescriptorType = UDESC_CONFIG, 1777 .wTotalLength[0] = sizeof(uss820dci_confd), 1778 .bNumInterface = 1, 1779 .bConfigurationValue = 1, 1780 .iConfiguration = 0, 1781 .bmAttributes = UC_SELF_POWERED, 1782 .bMaxPower = 0, 1783 }, 1784 .ifcd = { 1785 .bLength = sizeof(struct usb2_interface_descriptor), 1786 .bDescriptorType = UDESC_INTERFACE, 1787 .bNumEndpoints = 1, 1788 .bInterfaceClass = UICLASS_HUB, 1789 .bInterfaceSubClass = UISUBCLASS_HUB, 1790 .bInterfaceProtocol = UIPROTO_HSHUBSTT, 1791 }, 1792 1793 .endpd = { 1794 .bLength = sizeof(struct usb2_endpoint_descriptor), 1795 .bDescriptorType = UDESC_ENDPOINT, 1796 .bEndpointAddress = (UE_DIR_IN | USS820_DCI_INTR_ENDPT), 1797 .bmAttributes = UE_INTERRUPT, 1798 .wMaxPacketSize[0] = 8, 1799 .bInterval = 255, 1800 }, 1801 }; 1802 1803 static const struct usb2_hub_descriptor_min uss820dci_hubd = { 1804 .bDescLength = sizeof(uss820dci_hubd), 1805 .bDescriptorType = UDESC_HUB, 1806 .bNbrPorts = 1, 1807 .wHubCharacteristics[0] = 1808 (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF, 1809 .wHubCharacteristics[1] = 1810 (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 8, 1811 .bPwrOn2PwrGood = 50, 1812 .bHubContrCurrent = 0, 1813 .DeviceRemovable = {0}, /* port is removable */ 1814 }; 1815 1816 #define STRING_LANG \ 1817 0x09, 0x04, /* American English */ 1818 1819 #define STRING_VENDOR \ 1820 'A', 0, 'G', 0, 'E', 0, 'R', 0, 'E', 0 1821 1822 #define STRING_PRODUCT \ 1823 'D', 0, 'C', 0, 'I', 0, ' ', 0, 'R', 0, \ 1824 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \ 1825 'U', 0, 'B', 0, 1826 1827 USB_MAKE_STRING_DESC(STRING_LANG, uss820dci_langtab); 1828 USB_MAKE_STRING_DESC(STRING_VENDOR, uss820dci_vendor); 1829 USB_MAKE_STRING_DESC(STRING_PRODUCT, uss820dci_product); 1830 1831 static void 1832 uss820dci_root_ctrl_enter(struct usb2_xfer *xfer) 1833 { 1834 return; 1835 } 1836 1837 static void 1838 uss820dci_root_ctrl_start(struct usb2_xfer *xfer) 1839 { 1840 struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); 1841 1842 sc->sc_root_ctrl.xfer = xfer; 1843 1844 usb2_bus_roothub_exec(xfer->xroot->bus); 1845 } 1846 1847 static void 1848 uss820dci_root_ctrl_task(struct usb2_bus *bus) 1849 { 1850 uss820dci_root_ctrl_poll(USS820_DCI_BUS2SC(bus)); 1851 } 1852 1853 static void 1854 uss820dci_root_ctrl_done(struct usb2_xfer *xfer, 1855 struct usb2_sw_transfer *std) 1856 { 1857 struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); 1858 uint16_t value; 1859 uint16_t index; 1860 1861 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); 1862 1863 if (std->state != USB_SW_TR_SETUP) { 1864 if (std->state == USB_SW_TR_PRE_CALLBACK) { 1865 /* transfer transferred */ 1866 uss820dci_device_done(xfer, std->err); 1867 } 1868 goto done; 1869 } 1870 /* buffer reset */ 1871 std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0); 1872 std->len = 0; 1873 1874 value = UGETW(std->req.wValue); 1875 index = UGETW(std->req.wIndex); 1876 1877 /* demultiplex the control request */ 1878 1879 switch (std->req.bmRequestType) { 1880 case UT_READ_DEVICE: 1881 switch (std->req.bRequest) { 1882 case UR_GET_DESCRIPTOR: 1883 goto tr_handle_get_descriptor; 1884 case UR_GET_CONFIG: 1885 goto tr_handle_get_config; 1886 case UR_GET_STATUS: 1887 goto tr_handle_get_status; 1888 default: 1889 goto tr_stalled; 1890 } 1891 break; 1892 1893 case UT_WRITE_DEVICE: 1894 switch (std->req.bRequest) { 1895 case UR_SET_ADDRESS: 1896 goto tr_handle_set_address; 1897 case UR_SET_CONFIG: 1898 goto tr_handle_set_config; 1899 case UR_CLEAR_FEATURE: 1900 goto tr_valid; /* nop */ 1901 case UR_SET_DESCRIPTOR: 1902 goto tr_valid; /* nop */ 1903 case UR_SET_FEATURE: 1904 default: 1905 goto tr_stalled; 1906 } 1907 break; 1908 1909 case UT_WRITE_ENDPOINT: 1910 switch (std->req.bRequest) { 1911 case UR_CLEAR_FEATURE: 1912 switch (UGETW(std->req.wValue)) { 1913 case UF_ENDPOINT_HALT: 1914 goto tr_handle_clear_halt; 1915 case UF_DEVICE_REMOTE_WAKEUP: 1916 goto tr_handle_clear_wakeup; 1917 default: 1918 goto tr_stalled; 1919 } 1920 break; 1921 case UR_SET_FEATURE: 1922 switch (UGETW(std->req.wValue)) { 1923 case UF_ENDPOINT_HALT: 1924 goto tr_handle_set_halt; 1925 case UF_DEVICE_REMOTE_WAKEUP: 1926 goto tr_handle_set_wakeup; 1927 default: 1928 goto tr_stalled; 1929 } 1930 break; 1931 case UR_SYNCH_FRAME: 1932 goto tr_valid; /* nop */ 1933 default: 1934 goto tr_stalled; 1935 } 1936 break; 1937 1938 case UT_READ_ENDPOINT: 1939 switch (std->req.bRequest) { 1940 case UR_GET_STATUS: 1941 goto tr_handle_get_ep_status; 1942 default: 1943 goto tr_stalled; 1944 } 1945 break; 1946 1947 case UT_WRITE_INTERFACE: 1948 switch (std->req.bRequest) { 1949 case UR_SET_INTERFACE: 1950 goto tr_handle_set_interface; 1951 case UR_CLEAR_FEATURE: 1952 goto tr_valid; /* nop */ 1953 case UR_SET_FEATURE: 1954 default: 1955 goto tr_stalled; 1956 } 1957 break; 1958 1959 case UT_READ_INTERFACE: 1960 switch (std->req.bRequest) { 1961 case UR_GET_INTERFACE: 1962 goto tr_handle_get_interface; 1963 case UR_GET_STATUS: 1964 goto tr_handle_get_iface_status; 1965 default: 1966 goto tr_stalled; 1967 } 1968 break; 1969 1970 case UT_WRITE_CLASS_INTERFACE: 1971 case UT_WRITE_VENDOR_INTERFACE: 1972 /* XXX forward */ 1973 break; 1974 1975 case UT_READ_CLASS_INTERFACE: 1976 case UT_READ_VENDOR_INTERFACE: 1977 /* XXX forward */ 1978 break; 1979 1980 case UT_WRITE_CLASS_DEVICE: 1981 switch (std->req.bRequest) { 1982 case UR_CLEAR_FEATURE: 1983 goto tr_valid; 1984 case UR_SET_DESCRIPTOR: 1985 case UR_SET_FEATURE: 1986 break; 1987 default: 1988 goto tr_stalled; 1989 } 1990 break; 1991 1992 case UT_WRITE_CLASS_OTHER: 1993 switch (std->req.bRequest) { 1994 case UR_CLEAR_FEATURE: 1995 goto tr_handle_clear_port_feature; 1996 case UR_SET_FEATURE: 1997 goto tr_handle_set_port_feature; 1998 case UR_CLEAR_TT_BUFFER: 1999 case UR_RESET_TT: 2000 case UR_STOP_TT: 2001 goto tr_valid; 2002 2003 default: 2004 goto tr_stalled; 2005 } 2006 break; 2007 2008 case UT_READ_CLASS_OTHER: 2009 switch (std->req.bRequest) { 2010 case UR_GET_TT_STATE: 2011 goto tr_handle_get_tt_state; 2012 case UR_GET_STATUS: 2013 goto tr_handle_get_port_status; 2014 default: 2015 goto tr_stalled; 2016 } 2017 break; 2018 2019 case UT_READ_CLASS_DEVICE: 2020 switch (std->req.bRequest) { 2021 case UR_GET_DESCRIPTOR: 2022 goto tr_handle_get_class_descriptor; 2023 case UR_GET_STATUS: 2024 goto tr_handle_get_class_status; 2025 2026 default: 2027 goto tr_stalled; 2028 } 2029 break; 2030 default: 2031 goto tr_stalled; 2032 } 2033 goto tr_valid; 2034 2035 tr_handle_get_descriptor: 2036 switch (value >> 8) { 2037 case UDESC_DEVICE: 2038 if (value & 0xff) { 2039 goto tr_stalled; 2040 } 2041 std->len = sizeof(uss820dci_devd); 2042 std->ptr = USB_ADD_BYTES(&uss820dci_devd, 0); 2043 goto tr_valid; 2044 case UDESC_CONFIG: 2045 if (value & 0xff) { 2046 goto tr_stalled; 2047 } 2048 std->len = sizeof(uss820dci_confd); 2049 std->ptr = USB_ADD_BYTES(&uss820dci_confd, 0); 2050 goto tr_valid; 2051 case UDESC_STRING: 2052 switch (value & 0xff) { 2053 case 0: /* Language table */ 2054 std->len = sizeof(uss820dci_langtab); 2055 std->ptr = USB_ADD_BYTES(&uss820dci_langtab, 0); 2056 goto tr_valid; 2057 2058 case 1: /* Vendor */ 2059 std->len = sizeof(uss820dci_vendor); 2060 std->ptr = USB_ADD_BYTES(&uss820dci_vendor, 0); 2061 goto tr_valid; 2062 2063 case 2: /* Product */ 2064 std->len = sizeof(uss820dci_product); 2065 std->ptr = USB_ADD_BYTES(&uss820dci_product, 0); 2066 goto tr_valid; 2067 default: 2068 break; 2069 } 2070 break; 2071 default: 2072 goto tr_stalled; 2073 } 2074 goto tr_stalled; 2075 2076 tr_handle_get_config: 2077 std->len = 1; 2078 sc->sc_hub_temp.wValue[0] = sc->sc_conf; 2079 goto tr_valid; 2080 2081 tr_handle_get_status: 2082 std->len = 2; 2083 USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED); 2084 goto tr_valid; 2085 2086 tr_handle_set_address: 2087 if (value & 0xFF00) { 2088 goto tr_stalled; 2089 } 2090 sc->sc_rt_addr = value; 2091 goto tr_valid; 2092 2093 tr_handle_set_config: 2094 if (value >= 2) { 2095 goto tr_stalled; 2096 } 2097 sc->sc_conf = value; 2098 goto tr_valid; 2099 2100 tr_handle_get_interface: 2101 std->len = 1; 2102 sc->sc_hub_temp.wValue[0] = 0; 2103 goto tr_valid; 2104 2105 tr_handle_get_tt_state: 2106 tr_handle_get_class_status: 2107 tr_handle_get_iface_status: 2108 tr_handle_get_ep_status: 2109 std->len = 2; 2110 USETW(sc->sc_hub_temp.wValue, 0); 2111 goto tr_valid; 2112 2113 tr_handle_set_halt: 2114 tr_handle_set_interface: 2115 tr_handle_set_wakeup: 2116 tr_handle_clear_wakeup: 2117 tr_handle_clear_halt: 2118 goto tr_valid; 2119 2120 tr_handle_clear_port_feature: 2121 if (index != 1) { 2122 goto tr_stalled; 2123 } 2124 DPRINTFN(9, "UR_CLEAR_PORT_FEATURE on port %d\n", index); 2125 2126 switch (value) { 2127 case UHF_PORT_SUSPEND: 2128 uss820dci_wakeup_peer(sc); 2129 break; 2130 2131 case UHF_PORT_ENABLE: 2132 sc->sc_flags.port_enabled = 0; 2133 break; 2134 2135 case UHF_PORT_TEST: 2136 case UHF_PORT_INDICATOR: 2137 case UHF_C_PORT_ENABLE: 2138 case UHF_C_PORT_OVER_CURRENT: 2139 case UHF_C_PORT_RESET: 2140 /* nops */ 2141 break; 2142 case UHF_PORT_POWER: 2143 sc->sc_flags.port_powered = 0; 2144 uss820dci_pull_down(sc); 2145 break; 2146 case UHF_C_PORT_CONNECTION: 2147 sc->sc_flags.change_connect = 0; 2148 break; 2149 case UHF_C_PORT_SUSPEND: 2150 sc->sc_flags.change_suspend = 0; 2151 break; 2152 default: 2153 std->err = USB_ERR_IOERROR; 2154 goto done; 2155 } 2156 goto tr_valid; 2157 2158 tr_handle_set_port_feature: 2159 if (index != 1) { 2160 goto tr_stalled; 2161 } 2162 DPRINTFN(9, "UR_SET_PORT_FEATURE\n"); 2163 2164 switch (value) { 2165 case UHF_PORT_ENABLE: 2166 sc->sc_flags.port_enabled = 1; 2167 break; 2168 case UHF_PORT_SUSPEND: 2169 case UHF_PORT_RESET: 2170 case UHF_PORT_TEST: 2171 case UHF_PORT_INDICATOR: 2172 /* nops */ 2173 break; 2174 case UHF_PORT_POWER: 2175 sc->sc_flags.port_powered = 1; 2176 break; 2177 default: 2178 std->err = USB_ERR_IOERROR; 2179 goto done; 2180 } 2181 goto tr_valid; 2182 2183 tr_handle_get_port_status: 2184 2185 DPRINTFN(9, "UR_GET_PORT_STATUS\n"); 2186 2187 if (index != 1) { 2188 goto tr_stalled; 2189 } 2190 if (sc->sc_flags.status_vbus) { 2191 uss820dci_pull_up(sc); 2192 } else { 2193 uss820dci_pull_down(sc); 2194 } 2195 2196 /* Select FULL-speed and Device Side Mode */ 2197 2198 value = UPS_PORT_MODE_DEVICE; 2199 2200 if (sc->sc_flags.port_powered) { 2201 value |= UPS_PORT_POWER; 2202 } 2203 if (sc->sc_flags.port_enabled) { 2204 value |= UPS_PORT_ENABLED; 2205 } 2206 if (sc->sc_flags.status_vbus && 2207 sc->sc_flags.status_bus_reset) { 2208 value |= UPS_CURRENT_CONNECT_STATUS; 2209 } 2210 if (sc->sc_flags.status_suspend) { 2211 value |= UPS_SUSPEND; 2212 } 2213 USETW(sc->sc_hub_temp.ps.wPortStatus, value); 2214 2215 value = 0; 2216 2217 if (sc->sc_flags.change_connect) { 2218 value |= UPS_C_CONNECT_STATUS; 2219 } 2220 if (sc->sc_flags.change_suspend) { 2221 value |= UPS_C_SUSPEND; 2222 } 2223 USETW(sc->sc_hub_temp.ps.wPortChange, value); 2224 std->len = sizeof(sc->sc_hub_temp.ps); 2225 goto tr_valid; 2226 2227 tr_handle_get_class_descriptor: 2228 if (value & 0xFF) { 2229 goto tr_stalled; 2230 } 2231 std->ptr = USB_ADD_BYTES(&uss820dci_hubd, 0); 2232 std->len = sizeof(uss820dci_hubd); 2233 goto tr_valid; 2234 2235 tr_stalled: 2236 std->err = USB_ERR_STALLED; 2237 tr_valid: 2238 done: 2239 return; 2240 } 2241 2242 static void 2243 uss820dci_root_ctrl_poll(struct uss820dci_softc *sc) 2244 { 2245 usb2_sw_transfer(&sc->sc_root_ctrl, 2246 &uss820dci_root_ctrl_done); 2247 } 2248 2249 struct usb2_pipe_methods uss820dci_root_ctrl_methods = 2250 { 2251 .open = uss820dci_root_ctrl_open, 2252 .close = uss820dci_root_ctrl_close, 2253 .enter = uss820dci_root_ctrl_enter, 2254 .start = uss820dci_root_ctrl_start, 2255 .enter_is_cancelable = 1, 2256 .start_is_cancelable = 0, 2257 }; 2258 2259 /*------------------------------------------------------------------------* 2260 * at91dci root interrupt support 2261 *------------------------------------------------------------------------*/ 2262 static void 2263 uss820dci_root_intr_open(struct usb2_xfer *xfer) 2264 { 2265 return; 2266 } 2267 2268 static void 2269 uss820dci_root_intr_close(struct usb2_xfer *xfer) 2270 { 2271 struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); 2272 2273 if (sc->sc_root_intr.xfer == xfer) { 2274 sc->sc_root_intr.xfer = NULL; 2275 } 2276 uss820dci_device_done(xfer, USB_ERR_CANCELLED); 2277 } 2278 2279 static void 2280 uss820dci_root_intr_enter(struct usb2_xfer *xfer) 2281 { 2282 return; 2283 } 2284 2285 static void 2286 uss820dci_root_intr_start(struct usb2_xfer *xfer) 2287 { 2288 struct uss820dci_softc *sc = USS820_DCI_BUS2SC(xfer->xroot->bus); 2289 2290 sc->sc_root_intr.xfer = xfer; 2291 } 2292 2293 struct usb2_pipe_methods uss820dci_root_intr_methods = 2294 { 2295 .open = uss820dci_root_intr_open, 2296 .close = uss820dci_root_intr_close, 2297 .enter = uss820dci_root_intr_enter, 2298 .start = uss820dci_root_intr_start, 2299 .enter_is_cancelable = 1, 2300 .start_is_cancelable = 1, 2301 }; 2302 2303 static void 2304 uss820dci_xfer_setup(struct usb2_setup_params *parm) 2305 { 2306 const struct usb2_hw_ep_profile *pf; 2307 struct uss820dci_softc *sc; 2308 struct usb2_xfer *xfer; 2309 void *last_obj; 2310 uint32_t ntd; 2311 uint32_t n; 2312 uint8_t ep_no; 2313 2314 sc = USS820_DCI_BUS2SC(parm->udev->bus); 2315 xfer = parm->curr_xfer; 2316 2317 /* 2318 * NOTE: This driver does not use any of the parameters that 2319 * are computed from the following values. Just set some 2320 * reasonable dummies: 2321 */ 2322 parm->hc_max_packet_size = 0x500; 2323 parm->hc_max_packet_count = 1; 2324 parm->hc_max_frame_size = 0x500; 2325 2326 usb2_transfer_setup_sub(parm); 2327 2328 /* 2329 * compute maximum number of TDs 2330 */ 2331 if (parm->methods == &uss820dci_device_ctrl_methods) { 2332 2333 ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ; 2334 2335 } else if (parm->methods == &uss820dci_device_bulk_methods) { 2336 2337 ntd = xfer->nframes + 1 /* SYNC */ ; 2338 2339 } else if (parm->methods == &uss820dci_device_intr_methods) { 2340 2341 ntd = xfer->nframes + 1 /* SYNC */ ; 2342 2343 } else if (parm->methods == &uss820dci_device_isoc_fs_methods) { 2344 2345 ntd = xfer->nframes + 1 /* SYNC */ ; 2346 2347 } else { 2348 2349 ntd = 0; 2350 } 2351 2352 /* 2353 * check if "usb2_transfer_setup_sub" set an error 2354 */ 2355 if (parm->err) { 2356 return; 2357 } 2358 /* 2359 * allocate transfer descriptors 2360 */ 2361 last_obj = NULL; 2362 2363 /* 2364 * get profile stuff 2365 */ 2366 if (ntd) { 2367 2368 ep_no = xfer->endpoint & UE_ADDR; 2369 uss820dci_get_hw_ep_profile(parm->udev, &pf, ep_no); 2370 2371 if (pf == NULL) { 2372 /* should not happen */ 2373 parm->err = USB_ERR_INVAL; 2374 return; 2375 } 2376 } else { 2377 ep_no = 0; 2378 pf = NULL; 2379 } 2380 2381 /* align data */ 2382 parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1)); 2383 2384 for (n = 0; n != ntd; n++) { 2385 2386 struct uss820dci_td *td; 2387 2388 if (parm->buf) { 2389 2390 td = USB_ADD_BYTES(parm->buf, parm->size[0]); 2391 2392 /* init TD */ 2393 td->io_tag = sc->sc_io_tag; 2394 td->io_hdl = sc->sc_io_hdl; 2395 td->max_packet_size = xfer->max_packet_size; 2396 td->rx_stat_reg = USS820_GET_REG(sc, USS820_RXSTAT); 2397 td->tx_stat_reg = USS820_GET_REG(sc, USS820_TXSTAT); 2398 td->rx_flag_reg = USS820_GET_REG(sc, USS820_RXFLG); 2399 td->tx_flag_reg = USS820_GET_REG(sc, USS820_TXFLG); 2400 td->rx_fifo_reg = USS820_GET_REG(sc, USS820_RXDAT); 2401 td->tx_fifo_reg = USS820_GET_REG(sc, USS820_TXDAT); 2402 td->rx_count_low_reg = USS820_GET_REG(sc, USS820_RXCNTL); 2403 td->rx_count_high_reg = USS820_GET_REG(sc, USS820_RXCNTH); 2404 td->tx_count_low_reg = USS820_GET_REG(sc, USS820_TXCNTL); 2405 td->tx_count_high_reg = USS820_GET_REG(sc, USS820_TXCNTH); 2406 td->rx_cntl_reg = USS820_GET_REG(sc, USS820_RXCON); 2407 td->tx_cntl_reg = USS820_GET_REG(sc, USS820_TXCON); 2408 td->pend_reg = USS820_GET_REG(sc, USS820_PEND); 2409 td->ep_reg = USS820_GET_REG(sc, USS820_EPINDEX); 2410 td->ep_index = ep_no; 2411 if (pf->support_multi_buffer && 2412 (parm->methods != &uss820dci_device_ctrl_methods)) { 2413 td->support_multi_buffer = 1; 2414 } 2415 td->obj_next = last_obj; 2416 2417 last_obj = td; 2418 } 2419 parm->size[0] += sizeof(*td); 2420 } 2421 2422 xfer->td_start[0] = last_obj; 2423 } 2424 2425 static void 2426 uss820dci_xfer_unsetup(struct usb2_xfer *xfer) 2427 { 2428 return; 2429 } 2430 2431 static void 2432 uss820dci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc, 2433 struct usb2_pipe *pipe) 2434 { 2435 struct uss820dci_softc *sc = USS820_DCI_BUS2SC(udev->bus); 2436 2437 DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n", 2438 pipe, udev->address, 2439 edesc->bEndpointAddress, udev->flags.usb2_mode, 2440 sc->sc_rt_addr); 2441 2442 if (udev->device_index == sc->sc_rt_addr) { 2443 2444 if (udev->flags.usb2_mode != USB_MODE_HOST) { 2445 /* not supported */ 2446 return; 2447 } 2448 switch (edesc->bEndpointAddress) { 2449 case USB_CONTROL_ENDPOINT: 2450 pipe->methods = &uss820dci_root_ctrl_methods; 2451 break; 2452 case UE_DIR_IN | USS820_DCI_INTR_ENDPT: 2453 pipe->methods = &uss820dci_root_intr_methods; 2454 break; 2455 default: 2456 /* do nothing */ 2457 break; 2458 } 2459 } else { 2460 2461 if (udev->flags.usb2_mode != USB_MODE_DEVICE) { 2462 /* not supported */ 2463 return; 2464 } 2465 if (udev->speed != USB_SPEED_FULL) { 2466 /* not supported */ 2467 return; 2468 } 2469 switch (edesc->bmAttributes & UE_XFERTYPE) { 2470 case UE_CONTROL: 2471 pipe->methods = &uss820dci_device_ctrl_methods; 2472 break; 2473 case UE_INTERRUPT: 2474 pipe->methods = &uss820dci_device_intr_methods; 2475 break; 2476 case UE_ISOCHRONOUS: 2477 pipe->methods = &uss820dci_device_isoc_fs_methods; 2478 break; 2479 case UE_BULK: 2480 pipe->methods = &uss820dci_device_bulk_methods; 2481 break; 2482 default: 2483 /* do nothing */ 2484 break; 2485 } 2486 } 2487 } 2488 2489 struct usb2_bus_methods uss820dci_bus_methods = 2490 { 2491 .pipe_init = &uss820dci_pipe_init, 2492 .xfer_setup = &uss820dci_xfer_setup, 2493 .xfer_unsetup = &uss820dci_xfer_unsetup, 2494 .get_hw_ep_profile = &uss820dci_get_hw_ep_profile, 2495 .set_stall = &uss820dci_set_stall, 2496 .clear_stall = &uss820dci_clear_stall, 2497 .roothub_exec = &uss820dci_root_ctrl_task, 2498 }; 2499