]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/serial/visor.c
USB: serial: aircable: clean up urb->status usage
[linux-2.6-omap-h63xx.git] / drivers / usb / serial / visor.c
index befe2e11a041043fd7f66b8715678f6caf16132f..81ae76f15bf0b3d27c240260ffa5622c3be0d2aa 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,7 @@ 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 termios *old_termios);
+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);
@@ -90,8 +90,6 @@ static struct usb_device_id id_table [] = {
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
-       { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE31_ID),
-               .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID),
@@ -151,7 +149,6 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) },
        { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) },
        { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) },
-       { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE31_ID) },
        { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) },
        { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
        { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
@@ -189,6 +186,7 @@ static struct usb_serial_driver handspring_device = {
                .name =         "visor",
        },
        .description =          "Handspring Visor / Palm OS",
+       .usb_driver =           &visor_driver,
        .id_table =             id_table,
        .num_interrupt_in =     NUM_DONT_CARE,
        .num_bulk_in =          2,
@@ -219,6 +217,7 @@ static struct usb_serial_driver clie_5_device = {
                .name =         "clie_5",
        },
        .description =          "Sony Clie 5.0",
+       .usb_driver =           &visor_driver,
        .id_table =             clie_id_5_table,
        .num_interrupt_in =     NUM_DONT_CARE,
        .num_bulk_in =          2,
@@ -249,6 +248,7 @@ static struct usb_serial_driver clie_3_5_device = {
                .name =         "clie_3.5",
        },
        .description =          "Sony Clie 3.5",
+       .usb_driver =           &visor_driver,
        .id_table =             clie_id_3_5_table,
        .num_interrupt_in =     0,
        .num_bulk_in =          1,
@@ -273,7 +273,8 @@ struct visor_private {
        int bytes_in;
        int bytes_out;
        int outstanding_urbs;
-       int throttled;
+       unsigned char throttled;
+       unsigned char actually_throttled;
 };
 
 /* number of outstanding urbs to prevent userspace DoS from happening */
@@ -348,8 +349,7 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
                         
        /* shutdown our urbs */
        usb_kill_urb(port->read_urb);
-       if (port->interrupt_in_urb)
-               usb_kill_urb(port->interrupt_in_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);
@@ -385,19 +385,21 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
                dbg("%s - write limit hit\n", __FUNCTION__);
                return 0;
        }
+       priv->outstanding_urbs++;
        spin_unlock_irqrestore(&priv->lock, flags);
 
        buffer = kmalloc (count, GFP_ATOMIC);
        if (!buffer) {
                dev_err(&port->dev, "out of memory\n");
-               return -ENOMEM;
+               count = -ENOMEM;
+               goto error_no_buffer;
        }
 
        urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb) {
                dev_err(&port->dev, "no more free urbs\n");
-               kfree (buffer);
-               return -ENOMEM;
+               count = -ENOMEM;
+               goto error_no_urb;
        }
 
        memcpy (buffer, buf, count);
@@ -416,18 +418,26 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
                dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n",
                        __FUNCTION__, status);
                count = status;
-               kfree (buffer);
+               goto error;
        } else {
                spin_lock_irqsave(&priv->lock, flags);
-               ++priv->outstanding_urbs;
                priv->bytes_out += count;
                spin_unlock_irqrestore(&priv->lock, flags);
        }
 
        /* we are done with this urb, so let the host driver
         * really free it when it is finished with it */
-       usb_free_urb (urb);
+       usb_free_urb(urb);
 
+       return count;
+error:
+       usb_free_urb(urb);
+error_no_urb:
+       kfree(buffer);
+error_no_buffer:
+       spin_lock_irqsave(&priv->lock, flags);
+       --priv->outstanding_urbs;
+       spin_unlock_irqrestore(&priv->lock, flags);
        return count;
 }
 
@@ -500,9 +510,8 @@ static void visor_read_bulk_callback (struct urb *urb)
        struct visor_private *priv = usb_get_serial_port_data(port);
        unsigned char *data = urb->transfer_buffer;
        struct tty_struct *tty;
-       unsigned long flags;
-       int throttled;
        int result;
+       int available_room;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -515,17 +524,20 @@ static void visor_read_bulk_callback (struct urb *urb)
 
        tty = port->tty;
        if (tty && urb->actual_length) {
-               tty_buffer_request_room(tty, urb->actual_length);
-               tty_insert_flip_string(tty, data, urb->actual_length);
-               tty_flip_buffer_push(tty);
+               available_room = tty_buffer_request_room(tty, urb->actual_length);
+               if (available_room) {
+                       tty_insert_flip_string(tty, data, available_room);
+                       tty_flip_buffer_push(tty);
+               }
+               spin_lock(&priv->lock);
+               priv->bytes_in += available_room;
+
+       } else {
+               spin_lock(&priv->lock);
        }
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->bytes_in += urb->actual_length;
-       throttled = priv->throttled;
-       spin_unlock_irqrestore(&priv->lock, flags);
 
        /* Continue trying to always read if we should */
-       if (!throttled) {
+       if (!priv->throttled) {
                usb_fill_bulk_urb (port->read_urb, port->serial->dev,
                                   usb_rcvbulkpipe(port->serial->dev,
                                                   port->bulk_in_endpointAddress),
@@ -535,8 +547,10 @@ static void visor_read_bulk_callback (struct urb *urb)
                result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
                if (result)
                        dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
+       } else {
+               priv->actually_throttled = 1;
        }
-       return;
+       spin_unlock(&priv->lock);
 }
 
 static void visor_read_int_callback (struct urb *urb)
@@ -599,6 +613,7 @@ static void visor_unthrottle (struct usb_serial_port *port)
        dbg("%s - port %d", __FUNCTION__, port->number);
        spin_lock_irqsave(&priv->lock, flags);
        priv->throttled = 0;
+       priv->actually_throttled = 0;
        spin_unlock_irqrestore(&priv->lock, flags);
 
        port->read_urb->dev = port->serial->dev;
@@ -917,7 +932,7 @@ static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsign
 
 
 /* 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 termios *old_termios)
+static void visor_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
        unsigned int cflag;