This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / usb / serial / visor.c
index d5b5cdd..933d67c 100644 (file)
 /* function prototypes for a handspring visor */
 static int  visor_open         (struct usb_serial_port *port, struct file *filp);
 static void visor_close                (struct usb_serial_port *port, struct file *filp);
-static int  visor_write                (struct usb_serial_port *port, const unsigned char *buf, int count);
+static int  visor_write                (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
 static int  visor_write_room           (struct usb_serial_port *port);
 static int  visor_chars_in_buffer      (struct usb_serial_port *port);
 static void visor_throttle     (struct usb_serial_port *port);
@@ -459,9 +459,9 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
        dbg("%s - port %d", __FUNCTION__, port->number);
                         
        /* shutdown our urbs */
-       usb_kill_urb(port->read_urb);
+       usb_unlink_urb (port->read_urb);
        if (port->interrupt_in_urb)
-               usb_kill_urb(port->interrupt_in_urb);
+               usb_unlink_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);
@@ -480,7 +480,7 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
 }
 
 
-static int visor_write (struct usb_serial_port *port, const unsigned char *buf, int count)
+static int visor_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
 {
        struct visor_private *priv = usb_get_serial_port_data(port);
        struct usb_serial *serial = port->serial;
@@ -494,7 +494,7 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
        spin_lock_irqsave(&priv->lock, flags);
        if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
                spin_unlock_irqrestore(&priv->lock, flags);
-               dbg("%s - write limit hit\n", __FUNCTION__);
+               dev_dbg(&port->dev, "write limit hit\n");
                return 0;
        }
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -512,7 +512,15 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
                return -ENOMEM;
        }
 
-       memcpy (buffer, buf, count);
+       if (from_user) {
+               if (copy_from_user (buffer, buf, count)) {
+                       kfree (buffer);
+                       usb_free_urb (urb);
+                       return -EFAULT;
+               }
+       } else {
+               memcpy (buffer, buf, count);
+       }
 
        usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer);
 
@@ -684,7 +692,7 @@ exit:
 static void visor_throttle (struct usb_serial_port *port)
 {
        dbg("%s - port %d", __FUNCTION__, port->number);
-       usb_kill_urb(port->read_urb);
+       usb_unlink_urb (port->read_urb);
 }