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