1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * USB HandSpring Visor, Palm m50x, and Sony Clie driver 4 * (supports all of the Palm OS USB devices) 5 * 6 * Copyright (C) 1999 - 2004 7 * Greg Kroah-Hartman (greg@kroah.com) 8 * 9 * See Documentation/usb/usb-serial.txt for more information on using this 10 * driver 11 * 12 */ 13 14 #include <linux/kernel.h> 15 #include <linux/errno.h> 16 #include <linux/slab.h> 17 #include <linux/tty.h> 18 #include <linux/tty_driver.h> 19 #include <linux/tty_flip.h> 20 #include <linux/module.h> 21 #include <linux/moduleparam.h> 22 #include <linux/spinlock.h> 23 #include <linux/uaccess.h> 24 #include <linux/usb.h> 25 #include <linux/usb/serial.h> 26 #include <linux/usb/cdc.h> 27 #include "visor.h" 28 29 /* 30 * Version Information 31 */ 32 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>" 33 #define DRIVER_DESC "USB HandSpring Visor / Palm OS driver" 34 35 /* function prototypes for a handspring visor */ 36 static int visor_open(struct tty_struct *tty, struct usb_serial_port *port); 37 static void visor_close(struct usb_serial_port *port); 38 static int visor_probe(struct usb_serial *serial, 39 const struct usb_device_id *id); 40 static int visor_calc_num_ports(struct usb_serial *serial, 41 struct usb_serial_endpoints *epds); 42 static int clie_5_calc_num_ports(struct usb_serial *serial, 43 struct usb_serial_endpoints *epds); 44 static void visor_read_int_callback(struct urb *urb); 45 static int clie_3_5_startup(struct usb_serial *serial); 46 static int palm_os_3_probe(struct usb_serial *serial, 47 const struct usb_device_id *id); 48 static int palm_os_4_probe(struct usb_serial *serial, 49 const struct usb_device_id *id); 50 51 static const struct usb_device_id id_table[] = { 52 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID), 53 .driver_info = (kernel_ulong_t)&palm_os_3_probe }, 54 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID), 55 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 56 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID), 57 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 58 { USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID), 59 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 60 { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID), 61 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 62 { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID), 63 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 64 { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID), 65 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 66 { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID), 67 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 68 { USB_DEVICE(PALM_VENDOR_ID, PALM_M100_ID), 69 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 70 { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID), 71 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 72 { USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID), 73 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 74 { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID), 75 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 76 { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650), 77 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 78 { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID), 79 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 80 { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID), 81 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 82 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID), 83 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 84 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID), 85 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 86 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID), 87 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 88 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID), 89 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 90 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID), 91 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 92 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID), 93 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 94 { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID), 95 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 96 { USB_DEVICE_INTERFACE_CLASS(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID, 0xff), 97 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 98 { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), 99 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 100 { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID), 101 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 102 { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID), 103 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 104 { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID), 105 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 106 { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID), 107 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 108 { USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID), 109 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 110 { } /* Terminating entry */ 111 }; 112 113 static const struct usb_device_id clie_id_5_table[] = { 114 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID), 115 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 116 { } /* Terminating entry */ 117 }; 118 119 static const struct usb_device_id clie_id_3_5_table[] = { 120 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) }, 121 { } /* Terminating entry */ 122 }; 123 124 static const struct usb_device_id id_table_combined[] = { 125 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) }, 126 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) }, 127 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID) }, 128 { USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID) }, 129 { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) }, 130 { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) }, 131 { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) }, 132 { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) }, 133 { USB_DEVICE(PALM_VENDOR_ID, PALM_M100_ID) }, 134 { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) }, 135 { USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) }, 136 { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) }, 137 { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) }, 138 { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) }, 139 { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) }, 140 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) }, 141 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, 142 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) }, 143 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) }, 144 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) }, 145 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) }, 146 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID) }, 147 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID) }, 148 { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) }, 149 { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID) }, 150 { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID) }, 151 { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) }, 152 { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) }, 153 { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) }, 154 { USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID) }, 155 { } /* Terminating entry */ 156 }; 157 158 MODULE_DEVICE_TABLE(usb, id_table_combined); 159 160 /* All of the device info needed for the Handspring Visor, 161 and Palm 4.0 devices */ 162 static struct usb_serial_driver handspring_device = { 163 .driver = { 164 .owner = THIS_MODULE, 165 .name = "visor", 166 }, 167 .description = "Handspring Visor / Palm OS", 168 .id_table = id_table, 169 .num_ports = 2, 170 .bulk_out_size = 256, 171 .open = visor_open, 172 .close = visor_close, 173 .throttle = usb_serial_generic_throttle, 174 .unthrottle = usb_serial_generic_unthrottle, 175 .probe = visor_probe, 176 .calc_num_ports = visor_calc_num_ports, 177 .read_int_callback = visor_read_int_callback, 178 }; 179 180 /* All of the device info needed for the Clie UX50, TH55 Palm 5.0 devices */ 181 static struct usb_serial_driver clie_5_device = { 182 .driver = { 183 .owner = THIS_MODULE, 184 .name = "clie_5", 185 }, 186 .description = "Sony Clie 5.0", 187 .id_table = clie_id_5_table, 188 .num_ports = 2, 189 .num_bulk_out = 2, 190 .bulk_out_size = 256, 191 .open = visor_open, 192 .close = visor_close, 193 .throttle = usb_serial_generic_throttle, 194 .unthrottle = usb_serial_generic_unthrottle, 195 .probe = visor_probe, 196 .calc_num_ports = clie_5_calc_num_ports, 197 .read_int_callback = visor_read_int_callback, 198 }; 199 200 /* device info for the Sony Clie OS version 3.5 */ 201 static struct usb_serial_driver clie_3_5_device = { 202 .driver = { 203 .owner = THIS_MODULE, 204 .name = "clie_3.5", 205 }, 206 .description = "Sony Clie 3.5", 207 .id_table = clie_id_3_5_table, 208 .num_ports = 1, 209 .bulk_out_size = 256, 210 .open = visor_open, 211 .close = visor_close, 212 .throttle = usb_serial_generic_throttle, 213 .unthrottle = usb_serial_generic_unthrottle, 214 .attach = clie_3_5_startup, 215 }; 216 217 static struct usb_serial_driver * const serial_drivers[] = { 218 &handspring_device, &clie_5_device, &clie_3_5_device, NULL 219 }; 220 221 /****************************************************************************** 222 * Handspring Visor specific driver functions 223 ******************************************************************************/ 224 static int visor_open(struct tty_struct *tty, struct usb_serial_port *port) 225 { 226 int result = 0; 227 228 if (!port->read_urb) { 229 /* this is needed for some brain dead Sony devices */ 230 dev_err(&port->dev, "Device lied about number of ports, please use a lower one.\n"); 231 return -ENODEV; 232 } 233 234 /* Start reading from the device */ 235 result = usb_serial_generic_open(tty, port); 236 if (result) 237 goto exit; 238 239 if (port->interrupt_in_urb) { 240 dev_dbg(&port->dev, "adding interrupt input for treo\n"); 241 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 242 if (result) 243 dev_err(&port->dev, 244 "%s - failed submitting interrupt urb, error %d\n", 245 __func__, result); 246 } 247 exit: 248 return result; 249 } 250 251 252 static void visor_close(struct usb_serial_port *port) 253 { 254 unsigned char *transfer_buffer; 255 256 usb_serial_generic_close(port); 257 usb_kill_urb(port->interrupt_in_urb); 258 259 transfer_buffer = kmalloc(0x12, GFP_KERNEL); 260 if (!transfer_buffer) 261 return; 262 usb_control_msg(port->serial->dev, 263 usb_rcvctrlpipe(port->serial->dev, 0), 264 VISOR_CLOSE_NOTIFICATION, 0xc2, 265 0x0000, 0x0000, 266 transfer_buffer, 0x12, 300); 267 kfree(transfer_buffer); 268 } 269 270 static void visor_read_int_callback(struct urb *urb) 271 { 272 struct usb_serial_port *port = urb->context; 273 int status = urb->status; 274 int result; 275 276 switch (status) { 277 case 0: 278 /* success */ 279 break; 280 case -ECONNRESET: 281 case -ENOENT: 282 case -ESHUTDOWN: 283 /* this urb is terminated, clean up */ 284 dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n", 285 __func__, status); 286 return; 287 default: 288 dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n", 289 __func__, status); 290 goto exit; 291 } 292 293 /* 294 * This information is still unknown what it can be used for. 295 * If anyone has an idea, please let the author know... 296 * 297 * Rumor has it this endpoint is used to notify when data 298 * is ready to be read from the bulk ones. 299 */ 300 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, 301 urb->transfer_buffer); 302 303 exit: 304 result = usb_submit_urb(urb, GFP_ATOMIC); 305 if (result) 306 dev_err(&urb->dev->dev, 307 "%s - Error %d submitting interrupt urb\n", 308 __func__, result); 309 } 310 311 static int palm_os_3_probe(struct usb_serial *serial, 312 const struct usb_device_id *id) 313 { 314 struct device *dev = &serial->dev->dev; 315 struct visor_connection_info *connection_info; 316 unsigned char *transfer_buffer; 317 char *string; 318 int retval = 0; 319 int i; 320 int num_ports = 0; 321 322 transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL); 323 if (!transfer_buffer) 324 return -ENOMEM; 325 326 /* send a get connection info request */ 327 retval = usb_control_msg(serial->dev, 328 usb_rcvctrlpipe(serial->dev, 0), 329 VISOR_GET_CONNECTION_INFORMATION, 330 0xc2, 0x0000, 0x0000, transfer_buffer, 331 sizeof(*connection_info), 300); 332 if (retval < 0) { 333 dev_err(dev, "%s - error %d getting connection information\n", 334 __func__, retval); 335 goto exit; 336 } 337 338 if (retval != sizeof(*connection_info)) { 339 dev_err(dev, "Invalid connection information received from device\n"); 340 retval = -ENODEV; 341 goto exit; 342 } 343 344 connection_info = (struct visor_connection_info *)transfer_buffer; 345 346 num_ports = le16_to_cpu(connection_info->num_ports); 347 348 /* Handle devices that report invalid stuff here. */ 349 if (num_ports == 0 || num_ports > 2) { 350 dev_warn(dev, "%s: No valid connect info available\n", 351 serial->type->description); 352 num_ports = 2; 353 } 354 355 for (i = 0; i < num_ports; ++i) { 356 switch (connection_info->connections[i].port_function_id) { 357 case VISOR_FUNCTION_GENERIC: 358 string = "Generic"; 359 break; 360 case VISOR_FUNCTION_DEBUGGER: 361 string = "Debugger"; 362 break; 363 case VISOR_FUNCTION_HOTSYNC: 364 string = "HotSync"; 365 break; 366 case VISOR_FUNCTION_CONSOLE: 367 string = "Console"; 368 break; 369 case VISOR_FUNCTION_REMOTE_FILE_SYS: 370 string = "Remote File System"; 371 break; 372 default: 373 string = "unknown"; 374 break; 375 } 376 dev_info(dev, "%s: port %d, is for %s use\n", 377 serial->type->description, 378 connection_info->connections[i].port, string); 379 } 380 dev_info(dev, "%s: Number of ports: %d\n", serial->type->description, 381 num_ports); 382 383 /* 384 * save off our num_ports info so that we can use it in the 385 * calc_num_ports callback 386 */ 387 usb_set_serial_data(serial, (void *)(long)num_ports); 388 389 /* ask for the number of bytes available, but ignore the 390 response as it is broken */ 391 retval = usb_control_msg(serial->dev, 392 usb_rcvctrlpipe(serial->dev, 0), 393 VISOR_REQUEST_BYTES_AVAILABLE, 394 0xc2, 0x0000, 0x0005, transfer_buffer, 395 0x02, 300); 396 if (retval < 0) 397 dev_err(dev, "%s - error %d getting bytes available request\n", 398 __func__, retval); 399 retval = 0; 400 401 exit: 402 kfree(transfer_buffer); 403 404 return retval; 405 } 406 407 static int palm_os_4_probe(struct usb_serial *serial, 408 const struct usb_device_id *id) 409 { 410 struct device *dev = &serial->dev->dev; 411 struct palm_ext_connection_info *connection_info; 412 unsigned char *transfer_buffer; 413 int retval; 414 415 transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL); 416 if (!transfer_buffer) 417 return -ENOMEM; 418 419 retval = usb_control_msg(serial->dev, 420 usb_rcvctrlpipe(serial->dev, 0), 421 PALM_GET_EXT_CONNECTION_INFORMATION, 422 0xc2, 0x0000, 0x0000, transfer_buffer, 423 sizeof(*connection_info), 300); 424 if (retval < 0) 425 dev_err(dev, "%s - error %d getting connection info\n", 426 __func__, retval); 427 else 428 usb_serial_debug_data(dev, __func__, retval, transfer_buffer); 429 430 kfree(transfer_buffer); 431 return 0; 432 } 433 434 435 static int visor_probe(struct usb_serial *serial, 436 const struct usb_device_id *id) 437 { 438 int retval = 0; 439 int (*startup)(struct usb_serial *serial, 440 const struct usb_device_id *id); 441 442 /* 443 * some Samsung Android phones in modem mode have the same ID 444 * as SPH-I500, but they are ACM devices, so dont bind to them 445 */ 446 if (id->idVendor == SAMSUNG_VENDOR_ID && 447 id->idProduct == SAMSUNG_SPH_I500_ID && 448 serial->dev->descriptor.bDeviceClass == USB_CLASS_COMM && 449 serial->dev->descriptor.bDeviceSubClass == 450 USB_CDC_SUBCLASS_ACM) 451 return -ENODEV; 452 453 if (serial->dev->actconfig->desc.bConfigurationValue != 1) { 454 dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", 455 serial->dev->actconfig->desc.bConfigurationValue); 456 return -ENODEV; 457 } 458 459 if (id->driver_info) { 460 startup = (void *)id->driver_info; 461 retval = startup(serial, id); 462 } 463 464 return retval; 465 } 466 467 static int visor_calc_num_ports(struct usb_serial *serial, 468 struct usb_serial_endpoints *epds) 469 { 470 unsigned int vid = le16_to_cpu(serial->dev->descriptor.idVendor); 471 int num_ports = (int)(long)(usb_get_serial_data(serial)); 472 473 if (num_ports) 474 usb_set_serial_data(serial, NULL); 475 476 /* 477 * Only swap the bulk endpoints for the Handspring devices with 478 * interrupt in endpoints, which for now are the Treo devices. 479 */ 480 if (!(vid == HANDSPRING_VENDOR_ID || vid == KYOCERA_VENDOR_ID) || 481 epds->num_interrupt_in == 0) 482 goto out; 483 484 if (epds->num_bulk_in < 2 || epds->num_interrupt_in < 2) { 485 dev_err(&serial->interface->dev, "missing endpoints\n"); 486 return -ENODEV; 487 } 488 489 /* 490 * It appears that Treos and Kyoceras want to use the 491 * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint, 492 * so let's swap the 1st and 2nd bulk in and interrupt endpoints. 493 * Note that swapping the bulk out endpoints would break lots of 494 * apps that want to communicate on the second port. 495 */ 496 swap(epds->bulk_in[0], epds->bulk_in[1]); 497 swap(epds->interrupt_in[0], epds->interrupt_in[1]); 498 out: 499 return num_ports; 500 } 501 502 static int clie_5_calc_num_ports(struct usb_serial *serial, 503 struct usb_serial_endpoints *epds) 504 { 505 /* 506 * TH55 registers 2 ports. 507 * Communication in from the UX50/TH55 uses the first bulk-in 508 * endpoint, while communication out to the UX50/TH55 uses the second 509 * bulk-out endpoint. 510 */ 511 512 /* 513 * FIXME: Should we swap the descriptors instead of using the same 514 * bulk-out endpoint for both ports? 515 */ 516 epds->bulk_out[0] = epds->bulk_out[1]; 517 518 return serial->type->num_ports; 519 } 520 521 static int clie_3_5_startup(struct usb_serial *serial) 522 { 523 struct device *dev = &serial->dev->dev; 524 int result; 525 u8 *data; 526 527 data = kmalloc(1, GFP_KERNEL); 528 if (!data) 529 return -ENOMEM; 530 531 /* 532 * Note that PEG-300 series devices expect the following two calls. 533 */ 534 535 /* get the config number */ 536 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 537 USB_REQ_GET_CONFIGURATION, USB_DIR_IN, 538 0, 0, data, 1, 3000); 539 if (result < 0) { 540 dev_err(dev, "%s: get config number failed: %d\n", 541 __func__, result); 542 goto out; 543 } 544 if (result != 1) { 545 dev_err(dev, "%s: get config number bad return length: %d\n", 546 __func__, result); 547 result = -EIO; 548 goto out; 549 } 550 551 /* get the interface number */ 552 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 553 USB_REQ_GET_INTERFACE, 554 USB_DIR_IN | USB_RECIP_INTERFACE, 555 0, 0, data, 1, 3000); 556 if (result < 0) { 557 dev_err(dev, "%s: get interface number failed: %d\n", 558 __func__, result); 559 goto out; 560 } 561 if (result != 1) { 562 dev_err(dev, 563 "%s: get interface number bad return length: %d\n", 564 __func__, result); 565 result = -EIO; 566 goto out; 567 } 568 569 result = 0; 570 out: 571 kfree(data); 572 573 return result; 574 } 575 576 module_usb_serial_driver(serial_drivers, id_table_combined); 577 578 MODULE_AUTHOR(DRIVER_AUTHOR); 579 MODULE_DESCRIPTION(DRIVER_DESC); 580 MODULE_LICENSE("GPL v2"); 581