1 /* $NetBSD: if_cdce.c,v 1.4 2004/10/24 12:50:54 augustss Exp $ */ 2 3 /*- 4 * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com> 5 * Copyright (c) 2003-2005 Craig Boston 6 * Copyright (c) 2004 Daniel Hartmeier 7 * Copyright (c) 2009 Hans Petter Selasky 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by Bill Paul. 21 * 4. Neither the name of the author nor the names of any co-contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul, THE VOICES IN HIS HEAD OR 29 * THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 32 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 /* 39 * USB Communication Device Class (Ethernet Networking Control Model) 40 * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf 41 */ 42 43 #include <sys/cdefs.h> 44 __FBSDID("$FreeBSD$"); 45 46 #include "usbdevs.h" 47 #include <dev/usb/usb.h> 48 #include <dev/usb/usb_mfunc.h> 49 #include <dev/usb/usb_error.h> 50 #include <dev/usb/usb_cdc.h> 51 52 #define USB_DEBUG_VAR cdce_debug 53 54 #include <dev/usb/usb_core.h> 55 #include <dev/usb/usb_lookup.h> 56 #include <dev/usb/usb_process.h> 57 #include <dev/usb/usb_debug.h> 58 #include <dev/usb/usb_request.h> 59 #include <dev/usb/usb_busdma.h> 60 #include <dev/usb/usb_util.h> 61 #include <dev/usb/usb_parse.h> 62 #include <dev/usb/usb_device.h> 63 64 #include <dev/usb/net/usb_ethernet.h> 65 #include <dev/usb/net/if_cdcereg.h> 66 67 static device_probe_t cdce_probe; 68 static device_attach_t cdce_attach; 69 static device_detach_t cdce_detach; 70 static device_suspend_t cdce_suspend; 71 static device_resume_t cdce_resume; 72 static usb_handle_request_t cdce_handle_request; 73 74 static usb2_callback_t cdce_bulk_write_callback; 75 static usb2_callback_t cdce_bulk_read_callback; 76 static usb2_callback_t cdce_intr_read_callback; 77 static usb2_callback_t cdce_intr_write_callback; 78 79 static usb2_ether_fn_t cdce_attach_post; 80 static usb2_ether_fn_t cdce_init; 81 static usb2_ether_fn_t cdce_stop; 82 static usb2_ether_fn_t cdce_start; 83 static usb2_ether_fn_t cdce_setmulti; 84 static usb2_ether_fn_t cdce_setpromisc; 85 86 static uint32_t cdce_m_crc32(struct mbuf *, uint32_t, uint32_t); 87 88 #if USB_DEBUG 89 static int cdce_debug = 0; 90 91 SYSCTL_NODE(_hw_usb2, OID_AUTO, cdce, CTLFLAG_RW, 0, "USB CDC-Ethernet"); 92 SYSCTL_INT(_hw_usb2_cdce, OID_AUTO, debug, CTLFLAG_RW, &cdce_debug, 0, 93 "Debug level"); 94 #endif 95 96 static const struct usb2_config cdce_config[CDCE_N_TRANSFER] = { 97 98 [CDCE_BULK_RX] = { 99 .type = UE_BULK, 100 .endpoint = UE_ADDR_ANY, 101 .direction = UE_DIR_RX, 102 .if_index = 0, 103 .frames = CDCE_FRAMES_MAX, 104 .bufsize = (CDCE_FRAMES_MAX * MCLBYTES), 105 .flags = {.pipe_bof = 1,.short_frames_ok = 1,.short_xfer_ok = 1,.ext_buffer = 1,}, 106 .callback = cdce_bulk_read_callback, 107 .timeout = 0, /* no timeout */ 108 .usb_mode = USB_MODE_MAX, /* both modes */ 109 }, 110 111 [CDCE_BULK_TX] = { 112 .type = UE_BULK, 113 .endpoint = UE_ADDR_ANY, 114 .direction = UE_DIR_TX, 115 .if_index = 0, 116 .frames = CDCE_FRAMES_MAX, 117 .bufsize = (CDCE_FRAMES_MAX * MCLBYTES), 118 .flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1,}, 119 .callback = cdce_bulk_write_callback, 120 .timeout = 10000, /* 10 seconds */ 121 .usb_mode = USB_MODE_MAX, /* both modes */ 122 }, 123 124 [CDCE_INTR_RX] = { 125 .type = UE_INTERRUPT, 126 .endpoint = UE_ADDR_ANY, 127 .direction = UE_DIR_RX, 128 .if_index = 1, 129 .bufsize = CDCE_IND_SIZE_MAX, 130 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,.no_pipe_ok = 1,}, 131 .callback = cdce_intr_read_callback, 132 .timeout = 0, 133 .usb_mode = USB_MODE_HOST, 134 }, 135 136 [CDCE_INTR_TX] = { 137 .type = UE_INTERRUPT, 138 .endpoint = UE_ADDR_ANY, 139 .direction = UE_DIR_TX, 140 .if_index = 1, 141 .bufsize = CDCE_IND_SIZE_MAX, 142 .flags = {.pipe_bof = 1,.force_short_xfer = 1,.no_pipe_ok = 1,}, 143 .callback = cdce_intr_write_callback, 144 .timeout = 10000, /* 10 seconds */ 145 .usb_mode = USB_MODE_DEVICE, 146 }, 147 }; 148 149 static device_method_t cdce_methods[] = { 150 /* USB interface */ 151 DEVMETHOD(usb_handle_request, cdce_handle_request), 152 153 /* Device interface */ 154 DEVMETHOD(device_probe, cdce_probe), 155 DEVMETHOD(device_attach, cdce_attach), 156 DEVMETHOD(device_detach, cdce_detach), 157 DEVMETHOD(device_suspend, cdce_suspend), 158 DEVMETHOD(device_resume, cdce_resume), 159 160 {0, 0} 161 }; 162 163 static driver_t cdce_driver = { 164 .name = "cdce", 165 .methods = cdce_methods, 166 .size = sizeof(struct cdce_softc), 167 }; 168 169 static devclass_t cdce_devclass; 170 171 DRIVER_MODULE(cdce, uhub, cdce_driver, cdce_devclass, NULL, 0); 172 MODULE_VERSION(cdce, 1); 173 MODULE_DEPEND(cdce, uether, 1, 1, 1); 174 MODULE_DEPEND(cdce, usb, 1, 1, 1); 175 MODULE_DEPEND(cdce, ether, 1, 1, 1); 176 177 static const struct usb2_ether_methods cdce_ue_methods = { 178 .ue_attach_post = cdce_attach_post, 179 .ue_start = cdce_start, 180 .ue_init = cdce_init, 181 .ue_stop = cdce_stop, 182 .ue_setmulti = cdce_setmulti, 183 .ue_setpromisc = cdce_setpromisc, 184 }; 185 186 static const struct usb2_device_id cdce_devs[] = { 187 {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, 0)}, 188 {USB_IF_CSI(UICLASS_CDC, UISUBCLASS_MOBILE_DIRECT_LINE_MODEL, 0)}, 189 190 {USB_VPI(USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632, CDCE_FLAG_NO_UNION)}, 191 {USB_VPI(USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250, CDCE_FLAG_NO_UNION)}, 192 {USB_VPI(USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX, CDCE_FLAG_NO_UNION)}, 193 {USB_VPI(USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00, CDCE_FLAG_NO_UNION)}, 194 {USB_VPI(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, 195 {USB_VPI(USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, 196 {USB_VPI(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_ETHERNETGADGET, CDCE_FLAG_NO_UNION)}, 197 {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501, CDCE_FLAG_NO_UNION)}, 198 {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500, CDCE_FLAG_ZAURUS)}, 199 {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, 200 {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLA300, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, 201 {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC700, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, 202 {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC750, CDCE_FLAG_ZAURUS | CDCE_FLAG_NO_UNION)}, 203 }; 204 205 static int 206 cdce_probe(device_t dev) 207 { 208 struct usb2_attach_arg *uaa = device_get_ivars(dev); 209 210 return (usb2_lookup_id_by_uaa(cdce_devs, sizeof(cdce_devs), uaa)); 211 } 212 213 static void 214 cdce_attach_post(struct usb2_ether *ue) 215 { 216 /* no-op */ 217 return; 218 } 219 220 static int 221 cdce_attach(device_t dev) 222 { 223 struct cdce_softc *sc = device_get_softc(dev); 224 struct usb2_ether *ue = &sc->sc_ue; 225 struct usb2_attach_arg *uaa = device_get_ivars(dev); 226 struct usb2_interface *iface; 227 const struct usb2_cdc_union_descriptor *ud; 228 const struct usb2_interface_descriptor *id; 229 const struct usb2_cdc_ethernet_descriptor *ued; 230 int error; 231 uint8_t i; 232 char eaddr_str[5 * ETHER_ADDR_LEN]; /* approx */ 233 234 sc->sc_flags = USB_GET_DRIVER_INFO(uaa); 235 236 device_set_usb2_desc(dev); 237 238 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); 239 240 if (sc->sc_flags & CDCE_FLAG_NO_UNION) { 241 sc->sc_ifaces_index[0] = uaa->info.bIfaceIndex; 242 sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex; 243 sc->sc_data_iface_no = 0; /* not used */ 244 goto alloc_transfers; 245 } 246 ud = usb2_find_descriptor 247 (uaa->device, NULL, uaa->info.bIfaceIndex, 248 UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_UNION, 0 - 1); 249 250 if ((ud == NULL) || (ud->bLength < sizeof(*ud))) { 251 device_printf(dev, "no union descriptor!\n"); 252 goto detach; 253 } 254 sc->sc_data_iface_no = ud->bSlaveInterface[0]; 255 256 for (i = 0;; i++) { 257 258 iface = usb2_get_iface(uaa->device, i); 259 260 if (iface) { 261 262 id = usb2_get_interface_descriptor(iface); 263 264 if (id && (id->bInterfaceNumber == 265 sc->sc_data_iface_no)) { 266 sc->sc_ifaces_index[0] = i; 267 sc->sc_ifaces_index[1] = uaa->info.bIfaceIndex; 268 usb2_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex); 269 break; 270 } 271 } else { 272 device_printf(dev, "no data interface found!\n"); 273 goto detach; 274 } 275 } 276 277 /* 278 * <quote> 279 * 280 * The Data Class interface of a networking device shall have 281 * a minimum of two interface settings. The first setting 282 * (the default interface setting) includes no endpoints and 283 * therefore no networking traffic is exchanged whenever the 284 * default interface setting is selected. One or more 285 * additional interface settings are used for normal 286 * operation, and therefore each includes a pair of endpoints 287 * (one IN, and one OUT) to exchange network traffic. Select 288 * an alternate interface setting to initialize the network 289 * aspects of the device and to enable the exchange of 290 * network traffic. 291 * 292 * </quote> 293 * 294 * Some devices, most notably cable modems, include interface 295 * settings that have no IN or OUT endpoint, therefore loop 296 * through the list of all available interface settings 297 * looking for one with both IN and OUT endpoints. 298 */ 299 300 alloc_transfers: 301 302 for (i = 0; i != 32; i++) { 303 304 error = usb2_set_alt_interface_index 305 (uaa->device, sc->sc_ifaces_index[0], i); 306 307 if (error) { 308 device_printf(dev, "no valid alternate " 309 "setting found!\n"); 310 goto detach; 311 } 312 error = usb2_transfer_setup 313 (uaa->device, sc->sc_ifaces_index, 314 sc->sc_xfer, cdce_config, CDCE_N_TRANSFER, 315 sc, &sc->sc_mtx); 316 317 if (error == 0) { 318 break; 319 } 320 } 321 322 ued = usb2_find_descriptor 323 (uaa->device, NULL, uaa->info.bIfaceIndex, 324 UDESC_CS_INTERFACE, 0 - 1, UDESCSUB_CDC_ENF, 0 - 1); 325 326 if ((ued == NULL) || (ued->bLength < sizeof(*ued))) { 327 error = USB_ERR_INVAL; 328 } else { 329 error = usb2_req_get_string_any(uaa->device, NULL, 330 eaddr_str, sizeof(eaddr_str), ued->iMacAddress); 331 } 332 333 if (error) { 334 335 /* fake MAC address */ 336 337 device_printf(dev, "faking MAC address\n"); 338 sc->sc_ue.ue_eaddr[0] = 0x2a; 339 memcpy(&sc->sc_ue.ue_eaddr[1], &ticks, sizeof(uint32_t)); 340 sc->sc_ue.ue_eaddr[5] = device_get_unit(dev); 341 342 } else { 343 344 bzero(sc->sc_ue.ue_eaddr, sizeof(sc->sc_ue.ue_eaddr)); 345 346 for (i = 0; i != (ETHER_ADDR_LEN * 2); i++) { 347 348 char c = eaddr_str[i]; 349 350 if ('0' <= c && c <= '9') 351 c -= '0'; 352 else if (c != 0) 353 c -= 'A' - 10; 354 else 355 break; 356 357 c &= 0xf; 358 359 if ((i & 1) == 0) 360 c <<= 4; 361 sc->sc_ue.ue_eaddr[i / 2] |= c; 362 } 363 364 if (uaa->usb2_mode == USB_MODE_DEVICE) { 365 /* 366 * Do not use the same MAC address like the peer ! 367 */ 368 sc->sc_ue.ue_eaddr[5] ^= 0xFF; 369 } 370 } 371 372 ue->ue_sc = sc; 373 ue->ue_dev = dev; 374 ue->ue_udev = uaa->device; 375 ue->ue_mtx = &sc->sc_mtx; 376 ue->ue_methods = &cdce_ue_methods; 377 378 error = usb2_ether_ifattach(ue); 379 if (error) { 380 device_printf(dev, "could not attach interface\n"); 381 goto detach; 382 } 383 return (0); /* success */ 384 385 detach: 386 cdce_detach(dev); 387 return (ENXIO); /* failure */ 388 } 389 390 static int 391 cdce_detach(device_t dev) 392 { 393 struct cdce_softc *sc = device_get_softc(dev); 394 struct usb2_ether *ue = &sc->sc_ue; 395 396 /* stop all USB transfers first */ 397 usb2_transfer_unsetup(sc->sc_xfer, CDCE_N_TRANSFER); 398 usb2_ether_ifdetach(ue); 399 mtx_destroy(&sc->sc_mtx); 400 401 return (0); 402 } 403 404 static void 405 cdce_start(struct usb2_ether *ue) 406 { 407 struct cdce_softc *sc = usb2_ether_getsc(ue); 408 409 /* 410 * Start the USB transfers, if not already started: 411 */ 412 usb2_transfer_start(sc->sc_xfer[CDCE_BULK_TX]); 413 usb2_transfer_start(sc->sc_xfer[CDCE_BULK_RX]); 414 } 415 416 static void 417 cdce_free_queue(struct mbuf **ppm, uint8_t n) 418 { 419 uint8_t x; 420 for (x = 0; x != n; x++) { 421 if (ppm[x] != NULL) { 422 m_freem(ppm[x]); 423 ppm[x] = NULL; 424 } 425 } 426 } 427 428 static void 429 cdce_bulk_write_callback(struct usb2_xfer *xfer) 430 { 431 struct cdce_softc *sc = xfer->priv_sc; 432 struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue); 433 struct mbuf *m; 434 struct mbuf *mt; 435 uint32_t crc; 436 uint8_t x; 437 438 DPRINTFN(1, "\n"); 439 440 switch (USB_GET_STATE(xfer)) { 441 case USB_ST_TRANSFERRED: 442 DPRINTFN(11, "transfer complete: " 443 "%u bytes in %u frames\n", xfer->actlen, 444 xfer->aframes); 445 446 ifp->if_opackets++; 447 448 /* free all previous TX buffers */ 449 cdce_free_queue(sc->sc_tx_buf, CDCE_FRAMES_MAX); 450 451 /* FALLTHROUGH */ 452 case USB_ST_SETUP: 453 tr_setup: 454 for (x = 0; x != CDCE_FRAMES_MAX; x++) { 455 456 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 457 458 if (m == NULL) 459 break; 460 461 if (sc->sc_flags & CDCE_FLAG_ZAURUS) { 462 /* 463 * Zaurus wants a 32-bit CRC appended 464 * to every frame 465 */ 466 467 crc = cdce_m_crc32(m, 0, m->m_pkthdr.len); 468 crc = htole32(crc); 469 470 if (!m_append(m, 4, (void *)&crc)) { 471 m_freem(m); 472 ifp->if_oerrors++; 473 continue; 474 } 475 } 476 if (m->m_len != m->m_pkthdr.len) { 477 mt = m_defrag(m, M_DONTWAIT); 478 if (mt == NULL) { 479 m_freem(m); 480 ifp->if_oerrors++; 481 continue; 482 } 483 m = mt; 484 } 485 if (m->m_pkthdr.len > MCLBYTES) { 486 m->m_pkthdr.len = MCLBYTES; 487 } 488 sc->sc_tx_buf[x] = m; 489 xfer->frlengths[x] = m->m_len; 490 usb2_set_frame_data(xfer, m->m_data, x); 491 492 /* 493 * If there's a BPF listener, bounce a copy of 494 * this frame to him: 495 */ 496 BPF_MTAP(ifp, m); 497 } 498 if (x != 0) { 499 xfer->nframes = x; 500 usb2_start_hardware(xfer); 501 } 502 break; 503 504 default: /* Error */ 505 DPRINTFN(11, "transfer error, %s\n", 506 usb2_errstr(xfer->error)); 507 508 /* free all previous TX buffers */ 509 cdce_free_queue(sc->sc_tx_buf, CDCE_FRAMES_MAX); 510 511 /* count output errors */ 512 ifp->if_oerrors++; 513 514 if (xfer->error != USB_ERR_CANCELLED) { 515 /* try to clear stall first */ 516 xfer->flags.stall_pipe = 1; 517 goto tr_setup; 518 } 519 break; 520 } 521 } 522 523 static int32_t 524 cdce_m_crc32_cb(void *arg, void *src, uint32_t count) 525 { 526 uint32_t *p_crc = arg; 527 528 *p_crc = crc32_raw(src, count, *p_crc); 529 return (0); 530 } 531 532 static uint32_t 533 cdce_m_crc32(struct mbuf *m, uint32_t src_offset, uint32_t src_len) 534 { 535 uint32_t crc = 0xFFFFFFFF; 536 int error; 537 538 error = m_apply(m, src_offset, src_len, cdce_m_crc32_cb, &crc); 539 return (crc ^ 0xFFFFFFFF); 540 } 541 542 static void 543 cdce_init(struct usb2_ether *ue) 544 { 545 struct cdce_softc *sc = usb2_ether_getsc(ue); 546 struct ifnet *ifp = usb2_ether_getifp(ue); 547 548 CDCE_LOCK_ASSERT(sc, MA_OWNED); 549 550 ifp->if_drv_flags |= IFF_DRV_RUNNING; 551 552 /* start interrupt transfer */ 553 usb2_transfer_start(sc->sc_xfer[CDCE_INTR_RX]); 554 usb2_transfer_start(sc->sc_xfer[CDCE_INTR_TX]); 555 556 /* stall data write direction, which depends on USB mode */ 557 usb2_transfer_set_stall(sc->sc_xfer[CDCE_BULK_TX]); 558 559 /* start data transfers */ 560 cdce_start(ue); 561 } 562 563 static void 564 cdce_stop(struct usb2_ether *ue) 565 { 566 struct cdce_softc *sc = usb2_ether_getsc(ue); 567 struct ifnet *ifp = usb2_ether_getifp(ue); 568 569 CDCE_LOCK_ASSERT(sc, MA_OWNED); 570 571 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 572 573 /* 574 * stop all the transfers, if not already stopped: 575 */ 576 usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_RX]); 577 usb2_transfer_stop(sc->sc_xfer[CDCE_BULK_TX]); 578 usb2_transfer_stop(sc->sc_xfer[CDCE_INTR_RX]); 579 usb2_transfer_stop(sc->sc_xfer[CDCE_INTR_TX]); 580 } 581 582 static void 583 cdce_setmulti(struct usb2_ether *ue) 584 { 585 /* no-op */ 586 return; 587 } 588 589 static void 590 cdce_setpromisc(struct usb2_ether *ue) 591 { 592 /* no-op */ 593 return; 594 } 595 596 static int 597 cdce_suspend(device_t dev) 598 { 599 device_printf(dev, "Suspending\n"); 600 return (0); 601 } 602 603 static int 604 cdce_resume(device_t dev) 605 { 606 device_printf(dev, "Resuming\n"); 607 return (0); 608 } 609 610 static void 611 cdce_bulk_read_callback(struct usb2_xfer *xfer) 612 { 613 struct cdce_softc *sc = xfer->priv_sc; 614 struct mbuf *m; 615 uint8_t x; 616 617 switch (USB_GET_STATE(xfer)) { 618 case USB_ST_TRANSFERRED: 619 620 DPRINTF("received %u bytes in %u frames\n", 621 xfer->actlen, xfer->aframes); 622 623 for (x = 0; x != xfer->aframes; x++) { 624 625 m = sc->sc_rx_buf[x]; 626 sc->sc_rx_buf[x] = NULL; 627 628 /* Strip off CRC added by Zaurus, if any */ 629 if ((sc->sc_flags & CDCE_FLAG_ZAURUS) && 630 (xfer->frlengths[x] >= 14)) 631 xfer->frlengths[x] -= 4; 632 633 if (xfer->frlengths[x] < sizeof(struct ether_header)) { 634 m_freem(m); 635 continue; 636 } 637 /* queue up mbuf */ 638 usb2_ether_rxmbuf(&sc->sc_ue, m, xfer->frlengths[x]); 639 } 640 641 /* FALLTHROUGH */ 642 case USB_ST_SETUP: 643 /* 644 * TODO: Implement support for multi frame transfers, 645 * when the USB hardware supports it. 646 */ 647 for (x = 0; x != 1; x++) { 648 if (sc->sc_rx_buf[x] == NULL) { 649 m = usb2_ether_newbuf(); 650 if (m == NULL) 651 goto tr_stall; 652 sc->sc_rx_buf[x] = m; 653 } else { 654 m = sc->sc_rx_buf[x]; 655 } 656 657 usb2_set_frame_data(xfer, m->m_data, x); 658 xfer->frlengths[x] = m->m_len; 659 } 660 /* set number of frames and start hardware */ 661 xfer->nframes = x; 662 usb2_start_hardware(xfer); 663 /* flush any received frames */ 664 usb2_ether_rxflush(&sc->sc_ue); 665 break; 666 667 default: /* Error */ 668 DPRINTF("error = %s\n", 669 usb2_errstr(xfer->error)); 670 671 if (xfer->error != USB_ERR_CANCELLED) { 672 tr_stall: 673 /* try to clear stall first */ 674 xfer->flags.stall_pipe = 1; 675 xfer->nframes = 0; 676 usb2_start_hardware(xfer); 677 break; 678 } 679 680 /* need to free the RX-mbufs when we are cancelled */ 681 cdce_free_queue(sc->sc_rx_buf, CDCE_FRAMES_MAX); 682 break; 683 } 684 } 685 686 static void 687 cdce_intr_read_callback(struct usb2_xfer *xfer) 688 { 689 ; /* style fix */ 690 switch (USB_GET_STATE(xfer)) { 691 case USB_ST_TRANSFERRED: 692 693 DPRINTF("Received %d bytes\n", 694 xfer->actlen); 695 696 /* TODO: decode some indications */ 697 698 /* FALLTHROUGH */ 699 case USB_ST_SETUP: 700 tr_setup: 701 xfer->frlengths[0] = xfer->max_data_length; 702 usb2_start_hardware(xfer); 703 break; 704 705 default: /* Error */ 706 if (xfer->error != USB_ERR_CANCELLED) { 707 /* start clear stall */ 708 xfer->flags.stall_pipe = 1; 709 goto tr_setup; 710 } 711 break; 712 } 713 } 714 715 static void 716 cdce_intr_write_callback(struct usb2_xfer *xfer) 717 { 718 ; /* style fix */ 719 switch (USB_GET_STATE(xfer)) { 720 case USB_ST_TRANSFERRED: 721 722 DPRINTF("Transferred %d bytes\n", xfer->actlen); 723 724 /* FALLTHROUGH */ 725 case USB_ST_SETUP: 726 tr_setup: 727 #if 0 728 xfer->frlengths[0] = XXX; 729 usb2_start_hardware(xfer); 730 #endif 731 break; 732 733 default: /* Error */ 734 if (xfer->error != USB_ERR_CANCELLED) { 735 /* start clear stall */ 736 xfer->flags.stall_pipe = 1; 737 goto tr_setup; 738 } 739 break; 740 } 741 } 742 743 static int 744 cdce_handle_request(device_t dev, 745 const void *req, void **pptr, uint16_t *plen, 746 uint16_t offset, uint8_t is_complete) 747 { 748 return (ENXIO); /* use builtin handler */ 749 } 750