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