diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-09-06 18:39:07 +0100 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-09-06 18:39:07 +0100 |
commit | ed129684f8f1715a59248d413db621a71c96e285 (patch) | |
tree | c1885a9dafa95a57475321f1ed328aeed2e27754 /linux/drivers/media/video/pwc/pwc-if.c | |
parent | 254094433ada550c4411ed47b20d0fd13f490d21 (diff) | |
parent | 6b59fbe5fa40581818289f66c6337c300056bda8 (diff) | |
download | mediapointer-dvb-s2-ed129684f8f1715a59248d413db621a71c96e285.tar.gz mediapointer-dvb-s2-ed129684f8f1715a59248d413db621a71c96e285.tar.bz2 |
merge: http://linuxtv.org/hg/~mkrufky/fusionhdtv
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/video/pwc/pwc-if.c')
-rw-r--r-- | linux/drivers/media/video/pwc/pwc-if.c | 81 |
1 files changed, 37 insertions, 44 deletions
diff --git a/linux/drivers/media/video/pwc/pwc-if.c b/linux/drivers/media/video/pwc/pwc-if.c index f231363d8..47e663b42 100644 --- a/linux/drivers/media/video/pwc/pwc-if.c +++ b/linux/drivers/media/video/pwc/pwc-if.c @@ -126,9 +126,9 @@ static struct usb_driver pwc_driver = { static int default_size = PSZ_QCIF; static int default_fps = 10; static int default_fbufs = 3; /* Default number of frame buffers */ - int pwc_mbufs = 2; /* Default number of mmap() buffers */ + int pwc_mbufs = 2; /* Default number of mmap() buffers */ #ifdef CONFIG_USB_PWC_DEBUG - int pwc_trace = PWC_DEBUG_LEVEL; + int pwc_trace = PWC_DEBUG_LEVEL; #endif static int power_save = 0; static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */ @@ -209,33 +209,8 @@ static struct video_device pwc_template = { /* Here we want the physical address of the memory. * This is used when initializing the contents of the area. */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) -static unsigned long kvirt_to_pa(unsigned long adr) -{ - unsigned long kva, ret; - - kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); - kva |= adr & (PAGE_SIZE-1); /* restore the offset */ - ret = __pa(kva); - return ret; -} -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) -/** - * kzalloc - allocate memory. The memory is set to zero. - * @size: how many bytes of memory are required. - * @flags: the type of memory to allocate. - */ -void *kzalloc(size_t size, int flags) -{ - void *ret = kmalloc(size, flags); - if (ret) - memset(ret, 0, size); - return ret; -} -#endif static void *pwc_rvmalloc(unsigned long size) { @@ -1232,12 +1207,19 @@ static int pwc_video_open(struct inode *inode, struct file *file) return 0; } + +static void pwc_cleanup(struct pwc_device *pdev) +{ + pwc_remove_sysfs_files(pdev->vdev); + video_unregister_device(pdev->vdev); +} + /* Note that all cleanup is done in the reverse order as in _open */ static int pwc_video_close(struct inode *inode, struct file *file) { struct video_device *vdev = file->private_data; struct pwc_device *pdev; - int i; + int i, hint; PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); @@ -1260,8 +1242,9 @@ static int pwc_video_close(struct inode *inode, struct file *file) pwc_isoc_cleanup(pdev); pwc_free_buffers(pdev); + lock_kernel(); /* Turn off LEDS and power down camera, but only when not unplugged */ - if (pdev->error_status != EPIPE) { + if (!pdev->unplugged) { /* Turn LEDs off */ if (pwc_set_leds(pdev, 0, 0) < 0) PWC_DEBUG_MODULE("Failed to set LED on/off time.\n"); @@ -1270,9 +1253,19 @@ static int pwc_video_close(struct inode *inode, struct file *file) if (i < 0) PWC_ERROR("Failed to power down camera (%d)\n", i); } + pdev->vopen--; + PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); + } else { + pwc_cleanup(pdev); + /* Free memory (don't set pdev to 0 just yet) */ + kfree(pdev); + /* search device_hint[] table if we occupy a slot, by any chance */ + for (hint = 0; hint < MAX_DEV_HINTS; hint++) + if (device_hint[hint].pdev == pdev) + device_hint[hint].pdev = NULL; } - pdev->vopen--; - PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); + unlock_kernel(); + return 0; } @@ -1842,21 +1835,21 @@ static void usb_pwc_disconnect(struct usb_interface *intf) /* Alert waiting processes */ wake_up_interruptible(&pdev->frameq); /* Wait until device is closed */ - while (pdev->vopen) - schedule(); - /* Device is now closed, so we can safely unregister it */ - PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); - pwc_remove_sysfs_files(pdev->vdev); - video_unregister_device(pdev->vdev); - - /* Free memory (don't set pdev to 0 just yet) */ - kfree(pdev); + if(pdev->vopen) { + pdev->unplugged = 1; + } else { + /* Device is closed, so we can safely unregister it */ + PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); + pwc_cleanup(pdev); + /* Free memory (don't set pdev to 0 just yet) */ + kfree(pdev); disconnect_out: - /* search device_hint[] table if we occupy a slot, by any chance */ - for (hint = 0; hint < MAX_DEV_HINTS; hint++) - if (device_hint[hint].pdev == pdev) - device_hint[hint].pdev = NULL; + /* search device_hint[] table if we occupy a slot, by any chance */ + for (hint = 0; hint < MAX_DEV_HINTS; hint++) + if (device_hint[hint].pdev == pdev) + device_hint[hint].pdev = NULL; + } unlock_kernel(); } |