aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-06-26 19:49:42 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-06-26 19:49:42 -0400
commit9a08e732533b940d2d31f4e9999dfee5e1ca3914 (patch)
tree9f3e262bcc4efb2c3bcd0a681dc8732d85b43188
parentb9e3614f444f6546204f4538afcaa3ebe36d49f2 (diff)
parentd099321bdbba0d49796841cd9d9faf6b0f0aa658 (diff)
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()
-rw-r--r--drivers/usb/gadget/file_storage.c12
-rw-r--r--drivers/usb/misc/iowarrior.c7
-rw-r--r--drivers/usb/misc/usblcd.c22
-rw-r--r--drivers/usb/serial/ftdi_sio.c1
-rw-r--r--drivers/usb/serial/ftdi_sio.h1
-rw-r--r--drivers/usb/serial/io_edgeport.c4
-rw-r--r--drivers/usb/serial/option.c6
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c8
8 files changed, 40 insertions, 21 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index c6b6479fa4dd..4639b629e60c 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -686,7 +686,6 @@ struct fsg_dev {
686 int thread_wakeup_needed; 686 int thread_wakeup_needed;
687 struct completion thread_notifier; 687 struct completion thread_notifier;
688 struct task_struct *thread_task; 688 struct task_struct *thread_task;
689 sigset_t thread_signal_mask;
690 689
691 int cmnd_size; 690 int cmnd_size;
692 u8 cmnd[MAX_COMMAND_SIZE]; 691 u8 cmnd[MAX_COMMAND_SIZE];
@@ -3277,8 +3276,7 @@ static void handle_exception(struct fsg_dev *fsg)
3277 /* Clear the existing signals. Anything but SIGUSR1 is converted 3276 /* Clear the existing signals. Anything but SIGUSR1 is converted
3278 * into a high-priority EXIT exception. */ 3277 * into a high-priority EXIT exception. */
3279 for (;;) { 3278 for (;;) {
3280 sig = dequeue_signal_lock(current, &fsg->thread_signal_mask, 3279 sig = dequeue_signal_lock(current, &current->blocked, &info);
3281 &info);
3282 if (!sig) 3280 if (!sig)
3283 break; 3281 break;
3284 if (sig != SIGUSR1) { 3282 if (sig != SIGUSR1) {
@@ -3431,10 +3429,10 @@ static int fsg_main_thread(void *fsg_)
3431 3429
3432 /* Allow the thread to be killed by a signal, but set the signal mask 3430 /* Allow the thread to be killed by a signal, but set the signal mask
3433 * to block everything but INT, TERM, KILL, and USR1. */ 3431 * to block everything but INT, TERM, KILL, and USR1. */
3434 siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) | 3432 allow_signal(SIGINT);
3435 sigmask(SIGTERM) | sigmask(SIGKILL) | 3433 allow_signal(SIGTERM);
3436 sigmask(SIGUSR1)); 3434 allow_signal(SIGKILL);
3437 sigprocmask(SIG_SETMASK, &fsg->thread_signal_mask, NULL); 3435 allow_signal(SIGUSR1);
3438 3436
3439 /* Arrange for userspace references to be interpreted as kernel 3437 /* Arrange for userspace references to be interpreted as kernel
3440 * pointers. That way we can pass a kernel pointer to a routine 3438 * pointers. That way we can pass a kernel pointer to a routine
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index fc51207b71b8..3bb33f7bfa36 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -495,8 +495,8 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file,
495 495
496 /* verify that the device wasn't unplugged */ 496 /* verify that the device wasn't unplugged */
497 if (!dev->present) { 497 if (!dev->present) {
498 mutex_unlock(&dev->mutex); 498 retval = -ENODEV;
499 return -ENODEV; 499 goto error_out;
500 } 500 }
501 501
502 dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __func__, dev->minor, cmd, 502 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 retval = -ENOTTY; 579 retval = -ENOTTY;
580 break; 580 break;
581 } 581 }
582 582error_out:
583 /* unlock the device */ 583 /* unlock the device */
584 mutex_unlock(&dev->mutex); 584 mutex_unlock(&dev->mutex);
585 kfree(buffer);
585 return retval; 586 return retval;
586} 587}
587 588
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index 887ef953f3d8..12bad8a205a7 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -42,10 +42,14 @@ struct usb_lcd {
42 size_t bulk_in_size; /* the size of the receive buffer */ 42 size_t bulk_in_size; /* the size of the receive buffer */
43 __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ 43 __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
44 __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ 44 __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
45 struct kref kref; 45 struct kref kref;
46 struct semaphore limit_sem; /* to stop writes at full throttle from
47 * using up all RAM */
46}; 48};
47#define to_lcd_dev(d) container_of(d, struct usb_lcd, kref) 49#define to_lcd_dev(d) container_of(d, struct usb_lcd, kref)
48 50
51#define USB_LCD_CONCURRENT_WRITES 5
52
49static struct usb_driver lcd_driver; 53static struct usb_driver lcd_driver;
50static DEFINE_MUTEX(usb_lcd_open_mutex); 54static DEFINE_MUTEX(usb_lcd_open_mutex);
51 55
@@ -186,12 +190,13 @@ static void lcd_write_bulk_callback(struct urb *urb)
186 /* free up our allocated buffer */ 190 /* free up our allocated buffer */
187 usb_buffer_free(urb->dev, urb->transfer_buffer_length, 191 usb_buffer_free(urb->dev, urb->transfer_buffer_length,
188 urb->transfer_buffer, urb->transfer_dma); 192 urb->transfer_buffer, urb->transfer_dma);
193 up(&dev->limit_sem);
189} 194}
190 195
191static ssize_t lcd_write(struct file *file, const char __user * user_buffer, size_t count, loff_t *ppos) 196static ssize_t lcd_write(struct file *file, const char __user * user_buffer, size_t count, loff_t *ppos)
192{ 197{
193 struct usb_lcd *dev; 198 struct usb_lcd *dev;
194 int retval = 0; 199 int retval = 0, r;
195 struct urb *urb = NULL; 200 struct urb *urb = NULL;
196 char *buf = NULL; 201 char *buf = NULL;
197 202
@@ -201,10 +206,16 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz
201 if (count == 0) 206 if (count == 0)
202 goto exit; 207 goto exit;
203 208
209 r = down_interruptible(&dev->limit_sem);
210 if (r < 0)
211 return -EINTR;
212
204 /* create a urb, and a buffer for it, and copy the data to the urb */ 213 /* create a urb, and a buffer for it, and copy the data to the urb */
205 urb = usb_alloc_urb(0, GFP_KERNEL); 214 urb = usb_alloc_urb(0, GFP_KERNEL);
206 if (!urb) 215 if (!urb) {
207 return -ENOMEM; 216 retval = -ENOMEM;
217 goto err_no_buf;
218 }
208 219
209 buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma); 220 buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
210 if (!buf) { 221 if (!buf) {
@@ -239,6 +250,8 @@ exit:
239error: 250error:
240 usb_buffer_free(dev->udev, count, buf, urb->transfer_dma); 251 usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
241 usb_free_urb(urb); 252 usb_free_urb(urb);
253err_no_buf:
254 up(&dev->limit_sem);
242 return retval; 255 return retval;
243} 256}
244 257
@@ -277,6 +290,7 @@ static int lcd_probe(struct usb_interface *interface, const struct usb_device_id
277 goto error; 290 goto error;
278 } 291 }
279 kref_init(&dev->kref); 292 kref_init(&dev->kref);
293 sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES);
280 294
281 dev->udev = usb_get_dev(interface_to_usbdev(interface)); 295 dev->udev = usb_get_dev(interface_to_usbdev(interface));
282 dev->interface = interface; 296 dev->interface = interface;
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 2353679f601e..da1c6f7f82b8 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -317,6 +317,7 @@ static struct usb_device_id id_table_combined [] = {
317 { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, 317 { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) },
318 { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, 318 { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) },
319 { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, 319 { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) },
320 { USB_DEVICE(FTDI_VID, FTDI_IPLUS2_PID) },
320 { USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) }, 321 { USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) },
321 { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, 322 { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
322 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, 323 { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 33aee9047242..d9e49716db13 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -56,6 +56,7 @@
56 56
57/* iPlus device */ 57/* iPlus device */
58#define FTDI_IPLUS_PID 0xD070 /* Product Id */ 58#define FTDI_IPLUS_PID 0xD070 /* Product Id */
59#define FTDI_IPLUS2_PID 0xD071 /* Product Id */
59 60
60/* DMX4ALL DMX Interfaces */ 61/* DMX4ALL DMX Interfaces */
61#define FTDI_DMX4ALL 0xC850 62#define FTDI_DMX4ALL 0xC850
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 4807f960150b..056e1923c4de 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -3046,11 +3046,11 @@ static void edge_shutdown (struct usb_serial *serial)
3046 } 3046 }
3047 /* free up our endpoint stuff */ 3047 /* free up our endpoint stuff */
3048 if (edge_serial->is_epic) { 3048 if (edge_serial->is_epic) {
3049 usb_unlink_urb(edge_serial->interrupt_read_urb); 3049 usb_kill_urb(edge_serial->interrupt_read_urb);
3050 usb_free_urb(edge_serial->interrupt_read_urb); 3050 usb_free_urb(edge_serial->interrupt_read_urb);
3051 kfree(edge_serial->interrupt_in_buffer); 3051 kfree(edge_serial->interrupt_in_buffer);
3052 3052
3053 usb_unlink_urb(edge_serial->read_urb); 3053 usb_kill_urb(edge_serial->read_urb);
3054 usb_free_urb(edge_serial->read_urb); 3054 usb_free_urb(edge_serial->read_urb);
3055 kfree(edge_serial->bulk_in_buffer); 3055 kfree(edge_serial->bulk_in_buffer);
3056 } 3056 }
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 89f067d95076..5d3999e3ff61 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -111,7 +111,8 @@ static int option_send_setup(struct usb_serial_port *port);
111#define NOVATELWIRELESS_VENDOR_ID 0x1410 111#define NOVATELWIRELESS_VENDOR_ID 0x1410
112 112
113#define ANYDATA_VENDOR_ID 0x16d5 113#define ANYDATA_VENDOR_ID 0x16d5
114#define ANYDATA_PRODUCT_ID 0x6501 114#define ANYDATA_PRODUCT_ADU_E100A 0x6501
115#define ANYDATA_PRODUCT_ADU_500A 0x6502
115 116
116#define BANDRICH_VENDOR_ID 0x1A8D 117#define BANDRICH_VENDOR_ID 0x1A8D
117#define BANDRICH_PRODUCT_C100_1 0x1002 118#define BANDRICH_PRODUCT_C100_1 0x1002
@@ -169,7 +170,8 @@ static struct usb_device_id option_ids[] = {
169 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ 170 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
170 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ 171 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
171 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ 172 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
172 { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, 173 { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
174 { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
173 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, 175 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
174 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, 176 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
175 { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */ 177 { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 4203e2b1a761..3d505fd0645b 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -1555,15 +1555,17 @@ static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty)
1555 spin_lock_irqsave(&tport->tp_lock, flags); 1555 spin_lock_irqsave(&tport->tp_lock, flags);
1556 1556
1557 if (tport->tp_read_urb_state == TI_READ_URB_STOPPED) { 1557 if (tport->tp_read_urb_state == TI_READ_URB_STOPPED) {
1558 tport->tp_read_urb_state = TI_READ_URB_RUNNING;
1558 urb = tport->tp_port->read_urb; 1559 urb = tport->tp_port->read_urb;
1560 spin_unlock_irqrestore(&tport->tp_lock, flags);
1559 urb->complete = ti_bulk_in_callback; 1561 urb->complete = ti_bulk_in_callback;
1560 urb->context = tport; 1562 urb->context = tport;
1561 urb->dev = tport->tp_port->serial->dev; 1563 urb->dev = tport->tp_port->serial->dev;
1562 status = usb_submit_urb(urb, GFP_KERNEL); 1564 status = usb_submit_urb(urb, GFP_KERNEL);
1565 } else {
1566 tport->tp_read_urb_state = TI_READ_URB_RUNNING;
1567 spin_unlock_irqrestore(&tport->tp_lock, flags);
1563 } 1568 }
1564 tport->tp_read_urb_state = TI_READ_URB_RUNNING;
1565
1566 spin_unlock_irqrestore(&tport->tp_lock, flags);
1567 1569
1568 return status; 1570 return status;
1569} 1571}