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, 0, "USB uhso"); 292 static int uhso_autoswitch = 1; 293 SYSCTL_INT(_hw_usb_uhso, OID_AUTO, auto_switch, CTLFLAG_RWTUN, 294 &uhso_autoswitch, 0, "Automatically switch to modem mode"); 295 296 #ifdef USB_DEBUG 297 #ifdef UHSO_DEBUG 298 static int uhso_debug = UHSO_DEBUG; 299 #else 300 static int uhso_debug = -1; 301 #endif 302 303 SYSCTL_INT(_hw_usb_uhso, OID_AUTO, debug, CTLFLAG_RWTUN, 304 &uhso_debug, 0, "Debug level"); 305 306 #define UHSO_DPRINTF(n, x, ...) {\ 307 if (uhso_debug >= n) {\ 308 printf("%s: " x, __func__, ##__VA_ARGS__);\ 309 }\ 310 } 311 #else 312 #define UHSO_DPRINTF(n, x, ...) 313 #endif 314 315 #ifdef UHSO_DEBUG_HEXDUMP 316 # define UHSO_HEXDUMP(_buf, _len) do { \ 317 { \ 318 size_t __tmp; \ 319 const char *__buf = (const char *)_buf; \ 320 for (__tmp = 0; __tmp < _len; __tmp++) \ 321 printf("%02hhx ", *__buf++); \ 322 printf("\n"); \ 323 } \ 324 } while(0) 325 #else 326 # define UHSO_HEXDUMP(_buf, _len) 327 #endif 328 329 enum { 330 UHSO_MUX_ENDPT_INTR = 0, 331 UHSO_MUX_ENDPT_MAX 332 }; 333 334 enum { 335 UHSO_CTRL_READ = 0, 336 UHSO_CTRL_WRITE, 337 UHSO_CTRL_MAX 338 }; 339 340 enum { 341 UHSO_IFNET_READ = 0, 342 UHSO_IFNET_WRITE, 343 UHSO_IFNET_MAX 344 }; 345 346 enum { 347 UHSO_BULK_ENDPT_READ = 0, 348 UHSO_BULK_ENDPT_WRITE, 349 UHSO_BULK_ENDPT_INTR, 350 UHSO_BULK_ENDPT_MAX 351 }; 352 353 static usb_callback_t uhso_mux_intr_callback; 354 static usb_callback_t uhso_mux_read_callback; 355 static usb_callback_t uhso_mux_write_callback; 356 static usb_callback_t uhso_bs_read_callback; 357 static usb_callback_t uhso_bs_write_callback; 358 static usb_callback_t uhso_bs_intr_callback; 359 static usb_callback_t uhso_ifnet_read_callback; 360 static usb_callback_t uhso_ifnet_write_callback; 361 362 /* Config used for the default control pipes */ 363 static const struct usb_config uhso_ctrl_config[UHSO_CTRL_MAX] = { 364 [UHSO_CTRL_READ] = { 365 .type = UE_CONTROL, 366 .endpoint = 0x00, 367 .direction = UE_DIR_ANY, 368 .flags = { .pipe_bof = 1, .short_xfer_ok = 1 }, 369 .bufsize = sizeof(struct usb_device_request) + 1024, 370 .callback = &uhso_mux_read_callback 371 }, 372 373 [UHSO_CTRL_WRITE] = { 374 .type = UE_CONTROL, 375 .endpoint = 0x00, 376 .direction = UE_DIR_ANY, 377 .flags = { .pipe_bof = 1, .force_short_xfer = 1 }, 378 .bufsize = sizeof(struct usb_device_request) + 1024, 379 .timeout = 1000, 380 .callback = &uhso_mux_write_callback 381 } 382 }; 383 384 /* Config for the multiplexed serial ports */ 385 static const struct usb_config uhso_mux_config[UHSO_MUX_ENDPT_MAX] = { 386 [UHSO_MUX_ENDPT_INTR] = { 387 .type = UE_INTERRUPT, 388 .endpoint = UE_ADDR_ANY, 389 .direction = UE_DIR_IN, 390 .flags = { .short_xfer_ok = 1 }, 391 .bufsize = 0, 392 .callback = &uhso_mux_intr_callback, 393 } 394 }; 395 396 /* Config for the raw IP-packet interface */ 397 static const struct usb_config uhso_ifnet_config[UHSO_IFNET_MAX] = { 398 [UHSO_IFNET_READ] = { 399 .type = UE_BULK, 400 .endpoint = UE_ADDR_ANY, 401 .direction = UE_DIR_IN, 402 .flags = { .pipe_bof = 1, .short_xfer_ok = 1 }, 403 .bufsize = MCLBYTES, 404 .callback = &uhso_ifnet_read_callback 405 }, 406 [UHSO_IFNET_WRITE] = { 407 .type = UE_BULK, 408 .endpoint = UE_ADDR_ANY, 409 .direction = UE_DIR_OUT, 410 .flags = { .pipe_bof = 1, .force_short_xfer = 1 }, 411 .bufsize = MCLBYTES, 412 .timeout = 5 * USB_MS_HZ, 413 .callback = &uhso_ifnet_write_callback 414 } 415 }; 416 417 /* Config for interfaces with normal bulk serial ports */ 418 static const struct usb_config uhso_bs_config[UHSO_BULK_ENDPT_MAX] = { 419 [UHSO_BULK_ENDPT_READ] = { 420 .type = UE_BULK, 421 .endpoint = UE_ADDR_ANY, 422 .direction = UE_DIR_IN, 423 .flags = { .pipe_bof = 1, .short_xfer_ok = 1 }, 424 .bufsize = 4096, 425 .callback = &uhso_bs_read_callback 426 }, 427 428 [UHSO_BULK_ENDPT_WRITE] = { 429 .type = UE_BULK, 430 .endpoint = UE_ADDR_ANY, 431 .direction = UE_DIR_OUT, 432 .flags = { .pipe_bof = 1, .force_short_xfer = 1 }, 433 .bufsize = 8192, 434 .callback = &uhso_bs_write_callback 435 }, 436 437 [UHSO_BULK_ENDPT_INTR] = { 438 .type = UE_INTERRUPT, 439 .endpoint = UE_ADDR_ANY, 440 .direction = UE_DIR_IN, 441 .flags = { .short_xfer_ok = 1 }, 442 .bufsize = 0, 443 .callback = &uhso_bs_intr_callback, 444 } 445 }; 446 447 static int uhso_probe_iface(struct uhso_softc *, int, 448 int (*probe)(struct usb_device *, int)); 449 static int uhso_probe_iface_auto(struct usb_device *, int); 450 static int uhso_probe_iface_static(struct usb_device *, int); 451 static int uhso_attach_muxserial(struct uhso_softc *, struct usb_interface *, 452 int type); 453 static int uhso_attach_bulkserial(struct uhso_softc *, struct usb_interface *, 454 int type); 455 static int uhso_attach_ifnet(struct uhso_softc *, struct usb_interface *, 456 int type); 457 static void uhso_test_autoinst(void *, struct usb_device *, 458 struct usb_attach_arg *); 459 static int uhso_driver_loaded(struct module *, int, void *); 460 static int uhso_radio_sysctl(SYSCTL_HANDLER_ARGS); 461 static int uhso_radio_ctrl(struct uhso_softc *, int); 462 463 static void uhso_free(struct ucom_softc *); 464 static void uhso_ucom_start_read(struct ucom_softc *); 465 static void uhso_ucom_stop_read(struct ucom_softc *); 466 static void uhso_ucom_start_write(struct ucom_softc *); 467 static void uhso_ucom_stop_write(struct ucom_softc *); 468 static void uhso_ucom_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *); 469 static void uhso_ucom_cfg_set_dtr(struct ucom_softc *, uint8_t); 470 static void uhso_ucom_cfg_set_rts(struct ucom_softc *, uint8_t); 471 static void uhso_if_init(void *); 472 static void uhso_if_start(struct ifnet *); 473 static void uhso_if_stop(struct uhso_softc *); 474 static int uhso_if_ioctl(struct ifnet *, u_long, caddr_t); 475 static int uhso_if_output(struct ifnet *, struct mbuf *, 476 const struct sockaddr *, struct route *); 477 static void uhso_if_rxflush(void *); 478 479 static device_probe_t uhso_probe; 480 static device_attach_t uhso_attach; 481 static device_detach_t uhso_detach; 482 static void uhso_free_softc(struct uhso_softc *); 483 484 static device_method_t uhso_methods[] = { 485 DEVMETHOD(device_probe, uhso_probe), 486 DEVMETHOD(device_attach, uhso_attach), 487 DEVMETHOD(device_detach, uhso_detach), 488 { 0, 0 } 489 }; 490 491 static driver_t uhso_driver = { 492 .name = "uhso", 493 .methods = uhso_methods, 494 .size = sizeof(struct uhso_softc) 495 }; 496 497 static devclass_t uhso_devclass; 498 DRIVER_MODULE(uhso, uhub, uhso_driver, uhso_devclass, uhso_driver_loaded, 0); 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, sc, 0, uhso_radio_sysctl, "I", "Enable radio"); 603 604 /* 605 * The default interface description on most Option devices isn't 606 * very helpful. So we skip device_set_usb_desc and set the 607 * device description manually. 608 */ 609 device_set_desc_copy(self, uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)]); 610 /* Announce device */ 611 device_printf(self, "<%s port> at <%s %s> on %s\n", 612 uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)], 613 usb_get_manufacturer(uaa->device), 614 usb_get_product(uaa->device), 615 device_get_nameunit(device_get_parent(self))); 616 617 if (sc->sc_ttys > 0) { 618 SYSCTL_ADD_INT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "ports", 619 CTLFLAG_RD, &sc->sc_ttys, 0, "Number of attached serial ports"); 620 621 tree = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, 622 "port", CTLFLAG_RD, NULL, "Serial ports"); 623 } 624 625 /* 626 * Loop through the number of found TTYs and create sysctl 627 * nodes for them. 628 */ 629 for (i = 0; i < sc->sc_ttys; i++) { 630 ht = &sc->sc_tty[i]; 631 ucom = &sc->sc_ucom[i]; 632 633 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) 634 port = uhso_mux_port_map[ht->ht_muxport]; 635 else 636 port = UHSO_IFACE_PORT_TYPE(sc->sc_type); 637 638 desc = uhso_port_type_sysctl[port]; 639 640 tty_node = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(tree), OID_AUTO, 641 desc, CTLFLAG_RD, NULL, ""); 642 643 ht->ht_name[0] = 0; 644 if (sc->sc_ttys == 1) 645 snprintf(ht->ht_name, 32, "cuaU%d", ucom->sc_super->sc_unit); 646 else { 647 snprintf(ht->ht_name, 32, "cuaU%d.%d", 648 ucom->sc_super->sc_unit, ucom->sc_subunit); 649 } 650 651 desc = uhso_port_type[port]; 652 SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO, 653 "tty", CTLFLAG_RD, ht->ht_name, 0, ""); 654 SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO, 655 "desc", CTLFLAG_RD, desc, 0, ""); 656 657 if (bootverbose) 658 device_printf(sc->sc_dev, 659 "\"%s\" port at %s\n", desc, ht->ht_name); 660 } 661 662 return (0); 663 out: 664 uhso_detach(sc->sc_dev); 665 return (ENXIO); 666 } 667 668 static int 669 uhso_detach(device_t self) 670 { 671 struct uhso_softc *sc = device_get_softc(self); 672 int i; 673 674 usbd_transfer_unsetup(sc->sc_xfer, 3); 675 usbd_transfer_unsetup(sc->sc_ctrl_xfer, UHSO_CTRL_MAX); 676 if (sc->sc_ttys > 0) { 677 ucom_detach(&sc->sc_super_ucom, sc->sc_ucom); 678 679 for (i = 0; i < sc->sc_ttys; i++) { 680 if (sc->sc_tty[i].ht_muxport != -1) { 681 usbd_transfer_unsetup(sc->sc_tty[i].ht_xfer, 682 UHSO_CTRL_MAX); 683 } 684 } 685 } 686 687 if (sc->sc_ifp != NULL) { 688 callout_drain(&sc->sc_c); 689 free_unr(uhso_ifnet_unit, sc->sc_ifp->if_dunit); 690 mtx_lock(&sc->sc_mtx); 691 uhso_if_stop(sc); 692 bpfdetach(sc->sc_ifp); 693 if_detach(sc->sc_ifp); 694 if_free(sc->sc_ifp); 695 mtx_unlock(&sc->sc_mtx); 696 usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX); 697 } 698 699 device_claim_softc(self); 700 701 uhso_free_softc(sc); 702 703 return (0); 704 } 705 706 UCOM_UNLOAD_DRAIN(uhso); 707 708 static void 709 uhso_free_softc(struct uhso_softc *sc) 710 { 711 if (ucom_unref(&sc->sc_super_ucom)) { 712 free(sc->sc_tty, M_USBDEV); 713 free(sc->sc_ucom, M_USBDEV); 714 mtx_destroy(&sc->sc_mtx); 715 device_free_softc(sc); 716 } 717 } 718 719 static void 720 uhso_free(struct ucom_softc *ucom) 721 { 722 uhso_free_softc(ucom->sc_parent); 723 } 724 725 static void 726 uhso_test_autoinst(void *arg, struct usb_device *udev, 727 struct usb_attach_arg *uaa) 728 { 729 struct usb_interface *iface; 730 struct usb_interface_descriptor *id; 731 732 if (uaa->dev_state != UAA_DEV_READY || !uhso_autoswitch) 733 return; 734 735 iface = usbd_get_iface(udev, 0); 736 if (iface == NULL) 737 return; 738 id = iface->idesc; 739 if (id == NULL || id->bInterfaceClass != UICLASS_MASS) 740 return; 741 if (usbd_lookup_id_by_uaa(uhso_devs, sizeof(uhso_devs), uaa)) 742 return; /* no device match */ 743 744 if (usb_msc_eject(udev, 0, MSC_EJECT_REZERO) == 0) { 745 /* success, mark the udev as disappearing */ 746 uaa->dev_state = UAA_DEV_EJECTING; 747 } 748 } 749 750 static int 751 uhso_driver_loaded(struct module *mod, int what, void *arg) 752 { 753 switch (what) { 754 case MOD_LOAD: 755 /* register our autoinstall handler */ 756 uhso_etag = EVENTHANDLER_REGISTER(usb_dev_configured, 757 uhso_test_autoinst, NULL, EVENTHANDLER_PRI_ANY); 758 /* create our unit allocator for inet devs */ 759 uhso_ifnet_unit = new_unrhdr(0, INT_MAX, NULL); 760 break; 761 case MOD_UNLOAD: 762 EVENTHANDLER_DEREGISTER(usb_dev_configured, uhso_etag); 763 delete_unrhdr(uhso_ifnet_unit); 764 break; 765 default: 766 return (EOPNOTSUPP); 767 } 768 return (0); 769 } 770 771 /* 772 * Probe the interface type by querying the device. The elements 773 * of an array indicates the capabilities of a particular interface. 774 * Returns a bit mask with the interface capabilities. 775 */ 776 static int 777 uhso_probe_iface_auto(struct usb_device *udev, int index) 778 { 779 struct usb_device_request req; 780 usb_error_t uerr; 781 uint16_t actlen = 0; 782 char port; 783 char buf[17] = {0}; 784 785 req.bmRequestType = UT_READ_VENDOR_DEVICE; 786 req.bRequest = 0x86; 787 USETW(req.wValue, 0); 788 USETW(req.wIndex, 0); 789 USETW(req.wLength, 17); 790 791 uerr = usbd_do_request_flags(udev, NULL, &req, buf, 792 0, &actlen, USB_MS_HZ); 793 if (uerr != 0) { 794 printf("%s: usbd_do_request_flags failed, %s\n", 795 __func__, usbd_errstr(uerr)); 796 return (0); 797 } 798 799 UHSO_DPRINTF(1, "actlen=%d\n", actlen); 800 UHSO_HEXDUMP(buf, 17); 801 802 if (index < 0 || index > 16) { 803 UHSO_DPRINTF(0, "Index %d out of range\n", index); 804 return (0); 805 } 806 807 UHSO_DPRINTF(1, "index=%d, type=%x[%s]\n", index, buf[index], 808 uhso_port_type[(int)uhso_port_map[(int)buf[index]]]); 809 810 if (buf[index] >= uhso_port_map_max) 811 port = 0; 812 else 813 port = uhso_port_map[(int)buf[index]]; 814 815 switch (port) { 816 case UHSO_PORT_TYPE_NETWORK: 817 return (UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX, 818 UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, port)); 819 case UHSO_PORT_TYPE_DIAG: 820 case UHSO_PORT_TYPE_DIAG2: 821 case UHSO_PORT_TYPE_GPS: 822 case UHSO_PORT_TYPE_GPSCTL: 823 case UHSO_PORT_TYPE_CTL: 824 case UHSO_PORT_TYPE_APP: 825 case UHSO_PORT_TYPE_APP2: 826 case UHSO_PORT_TYPE_MODEM: 827 return (UHSO_IFACE_SPEC(UHSO_IF_BULK, 828 UHSO_PORT_SERIAL, port)); 829 case UHSO_PORT_TYPE_MSD: 830 return (0); 831 case UHSO_PORT_TYPE_UNKNOWN: 832 default: 833 return (0); 834 } 835 836 return (0); 837 } 838 839 /* 840 * Returns the capabilities of interfaces for devices that don't 841 * support the automatic query. 842 * Returns a bit mask with the interface capabilities. 843 */ 844 static int 845 uhso_probe_iface_static(struct usb_device *udev, int index) 846 { 847 struct usb_config_descriptor *cd; 848 849 cd = usbd_get_config_descriptor(udev); 850 if (cd->bNumInterface <= 3) { 851 /* Cards with 3 or less interfaces */ 852 switch (index) { 853 case 0: 854 return UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX, 855 UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, 856 UHSO_PORT_TYPE_NETWORK); 857 case 1: 858 return UHSO_IFACE_SPEC(UHSO_IF_BULK, 859 UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG); 860 case 2: 861 return UHSO_IFACE_SPEC(UHSO_IF_BULK, 862 UHSO_PORT_SERIAL, UHSO_PORT_TYPE_MODEM); 863 } 864 } else { 865 /* Cards with 4 interfaces */ 866 switch (index) { 867 case 0: 868 return UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX, 869 UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, 870 UHSO_PORT_TYPE_NETWORK); 871 case 1: 872 return UHSO_IFACE_SPEC(UHSO_IF_BULK, 873 UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG2); 874 case 2: 875 return UHSO_IFACE_SPEC(UHSO_IF_BULK, 876 UHSO_PORT_SERIAL, UHSO_PORT_TYPE_MODEM); 877 case 3: 878 return UHSO_IFACE_SPEC(UHSO_IF_BULK, 879 UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG); 880 } 881 } 882 return (0); 883 } 884 885 /* 886 * Probes an interface for its particular capabilities and attaches if 887 * it's a supported interface. 888 */ 889 static int 890 uhso_probe_iface(struct uhso_softc *sc, int index, 891 int (*probe)(struct usb_device *, int)) 892 { 893 struct usb_interface *iface; 894 int type, error; 895 896 UHSO_DPRINTF(1, "Probing for interface %d, probe_func=%p\n", index, probe); 897 898 type = probe(sc->sc_udev, index); 899 UHSO_DPRINTF(1, "Probe result %x\n", type); 900 if (type <= 0) 901 return (ENXIO); 902 903 sc->sc_type = type; 904 iface = usbd_get_iface(sc->sc_udev, index); 905 906 if (UHSO_IFACE_PORT_TYPE(type) == UHSO_PORT_TYPE_NETWORK) { 907 error = uhso_attach_ifnet(sc, iface, type); 908 if (error) { 909 UHSO_DPRINTF(1, "uhso_attach_ifnet failed"); 910 return (ENXIO); 911 } 912 913 /* 914 * If there is an additional interrupt endpoint on this 915 * interface then we most likely have a multiplexed serial port 916 * available. 917 */ 918 if (iface->idesc->bNumEndpoints < 3) { 919 sc->sc_type = UHSO_IFACE_SPEC( 920 UHSO_IFACE_USB_TYPE(type) & ~UHSO_IF_MUX, 921 UHSO_IFACE_PORT(type) & ~UHSO_PORT_SERIAL, 922 UHSO_IFACE_PORT_TYPE(type)); 923 return (0); 924 } 925 926 UHSO_DPRINTF(1, "Trying to attach mux. serial\n"); 927 error = uhso_attach_muxserial(sc, iface, type); 928 if (error == 0 && sc->sc_ttys > 0) { 929 error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom, 930 sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx); 931 if (error) { 932 device_printf(sc->sc_dev, "ucom_attach failed\n"); 933 return (ENXIO); 934 } 935 ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev); 936 937 mtx_lock(&sc->sc_mtx); 938 usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); 939 mtx_unlock(&sc->sc_mtx); 940 } 941 } else if ((UHSO_IFACE_USB_TYPE(type) & UHSO_IF_BULK) && 942 UHSO_IFACE_PORT(type) & UHSO_PORT_SERIAL) { 943 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 1236 usbd_get_page(pc, 0, &res); 1237 1238 memset(&req, 0, sizeof(struct usb_device_request)); 1239 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 1240 req.bRequest = UCDC_SEND_ENCAPSULATED_COMMAND; 1241 USETW(req.wValue, 0); 1242 USETW(req.wIndex, ht->ht_muxport); 1243 USETW(req.wLength, actlen); 1244 1245 pc = usbd_xfer_get_frame(xfer, 0); 1246 usbd_copy_in(pc, 0, &req, sizeof(req)); 1247 1248 usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); 1249 usbd_xfer_set_frame_len(xfer, 1, actlen); 1250 usbd_xfer_set_frames(xfer, 2); 1251 1252 UHSO_DPRINTF(3, "Prepared %d bytes for transmit " 1253 "on muxport %d\n", actlen, ht->ht_muxport); 1254 1255 usbd_transfer_submit(xfer); 1256 } 1257 break; 1258 default: 1259 UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); 1260 if (error == USB_ERR_CANCELLED) 1261 break; 1262 usbd_xfer_set_stall(xfer); 1263 goto tr_setup; 1264 } 1265 } 1266 1267 static int 1268 uhso_attach_bulkserial(struct uhso_softc *sc, struct usb_interface *iface, 1269 int type) 1270 { 1271 usb_error_t uerr; 1272 int tty; 1273 1274 /* Try attaching RD/WR/INTR first */ 1275 uerr = usbd_transfer_setup(sc->sc_udev, 1276 &iface->idesc->bInterfaceNumber, sc->sc_xfer, 1277 uhso_bs_config, UHSO_BULK_ENDPT_MAX, sc, &sc->sc_mtx); 1278 if (uerr) { 1279 /* Try only RD/WR */ 1280 uerr = usbd_transfer_setup(sc->sc_udev, 1281 &iface->idesc->bInterfaceNumber, sc->sc_xfer, 1282 uhso_bs_config, UHSO_BULK_ENDPT_MAX - 1, sc, &sc->sc_mtx); 1283 } 1284 if (uerr) { 1285 UHSO_DPRINTF(0, "usbd_transfer_setup failed"); 1286 return (-1); 1287 } 1288 1289 tty = uhso_alloc_tty(sc); 1290 if (tty < 0) { 1291 usbd_transfer_unsetup(sc->sc_xfer, UHSO_BULK_ENDPT_MAX); 1292 return (ENOMEM); 1293 } 1294 1295 sc->sc_tty[tty].ht_muxport = -1; 1296 return (0); 1297 } 1298 1299 static void 1300 uhso_bs_read_callback(struct usb_xfer *xfer, usb_error_t error) 1301 { 1302 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1303 struct usb_page_cache *pc; 1304 int actlen; 1305 1306 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1307 1308 UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen); 1309 1310 switch (USB_GET_STATE(xfer)) { 1311 case USB_ST_TRANSFERRED: 1312 pc = usbd_xfer_get_frame(xfer, 0); 1313 ucom_put_data(&sc->sc_ucom[0], pc, 0, actlen); 1314 /* FALLTHROUGH */ 1315 case USB_ST_SETUP: 1316 tr_setup: 1317 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 1318 usbd_transfer_submit(xfer); 1319 break; 1320 default: 1321 UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); 1322 if (error == USB_ERR_CANCELLED) 1323 break; 1324 usbd_xfer_set_stall(xfer); 1325 goto tr_setup; 1326 } 1327 } 1328 1329 static void 1330 uhso_bs_write_callback(struct usb_xfer *xfer, usb_error_t error) 1331 { 1332 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1333 struct usb_page_cache *pc; 1334 int actlen; 1335 1336 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1337 1338 UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen); 1339 1340 switch (USB_GET_STATE(xfer)) { 1341 case USB_ST_TRANSFERRED: 1342 case USB_ST_SETUP: 1343 tr_setup: 1344 pc = usbd_xfer_get_frame(xfer, 0); 1345 if (ucom_get_data(&sc->sc_ucom[0], pc, 0, 8192, &actlen)) { 1346 usbd_xfer_set_frame_len(xfer, 0, actlen); 1347 usbd_transfer_submit(xfer); 1348 } 1349 break; 1350 break; 1351 default: 1352 UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); 1353 if (error == USB_ERR_CANCELLED) 1354 break; 1355 usbd_xfer_set_stall(xfer); 1356 goto tr_setup; 1357 } 1358 } 1359 1360 static void 1361 uhso_bs_cfg(struct uhso_softc *sc) 1362 { 1363 struct usb_device_request req; 1364 usb_error_t uerr; 1365 1366 if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK)) 1367 return; 1368 1369 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 1370 req.bRequest = UCDC_SET_CONTROL_LINE_STATE; 1371 USETW(req.wValue, sc->sc_line); 1372 USETW(req.wIndex, sc->sc_iface_no); 1373 USETW(req.wLength, 0); 1374 1375 uerr = ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom[0], &req, NULL, 0, 1000); 1376 if (uerr != 0) { 1377 device_printf(sc->sc_dev, "failed to set ctrl line state to " 1378 "0x%02x: %s\n", sc->sc_line, usbd_errstr(uerr)); 1379 } 1380 } 1381 1382 static void 1383 uhso_bs_intr_callback(struct usb_xfer *xfer, usb_error_t error) 1384 { 1385 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1386 struct usb_page_cache *pc; 1387 int actlen; 1388 struct usb_cdc_notification cdc; 1389 1390 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1391 UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen); 1392 1393 switch (USB_GET_STATE(xfer)) { 1394 case USB_ST_TRANSFERRED: 1395 if (actlen < UCDC_NOTIFICATION_LENGTH) { 1396 UHSO_DPRINTF(0, "UCDC notification too short: %d\n", actlen); 1397 goto tr_setup; 1398 } 1399 else if (actlen > (int)sizeof(struct usb_cdc_notification)) { 1400 UHSO_DPRINTF(0, "UCDC notification too large: %d\n", actlen); 1401 actlen = sizeof(struct usb_cdc_notification); 1402 } 1403 1404 pc = usbd_xfer_get_frame(xfer, 0); 1405 usbd_copy_out(pc, 0, &cdc, actlen); 1406 1407 if (UGETW(cdc.wIndex) != sc->sc_iface_no) { 1408 UHSO_DPRINTF(0, "Interface mismatch, got %d expected %d\n", 1409 UGETW(cdc.wIndex), sc->sc_iface_no); 1410 goto tr_setup; 1411 } 1412 1413 if (cdc.bmRequestType == UCDC_NOTIFICATION && 1414 cdc.bNotification == UCDC_N_SERIAL_STATE) { 1415 UHSO_DPRINTF(2, "notify = 0x%02x\n", cdc.data[0]); 1416 1417 sc->sc_msr = 0; 1418 sc->sc_lsr = 0; 1419 if (cdc.data[0] & UCDC_N_SERIAL_RI) 1420 sc->sc_msr |= SER_RI; 1421 if (cdc.data[0] & UCDC_N_SERIAL_DSR) 1422 sc->sc_msr |= SER_DSR; 1423 if (cdc.data[0] & UCDC_N_SERIAL_DCD) 1424 sc->sc_msr |= SER_DCD; 1425 1426 ucom_status_change(&sc->sc_ucom[0]); 1427 } 1428 case USB_ST_SETUP: 1429 tr_setup: 1430 default: 1431 if (error == USB_ERR_CANCELLED) 1432 break; 1433 usbd_xfer_set_stall(xfer); 1434 goto tr_setup; 1435 } 1436 } 1437 1438 static void 1439 uhso_ucom_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr) 1440 { 1441 struct uhso_softc *sc = ucom->sc_parent; 1442 1443 *lsr = sc->sc_lsr; 1444 *msr = sc->sc_msr; 1445 } 1446 1447 static void 1448 uhso_ucom_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff) 1449 { 1450 struct uhso_softc *sc = ucom->sc_parent; 1451 1452 if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK)) 1453 return; 1454 1455 if (onoff) 1456 sc->sc_line |= UCDC_LINE_DTR; 1457 else 1458 sc->sc_line &= ~UCDC_LINE_DTR; 1459 1460 uhso_bs_cfg(sc); 1461 } 1462 1463 static void 1464 uhso_ucom_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff) 1465 { 1466 struct uhso_softc *sc = ucom->sc_parent; 1467 1468 if (!(UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK)) 1469 return; 1470 1471 if (onoff) 1472 sc->sc_line |= UCDC_LINE_RTS; 1473 else 1474 sc->sc_line &= ~UCDC_LINE_RTS; 1475 1476 uhso_bs_cfg(sc); 1477 } 1478 1479 static void 1480 uhso_ucom_start_read(struct ucom_softc *ucom) 1481 { 1482 struct uhso_softc *sc = ucom->sc_parent; 1483 1484 UHSO_DPRINTF(3, "unit=%d, subunit=%d\n", 1485 ucom->sc_super->sc_unit, ucom->sc_subunit); 1486 1487 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { 1488 sc->sc_tty[ucom->sc_subunit].ht_open = 1; 1489 usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); 1490 } 1491 else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { 1492 sc->sc_tty[0].ht_open = 1; 1493 usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_READ]); 1494 if (sc->sc_xfer[UHSO_BULK_ENDPT_INTR] != NULL) 1495 usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_INTR]); 1496 } 1497 } 1498 1499 static void 1500 uhso_ucom_stop_read(struct ucom_softc *ucom) 1501 { 1502 1503 struct uhso_softc *sc = ucom->sc_parent; 1504 1505 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { 1506 sc->sc_tty[ucom->sc_subunit].ht_open = 0; 1507 usbd_transfer_stop( 1508 sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_READ]); 1509 } 1510 else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { 1511 sc->sc_tty[0].ht_open = 0; 1512 usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_READ]); 1513 if (sc->sc_xfer[UHSO_BULK_ENDPT_INTR] != NULL) 1514 usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_INTR]); 1515 } 1516 } 1517 1518 static void 1519 uhso_ucom_start_write(struct ucom_softc *ucom) 1520 { 1521 struct uhso_softc *sc = ucom->sc_parent; 1522 1523 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { 1524 UHSO_DPRINTF(3, "local unit %d\n", ucom->sc_subunit); 1525 1526 usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); 1527 1528 usbd_xfer_set_priv( 1529 sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE], 1530 &sc->sc_tty[ucom->sc_subunit]); 1531 usbd_transfer_start( 1532 sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]); 1533 1534 } 1535 else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { 1536 usbd_transfer_start(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]); 1537 } 1538 } 1539 1540 static void 1541 uhso_ucom_stop_write(struct ucom_softc *ucom) 1542 { 1543 struct uhso_softc *sc = ucom->sc_parent; 1544 1545 if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { 1546 usbd_transfer_stop( 1547 sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]); 1548 } 1549 else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { 1550 usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]); 1551 } 1552 } 1553 1554 static int 1555 uhso_attach_ifnet(struct uhso_softc *sc, struct usb_interface *iface, int type) 1556 { 1557 struct ifnet *ifp; 1558 usb_error_t uerr; 1559 struct sysctl_ctx_list *sctx; 1560 struct sysctl_oid *soid; 1561 unsigned int devunit; 1562 1563 uerr = usbd_transfer_setup(sc->sc_udev, 1564 &iface->idesc->bInterfaceNumber, sc->sc_if_xfer, 1565 uhso_ifnet_config, UHSO_IFNET_MAX, sc, &sc->sc_mtx); 1566 if (uerr) { 1567 UHSO_DPRINTF(0, "usbd_transfer_setup failed: %s\n", 1568 usbd_errstr(uerr)); 1569 return (-1); 1570 } 1571 1572 sc->sc_ifp = ifp = if_alloc(IFT_OTHER); 1573 if (sc->sc_ifp == NULL) { 1574 device_printf(sc->sc_dev, "if_alloc() failed\n"); 1575 return (-1); 1576 } 1577 1578 callout_init_mtx(&sc->sc_c, &sc->sc_mtx, 0); 1579 mtx_lock(&sc->sc_mtx); 1580 callout_reset(&sc->sc_c, 1, uhso_if_rxflush, sc); 1581 mtx_unlock(&sc->sc_mtx); 1582 1583 /* 1584 * We create our own unit numbers for ifnet devices because the 1585 * USB interface unit numbers can be at arbitrary positions yielding 1586 * odd looking device names. 1587 */ 1588 devunit = alloc_unr(uhso_ifnet_unit); 1589 1590 if_initname(ifp, device_get_name(sc->sc_dev), devunit); 1591 ifp->if_mtu = UHSO_MAX_MTU; 1592 ifp->if_ioctl = uhso_if_ioctl; 1593 ifp->if_init = uhso_if_init; 1594 ifp->if_start = uhso_if_start; 1595 ifp->if_output = uhso_if_output; 1596 ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_NOARP; 1597 ifp->if_softc = sc; 1598 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 1599 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 1600 IFQ_SET_READY(&ifp->if_snd); 1601 1602 if_attach(ifp); 1603 bpfattach(ifp, DLT_RAW, 0); 1604 1605 sctx = device_get_sysctl_ctx(sc->sc_dev); 1606 soid = device_get_sysctl_tree(sc->sc_dev); 1607 /* Unlocked read... */ 1608 SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "netif", 1609 CTLFLAG_RD, ifp->if_xname, 0, "Attached network interface"); 1610 1611 return (0); 1612 } 1613 1614 static void 1615 uhso_ifnet_read_callback(struct usb_xfer *xfer, usb_error_t error) 1616 { 1617 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1618 struct mbuf *m; 1619 struct usb_page_cache *pc; 1620 int actlen; 1621 1622 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1623 1624 UHSO_DPRINTF(3, "status=%d, actlen=%d\n", USB_GET_STATE(xfer), actlen); 1625 1626 switch (USB_GET_STATE(xfer)) { 1627 case USB_ST_TRANSFERRED: 1628 if (actlen > 0 && (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)) { 1629 pc = usbd_xfer_get_frame(xfer, 0); 1630 if (mbufq_full(&sc->sc_rxq)) 1631 break; 1632 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); 1633 usbd_copy_out(pc, 0, mtod(m, uint8_t *), actlen); 1634 m->m_pkthdr.len = m->m_len = actlen; 1635 /* Enqueue frame for further processing */ 1636 mbufq_enqueue(&sc->sc_rxq, m); 1637 if (!callout_pending(&sc->sc_c) || 1638 !callout_active(&sc->sc_c)) { 1639 callout_schedule(&sc->sc_c, 1); 1640 } 1641 } 1642 /* FALLTHROUGH */ 1643 case USB_ST_SETUP: 1644 tr_setup: 1645 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 1646 usbd_transfer_submit(xfer); 1647 break; 1648 default: 1649 UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); 1650 if (error == USB_ERR_CANCELLED) 1651 break; 1652 usbd_xfer_set_stall(xfer); 1653 goto tr_setup; 1654 } 1655 } 1656 1657 /* 1658 * Deferred RX processing, called with mutex locked. 1659 * 1660 * Each frame we receive might contain several small ip-packets as well 1661 * as partial ip-packets. We need to separate/assemble them into individual 1662 * packets before sending them to the ip-layer. 1663 */ 1664 static void 1665 uhso_if_rxflush(void *arg) 1666 { 1667 struct epoch_tracker et; 1668 struct uhso_softc *sc = arg; 1669 struct ifnet *ifp = sc->sc_ifp; 1670 uint8_t *cp; 1671 struct mbuf *m, *m0, *mwait; 1672 struct ip *ip; 1673 #ifdef INET6 1674 struct ip6_hdr *ip6; 1675 #endif 1676 uint16_t iplen; 1677 int isr; 1678 1679 m = NULL; 1680 mwait = sc->sc_mwait; 1681 NET_EPOCH_ENTER(et); 1682 for (;;) { 1683 if (m == NULL) { 1684 if ((m = mbufq_dequeue(&sc->sc_rxq)) == NULL) 1685 break; 1686 UHSO_DPRINTF(3, "dequeue m=%p, len=%d\n", m, m->m_len); 1687 } 1688 mtx_unlock(&sc->sc_mtx); 1689 1690 /* Do we have a partial packet waiting? */ 1691 if (mwait != NULL) { 1692 m0 = mwait; 1693 mwait = NULL; 1694 1695 UHSO_DPRINTF(3, "partial m0=%p(%d), concat w/ m=%p(%d)\n", 1696 m0, m0->m_len, m, m->m_len); 1697 1698 m_catpkt(m0, m); 1699 m = m_pullup(m0, sizeof(struct ip)); 1700 if (m == NULL) { 1701 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 1702 UHSO_DPRINTF(0, "m_pullup failed\n"); 1703 mtx_lock(&sc->sc_mtx); 1704 continue; 1705 } 1706 UHSO_DPRINTF(3, "Constructed mbuf=%p, len=%d\n", 1707 m, m->m_pkthdr.len); 1708 } 1709 1710 cp = mtod(m, uint8_t *); 1711 ip = (struct ip *)cp; 1712 #ifdef INET6 1713 ip6 = (struct ip6_hdr *)cp; 1714 #endif 1715 1716 /* Check for IPv4 */ 1717 if (ip->ip_v == IPVERSION) { 1718 iplen = htons(ip->ip_len); 1719 isr = NETISR_IP; 1720 } 1721 #ifdef INET6 1722 /* Check for IPv6 */ 1723 else if ((ip6->ip6_vfc & IPV6_VERSION_MASK) == IPV6_VERSION) { 1724 iplen = htons(ip6->ip6_plen); 1725 isr = NETISR_IPV6; 1726 } 1727 #endif 1728 else { 1729 UHSO_DPRINTF(0, "got unexpected ip version %d, " 1730 "m=%p, len=%d\n", (*cp & 0xf0) >> 4, m, m->m_len); 1731 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 1732 UHSO_HEXDUMP(cp, 4); 1733 m_freem(m); 1734 m = NULL; 1735 mtx_lock(&sc->sc_mtx); 1736 continue; 1737 } 1738 1739 if (iplen == 0) { 1740 UHSO_DPRINTF(0, "Zero IP length\n"); 1741 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 1742 m_freem(m); 1743 m = NULL; 1744 mtx_lock(&sc->sc_mtx); 1745 continue; 1746 } 1747 1748 UHSO_DPRINTF(3, "m=%p, len=%d, cp=%p, iplen=%d\n", 1749 m, m->m_pkthdr.len, cp, iplen); 1750 1751 m0 = NULL; 1752 1753 /* More IP packets in this mbuf */ 1754 if (iplen < m->m_pkthdr.len) { 1755 m0 = m; 1756 1757 /* 1758 * Allocate a new mbuf for this IP packet and 1759 * copy the IP-packet into it. 1760 */ 1761 m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR); 1762 memcpy(mtod(m, uint8_t *), mtod(m0, uint8_t *), iplen); 1763 m->m_pkthdr.len = m->m_len = iplen; 1764 1765 /* Adjust the size of the original mbuf */ 1766 m_adj(m0, iplen); 1767 m0 = m_defrag(m0, M_WAITOK); 1768 1769 UHSO_DPRINTF(3, "New mbuf=%p, len=%d/%d, m0=%p, " 1770 "m0_len=%d/%d\n", m, m->m_pkthdr.len, m->m_len, 1771 m0, m0->m_pkthdr.len, m0->m_len); 1772 } 1773 else if (iplen > m->m_pkthdr.len) { 1774 UHSO_DPRINTF(3, "Deferred mbuf=%p, len=%d\n", 1775 m, m->m_pkthdr.len); 1776 mwait = m; 1777 m = NULL; 1778 mtx_lock(&sc->sc_mtx); 1779 continue; 1780 } 1781 1782 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 1783 m->m_pkthdr.rcvif = ifp; 1784 1785 /* Dispatch to IP layer */ 1786 BPF_MTAP(sc->sc_ifp, m); 1787 M_SETFIB(m, ifp->if_fib); 1788 netisr_dispatch(isr, m); 1789 m = m0 != NULL ? m0 : NULL; 1790 mtx_lock(&sc->sc_mtx); 1791 } 1792 NET_EPOCH_EXIT(et); 1793 sc->sc_mwait = mwait; 1794 } 1795 1796 static void 1797 uhso_ifnet_write_callback(struct usb_xfer *xfer, usb_error_t error) 1798 { 1799 struct uhso_softc *sc = usbd_xfer_softc(xfer); 1800 struct ifnet *ifp = sc->sc_ifp; 1801 struct usb_page_cache *pc; 1802 struct mbuf *m; 1803 int actlen; 1804 1805 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1806 1807 UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen); 1808 1809 switch (USB_GET_STATE(xfer)) { 1810 case USB_ST_TRANSFERRED: 1811 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 1812 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1813 case USB_ST_SETUP: 1814 tr_setup: 1815 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 1816 if (m == NULL) 1817 break; 1818 1819 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1820 1821 if (m->m_pkthdr.len > MCLBYTES) 1822 m->m_pkthdr.len = MCLBYTES; 1823 1824 usbd_xfer_set_frame_len(xfer, 0, m->m_pkthdr.len); 1825 pc = usbd_xfer_get_frame(xfer, 0); 1826 usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len); 1827 usbd_transfer_submit(xfer); 1828 1829 BPF_MTAP(ifp, m); 1830 m_freem(m); 1831 break; 1832 default: 1833 UHSO_DPRINTF(0, "error: %s\n", usbd_errstr(error)); 1834 if (error == USB_ERR_CANCELLED) 1835 break; 1836 usbd_xfer_set_stall(xfer); 1837 goto tr_setup; 1838 } 1839 } 1840 1841 static int 1842 uhso_if_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1843 { 1844 struct uhso_softc *sc; 1845 1846 sc = ifp->if_softc; 1847 1848 switch (cmd) { 1849 case SIOCSIFFLAGS: 1850 if (ifp->if_flags & IFF_UP) { 1851 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 1852 uhso_if_init(sc); 1853 } 1854 } 1855 else { 1856 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 1857 mtx_lock(&sc->sc_mtx); 1858 uhso_if_stop(sc); 1859 mtx_unlock(&sc->sc_mtx); 1860 } 1861 } 1862 break; 1863 case SIOCSIFADDR: 1864 case SIOCADDMULTI: 1865 case SIOCDELMULTI: 1866 break; 1867 default: 1868 return (EINVAL); 1869 } 1870 return (0); 1871 } 1872 1873 static void 1874 uhso_if_init(void *priv) 1875 { 1876 struct uhso_softc *sc = priv; 1877 struct ifnet *ifp = sc->sc_ifp; 1878 1879 mtx_lock(&sc->sc_mtx); 1880 uhso_if_stop(sc); 1881 ifp = sc->sc_ifp; 1882 ifp->if_flags |= IFF_UP; 1883 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1884 mtx_unlock(&sc->sc_mtx); 1885 1886 UHSO_DPRINTF(2, "ifnet initialized\n"); 1887 } 1888 1889 static int 1890 uhso_if_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst, 1891 struct route *ro) 1892 { 1893 int error; 1894 1895 /* Only IPv4/6 support */ 1896 if (dst->sa_family != AF_INET 1897 #ifdef INET6 1898 && dst->sa_family != AF_INET6 1899 #endif 1900 ) { 1901 return (EAFNOSUPPORT); 1902 } 1903 1904 error = (ifp->if_transmit)(ifp, m0); 1905 if (error) { 1906 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 1907 return (ENOBUFS); 1908 } 1909 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 1910 return (0); 1911 } 1912 1913 static void 1914 uhso_if_start(struct ifnet *ifp) 1915 { 1916 struct uhso_softc *sc = ifp->if_softc; 1917 1918 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { 1919 UHSO_DPRINTF(1, "Not running\n"); 1920 return; 1921 } 1922 1923 mtx_lock(&sc->sc_mtx); 1924 usbd_transfer_start(sc->sc_if_xfer[UHSO_IFNET_READ]); 1925 usbd_transfer_start(sc->sc_if_xfer[UHSO_IFNET_WRITE]); 1926 mtx_unlock(&sc->sc_mtx); 1927 UHSO_DPRINTF(3, "interface started\n"); 1928 } 1929 1930 static void 1931 uhso_if_stop(struct uhso_softc *sc) 1932 { 1933 1934 usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_READ]); 1935 usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_WRITE]); 1936 sc->sc_ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 1937 } 1938