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