diff options
-rw-r--r-- | Documentation/usb/sn9c102.txt | 9 | ||||
-rw-r--r-- | drivers/usb/media/sn9c102.h | 27 | ||||
-rw-r--r-- | drivers/usb/media/sn9c102_core.c | 92 | ||||
-rw-r--r-- | drivers/usb/media/sn9c102_sensor.h | 16 |
4 files changed, 54 insertions, 90 deletions
diff --git a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt index 541b17fd27f..c6b76414172 100644 --- a/Documentation/usb/sn9c102.txt +++ b/Documentation/usb/sn9c102.txt @@ -111,6 +111,12 @@ corresponding modules must be compiled: # CONFIG_VIDEO_DEV=m +To enable advanced debugging functionality on the device through /sysfs: + + # Multimedia devices + # + CONFIG_VIDEO_ADV_DEBUG=y + # USB support # CONFIG_USB=m @@ -208,7 +214,8 @@ Default: 2 8. Optional device control through "sysfs" [1] ========================================== -It is possible to read and write both the SN9C10x and the image sensor +If the kernel has been compiled with the CONFIG_VIDEO_ADV_DEBUG option enabled, +it is possible to read and write both the SN9C10x and the image sensor registers by using the "sysfs" filesystem interface. Every time a supported device is recognized, a write-only file named "green" is diff --git a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h index 967c6b6bc0f..17d60c1eea7 100644 --- a/drivers/usb/media/sn9c102.h +++ b/drivers/usb/media/sn9c102.h @@ -23,7 +23,8 @@ #include <linux/version.h> #include <linux/usb.h> -#include <linux/videodev.h> +#include <linux/videodev2.h> +#include <media/v4l2-common.h> #include <linux/device.h> #include <linux/list.h> #include <linux/spinlock.h> @@ -52,13 +53,6 @@ /*****************************************************************************/ -#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers" -#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia" -#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" -#define SN9C102_MODULE_LICENSE "GPL" -#define SN9C102_MODULE_VERSION "1:1.25" -#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 25) - enum sn9c102_bridge { BRIDGE_SN9C101 = 0x01, BRIDGE_SN9C102 = 0x02, @@ -119,8 +113,6 @@ static DECLARE_MUTEX(sn9c102_sysfs_lock); static DECLARE_RWSEM(sn9c102_disconnect); struct sn9c102_device { - struct device dev; - struct video_device* v4ldev; enum sn9c102_bridge bridge; @@ -161,7 +153,6 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, struct sn9c102_sensor* sensor) { cam->sensor = sensor; - cam->sensor->dev = &cam->dev; cam->sensor->usbdev = cam->usbdev; } @@ -174,14 +165,19 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, do { \ if (debug >= (level)) { \ if ((level) == 1) \ - dev_err(&cam->dev, fmt "\n", ## args); \ + dev_err(&cam->usbdev->dev, fmt "\n", ## args); \ else if ((level) == 2) \ - dev_info(&cam->dev, fmt "\n", ## args); \ + dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ else if ((level) >= 3) \ - dev_info(&cam->dev, "[%s:%d] " fmt "\n", \ + dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ __FUNCTION__, __LINE__ , ## args); \ } \ } while (0) +# define V4LDBG(level, name, cmd) \ +do { \ + if (debug >= (level)) \ + v4l_print_ioctl(name, cmd); \ +} while (0) # define KDBG(level, fmt, args...) \ do { \ if (debug >= (level)) { \ @@ -193,8 +189,9 @@ do { \ } \ } while (0) #else -# define KDBG(level, fmt, args...) do {;} while(0) # define DBG(level, fmt, args...) do {;} while(0) +# define V4LDBG(level, name, cmd) do {;} while(0) +# define KDBG(level, fmt, args...) do {;} while(0) #endif #undef PDBG diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c index 6090439663e..c81397e4714 100644 --- a/drivers/usb/media/sn9c102_core.c +++ b/drivers/usb/media/sn9c102_core.c @@ -45,6 +45,15 @@ /*****************************************************************************/ +#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers" +#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia" +#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" +#define SN9C102_MODULE_LICENSE "GPL" +#define SN9C102_MODULE_VERSION "1:1.26" +#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 26) + +/*****************************************************************************/ + MODULE_DEVICE_TABLE(usb, sn9c102_id_table); MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL); @@ -115,50 +124,6 @@ static sn9c102_eof_header_t sn9c102_eof_header[] = { /*****************************************************************************/ -static void* rvmalloc(size_t size) -{ - void* mem; - unsigned long adr; - - size = PAGE_ALIGN(size); - - mem = vmalloc_32((unsigned long)size); - if (!mem) - return NULL; - - memset(mem, 0, size); - - adr = (unsigned long)mem; - while (size > 0) { - SetPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - return mem; -} - - -static void rvfree(void* mem, size_t size) -{ - unsigned long adr; - - if (!mem) - return; - - size = PAGE_ALIGN(size); - - adr = (unsigned long)mem; - while (size > 0) { - ClearPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - vfree(mem); -} - - static u32 sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, enum sn9c102_io_method io) @@ -177,7 +142,7 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, cam->nbuffers = count; while (cam->nbuffers > 0) { - if ((buff = rvmalloc(cam->nbuffers * PAGE_ALIGN(imagesize)))) + if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize)))) break; cam->nbuffers--; } @@ -201,8 +166,7 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, static void sn9c102_release_buffers(struct sn9c102_device* cam) { if (cam->nbuffers) { - rvfree(cam->frame[0].bufmem, - cam->nbuffers * PAGE_ALIGN(cam->frame[0].buf.length)); + vfree(cam->frame[0].bufmem); cam->nbuffers = 0; } cam->frame_current = NULL; @@ -745,7 +709,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam) int err = 0; for (i = 0; i < SN9C102_URBS; i++) { - cam->transfer_buffer[i] = kmalloc(SN9C102_ISO_PACKETS * psz, + cam->transfer_buffer[i] = kzalloc(SN9C102_ISO_PACKETS * psz, GFP_KERNEL); if (!cam->transfer_buffer[i]) { err = -ENOMEM; @@ -865,6 +829,7 @@ static int sn9c102_stream_interrupt(struct sn9c102_device* cam) /*****************************************************************************/ +#ifdef CONFIG_VIDEO_ADV_DEBUG static u8 sn9c102_strtou8(const char* buff, size_t len, ssize_t* count) { char str[5]; @@ -1289,6 +1254,7 @@ static void sn9c102_create_sysfs(struct sn9c102_device* cam) video_device_create_file(v4ldev, &class_device_attr_i2c_val); } } +#endif /* CONFIG_VIDEO_ADV_DEBUG */ /*****************************************************************************/ @@ -1754,9 +1720,8 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) { struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); unsigned long size = vma->vm_end - vma->vm_start, - start = vma->vm_start, - pos, - page; + start = vma->vm_start; + void *pos; u32 i; if (down_interruptible(&cam->fileop_sem)) @@ -1790,15 +1755,12 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) return -EINVAL; } - /* VM_IO is eventually going to replace PageReserved altogether */ vma->vm_flags |= VM_IO; - vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ + vma->vm_flags |= VM_RESERVED; - pos = (unsigned long)cam->frame[i].bufmem; + pos = cam->frame[i].bufmem; while (size > 0) { /* size is page-aligned */ - page = vmalloc_to_pfn((void *)pos); - if (remap_pfn_range(vma, start, page, PAGE_SIZE, - vma->vm_page_prot)) { + if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { up(&cam->fileop_sem); return -EAGAIN; } @@ -1831,7 +1793,8 @@ sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg) strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card)); if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0) - strlcpy(cap.bus_info, cam->dev.bus_id, sizeof(cap.bus_info)); + strlcpy(cap.bus_info, cam->usbdev->dev.bus_id, + sizeof(cap.bus_info)); if (copy_to_user(arg, &cap, sizeof(cap))) return -EFAULT; @@ -1852,7 +1815,7 @@ sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg) return -EINVAL; memset(&i, 0, sizeof(i)); - strcpy(i.name, "USB"); + strcpy(i.name, "Camera"); if (copy_to_user(arg, &i, sizeof(i))) return -EFAULT; @@ -2708,6 +2671,8 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp, return -EIO; } + V4LDBG(3, "sn9c102", cmd); + err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); up(&cam->fileop_sem); @@ -2740,13 +2705,12 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) unsigned int i; int err = 0, r; - if (!(cam = kmalloc(sizeof(struct sn9c102_device), GFP_KERNEL))) + if (!(cam = kzalloc(sizeof(struct sn9c102_device), GFP_KERNEL))) return -ENOMEM; cam->usbdev = udev; - memcpy(&cam->dev, &udev->dev, sizeof(struct device)); - if (!(cam->control_buffer = kmalloc(8, GFP_KERNEL))) { + if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) { DBG(1, "kmalloc() failed"); err = -ENOMEM; goto fail; @@ -2806,7 +2770,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) strcpy(cam->v4ldev->name, "SN9C10x PC Camera"); cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; - cam->v4ldev->hardware = VID_HARDWARE_SN9C102; + cam->v4ldev->hardware = 0; cam->v4ldev->fops = &sn9c102_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; @@ -2832,8 +2796,10 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; +#ifdef CONFIG_VIDEO_ADV_DEBUG sn9c102_create_sysfs(cam); DBG(2, "Optional device control through 'sysfs' interface ready"); +#endif usb_set_intfdata(intf, cam); diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h index a0e561b2c85..7d953b24f2f 100644 --- a/drivers/usb/media/sn9c102_sensor.h +++ b/drivers/usb/media/sn9c102_sensor.h @@ -196,10 +196,11 @@ extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index); /* NOTE: there are no exported debugging functions. To uniform the output you must use the dev_info()/dev_warn()/dev_err() macros defined in device.h, - already included here, the argument being the struct device 'dev' of the - sensor structure. Do NOT use these macros before the sensor is attached or - the kernel will crash! However, you should not need to notify the user about - common errors or other messages, since this is done by the master module. + already included here, the argument being the struct device '&usbdev->dev' + of the sensor structure. Do NOT use these macros before the sensor is + attached or the kernel will crash! However, you should not need to notify + the user about common errors or other messages, since this is done by the + master module. */ /*****************************************************************************/ @@ -358,13 +359,6 @@ struct sn9c102_sensor { error code without rolling back. */ - const struct device* dev; - /* - This is the argument for dev_err(), dev_info() and dev_warn(). It - is used for debugging purposes. You must not access the struct - before the sensor is attached. - */ - const struct usb_device* usbdev; /* Points to the usb_device struct after the sensor is attached. |