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