diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-24 14:36:03 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-24 14:36:03 -0700 |
| commit | 4dfe9e6bdbdf5a69ed41c58411350bcbdbaf4d03 (patch) | |
| tree | ebede9ac7baba3a8a329fe683b358f127e8154ab /usb | |
| parent | 344fceebd77ff2e341f36f9821da096adcc3840f (diff) | |
| download | patches-4dfe9e6bdbdf5a69ed41c58411350bcbdbaf4d03.tar.gz | |
usb patches and pci-bridge update from Kay
Also, build fix for 2.6.24-rc1 and my .config
Diffstat (limited to 'usb')
| -rw-r--r-- | usb/usb-autosuspend-for-cdc-acm.patch | 201 | ||||
| -rw-r--r-- | usb/usb-fix-interface-sysfs-file-creation-bug.patch | 43 | ||||
| -rw-r--r-- | usb/usb-fix-locking-in-idmouse.patch | 166 | ||||
| -rw-r--r-- | usb/usb-fix-read-vs.-disconnect-race-in-cytherm-driver.patch | 41 | ||||
| -rw-r--r-- | usb/usb-remove-unnecessary-zeroing-from-ub.patch | 93 | ||||
| -rw-r--r-- | usb/usb-serial-pl2303-support-for-io-data-device-rsaq5.patch | 40 | ||||
| -rw-r--r-- | usb/usb-usbserial-fix-potential-deadlock-between-write-and-irq.patch | 46 |
7 files changed, 630 insertions, 0 deletions
diff --git a/usb/usb-autosuspend-for-cdc-acm.patch b/usb/usb-autosuspend-for-cdc-acm.patch new file mode 100644 index 00000000000000..4ee2f244fc9199 --- /dev/null +++ b/usb/usb-autosuspend-for-cdc-acm.patch @@ -0,0 +1,201 @@ +From oliver@neukum.org Wed Oct 24 14:29:56 2007 +From: Oliver Neukum <oliver@neukum.org> +Date: Fri, 12 Oct 2007 17:24:28 +0200 +Subject: USB: autosuspend for cdc-acm +To: Greg KH <greg@kroah.com> +Cc: Alan Stern <stern@rowland.harvard.edu>, linux-usb-devel@lists.sourceforge.net +Message-ID: <200710121724.29251.oliver@neukum.org> +Content-Disposition: inline + + +Here we go. This patch implements suspend/resume and autosuspend +for the CDC ACM driver. + +Signed-off-by: Oliver Neukum <oneukum@suse.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/usb/class/cdc-acm.c | 92 ++++++++++++++++++++++++++++++++++++-------- + drivers/usb/class/cdc-acm.h | 2 + 2 files changed, 79 insertions(+), 15 deletions(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -496,10 +496,19 @@ static int acm_tty_open(struct tty_struc + otherwise it is scheduled, and with high data rates data can get lost. */ + tty->low_latency = 1; + ++ if (usb_autopm_get_interface(acm->control)) { ++ mutex_unlock(&open_mutex); ++ return -EIO; ++ } ++ ++ mutex_lock(&acm->mutex); ++ mutex_unlock(&open_mutex); + if (acm->used++) { ++ usb_autopm_put_interface(acm->control); + goto done; + } + ++ + acm->ctrlurb->dev = acm->dev; + if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { + dbg("usb_submit_urb(ctrl irq) failed"); +@@ -526,14 +535,15 @@ static int acm_tty_open(struct tty_struc + + done: + err_out: +- mutex_unlock(&open_mutex); ++ mutex_unlock(&acm->mutex); + return rv; + + full_bailout: + usb_kill_urb(acm->ctrlurb); + bail_out: ++ usb_autopm_put_interface(acm->control); + acm->used--; +- mutex_unlock(&open_mutex); ++ mutex_unlock(&acm->mutex); + return -EIO; + } + +@@ -570,6 +580,7 @@ static void acm_tty_close(struct tty_str + usb_kill_urb(acm->writeurb); + for (i = 0; i < nr; i++) + usb_kill_urb(acm->ru[i].urb); ++ usb_autopm_put_interface(acm->control); + } else + acm_tty_unregister(acm); + } +@@ -980,6 +991,7 @@ skip_normal_probe: + spin_lock_init(&acm->throttle_lock); + spin_lock_init(&acm->write_lock); + spin_lock_init(&acm->read_lock); ++ mutex_init(&acm->mutex); + acm->write_ready = 1; + acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); + +@@ -1096,6 +1108,25 @@ alloc_fail: + return -ENOMEM; + } + ++static void stop_data_traffic(struct acm *acm) ++{ ++ int i; ++ ++ tasklet_disable(&acm->urb_task); ++ ++ usb_kill_urb(acm->ctrlurb); ++ usb_kill_urb(acm->writeurb); ++ for (i = 0; i < acm->rx_buflimit; i++) ++ usb_kill_urb(acm->ru[i].urb); ++ ++ INIT_LIST_HEAD(&acm->filled_read_bufs); ++ INIT_LIST_HEAD(&acm->spare_read_bufs); ++ ++ tasklet_enable(&acm->urb_task); ++ ++ cancel_work_sync(&acm->work); ++} ++ + static void acm_disconnect(struct usb_interface *intf) + { + struct acm *acm = usb_get_intfdata(intf); +@@ -1123,19 +1154,7 @@ static void acm_disconnect(struct usb_in + usb_set_intfdata(acm->control, NULL); + usb_set_intfdata(acm->data, NULL); + +- tasklet_disable(&acm->urb_task); +- +- usb_kill_urb(acm->ctrlurb); +- usb_kill_urb(acm->writeurb); +- for (i = 0; i < acm->rx_buflimit; i++) +- usb_kill_urb(acm->ru[i].urb); +- +- INIT_LIST_HEAD(&acm->filled_read_bufs); +- INIT_LIST_HEAD(&acm->spare_read_bufs); +- +- tasklet_enable(&acm->urb_task); +- +- flush_scheduled_work(); /* wait for acm_softint */ ++ stop_data_traffic(acm); + + acm_write_buffers_free(acm); + usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); +@@ -1156,6 +1175,46 @@ static void acm_disconnect(struct usb_in + tty_hangup(acm->tty); + } + ++static int acm_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct acm *acm = usb_get_intfdata(intf); ++ ++ if (acm->susp_count++) ++ return 0; ++ /* ++ we treat opened interfaces differently, ++ we must guard against open ++ */ ++ mutex_lock(&acm->mutex); ++ ++ if (acm->used) ++ stop_data_traffic(acm); ++ ++ mutex_unlock(&acm->mutex); ++ return 0; ++} ++ ++static int acm_resume(struct usb_interface *intf) ++{ ++ struct acm *acm = usb_get_intfdata(intf); ++ int rv = 0; ++ ++ if (--acm->susp_count) ++ return 0; ++ ++ mutex_lock(&acm->mutex); ++ if (acm->used) { ++ rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO); ++ if (rv < 0) ++ goto err_out; ++ ++ tasklet_schedule(&acm->urb_task); ++ } ++ ++err_out: ++ mutex_unlock(&acm->mutex); ++ return rv; ++} + /* + * USB driver structure. + */ +@@ -1208,7 +1267,10 @@ static struct usb_driver acm_driver = { + .name = "cdc_acm", + .probe = acm_probe, + .disconnect = acm_disconnect, ++ .suspend = acm_suspend, ++ .resume = acm_resume, + .id_table = acm_ids, ++ .supports_autosuspend = 1, + }; + + /* +--- a/drivers/usb/class/cdc-acm.h ++++ b/drivers/usb/class/cdc-acm.h +@@ -107,6 +107,7 @@ struct acm { + int write_used; /* number of non-empty write buffers */ + int write_ready; /* write urb is not running */ + spinlock_t write_lock; ++ struct mutex mutex; + struct usb_cdc_line_coding line; /* bits, stop, parity */ + struct work_struct work; /* work queue entry for line discipline waking up */ + struct tasklet_struct urb_task; /* rx processing */ +@@ -120,6 +121,7 @@ struct acm { + unsigned char throttle; /* throttled by tty layer */ + unsigned char clocal; /* termios CLOCAL */ + unsigned int ctrl_caps; /* control capabilities from the class specific header */ ++ unsigned int susp_count; /* number of suspended interfaces */ + }; + + #define CDC_DATA_INTERFACE_TYPE 0x0a diff --git a/usb/usb-fix-interface-sysfs-file-creation-bug.patch b/usb/usb-fix-interface-sysfs-file-creation-bug.patch new file mode 100644 index 00000000000000..802544caa904ec --- /dev/null +++ b/usb/usb-fix-interface-sysfs-file-creation-bug.patch @@ -0,0 +1,43 @@ +From stern@rowland.harvard.edu Wed Oct 24 14:21:21 2007 +From: Alan Stern <stern@rowland.harvard.edu> +Date: Fri, 19 Oct 2007 09:51:58 -0400 (EDT) +Subject: USB: fix interface sysfs file-creation bug +To: Greg KH <greg@kroah.com> +Cc: USB development list <linux-usb-devel@lists.sourceforge.net> +Message-ID: <Pine.LNX.4.44L0.0710190950520.3873-100000@iolanthe.rowland.org> + + +This patch (as1005) fixes a rather subtle problem. When +usb_set_configuration() registers the interfaces and their files in +sysfs, it doesn't expect those files to exist already. But when an +interface is registered, its driver may call usb_set_interface() and +thereby cause the sysfs files to be created. The result is an error +when usb_set_configuration() goes on to create those same files again. + +The (not-so-great) solution is to have usb_set_configuration() remove +any existing files before creating them. + +Signed-off-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/core/message.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -1641,7 +1641,13 @@ free_interfaces: + intf->dev.bus_id, ret); + continue; + } +- usb_create_sysfs_intf_files (intf); ++ ++ /* The driver's probe method can call usb_set_interface(), ++ * which would mean the interface's sysfs files are already ++ * created. Just in case, we'll remove them first. ++ */ ++ usb_remove_sysfs_intf_files(intf); ++ usb_create_sysfs_intf_files(intf); + } + + usb_autosuspend_device(dev); diff --git a/usb/usb-fix-locking-in-idmouse.patch b/usb/usb-fix-locking-in-idmouse.patch new file mode 100644 index 00000000000000..fcb27c8deb8a0f --- /dev/null +++ b/usb/usb-fix-locking-in-idmouse.patch @@ -0,0 +1,166 @@ +From oliver@neukum.org Wed Oct 24 14:23:59 2007 +From: Oliver Neukum <oliver@neukum.org> +Date: Tue, 23 Oct 2007 14:23:13 +0200 +Subject: USB: fix locking in idmouse +To: echtler@fs.tum.de, aderesch@fs.tum.de, linux-usb-devel@lists.sourceforge.net, greg@kroah.com, Pete Zaitcev <zaitcev@redhat.com> +Message-ID: <200710231423.14209.oliver@neukum.org> +Content-Disposition: inline + + +Pete caused me to lock at buggy drivers in this respect. The idmouse has +a race between open and disconnect. This patch + +- solves the open/disconnect race +- switches locking to mutexes + +Signed-off-by: Oliver Neukum <oneukum@suse.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/usb/misc/idmouse.c | 45 ++++++++++++++++++++++++++++----------------- + 1 file changed, 28 insertions(+), 17 deletions(-) + +--- a/drivers/usb/misc/idmouse.c ++++ b/drivers/usb/misc/idmouse.c +@@ -66,6 +66,7 @@ static struct usb_device_id idmouse_tabl + USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000) + + MODULE_DEVICE_TABLE(usb, idmouse_table); ++static DEFINE_MUTEX(open_disc_mutex); + + /* structure to hold all of our device specific stuff */ + struct usb_idmouse { +@@ -80,7 +81,7 @@ struct usb_idmouse { + + int open; /* if the port is open or not */ + int present; /* if the device is not disconnected */ +- struct semaphore sem; /* locks this structure */ ++ struct mutex lock; /* locks this structure */ + + }; + +@@ -213,13 +214,17 @@ static int idmouse_open(struct inode *in + if (!interface) + return -ENODEV; + ++ mutex_lock(&open_disc_mutex); + /* get the device information block from the interface */ + dev = usb_get_intfdata(interface); +- if (!dev) ++ if (!dev) { ++ mutex_unlock(&open_disc_mutex); + return -ENODEV; ++ } + + /* lock this device */ +- down(&dev->sem); ++ mutex_lock(&dev->lock); ++ mutex_unlock(&open_disc_mutex); + + /* check if already open */ + if (dev->open) { +@@ -245,7 +250,7 @@ static int idmouse_open(struct inode *in + error: + + /* unlock this device */ +- up(&dev->sem); ++ mutex_unlock(&dev->lock); + return result; + } + +@@ -258,12 +263,14 @@ static int idmouse_release(struct inode + if (dev == NULL) + return -ENODEV; + ++ mutex_lock(&open_disc_mutex); + /* lock our device */ +- down(&dev->sem); ++ mutex_lock(&dev->lock); + + /* are we really open? */ + if (dev->open <= 0) { +- up(&dev->sem); ++ mutex_unlock(&dev->lock); ++ mutex_unlock(&open_disc_mutex); + return -ENODEV; + } + +@@ -271,10 +278,12 @@ static int idmouse_release(struct inode + + if (!dev->present) { + /* the device was unplugged before the file was released */ +- up(&dev->sem); ++ mutex_unlock(&dev->lock); ++ mutex_unlock(&open_disc_mutex); + idmouse_delete(dev); + } else { +- up(&dev->sem); ++ mutex_unlock(&dev->lock); ++ mutex_unlock(&open_disc_mutex); + } + return 0; + } +@@ -286,18 +295,18 @@ static ssize_t idmouse_read(struct file + int result; + + /* lock this object */ +- down(&dev->sem); ++ mutex_lock(&dev->lock); + + /* verify that the device wasn't unplugged */ + if (!dev->present) { +- up(&dev->sem); ++ mutex_unlock(&dev->lock); + return -ENODEV; + } + + result = simple_read_from_buffer(buffer, count, ppos, + dev->bulk_in_buffer, IMGSIZE); + /* unlock the device */ +- up(&dev->sem); ++ mutex_unlock(&dev->lock); + return result; + } + +@@ -320,7 +329,7 @@ static int idmouse_probe(struct usb_inte + if (dev == NULL) + return -ENOMEM; + +- init_MUTEX(&dev->sem); ++ mutex_init(&dev->lock); + dev->udev = udev; + dev->interface = interface; + +@@ -372,24 +381,26 @@ static void idmouse_disconnect(struct us + + /* get device structure */ + dev = usb_get_intfdata(interface); +- usb_set_intfdata(interface, NULL); + + /* give back our minor */ + usb_deregister_dev(interface, &idmouse_class); + +- /* lock it */ +- down(&dev->sem); ++ mutex_lock(&open_disc_mutex); ++ usb_set_intfdata(interface, NULL); ++ /* lock the device */ ++ mutex_lock(&dev->lock); ++ mutex_unlock(&open_disc_mutex); + + /* prevent device read, write and ioctl */ + dev->present = 0; + + /* if the device is opened, idmouse_release will clean this up */ + if (!dev->open) { +- up(&dev->sem); ++ mutex_unlock(&dev->lock); + idmouse_delete(dev); + } else { + /* unlock */ +- up(&dev->sem); ++ mutex_unlock(&dev->lock); + } + + info("%s disconnected", DRIVER_DESC); diff --git a/usb/usb-fix-read-vs.-disconnect-race-in-cytherm-driver.patch b/usb/usb-fix-read-vs.-disconnect-race-in-cytherm-driver.patch new file mode 100644 index 00000000000000..19ff2411402351 --- /dev/null +++ b/usb/usb-fix-read-vs.-disconnect-race-in-cytherm-driver.patch @@ -0,0 +1,41 @@ +From oliver@neukum.org Wed Oct 24 14:24:18 2007 +From: Oliver Neukum <oliver@neukum.org> +Date: Tue, 23 Oct 2007 12:26:41 +0200 +Subject: USB: fix read vs. disconnect race in cytherm driver +To: erik@rigtorp.com, greg@kroah.com, linux-usb-devel@lists.sourceforge.net +Message-ID: <200710231226.41769.oliver@neukum.org> +Content-Disposition: inline + + +the disconnect method of this driver set intfdata to NULL before +removing attribute files. The attributes' read methods will happily +follow the NULL pointer. Here's the correct ordering. + +Signed-off-by : Oliver Neukum <oneukum@suse.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/usb/misc/cytherm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/misc/cytherm.c ++++ b/drivers/usb/misc/cytherm.c +@@ -399,7 +399,6 @@ static void cytherm_disconnect(struct us + struct usb_cytherm *dev; + + dev = usb_get_intfdata (interface); +- usb_set_intfdata (interface, NULL); + + device_remove_file(&interface->dev, &dev_attr_brightness); + device_remove_file(&interface->dev, &dev_attr_temp); +@@ -407,6 +406,9 @@ static void cytherm_disconnect(struct us + device_remove_file(&interface->dev, &dev_attr_port0); + device_remove_file(&interface->dev, &dev_attr_port1); + ++ /* first remove the files, then NULL the pointer */ ++ usb_set_intfdata (interface, NULL); ++ + usb_put_dev(dev->udev); + + kfree(dev); diff --git a/usb/usb-remove-unnecessary-zeroing-from-ub.patch b/usb/usb-remove-unnecessary-zeroing-from-ub.patch new file mode 100644 index 00000000000000..a72793abf69fa7 --- /dev/null +++ b/usb/usb-remove-unnecessary-zeroing-from-ub.patch @@ -0,0 +1,93 @@ +From zaitcev@redhat.com Wed Oct 24 14:22:09 2007 +From: Pete Zaitcev <zaitcev@redhat.com> +Date: Tue, 23 Oct 2007 18:57:25 -0700 +Subject: USB: Remove unnecessary zeroing from ub +To: greg@kroah.com +Cc: zaitcev@redhat.com, linux-usb-devel@lists.sourceforge.net +Message-ID: <20071023185725.9892f3e2.zaitcev@redhat.com> + + +These zeroings were taken from usb-storage long time ago. I examined +the submission paths and usb_fill_bulk_urb and found them unnecessary. + +Signed-off-by: Pete Zaitcev <zaitcev@yahoo.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/block/ub.c | 23 ----------------------- + 1 file changed, 23 deletions(-) + +--- a/drivers/block/ub.c ++++ b/drivers/block/ub.c +@@ -922,11 +922,6 @@ static int ub_scsi_cmd_start(struct ub_d + usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe, + bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc); + +- /* Fill what we shouldn't be filling, because usb-storage did so. */ +- sc->work_urb.actual_length = 0; +- sc->work_urb.error_count = 0; +- sc->work_urb.status = 0; +- + if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { + /* XXX Clear stalls */ + ub_complete(&sc->work_done); +@@ -1313,9 +1308,6 @@ static void ub_data_start(struct ub_dev + sc->last_pipe = pipe; + usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, sg_virt(sg), + sg->length, ub_urb_complete, sc); +- sc->work_urb.actual_length = 0; +- sc->work_urb.error_count = 0; +- sc->work_urb.status = 0; + + if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { + /* XXX Clear stalls */ +@@ -1356,9 +1348,6 @@ static int __ub_state_stat(struct ub_dev + sc->last_pipe = sc->recv_bulk_pipe; + usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe, + &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc); +- sc->work_urb.actual_length = 0; +- sc->work_urb.error_count = 0; +- sc->work_urb.status = 0; + + if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { + /* XXX Clear stalls */ +@@ -1473,9 +1462,6 @@ static int ub_submit_clear_stall(struct + + usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, + (unsigned char*) cr, NULL, 0, ub_urb_complete, sc); +- sc->work_urb.actual_length = 0; +- sc->work_urb.error_count = 0; +- sc->work_urb.status = 0; + + if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { + ub_complete(&sc->work_done); +@@ -1954,9 +1940,6 @@ static int ub_sync_reset(struct ub_dev * + + usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, + (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); +- sc->work_urb.actual_length = 0; +- sc->work_urb.error_count = 0; +- sc->work_urb.status = 0; + + if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { + printk(KERN_WARNING +@@ -2008,9 +1991,6 @@ static int ub_sync_getmaxlun(struct ub_d + + usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe, + (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl); +- sc->work_urb.actual_length = 0; +- sc->work_urb.error_count = 0; +- sc->work_urb.status = 0; + + if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) + goto err_submit; +@@ -2078,9 +2058,6 @@ static int ub_probe_clear_stall(struct u + + usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, + (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); +- sc->work_urb.actual_length = 0; +- sc->work_urb.error_count = 0; +- sc->work_urb.status = 0; + + if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { + printk(KERN_WARNING diff --git a/usb/usb-serial-pl2303-support-for-io-data-device-rsaq5.patch b/usb/usb-serial-pl2303-support-for-io-data-device-rsaq5.patch new file mode 100644 index 00000000000000..ac8c8340a5996d --- /dev/null +++ b/usb/usb-serial-pl2303-support-for-io-data-device-rsaq5.patch @@ -0,0 +1,40 @@ +From mokuno@sm.sony.co.jp Wed Oct 24 14:24:40 2007 +From: Masakazu Mokuno <mokuno@sm.sony.co.jp> +Date: Tue, 23 Oct 2007 13:51:57 +0900 +Subject: usb: serial/pl2303: support for IO Data Device RSAQ5 +To: Greg KH <greg@kroah.com> +Cc: linux-usb-devel@lists.sourceforge.net +Message-ID: <20071023133459.E0CE.MOKUNO@sm.sony.co.jp> + + +This patch adds support for the IO Data Device USB-RSAQ5, PL2303 based +USB-serial converter, to pl2303 driver + +Signed-off-by: Masakazu Mokuno <mokuno@sm.sony.co.jp> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/pl2303.c | 1 + + drivers/usb/serial/pl2303.h | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/usb/serial/pl2303.c ++++ b/drivers/usb/serial/pl2303.c +@@ -56,6 +56,7 @@ static struct usb_device_id id_table [] + { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) }, + { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, ++ { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, + { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, + { USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) }, + { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) }, +--- a/drivers/usb/serial/pl2303.h ++++ b/drivers/usb/serial/pl2303.h +@@ -20,6 +20,7 @@ + + #define IODATA_VENDOR_ID 0x04bb + #define IODATA_PRODUCT_ID 0x0a03 ++#define IODATA_PRODUCT_ID_RSAQ5 0x0a0e + + #define ELCOM_VENDOR_ID 0x056e + #define ELCOM_PRODUCT_ID 0x5003 diff --git a/usb/usb-usbserial-fix-potential-deadlock-between-write-and-irq.patch b/usb/usb-usbserial-fix-potential-deadlock-between-write-and-irq.patch new file mode 100644 index 00000000000000..39cc56f9ce9c41 --- /dev/null +++ b/usb/usb-usbserial-fix-potential-deadlock-between-write-and-irq.patch @@ -0,0 +1,46 @@ +From jikos@jikos.cz Wed Oct 24 14:28:04 2007 +From: Jiri Kosina <jikos@jikos.cz> +Date: Sat, 20 Oct 2007 00:05:19 +0200 (CEST) +Subject: USB: usbserial - fix potential deadlock between write() and IRQ +To: Larry Finger <larry.finger@lwfinger.net> +Cc: LKML <linux-kernel@vger.kernel.org>, Greg Kroah-Hartman <gregkh@suse.de>, linux-usb-devel@lists.sourceforge.net +Message-ID: <Pine.LNX.4.64.0710200001520.18815@twin.jikos.cz> + + +From: Jiri Kosina <jkosina@suse.cz> + +USB: usbserial - fix potential deadlock between write() and IRQ + +usb_serial_generic_write() doesn't disable interrupts when taking port->lock, +and could therefore deadlock with usb_serial_generic_read_bulk_callback() +being called from interrupt, taking the same lock. Fix it. + +Signed-off-by: Jiri Kosina <jkosina@suse.cz> +Acked-by: Larry Finger <larry.finger@lwfinger.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/generic.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/usb/serial/generic.c ++++ b/drivers/usb/serial/generic.c +@@ -208,14 +208,15 @@ int usb_serial_generic_write(struct usb_ + + /* only do something if we have a bulk out endpoint */ + if (serial->num_bulk_out) { +- spin_lock_bh(&port->lock); ++ unsigned long flags; ++ spin_lock_irqsave(&port->lock, flags); + if (port->write_urb_busy) { +- spin_unlock_bh(&port->lock); ++ spin_unlock_irqrestore(&port->lock, flags); + dbg("%s - already writing", __FUNCTION__); + return 0; + } + port->write_urb_busy = 1; +- spin_unlock_bh(&port->lock); ++ spin_unlock_irqrestore(&port->lock, flags); + + count = (count > port->bulk_out_size) ? port->bulk_out_size : count; + |
