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