1 /* $NetBSD: u3g.c,v 1.26 2012/10/05 22:04:56 khorben 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.26 2012/10/05 22:04:56 khorben 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_EM770W }, 189 { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_K3765 }, 190 { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE }, 191 /* OEM: Merlin */ 192 { USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620 }, 193 /* OEM: Novatel */ 194 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_ES620 }, 195 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_EU8X0D }, 196 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MC950D }, 197 #if 0 198 /* These are matched in u3ginit_match() */ 199 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MC950D_DRIVER }, 200 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_U760_DRIVER }, 201 #endif 202 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MERLINU740 }, 203 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_MERLINV620 }, 204 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_S720 }, 205 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_U720 }, 206 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_U727 }, 207 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_U740_2 }, 208 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_U760 }, 209 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_U870 }, 210 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_V740 }, 211 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_X950D }, 212 { USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_XU870 }, 213 /* OEM: Option N.V. */ 214 { USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_QUADPLUSUMTS }, 215 { USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_HSDPA }, 216 { USB_VENDOR_OPTIONNV, USB_PRODUCT_OPTIONNV_GTMAXHSUPA }, 217 /* OEM: Qualcomm, Inc. */ 218 { USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM }, 219 { USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_ZTE_MF626 }, 220 { USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_NTT_DOCOMO_L02C_MODEM }, 221 222 /* OEM: Sierra Wireless: */ 223 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U }, 224 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E }, 225 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC875U }, 226 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880 }, 227 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E }, 228 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880U }, 229 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881 }, 230 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E }, 231 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881U }, 232 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD580 }, 233 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD595 }, 234 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD875 }, 235 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C597 }, 236 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625 }, 237 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720 }, 238 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720_2 }, 239 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725 }, 240 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755 }, 241 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2 }, 242 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3 }, 243 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765 }, 244 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775_2 }, 245 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780 }, 246 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781 }, 247 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MINI5725 }, 248 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_USB305 }, 249 250 /* Toshiba */ 251 { USB_VENDOR_TOSHIBA, USB_PRODUCT_TOSHIBA_HSDPA_MODEM_EU870DT1 }, 252 253 /* 4G Systems */ 254 { USB_VENDOR_4GSYSTEMS, USB_PRODUCT_4GSYSTEMS_XSSTICK_P14 }, 255 }; 256 257 static int 258 send_bulkmsg(usbd_device_handle dev, void *cmd, size_t cmdlen) 259 { 260 usbd_interface_handle iface; 261 usb_interface_descriptor_t *id; 262 usb_endpoint_descriptor_t *ed; 263 usbd_pipe_handle pipe; 264 usbd_xfer_handle xfer; 265 int err, i; 266 267 /* Move the device into the configured state. */ 268 err = usbd_set_config_index(dev, 0, 0); 269 if (err) { 270 aprint_error("u3g: failed to set configuration index\n"); 271 return UMATCH_NONE; 272 } 273 274 err = usbd_device2interface_handle(dev, 0, &iface); 275 if (err != 0) { 276 aprint_error("u3ginit: failed to get interface\n"); 277 return UMATCH_NONE; 278 } 279 280 id = usbd_get_interface_descriptor(iface); 281 ed = NULL; 282 for (i = 0 ; i < id->bNumEndpoints ; i++) { 283 ed = usbd_interface2endpoint_descriptor(iface, i); 284 if (ed == NULL) 285 continue; 286 if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_OUT) 287 continue; 288 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK) 289 break; 290 } 291 292 if (i == id->bNumEndpoints) 293 return UMATCH_NONE; 294 295 err = usbd_open_pipe(iface, ed->bEndpointAddress, 296 USBD_EXCLUSIVE_USE, &pipe); 297 if (err != 0) { 298 aprint_error("u3ginit: failed to open bulk transfer pipe %d\n", 299 ed->bEndpointAddress); 300 return UMATCH_NONE; 301 } 302 303 xfer = usbd_alloc_xfer(dev); 304 if (xfer != NULL) { 305 usbd_setup_xfer(xfer, pipe, NULL, cmd, cmdlen, 306 USBD_SYNCHRONOUS, USBD_DEFAULT_TIMEOUT, NULL); 307 308 err = usbd_transfer(xfer); 309 310 #if 0 /* XXXpooka: at least my huawei "fails" this always, but still detaches */ 311 if (err) 312 aprint_error("u3ginit: transfer failed\n"); 313 #else 314 err = 0; 315 #endif 316 usbd_free_xfer(xfer); 317 } else { 318 aprint_error("u3ginit: failed to allocate xfer\n"); 319 err = USBD_NOMEM; 320 } 321 322 usbd_abort_pipe(pipe); 323 usbd_close_pipe(pipe); 324 325 return (err == USBD_NORMAL_COMPLETION ? UMATCH_HIGHEST : UMATCH_NONE); 326 } 327 328 static int 329 u3g_novatel_reinit(usbd_device_handle dev) 330 { 331 unsigned char cmd[31]; 332 333 memset(cmd, 0, sizeof(cmd)); 334 /* Byte 0..3: Command Block Wrapper (CBW) signature */ 335 cmd[0] = 0x55; 336 cmd[1] = 0x53; 337 cmd[2] = 0x42; 338 cmd[3] = 0x43; 339 /* 4..7: CBW Tag, has to unique, but only a single transfer used. */ 340 cmd[4] = 0x01; 341 /* 8..11: CBW Transfer Length, no data here */ 342 /* 12: CBW Flag: output, so 0 */ 343 /* 13: CBW Lun: 0 */ 344 /* 14: CBW Length */ 345 cmd[14] = 0x06; 346 /* Rest is the SCSI payload */ 347 /* 0: SCSI START/STOP opcode */ 348 cmd[15] = 0x1b; 349 /* 1..3 unused */ 350 /* 4 Load/Eject command */ 351 cmd[19] = 0x02; 352 /* 5: unused */ 353 354 return send_bulkmsg(dev, cmd, sizeof(cmd)); 355 } 356 357 static int 358 u3g_huawei_reinit(usbd_device_handle dev) 359 { 360 /* 361 * The Huawei device presents itself as a umass device with Windows 362 * drivers on it. After installation of the driver, it reinits into a 363 * 3G serial device. 364 */ 365 usb_device_request_t req; 366 usb_config_descriptor_t *cdesc; 367 368 /* Get the config descriptor */ 369 cdesc = usbd_get_config_descriptor(dev); 370 if (cdesc == NULL) { 371 usb_device_descriptor_t dd; 372 373 if (usbd_get_device_desc(dev, &dd) != 0) 374 return (UMATCH_NONE); 375 376 if (dd.bNumConfigurations != 1) 377 return (UMATCH_NONE); 378 379 if (usbd_set_config_index(dev, 0, 1) != 0) 380 return (UMATCH_NONE); 381 382 cdesc = usbd_get_config_descriptor(dev); 383 384 if (cdesc == NULL) 385 return (UMATCH_NONE); 386 } 387 388 /* 389 * One iface means umass mode, more than 1 (4 usually) means 3G mode. 390 * 391 * XXX: We should check the first interface's device class just to be 392 * sure. If it's a mass storage device, then we can be fairly certain 393 * it needs a mode-switch. 394 */ 395 if (cdesc->bNumInterface > 1) 396 return (UMATCH_NONE); 397 398 req.bmRequestType = UT_WRITE_DEVICE; 399 req.bRequest = UR_SET_FEATURE; 400 USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP); 401 USETW(req.wIndex, UHF_PORT_SUSPEND); 402 USETW(req.wLength, 0); 403 404 (void) usbd_do_request(dev, &req, 0); 405 406 return (UMATCH_HIGHEST); /* Prevent umass from attaching */ 407 } 408 409 static int 410 u3g_huawei_k3765_reinit(usbd_device_handle dev) 411 { 412 unsigned char cmd[31]; 413 414 /* magic string adapted from some webpage */ 415 memset(cmd, 0, sizeof(cmd)); 416 cmd[0] = 0x55; 417 cmd[1] = 0x53; 418 cmd[2] = 0x42; 419 cmd[3] = 0x43; 420 cmd[15]= 0x11; 421 cmd[16]= 0x06; 422 423 return send_bulkmsg(dev, cmd, sizeof(cmd)); 424 } 425 426 static int 427 u3g_sierra_reinit(usbd_device_handle dev) 428 { 429 /* Some Sierra devices presents themselves as a umass device with 430 * Windows drivers on it. After installation of the driver, it 431 * reinits into a * 3G serial device. 432 */ 433 usb_device_request_t req; 434 435 req.bmRequestType = UT_VENDOR; 436 req.bRequest = UR_SET_INTERFACE; 437 USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP); 438 USETW(req.wIndex, UHF_PORT_CONNECTION); 439 USETW(req.wLength, 0); 440 441 (void) usbd_do_request(dev, &req, 0); 442 443 return (UMATCH_HIGHEST); /* Match to prevent umass from attaching */ 444 } 445 446 static int 447 u3g_4gsystems_reinit(usbd_device_handle dev) 448 { 449 /* magic string adapted from usb_modeswitch database */ 450 static unsigned char cmd[31] = { 451 0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0x80, 0x00, 452 0x00, 0x00, 0x80, 0x00, 0x06, 0x06, 0xf5, 0x04, 0x02, 0x52, 453 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 454 0x00 455 }; 456 457 return send_bulkmsg(dev, cmd, sizeof(cmd)); 458 } 459 460 /* 461 * First personality: 462 * 463 * Claim the entire device if a mode-switch is required. 464 */ 465 466 static int 467 u3ginit_match(device_t parent, cfdata_t match, void *aux) 468 { 469 struct usb_attach_arg *uaa = aux; 470 471 /* 472 * Huawei changes product when it is configured as a modem. 473 */ 474 switch (uaa->vendor) { 475 case USB_VENDOR_HUAWEI: 476 if (uaa->product == USB_PRODUCT_HUAWEI_K3765) 477 return UMATCH_NONE; 478 479 switch (uaa->product) { 480 case USB_PRODUCT_HUAWEI_E1750INIT: 481 case USB_PRODUCT_HUAWEI_K3765INIT: 482 return u3g_huawei_k3765_reinit(uaa->device); 483 break; 484 default: 485 return u3g_huawei_reinit(uaa->device); 486 break; 487 } 488 break; 489 490 case USB_VENDOR_NOVATEL2: 491 switch (uaa->product){ 492 case USB_PRODUCT_NOVATEL2_MC950D_DRIVER: 493 case USB_PRODUCT_NOVATEL2_U760_DRIVER: 494 return u3g_novatel_reinit(uaa->device); 495 break; 496 default: 497 break; 498 } 499 break; 500 501 case USB_VENDOR_SIERRA: 502 if (uaa->product == USB_PRODUCT_SIERRA_INSTALLER) 503 return u3g_sierra_reinit(uaa->device); 504 break; 505 506 case USB_VENDOR_QUALCOMMINC: 507 if (uaa->product == USB_PRODUCT_QUALCOMMINC_ZTE_STOR) 508 return u3g_novatel_reinit(uaa->device); 509 break; 510 511 case USB_VENDOR_QUALCOMM: 512 if (uaa->product == USB_PRODUCT_QUALCOMM_NTT_DOCOMO_L02C_STORAGE) 513 return u3g_novatel_reinit(uaa->device); 514 break; 515 516 case USB_VENDOR_4GSYSTEMS: 517 if (uaa->product == USB_PRODUCT_4GSYSTEMS_XSSTICK_P14_INSTALLER) 518 return u3g_4gsystems_reinit(uaa->device); 519 break; 520 521 default: 522 break; 523 } 524 525 return UMATCH_NONE; 526 } 527 528 static void 529 u3ginit_attach(device_t parent, device_t self, void *aux) 530 { 531 struct usb_attach_arg *uaa = aux; 532 533 aprint_naive("\n"); 534 aprint_normal(": Switching to 3G mode\n"); 535 536 if (uaa->vendor == USB_VENDOR_NOVATEL2) { 537 switch (uaa->product) { 538 case USB_PRODUCT_NOVATEL2_MC950D_DRIVER: 539 case USB_PRODUCT_NOVATEL2_U760_DRIVER: 540 /* About to disappear... */ 541 return; 542 break; 543 default: 544 break; 545 } 546 } 547 548 /* Move the device into the configured state. */ 549 (void) usbd_set_config_index(uaa->device, 0, 1); 550 } 551 552 static int 553 u3ginit_detach(device_t self, int flags) 554 { 555 556 return (0); 557 } 558 559 560 /* 561 * Second personality: 562 * 563 * Claim only those interfaces required for 3G modem operation. 564 */ 565 566 static int 567 u3g_match(device_t parent, cfdata_t match, void *aux) 568 { 569 struct usbif_attach_arg *uaa = aux; 570 usbd_interface_handle iface; 571 usb_interface_descriptor_t *id; 572 usbd_status error; 573 574 if (!usb_lookup(u3g_devs, uaa->vendor, uaa->product)) 575 return (UMATCH_NONE); 576 577 error = usbd_device2interface_handle(uaa->device, uaa->ifaceno, &iface); 578 if (error) { 579 printf("u3g_match: failed to get interface, err=%s\n", 580 usbd_errstr(error)); 581 return (UMATCH_NONE); 582 } 583 584 id = usbd_get_interface_descriptor(iface); 585 if (id == NULL) { 586 printf("u3g_match: failed to get interface descriptor\n"); 587 return (UMATCH_NONE); 588 } 589 590 /* 591 * 3G modems generally report vendor-specific class 592 * 593 * XXX: this may be too generalised. 594 */ 595 return ((id->bInterfaceClass == UICLASS_VENDOR) ? 596 UMATCH_VENDOR_PRODUCT : UMATCH_NONE); 597 } 598 599 static void 600 u3g_attach(device_t parent, device_t self, void *aux) 601 { 602 struct u3g_softc *sc = device_private(self); 603 struct usbif_attach_arg *uaa = aux; 604 usbd_device_handle dev = uaa->device; 605 usbd_interface_handle iface; 606 usb_interface_descriptor_t *id; 607 usb_endpoint_descriptor_t *ed; 608 struct ucom_attach_args uca; 609 usbd_status error; 610 int n, intr_address, intr_size; 611 612 aprint_naive("\n"); 613 aprint_normal("\n"); 614 615 sc->sc_dev = self; 616 sc->sc_dying = false; 617 sc->sc_udev = dev; 618 619 error = usbd_device2interface_handle(dev, uaa->ifaceno, &iface); 620 if (error) { 621 aprint_error_dev(self, "failed to get interface, err=%s\n", 622 usbd_errstr(error)); 623 return; 624 } 625 626 id = usbd_get_interface_descriptor(iface); 627 628 uca.info = "3G Modem"; 629 uca.ibufsize = U3G_BUFF_SIZE; 630 uca.obufsize = U3G_BUFF_SIZE; 631 uca.ibufsizepad = U3G_BUFF_SIZE; 632 uca.portno = uaa->ifaceno; 633 uca.opkthdrlen = 0; 634 uca.device = dev; 635 uca.iface = iface; 636 uca.methods = &u3g_methods; 637 uca.arg = sc; 638 uca.bulkin = uca.bulkout = -1; 639 640 sc->sc_outpins = 0; 641 sc->sc_msr = UMSR_DSR | UMSR_CTS | UMSR_DCD; 642 sc->sc_ifaceno = uaa->ifaceno; 643 sc->sc_open = false; 644 sc->sc_purging = false; 645 646 intr_address = -1; 647 intr_size = 0; 648 649 for (n = 0; n < id->bNumEndpoints; n++) { 650 ed = usbd_interface2endpoint_descriptor(iface, n); 651 if (ed == NULL) { 652 aprint_error_dev(self, "no endpoint descriptor " 653 "for %d (interface: %d)\n", n, sc->sc_ifaceno); 654 sc->sc_dying = true; 655 return; 656 } 657 658 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 659 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 660 intr_address = ed->bEndpointAddress; 661 intr_size = UGETW(ed->wMaxPacketSize); 662 } else 663 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 664 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 665 uca.bulkin = ed->bEndpointAddress; 666 } else 667 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 668 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 669 uca.bulkout = ed->bEndpointAddress; 670 } 671 } 672 673 if (uca.bulkin == -1) { 674 aprint_error_dev(self, "Missing bulk in for interface %d\n", 675 sc->sc_ifaceno); 676 sc->sc_dying = true; 677 return; 678 } 679 680 if (uca.bulkout == -1) { 681 aprint_error_dev(self, "Missing bulk out for interface %d\n", 682 sc->sc_ifaceno); 683 sc->sc_dying = true; 684 return; 685 } 686 687 sc->sc_ucom = config_found_sm_loc(self, "ucombus", 688 NULL, &uca, ucomprint, ucomsubmatch); 689 690 /* 691 * If the interface has an interrupt pipe, open it immediately so 692 * that we can track input pin state changes regardless of whether 693 * the tty(4) device is open or not. 694 */ 695 if (intr_address != -1) { 696 sc->sc_intr_buff = malloc(intr_size, M_USBDEV, M_WAITOK); 697 error = usbd_open_pipe_intr(iface, intr_address, 698 USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, sc->sc_intr_buff, 699 intr_size, u3g_intr, 100); 700 if (error) { 701 aprint_error_dev(self, "cannot open interrupt pipe " 702 "(addr %d)\n", intr_address); 703 return; 704 } 705 } else { 706 sc->sc_intr_pipe = NULL; 707 sc->sc_intr_buff = NULL; 708 } 709 710 if (!pmf_device_register(self, NULL, NULL)) 711 aprint_error_dev(self, "couldn't establish power handler\n"); 712 } 713 714 static int 715 u3g_detach(device_t self, int flags) 716 { 717 struct u3g_softc *sc = device_private(self); 718 int rv; 719 720 if (sc->sc_dying) 721 return 0; 722 723 pmf_device_deregister(self); 724 725 if (sc->sc_ucom != NULL) { 726 rv = config_detach(sc->sc_ucom, flags); 727 if (rv != 0) { 728 aprint_verbose_dev(self, "Can't deallocate " 729 "port (%d)", rv); 730 } 731 } 732 733 if (sc->sc_intr_pipe != NULL) { 734 (void) usbd_abort_pipe(sc->sc_intr_pipe); 735 (void) usbd_close_pipe(sc->sc_intr_pipe); 736 sc->sc_intr_pipe = NULL; 737 } 738 if (sc->sc_intr_buff != NULL) { 739 free(sc->sc_intr_buff, M_USBDEV); 740 sc->sc_intr_buff = NULL; 741 } 742 743 return (0); 744 } 745 746 static void 747 u3g_childdet(device_t self, device_t child) 748 { 749 struct u3g_softc *sc = device_private(self); 750 751 if (sc->sc_ucom == child) 752 sc->sc_ucom = NULL; 753 } 754 755 static int 756 u3g_activate(device_t self, enum devact act) 757 { 758 struct u3g_softc *sc = device_private(self); 759 int rv; 760 761 switch (act) { 762 case DVACT_DEACTIVATE: 763 if (sc->sc_ucom != NULL && config_deactivate(sc->sc_ucom)) 764 rv = -1; 765 else 766 rv = 0; 767 break; 768 769 default: 770 rv = 0; 771 break; 772 } 773 774 return (rv); 775 } 776 777 static void 778 u3g_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 779 { 780 struct u3g_softc *sc = (struct u3g_softc *)priv; 781 u_char *buf; 782 783 if (sc->sc_dying) 784 return; 785 786 if (status != USBD_NORMAL_COMPLETION) { 787 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 788 return; 789 usbd_clear_endpoint_stall_async(sc->sc_intr_pipe); 790 return; 791 } 792 793 buf = sc->sc_intr_buff; 794 if (buf[0] == 0xa1 && buf[1] == 0x20) { 795 u_char msr; 796 797 msr = sc->sc_msr & ~(UMSR_DCD | UMSR_DSR | UMSR_RI); 798 799 if (buf[8] & U3G_INPIN_DCD) 800 msr |= UMSR_DCD; 801 802 if (buf[8] & U3G_INPIN_DSR) 803 msr |= UMSR_DSR; 804 805 if (buf[8] & U3G_INPIN_RI) 806 msr |= UMSR_RI; 807 808 if (msr != sc->sc_msr) { 809 sc->sc_msr = msr; 810 if (sc->sc_open) 811 ucom_status_change(device_private(sc->sc_ucom)); 812 } 813 } 814 } 815 816 /*ARGSUSED*/ 817 static void 818 u3g_get_status(void *arg, int portno, u_char *lsr, u_char *msr) 819 { 820 struct u3g_softc *sc = arg; 821 822 if (lsr != NULL) 823 *lsr = 0; /* LSR isn't supported */ 824 if (msr != NULL) 825 *msr = sc->sc_msr; 826 } 827 828 /*ARGSUSED*/ 829 static void 830 u3g_set(void *arg, int portno, int reg, int onoff) 831 { 832 struct u3g_softc *sc = arg; 833 usb_device_request_t req; 834 uint16_t mask, new_state; 835 usbd_status err; 836 837 if (sc->sc_dying) 838 return; 839 840 switch (reg) { 841 case UCOM_SET_DTR: 842 mask = U3G_OUTPIN_DTR; 843 break; 844 case UCOM_SET_RTS: 845 mask = U3G_OUTPIN_RTS; 846 break; 847 default: 848 return; 849 } 850 851 new_state = sc->sc_outpins & ~mask; 852 if (onoff) 853 new_state |= mask; 854 855 if (new_state == sc->sc_outpins) 856 return; 857 858 sc->sc_outpins = new_state; 859 860 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 861 req.bRequest = U3G_SET_PIN; 862 USETW(req.wValue, new_state); 863 USETW(req.wIndex, sc->sc_ifaceno); 864 USETW(req.wLength, 0); 865 866 err = usbd_do_request(sc->sc_udev, &req, 0); 867 if (err == USBD_STALLED) 868 usbd_clear_endpoint_stall(sc->sc_udev->default_pipe); 869 } 870 871 /*ARGSUSED*/ 872 static int 873 u3g_open(void *arg, int portno) 874 { 875 struct u3g_softc *sc = arg; 876 usb_device_request_t req; 877 usb_endpoint_descriptor_t *ed; 878 usb_interface_descriptor_t *id; 879 usbd_interface_handle ih; 880 usbd_status err; 881 int i; 882 883 if (sc->sc_dying) 884 return (0); 885 886 err = usbd_device2interface_handle(sc->sc_udev, portno, &ih); 887 if (err) 888 return (EIO); 889 890 id = usbd_get_interface_descriptor(ih); 891 892 for (i = 0; i < id->bNumEndpoints; i++) { 893 ed = usbd_interface2endpoint_descriptor(ih, i); 894 if (ed == NULL) 895 return (EIO); 896 897 if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 898 /* Issue ENDPOINT_HALT request */ 899 req.bmRequestType = UT_WRITE_ENDPOINT; 900 req.bRequest = UR_CLEAR_FEATURE; 901 USETW(req.wValue, UF_ENDPOINT_HALT); 902 USETW(req.wIndex, ed->bEndpointAddress); 903 USETW(req.wLength, 0); 904 err = usbd_do_request(sc->sc_udev, &req, 0); 905 if (err) 906 return (EIO); 907 } 908 } 909 910 sc->sc_open = true; 911 sc->sc_purging = true; 912 getmicrotime(&sc->sc_purge_start); 913 914 return (0); 915 } 916 917 /*ARGSUSED*/ 918 static void 919 u3g_close(void *arg, int portno) 920 { 921 struct u3g_softc *sc = arg; 922 923 sc->sc_open = false; 924 } 925 926 /*ARGSUSED*/ 927 static void 928 u3g_read(void *arg, int portno, u_char **cpp, uint32_t *ccp) 929 { 930 struct u3g_softc *sc = arg; 931 struct timeval curr_tv, diff_tv; 932 933 /* 934 * If we're not purging input data following first open, do nothing. 935 */ 936 if (sc->sc_purging == false) 937 return; 938 939 /* 940 * Otherwise check if the purge timeout has expired 941 */ 942 getmicrotime(&curr_tv); 943 timersub(&curr_tv, &sc->sc_purge_start, &diff_tv); 944 945 if (diff_tv.tv_sec >= U3G_PURGE_SECS) { 946 /* Timeout expired. */ 947 sc->sc_purging = false; 948 } else { 949 /* Still purging. Adjust the caller's byte count. */ 950 *ccp = 0; 951 } 952 } 953 954 /*ARGSUSED*/ 955 static void 956 u3g_write(void *arg, int portno, u_char *to, u_char *from, u_int32_t *count) 957 { 958 struct u3g_softc *sc = arg; 959 960 /* 961 * Stop purging as soon as the first data is written to the device. 962 */ 963 sc->sc_purging = false; 964 memcpy(to, from, *count); 965 } 966