]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/usb/serial/visor.c
USB: more serial drivers writing after disconnect
[karo-tx-linux.git] / drivers / usb / serial / visor.c
index ca826b92f6e69e1f0c4f7eb992037a0854e7285a..22b3f78a388ce0d40486ede8c98f9af41051dc49 100644 (file)
@@ -5,9 +5,9 @@
  *     Copyright (C) 1999 - 2004
  *         Greg Kroah-Hartman (greg@kroah.com)
  *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License.
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License version
+ *     2 as published by the Free Software Foundation.
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
@@ -46,7 +46,6 @@ static int  visor_probe               (struct usb_serial *serial, const struct usb_device_id
 static int  visor_calc_num_ports(struct usb_serial *serial);
 static void visor_shutdown     (struct usb_serial *serial);
 static int  visor_ioctl                (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void visor_set_termios  (struct usb_serial_port *port, struct ktermios *old_termios);
 static void visor_write_bulk_callback  (struct urb *urb);
 static void visor_read_bulk_callback   (struct urb *urb);
 static void visor_read_int_callback    (struct urb *urb);
@@ -104,6 +103,8 @@ static struct usb_device_id id_table [] = {
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
+       { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID),
+               .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), 
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), 
@@ -201,7 +202,6 @@ static struct usb_serial_driver handspring_device = {
        .calc_num_ports =       visor_calc_num_ports,
        .shutdown =             visor_shutdown,
        .ioctl =                visor_ioctl,
-       .set_termios =          visor_set_termios,
        .write =                visor_write,
        .write_room =           visor_write_room,
        .chars_in_buffer =      visor_chars_in_buffer,
@@ -232,7 +232,6 @@ static struct usb_serial_driver clie_5_device = {
        .calc_num_ports =       visor_calc_num_ports,
        .shutdown =             visor_shutdown,
        .ioctl =                visor_ioctl,
-       .set_termios =          visor_set_termios,
        .write =                visor_write,
        .write_room =           visor_write_room,
        .chars_in_buffer =      visor_chars_in_buffer,
@@ -260,7 +259,6 @@ static struct usb_serial_driver clie_3_5_device = {
        .unthrottle =           visor_unthrottle,
        .attach =               clie_3_5_startup,
        .ioctl =                visor_ioctl,
-       .set_termios =          visor_set_termios,
        .write =                visor_write,
        .write_room =           visor_write_room,
        .chars_in_buffer =      visor_chars_in_buffer,
@@ -351,16 +349,20 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
        usb_kill_urb(port->read_urb);
        usb_kill_urb(port->interrupt_in_urb);
 
-       /* Try to send shutdown message, if the device is gone, this will just fail. */
-       transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
-       if (transfer_buffer) {
-               usb_control_msg (port->serial->dev,
-                                usb_rcvctrlpipe(port->serial->dev, 0),
-                                VISOR_CLOSE_NOTIFICATION, 0xc2,
-                                0x0000, 0x0000, 
-                                transfer_buffer, 0x12, 300);
-               kfree (transfer_buffer);
+       mutex_lock(&port->serial->disc_mutex);
+       if (!port->serial->disconnected) {
+               /* Try to send shutdown message, unless the device is gone */
+               transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
+               if (transfer_buffer) {
+                       usb_control_msg (port->serial->dev,
+                                        usb_rcvctrlpipe(port->serial->dev, 0),
+                                        VISOR_CLOSE_NOTIFICATION, 0xc2,
+                                        0x0000, 0x0000,
+                                        transfer_buffer, 0x12, 300);
+                       kfree (transfer_buffer);
+               }
        }
+       mutex_unlock(&port->serial->disc_mutex);
 
        if (stats)
                dev_info(&port->dev, "Bytes In = %d  Bytes Out = %d\n",
@@ -485,16 +487,17 @@ static void visor_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct visor_private *priv = usb_get_serial_port_data(port);
+       int status = urb->status;
        unsigned long flags;
 
        /* free up the transfer buffer, as usb_free_urb() does not do this */
        kfree (urb->transfer_buffer);
 
        dbg("%s - port %d", __FUNCTION__, port->number);
-       
-       if (urb->status)
+
+       if (status)
                dbg("%s - nonzero write bulk status received: %d",
-                   __FUNCTION__, urb->status);
+                   __FUNCTION__, status);
 
        spin_lock_irqsave(&priv->lock, flags);
        --priv->outstanding_urbs;
@@ -509,14 +512,16 @@ static void visor_read_bulk_callback (struct urb *urb)
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct visor_private *priv = usb_get_serial_port_data(port);
        unsigned char *data = urb->transfer_buffer;
+       int status = urb->status;
        struct tty_struct *tty;
        int result;
        int available_room;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (urb->status) {
-               dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
+       if (status) {
+               dbg("%s - nonzero read bulk status received: %d",
+                   __FUNCTION__, status);
                return;
        }
 
@@ -556,9 +561,10 @@ static void visor_read_bulk_callback (struct urb *urb)
 static void visor_read_int_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       int status = urb->status;
        int result;
 
-       switch (urb->status) {
+       switch (status) {
        case 0:
                /* success */
                break;
@@ -567,11 +573,11 @@ static void visor_read_int_callback (struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d",
-                   __FUNCTION__, urb->status);
+                   __FUNCTION__, status);
                return;
        default:
                dbg("%s - nonzero urb status received: %d",
-                   __FUNCTION__, urb->status);
+                   __FUNCTION__, status);
                goto exit;
        }
 
@@ -930,74 +936,6 @@ static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsign
        return -ENOIOCTLCMD;
 }
 
-
-/* This function is all nice and good, but we don't change anything based on it :) */
-static void visor_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
-{
-       unsigned int cflag;
-
-       dbg("%s - port %d", __FUNCTION__, port->number);
-
-       if ((!port->tty) || (!port->tty->termios)) {
-               dbg("%s - no tty structures", __FUNCTION__);
-               return;
-       }
-
-       cflag = port->tty->termios->c_cflag;
-       /* check that they really want us to change something */
-       if (old_termios) {
-               if ((cflag == old_termios->c_cflag) &&
-                   (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
-                       dbg("%s - nothing to change...", __FUNCTION__);
-                       return;
-               }
-       }
-
-       /* get the byte size */
-       switch (cflag & CSIZE) {
-               case CS5:       dbg("%s - data bits = 5", __FUNCTION__);   break;
-               case CS6:       dbg("%s - data bits = 6", __FUNCTION__);   break;
-               case CS7:       dbg("%s - data bits = 7", __FUNCTION__);   break;
-               default:
-               case CS8:       dbg("%s - data bits = 8", __FUNCTION__);   break;
-       }
-       
-       /* determine the parity */
-       if (cflag & PARENB)
-               if (cflag & PARODD)
-                       dbg("%s - parity = odd", __FUNCTION__);
-               else
-                       dbg("%s - parity = even", __FUNCTION__);
-       else
-               dbg("%s - parity = none", __FUNCTION__);
-
-       /* figure out the stop bits requested */
-       if (cflag & CSTOPB)
-               dbg("%s - stop bits = 2", __FUNCTION__);
-       else
-               dbg("%s - stop bits = 1", __FUNCTION__);
-
-       
-       /* figure out the flow control settings */
-       if (cflag & CRTSCTS)
-               dbg("%s - RTS/CTS is enabled", __FUNCTION__);
-       else
-               dbg("%s - RTS/CTS is disabled", __FUNCTION__);
-       
-       /* determine software flow control */
-       if (I_IXOFF(port->tty))
-               dbg("%s - XON/XOFF is enabled, XON = %2x, XOFF = %2x",
-                   __FUNCTION__, START_CHAR(port->tty), STOP_CHAR(port->tty));
-       else
-               dbg("%s - XON/XOFF is disabled", __FUNCTION__);
-
-       /* get the baud rate wanted */
-       dbg("%s - baud rate = %d", __FUNCTION__, tty_get_baud_rate(port->tty));
-
-       return;
-}
-
-
 static int __init visor_init (void)
 {
        int i, retval;