1 /* $NetBSD: u3g.c,v 1.21 2011/11/06 02:29:33 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2009 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* 32 * Copyright (c) 2008 AnyWi Technologies 33 * Author: Andrea Guzzo <aguzzo@anywi.com> 34 * * based on uark.c 1.1 2006/08/14 08:30:22 jsg * 35 * * parts from ubsa.c 183348 2008-09-25 12:00:56Z phk * 36 * 37 * Permission to use, copy, modify, and distribute this software for any 38 * purpose with or without fee is hereby granted, provided that the above 39 * copyright notice and this permission notice appear in all copies. 40 * 41 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 42 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 43 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 44 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 45 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 46 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 47 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 48 * 49 * $FreeBSD$ 50 */ 51 52 #include <sys/cdefs.h> 53 __KERNEL_RCSID(0, "$NetBSD: u3g.c,v 1.21 2011/11/06 02:29:33 christos Exp $"); 54 55 #include <sys/param.h> 56 #include <sys/systm.h> 57 #include <sys/kernel.h> 58 #include <sys/malloc.h> 59 #include <sys/bus.h> 60 #include <sys/conf.h> 61 #include <sys/tty.h> 62 63 #include <dev/usb/usb.h> 64 #include <dev/usb/usbdi.h> 65 #include <dev/usb/usbdivar.h> 66 #include <dev/usb/usbdi_util.h> 67 68 #include <dev/usb/ucomvar.h> 69 70 #include "usbdevs.h" 71 72 /* 73 * We read/write data from/to the device in 4KB chunks to maximise 74 * performance. 75 */ 76 #define U3G_BUFF_SIZE 4096 77 78 /* 79 * Some 3G devices (the Huawei E160/E220 springs to mind here) buffer up 80 * data internally even when the USB pipes are closed. So on first open, 81 * we can receive a large chunk of stale data. 82 * 83 * This causes a real problem because the default TTYDEF_LFLAG (applied 84 * on first open) has the ECHO flag set, resulting in all the stale data 85 * being echoed straight back to the device by the tty(4) layer. Some 86 * devices (again, the Huawei E160/E220 for example) react to this spew 87 * by going catatonic. 88 * 89 * All this happens before the application gets a chance to disable ECHO. 90 * 91 * We work around this by ignoring all data received from the device for 92 * a period of two seconds, or until the application starts sending data - 93 * whichever comes first. 94 */ 95 #define U3G_PURGE_SECS 2 96 97 /* 98 * Define bits for the virtual modem control pins. 99 * The input pin states are reported via the interrupt pipe on some devices. 100 */ 101 #define U3G_OUTPIN_DTR (1u << 0) 102 #define U3G_OUTPIN_RTS (1u << 1) 103 #define U3G_INPIN_DCD (1u << 0) 104 #define U3G_INPIN_DSR (1u << 1) 105 #define U3G_INPIN_RI (1u << 3) 106 107 /* 108 * USB request to set the output pin status 109 */ 110 #define U3G_SET_PIN 0x22 111 112 struct u3g_softc { 113 device_t sc_dev; 114 usbd_device_handle sc_udev; 115 bool sc_dying; /* We're going away */ 116 117 device_t sc_ucom; /* Child ucom(4) handle */ 118 int sc_ifaceno; /* Device interface number */ 119 120 bool sc_open; /* Device is in use */ 121 bool sc_purging; /* Purging stale data */ 122 struct timeval sc_purge_start; /* Control duration of purge */ 123 124 u_char sc_msr; /* Emulated 'msr' */ 125 uint16_t sc_outpins; /* Output pin state */ 126 127 usbd_pipe_handle sc_intr_pipe; /* Interrupt pipe */ 128 u_char *sc_intr_buff; /* Interrupt buffer */ 129 }; 130 131 /* 132 * The device driver has two personalities. The first uses the 'usbdevif' 133 * interface attribute so that a match will claim the entire USB device 134 * for itself. This is used for when a device needs to be mode-switched 135 * and ensures any other interfaces present cannot be claimed by other 136 * drivers while the mode-switch is in progress. 137 * 138 * The second personality uses the 'usbifif' interface attribute so that 139 * it can claim the 3G modem interfaces for itself, leaving others (such 140 * as the mass storage interfaces on some devices) for other drivers. 141 */ 142 static int u3ginit_match(device_t, cfdata_t, void *); 143 static void u3ginit_attach(device_t, device_t, void *); 144 static int u3ginit_detach(device_t, int); 145 146 CFATTACH_DECL2_NEW(u3ginit, 0, u3ginit_match, 147 u3ginit_attach, u3ginit_detach, NULL, NULL, NULL); 148 149 150 static int u3g_match(device_t, cfdata_t, void *); 151 static void u3g_attach(device_t, device_t, void *); 152 static int u3g_detach(device_t, int); 153 static int u3g_activate(device_t, enum devact); 154 static void u3g_childdet(device_t, device_t); 155 156 CFATTACH_DECL2_NEW(u3g, sizeof(struct u3g_softc), u3g_match, 157 u3g_attach, u3g_detach, u3g_activate, NULL, u3g_childdet); 158 159 160 static void u3g_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); 161 static void u3g_get_status(void *, int, u_char *, u_char *); 162 static void u3g_set(void *, int, int, int); 163 static int u3g_open(void *, int); 164 static void u3g_close(void *, int); 165 static void u3g_read(void *, int, u_char **, uint32_t *); 166 static void u3g_write(void *, int, u_char *, u_char *, u_int32_t *); 167 168 struct ucom_methods u3g_methods = { 169 u3g_get_status, 170 u3g_set, 171 NULL, 172 NULL, 173 u3g_open, 174 u3g_close, 175 u3g_read, 176 u3g_write, 177 }; 178 179 /* 180 * Allegedly supported devices 181 */ 182 static const struct usb_devno u3g_devs[] = { 183 { USB_VENDOR_DELL, USB_PRODUCT_DELL_W5500 }, 184 /* OEM: Huawei */ 185 { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E1750 }, 186 { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E1820 }, 187 { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220 }, 188 { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3765 }, 189 { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE }, 190 /* OEM: Merlin */ 191 { USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620 }, 192 /* OEM: Novatel */ 193 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_ES620 }, 194 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MC950D }, 195 #if 0 196 /* These are matched in u3ginit_match() */ 197 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MC950D_DRIVER }, 198 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_U760_DRIVER }, 199 #endif 200 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MERLINU740 }, 201 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MERLINV620 }, 202 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_S720 }, 203 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_U720 }, 204 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_U727 }, 205 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_U740_2 }, 206 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_U760 }, 207 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_U870 }, 208 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_V740 }, 209 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_X950D }, 210 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_XU870 }, 211 /* OEM: Option N.V. */ 212 { USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_QUADPLUSUMTS }, 213 { USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_HSDPA }, 214 { USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_GTMAXHSUPA }, 215 /* OEM: Qualcomm, Inc. */ 216 { USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM }, 217 { USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_ZTE_MF626 }, 218 219 /* OEM: Sierra Wireless: */ 220 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U }, 221 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E }, 222 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC875U }, 223 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880 }, 224 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E }, 225 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880U }, 226 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881 }, 227 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E }, 228 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881U }, 229 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD580 }, 230 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD595 }, 231 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD875 }, 232 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C597 }, 233 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625 }, 234 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720 }, 235 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720_2 }, 236 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725 }, 237 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755 }, 238 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2 }, 239 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3 }, 240 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765 }, 241 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775_2 }, 242 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780 }, 243 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781 }, 244 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MINI5725 }, 245 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_USB305 }, 246 247 /* Toshiba */ 248 { USB_VENDOR_TOSHIBA, USB_PRODUCT_TOSHIBA_HSDPA_MODEM_EU870DT1 }, 249 250 /* 4G Systems */ 251 { USB_VENDOR_4GSYSTEMS, USB_PRODUCT_4GSYSTEMS_XSSTICK_P14 }, 252 }; 253 254 static int 255 send_bulkmsg(usbd_device_handle dev, void *cmd, size_t cmdlen) 256 { 257 usbd_interface_handle iface; 258 usb_interface_descriptor_t *id; 259 usb_endpoint_descriptor_t *ed; 260 usbd_pipe_handle pipe; 261 usbd_xfer_handle xfer; 262 int err, i; 263 264 /* Move the device into the configured state. */ 265 err = usbd_set_config_index(dev, 0, 0); 266 if (err) { 267 aprint_error("u3g: failed to set configuration index\n"); 268 return UMATCH_NONE; 269 } 270 271 err = usbd_device2interface_handle(dev, 0, &iface); 272 if (err != 0) { 273 aprint_error("u3ginit: failed to get interface\n"); 274 return UMATCH_NONE; 275 } 276 277 id = usbd_get_interface_descriptor(iface); 278 ed = NULL; 279 for (i = 0 ; i < id->bNumEndpoints ; i++) { 280 ed = usbd_interface2endpoint_descriptor(iface, i); 281 if (ed == NULL) 282 continue; 283 if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_OUT) 284 continue; 285 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK) 286 break; 287 } 288 289 if (i == id->bNumEndpoints) 290 return UMATCH_NONE; 291 292 err = usbd_open_pipe(iface, ed->bEndpointAddress, 293 USBD_EXCLUSIVE_USE, &pipe); 294 if (err != 0) { 295 aprint_error("u3ginit: failed to open bulk transfer pipe %d\n", 296 ed->bEndpointAddress); 297 return UMATCH_NONE; 298 } 299 300 xfer = usbd_alloc_xfer(dev); 301 if (xfer != NULL) { 302 usbd_setup_xfer(xfer, pipe, NULL, cmd, cmdlen, 303 USBD_SYNCHRONOUS, USBD_DEFAULT_TIMEOUT, NULL); 304 305 err = usbd_transfer(xfer); 306 307 #if 0 /* XXXpooka: at least my huawei "fails" this always, but still detaches */ 308 if (err) 309 aprint_error("u3ginit: transfer failed\n"); 310 #else 311 err = 0; 312 #endif 313 usbd_free_xfer(xfer); 314 } else { 315 aprint_error("u3ginit: failed to allocate xfer\n"); 316 err = USBD_NOMEM; 317 } 318 319 usbd_abort_pipe(pipe); 320 usbd_close_pipe(pipe); 321 322 return (err == USBD_NORMAL_COMPLETION ? UMATCH_HIGHEST : UMATCH_NONE); 323 } 324 325 static int 326 u3g_novatel_reinit(usbd_device_handle dev) 327 { 328 unsigned char cmd[31]; 329 330 memset(cmd, 0, sizeof(cmd)); 331 /* Byte 0..3: Command Block Wrapper (CBW) signature */ 332 cmd[0] = 0x55; 333 cmd[1] = 0x53; 334 cmd[2] = 0x42; 335 cmd[3] = 0x43; 336 /* 4..7: CBW Tag, has to unique, but only a single transfer used. */ 337 cmd[4] = 0x01; 338 /* 8..11: CBW Transfer Length, no data here */ 339 /* 12: CBW Flag: output, so 0 */ 340 /* 13: CBW Lun: 0 */ 341 /* 14: CBW Length */ 342 cmd[14] = 0x06; 343 /* Rest is the SCSI payload */ 344 /* 0: SCSI START/STOP opcode */ 345 cmd[15] = 0x1b; 346 /* 1..3 unused */ 347 /* 4 Load/Eject command */ 348 cmd[19] = 0x02; 349 /* 5: unused */ 350 351 return send_bulkmsg(dev, cmd, sizeof(cmd)); 352 } 353 354 static int 355 u3g_huawei_reinit(usbd_device_handle dev) 356 { 357 /* 358 * The Huawei device presents itself as a umass device with Windows 359 * drivers on it. After installation of the driver, it reinits into a 360 * 3G serial device. 361 */ 362 usb_device_request_t req; 363 usb_config_descriptor_t *cdesc; 364 365 /* Get the config descriptor */ 366 cdesc = usbd_get_config_descriptor(dev); 367 if (cdesc == NULL) { 368 usb_device_descriptor_t dd; 369 370 if (usbd_get_device_desc(dev, &dd) != 0) 371 return (UMATCH_NONE); 372 373 if (dd.bNumConfigurations != 1) 374 return (UMATCH_NONE); 375 376 if (usbd_set_config_index(dev, 0, 1) != 0) 377 return (UMATCH_NONE); 378 379 cdesc = usbd_get_config_descriptor(dev); 380 381 if (cdesc == NULL) 382 return (UMATCH_NONE); 383 } 384 385 /* 386 * One iface means umass mode, more than 1 (4 usually) means 3G mode. 387 * 388 * XXX: We should check the first interface's device class just to be 389 * sure. If it's a mass storage device, then we can be fairly certain 390 * it needs a mode-switch. 391 */ 392 if (cdesc->bNumInterface > 1) 393 return (UMATCH_NONE); 394 395 req.bmRequestType = UT_WRITE_DEVICE; 396 req.bRequest = UR_SET_FEATURE; 397 USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP); 398 USETW(req.wIndex, UHF_PORT_SUSPEND); 399 USETW(req.wLength, 0); 400 401 (void) usbd_do_request(dev, &req, 0); 402 403 return (UMATCH_HIGHEST); /* Prevent umass from attaching */ 404 } 405 406 static int 407 u3g_huawei_k3765_reinit(usbd_device_handle dev) 408 { 409 unsigned char cmd[31]; 410 411 /* magic string adapted from some webpage */ 412 memset(cmd, 0, sizeof(cmd)); 413 cmd[0] = 0x55; 414 cmd[1] = 0x53; 415 cmd[2] = 0x42; 416 cmd[3] = 0x43; 417 cmd[15]= 0x11; 418 cmd[16]= 0x06; 419 420 return send_bulkmsg(dev, cmd, sizeof(cmd)); 421 } 422 423 static int 424 u3g_sierra_reinit(usbd_device_handle dev) 425 { 426 /* Some Sierra devices presents themselves as a umass device with 427 * Windows drivers on it. After installation of the driver, it 428 * reinits into a * 3G serial device. 429 */ 430 usb_device_request_t req; 431 432 req.bmRequestType = UT_VENDOR; 433 req.bRequest = UR_SET_INTERFACE; 434 USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP); 435 USETW(req.wIndex, UHF_PORT_CONNECTION); 436 USETW(req.wLength, 0); 437 438 (void) usbd_do_request(dev, &req, 0); 439 440 return (UMATCH_HIGHEST); /* Match to prevent umass from attaching */ 441 } 442 443 static int 444 u3g_4gsystems_reinit(usbd_device_handle dev) 445 { 446 /* magic string adapted from usb_modeswitch database */ 447 static unsigned char cmd[31] = { 448 0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0x80, 0x00, 449 0x00, 0x00, 0x80, 0x00, 0x06, 0x06, 0xf5, 0x04, 0x02, 0x52, 450 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 451 0x00 452 }; 453 454 return send_bulkmsg(dev, cmd, sizeof(cmd)); 455 } 456 457 /* 458 * First personality: 459 * 460 * Claim the entire device if a mode-switch is required. 461 */ 462 463 static int 464 u3ginit_match(device_t parent, cfdata_t match, void *aux) 465 { 466 struct usb_attach_arg *uaa = aux; 467 468 /* 469 * Huawei changes product when it is configured as a modem. 470 */ 471 switch (uaa->vendor) { 472 case USB_VENDOR_HUAWEI: 473 if (uaa->product == USB_PRODUCT_HUAWEI_K3765) 474 return UMATCH_NONE; 475 476 switch (uaa->product) { 477 case USB_PRODUCT_HUAWEI_E1750INIT: 478 case USB_PRODUCT_HUAWEI_K3765INIT: 479 return u3g_huawei_k3765_reinit(uaa->device); 480 break; 481 default: 482 return u3g_huawei_reinit(uaa->device); 483 break; 484 } 485 break; 486 487 case USB_VENDOR_NOVATEL2: 488 switch (uaa->product){ 489 case USB_PRODUCT_NOVATEL2_MC950D_DRIVER: 490 case USB_PRODUCT_NOVATEL2_U760_DRIVER: 491 return u3g_novatel_reinit(uaa->device); 492 break; 493 default: 494 break; 495 } 496 break; 497 498 case USB_VENDOR_SIERRA: 499 if (uaa->product == USB_PRODUCT_SIERRA_INSTALLER) 500 return u3g_sierra_reinit(uaa->device); 501 break; 502 503 case USB_VENDOR_QUALCOMMINC: 504 if (uaa->product == USB_PRODUCT_QUALCOMMINC_ZTE_STOR) 505 return u3g_novatel_reinit(uaa->device); 506 break; 507 508 case USB_VENDOR_4GSYSTEMS: 509 if (uaa->product == USB_PRODUCT_4GSYSTEMS_XSSTICK_P14_INSTALLER) 510 return u3g_4gsystems_reinit(uaa->device); 511 break; 512 513 default: 514 break; 515 } 516 517 return UMATCH_NONE; 518 } 519 520 static void 521 u3ginit_attach(device_t parent, device_t self, void *aux) 522 { 523 struct usb_attach_arg *uaa = aux; 524 525 aprint_naive("\n"); 526 aprint_normal(": Switching to 3G mode\n"); 527 528 if (uaa->vendor == USB_VENDOR_NOVATEL2) { 529 switch (uaa->product) { 530 case USB_PRODUCT_NOVATEL2_MC950D_DRIVER: 531 case USB_PRODUCT_NOVATEL2_U760_DRIVER: 532 /* About to disappear... */ 533 return; 534 break; 535 default: 536 break; 537 } 538 } 539 540 /* Move the device into the configured state. */ 541 (void) usbd_set_config_index(uaa->device, 0, 1); 542 } 543 544 static int 545 u3ginit_detach(device_t self, int flags) 546 { 547 548 return (0); 549 } 550 551 552 /* 553 * Second personality: 554 * 555 * Claim only those interfaces required for 3G modem operation. 556 */ 557 558 static int 559 u3g_match(device_t parent, cfdata_t match, void *aux) 560 { 561 struct usbif_attach_arg *uaa = aux; 562 usbd_interface_handle iface; 563 usb_interface_descriptor_t *id; 564 usbd_status error; 565 566 if (!usb_lookup(u3g_devs, uaa->vendor, uaa->product)) 567 return (UMATCH_NONE); 568 569 error = usbd_device2interface_handle(uaa->device, uaa->ifaceno, &iface); 570 if (error) { 571 printf("u3g_match: failed to get interface, err=%s\n", 572 usbd_errstr(error)); 573 return (UMATCH_NONE); 574 } 575 576 id = usbd_get_interface_descriptor(iface); 577 if (id == NULL) { 578 printf("u3g_match: failed to get interface descriptor\n"); 579 return (UMATCH_NONE); 580 } 581 582 /* 583 * 3G modems generally report vendor-specific class 584 * 585 * XXX: this may be too generalised. 586 */ 587 return ((id->bInterfaceClass == UICLASS_VENDOR) ? 588 UMATCH_VENDOR_PRODUCT : UMATCH_NONE); 589 } 590 591 static void 592 u3g_attach(device_t parent, device_t self, void *aux) 593 { 594 struct u3g_softc *sc = device_private(self); 595 struct usbif_attach_arg *uaa = aux; 596 usbd_device_handle dev = uaa->device; 597 usbd_interface_handle iface; 598 usb_interface_descriptor_t *id; 599 usb_endpoint_descriptor_t *ed; 600 struct ucom_attach_args uca; 601 usbd_status error; 602 int n, intr_address, intr_size; 603 604 aprint_naive("\n"); 605 aprint_normal("\n"); 606 607 sc->sc_dev = self; 608 sc->sc_dying = false; 609 sc->sc_udev = dev; 610 611 error = usbd_device2interface_handle(dev, uaa->ifaceno, &iface); 612 if (error) { 613 aprint_error_dev(self, "failed to get interface, err=%s\n", 614 usbd_errstr(error)); 615 return; 616 } 617 618 id = usbd_get_interface_descriptor(iface); 619 620 uca.info = "3G Modem"; 621 uca.ibufsize = U3G_BUFF_SIZE; 622 uca.obufsize = U3G_BUFF_SIZE; 623 uca.ibufsizepad = U3G_BUFF_SIZE; 624 uca.portno = uaa->ifaceno; 625 uca.opkthdrlen = 0; 626 uca.device = dev; 627 uca.iface = iface; 628 uca.methods = &u3g_methods; 629 uca.arg = sc; 630 uca.bulkin = uca.bulkout = -1; 631 632 sc->sc_outpins = 0; 633 sc->sc_msr = UMSR_DSR | UMSR_CTS | UMSR_DCD; 634 sc->sc_ifaceno = uaa->ifaceno; 635 sc->sc_open = false; 636 sc->sc_purging = false; 637 638 intr_address = -1; 639 intr_size = 0; 640 641 for (n = 0; n < id->bNumEndpoints; n++) { 642 ed = usbd_interface2endpoint_descriptor(iface, n); 643 if (ed == NULL) { 644 aprint_error_dev(self, "no endpoint descriptor " 645 "for %d (interface: %d)\n", n, sc->sc_ifaceno); 646 sc->sc_dying = true; 647 return; 648 } 649 650 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 651 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 652 intr_address = ed->bEndpointAddress; 653 intr_size = UGETW(ed->wMaxPacketSize); 654 } else 655 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 656 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 657 uca.bulkin = ed->bEndpointAddress; 658 } else 659 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 660 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 661 uca.bulkout = ed->bEndpointAddress; 662 } 663 } 664 665 if (uca.bulkin == -1) { 666 aprint_error_dev(self, "Missing bulk in for interface %d\n", 667 sc->sc_ifaceno); 668 sc->sc_dying = true; 669 return; 670 } 671 672 if (uca.bulkout == -1) { 673 aprint_error_dev(self, "Missing bulk out for interface %d\n", 674 sc->sc_ifaceno); 675 sc->sc_dying = true; 676 return; 677 } 678 679 sc->sc_ucom = config_found_sm_loc(self, "ucombus", 680 NULL, &uca, ucomprint, ucomsubmatch); 681 682 /* 683 * If the interface has an interrupt pipe, open it immediately so 684 * that we can track input pin state changes regardless of whether 685 * the tty(4) device is open or not. 686 */ 687 if (intr_address != -1) { 688 sc->sc_intr_buff = malloc(intr_size, M_USBDEV, M_WAITOK); 689 error = usbd_open_pipe_intr(iface, intr_address, 690 USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, sc->sc_intr_buff, 691 intr_size, u3g_intr, 100); 692 if (error) { 693 aprint_error_dev(self, "cannot open interrupt pipe " 694 "(addr %d)\n", intr_address); 695 return; 696 } 697 } else { 698 sc->sc_intr_pipe = NULL; 699 sc->sc_intr_buff = NULL; 700 } 701 702 if (!pmf_device_register(self, NULL, NULL)) 703 aprint_error_dev(self, "couldn't establish power handler\n"); 704 } 705 706 static int 707 u3g_detach(device_t self, int flags) 708 { 709 struct u3g_softc *sc = device_private(self); 710 int rv; 711 712 if (sc->sc_dying) 713 return 0; 714 715 pmf_device_deregister(self); 716 717 if (sc->sc_ucom != NULL) { 718 rv = config_detach(sc->sc_ucom, flags); 719 if (rv != 0) { 720 aprint_verbose_dev(self, "Can't deallocate " 721 "port (%d)", rv); 722 } 723 } 724 725 if (sc->sc_intr_pipe != NULL) { 726 (void) usbd_abort_pipe(sc->sc_intr_pipe); 727 (void) usbd_close_pipe(sc->sc_intr_pipe); 728 sc->sc_intr_pipe = NULL; 729 } 730 if (sc->sc_intr_buff != NULL) { 731 free(sc->sc_intr_buff, M_USBDEV); 732 sc->sc_intr_buff = NULL; 733 } 734 735 return (0); 736 } 737 738 static void 739 u3g_childdet(device_t self, device_t child) 740 { 741 struct u3g_softc *sc = device_private(self); 742 743 if (sc->sc_ucom == child) 744 sc->sc_ucom = NULL; 745 } 746 747 static int 748 u3g_activate(device_t self, enum devact act) 749 { 750 struct u3g_softc *sc = device_private(self); 751 int rv; 752 753 switch (act) { 754 case DVACT_DEACTIVATE: 755 if (sc->sc_ucom != NULL && config_deactivate(sc->sc_ucom)) 756 rv = -1; 757 else 758 rv = 0; 759 break; 760 761 default: 762 rv = 0; 763 break; 764 } 765 766 return (rv); 767 } 768 769 static void 770 u3g_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 771 { 772 struct u3g_softc *sc = (struct u3g_softc *)priv; 773 u_char *buf; 774 775 if (sc->sc_dying) 776 return; 777 778 if (status != USBD_NORMAL_COMPLETION) { 779 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 780 return; 781 usbd_clear_endpoint_stall_async(sc->sc_intr_pipe); 782 return; 783 } 784 785 buf = sc->sc_intr_buff; 786 if (buf[0] == 0xa1 && buf[1] == 0x20) { 787 u_char msr; 788 789 msr = sc->sc_msr & ~(UMSR_DCD | UMSR_DSR | UMSR_RI); 790 791 if (buf[8] & U3G_INPIN_DCD) 792 msr |= UMSR_DCD; 793 794 if (buf[8] & U3G_INPIN_DSR) 795 msr |= UMSR_DSR; 796 797 if (buf[8] & U3G_INPIN_RI) 798 msr |= UMSR_RI; 799 800 if (msr != sc->sc_msr) { 801 sc->sc_msr = msr; 802 if (sc->sc_open) 803 ucom_status_change(device_private(sc->sc_ucom)); 804 } 805 } 806 } 807 808 /*ARGSUSED*/ 809 static void 810 u3g_get_status(void *arg, int portno, u_char *lsr, u_char *msr) 811 { 812 struct u3g_softc *sc = arg; 813 814 if (lsr != NULL) 815 *lsr = 0; /* LSR isn't supported */ 816 if (msr != NULL) 817 *msr = sc->sc_msr; 818 } 819 820 /*ARGSUSED*/ 821 static void 822 u3g_set(void *arg, int portno, int reg, int onoff) 823 { 824 struct u3g_softc *sc = arg; 825 usb_device_request_t req; 826 uint16_t mask, new_state; 827 usbd_status err; 828 829 if (sc->sc_dying) 830 return; 831 832 switch (reg) { 833 case UCOM_SET_DTR: 834 mask = U3G_OUTPIN_DTR; 835 break; 836 case UCOM_SET_RTS: 837 mask = U3G_OUTPIN_RTS; 838 break; 839 default: 840 return; 841 } 842 843 new_state = sc->sc_outpins & ~mask; 844 if (onoff) 845 new_state |= mask; 846 847 if (new_state == sc->sc_outpins) 848 return; 849 850 sc->sc_outpins = new_state; 851 852 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 853 req.bRequest = U3G_SET_PIN; 854 USETW(req.wValue, new_state); 855 USETW(req.wIndex, sc->sc_ifaceno); 856 USETW(req.wLength, 0); 857 858 err = usbd_do_request(sc->sc_udev, &req, 0); 859 if (err == USBD_STALLED) 860 usbd_clear_endpoint_stall(sc->sc_udev->default_pipe); 861 } 862 863 /*ARGSUSED*/ 864 static int 865 u3g_open(void *arg, int portno) 866 { 867 struct u3g_softc *sc = arg; 868 usb_device_request_t req; 869 usb_endpoint_descriptor_t *ed; 870 usb_interface_descriptor_t *id; 871 usbd_interface_handle ih; 872 usbd_status err; 873 int i; 874 875 if (sc->sc_dying) 876 return (0); 877 878 err = usbd_device2interface_handle(sc->sc_udev, portno, &ih); 879 if (err) 880 return (EIO); 881 882 id = usbd_get_interface_descriptor(ih); 883 884 for (i = 0; i < id->bNumEndpoints; i++) { 885 ed = usbd_interface2endpoint_descriptor(ih, i); 886 if (ed == NULL) 887 return (EIO); 888 889 if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 890 /* Issue ENDPOINT_HALT request */ 891 req.bmRequestType = UT_WRITE_ENDPOINT; 892 req.bRequest = UR_CLEAR_FEATURE; 893 USETW(req.wValue, UF_ENDPOINT_HALT); 894 USETW(req.wIndex, ed->bEndpointAddress); 895 USETW(req.wLength, 0); 896 err = usbd_do_request(sc->sc_udev, &req, 0); 897 if (err) 898 return (EIO); 899 } 900 } 901 902 sc->sc_open = true; 903 sc->sc_purging = true; 904 getmicrotime(&sc->sc_purge_start); 905 906 return (0); 907 } 908 909 /*ARGSUSED*/ 910 static void 911 u3g_close(void *arg, int portno) 912 { 913 struct u3g_softc *sc = arg; 914 915 sc->sc_open = false; 916 } 917 918 /*ARGSUSED*/ 919 static void 920 u3g_read(void *arg, int portno, u_char **cpp, uint32_t *ccp) 921 { 922 struct u3g_softc *sc = arg; 923 struct timeval curr_tv, diff_tv; 924 925 /* 926 * If we're not purging input data following first open, do nothing. 927 */ 928 if (sc->sc_purging == false) 929 return; 930 931 /* 932 * Otherwise check if the purge timeout has expired 933 */ 934 getmicrotime(&curr_tv); 935 timersub(&curr_tv, &sc->sc_purge_start, &diff_tv); 936 937 if (diff_tv.tv_sec >= U3G_PURGE_SECS) { 938 /* Timeout expired. */ 939 sc->sc_purging = false; 940 } else { 941 /* Still purging. Adjust the caller's byte count. */ 942 *ccp = 0; 943 } 944 } 945 946 /*ARGSUSED*/ 947 static void 948 u3g_write(void *arg, int portno, u_char *to, u_char *from, u_int32_t *count) 949 { 950 struct u3g_softc *sc = arg; 951 952 /* 953 * Stop purging as soon as the first data is written to the device. 954 */ 955 sc->sc_purging = false; 956 memcpy(to, from, *count); 957 } 958