diff options
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r-- | drivers/usb/serial/airprime.c | 47 | ||||
-rw-r--r-- | drivers/usb/serial/cp2101.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 90 | ||||
-rw-r--r-- | drivers/usb/serial/ftdi_sio.h | 21 | ||||
-rw-r--r-- | drivers/usb/serial/ipaq.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 22 |
6 files changed, 129 insertions, 55 deletions
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 18816bf96a4..310a8b5f590 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -44,8 +44,43 @@ struct airprime_private { int outstanding_urbs; int throttled; struct urb *read_urbp[NUM_READ_URBS]; + + /* Settings for the port */ + int rts_state; /* Handshaking pins (outputs) */ + int dtr_state; + int cts_state; /* Handshaking pins (inputs) */ + int dsr_state; + int dcd_state; + int ri_state; }; +static int airprime_send_setup(struct usb_serial_port *port) +{ + struct usb_serial *serial = port->serial; + struct airprime_private *priv; + + dbg("%s", __FUNCTION__); + + if (port->number != 0) + return 0; + + priv = usb_get_serial_port_data(port); + + if (port->tty) { + int val = 0; + if (priv->dtr_state) + val |= 0x01; + if (priv->rts_state) + val |= 0x02; + + return usb_control_msg(serial->dev, + usb_rcvctrlpipe(serial->dev, 0), + 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); + } + + return 0; +} + static void airprime_read_bulk_callback(struct urb *urb) { struct usb_serial_port *port = urb->context; @@ -118,6 +153,10 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) usb_set_serial_port_data(port, priv); } + /* Set some sane defaults */ + priv->rts_state = 1; + priv->dtr_state = 1; + for (i = 0; i < NUM_READ_URBS; ++i) { buffer = kmalloc(buffer_size, GFP_KERNEL); if (!buffer) { @@ -151,6 +190,9 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) /* remember this urb so we can kill it when the port is closed */ priv->read_urbp[i] = urb; } + + airprime_send_setup(port); + goto out; errout: @@ -176,6 +218,11 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp) dbg("%s - port %d", __FUNCTION__, port->number); + priv->rts_state = 0; + priv->dtr_state = 0; + + airprime_send_setup(port); + for (i = 0; i < NUM_READ_URBS; ++i) { usb_kill_urb (priv->read_urbp[i]); kfree (priv->read_urbp[i]->transfer_buffer); diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index db623e75489..d7d0ba986a8 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -63,6 +63,8 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ + { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ + { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index c525b42dadd..1633a0fd48e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -315,6 +315,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, @@ -420,6 +421,14 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IBS_US485_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IBS_PICPRO_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IBS_PCMCIA_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IBS_PK1_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IBS_RS232MON_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IBS_APP70_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, /* * These will probably use user-space drivers. Uncomment them if * you need them or use the user-specified vendor/product module @@ -459,6 +468,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) }, { USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) }, + { USB_DEVICE(TTI_VID, TTI_QL355P_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, @@ -533,6 +543,7 @@ static const char *ftdi_chip_name[] = { [FT8U232AM] = "FT8U232AM", [FT232BM] = "FT232BM", [FT2232C] = "FT2232C", + [FT232RL] = "FT232RL", }; @@ -588,6 +599,8 @@ struct ftdi_private { static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); static int ftdi_sio_attach (struct usb_serial *serial); static void ftdi_shutdown (struct usb_serial *serial); +static int ftdi_sio_port_probe (struct usb_serial_port *port); +static int ftdi_sio_port_remove (struct usb_serial_port *port); static int ftdi_open (struct usb_serial_port *port, struct file *filp); static void ftdi_close (struct usb_serial_port *port, struct file *filp); static int ftdi_write (struct usb_serial_port *port, const unsigned char *buf, int count); @@ -622,6 +635,8 @@ static struct usb_serial_driver ftdi_sio_device = { .num_bulk_out = 1, .num_ports = 1, .probe = ftdi_sio_probe, + .port_probe = ftdi_sio_port_probe, + .port_remove = ftdi_sio_port_remove, .open = ftdi_open, .close = ftdi_close, .throttle = ftdi_throttle, @@ -1024,11 +1039,10 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a { struct usb_serial_port *port = to_usb_serial_port(dev); struct ftdi_private *priv = usb_get_serial_port_data(port); - struct usb_device *udev; + struct usb_device *udev = port->serial->dev; unsigned short latency = 0; int rv = 0; - udev = to_usb_device(dev); dbg("%s",__FUNCTION__); @@ -1052,13 +1066,11 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute * { struct usb_serial_port *port = to_usb_serial_port(dev); struct ftdi_private *priv = usb_get_serial_port_data(port); - struct usb_device *udev; + struct usb_device *udev = port->serial->dev; char buf[1]; int v = simple_strtoul(valbuf, NULL, 10); int rv = 0; - udev = to_usb_device(dev); - dbg("%s: setting latency timer = %i", __FUNCTION__, v); rv = usb_control_msg(udev, @@ -1083,13 +1095,11 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att { struct usb_serial_port *port = to_usb_serial_port(dev); struct ftdi_private *priv = usb_get_serial_port_data(port); - struct usb_device *udev; + struct usb_device *udev = port->serial->dev; char buf[1]; int v = simple_strtoul(valbuf, NULL, 10); int rv = 0; - udev = to_usb_device(dev); - dbg("%s: setting event char = %i", __FUNCTION__, v); rv = usb_control_msg(udev, @@ -1110,46 +1120,38 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer, store_latency_timer); static DEVICE_ATTR(event_char, S_IWUSR, NULL, store_event_char); -static int create_sysfs_attrs(struct usb_serial *serial) +static int create_sysfs_attrs(struct usb_serial_port *port) { - struct ftdi_private *priv; - struct usb_device *udev; + struct ftdi_private *priv = usb_get_serial_port_data(port); int retval = 0; dbg("%s",__FUNCTION__); - priv = usb_get_serial_port_data(serial->port[0]); - udev = serial->dev; - /* XXX I've no idea if the original SIO supports the event_char * sysfs parameter, so I'm playing it safe. */ if (priv->chip_type != SIO) { dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]); - retval = device_create_file(&udev->dev, &dev_attr_event_char); + retval = device_create_file(&port->dev, &dev_attr_event_char); if ((!retval) && (priv->chip_type == FT232BM || priv->chip_type == FT2232C)) { - retval = device_create_file(&udev->dev, + retval = device_create_file(&port->dev, &dev_attr_latency_timer); } } return retval; } -static void remove_sysfs_attrs(struct usb_serial *serial) +static void remove_sysfs_attrs(struct usb_serial_port *port) { - struct ftdi_private *priv; - struct usb_device *udev; + struct ftdi_private *priv = usb_get_serial_port_data(port); dbg("%s",__FUNCTION__); - priv = usb_get_serial_port_data(serial->port[0]); - udev = serial->dev; - /* XXX see create_sysfs_attrs */ if (priv->chip_type != SIO) { - device_remove_file(&udev->dev, &dev_attr_event_char); + device_remove_file(&port->dev, &dev_attr_event_char); if (priv->chip_type == FT232BM || priv->chip_type == FT2232C) { - device_remove_file(&udev->dev, &dev_attr_latency_timer); + device_remove_file(&port->dev, &dev_attr_latency_timer); } } @@ -1169,13 +1171,9 @@ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id return (0); } -/* attach subroutine */ -static int ftdi_sio_attach (struct usb_serial *serial) +static int ftdi_sio_port_probe(struct usb_serial_port *port) { - struct usb_serial_port *port = serial->port[0]; struct ftdi_private *priv; - struct ftdi_sio_quirk *quirk; - int retval; dbg("%s",__FUNCTION__); @@ -1215,19 +1213,21 @@ static int ftdi_sio_attach (struct usb_serial *serial) kfree(port->bulk_out_buffer); port->bulk_out_buffer = NULL; - usb_set_serial_port_data(serial->port[0], priv); + usb_set_serial_port_data(port, priv); - ftdi_determine_type (serial->port[0]); - retval = create_sysfs_attrs(serial); - if (retval) - dev_err(&serial->dev->dev, "Error creating sysfs files, " - "continuing\n"); + ftdi_determine_type (port); + create_sysfs_attrs(port); + return 0; +} +/* attach subroutine */ +static int ftdi_sio_attach (struct usb_serial *serial) +{ /* Check for device requiring special set up. */ - quirk = (struct ftdi_sio_quirk *)usb_get_serial_data(serial); - if (quirk && quirk->setup) { + struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial); + + if (quirk && quirk->setup) quirk->setup(serial); - } return 0; } /* ftdi_sio_attach */ @@ -1271,17 +1271,18 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) * calls __serial_close for each open of the port * shutdown is called then (ie ftdi_shutdown) */ - - static void ftdi_shutdown (struct usb_serial *serial) -{ /* ftdi_shutdown */ +{ + dbg("%s", __FUNCTION__); +} - struct usb_serial_port *port = serial->port[0]; +static int ftdi_sio_port_remove(struct usb_serial_port *port) +{ struct ftdi_private *priv = usb_get_serial_port_data(port); dbg("%s", __FUNCTION__); - remove_sysfs_attrs(serial); + remove_sysfs_attrs(port); /* all open ports are closed at this point * (by usbserial.c:__serial_close, which calls ftdi_close) @@ -1291,8 +1292,9 @@ static void ftdi_shutdown (struct usb_serial *serial) usb_set_serial_port_data(port, NULL); kfree(priv); } -} /* ftdi_shutdown */ + return 0; +} static int ftdi_open (struct usb_serial_port *port, struct file *filp) { /* ftdi_open */ diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 1bdda935f7d..513cfe1b768 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -27,6 +27,7 @@ #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ +#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ #define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ @@ -339,6 +340,12 @@ #define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */ /* + * TTi (Thurlby Thandar Instruments) + */ +#define TTI_VID 0x103E /* Vendor Id */ +#define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */ + +/* * Definitions for B&B Electronics products. */ #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ @@ -497,6 +504,19 @@ #define TELLDUS_VID 0x1781 /* Vendor ID */ #define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */ +/* + * IBS elektronik product ids + * Submitted by Thomas Schleusener + */ +#define FTDI_IBS_US485_PID 0xff38 /* IBS US485 (USB<-->RS422/485 interface) */ +#define FTDI_IBS_PICPRO_PID 0xff39 /* IBS PIC-Programmer */ +#define FTDI_IBS_PCMCIA_PID 0xff3a /* IBS Card reader for PCMCIA SRAM-cards */ +#define FTDI_IBS_PK1_PID 0xff3b /* IBS PK1 - Particel counter */ +#define FTDI_IBS_RS232MON_PID 0xff3c /* IBS RS232 - Monitor */ +#define FTDI_IBS_APP70_PID 0xff3d /* APP 70 (dust monitoring system) */ +#define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */ +#define FTDI_IBS_PROD_PID 0xff3f /* future device */ + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ @@ -620,6 +640,7 @@ typedef enum { FT8U232AM = 2, FT232BM = 3, FT2232C = 4, + FT232RL = 5, } ftdi_chip_type_t; typedef enum { diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index a408184334e..d16e2e1764a 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -247,6 +247,8 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(0x04AD, 0x0301) }, /* USB Sync 0301 */ { USB_DEVICE(0x04AD, 0x0302) }, /* USB Sync 0302 */ { USB_DEVICE(0x04AD, 0x0303) }, /* USB Sync 0303 */ + { USB_DEVICE(0x04AD, 0x0306) }, /* GPS Pocket PC USB Sync */ + { USB_DEVICE(0x04B7, 0x0531) }, /* MyGuide 7000 XL USB Sync */ { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */ { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 6bf22a28adb..8511352251f 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -99,9 +99,12 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po continue; *minor = i; + j = 0; dbg("%s - minor base = %d", __FUNCTION__, *minor); - for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) + for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) { serial_table[i] = serial; + serial->port[j++]->number = i; + } spin_unlock(&table_lock); return serial; } @@ -135,11 +138,6 @@ static void destroy_serial(struct kref *kref) dbg("%s - %s", __FUNCTION__, serial->type->description); - serial->type->shutdown(serial); - - /* return the minor range that this device had */ - return_serial(serial); - for (i = 0; i < serial->num_ports; ++i) serial->port[i]->open_count = 0; @@ -150,6 +148,12 @@ static void destroy_serial(struct kref *kref) serial->port[i] = NULL; } + if (serial->type->shutdown) + serial->type->shutdown(serial); + + /* return the minor range that this device had */ + return_serial(serial); + /* If this is a "fake" port, we have to clean it up here, as it will * not get cleaned up in port_release() as it was never registered with * the driver core */ @@ -826,7 +830,6 @@ int usb_serial_probe(struct usb_interface *interface, num_ports = type->num_ports; } - serial->minor = minor; serial->num_ports = num_ports; serial->num_bulk_in = num_bulk_in; serial->num_bulk_out = num_bulk_out; @@ -847,7 +850,6 @@ int usb_serial_probe(struct usb_interface *interface, port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); if (!port) goto probe_error; - port->number = i + serial->minor; port->serial = serial; spin_lock_init(&port->lock); mutex_init(&port->mutex); @@ -980,6 +982,7 @@ int usb_serial_probe(struct usb_interface *interface, dev_err(&interface->dev, "No more free serial devices\n"); goto probe_error; } + serial->minor = minor; /* register all of the individual ports with the driver core */ for (i = 0; i < num_ports; ++i) { @@ -1034,9 +1037,6 @@ probe_error: kfree(port->interrupt_out_buffer); } - /* return the minor range that this device had */ - return_serial (serial); - /* free up any memory that we allocated */ for (i = 0; i < serial->num_port_pointers; ++i) kfree(serial->port[i]); |