Commit 9a08e732 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6:
  USB: ftdio_sio: New IPlus device ID
  USB: add new device id to option driver
  USB: fix race leading to use after free in io_edgeport
  USB: usblcd doesn't limit memory consumption during write
  USB: memory leak in iowarrior.c
  USB: ti serial driver sleeps with spinlock held
  USB: g_file_storage: call allow_signal()
parents b9e3614f d099321b
...@@ -686,7 +686,6 @@ struct fsg_dev { ...@@ -686,7 +686,6 @@ struct fsg_dev {
int thread_wakeup_needed; int thread_wakeup_needed;
struct completion thread_notifier; struct completion thread_notifier;
struct task_struct *thread_task; struct task_struct *thread_task;
sigset_t thread_signal_mask;
int cmnd_size; int cmnd_size;
u8 cmnd[MAX_COMMAND_SIZE]; u8 cmnd[MAX_COMMAND_SIZE];
...@@ -3277,8 +3276,7 @@ static void handle_exception(struct fsg_dev *fsg) ...@@ -3277,8 +3276,7 @@ static void handle_exception(struct fsg_dev *fsg)
/* Clear the existing signals. Anything but SIGUSR1 is converted /* Clear the existing signals. Anything but SIGUSR1 is converted
* into a high-priority EXIT exception. */ * into a high-priority EXIT exception. */
for (;;) { for (;;) {
sig = dequeue_signal_lock(current, &fsg->thread_signal_mask, sig = dequeue_signal_lock(current, &current->blocked, &info);
&info);
if (!sig) if (!sig)
break; break;
if (sig != SIGUSR1) { if (sig != SIGUSR1) {
...@@ -3431,10 +3429,10 @@ static int fsg_main_thread(void *fsg_) ...@@ -3431,10 +3429,10 @@ static int fsg_main_thread(void *fsg_)
/* Allow the thread to be killed by a signal, but set the signal mask /* Allow the thread to be killed by a signal, but set the signal mask
* to block everything but INT, TERM, KILL, and USR1. */ * to block everything but INT, TERM, KILL, and USR1. */
siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) | allow_signal(SIGINT);
sigmask(SIGTERM) | sigmask(SIGKILL) | allow_signal(SIGTERM);
sigmask(SIGUSR1)); allow_signal(SIGKILL);
sigprocmask(SIG_SETMASK, &fsg->thread_signal_mask, NULL); allow_signal(SIGUSR1);
/* Arrange for userspace references to be interpreted as kernel /* Arrange for userspace references to be interpreted as kernel
* pointers. That way we can pass a kernel pointer to a routine * pointers. That way we can pass a kernel pointer to a routine
......
...@@ -495,8 +495,8 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file, ...@@ -495,8 +495,8 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file,
/* verify that the device wasn't unplugged */ /* verify that the device wasn't unplugged */
if (!dev->present) { if (!dev->present) {
mutex_unlock(&dev->mutex); retval = -ENODEV;
return -ENODEV; goto error_out;
} }
dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __func__, dev->minor, cmd, dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __func__, dev->minor, cmd,
...@@ -579,9 +579,10 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file, ...@@ -579,9 +579,10 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file,
retval = -ENOTTY; retval = -ENOTTY;
break; break;
} }
error_out:
/* unlock the device */ /* unlock the device */
mutex_unlock(&dev->mutex); mutex_unlock(&dev->mutex);
kfree(buffer);
return retval; return retval;
} }
......
...@@ -42,10 +42,14 @@ struct usb_lcd { ...@@ -42,10 +42,14 @@ struct usb_lcd {
size_t bulk_in_size; /* the size of the receive buffer */ size_t bulk_in_size; /* the size of the receive buffer */
__u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
__u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
struct kref kref; struct kref kref;
struct semaphore limit_sem; /* to stop writes at full throttle from
* using up all RAM */
}; };
#define to_lcd_dev(d) container_of(d, struct usb_lcd, kref) #define to_lcd_dev(d) container_of(d, struct usb_lcd, kref)
#define USB_LCD_CONCURRENT_WRITES 5
static struct usb_driver lcd_driver; static struct usb_driver lcd_driver;
static DEFINE_MUTEX(usb_lcd_open_mutex); static DEFINE_MUTEX(usb_lcd_open_mutex);
...@@ -186,12 +190,13 @@ static void lcd_write_bulk_callback(struct urb *urb) ...@@ -186,12 +190,13 @@ static void lcd_write_bulk_callback(struct urb *urb)
/* free up our allocated buffer */ /* free up our allocated buffer */
usb_buffer_free(urb->dev, urb->transfer_buffer_length, usb_buffer_free(urb->dev, urb->transfer_buffer_length,
urb->transfer_buffer, urb->transfer_dma); urb->transfer_buffer, urb->transfer_dma);
up(&dev->limit_sem);
} }
static ssize_t lcd_write(struct file *file, const char __user * user_buffer, size_t count, loff_t *ppos) static ssize_t lcd_write(struct file *file, const char __user * user_buffer, size_t count, loff_t *ppos)
{ {
struct usb_lcd *dev; struct usb_lcd *dev;
int retval = 0; int retval = 0, r;
struct urb *urb = NULL; struct urb *urb = NULL;
char *buf = NULL; char *buf = NULL;
...@@ -201,10 +206,16 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz ...@@ -201,10 +206,16 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz
if (count == 0) if (count == 0)
goto exit; goto exit;
r = down_interruptible(&dev->limit_sem);
if (r < 0)
return -EINTR;
/* create a urb, and a buffer for it, and copy the data to the urb */ /* create a urb, and a buffer for it, and copy the data to the urb */
urb = usb_alloc_urb(0, GFP_KERNEL); urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) if (!urb) {
return -ENOMEM; retval = -ENOMEM;
goto err_no_buf;
}
buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma); buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
if (!buf) { if (!buf) {
...@@ -239,6 +250,8 @@ exit: ...@@ -239,6 +250,8 @@ exit:
error: error:
usb_buffer_free(dev->udev, count, buf, urb->transfer_dma); usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
usb_free_urb(urb); usb_free_urb(urb);
err_no_buf:
up(&dev->limit_sem);
return retval; return retval;
} }
...@@ -277,6 +290,7 @@ static int lcd_probe(struct usb_interface *interface, const struct usb_device_id ...@@ -277,6 +290,7 @@ static int lcd_probe(struct usb_interface *interface, const struct usb_device_id
goto error; goto error;
} }
kref_init(&dev->kref); kref_init(&dev->kref);
sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES);
dev->udev = usb_get_dev(interface_to_usbdev(interface)); dev->udev = usb_get_dev(interface_to_usbdev(interface));
dev->interface = interface; dev->interface = interface;
......
...@@ -317,6 +317,7 @@ static struct usb_device_id id_table_combined [] = { ...@@ -317,6 +317,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_IPLUS2_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) }, { USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) },
{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
......
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
/* iPlus device */ /* iPlus device */
#define FTDI_IPLUS_PID 0xD070 /* Product Id */ #define FTDI_IPLUS_PID 0xD070 /* Product Id */
#define FTDI_IPLUS2_PID 0xD071 /* Product Id */
/* DMX4ALL DMX Interfaces */ /* DMX4ALL DMX Interfaces */
#define FTDI_DMX4ALL 0xC850 #define FTDI_DMX4ALL 0xC850
......
...@@ -3046,11 +3046,11 @@ static void edge_shutdown (struct usb_serial *serial) ...@@ -3046,11 +3046,11 @@ static void edge_shutdown (struct usb_serial *serial)
} }
/* free up our endpoint stuff */ /* free up our endpoint stuff */
if (edge_serial->is_epic) { if (edge_serial->is_epic) {
usb_unlink_urb(edge_serial->interrupt_read_urb); usb_kill_urb(edge_serial->interrupt_read_urb);
usb_free_urb(edge_serial->interrupt_read_urb); usb_free_urb(edge_serial->interrupt_read_urb);
kfree(edge_serial->interrupt_in_buffer); kfree(edge_serial->interrupt_in_buffer);
usb_unlink_urb(edge_serial->read_urb); usb_kill_urb(edge_serial->read_urb);
usb_free_urb(edge_serial->read_urb); usb_free_urb(edge_serial->read_urb);
kfree(edge_serial->bulk_in_buffer); kfree(edge_serial->bulk_in_buffer);
} }
......
...@@ -111,7 +111,8 @@ static int option_send_setup(struct usb_serial_port *port); ...@@ -111,7 +111,8 @@ static int option_send_setup(struct usb_serial_port *port);
#define NOVATELWIRELESS_VENDOR_ID 0x1410 #define NOVATELWIRELESS_VENDOR_ID 0x1410
#define ANYDATA_VENDOR_ID 0x16d5 #define ANYDATA_VENDOR_ID 0x16d5
#define ANYDATA_PRODUCT_ID 0x6501 #define ANYDATA_PRODUCT_ADU_E100A 0x6501
#define ANYDATA_PRODUCT_ADU_500A 0x6502
#define BANDRICH_VENDOR_ID 0x1A8D #define BANDRICH_VENDOR_ID 0x1A8D
#define BANDRICH_PRODUCT_C100_1 0x1002 #define BANDRICH_PRODUCT_C100_1 0x1002
...@@ -169,7 +170,8 @@ static struct usb_device_id option_ids[] = { ...@@ -169,7 +170,8 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
{ USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */ { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */
......
...@@ -1555,15 +1555,17 @@ static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty) ...@@ -1555,15 +1555,17 @@ static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty)
spin_lock_irqsave(&tport->tp_lock, flags); spin_lock_irqsave(&tport->tp_lock, flags);
if (tport->tp_read_urb_state == TI_READ_URB_STOPPED) { 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; urb = tport->tp_port->read_urb;
spin_unlock_irqrestore(&tport->tp_lock, flags);
urb->complete = ti_bulk_in_callback; urb->complete = ti_bulk_in_callback;
urb->context = tport; urb->context = tport;
urb->dev = tport->tp_port->serial->dev; urb->dev = tport->tp_port->serial->dev;
status = usb_submit_urb(urb, GFP_KERNEL); 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; return status;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment