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 {
int thread_wakeup_needed;
struct completion thread_notifier;
struct task_struct *thread_task;
sigset_t thread_signal_mask;
int cmnd_size;
u8 cmnd[MAX_COMMAND_SIZE];
......@@ -3277,8 +3276,7 @@ static void handle_exception(struct fsg_dev *fsg)
/* Clear the existing signals. Anything but SIGUSR1 is converted
* into a high-priority EXIT exception. */
for (;;) {
sig = dequeue_signal_lock(current, &fsg->thread_signal_mask,
&info);
sig = dequeue_signal_lock(current, &current->blocked, &info);
if (!sig)
break;
if (sig != SIGUSR1) {
......@@ -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
* to block everything but INT, TERM, KILL, and USR1. */
siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) |
sigmask(SIGTERM) | sigmask(SIGKILL) |
sigmask(SIGUSR1));
sigprocmask(SIG_SETMASK, &fsg->thread_signal_mask, NULL);
allow_signal(SIGINT);
allow_signal(SIGTERM);
allow_signal(SIGKILL);
allow_signal(SIGUSR1);
/* Arrange for userspace references to be interpreted as kernel
* 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,
/* verify that the device wasn't unplugged */
if (!dev->present) {
mutex_unlock(&dev->mutex);
return -ENODEV;
retval = -ENODEV;
goto error_out;
}
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,
retval = -ENOTTY;
break;
}
error_out:
/* unlock the device */
mutex_unlock(&dev->mutex);
kfree(buffer);
return retval;
}
......
......@@ -42,10 +42,14 @@ struct usb_lcd {
size_t bulk_in_size; /* the size of the receive buffer */
__u8 bulk_in_endpointAddr; /* the address of the bulk in 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 USB_LCD_CONCURRENT_WRITES 5
static struct usb_driver lcd_driver;
static DEFINE_MUTEX(usb_lcd_open_mutex);
......@@ -186,12 +190,13 @@ static void lcd_write_bulk_callback(struct urb *urb)
/* free up our allocated buffer */
usb_buffer_free(urb->dev, urb->transfer_buffer_length,
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)
{
struct usb_lcd *dev;
int retval = 0;
int retval = 0, r;
struct urb *urb = NULL;
char *buf = NULL;
......@@ -201,10 +206,16 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz
if (count == 0)
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 */
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb)
return -ENOMEM;
if (!urb) {
retval = -ENOMEM;
goto err_no_buf;
}
buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
if (!buf) {
......@@ -239,6 +250,8 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz
error:
usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
usb_free_urb(urb);
err_no_buf:
up(&dev->limit_sem);
return retval;
}
......@@ -277,6 +290,7 @@ static int lcd_probe(struct usb_interface *interface, const struct usb_device_id
goto error;
}
kref_init(&dev->kref);
sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES);
dev->udev = usb_get_dev(interface_to_usbdev(interface));
dev->interface = interface;
......
......@@ -317,6 +317,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_IRTRANS_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_SIO_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
......
......@@ -56,6 +56,7 @@
/* iPlus device */
#define FTDI_IPLUS_PID 0xD070 /* Product Id */
#define FTDI_IPLUS2_PID 0xD071 /* Product Id */
/* DMX4ALL DMX Interfaces */
#define FTDI_DMX4ALL 0xC850
......
......@@ -3046,11 +3046,11 @@ static void edge_shutdown (struct usb_serial *serial)
}
/* free up our endpoint stuff */
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);
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);
kfree(edge_serial->bulk_in_buffer);
}
......
......@@ -111,7 +111,8 @@ static int option_send_setup(struct usb_serial_port *port);
#define NOVATELWIRELESS_VENDOR_ID 0x1410
#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_PRODUCT_C100_1 0x1002
......@@ -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, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
{ 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_2) },
{ 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)
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;
}
......
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