diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-08-24 00:35:04 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-08-24 00:35:04 -0400 |
| commit | 9e1a3e31cbfd5f5822e633c4bdf3304079cb10c2 (patch) | |
| tree | 88653393c17c0ac5c0b30a244d6e6dc97b314e1f | |
| parent | de80af4cc9c30318224b8520dc76a7d097e64cbd (diff) | |
| parent | d65cc1b45e7d3a24c25fd3d730042e407d6d64ce (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: (35 commits)
usb: add PRODUCT, TYPE to usb-interface events
USB: resubmission unusual_devs modification for Nikon D80
usb quirks: Add Canon EOS 5D (PC Connection mode) to the autosuspend blacklist
USB: make EHCI initialize properly on PPC SOCs
UEAGLE: Remove sysfs files on error case
USB: fsl_usb2_udc: fix bug in processing setup requests
USB: g_file_storage: fix bug in DMA buffer handling
USB: update last_busy field correctly
USB: fix DoS in pwc USB video driver
USB: allow retry on descriptor fetch errors
USB: unkill cxacru atm driver
USB: Adding support for HTC Smartphones to ipaq
USB: another quirky device
USB: quirky mass storage device
USB: ohci, fix oddball gcc warning
usb-storage: fix bugs in the disconnect pathway
usb: typo in usb R8A66597 HCD config
USB: accept 1-byte Device Status replies, fixing some b0rken devices
USB: blacklist Samsung ML-2010 printer
usb-serial: fix oti6858.c segfault in termios handling
...
35 files changed, 255 insertions, 172 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 2c7b158ce7e1..40307f3f6fe3 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
| @@ -1772,6 +1772,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
| 1772 | if (dev->alt_max_pkt_size == NULL) { | 1772 | if (dev->alt_max_pkt_size == NULL) { |
| 1773 | em28xx_errdev("out of memory!\n"); | 1773 | em28xx_errdev("out of memory!\n"); |
| 1774 | em28xx_devused&=~(1<<nr); | 1774 | em28xx_devused&=~(1<<nr); |
| 1775 | kfree(dev); | ||
| 1775 | return -ENOMEM; | 1776 | return -ENOMEM; |
| 1776 | } | 1777 | } |
| 1777 | 1778 | ||
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 9c0e8d18c2f6..3d81966d8c42 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
| @@ -1196,12 +1196,19 @@ static int pwc_video_open(struct inode *inode, struct file *file) | |||
| 1196 | return 0; | 1196 | return 0; |
| 1197 | } | 1197 | } |
| 1198 | 1198 | ||
| 1199 | |||
| 1200 | static void pwc_cleanup(struct pwc_device *pdev) | ||
| 1201 | { | ||
| 1202 | pwc_remove_sysfs_files(pdev->vdev); | ||
| 1203 | video_unregister_device(pdev->vdev); | ||
| 1204 | } | ||
| 1205 | |||
| 1199 | /* Note that all cleanup is done in the reverse order as in _open */ | 1206 | /* Note that all cleanup is done in the reverse order as in _open */ |
| 1200 | static int pwc_video_close(struct inode *inode, struct file *file) | 1207 | static int pwc_video_close(struct inode *inode, struct file *file) |
| 1201 | { | 1208 | { |
| 1202 | struct video_device *vdev = file->private_data; | 1209 | struct video_device *vdev = file->private_data; |
| 1203 | struct pwc_device *pdev; | 1210 | struct pwc_device *pdev; |
| 1204 | int i; | 1211 | int i, hint; |
| 1205 | 1212 | ||
| 1206 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); | 1213 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); |
| 1207 | 1214 | ||
| @@ -1224,8 +1231,9 @@ static int pwc_video_close(struct inode *inode, struct file *file) | |||
| 1224 | pwc_isoc_cleanup(pdev); | 1231 | pwc_isoc_cleanup(pdev); |
| 1225 | pwc_free_buffers(pdev); | 1232 | pwc_free_buffers(pdev); |
| 1226 | 1233 | ||
| 1234 | lock_kernel(); | ||
| 1227 | /* Turn off LEDS and power down camera, but only when not unplugged */ | 1235 | /* Turn off LEDS and power down camera, but only when not unplugged */ |
| 1228 | if (pdev->error_status != EPIPE) { | 1236 | if (!pdev->unplugged) { |
| 1229 | /* Turn LEDs off */ | 1237 | /* Turn LEDs off */ |
| 1230 | if (pwc_set_leds(pdev, 0, 0) < 0) | 1238 | if (pwc_set_leds(pdev, 0, 0) < 0) |
| 1231 | PWC_DEBUG_MODULE("Failed to set LED on/off time.\n"); | 1239 | PWC_DEBUG_MODULE("Failed to set LED on/off time.\n"); |
| @@ -1234,9 +1242,19 @@ static int pwc_video_close(struct inode *inode, struct file *file) | |||
| 1234 | if (i < 0) | 1242 | if (i < 0) |
| 1235 | PWC_ERROR("Failed to power down camera (%d)\n", i); | 1243 | PWC_ERROR("Failed to power down camera (%d)\n", i); |
| 1236 | } | 1244 | } |
| 1245 | pdev->vopen--; | ||
| 1246 | PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", i); | ||
| 1247 | } else { | ||
| 1248 | pwc_cleanup(pdev); | ||
| 1249 | /* Free memory (don't set pdev to 0 just yet) */ | ||
| 1250 | kfree(pdev); | ||
| 1251 | /* search device_hint[] table if we occupy a slot, by any chance */ | ||
| 1252 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) | ||
| 1253 | if (device_hint[hint].pdev == pdev) | ||
| 1254 | device_hint[hint].pdev = NULL; | ||
| 1237 | } | 1255 | } |
| 1238 | pdev->vopen--; | 1256 | unlock_kernel(); |
| 1239 | PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); | 1257 | |
| 1240 | return 0; | 1258 | return 0; |
| 1241 | } | 1259 | } |
| 1242 | 1260 | ||
| @@ -1791,21 +1809,21 @@ static void usb_pwc_disconnect(struct usb_interface *intf) | |||
| 1791 | /* Alert waiting processes */ | 1809 | /* Alert waiting processes */ |
| 1792 | wake_up_interruptible(&pdev->frameq); | 1810 | wake_up_interruptible(&pdev->frameq); |
| 1793 | /* Wait until device is closed */ | 1811 | /* Wait until device is closed */ |
| 1794 | while (pdev->vopen) | 1812 | if(pdev->vopen) { |
| 1795 | schedule(); | 1813 | pdev->unplugged = 1; |
| 1796 | /* Device is now closed, so we can safely unregister it */ | 1814 | } else { |
| 1797 | PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); | 1815 | /* Device is closed, so we can safely unregister it */ |
| 1798 | pwc_remove_sysfs_files(pdev->vdev); | 1816 | PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); |
| 1799 | video_unregister_device(pdev->vdev); | 1817 | pwc_cleanup(pdev); |
| 1800 | 1818 | /* Free memory (don't set pdev to 0 just yet) */ | |
| 1801 | /* Free memory (don't set pdev to 0 just yet) */ | 1819 | kfree(pdev); |
| 1802 | kfree(pdev); | ||
| 1803 | 1820 | ||
| 1804 | disconnect_out: | 1821 | disconnect_out: |
| 1805 | /* search device_hint[] table if we occupy a slot, by any chance */ | 1822 | /* search device_hint[] table if we occupy a slot, by any chance */ |
| 1806 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) | 1823 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) |
| 1807 | if (device_hint[hint].pdev == pdev) | 1824 | if (device_hint[hint].pdev == pdev) |
| 1808 | device_hint[hint].pdev = NULL; | 1825 | device_hint[hint].pdev = NULL; |
| 1826 | } | ||
| 1809 | 1827 | ||
| 1810 | unlock_kernel(); | 1828 | unlock_kernel(); |
| 1811 | } | 1829 | } |
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 910a04f53920..8e8e5b27e77e 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
| @@ -193,6 +193,7 @@ struct pwc_device | |||
| 193 | char vsnapshot; /* snapshot mode */ | 193 | char vsnapshot; /* snapshot mode */ |
| 194 | char vsync; /* used by isoc handler */ | 194 | char vsync; /* used by isoc handler */ |
| 195 | char vmirror; /* for ToUCaM series */ | 195 | char vmirror; /* for ToUCaM series */ |
| 196 | char unplugged; | ||
| 196 | 197 | ||
| 197 | int cmd_len; | 198 | int cmd_len; |
| 198 | unsigned char cmd_buf[13]; | 199 | unsigned char cmd_buf[13]; |
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 63436892688c..7580aa5da0f8 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
| @@ -21,6 +21,7 @@ config USB_ARCH_HAS_HCD | |||
| 21 | default y if USB_ARCH_HAS_EHCI | 21 | default y if USB_ARCH_HAS_EHCI |
