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