fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / usb / serial / ir-usb.c
index 0adcbb1..8fdf486 100644 (file)
@@ -46,7 +46,6 @@
  *     initial version released.
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <asm/uaccess.h>
 #include <linux/usb.h>
-
-#ifdef CONFIG_USB_SERIAL_DEBUG
-       static int debug = 1;
-#else
-       static int debug;
-#endif
-
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
 
 /*
  * Version Information
@@ -101,19 +93,21 @@ struct irda_class_desc {
        u8      bMaxUnicastList;
 } __attribute__ ((packed));
 
+static int debug;
+
 /* if overridden by the user, then use their value for the size of the read and
  * write urbs */
-static int buffer_size = 0;
+static int buffer_size;
 /* if overridden by the user, then use the specified number of XBOFs */
 static int xbof = -1;
 
 static int  ir_startup (struct usb_serial *serial);
 static int  ir_open (struct usb_serial_port *port, struct file *filep);
 static void ir_close (struct usb_serial_port *port, struct file *filep);
-static int  ir_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
-static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
-static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
-static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios);
+static int  ir_write (struct usb_serial_port *port, const unsigned char *buf, int count);
+static void ir_write_bulk_callback (struct urb *urb);
+static void ir_read_bulk_callback (struct urb *urb);
+static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
 
 static u8 ir_baud = 0;
 static u8 ir_xbof = 0;
@@ -130,17 +124,20 @@ static struct usb_device_id id_table [] = {
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver ir_driver = {
-       .owner =        THIS_MODULE,
        .name =         "ir-usb",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table,
+       .no_dynamic_id =        1,
 };
 
 
-static struct usb_serial_device_type ir_device = {
-       .owner =                THIS_MODULE,
-       .name =                 "IR Dongle",
+static struct usb_serial_driver ir_device = {
+       .driver = {
+               .owner =        THIS_MODULE,
+               .name =         "ir-usb",
+       },
+       .description =          "IR Dongle",
        .id_table =             id_table,
        .num_interrupt_in =     1,
        .num_bulk_in =          1,
@@ -186,15 +183,14 @@ static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev,
        struct irda_class_desc *desc;
        int ret;
                
-       desc = kmalloc(sizeof (struct irda_class_desc), GFP_KERNEL);
+       desc = kzalloc(sizeof (struct irda_class_desc), GFP_KERNEL);
        if (desc == NULL) 
                return NULL;
-       memset(desc, 0, sizeof(struct irda_class_desc));
        
        ret = usb_control_msg(dev, usb_rcvctrlpipe(dev,0),
                        IU_REQ_GET_CLASS_DESC,
                        USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-                       0, ifnum, desc, sizeof(*desc), HZ);
+                       0, ifnum, desc, sizeof(*desc), 1000);
        
        dbg("%s -  ret=%d", __FUNCTION__, ret);
        if (ret < sizeof(*desc)) {
@@ -327,10 +323,10 @@ static void ir_close (struct usb_serial_port *port, struct file * filp)
        dbg("%s - port %d", __FUNCTION__, port->number);
                         
        /* shutdown our bulk read */
-       usb_unlink_urb (port->read_urb);
+       usb_kill_urb(port->read_urb);
 }
 
-static int ir_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
+static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int count)
 {
        unsigned char *transfer_buffer;
        int result;
@@ -346,10 +342,14 @@ static int ir_write (struct usb_serial_port *port, int from_user, const unsigned
        if (count == 0)
                return 0;
 
-       if (port->write_urb->status == -EINPROGRESS) {
-               dbg ("%s - already writing", __FUNCTION__);
+       spin_lock_bh(&port->lock);
+       if (port->write_urb_busy) {
+               spin_unlock_bh(&port->lock);
+               dbg("%s - already writing", __FUNCTION__);
                return 0;
        }
+       port->write_urb_busy = 1;
+       spin_unlock_bh(&port->lock);
 
        transfer_buffer = port->write_urb->transfer_buffer;
        transfer_size = min(count, port->bulk_out_size - 1);
@@ -364,12 +364,7 @@ static int ir_write (struct usb_serial_port *port, int from_user, const unsigned
        *transfer_buffer = ir_xbof | ir_baud;
        ++transfer_buffer;
 
-       if (from_user) {
-               if (copy_from_user (transfer_buffer, buf, transfer_size))
-                       return -EFAULT;
-       } else {
-               memcpy (transfer_buffer, buf, transfer_size);
-       }
+       memcpy (transfer_buffer, buf, transfer_size);
 
        usb_fill_bulk_urb (
                port->write_urb,
@@ -384,35 +379,38 @@ static int ir_write (struct usb_serial_port *port, int from_user, const unsigned
        port->write_urb->transfer_flags = URB_ZERO_PACKET;
 
        result = usb_submit_urb (port->write_urb, GFP_ATOMIC);
-       if (result)
+       if (result) {
+               port->write_urb_busy = 0;
                dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
-       else
+       else
                result = transfer_size;
 
        return result;
 }
 
-static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void ir_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
-       
+
+       port->write_urb_busy = 0;
        if (urb->status) {
                dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
                return;
        }
 
        usb_serial_debug_data (
-               __FILE__,
+               debug,
+               &port->dev,
                __FUNCTION__,
                urb->actual_length,
                urb->transfer_buffer);
 
-       schedule_work(&port->work);
+       usb_serial_port_softint(port);
 }
 
-static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void ir_read_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct tty_struct *tty;
@@ -439,7 +437,8 @@ static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
                                ir_baud = *data & 0x0f;
 
                        usb_serial_debug_data (
-                               __FILE__,
+                               debug,
+                               &port->dev,
                                __FUNCTION__,
                                urb->actual_length,
                                data);
@@ -452,6 +451,9 @@ static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
                         */
                        tty = port->tty;
 
+                       /*
+                        *      FIXME: must not do this in IRQ context
+                        */
                        tty->ldisc.receive_buf(
                                tty,
                                data+1,
@@ -495,7 +497,7 @@ static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
        return;
 }
 
-static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
        unsigned char *transfer_buffer;
        unsigned int cflag;
@@ -614,10 +616,10 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(debug, "i");
+module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
-MODULE_PARM(xbof, "i");
+module_param(xbof, int, 0);
 MODULE_PARM_DESC(xbof, "Force specific number of XBOFs");
-MODULE_PARM(buffer_size, "i");
+module_param(buffer_size, int, 0);
 MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers");