1 /* 2 * USB HandSpring Visor, Palm m50x, and Sony Clie driver 3 * (supports all of the Palm OS USB devices) 4 * 5 * Copyright (C) 1999 - 2004 6 * Greg Kroah-Hartman (greg@kroah.com) 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License version 10 * 2 as published by the Free Software Foundation. 11 * 12 * See Documentation/usb/usb-serial.txt for more information on using this 13 * driver 14 * 15 */ 16 17 #include <linux/kernel.h> 18 #include <linux/errno.h> 19 #include <linux/init.h> 20 #include <linux/slab.h> 21 #include <linux/tty.h> 22 #include <linux/tty_driver.h> 23 #include <linux/tty_flip.h> 24 #include <linux/module.h> 25 #include <linux/moduleparam.h> 26 #include <linux/spinlock.h> 27 #include <linux/uaccess.h> 28 #include <linux/usb.h> 29 #include <linux/usb/serial.h> 30 #include <linux/usb/cdc.h> 31 #include "visor.h" 32 33 /* 34 * Version Information 35 */ 36 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>" 37 #define DRIVER_DESC "USB HandSpring Visor / Palm OS driver" 38 39 /* function prototypes for a handspring visor */ 40 static int visor_open(struct tty_struct *tty, struct usb_serial_port *port); 41 static void visor_close(struct usb_serial_port *port); 42 static int visor_probe(struct usb_serial *serial, 43 const struct usb_device_id *id); 44 static int visor_calc_num_ports(struct usb_serial *serial); 45 static void visor_read_int_callback(struct urb *urb); 46 static int clie_3_5_startup(struct usb_serial *serial); 47 static int treo_attach(struct usb_serial *serial); 48 static int clie_5_attach(struct usb_serial *serial); 49 static int palm_os_3_probe(struct usb_serial *serial, 50 const struct usb_device_id *id); 51 static int palm_os_4_probe(struct usb_serial *serial, 52 const struct usb_device_id *id); 53 54 /* Parameters that may be passed into the module. */ 55 static bool debug; 56 static __u16 vendor; 57 static __u16 product; 58 59 static struct usb_device_id id_table [] = { 60 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID), 61 .driver_info = (kernel_ulong_t)&palm_os_3_probe }, 62 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID), 63 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 64 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID), 65 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 66 { USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID), 67 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 68 { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID), 69 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 70 { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID), 71 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 72 { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID), 73 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 74 { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID), 75 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 76 { USB_DEVICE(PALM_VENDOR_ID, PALM_M100_ID), 77 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 78 { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID), 79 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 80 { USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID), 81 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 82 { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID), 83 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 84 { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650), 85 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 86 { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID), 87 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 88 { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID), 89 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 90 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID), 91 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 92 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID), 93 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 94 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID), 95 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 96 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID), 97 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 98 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID), 99 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 100 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID), 101 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 102 { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID), 103 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 104 { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), 105 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 106 { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), 107 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 108 { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID), 109 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 110 { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID), 111 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 112 { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID), 113 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 114 { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID), 115 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 116 { USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID), 117 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 118 { }, /* optional parameter entry */ 119 { } /* Terminating entry */ 120 }; 121 122 static struct usb_device_id clie_id_5_table [] = { 123 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID), 124 .driver_info = (kernel_ulong_t)&palm_os_4_probe }, 125 { }, /* optional parameter entry */ 126 { } /* Terminating entry */ 127 }; 128 129 static struct usb_device_id clie_id_3_5_table [] = { 130 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) }, 131 { } /* Terminating entry */ 132 }; 133 134 static struct usb_device_id id_table_combined [] = { 135 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) }, 136 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) }, 137 { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID) }, 138 { USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID) }, 139 { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) }, 140 { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) }, 141 { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) }, 142 { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) }, 143 { USB_DEVICE(PALM_VENDOR_ID, PALM_M100_ID) }, 144 { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) }, 145 { USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) }, 146 { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) }, 147 { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) }, 148 { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) }, 149 { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) }, 150 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) }, 151 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, 152 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) }, 153 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) }, 154 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) }, 155 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) }, 156 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID) }, 157 { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID) }, 158 { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) }, 159 { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID) }, 160 { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID) }, 161 { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) }, 162 { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) }, 163 { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) }, 164 { USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID) }, 165 { }, /* optional parameter entry */ 166 { } /* Terminating entry */ 167 }; 168 169 MODULE_DEVICE_TABLE(usb, id_table_combined); 170 171 static struct usb_driver visor_driver = { 172 .name = "visor", 173 .probe = usb_serial_probe, 174 .disconnect = usb_serial_disconnect, 175 .id_table = id_table_combined, 176 }; 177 178 /* All of the device info needed for the Handspring Visor, 179 and Palm 4.0 devices */ 180 static struct usb_serial_driver handspring_device = { 181 .driver = { 182 .owner = THIS_MODULE, 183 .name = "visor", 184 }, 185 .description = "Handspring Visor / Palm OS", 186 .id_table = id_table, 187 .num_ports = 2, 188 .bulk_out_size = 256, 189 .open = visor_open, 190 .close = visor_close, 191 .throttle = usb_serial_generic_throttle, 192 .unthrottle = usb_serial_generic_unthrottle, 193 .attach = treo_attach, 194 .probe = visor_probe, 195 .calc_num_ports = visor_calc_num_ports, 196 .read_int_callback = visor_read_int_callback, 197 }; 198 199 /* All of the device info needed for the Clie UX50, TH55 Palm 5.0 devices */ 200 static struct usb_serial_driver clie_5_device = { 201 .driver = { 202 .owner = THIS_MODULE, 203 .name = "clie_5", 204 }, 205 .description = "Sony Clie 5.0", 206 .id_table = clie_id_5_table, 207 .num_ports = 2, 208 .bulk_out_size = 256, 209 .open = visor_open, 210 .close = visor_close, 211 .throttle = usb_serial_generic_throttle, 212 .unthrottle = usb_serial_generic_unthrottle, 213 .attach = clie_5_attach, 214 .probe = visor_probe, 215 .calc_num_ports = visor_calc_num_ports, 216 .read_int_callback = visor_read_int_callback, 217 }; 218 219 /* device info for the Sony Clie OS version 3.5 */ 220 static struct usb_serial_driver clie_3_5_device = { 221 .driver = { 222 .owner = THIS_MODULE, 223 .name = "clie_3.5", 224 }, 225 .description = "Sony Clie 3.5", 226 .id_table = clie_id_3_5_table, 227 .num_ports = 1, 228 .bulk_out_size = 256, 229 .open = visor_open, 230 .close = visor_close, 231 .throttle = usb_serial_generic_throttle, 232 .unthrottle = usb_serial_generic_unthrottle, 233 .attach = clie_3_5_startup, 234 }; 235 236 static struct usb_serial_driver * const serial_drivers[] = { 237 &handspring_device, &clie_5_device, &clie_3_5_device, NULL 238 }; 239 240 /****************************************************************************** 241 * Handspring Visor specific driver functions 242 ******************************************************************************/ 243 static int visor_open(struct tty_struct *tty, struct usb_serial_port *port) 244 { 245 int result = 0; 246 247 dbg("%s - port %d", __func__, port->number); 248 249 if (!port->read_urb) { 250 /* this is needed for some brain dead Sony devices */ 251 dev_err(&port->dev, "Device lied about number of ports, please use a lower one.\n"); 252 return -ENODEV; 253 } 254 255 /* Start reading from the device */ 256 result = usb_serial_generic_open(tty, port); 257 if (result) 258 goto exit; 259 260 if (port->interrupt_in_urb) { 261 dbg("%s - adding interrupt input for treo", __func__); 262 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 263 if (result) 264 dev_err(&port->dev, 265 "%s - failed submitting interrupt urb, error %d\n", 266 __func__, result); 267 } 268 exit: 269 return result; 270 } 271 272 273 static void visor_close(struct usb_serial_port *port) 274 { 275 unsigned char *transfer_buffer; 276 277 dbg("%s - port %d", __func__, port->number); 278 279 /* shutdown our urbs */ 280 usb_serial_generic_close(port); 281 usb_kill_urb(port->interrupt_in_urb); 282 283 mutex_lock(&port->serial->disc_mutex); 284 if (!port->serial->disconnected) { 285 /* Try to send shutdown message, unless the device is gone */ 286 transfer_buffer = kmalloc(0x12, GFP_KERNEL); 287 if (transfer_buffer) { 288 usb_control_msg(port->serial->dev, 289 usb_rcvctrlpipe(port->serial->dev, 0), 290 VISOR_CLOSE_NOTIFICATION, 0xc2, 291 0x0000, 0x0000, 292 transfer_buffer, 0x12, 300); 293 kfree(transfer_buffer); 294 } 295 } 296 mutex_unlock(&port->serial->disc_mutex); 297 } 298 299 static void visor_read_int_callback(struct urb *urb) 300 { 301 struct usb_serial_port *port = urb->context; 302 int status = urb->status; 303 int result; 304 305 switch (status) { 306 case 0: 307 /* success */ 308 break; 309 case -ECONNRESET: 310 case -ENOENT: 311 case -ESHUTDOWN: 312 /* this urb is terminated, clean up */ 313 dbg("%s - urb shutting down with status: %d", 314 __func__, status); 315 return; 316 default: 317 dbg("%s - nonzero urb status received: %d", 318 __func__, status); 319 goto exit; 320 } 321 322 /* 323 * This information is still unknown what it can be used for. 324 * If anyone has an idea, please let the author know... 325 * 326 * Rumor has it this endpoint is used to notify when data 327 * is ready to be read from the bulk ones. 328 */ 329 usb_serial_debug_data(debug, &port->dev, __func__, 330 urb->actual_length, urb->transfer_buffer); 331 332 exit: 333 result = usb_submit_urb(urb, GFP_ATOMIC); 334 if (result) 335 dev_err(&urb->dev->dev, 336 "%s - Error %d submitting interrupt urb\n", 337 __func__, result); 338 } 339 340 static int palm_os_3_probe(struct usb_serial *serial, 341 const struct usb_device_id *id) 342 { 343 struct device *dev = &serial->dev->dev; 344 struct visor_connection_info *connection_info; 345 unsigned char *transfer_buffer; 346 char *string; 347 int retval = 0; 348 int i; 349 int num_ports = 0; 350 351 dbg("%s", __func__); 352 353 transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL); 354 if (!transfer_buffer) { 355 dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __func__, 356 sizeof(*connection_info)); 357 return -ENOMEM; 358 } 359 360 /* send a get connection info request */ 361 retval = usb_control_msg(serial->dev, 362 usb_rcvctrlpipe(serial->dev, 0), 363 VISOR_GET_CONNECTION_INFORMATION, 364 0xc2, 0x0000, 0x0000, transfer_buffer, 365 sizeof(*connection_info), 300); 366 if (retval < 0) { 367 dev_err(dev, "%s - error %d getting connection information\n", 368 __func__, retval); 369 goto exit; 370 } 371 372 if (retval == sizeof(*connection_info)) { 373 connection_info = (struct visor_connection_info *) 374 transfer_buffer; 375 376 num_ports = le16_to_cpu(connection_info->num_ports); 377 for (i = 0; i < num_ports; ++i) { 378 switch ( 379 connection_info->connections[i].port_function_id) { 380 case VISOR_FUNCTION_GENERIC: 381 string = "Generic"; 382 break; 383 case VISOR_FUNCTION_DEBUGGER: 384 string = "Debugger"; 385 break; 386 case VISOR_FUNCTION_HOTSYNC: 387 string = "HotSync"; 388 break; 389 case VISOR_FUNCTION_CONSOLE: 390 string = "Console"; 391 break; 392 case VISOR_FUNCTION_REMOTE_FILE_SYS: 393 string = "Remote File System"; 394 break; 395 default: 396 string = "unknown"; 397 break; 398 } 399 dev_info(dev, "%s: port %d, is for %s use\n", 400 serial->type->description, 401 connection_info->connections[i].port, string); 402 } 403 } 404 /* 405 * Handle devices that report invalid stuff here. 406 */ 407 if (num_ports == 0 || num_ports > 2) { 408 dev_warn(dev, "%s: No valid connect info available\n", 409 serial->type->description); 410 num_ports = 2; 411 } 412 413 dev_info(dev, "%s: Number of ports: %d\n", serial->type->description, 414 num_ports); 415 416 /* 417 * save off our num_ports info so that we can use it in the 418 * calc_num_ports callback 419 */ 420 usb_set_serial_data(serial, (void *)(long)num_ports); 421 422 /* ask for the number of bytes available, but ignore the 423 response as it is broken */ 424 retval = usb_control_msg(serial->dev, 425 usb_rcvctrlpipe(serial->dev, 0), 426 VISOR_REQUEST_BYTES_AVAILABLE, 427 0xc2, 0x0000, 0x0005, transfer_buffer, 428 0x02, 300); 429 if (retval < 0) 430 dev_err(dev, "%s - error %d getting bytes available request\n", 431 __func__, retval); 432 retval = 0; 433 434 exit: 435 kfree(transfer_buffer); 436 437 return retval; 438 } 439 440 static int palm_os_4_probe(struct usb_serial *serial, 441 const struct usb_device_id *id) 442 { 443 struct device *dev = &serial->dev->dev; 444 struct palm_ext_connection_info *connection_info; 445 unsigned char *transfer_buffer; 446 int retval; 447 448 dbg("%s", __func__); 449 450 transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL); 451 if (!transfer_buffer) { 452 dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __func__, 453 sizeof(*connection_info)); 454 return -ENOMEM; 455 } 456 457 retval = usb_control_msg(serial->dev, 458 usb_rcvctrlpipe(serial->dev, 0), 459 PALM_GET_EXT_CONNECTION_INFORMATION, 460 0xc2, 0x0000, 0x0000, transfer_buffer, 461 sizeof(*connection_info), 300); 462 if (retval < 0) 463 dev_err(dev, "%s - error %d getting connection info\n", 464 __func__, retval); 465 else 466 usb_serial_debug_data(debug, &serial->dev->dev, __func__, 467 retval, transfer_buffer); 468 469 kfree(transfer_buffer); 470 return 0; 471 } 472 473 474 static int visor_probe(struct usb_serial *serial, 475 const struct usb_device_id *id) 476 { 477 int retval = 0; 478 int (*startup)(struct usb_serial *serial, 479 const struct usb_device_id *id); 480 481 dbg("%s", __func__); 482 483 /* 484 * some Samsung Android phones in modem mode have the same ID 485 * as SPH-I500, but they are ACM devices, so dont bind to them 486 */ 487 if (id->idVendor == SAMSUNG_VENDOR_ID && 488 id->idProduct == SAMSUNG_SPH_I500_ID && 489 serial->dev->descriptor.bDeviceClass == USB_CLASS_COMM && 490 serial->dev->descriptor.bDeviceSubClass == 491 USB_CDC_SUBCLASS_ACM) 492 return -ENODEV; 493 494 if (serial->dev->actconfig->desc.bConfigurationValue != 1) { 495 dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", 496 serial->dev->actconfig->desc.bConfigurationValue); 497 return -ENODEV; 498 } 499 500 if (id->driver_info) { 501 startup = (void *)id->driver_info; 502 retval = startup(serial, id); 503 } 504 505 return retval; 506 } 507 508 static int visor_calc_num_ports(struct usb_serial *serial) 509 { 510 int num_ports = (int)(long)(usb_get_serial_data(serial)); 511 512 if (num_ports) 513 usb_set_serial_data(serial, NULL); 514 515 return num_ports; 516 } 517 518 static int clie_3_5_startup(struct usb_serial *serial) 519 { 520 struct device *dev = &serial->dev->dev; 521 int result; 522 u8 *data; 523 524 dbg("%s", __func__); 525 526 data = kmalloc(1, GFP_KERNEL); 527 if (!data) 528 return -ENOMEM; 529 530 /* 531 * Note that PEG-300 series devices expect the following two calls. 532 */ 533 534 /* get the config number */ 535 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 536 USB_REQ_GET_CONFIGURATION, USB_DIR_IN, 537 0, 0, data, 1, 3000); 538 if (result < 0) { 539 dev_err(dev, "%s: get config number failed: %d\n", 540 __func__, result); 541 goto out; 542 } 543 if (result != 1) { 544 dev_err(dev, "%s: get config number bad return length: %d\n", 545 __func__, result); 546 result = -EIO; 547 goto out; 548 } 549 550 /* get the interface number */ 551 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 552 USB_REQ_GET_INTERFACE, 553 USB_DIR_IN | USB_RECIP_INTERFACE, 554 0, 0, data, 1, 3000); 555 if (result < 0) { 556 dev_err(dev, "%s: get interface number failed: %d\n", 557 __func__, result); 558 goto out; 559 } 560 if (result != 1) { 561 dev_err(dev, 562 "%s: get interface number bad return length: %d\n", 563 __func__, result); 564 result = -EIO; 565 goto out; 566 } 567 568 result = 0; 569 out: 570 kfree(data); 571 572 return result; 573 } 574 575 static int treo_attach(struct usb_serial *serial) 576 { 577 struct usb_serial_port *swap_port; 578 579 /* Only do this endpoint hack for the Handspring devices with 580 * interrupt in endpoints, which for now are the Treo devices. */ 581 if (!((le16_to_cpu(serial->dev->descriptor.idVendor) 582 == HANDSPRING_VENDOR_ID) || 583 (le16_to_cpu(serial->dev->descriptor.idVendor) 584 == KYOCERA_VENDOR_ID)) || 585 (serial->num_interrupt_in == 0)) 586 return 0; 587 588 dbg("%s", __func__); 589 590 /* 591 * It appears that Treos and Kyoceras want to use the 592 * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint, 593 * so let's swap the 1st and 2nd bulk in and interrupt endpoints. 594 * Note that swapping the bulk out endpoints would break lots of 595 * apps that want to communicate on the second port. 596 */ 597 #define COPY_PORT(dest, src) \ 598 do { \ 599 dest->read_urb = src->read_urb; \ 600 dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\ 601 dest->bulk_in_buffer = src->bulk_in_buffer; \ 602 dest->interrupt_in_urb = src->interrupt_in_urb; \ 603 dest->interrupt_in_endpointAddress = \ 604 src->interrupt_in_endpointAddress;\ 605 dest->interrupt_in_buffer = src->interrupt_in_buffer; \ 606 } while (0); 607 608 swap_port = kmalloc(sizeof(*swap_port), GFP_KERNEL); 609 if (!swap_port) 610 return -ENOMEM; 611 COPY_PORT(swap_port, serial->port[0]); 612 COPY_PORT(serial->port[0], serial->port[1]); 613 COPY_PORT(serial->port[1], swap_port); 614 kfree(swap_port); 615 616 return 0; 617 } 618 619 static int clie_5_attach(struct usb_serial *serial) 620 { 621 struct usb_serial_port *port; 622 unsigned int pipe; 623 int j; 624 625 dbg("%s", __func__); 626 627 /* TH55 registers 2 ports. 628 Communication in from the UX50/TH55 uses bulk_in_endpointAddress 629 from port 0. Communication out to the UX50/TH55 uses 630 bulk_out_endpointAddress from port 1 631 632 Lets do a quick and dirty mapping 633 */ 634 635 /* some sanity check */ 636 if (serial->num_ports < 2) 637 return -1; 638 639 /* port 0 now uses the modified endpoint Address */ 640 port = serial->port[0]; 641 port->bulk_out_endpointAddress = 642 serial->port[1]->bulk_out_endpointAddress; 643 644 pipe = usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress); 645 for (j = 0; j < ARRAY_SIZE(port->write_urbs); ++j) 646 port->write_urbs[j]->pipe = pipe; 647 648 return 0; 649 } 650 651 static int __init visor_init(void) 652 { 653 int i, retval; 654 /* Only if parameters were passed to us */ 655 if (vendor > 0 && product > 0) { 656 struct usb_device_id usb_dev_temp[] = { 657 { 658 USB_DEVICE(vendor, product), 659 .driver_info = 660 (kernel_ulong_t) &palm_os_4_probe 661 } 662 }; 663 664 /* Find the last entry in id_table */ 665 for (i = 0;; i++) { 666 if (id_table[i].idVendor == 0) { 667 id_table[i] = usb_dev_temp[0]; 668 break; 669 } 670 } 671 /* Find the last entry in id_table_combined */ 672 for (i = 0;; i++) { 673 if (id_table_combined[i].idVendor == 0) { 674 id_table_combined[i] = usb_dev_temp[0]; 675 break; 676 } 677 } 678 printk(KERN_INFO KBUILD_MODNAME 679 ": Untested USB device specified at time of module insertion\n"); 680 printk(KERN_INFO KBUILD_MODNAME 681 ": Warning: This is not guaranteed to work\n"); 682 printk(KERN_INFO KBUILD_MODNAME 683 ": Using a newer kernel is preferred to this method\n"); 684 printk(KERN_INFO KBUILD_MODNAME 685 ": Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x\n", 686 vendor, product); 687 } 688 689 retval = usb_serial_register_drivers(&visor_driver, serial_drivers); 690 if (retval == 0) 691 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); 692 return retval; 693 } 694 695 696 static void __exit visor_exit (void) 697 { 698 usb_serial_deregister_drivers(&visor_driver, serial_drivers); 699 } 700 701 702 module_init(visor_init); 703 module_exit(visor_exit); 704 705 MODULE_AUTHOR(DRIVER_AUTHOR); 706 MODULE_DESCRIPTION(DRIVER_DESC); 707 MODULE_LICENSE("GPL"); 708 709 module_param(debug, bool, S_IRUGO | S_IWUSR); 710 MODULE_PARM_DESC(debug, "Debug enabled or not"); 711 712 module_param(vendor, ushort, 0); 713 MODULE_PARM_DESC(vendor, "User specified vendor ID"); 714 module_param(product, ushort, 0); 715 MODULE_PARM_DESC(product, "User specified product ID"); 716 717