1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2010 Fredrik Lindberg <fli@shapeshifter.se> 5 * 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 ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 */ 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include <sys/param.h> 32 #include <sys/eventhandler.h> 33 #include <sys/sockio.h> 34 #include <sys/mbuf.h> 35 #include <sys/malloc.h> 36 #include <sys/kernel.h> 37 #include <sys/module.h> 38 #include <sys/socket.h> 39 #include <sys/tty.h> 40 #include <sys/sysctl.h> 41 #include <sys/condvar.h> 42 #include <sys/sx.h> 43 #include <sys/proc.h> 44 #include <sys/conf.h> 45 #include <sys/bus.h> 46 #include <sys/systm.h> 47 #include <sys/limits.h> 48 49 #include <machine/bus.h> 50 51 #include <net/if.h> 52 #include <net/if_var.h> 53 #include <net/if_types.h> 54 #include <net/netisr.h> 55 #include <net/bpf.h> 56 #include <netinet/in.h> 57 #include <netinet/ip.h> 58 #include <netinet/ip6.h> 59 60 #include <dev/usb/usb.h> 61 #include <dev/usb/usbdi.h> 62 #include <dev/usb/usbdi_util.h> 63 #include <dev/usb/usb_cdc.h> 64 #include "usbdevs.h" 65 #define USB_DEBUG_VAR uhso_debug 66 #include <dev/usb/usb_debug.h> 67 #include <dev/usb/usb_process.h> 68 #include <dev/usb/usb_busdma.h> 69 #include <dev/usb/usb_msctest.h> 70 71 #include <dev/usb/serial/usb_serial.h> 72 73 struct uhso_tty { 74 struct uhso_softc *ht_sc; 75 struct usb_xfer *ht_xfer[3]; 76 int ht_muxport; /* Mux. port no */ 77 int ht_open; 78 char ht_name[32]; 79 }; 80 81 struct uhso_softc { 82 device_t sc_dev; 83 struct usb_device *sc_udev; 84 struct mtx sc_mtx; 85 uint32_t sc_type; /* Interface definition */ 86 int sc_radio; 87 88 struct usb_xfer *sc_xfer[3]; 89 uint8_t sc_iface_no; 90 uint8_t sc_iface_index; 91 92 /* Control pipe */ 93 struct usb_xfer * sc_ctrl_xfer[2]; 94 uint8_t sc_ctrl_iface_no; 95 96 /* Network */ 97 struct usb_xfer *sc_if_xfer[2]; 98 struct ifnet *sc_ifp; 99 struct mbuf *sc_mwait; /* Partial packet */ 100 size_t sc_waitlen; /* No. of outstanding bytes */ 101 struct mbufq sc_rxq; 102 struct callout sc_c; 103 104 /* TTY related structures */ 105 struct ucom_super_softc sc_super_ucom; 106 int sc_ttys; 107 struct uhso_tty *sc_tty; 108 struct ucom_softc *sc_ucom; 109 int sc_msr; 110 int sc_lsr; 111 int sc_line; 112 }; 113 114 #define UHSO_MAX_MTU 2048 115 116 /* 117 * There are mainly two type of cards floating around. 118 * The first one has 2,3 or 4 interfaces with a multiplexed serial port 119 * and packet interface on the first interface and bulk serial ports 120 * on the others. 121 * The second type of card has several other interfaces, their purpose 122 * can be detected during run-time. 123 */ 124 #define UHSO_IFACE_SPEC(usb_type, port, port_type) \ 125 (((usb_type) << 24) | ((port) << 16) | (port_type)) 126 127 #define UHSO_IFACE_USB_TYPE(x) ((x >> 24) & 0xff) 128 #define UHSO_IFACE_PORT(x) ((x >> 16) & 0xff) 129 #define UHSO_IFACE_PORT_TYPE(x) (x & 0xff) 130 131 /* 132 * USB interface types 133 */ 134 #define UHSO_IF_NET 0x01 /* Network packet interface */ 135 #define UHSO_IF_MUX 0x02 /* Multiplexed serial port */ 136 #define UHSO_IF_BULK 0x04 /* Bulk interface */ 137 138 /* 139 * Port types 140 */ 141 #define UHSO_PORT_UNKNOWN 0x00 142 #define UHSO_PORT_SERIAL 0x01 /* Serial port */ 143 #define UHSO_PORT_NETWORK 0x02 /* Network packet interface */ 144 145 /* 146 * Multiplexed serial port destination sub-port names 147 */ 148 #define UHSO_MPORT_TYPE_CTL 0x00 /* Control port */ 149 #define UHSO_MPORT_TYPE_APP 0x01 /* Application */ 150 #define UHSO_MPORT_TYPE_PCSC 0x02 151 #define UHSO_MPORT_TYPE_GPS 0x03 152 #define UHSO_MPORT_TYPE_APP2 0x04 /* Secondary application */ 153 #define UHSO_MPORT_TYPE_MAX UHSO_MPORT_TYPE_APP2 154 #define UHSO_MPORT_TYPE_NOMAX 8 /* Max number of mux ports */ 155 156 /* 157 * Port definitions 158 * Note that these definitions are arbitrary and do not match the values 159 * returned by the auto config descriptor. 160 */ 161 #define UHSO_PORT_TYPE_UNKNOWN 0x00 162 #define UHSO_PORT_TYPE_CTL 0x01 163 #define UHSO_PORT_TYPE_APP 0x02 164 #define UHSO_PORT_TYPE_APP2 0x03 165 #define UHSO_PORT_TYPE_MODEM 0x04 166 #define UHSO_PORT_TYPE_NETWORK 0x05 167 #define UHSO_PORT_TYPE_DIAG 0x06 168 #define UHSO_PORT_TYPE_DIAG2 0x07 169 #define UHSO_PORT_TYPE_GPS 0x08 170 #define UHSO_PORT_TYPE_GPSCTL 0x09 171 #define UHSO_PORT_TYPE_PCSC 0x0a 172 #define UHSO_PORT_TYPE_MSD 0x0b 173 #define UHSO_PORT_TYPE_VOICE 0x0c 174 #define UHSO_PORT_TYPE_MAX 0x0c 175 176 static eventhandler_tag uhso_etag; 177 178 /* Overall port type */ 179 static char *uhso_port[] = { 180 "Unknown", 181 "Serial", 182 "Network", 183 "Network/Serial" 184 }; 185 186 /* 187 * Map between interface port type read from device and description type. 188 * The position in this array is a direct map to the auto config 189 * descriptor values. 190 */ 191 static unsigned char uhso_port_map[] = { 192 UHSO_PORT_TYPE_UNKNOWN, 193 UHSO_PORT_TYPE_DIAG, 194 UHSO_PORT_TYPE_GPS, 195 UHSO_PORT_TYPE_GPSCTL, 196 UHSO_PORT_TYPE_APP, 197 UHSO_PORT_TYPE_APP2, 198 UHSO_PORT_TYPE_CTL, 199 UHSO_PORT_TYPE_NETWORK, 200 UHSO_PORT_TYPE_MODEM, 201 UHSO_PORT_TYPE_MSD, 202 UHSO_PORT_TYPE_PCSC, 203 UHSO_PORT_TYPE_VOICE 204 }; 205 static char uhso_port_map_max = sizeof(uhso_port_map) / sizeof(char); 206 207 static unsigned char uhso_mux_port_map[] = { 208 UHSO_PORT_TYPE_CTL, 209 UHSO_PORT_TYPE_APP, 210 UHSO_PORT_TYPE_PCSC, 211 UHSO_PORT_TYPE_GPS, 212 UHSO_PORT_TYPE_APP2 213 }; 214 215 static char *uhso_port_type[] = { 216 "Unknown", /* Not a valid port */ 217 "Control", 218 "Application", 219 "Application (Secondary)", 220 "Modem", 221 "Network", 222 "Diagnostic", 223 "Diagnostic (Secondary)", 224 "GPS", 225 "GPS Control", 226 "PC Smartcard", 227 "MSD", 228 "Voice", 229 }; 230 231 static char *uhso_port_type_sysctl[] = { 232 "unknown", 233 "control", 234 "application", 235 "application", 236 "modem", 237 "network", 238 "diagnostic", 239 "diagnostic", 240 "gps", 241 "gps_control", 242 "pcsc", 243 "msd", 244 "voice", 245 }; 246 247 #define UHSO_STATIC_IFACE 0x01 248 #define UHSO_AUTO_IFACE 0x02 249 250 /* ifnet device unit allocations */ 251 static struct unrhdr *uhso_ifnet_unit = NULL; 252 253 static const STRUCT_USB_HOST_ID uhso_devs[] = { 254 #define UHSO_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } 255 /* Option GlobeTrotter MAX 7.2 with upgraded firmware */ 256 UHSO_DEV(OPTION, GTMAX72, UHSO_STATIC_IFACE), 257 /* Option GlobeSurfer iCON 7.2 */ 258 UHSO_DEV(OPTION, GSICON72, UHSO_STATIC_IFACE), 259 /* Option iCON 225 */ 260 UHSO_DEV(OPTION, GTHSDPA, UHSO_STATIC_IFACE), 261 /* Option GlobeSurfer iCON HSUPA */ 262 UHSO_DEV(OPTION, GSICONHSUPA, UHSO_STATIC_IFACE), 263 /* Option GlobeTrotter HSUPA */ 264 UHSO_DEV(OPTION, GTHSUPA, UHSO_STATIC_IFACE), 265 /* GE40x */ 266 UHSO_DEV(OPTION, GE40X, UHSO_AUTO_IFACE), 267 UHSO_DEV(OPTION, GE40X_1, UHSO_AUTO_IFACE), 268 UHSO_DEV(OPTION, GE40X_2, UHSO_AUTO_IFACE), 269 UHSO_DEV(OPTION, GE40X_3, UHSO_AUTO_IFACE), 270 /* Option GlobeSurfer iCON 401 */ 271 UHSO_DEV(OPTION, ICON401, UHSO_AUTO_IFACE), 272 /* Option GlobeTrotter Module 382 */ 273 UHSO_DEV(OPTION, GMT382, UHSO_AUTO_IFACE), 274 /* Option GTM661W */ 275 UHSO_DEV(OPTION, GTM661W, UHSO_AUTO_IFACE), 276 /* Option iCON EDGE */ 277 UHSO_DEV(OPTION, ICONEDGE, UHSO_STATIC_IFACE), 278 /* Option Module HSxPA */ 279 UHSO_DEV(OPTION, MODHSXPA, UHSO_STATIC_IFACE), 280 /* Option iCON 321 */ 281 UHSO_DEV(OPTION, ICON321, UHSO_STATIC_IFACE), 282 /* Option iCON 322 */ 283 UHSO_DEV(OPTION, GTICON322, UHSO_STATIC_IFACE), 284 /* Option iCON 505 */ 285 UHSO_DEV(OPTION, ICON505, UHSO_AUTO_IFACE), 286 /* Option iCON 452 */ 287 UHSO_DEV(OPTION, ICON505, UHSO_AUTO_IFACE), 288 #undef UHSO_DEV 289 }; 290 291 static SYSCTL_NODE(_hw_usb, OID_AUTO, uhso, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 292 "USB uhso"); 293 static int uhso_autoswitch = 1; 294 SYSCTL_INT(_hw_usb_uhso, OID_AUTO, auto_switch, CTLFLAG_RWTUN, 295 &uhso_autoswitch, 0, "Automatically switch to modem mode"); 296 297 #ifdef USB_DEBUG 298 #ifdef UHSO_DEBUG 299 static int uhso_debug = UHSO_DEBUG; 300 #else 301 static int uhso_debug = -1; 302 #endif 303 304 SYSCTL_INT(_hw_usb_uhso, OID_AUTO, debug, CTLFLAG_RWTUN, 305 &uhso_debug, 0, "Debug level"); 306 307 #define UHSO_DPRINTF(n, x, ...) {\ 308 if (uhso_debug >= n) {\ 309 printf("%s: " x, __func__, ##__VA_ARGS__);\ 310 }\ 311 } 312 #else 313 #define UHSO_DPRINTF(n, x, ...) 314 #endif 315 316 #ifdef UHSO_DEBUG_HEXDUMP 317 # define UHSO_HEXDUMP(_buf, _len) do { \ 318 { \ 319 size_t __tmp; \ 320 const char *__buf = (const char *)_buf; \ 321 for (__tmp = 0; __tmp < _len; __tmp++) \ 322 printf("%02hhx ", *__buf++); \ 323 printf("\n"); \ 324 } \ 325 } while(0) 326 #else 327 # define UHSO_HEXDUMP(_buf, _len) 328 #endif 329 330 enum { 331 UHSO_MUX_ENDPT_INTR = 0, 332 UHSO_MUX_ENDPT_MAX 333 }; 334 335 enum { 336 UHSO_CTRL_READ = 0, 337 UHSO_CTRL_WRITE, 338 UHSO_CTRL_MAX 339 }; 340 341 enum { 342 UHSO_IFNET_READ = 0, 343 UHSO_IFNET_WRITE, 344 UHSO_IFNET_MAX 345 }; 346 347 enum { 348 UHSO_BULK_ENDPT_READ = 0, 349 UHSO_BULK_ENDPT_WRITE, 350 UHSO_BULK_ENDPT_INTR, 351 UHSO_BULK_ENDPT_MAX 352 }; 353 354 static usb_callback_t uhso_mux_intr_callback; 355 static usb_callback_t uhso_mux_read_callback; 356 static usb_callback_t uhso_mux_write_callback; 357 static usb_callback_t uhso_bs_read_callback; 358 static usb_callback_t uhso_bs_write_callback; 359 static usb_callback_t uhso_bs_intr_callback; 360 static usb_callback_t uhso_ifnet_read_callback; 361 static usb_callback_t uhso_ifnet_write_callback; 362 363 /* Config used for the default control pipes */ 364 static const struct usb_config uhso_ctrl_config[UHSO_CTRL_MAX] = { 365 [UHSO_CTRL_READ] = { 366 .type = UE_CONTROL, 367 .endpoint = 0x00, 368 .direction = UE_DIR_ANY, 369 .flags = { .pipe_bof = 1, .short_xfer_ok = 1 }, 370 .bufsize = sizeof(struct usb_device_request) + 1024, 371 .callback = &uhso_mux_read_callback 372 }, 373 374 [UHSO_CTRL_WRITE] = { 375 .type = UE_CONTROL, 376 .endpoint = 0x00, 377 .direction = UE_DIR_ANY, 378 .flags = { .pipe_bof = 1, .force_short_xfer = 1 }, 379 .bufsize = sizeof(struct usb_device_request) + 1024, 380 .timeout = 1000, 381 .callback = &uhso_mux_write_callback 382 } 383 }; 384 385 /* Config for the multiplexed serial ports */ 386 static const struct usb_config uhso_mux_config[UHSO_MUX_ENDPT_MAX] = { 387 [UHSO_MUX_ENDPT_INTR] = { 388 .type = UE_INTERRUPT, 389 .endpoint = UE_ADDR_ANY, 390 .direction = UE_DIR_IN, 391 .flags = { .short_xfer_ok = 1 }, 392 .bufsize = 0, 393 .callback = &uhso_mux_intr_callback, 394 } 395 }; 396 397 /* Config for the raw IP-packet interface */ 398 static const struct usb_config uhso_ifnet_config[UHSO_IFNET_MAX] = { 399 [UHSO_IFNET_READ] = { 400 .type = UE_BULK, 401 .endpoint = UE_ADDR_ANY, 402 .direction = UE_DIR_IN, 403 .flags = { .pipe_bof = 1, .short_xfer_ok = 1 }, 404 .bufsize = MCLBYTES, 405 .callback = &uhso_ifnet_read_callback 406 }, 407 [UHSO_IFNET_WRITE] = { 408 .type = UE_BULK, 409 .endpoint = UE_ADDR_ANY, 410 .direction = UE_DIR_OUT, 411 .flags = { .pipe_bof = 1, .force_short_xfer = 1 }, 412 .bufsize = MCLBYTES, 413 .timeout = 5 * USB_MS_HZ, 414 .callback = &uhso_ifnet_write_callback 415 } 416 }; 417 418 /* Config for interfaces with normal bulk serial ports */ 419 static const struct usb_config uhso_bs_config[UHSO_BULK_ENDPT_MAX] = { 420 [UHSO_BULK_ENDPT_READ] = { 421 .type = UE_BULK, 422 .endpoint = UE_ADDR_ANY, 423 .direction = UE_DIR_IN, 424 .flags = { .pipe_bof = 1, .short_xfer_ok = 1 }, 425 .bufsize = 4096, 426 .callback = &uhso_bs_read_callback 427 }, 428 429 [UHSO_BULK_ENDPT_WRITE] = { 430 .type = UE_BULK, 431 .endpoint = UE_ADDR_ANY, 432 .direction = UE_DIR_OUT, 433 .flags = { .pipe_bof = 1, .force_short_xfer = 1 }, 434 .bufsize = 8192, 435 .callback = &uhso_bs_write_callback 436 }, 437 438 [UHSO_BULK_ENDPT_INTR] = { 439 .type = UE_INTERRUPT, 440 .endpoint = UE_ADDR_ANY, 441 .direction = UE_DIR_IN, 442 .flags = { .short_xfer_ok = 1 }, 443 .bufsize = 0, 444 .callback = &uhso_bs_intr_callback, 445 } 446 }; 447 448 static int uhso_probe_iface(struct uhso_softc *, int, 449 int (*probe)(struct usb_device *, int)); 450 static int uhso_probe_iface_auto(struct usb_device *, int); 451 static int uhso_probe_iface_static(struct usb_device *, int); 452 static int uhso_attach_muxserial(struct uhso_softc *, struct usb_interface *, 453 int type); 454 static int uhso_attach_bulkserial(struct uhso_softc *, struct usb_interface *, 455 int type); 456 static int uhso_attach_ifnet(struct uhso_softc *, struct usb_interface *, 457 int type); 458 static void uhso_test_autoinst(void *, struct usb_device *, 459 struct usb_attach_arg *); 460 static int uhso_driver_loaded(struct module *, int, void *); 461 static int uhso_radio_sysctl(SYSCTL_HANDLER_ARGS); 462 static int uhso_radio_ctrl(struct uhso_softc *, int); 463 464 static void uhso_free(struct ucom_softc *); 465 static void uhso_ucom_start_read(struct ucom_softc *); 466 static void uhso_ucom_stop_read(struct ucom_softc *); 467 static void uhso_ucom_start_write(struct ucom_softc *); 468 static void uhso_ucom_stop_write(struct ucom_softc *); 469 static void uhso_ucom_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *); 470 static void uhso_ucom_cfg_set_dtr(struct ucom_softc *, uint8_t); 471 static void uhso_ucom_cfg_set_rts(struct ucom_softc *, uint8_t); 472 static void uhso_if_init(void *); 473 static void uhso_if_start(struct ifnet *); 474 static void uhso_if_stop(struct uhso_softc *); 475 static int uhso_if_ioctl(struct ifnet *, u_long, caddr_t); 476 static int uhso_if_output(struct ifnet *, struct mbuf *, 477 const struct sockaddr *, struct route *); 478 static void uhso_if_rxflush(void *); 479 480 static device_probe_t uhso_probe; 481 static device_attach_t uhso_attach; 482 static device_detach_t uhso_detach; 483 static void uhso_free_softc(struct uhso_softc *); 484 485 static device_method_t uhso_methods[] = { 486 DEVMETHOD(device_probe, uhso_probe), 487 DEVMETHOD(device_attach, uhso_attach), 488 DEVMETHOD(device_detach, uhso_detach), 489 { 0, 0 } 490 }; 491 492 static driver_t uhso_driver = { 493 .name = "uhso", 494 .methods = uhso_methods, 495 .size = sizeof(struct uhso_softc) 496 }; 497 498 DRIVER_MODULE(uhso, uhub, uhso_driver, uhso_driver_loaded, NULL); 499 MODULE_DEPEND(uhso, ucom, 1, 1, 1); 500 MODULE_DEPEND(uhso, usb, 1, 1, 1); 501 MODULE_VERSION(uhso, 1); 502 USB_PNP_HOST_INFO(uhso_devs); 503 504 static struct ucom_callback uhso_ucom_callback = { 505 .ucom_cfg_get_status = &uhso_ucom_cfg_get_status, 506 .ucom_cfg_set_dtr = &uhso_ucom_cfg_set_dtr, 507 .ucom_cfg_set_rts = &uhso_ucom_cfg_set_rts, 508 .ucom_start_read = uhso_ucom_start_read, 509 .ucom_stop_read = uhso_ucom_stop_read, 510 .ucom_start_write = uhso_ucom_start_write, 511 .ucom_stop_write = uhso_ucom_stop_write, 512 .ucom_free = &uhso_free, 513 }; 514 515 static int 516 uhso_probe(device_t self) 517 { 518 struct usb_attach_arg *uaa = device_get_ivars(self); 519 int error; 520 521 if (uaa->usb_mode != USB_MODE_HOST) 522 return (ENXIO); 523 if (uaa->info.bConfigIndex != 0) 524 return (ENXIO); 525 if (uaa->info.bDeviceClass != 0xff) 526 return (ENXIO); 527 528 error = usbd_lookup_id_by_uaa(uhso_devs, sizeof(uhso_devs), uaa); 529 if (error != 0) 530 return (error); 531 532 /* 533 * Probe device to see if we are able to attach 534 * to this interface or not. 535 */ 536 if (USB_GET_DRIVER_INFO(uaa) == UHSO_AUTO_IFACE) { 537 if (uhso_probe_iface_auto(uaa->device, 538 uaa->info.bIfaceNum) == 0) 539 return (ENXIO); 540 } 541 return (error); 542 } 543 544 static int 545 uhso_attach(device_t self) 546 { 547 struct uhso_softc *sc = device_get_softc(self); 548 struct usb_attach_arg *uaa = device_get_ivars(self); 549 struct usb_interface_descriptor *id; 550 struct sysctl_ctx_list *sctx; 551 struct sysctl_oid *soid; 552 struct sysctl_oid *tree = NULL, *tty_node; 553 struct ucom_softc *ucom; 554 struct uhso_tty *ht; 555 int i, error, port; 556 void *probe_f; 557 usb_error_t uerr; 558 char *desc; 559 560 sc->sc_dev = self; 561 sc->sc_udev = uaa->device; 562 mtx_init(&sc->sc_mtx, "uhso", NULL, MTX_DEF); 563 mbufq_init(&sc->sc_rxq, INT_MAX); /* XXXGL: sane maximum */ 564 ucom_ref(&sc->sc_super_ucom); 565 566 sc->sc_radio = 1; 567 568 id = usbd_get_interface_descriptor(uaa->iface); 569 sc->sc_ctrl_iface_no = id->bInterfaceNumber; 570 571 sc->sc_iface_no = uaa->info.bIfaceNum; 572 sc->sc_iface_index = uaa->info.bIfaceIndex; 573 574 /* Setup control pipe */ 575 uerr = usbd_transfer_setup(uaa->device, 576 &sc->sc_iface_index, sc->sc_ctrl_xfer, 577 uhso_ctrl_config, UHSO_CTRL_MAX, sc, &sc->sc_mtx); 578 if (uerr) { 579 device_printf(self, "Failed to setup control pipe: %s\n", 580 usbd_errstr(uerr)); 581 goto out; 582 } 583 584 if (USB_GET_DRIVER_INFO(uaa) == UHSO_STATIC_IFACE) 585 probe_f = uhso_probe_iface_static; 586 else if (USB_GET_DRIVER_INFO(uaa) == UHSO_AUTO_IFACE) 587 probe_f = uhso_probe_iface_auto; 588 else 589 goto out; 590 591 error = uhso_probe_iface(sc, uaa->info.bIfaceNum, probe_f); 592 if (error != 0) 593 goto out; 594 595 sctx = device_get_sysctl_ctx(sc->sc_dev); 596 soid = device_get_sysctl_tree(sc->sc_dev); 597 598 SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "type", 599 CTLFLAG_RD, uhso_port[UHSO_IFACE_PORT(sc->sc_type)], 0, 600 "Port available at this interface"); 601 SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "radio", 602 CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, sc, 0, 603 uhso_radio_sysctl, "I", "Enable radio"); 604 605 /* 606 * The default interface description on most Option devices isn't 607 * very helpful. So we skip device_set_usb_desc and set the 608 * device description manually. 609 */ 610 device_set_desc_copy(self, uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)]); 611 /* Announce device */ 612 device_printf(self, "<%s port> at <%s %s> on %s\n", 613 uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)], 614 usb_get_manufacturer(uaa->device), 615 usb_get_product(uaa->device), 616 device_get_nameunit(device_get_parent(self))); 617 618 if (sc->sc_ttys > 0) { 619 SYSCTL_ADD_INT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "ports", 620 CTLFLAG_RD, &sc->sc_ttys, 0, "Number of attached serial ports"); 621 622 tree = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, 623 "port", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Serial ports"); 624 } 625 626 /* 627 * Loop through the number of found TTYs and create sysctl 628 * nodes for them. 629 */ 630 for (i = 0; i < sc->sc_ttys; i++) { 631 ht = &sc->sc_tty[i]; 632 ucom = &sc->sc_ucom[i]; 633 634 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) 635 port = uhso_mux_port_map[ht->ht_muxport]; 636 else 637 port = UHSO_IFACE_PORT_TYPE(sc->sc_type); 638 639 desc = uhso_port_type_sysctl[port]; 640 641 tty_node = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(tree), OID_AUTO, 642 desc, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, ""); 643 644 ht->ht_name[0] = 0; 645 if (sc->sc_ttys == 1) 646 snprintf(ht->ht_name, 32, "cuaU%d", ucom->sc_super->sc_unit); 647 else { 648 snprintf(ht->ht_name, 32, "cuaU%d.%d", 649 ucom->sc_super->sc_unit, ucom->sc_subunit); 650 } 651 652 desc = uhso_port_type[port]; 653 SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO, 654 "tty", CTLFLAG_RD, ht->ht_name, 0, ""); 655 SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO, 656 "desc", CTLFLAG_RD, desc, 0, ""); 657 658 if (bootverbose) 659 device_printf(sc->sc_dev, 660 "\"%s\" port at %s\n", desc, ht->ht_name); 661 } 662 663 return (0); 664 out: 665 uhso_detach(sc->sc_dev); 666 return (ENXIO); 667 } 668 669 static int 670 uhso_detach(device_t self) 671 { 672 struct uhso_softc *sc = device_get_softc(self); 673 int i; 674 675 usbd_transfer_unsetup(sc->sc_xfer, 3); 676 usbd_transfer_unsetup(sc->sc_ctrl_xfer, UHSO_CTRL_MAX); 677 if (sc->sc_ttys > 0) { 678 ucom_detach(&sc->sc_super_ucom, sc->sc_ucom); 679 680 for (i = 0; i < sc->sc_ttys; i++) { 681 if (sc->sc_tty[i].ht_muxport != -1) { 682 usbd_transfer_unsetup(sc->sc_tty[i].ht_xfer, 683 UHSO_CTRL_MAX); 684 } 685 } 686 } 687 688 if (sc->sc_ifp != NULL) { 689 callout_drain(&sc->sc_c); 690 free_unr(uhso_ifnet_unit, sc->sc_ifp->if_dunit); 691 mtx_lock(&sc->sc_mtx); 692 uhso_if_stop(sc); 693 mtx_unlock(&sc->sc_mtx); 694 bpfdetach(sc->sc_ifp); 695 if_detach(sc->sc_ifp); 696 if_free(sc->sc_ifp); 697 usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX); 698 } 699 700 device_claim_softc(self); 701 702 uhso_free_softc(sc); 703 704 return (0); 705 } 706 707 UCOM_UNLOAD_DRAIN(uhso); 708 709 static void 710 uhso_free_softc(struct uhso_softc *sc) 711 { 712 if (ucom_unref(&sc->sc_super_ucom)) { 713 free(sc->sc_tty, M_USBDEV); 714 free(sc->sc_ucom, M_USBDEV); 715 mtx_destroy(&sc->sc_mtx); 716 device_free_softc(sc); 717 } 718 } 719 720 static void 721 uhso_free(struct ucom_softc *ucom) 722 { 723 uhso_free_softc(ucom->sc_parent); 724 } 725 726 static void 727 uhso_test_autoinst(void *arg, struct usb_device *udev, 728 struct usb_attach_arg *uaa) 729 { 730 struct usb_interface *iface; 731 struct usb_interface_descriptor *id; 732 733 if (uaa->dev_state != UAA_DEV_READY || !uhso_autoswitch) 734 return; 735 736 iface = usbd_get_iface(udev, 0); 737 if (iface == NULL) 738 return; 739 id = iface->idesc; 740 if (id == NULL || id->bInterfaceClass != UICLASS_MASS) 741 return; 742 if (usbd_lookup_id_by_uaa(uhso_devs, sizeof(uhso_devs), uaa)) 743 return; /* no device match */ 744 745 if (usb_msc_eject(udev, 0, MSC_EJECT_REZERO) == 0) { 746 /* success, mark the udev as disappearing */ 747 uaa->dev_state = UAA_DEV_EJECTING; 748 } 749 } 750 751 static int 752 uhso_driver_loaded(struct module *mod, int what, void *arg) 753 { 754 switch (what) { 755 case MOD_LOAD: 756 /* register our autoinstall handler */ 757 uhso_etag = EVENTHANDLER_REGISTER(usb_dev_configured, 758 uhso_test_autoinst, NULL, EVENTHANDLER_PRI_ANY); 759 /* create our unit allocator for inet devs */ 760 uhso_ifnet_unit = new_unrhdr(0, INT_MAX, NULL); 761 break; 762 case MOD_UNLOAD: 763 EVENTHANDLER_DEREGISTER(usb_dev_configured, uhso_etag); 764 delete_unrhdr(uhso_ifnet_unit); 765 break; 766 default: 767 return (EOPNOTSUPP); 768 } 769 return (0); 770 } 771 772 /* 773 * Probe the interface type by querying the device. The elements 774 * of an array indicates the capabilities of a particular interface. 775 * Returns a bit mask with the interface capabilities. 776 */ 777 static int 778 uhso_probe_iface_auto(struct usb_device *udev, int index) 779 { 780 struct usb_device_request req; 781 usb_error_t uerr; 782 uint16_t actlen = 0; 783 char port; 784 char buf[17] = {0}; 785 786 req.bmRequestType = UT_READ_VENDOR_DEVICE; 787 req.bRequest = 0x86; 788 USETW(req.wValue, 0); 789 USETW(req.wIndex, 0); 790 USETW(req.wLength, 17); 791 792 uerr = usbd_do_request_flags(udev, NULL, &req, buf, 793 0, &actlen, USB_MS_HZ); 794 if (uerr != 0) { 795 printf("%s: usbd_do_request_flags failed, %s\n", 796 __func__, usbd_errstr(uerr)); 797 return (0); 798 } 799 800 UHSO_DPRINTF(1, "actlen=%d\n", actlen); 801 UHSO_HEXDUMP(buf, 17); 802 803 if (index < 0 || index > 16) { 804 UHSO_DPRINTF(0, "Index %d out of range\n", index); 805 return (0); 806 } 807 808 UHSO_DPRINTF(1, "index=%d, type=%x[%s]\n", index, buf[index], 809 uhso_port_type[(int)uhso_port_map[(int)buf[index]]]); 810 811 if (buf[index] >= uhso_port_map_max) 812 port = 0; 813 else 814 port = uhso_port_map[(int)buf[index]]; 815 816 switch (port) { 817 case UHSO_PORT_TYPE_NETWORK: 818 return (UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX, 819 UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, port)); 820 case UHSO_PORT_TYPE_DIAG: 821 case UHSO_PORT_TYPE_DIAG2: 822 case UHSO_PORT_TYPE_GPS: 823 case UHSO_PORT_TYPE_GPSCTL: 824 case UHSO_PORT_TYPE_CTL: 825 case UHSO_PORT_TYPE_APP: 826 case UHSO_PORT_TYPE_APP2: 827 case UHSO_PORT_TYPE_MODEM: 828 return (UHSO_IFACE_SPEC(UHSO_IF_BULK, 829 UHSO_PORT_SERIAL, port)); 830 case UHSO_PORT_TYPE_MSD: 831 return (0); 832 case UHSO_PORT_TYPE_UNKNOWN: 833 default: 834 return (0); 835 } 836 837 return (0); 838 } 839 840 /* 841 * Returns the capabilities of interfaces for devices that don't 842 * support the automatic query. 843 * Returns a bit mask with the interface capabilities. 844 */ 845 static int 846 uhso_probe_iface_static(struct usb_device *udev, int index) 847 { 848 struct usb_config_descriptor *cd; 849 850 cd = usbd_get_config_descriptor(udev); 851 if (cd->bNumInterface <= 3) { 852 /* Cards with 3 or less interfaces */ 853 switch (index) { 854 case 0: 855 return UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX, 856 UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, 857 UHSO_PORT_TYPE_NETWORK); 858 case 1: 859 return UHSO_IFACE_SPEC(UHSO_IF_BULK, 860 UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG); 861 case 2: 862 return UHSO_IFACE_SPEC(UHSO_IF_BULK, 863 UHSO_PORT_SERIAL, UHSO_PORT_TYPE_MODEM); 864 } 865 } else { 866 /* Cards with 4 interfaces */ 867 switch (index) { 868 case 0: 869 return UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX, 870 UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, 871 UHSO_PORT_TYPE_NETWORK); 872 case 1: 873 return UHSO_IFACE_SPEC(UHSO_IF_BULK, 874 UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG2); 875 case 2: 876 return UHSO_IFACE_SPEC(UHSO_IF_BULK, 877 UHSO_PORT_SERIAL, UHSO_PORT_TYPE_MODEM); 878 case 3: 879 return UHSO_IFACE_SPEC(UHSO_IF_BULK, 880 UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG); 881 } 882 } 883 return (0); 884 } 885 886 /* 887 * Probes an interface for its particular capabilities and attaches if 888 * it's a supported interface. 889 */ 890 static int 891 uhso_probe_iface(struct uhso_softc *sc, int index, 892 int (*probe)(struct usb_device *, int)) 893 { 894 struct usb_interface *iface; 895 int type, error; 896 897 UHSO_DPRINTF(1, "Probing for interface %d, probe_func=%p\n", index, probe); 898 899 type = probe(sc->sc_udev, index); 900 UHSO_DPRINTF(1, "Probe result %x\n", type); 901 if (type <= 0) 902 return (ENXIO); 903 904 sc->sc_type = type; 905 iface = usbd_get_iface(sc->sc_udev, index); 906 907 if (UHSO_IFACE_PORT_TYPE(type) == UHSO_PORT_TYPE_NETWORK) { 908 error = uhso_attach_ifnet(sc, iface, type); 909 if (error) { 910 UHSO_DPRINTF(1, "uhso_attach_ifnet failed"); 911 return (ENXIO); 912 } 913 914 /* 915 * If there is an additional interrupt endpoint on this 916 * interface then we most likely have a multiplexed serial port 917 * available. 918 */ 919 if (iface->idesc->bNumEndpoints < 3) { 920 sc->sc_type = UHSO_IFACE_SPEC( 921 UHSO_IFACE_USB_TYPE(type) & ~UHSO_IF_MUX, 922 UHSO_IFACE_PORT(type) & ~UHSO_PORT_SERIAL, 923 UHSO_IFACE_PORT_TYPE(type)); 924 return (0); 925 } 926 927 UHSO_DPRINTF(1, "Trying to attach mux. serial\n"); 928 error = uhso_attach_muxserial(sc, iface, type); 929 if (error == 0 && sc->sc_ttys > 0) { 930 error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom, 931 sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx); 932 if (error) { 933 device_printf(sc->sc_dev, "ucom_attach failed\n"); 934 return (ENXIO); 935 } 936 ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev); 937 938 mtx_lock(&sc->sc_mtx); 939 usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); 940 mtx_unlock(&sc->sc_mtx); 941 } 942 } else if ((UHSO_IFACE_USB_TYPE(type) & UHSO_IF_BULK) && 943 UHSO_IFACE_PORT(type) & UHSO_PORT_SERIAL) { 944 error = uhso_attach_bulkserial(sc, iface, type); 945 if (error) 946 return (ENXIO); 947 948 error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom, 949 sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx); 950 if (error) { 951 device_printf(sc->sc_dev, "ucom_attach failed\n"); 952 return (ENXIO); 953 } 954 ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev); 955 } 956 else { 957 UHSO_DPRINTF(0, "Unknown type %x\n", type); 958 return (ENXIO); 959 } 960 961 return (0); 962 } 963 964 static int 965 uhso_radio_ctrl(struct uhso_softc *sc, int onoff) 966 { 967 struct usb_device_request req; 968 usb_error_t uerr; 969 970 req.bmRequestType = UT_VENDOR; 971 req.bRequest = onoff ? 0x82 : 0x81; 972 USETW(req.wValue, 0); 973 USETW(req.wIndex, 0); 974 USETW(req.wLength, 0); 975 976 uerr = usbd_do_request(sc->sc_udev, NULL, &req, NULL); 977 if (uerr != 0) { 978 device_printf(sc->sc_dev, "usbd_do_request_flags failed: %s\n", 979 usbd_errstr(uerr)); 980 return (-1); 981 } 982 return (onoff); 983 } 984 985 static int 986 uhso_radio_sysctl(SYSCTL_HANDLER_ARGS) 987 { 988 struct uhso_softc *sc = arg1; 989 int error, radio; 990 991 radio = sc->sc_radio; 992 error = sysctl_handle_int(oidp, &radio, 0, req); 993 if (error) 994 return (error); 995 if (radio != sc->sc_radio) { 996 radio = radio != 0 ? 1 : 0; 997 error = uhso_radio_ctrl(sc, radio); 998 if (error != -1) 999 sc->sc_radio = radio; 1000 1001 } 1002 return (0); 1003 } 1004 1005 /* 1006 * Expands allocated memory to fit an additional TTY. 1007 * Two arrays are kept with matching indexes, one for ucom and one 1008 * for our private data. 1009 */ 1010 static int 1011 uhso_alloc_tty(struct uhso_softc *sc) 1012 { 1013 1014 sc->sc_ttys++; 1015 sc->sc_tty = reallocf(sc->sc_tty, sizeof(struct uhso_tty) * sc->sc_ttys, 1016 M_USBDEV, M_WAITOK | M_ZERO); 1017 if (sc->sc_tty == NULL) 1018 return (-1); 1019 1020 sc->sc_ucom = reallocf(sc->sc_ucom, 1021 sizeof(struct ucom_softc) * sc->sc_ttys, M_USBDEV, M_WAITOK | M_ZERO); 1022 if (sc->sc_ucom == NULL) 1023 return (-1); 1024 1025 sc->sc_tty[sc->sc_ttys - 1].ht_sc = sc; 1026 1027 UHSO_DPRINTF(1, "Allocated TTY %d\n", sc->sc_ttys - 1); 1028 return (sc->sc_ttys - 1); 1029 } 1030 1031 /* 1032 * Attach a multiplexed serial port 1033 * Data is read/written with requests on the default control pipe. An interrupt 1034 * endpoint returns when there is new data to be read. 1035 */ 1036 static int 1037 uhso_attach_muxserial(struct uhso_softc *sc, struct usb_interface *iface, 1038 int type) 1039 { 1040 struct usb_descriptor *desc; 1041 int i, port, tty; 1042 usb_error_t uerr; 1043 1044 /* 1045 * The class specific interface (type 0x24) descriptor subtype field 1046 * contains a bitmask that specifies which (and how many) ports that 1047 * are available through this multiplexed serial port. 1048 */ 1049 desc = usbd_find_descriptor(sc->sc_udev, NULL, 1050 iface->idesc->bInterfaceNumber, UDESC_CS_INTERFACE, 0xff, 0, 0); 1051 if (desc == NULL) { 1052 UHSO_DPRINTF(0, "Failed to find UDESC_CS_INTERFACE\n"); 1053 return (ENXIO); 1054 } 1055 1056 UHSO_DPRINTF(1, "Mux port mask %x\n", desc->bDescriptorSubtype); 1057 if (desc->bDescriptorSubtype == 0) 1058 return (ENXIO); 1059 1060 /* 1061 * The bitmask is one octet, loop through the number of 1062 * bits that are set and create a TTY for each. 1063 */ 1064 for (i = 0; i < 8; i++) { 1065 port = (1 << i); 1066 if ((port & desc->bDescriptorSubtype) == port) { 1067 UHSO_DPRINTF(2, "Found mux port %x (%d)\n", port, i); 1068 tty = uhso_alloc_tty(sc); 1069 if (tty < 0) 1070 return (ENOMEM); 1071 sc->sc_tty[tty].ht_muxport = i; 1072 uerr = usbd_transfer_setup(sc->sc_udev, 1073 &sc->sc_iface_index, sc->sc_tty[tty].ht_xfer, 1074 uhso_ctrl_config, UHSO_CTRL_MAX, sc, &sc->sc_mtx); 1075 if (uerr) { 1076 device_printf(sc->sc_dev, 1077 "Failed to setup control pipe: %s\n", 1078 usbd_errstr(uerr)); 1079 return (ENXIO); 1080 } 1081 } 1082 } 1083 1084 /* Setup the intr. endpoint */ 1085 uerr = usbd_transfer_setup(sc->sc_udev, 1086 &iface->idesc->bInterfaceNumber, sc->sc_xfer, 1087 uhso_mux_config, 1, sc, &sc->sc_mtx); 1088 if (uerr) 1089 return (ENXIO); 1090 1091 return (0); 1092 } 1093 1094 /* 1095 * Interrupt callback for the multiplexed serial port. Indicates 1096 * which serial port has data waiting. 1097 */ 1098 static void 1099 uhso_mux_intr_callback(struct usb_xfer *xfer, usb_error_t error) 1100 { 1101 struct usb_page_cache *pc; 1102 struct usb_page_search res; 1103 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1104 unsigned int i, mux; 1105 1106 UHSO_DPRINTF(3, "status %d\n", USB_GET_STATE(xfer)); 1107 1108 switch (USB_GET_STATE(xfer)) { 1109 case USB_ST_TRANSFERRED: 1110 /* 1111 * The multiplexed port number can be found at the first byte. 1112 * It contains a bit mask, we transform this in to an integer. 1113 */ 1114 pc = usbd_xfer_get_frame(xfer, 0); 1115 usbd_get_page(pc, 0, &res); 1116 1117 i = *((unsigned char *)res.buffer); 1118 mux = 0; 1119 while (i >>= 1) { 1120 mux++; 1121 } 1122 1123 UHSO_DPRINTF(3, "mux port %d (%d)\n", mux, i); 1124 if (mux > UHSO_MPORT_TYPE_NOMAX) 1125 break; 1126 1127 /* Issue a read for this serial port */ 1128 usbd_xfer_set_priv( 1129 sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ], 1130 &sc->sc_tty[mux]); 1131 usbd_transfer_start(sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ]); 1132 1133 break; 1134 case USB_ST_SETUP: 1135 tr_setup: 1136 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 1137 usbd_transfer_submit(xfer); 1138 break; 1139 default: 1140 UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); 1141 if (error == USB_ERR_CANCELLED) 1142 break; 1143 1144 usbd_xfer_set_stall(xfer); 1145 goto tr_setup; 1146 } 1147 } 1148 1149 static void 1150 uhso_mux_read_callback(struct usb_xfer *xfer, usb_error_t error) 1151 { 1152 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1153 struct usb_page_cache *pc; 1154 struct usb_device_request req; 1155 struct uhso_tty *ht; 1156 int actlen, len; 1157 1158 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1159 1160 UHSO_DPRINTF(3, "status %d\n", USB_GET_STATE(xfer)); 1161 1162 ht = usbd_xfer_get_priv(xfer); 1163 UHSO_DPRINTF(3, "ht=%p open=%d\n", ht, ht->ht_open); 1164 1165 switch (USB_GET_STATE(xfer)) { 1166 case USB_ST_TRANSFERRED: 1167 /* Got data, send to ucom */ 1168 pc = usbd_xfer_get_frame(xfer, 1); 1169 len = usbd_xfer_frame_len(xfer, 1); 1170 1171 UHSO_DPRINTF(3, "got %d bytes on mux port %d\n", len, 1172 ht->ht_muxport); 1173 if (len <= 0) { 1174 usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); 1175 break; 1176 } 1177 1178 /* Deliver data if the TTY is open, discard otherwise */ 1179 if (ht->ht_open) 1180 ucom_put_data(&sc->sc_ucom[ht->ht_muxport], pc, 0, len); 1181 /* FALLTHROUGH */ 1182 case USB_ST_SETUP: 1183 tr_setup: 1184 memset(&req, 0, sizeof(struct usb_device_request)); 1185 req.bmRequestType = UT_READ_CLASS_INTERFACE; 1186 req.bRequest = UCDC_GET_ENCAPSULATED_RESPONSE; 1187 USETW(req.wValue, 0); 1188 USETW(req.wIndex, ht->ht_muxport); 1189 USETW(req.wLength, 1024); 1190 1191 pc = usbd_xfer_get_frame(xfer, 0); 1192 usbd_copy_in(pc, 0, &req, sizeof(req)); 1193 1194 usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); 1195 usbd_xfer_set_frame_len(xfer, 1, 1024); 1196 usbd_xfer_set_frames(xfer, 2); 1197 usbd_transfer_submit(xfer); 1198 break; 1199 default: 1200 UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); 1201 if (error == USB_ERR_CANCELLED) 1202 break; 1203 usbd_xfer_set_stall(xfer); 1204 goto tr_setup; 1205 } 1206 } 1207 1208 static void 1209 uhso_mux_write_callback(struct usb_xfer *xfer, usb_error_t error) 1210 { 1211 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1212 struct uhso_tty *ht; 1213 struct usb_page_cache *pc; 1214 struct usb_device_request req; 1215 int actlen; 1216 struct usb_page_search res; 1217 1218 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1219 1220 ht = usbd_xfer_get_priv(xfer); 1221 UHSO_DPRINTF(3, "status=%d, using mux port %d\n", 1222 USB_GET_STATE(xfer), ht->ht_muxport); 1223 1224 switch (USB_GET_STATE(xfer)) { 1225 case USB_ST_TRANSFERRED: 1226 UHSO_DPRINTF(3, "wrote %zd data bytes to muxport %d\n", 1227 actlen - sizeof(struct usb_device_request) , 1228 ht->ht_muxport); 1229 /* FALLTHROUGH */ 1230 case USB_ST_SETUP: 1231 tr_setup: 1232 pc = usbd_xfer_get_frame(xfer, 1); 1233 if (ucom_get_data(&sc->sc_ucom[ht->ht_muxport], pc, 1234 0, 32, &actlen)) { 1235 usbd_get_page(pc, 0, &res); 1236 1237 memset(&req, 0, sizeof(struct usb_device_request)); 1238 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 1239 req.bRequest = UCDC_SEND_ENCAPSULATED_COMMAND; 1240 USETW(req.wValue, 0); 1241 USETW(req.wIndex, ht->ht_muxport); 1242 USETW(req.wLength, actlen); 1243 1244 pc = usbd_xfer_get_frame(xfer, 0); 1245 usbd_copy_in(pc, 0, &req, sizeof(req)); 1246 1247 usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); 1248 usbd_xfer_set_frame_len(xfer, 1, actlen); 1249 usbd_xfer_set_frames(xfer, 2); 1250 1251 UHSO_DPRINTF(3, "Prepared %d bytes for transmit " 1252 "on muxport %d\n", actlen, ht->ht_muxport); 1253 1254 usbd_transfer_submit(xfer); 1255 } 1256 break; 1257 default: 1258 UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); 1259 if (error == USB_ERR_CANCELLED) 1260 break; 1261 usbd_xfer_set_stall(xfer); 1262 goto tr_setup; 1263 } 1264 } 1265 1266 static int 1267 uhso_attach_bulkserial(struct uhso_softc *sc, struct usb_interface *iface, 1268 int type) 1269 { 1270 usb_error_t uerr; 1271 int tty; 1272 1273 /* Try attaching RD/WR/INTR first */ 1274 uerr = usbd_transfer_setup(sc->sc_udev, 1275 &iface->idesc->bInterfaceNumber, sc->sc_xfer, 1276 uhso_bs_config, UHSO_BULK_ENDPT_MAX, sc, &sc->sc_mtx); 1277 if (uerr) { 1278 /* Try only RD/WR */ 1279 uerr = usbd_transfer_setup(sc->sc_udev, 1280 &iface->idesc->bInterfaceNumber, sc->sc_xfer, 1281 uhso_bs_config, UHSO_BULK_ENDPT_MAX - 1, sc, &sc->sc_mtx); 1282 } 1283 if (uerr) { 1284 UHSO_DPRINTF(0, "usbd_transfer_setup failed"); 1285 return (-1); 1286 } 1287 1288 tty = uhso_alloc_tty(sc); 1289 if (tty < 0) { 1290 usbd_transfer_unsetup(sc->sc_xfer, UHSO_BULK_ENDPT_MAX); 1291 return (ENOMEM); 1292 } 1293 1294 sc->sc_tty[tty].ht_muxport = -1; 1295 return (0); 1296 } 1297 1298 static void 1299 uhso_bs_read_callback(struct usb_xfer *xfer, usb_error_t error) 1300 { 1301 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1302 struct usb_page_cache *pc; 1303 int actlen; 1304 1305 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1306 1307 UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen); 1308 1309 switch (USB_GET_STATE(xfer)) { 1310 case USB_ST_TRANSFERRED: 1311 pc = usbd_xfer_get_frame(xfer, 0); 1312 ucom_put_data(&sc->sc_ucom[0], pc, 0, actlen); 1313 /* FALLTHROUGH */ 1314 case USB_ST_SETUP: 1315 tr_setup: 1316 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 1317 usbd_transfer_submit(xfer); 1318 break; 1319 default: 1320 UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); 1321 if (error == USB_ERR_CANCELLED) 1322 break; 1323 usbd_xfer_set_stall(xfer); 1324 goto tr_setup; 1325 } 1326 } 1327 1328 static void 1329 uhso_bs_write_callback(struct usb_xfer *xfer, usb_error_t error) 1330 { 1331 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1332 struct usb_page_cache *pc; 1333 int actlen; 1334 1335 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1336 1337 UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen); 1338 1339 switch (USB_GET_STATE(xfer)) { 1340 case USB_ST_TRANSFERRED: 1341 case USB_ST_SETUP: 1342 tr_setup: 1343 pc = usbd_xfer_get_frame(xfer, 0); 1344 if (ucom_get_data(&sc->sc_ucom[0], pc, 0, 8192, &actlen)) { 1345 usbd_xfer_set_frame_len(xfer, 0, actlen); 1346 usbd_transfer_submit(xfer); 1347 } 1348 break; 1349 break; 1350 default: 1351 UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); 1352 if (error == USB_ERR_CANCELLED) 1353 break; 1354 usbd_xfer_set_stall(xfer); 1355 goto tr_setup; 1356 } 1357 } 1358 1359 static void 1360 uhso_bs_cfg(struct uhso_softc *sc) 1361 { 1362 struct usb_device_request req; 1363 usb_error_t uerr; 1364 1365 if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK)) 1366 return; 1367 1368 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 1369 req.bRequest = UCDC_SET_CONTROL_LINE_STATE; 1370 USETW(req.wValue, sc->sc_line); 1371 USETW(req.wIndex, sc->sc_iface_no); 1372 USETW(req.wLength, 0); 1373 1374 uerr = ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom[0], &req, NULL, 0, 1000); 1375 if (uerr != 0) { 1376 device_printf(sc->sc_dev, "failed to set ctrl line state to " 1377 "0x%02x: %s\n", sc->sc_line, usbd_errstr(uerr)); 1378 } 1379 } 1380 1381 static void 1382 uhso_bs_intr_callback(struct usb_xfer *xfer, usb_error_t error) 1383 { 1384 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1385 struct usb_page_cache *pc; 1386 int actlen; 1387 struct usb_cdc_notification cdc; 1388 1389 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1390 UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen); 1391 1392 switch (USB_GET_STATE(xfer)) { 1393 case USB_ST_TRANSFERRED: 1394 if (actlen < UCDC_NOTIFICATION_LENGTH) { 1395 UHSO_DPRINTF(0, "UCDC notification too short: %d\n", actlen); 1396 goto tr_setup; 1397 } 1398 else if (actlen > (int)sizeof(struct usb_cdc_notification)) { 1399 UHSO_DPRINTF(0, "UCDC notification too large: %d\n", actlen); 1400 actlen = sizeof(struct usb_cdc_notification); 1401 } 1402 1403 pc = usbd_xfer_get_frame(xfer, 0); 1404 usbd_copy_out(pc, 0, &cdc, actlen); 1405 1406 if (UGETW(cdc.wIndex) != sc->sc_iface_no) { 1407 UHSO_DPRINTF(0, "Interface mismatch, got %d expected %d\n", 1408 UGETW(cdc.wIndex), sc->sc_iface_no); 1409 goto tr_setup; 1410 } 1411 1412 if (cdc.bmRequestType == UCDC_NOTIFICATION && 1413 cdc.bNotification == UCDC_N_SERIAL_STATE) { 1414 UHSO_DPRINTF(2, "notify = 0x%02x\n", cdc.data[0]); 1415 1416 sc->sc_msr = 0; 1417 sc->sc_lsr = 0; 1418 if (cdc.data[0] & UCDC_N_SERIAL_RI) 1419 sc->sc_msr |= SER_RI; 1420 if (cdc.data[0] & UCDC_N_SERIAL_DSR) 1421 sc->sc_msr |= SER_DSR; 1422 if (cdc.data[0] & UCDC_N_SERIAL_DCD) 1423 sc->sc_msr |= SER_DCD; 1424 1425 ucom_status_change(&sc->sc_ucom[0]); 1426 } 1427 case USB_ST_SETUP: 1428 tr_setup: 1429 default: 1430 if (error == USB_ERR_CANCELLED) 1431 break; 1432 usbd_xfer_set_stall(xfer); 1433 goto tr_setup; 1434 } 1435 } 1436 1437 static void 1438 uhso_ucom_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr) 1439 { 1440 struct uhso_softc *sc = ucom->sc_parent; 1441 1442 *lsr = sc->sc_lsr; 1443 *msr = sc->sc_msr; 1444 } 1445 1446 static void 1447 uhso_ucom_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff) 1448 { 1449 struct uhso_softc *sc = ucom->sc_parent; 1450 1451 if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK)) 1452 return; 1453 1454 if (onoff) 1455 sc->sc_line |= UCDC_LINE_DTR; 1456 else 1457 sc->sc_line &= ~UCDC_LINE_DTR; 1458 1459 uhso_bs_cfg(sc); 1460 } 1461 1462 static void 1463 uhso_ucom_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff) 1464 { 1465 struct uhso_softc *sc = ucom->sc_parent; 1466 1467 if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK)) 1468 return; 1469 1470 if (onoff) 1471 sc->sc_line |= UCDC_LINE_RTS; 1472 else 1473 sc->sc_line &= ~UCDC_LINE_RTS; 1474 1475 uhso_bs_cfg(sc); 1476 } 1477 1478 static void 1479 uhso_ucom_start_read(struct ucom_softc *ucom) 1480 { 1481 struct uhso_softc *sc = ucom->sc_parent; 1482 1483 UHSO_DPRINTF(3, "unit=%d, subunit=%d\n", 1484 ucom->sc_super->sc_unit, ucom->sc_subunit); 1485 1486 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { 1487 sc->sc_tty[ucom->sc_subunit].ht_open = 1; 1488 usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); 1489 } 1490 else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { 1491 sc->sc_tty[0].ht_open = 1; 1492 usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_READ]); 1493 if (sc->sc_xfer[UHSO_BULK_ENDPT_INTR] != NULL) 1494 usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_INTR]); 1495 } 1496 } 1497 1498 static void 1499 uhso_ucom_stop_read(struct ucom_softc *ucom) 1500 { 1501 1502 struct uhso_softc *sc = ucom->sc_parent; 1503 1504 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { 1505 sc->sc_tty[ucom->sc_subunit].ht_open = 0; 1506 usbd_transfer_stop( 1507 sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_READ]); 1508 } 1509 else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { 1510 sc->sc_tty[0].ht_open = 0; 1511 usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_READ]); 1512 if (sc->sc_xfer[UHSO_BULK_ENDPT_INTR] != NULL) 1513 usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_INTR]); 1514 } 1515 } 1516 1517 static void 1518 uhso_ucom_start_write(struct ucom_softc *ucom) 1519 { 1520 struct uhso_softc *sc = ucom->sc_parent; 1521 1522 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { 1523 UHSO_DPRINTF(3, "local unit %d\n", ucom->sc_subunit); 1524 1525 usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); 1526 1527 usbd_xfer_set_priv( 1528 sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE], 1529 &sc->sc_tty[ucom->sc_subunit]); 1530 usbd_transfer_start( 1531 sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]); 1532 } 1533 else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { 1534 usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]); 1535 } 1536 } 1537 1538 static void 1539 uhso_ucom_stop_write(struct ucom_softc *ucom) 1540 { 1541 struct uhso_softc *sc = ucom->sc_parent; 1542 1543 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { 1544 usbd_transfer_stop( 1545 sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]); 1546 } 1547 else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { 1548 usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]); 1549 } 1550 } 1551 1552 static int 1553 uhso_attach_ifnet(struct uhso_softc *sc, struct usb_interface *iface, int type) 1554 { 1555 struct ifnet *ifp; 1556 usb_error_t uerr; 1557 struct sysctl_ctx_list *sctx; 1558 struct sysctl_oid *soid; 1559 unsigned int devunit; 1560 1561 uerr = usbd_transfer_setup(sc->sc_udev, 1562 &iface->idesc->bInterfaceNumber, sc->sc_if_xfer, 1563 uhso_ifnet_config, UHSO_IFNET_MAX, sc, &sc->sc_mtx); 1564 if (uerr) { 1565 UHSO_DPRINTF(0, "usbd_transfer_setup failed: %s\n", 1566 usbd_errstr(uerr)); 1567 return (-1); 1568 } 1569 1570 sc->sc_ifp = ifp = if_alloc(IFT_OTHER); 1571 if (sc->sc_ifp == NULL) { 1572 device_printf(sc->sc_dev, "if_alloc() failed\n"); 1573 return (-1); 1574 } 1575 1576 callout_init_mtx(&sc->sc_c, &sc->sc_mtx, 0); 1577 mtx_lock(&sc->sc_mtx); 1578 callout_reset(&sc->sc_c, 1, uhso_if_rxflush, sc); 1579 mtx_unlock(&sc->sc_mtx); 1580 1581 /* 1582 * We create our own unit numbers for ifnet devices because the 1583 * USB interface unit numbers can be at arbitrary positions yielding 1584 * odd looking device names. 1585 */ 1586 devunit = alloc_unr(uhso_ifnet_unit); 1587 1588 if_initname(ifp, device_get_name(sc->sc_dev), devunit); 1589 ifp->if_mtu = UHSO_MAX_MTU; 1590 ifp->if_ioctl = uhso_if_ioctl; 1591 ifp->if_init = uhso_if_init; 1592 ifp->if_start = uhso_if_start; 1593 ifp->if_output = uhso_if_output; 1594 ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_NOARP; 1595 ifp->if_softc = sc; 1596 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 1597 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 1598 IFQ_SET_READY(&ifp->if_snd); 1599 1600 if_attach(ifp); 1601 bpfattach(ifp, DLT_RAW, 0); 1602 1603 sctx = device_get_sysctl_ctx(sc->sc_dev); 1604 soid = device_get_sysctl_tree(sc->sc_dev); 1605 /* Unlocked read... */ 1606 SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "netif", 1607 CTLFLAG_RD, ifp->if_xname, 0, "Attached network interface"); 1608 1609 return (0); 1610 } 1611 1612 static void 1613 uhso_ifnet_read_callback(struct usb_xfer *xfer, usb_error_t error) 1614 { 1615 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1616 struct mbuf *m; 1617 struct usb_page_cache *pc; 1618 int actlen; 1619 1620 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1621 1622 UHSO_DPRINTF(3, "status=%d, actlen=%d\n", USB_GET_STATE(xfer), actlen); 1623 1624 switch (USB_GET_STATE(xfer)) { 1625 case USB_ST_TRANSFERRED: 1626 if (actlen > 0 && (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)) { 1627 pc = usbd_xfer_get_frame(xfer, 0); 1628 if (mbufq_full(&sc->sc_rxq)) 1629 break; 1630 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 1631 usbd_copy_out(pc, 0, mtod(m, uint8_t *), actlen); 1632 m->m_pkthdr.len = m->m_len = actlen; 1633 /* Enqueue frame for further processing */ 1634 mbufq_enqueue(&sc->sc_rxq, m); 1635 if (!callout_pending(&sc->sc_c) || 1636 !callout_active(&sc->sc_c)) { 1637 callout_schedule(&sc->sc_c, 1); 1638 } 1639 } 1640 /* FALLTHROUGH */ 1641 case USB_ST_SETUP: 1642 tr_setup: 1643 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 1644 usbd_transfer_submit(xfer); 1645 break; 1646 default: 1647 UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); 1648 if (error == USB_ERR_CANCELLED) 1649 break; 1650 usbd_xfer_set_stall(xfer); 1651 goto tr_setup; 1652 } 1653 } 1654 1655 /* 1656 * Deferred RX processing, called with mutex locked. 1657 * 1658 * Each frame we receive might contain several small ip-packets as well 1659 * as partial ip-packets. We need to separate/assemble them into individual 1660 * packets before sending them to the ip-layer. 1661 */ 1662 static void 1663 uhso_if_rxflush(void *arg) 1664 { 1665 struct epoch_tracker et; 1666 struct uhso_softc *sc = arg; 1667 struct ifnet *ifp = sc->sc_ifp; 1668 uint8_t *cp; 1669 struct mbuf *m, *m0, *mwait; 1670 struct ip *ip; 1671 #ifdef INET6 1672 struct ip6_hdr *ip6; 1673 #endif 1674 uint16_t iplen; 1675 int isr; 1676 1677 m = NULL; 1678 mwait = sc->sc_mwait; 1679 NET_EPOCH_ENTER(et); 1680 for (;;) { 1681 if (m == NULL) { 1682 if ((m = mbufq_dequeue(&sc->sc_rxq)) == NULL) 1683 break; 1684 UHSO_DPRINTF(3, "dequeue m=%p, len=%d\n", m, m->m_len); 1685 } 1686 mtx_unlock(&sc->sc_mtx); 1687 1688 /* Do we have a partial packet waiting? */ 1689 if (mwait != NULL) { 1690 m0 = mwait; 1691 mwait = NULL; 1692 1693 UHSO_DPRINTF(3, "partial m0=%p(%d), concat w/ m=%p(%d)\n", 1694 m0, m0->m_len, m, m->m_len); 1695 1696 m_catpkt(m0, m); 1697 m = m_pullup(m0, sizeof(struct ip)); 1698 if (m == NULL) { 1699 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 1700 UHSO_DPRINTF(0, "m_pullup failed\n"); 1701 mtx_lock(&sc->sc_mtx); 1702 continue; 1703 } 1704 UHSO_DPRINTF(3, "Constructed mbuf=%p, len=%d\n", 1705 m, m->m_pkthdr.len); 1706 } 1707 1708 cp = mtod(m, uint8_t *); 1709 ip = (struct ip *)cp; 1710 #ifdef INET6 1711 ip6 = (struct ip6_hdr *)cp; 1712 #endif 1713 1714 /* Check for IPv4 */ 1715 if (ip->ip_v == IPVERSION) { 1716 iplen = htons(ip->ip_len); 1717 isr = NETISR_IP; 1718 } 1719 #ifdef INET6 1720 /* Check for IPv6 */ 1721 else if ((ip6->ip6_vfc & IPV6_VERSION_MASK) == IPV6_VERSION) { 1722 iplen = htons(ip6->ip6_plen); 1723 isr = NETISR_IPV6; 1724 } 1725 #endif 1726 else { 1727 UHSO_DPRINTF(0, "got unexpected ip version %d, " 1728 "m=%p, len=%d\n", (*cp & 0xf0) >> 4, m, m->m_len); 1729 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 1730 UHSO_HEXDUMP(cp, 4); 1731 m_freem(m); 1732 m = NULL; 1733 mtx_lock(&sc->sc_mtx); 1734 continue; 1735 } 1736 1737 if (iplen == 0) { 1738 UHSO_DPRINTF(0, "Zero IP length\n"); 1739 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 1740 m_freem(m); 1741 m = NULL; 1742 mtx_lock(&sc->sc_mtx); 1743 continue; 1744 } 1745 1746 UHSO_DPRINTF(3, "m=%p, len=%d, cp=%p, iplen=%d\n", 1747 m, m->m_pkthdr.len, cp, iplen); 1748 1749 m0 = NULL; 1750 1751 /* More IP packets in this mbuf */ 1752 if (iplen < m->m_pkthdr.len) { 1753 m0 = m; 1754 1755 /* 1756 * Allocate a new mbuf for this IP packet and 1757 * copy the IP-packet into it. 1758 */ 1759 m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR); 1760 memcpy(mtod(m, uint8_t *), mtod(m0, uint8_t *), iplen); 1761 m->m_pkthdr.len = m->m_len = iplen; 1762 1763 /* Adjust the size of the original mbuf */ 1764 m_adj(m0, iplen); 1765 m0 = m_defrag(m0, M_WAITOK); 1766 1767 UHSO_DPRINTF(3, "New mbuf=%p, len=%d/%d, m0=%p, " 1768 "m0_len=%d/%d\n", m, m->m_pkthdr.len, m->m_len, 1769 m0, m0->m_pkthdr.len, m0->m_len); 1770 } 1771 else if (iplen > m->m_pkthdr.len) { 1772 UHSO_DPRINTF(3, "Deferred mbuf=%p, len=%d\n", 1773 m, m->m_pkthdr.len); 1774 mwait = m; 1775 m = NULL; 1776 mtx_lock(&sc->sc_mtx); 1777 continue; 1778 } 1779 1780 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 1781 m->m_pkthdr.rcvif = ifp; 1782 1783 /* Dispatch to IP layer */ 1784 BPF_MTAP(sc->sc_ifp, m); 1785 M_SETFIB(m, ifp->if_fib); 1786 netisr_dispatch(isr, m); 1787 m = m0 != NULL ? m0 : NULL; 1788 mtx_lock(&sc->sc_mtx); 1789 } 1790 NET_EPOCH_EXIT(et); 1791 sc->sc_mwait = mwait; 1792 } 1793 1794 static void 1795 uhso_ifnet_write_callback(struct usb_xfer *xfer, usb_error_t error) 1796 { 1797 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1798 struct ifnet *ifp = sc->sc_ifp; 1799 struct usb_page_cache *pc; 1800 struct mbuf *m; 1801 int actlen; 1802 1803 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1804 1805 UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen); 1806 1807 switch (USB_GET_STATE(xfer)) { 1808 case USB_ST_TRANSFERRED: 1809 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 1810 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1811 case USB_ST_SETUP: 1812 tr_setup: 1813 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 1814 if (m == NULL) 1815 break; 1816 1817 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1818 1819 if (m->m_pkthdr.len > MCLBYTES) 1820 m->m_pkthdr.len = MCLBYTES; 1821 1822 usbd_xfer_set_frame_len(xfer, 0, m->m_pkthdr.len); 1823 pc = usbd_xfer_get_frame(xfer, 0); 1824 usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len); 1825 usbd_transfer_submit(xfer); 1826 1827 BPF_MTAP(ifp, m); 1828 m_freem(m); 1829 break; 1830 default: 1831 UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); 1832 if (error == USB_ERR_CANCELLED) 1833 break; 1834 usbd_xfer_set_stall(xfer); 1835 goto tr_setup; 1836 } 1837 } 1838 1839 static int 1840 uhso_if_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1841 { 1842 struct uhso_softc *sc; 1843 1844 sc = ifp->if_softc; 1845 1846 switch (cmd) { 1847 case SIOCSIFFLAGS: 1848 if (ifp->if_flags & IFF_UP) { 1849 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 1850 uhso_if_init(sc); 1851 } 1852 } 1853 else { 1854 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 1855 mtx_lock(&sc->sc_mtx); 1856 uhso_if_stop(sc); 1857 mtx_unlock(&sc->sc_mtx); 1858 } 1859 } 1860 break; 1861 case SIOCSIFADDR: 1862 case SIOCADDMULTI: 1863 case SIOCDELMULTI: 1864 break; 1865 default: 1866 return (EINVAL); 1867 } 1868 return (0); 1869 } 1870 1871 static void 1872 uhso_if_init(void *priv) 1873 { 1874 struct uhso_softc *sc = priv; 1875 struct ifnet *ifp = sc->sc_ifp; 1876 1877 mtx_lock(&sc->sc_mtx); 1878 uhso_if_stop(sc); 1879 ifp = sc->sc_ifp; 1880 ifp->if_flags |= IFF_UP; 1881 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1882 mtx_unlock(&sc->sc_mtx); 1883 1884 UHSO_DPRINTF(2, "ifnet initialized\n"); 1885 } 1886 1887 static int 1888 uhso_if_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst, 1889 struct route *ro) 1890 { 1891 int error; 1892 1893 /* Only IPv4/6 support */ 1894 if (dst->sa_family != AF_INET 1895 #ifdef INET6 1896 && dst->sa_family != AF_INET6 1897 #endif 1898 ) { 1899 return (EAFNOSUPPORT); 1900 } 1901 1902 error = (ifp->if_transmit)(ifp, m0); 1903 if (error) { 1904 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 1905 return (ENOBUFS); 1906 } 1907 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 1908 return (0); 1909 } 1910 1911 static void 1912 uhso_if_start(struct ifnet *ifp) 1913 { 1914 struct uhso_softc *sc = ifp->if_softc; 1915 1916 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { 1917 UHSO_DPRINTF(1, "Not running\n"); 1918 return; 1919 } 1920 1921 mtx_lock(&sc->sc_mtx); 1922 usbd_transfer_start(sc->sc_if_xfer[UHSO_IFNET_READ]); 1923 usbd_transfer_start(sc->sc_if_xfer[UHSO_IFNET_WRITE]); 1924 mtx_unlock(&sc->sc_mtx); 1925 UHSO_DPRINTF(3, "interface started\n"); 1926 } 1927 1928 static void 1929 uhso_if_stop(struct uhso_softc *sc) 1930 { 1931 1932 usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_READ]); 1933 usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_WRITE]); 1934 sc->sc_ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 1935 } 1936