USB: ti serial driver sleeps with spinlock held
[pandora-kernel.git] / drivers / usb / serial / ti_usb_3410_5052.c
index ac9b8ee..3d505fd 100644 (file)
@@ -161,14 +161,14 @@ static void ti_throttle(struct usb_serial_port *port);
 static void ti_unthrottle(struct usb_serial_port *port);
 static int ti_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg);
 static void ti_set_termios(struct usb_serial_port *port,
-       struct termios *old_termios);
+       struct ktermios *old_termios);
 static int ti_tiocmget(struct usb_serial_port *port, struct file *file);
 static int ti_tiocmset(struct usb_serial_port *port, struct file *file,
        unsigned int set, unsigned int clear);
 static void ti_break(struct usb_serial_port *port, int break_state);
-static void ti_interrupt_callback(struct urb *urb, struct pt_regs *regs);
-static void ti_bulk_in_callback(struct urb *urb, struct pt_regs *regs);
-static void ti_bulk_out_callback(struct urb *urb, struct pt_regs *regs);
+static void ti_interrupt_callback(struct urb *urb);
+static void ti_bulk_in_callback(struct urb *urb);
+static void ti_bulk_out_callback(struct urb *urb);
 
 static void ti_recv(struct device *dev, struct tty_struct *tty,
        unsigned char *data, int length);
@@ -228,6 +228,7 @@ static int product_5052_count;
 /* null entry */
 static struct usb_device_id ti_id_table_3410[1+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
+       { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
 };
 
 static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
@@ -239,6 +240,7 @@ static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
 
 static struct usb_device_id ti_id_table_combined[] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
+       { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
@@ -260,6 +262,7 @@ static struct usb_serial_driver ti_1port_device = {
                .name           = "ti_usb_3410_5052_1",
        },
        .description            = "TI USB 3410 1 port adapter",
+       .usb_driver             = &ti_usb_driver,
        .id_table               = ti_id_table_3410,
        .num_interrupt_in       = 1,
        .num_bulk_in            = 1,
@@ -290,6 +293,7 @@ static struct usb_serial_driver ti_2port_device = {
                .name           = "ti_usb_3410_5052_2",
        },
        .description            = "TI USB 5052 2 port adapter",
+       .usb_driver             = &ti_usb_driver,
        .id_table               = ti_id_table_5052,
        .num_interrupt_in       = 1,
        .num_bulk_in            = 2,
@@ -459,13 +463,12 @@ static int ti_startup(struct usb_serial *serial)
 
        /* set up port structures */
        for (i = 0; i < serial->num_ports; ++i) {
-               tport = kmalloc(sizeof(struct ti_port), GFP_KERNEL);
+               tport = kzalloc(sizeof(struct ti_port), GFP_KERNEL);
                if (tport == NULL) {
                        dev_err(&dev->dev, "%s - out of memory\n", __FUNCTION__);
                        status = -ENOMEM;
                        goto free_tports;
                }
-               memset(tport, 0, sizeof(struct ti_port));
                spin_lock_init(&tport->tp_lock);
                tport->tp_uart_base_addr = (i == 0 ? TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
                tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0;
@@ -880,7 +883,7 @@ static int ti_ioctl(struct usb_serial_port *port, struct file *file,
 
 
 static void ti_set_termios(struct usb_serial_port *port,
-       struct termios *old_termios)
+       struct ktermios *old_termios)
 {
        struct ti_port *tport = usb_get_serial_port_data(port);
        struct tty_struct *tty = port->tty;
@@ -1098,7 +1101,7 @@ static void ti_break(struct usb_serial_port *port, int break_state)
 }
 
 
-static void ti_interrupt_callback(struct urb *urb, struct pt_regs *regs)
+static void ti_interrupt_callback(struct urb *urb)
 {
        struct ti_device *tdev = (struct ti_device *)urb->context;
        struct usb_serial_port *port;
@@ -1178,7 +1181,7 @@ exit:
 }
 
 
-static void ti_bulk_in_callback(struct urb *urb, struct pt_regs *regs)
+static void ti_bulk_in_callback(struct urb *urb)
 {
        struct ti_port *tport = (struct ti_port *)urb->context;
        struct usb_serial_port *port = tport->tp_port;
@@ -1241,7 +1244,7 @@ exit:
 }
 
 
-static void ti_bulk_out_callback(struct urb *urb, struct pt_regs *regs)
+static void ti_bulk_out_callback(struct urb *urb)
 {
        struct ti_port *tport = (struct ti_port *)urb->context;
        struct usb_serial_port *port = tport->tp_port;
@@ -1552,15 +1555,17 @@ static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty)
        spin_lock_irqsave(&tport->tp_lock, flags);
 
        if (tport->tp_read_urb_state == TI_READ_URB_STOPPED) {
+               tport->tp_read_urb_state = TI_READ_URB_RUNNING;
                urb = tport->tp_port->read_urb;
+               spin_unlock_irqrestore(&tport->tp_lock, flags);
                urb->complete = ti_bulk_in_callback;
                urb->context = tport;
                urb->dev = tport->tp_port->serial->dev;
                status = usb_submit_urb(urb, GFP_KERNEL);
+       } else  {
+               tport->tp_read_urb_state = TI_READ_URB_RUNNING;
+               spin_unlock_irqrestore(&tport->tp_lock, flags);
        }
-       tport->tp_read_urb_state = TI_READ_URB_RUNNING;
-
-       spin_unlock_irqrestore(&tport->tp_lock, flags);
 
        return status;
 }
@@ -1709,7 +1714,7 @@ static struct circ_buf *ti_buf_alloc(void)
 {
        struct circ_buf *cb;
 
-       cb = (struct circ_buf *)kmalloc(sizeof(struct circ_buf), GFP_KERNEL);
+       cb = kmalloc(sizeof(struct circ_buf), GFP_KERNEL);
        if (cb == NULL)
                return NULL;