Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * USB HandSpring Visor, Palm m50x, and Sony Clie driver
0004  * (supports all of the Palm OS USB devices)
0005  *
0006  *  Copyright (C) 1999 - 2004
0007  *      Greg Kroah-Hartman (greg@kroah.com)
0008  *
0009  * See Documentation/usb/usb-serial.rst for more information on using this
0010  * driver
0011  *
0012  */
0013 
0014 #include <linux/kernel.h>
0015 #include <linux/errno.h>
0016 #include <linux/slab.h>
0017 #include <linux/tty.h>
0018 #include <linux/tty_driver.h>
0019 #include <linux/tty_flip.h>
0020 #include <linux/module.h>
0021 #include <linux/moduleparam.h>
0022 #include <linux/spinlock.h>
0023 #include <linux/uaccess.h>
0024 #include <linux/usb.h>
0025 #include <linux/usb/serial.h>
0026 #include <linux/usb/cdc.h>
0027 #include "visor.h"
0028 
0029 /*
0030  * Version Information
0031  */
0032 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
0033 #define DRIVER_DESC "USB HandSpring Visor / Palm OS driver"
0034 
0035 /* function prototypes for a handspring visor */
0036 static int  visor_open(struct tty_struct *tty, struct usb_serial_port *port);
0037 static void visor_close(struct usb_serial_port *port);
0038 static int  visor_probe(struct usb_serial *serial,
0039                     const struct usb_device_id *id);
0040 static int  visor_calc_num_ports(struct usb_serial *serial,
0041                     struct usb_serial_endpoints *epds);
0042 static int  clie_5_calc_num_ports(struct usb_serial *serial,
0043                     struct usb_serial_endpoints *epds);
0044 static void visor_read_int_callback(struct urb *urb);
0045 static int  clie_3_5_startup(struct usb_serial *serial);
0046 static int palm_os_3_probe(struct usb_serial *serial,
0047                     const struct usb_device_id *id);
0048 static int palm_os_4_probe(struct usb_serial *serial,
0049                     const struct usb_device_id *id);
0050 
0051 static const struct usb_device_id id_table[] = {
0052     { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID),
0053         .driver_info = (kernel_ulong_t)&palm_os_3_probe },
0054     { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID),
0055         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0056     { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID),
0057         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0058     { USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID),
0059         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0060     { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID),
0061         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0062     { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID),
0063         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0064     { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID),
0065         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0066     { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID),
0067         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0068     { USB_DEVICE(PALM_VENDOR_ID, PALM_M100_ID),
0069         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0070     { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID),
0071         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0072     { USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID),
0073         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0074     { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID),
0075         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0076     { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650),
0077         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0078     { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID),
0079         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0080     { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID),
0081         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0082     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID),
0083         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0084     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID),
0085         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0086     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID),
0087         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0088     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID),
0089         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0090     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID),
0091         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0092     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID),
0093         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0094     { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID),
0095         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0096     { USB_DEVICE_INTERFACE_CLASS(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID, 0xff),
0097         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0098     { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID),
0099         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0100     { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID),
0101         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0102     { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID),
0103         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0104     { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID),
0105         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0106     { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID),
0107         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0108     { USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID),
0109         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0110     { }                 /* Terminating entry */
0111 };
0112 
0113 static const struct usb_device_id clie_id_5_table[] = {
0114     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID),
0115         .driver_info = (kernel_ulong_t)&palm_os_4_probe },
0116     { }                 /* Terminating entry */
0117 };
0118 
0119 static const struct usb_device_id clie_id_3_5_table[] = {
0120     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
0121     { }                 /* Terminating entry */
0122 };
0123 
0124 static const struct usb_device_id id_table_combined[] = {
0125     { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
0126     { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) },
0127     { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID) },
0128     { USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID) },
0129     { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
0130     { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
0131     { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) },
0132     { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },
0133     { USB_DEVICE(PALM_VENDOR_ID, PALM_M100_ID) },
0134     { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
0135     { USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) },
0136     { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) },
0137     { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) },
0138     { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) },
0139     { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) },
0140     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
0141     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
0142     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) },
0143     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) },
0144     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) },
0145     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) },
0146     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID) },
0147     { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID) },
0148     { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) },
0149     { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID) },
0150     { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID) },
0151     { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) },
0152     { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) },
0153     { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) },
0154     { USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID) },
0155     { }                 /* Terminating entry */
0156 };
0157 
0158 MODULE_DEVICE_TABLE(usb, id_table_combined);
0159 
0160 /* All of the device info needed for the Handspring Visor,
0161    and Palm 4.0 devices */
0162 static struct usb_serial_driver handspring_device = {
0163     .driver = {
0164         .owner =    THIS_MODULE,
0165         .name =     "visor",
0166     },
0167     .description =      "Handspring Visor / Palm OS",
0168     .id_table =     id_table,
0169     .num_ports =        2,
0170     .bulk_out_size =    256,
0171     .open =         visor_open,
0172     .close =        visor_close,
0173     .throttle =     usb_serial_generic_throttle,
0174     .unthrottle =       usb_serial_generic_unthrottle,
0175     .probe =        visor_probe,
0176     .calc_num_ports =   visor_calc_num_ports,
0177     .read_int_callback =    visor_read_int_callback,
0178 };
0179 
0180 /* All of the device info needed for the Clie UX50, TH55 Palm 5.0 devices */
0181 static struct usb_serial_driver clie_5_device = {
0182     .driver = {
0183         .owner =    THIS_MODULE,
0184         .name =     "clie_5",
0185     },
0186     .description =      "Sony Clie 5.0",
0187     .id_table =     clie_id_5_table,
0188     .num_ports =        2,
0189     .num_bulk_out =     2,
0190     .bulk_out_size =    256,
0191     .open =         visor_open,
0192     .close =        visor_close,
0193     .throttle =     usb_serial_generic_throttle,
0194     .unthrottle =       usb_serial_generic_unthrottle,
0195     .probe =        visor_probe,
0196     .calc_num_ports =   clie_5_calc_num_ports,
0197     .read_int_callback =    visor_read_int_callback,
0198 };
0199 
0200 /* device info for the Sony Clie OS version 3.5 */
0201 static struct usb_serial_driver clie_3_5_device = {
0202     .driver = {
0203         .owner =    THIS_MODULE,
0204         .name =     "clie_3.5",
0205     },
0206     .description =      "Sony Clie 3.5",
0207     .id_table =     clie_id_3_5_table,
0208     .num_ports =        1,
0209     .bulk_out_size =    256,
0210     .open =         visor_open,
0211     .close =        visor_close,
0212     .throttle =     usb_serial_generic_throttle,
0213     .unthrottle =       usb_serial_generic_unthrottle,
0214     .attach =       clie_3_5_startup,
0215 };
0216 
0217 static struct usb_serial_driver * const serial_drivers[] = {
0218     &handspring_device, &clie_5_device, &clie_3_5_device, NULL
0219 };
0220 
0221 /******************************************************************************
0222  * Handspring Visor specific driver functions
0223  ******************************************************************************/
0224 static int visor_open(struct tty_struct *tty, struct usb_serial_port *port)
0225 {
0226     int result = 0;
0227 
0228     if (!port->read_urb) {
0229         /* this is needed for some brain dead Sony devices */
0230         dev_err(&port->dev, "Device lied about number of ports, please use a lower one.\n");
0231         return -ENODEV;
0232     }
0233 
0234     /* Start reading from the device */
0235     result = usb_serial_generic_open(tty, port);
0236     if (result)
0237         goto exit;
0238 
0239     if (port->interrupt_in_urb) {
0240         dev_dbg(&port->dev, "adding interrupt input for treo\n");
0241         result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
0242         if (result)
0243             dev_err(&port->dev,
0244                 "%s - failed submitting interrupt urb, error %d\n",
0245                             __func__, result);
0246     }
0247 exit:
0248     return result;
0249 }
0250 
0251 
0252 static void visor_close(struct usb_serial_port *port)
0253 {
0254     unsigned char *transfer_buffer;
0255 
0256     usb_serial_generic_close(port);
0257     usb_kill_urb(port->interrupt_in_urb);
0258 
0259     transfer_buffer = kmalloc(0x12, GFP_KERNEL);
0260     if (!transfer_buffer)
0261         return;
0262     usb_control_msg(port->serial->dev,
0263                      usb_rcvctrlpipe(port->serial->dev, 0),
0264                      VISOR_CLOSE_NOTIFICATION, 0xc2,
0265                      0x0000, 0x0000,
0266                      transfer_buffer, 0x12, 300);
0267     kfree(transfer_buffer);
0268 }
0269 
0270 static void visor_read_int_callback(struct urb *urb)
0271 {
0272     struct usb_serial_port *port = urb->context;
0273     int status = urb->status;
0274     int result;
0275 
0276     switch (status) {
0277     case 0:
0278         /* success */
0279         break;
0280     case -ECONNRESET:
0281     case -ENOENT:
0282     case -ESHUTDOWN:
0283         /* this urb is terminated, clean up */
0284         dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
0285             __func__, status);
0286         return;
0287     default:
0288         dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
0289             __func__, status);
0290         goto exit;
0291     }
0292 
0293     /*
0294      * This information is still unknown what it can be used for.
0295      * If anyone has an idea, please let the author know...
0296      *
0297      * Rumor has it this endpoint is used to notify when data
0298      * is ready to be read from the bulk ones.
0299      */
0300     usb_serial_debug_data(&port->dev, __func__, urb->actual_length,
0301                   urb->transfer_buffer);
0302 
0303 exit:
0304     result = usb_submit_urb(urb, GFP_ATOMIC);
0305     if (result)
0306         dev_err(&urb->dev->dev,
0307                 "%s - Error %d submitting interrupt urb\n",
0308                             __func__, result);
0309 }
0310 
0311 static int palm_os_3_probe(struct usb_serial *serial,
0312                         const struct usb_device_id *id)
0313 {
0314     struct device *dev = &serial->dev->dev;
0315     struct visor_connection_info *connection_info;
0316     unsigned char *transfer_buffer;
0317     char *string;
0318     int retval = 0;
0319     int i;
0320     int num_ports = 0;
0321 
0322     transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL);
0323     if (!transfer_buffer)
0324         return -ENOMEM;
0325 
0326     /* send a get connection info request */
0327     retval = usb_control_msg(serial->dev,
0328                   usb_rcvctrlpipe(serial->dev, 0),
0329                   VISOR_GET_CONNECTION_INFORMATION,
0330                   0xc2, 0x0000, 0x0000, transfer_buffer,
0331                   sizeof(*connection_info), 300);
0332     if (retval < 0) {
0333         dev_err(dev, "%s - error %d getting connection information\n",
0334             __func__, retval);
0335         goto exit;
0336     }
0337 
0338     if (retval != sizeof(*connection_info)) {
0339         dev_err(dev, "Invalid connection information received from device\n");
0340         retval = -ENODEV;
0341         goto exit;
0342     }
0343 
0344     connection_info = (struct visor_connection_info *)transfer_buffer;
0345 
0346     num_ports = le16_to_cpu(connection_info->num_ports);
0347 
0348     /* Handle devices that report invalid stuff here. */
0349     if (num_ports == 0 || num_ports > 2) {
0350         dev_warn(dev, "%s: No valid connect info available\n",
0351             serial->type->description);
0352         num_ports = 2;
0353     }
0354 
0355     for (i = 0; i < num_ports; ++i) {
0356         switch (connection_info->connections[i].port_function_id) {
0357         case VISOR_FUNCTION_GENERIC:
0358             string = "Generic";
0359             break;
0360         case VISOR_FUNCTION_DEBUGGER:
0361             string = "Debugger";
0362             break;
0363         case VISOR_FUNCTION_HOTSYNC:
0364             string = "HotSync";
0365             break;
0366         case VISOR_FUNCTION_CONSOLE:
0367             string = "Console";
0368             break;
0369         case VISOR_FUNCTION_REMOTE_FILE_SYS:
0370             string = "Remote File System";
0371             break;
0372         default:
0373             string = "unknown";
0374             break;
0375         }
0376         dev_info(dev, "%s: port %d, is for %s use\n",
0377             serial->type->description,
0378             connection_info->connections[i].port, string);
0379     }
0380     dev_info(dev, "%s: Number of ports: %d\n", serial->type->description,
0381         num_ports);
0382 
0383     /*
0384      * save off our num_ports info so that we can use it in the
0385      * calc_num_ports callback
0386      */
0387     usb_set_serial_data(serial, (void *)(long)num_ports);
0388 
0389     /* ask for the number of bytes available, but ignore the
0390        response as it is broken */
0391     retval = usb_control_msg(serial->dev,
0392                   usb_rcvctrlpipe(serial->dev, 0),
0393                   VISOR_REQUEST_BYTES_AVAILABLE,
0394                   0xc2, 0x0000, 0x0005, transfer_buffer,
0395                   0x02, 300);
0396     if (retval < 0)
0397         dev_err(dev, "%s - error %d getting bytes available request\n",
0398             __func__, retval);
0399     retval = 0;
0400 
0401 exit:
0402     kfree(transfer_buffer);
0403 
0404     return retval;
0405 }
0406 
0407 static int palm_os_4_probe(struct usb_serial *serial,
0408                         const struct usb_device_id *id)
0409 {
0410     struct device *dev = &serial->dev->dev;
0411     struct palm_ext_connection_info *connection_info;
0412     unsigned char *transfer_buffer;
0413     int retval;
0414 
0415     transfer_buffer =  kmalloc(sizeof(*connection_info), GFP_KERNEL);
0416     if (!transfer_buffer)
0417         return -ENOMEM;
0418 
0419     retval = usb_control_msg(serial->dev,
0420                   usb_rcvctrlpipe(serial->dev, 0),
0421                   PALM_GET_EXT_CONNECTION_INFORMATION,
0422                   0xc2, 0x0000, 0x0000, transfer_buffer,
0423                   sizeof(*connection_info), 300);
0424     if (retval < 0)
0425         dev_err(dev, "%s - error %d getting connection info\n",
0426             __func__, retval);
0427     else
0428         usb_serial_debug_data(dev, __func__, retval, transfer_buffer);
0429 
0430     kfree(transfer_buffer);
0431     return 0;
0432 }
0433 
0434 
0435 static int visor_probe(struct usb_serial *serial,
0436                     const struct usb_device_id *id)
0437 {
0438     int retval = 0;
0439     int (*startup)(struct usb_serial *serial,
0440                     const struct usb_device_id *id);
0441 
0442     /*
0443      * some Samsung Android phones in modem mode have the same ID
0444      * as SPH-I500, but they are ACM devices, so dont bind to them
0445      */
0446     if (id->idVendor == SAMSUNG_VENDOR_ID &&
0447         id->idProduct == SAMSUNG_SPH_I500_ID &&
0448         serial->dev->descriptor.bDeviceClass == USB_CLASS_COMM &&
0449         serial->dev->descriptor.bDeviceSubClass ==
0450             USB_CDC_SUBCLASS_ACM)
0451         return -ENODEV;
0452 
0453     if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
0454         dev_err(&serial->dev->dev, "active config #%d != 1 ??\n",
0455             serial->dev->actconfig->desc.bConfigurationValue);
0456         return -ENODEV;
0457     }
0458 
0459     if (id->driver_info) {
0460         startup = (void *)id->driver_info;
0461         retval = startup(serial, id);
0462     }
0463 
0464     return retval;
0465 }
0466 
0467 static int visor_calc_num_ports(struct usb_serial *serial,
0468                     struct usb_serial_endpoints *epds)
0469 {
0470     unsigned int vid = le16_to_cpu(serial->dev->descriptor.idVendor);
0471     int num_ports = (int)(long)(usb_get_serial_data(serial));
0472 
0473     if (num_ports)
0474         usb_set_serial_data(serial, NULL);
0475 
0476     /*
0477      * Only swap the bulk endpoints for the Handspring devices with
0478      * interrupt in endpoints, which for now are the Treo devices.
0479      */
0480     if (!(vid == HANDSPRING_VENDOR_ID || vid == KYOCERA_VENDOR_ID) ||
0481             epds->num_interrupt_in == 0)
0482         goto out;
0483 
0484     if (epds->num_bulk_in < 2 || epds->num_interrupt_in < 2) {
0485         dev_err(&serial->interface->dev, "missing endpoints\n");
0486         return -ENODEV;
0487     }
0488 
0489     /*
0490      * It appears that Treos and Kyoceras want to use the
0491      * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
0492      * so let's swap the 1st and 2nd bulk in and interrupt endpoints.
0493      * Note that swapping the bulk out endpoints would break lots of
0494      * apps that want to communicate on the second port.
0495      */
0496     swap(epds->bulk_in[0], epds->bulk_in[1]);
0497     swap(epds->interrupt_in[0], epds->interrupt_in[1]);
0498 out:
0499     return num_ports;
0500 }
0501 
0502 static int clie_5_calc_num_ports(struct usb_serial *serial,
0503                     struct usb_serial_endpoints *epds)
0504 {
0505     /*
0506      * TH55 registers 2 ports.
0507      * Communication in from the UX50/TH55 uses the first bulk-in
0508      * endpoint, while communication out to the UX50/TH55 uses the second
0509      * bulk-out endpoint.
0510      */
0511 
0512     /*
0513      * FIXME: Should we swap the descriptors instead of using the same
0514      *        bulk-out endpoint for both ports?
0515      */
0516     epds->bulk_out[0] = epds->bulk_out[1];
0517 
0518     return serial->type->num_ports;
0519 }
0520 
0521 static int clie_3_5_startup(struct usb_serial *serial)
0522 {
0523     struct device *dev = &serial->dev->dev;
0524     int result;
0525     u8 *data;
0526 
0527     data = kmalloc(1, GFP_KERNEL);
0528     if (!data)
0529         return -ENOMEM;
0530 
0531     /*
0532      * Note that PEG-300 series devices expect the following two calls.
0533      */
0534 
0535     /* get the config number */
0536     result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
0537                   USB_REQ_GET_CONFIGURATION, USB_DIR_IN,
0538                   0, 0, data, 1, 3000);
0539     if (result < 0) {
0540         dev_err(dev, "%s: get config number failed: %d\n",
0541                             __func__, result);
0542         goto out;
0543     }
0544     if (result != 1) {
0545         dev_err(dev, "%s: get config number bad return length: %d\n",
0546                             __func__, result);
0547         result = -EIO;
0548         goto out;
0549     }
0550 
0551     /* get the interface number */
0552     result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
0553                   USB_REQ_GET_INTERFACE,
0554                   USB_DIR_IN | USB_RECIP_INTERFACE,
0555                   0, 0, data, 1, 3000);
0556     if (result < 0) {
0557         dev_err(dev, "%s: get interface number failed: %d\n",
0558                             __func__, result);
0559         goto out;
0560     }
0561     if (result != 1) {
0562         dev_err(dev,
0563             "%s: get interface number bad return length: %d\n",
0564                             __func__, result);
0565         result = -EIO;
0566         goto out;
0567     }
0568 
0569     result = 0;
0570 out:
0571     kfree(data);
0572 
0573     return result;
0574 }
0575 
0576 module_usb_serial_driver(serial_drivers, id_table_combined);
0577 
0578 MODULE_AUTHOR(DRIVER_AUTHOR);
0579 MODULE_DESCRIPTION(DRIVER_DESC);
0580 MODULE_LICENSE("GPL v2");