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