V4L/DVB (10138): v4l2-ioctl: change to long return type to match unlocked_ioctl.
[safe/jmp/linux-2.6] / drivers / media / video / w9968cf.c
index 2912326..a3997b7 100644 (file)
@@ -42,7 +42,7 @@
 #include <asm/page.h>
 #include <asm/uaccess.h>
 #include <linux/page-flags.h>
-#include <linux/moduleparam.h>
+#include <media/v4l2-ioctl.h>
 
 #include "w9968cf.h"
 #include "w9968cf_decoder.h"
@@ -111,7 +111,7 @@ static int specific_debug = W9968CF_SPECIFIC_DEBUG;
 
 static unsigned int param_nv[24]; /* number of values per parameter */
 
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
 module_param(ovmod_load, bool, 0644);
 #endif
 module_param(simcams, ushort, 0644);
@@ -144,7 +144,7 @@ module_param(debug, ushort, 0644);
 module_param(specific_debug, bool, 0644);
 #endif
 
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
 MODULE_PARM_DESC(ovmod_load,
                 "\n<0|1> Automatic 'ovcamchip' module loading."
                 "\n0 disabled, 1 enabled."
@@ -399,13 +399,13 @@ MODULE_PARM_DESC(specific_debug,
  ****************************************************************************/
 
 /* Video4linux interface */
-static struct file_operations w9968cf_fops;
-static int w9968cf_open(struct inode*, struct file*);
-static int w9968cf_release(struct inode*, struct file*);
-static int w9968cf_mmap(struct file*, struct vm_area_struct*);
-static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long);
-static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*);
-static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int,
+static const struct v4l2_file_operations w9968cf_fops;
+static int w9968cf_open(struct file *);
+static int w9968cf_release(struct file *);
+static int w9968cf_mmap(struct file *, struct vm_area_struct *);
+static long w9968cf_ioctl(struct file *, unsigned, unsigned long);
+static ssize_t w9968cf_read(struct file *, char __user *, size_t, loff_t *);
+static long w9968cf_v4l_ioctl(struct file *, unsigned int,
                             void __user *);
 
 /* USB-specific */
@@ -417,7 +417,7 @@ static int w9968cf_write_fsb(struct w9968cf_device*, u16* data);
 static int w9968cf_write_sb(struct w9968cf_device*, u16 value);
 static int w9968cf_read_sb(struct w9968cf_device*);
 static int w9968cf_upload_quantizationtables(struct w9968cf_device*);
-static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs);
+static void w9968cf_urb_complete(struct urb *urb);
 
 /* Low-level I2C (SMBus) I/O */
 static int w9968cf_smbus_start(struct w9968cf_device*);
@@ -445,8 +445,6 @@ static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr,
 static u32 w9968cf_i2c_func(struct i2c_adapter*);
 static int w9968cf_i2c_attach_inform(struct i2c_client*);
 static int w9968cf_i2c_detach_inform(struct i2c_client*);
-static int w9968cf_i2c_control(struct i2c_adapter*, unsigned int cmd,
-                              unsigned long arg);
 
 /* Memory management */
 static void* rvmalloc(unsigned long size);
@@ -781,7 +779,7 @@ static int w9968cf_allocate_memory(struct w9968cf_device* cam)
   If there are no requested frames in the FIFO list, packets are collected into
   a temporary buffer.
   --------------------------------------------------------------------------*/
-static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs)
+static void w9968cf_urb_complete(struct urb *urb)
 {
        struct w9968cf_device* cam = (struct w9968cf_device*)urb->context;
        struct w9968cf_frame_t** f;
@@ -913,7 +911,6 @@ static int w9968cf_start_transfer(struct w9968cf_device* cam)
 
        for (i = 0; i < W9968CF_URBS; i++) {
                urb = usb_alloc_urb(W9968CF_ISO_PACKETS, GFP_KERNEL);
-               cam->urb[i] = urb;
                if (!urb) {
                        for (j = 0; j < i; j++)
                                usb_free_urb(cam->urb[j]);
@@ -921,6 +918,7 @@ static int w9968cf_start_transfer(struct w9968cf_device* cam)
                        return -ENOMEM;
                }
 
+               cam->urb[i] = urb;
                urb->dev = udev;
                urb->context = (void*)cam;
                urb->pipe = usb_rcvisocpipe(udev, 1);
@@ -1544,21 +1542,12 @@ static int w9968cf_i2c_detach_inform(struct i2c_client* client)
 }
 
 
-static int
-w9968cf_i2c_control(struct i2c_adapter* adapter, unsigned int cmd,
-                   unsigned long arg)
-{
-       return 0;
-}
-
-
 static int w9968cf_i2c_init(struct w9968cf_device* cam)
 {
        int err = 0;
 
        static struct i2c_algorithm algo = {
                .smbus_xfer =    w9968cf_i2c_smbus_xfer,
-               .algo_control =  w9968cf_i2c_control,
                .functionality = w9968cf_i2c_func,
        };
 
@@ -1573,6 +1562,7 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam)
 
        memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
        strcpy(cam->i2c_adapter.name, "w9968cf");
+       cam->i2c_adapter.dev.parent = &cam->usbdev->dev;
        i2c_set_adapdata(&cam->i2c_adapter, cam);
 
        DBG(6, "Registering I2C adapter with kernel...")
@@ -1827,8 +1817,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
        int err = 0;
 
        /* Work around to avoid FP arithmetics */
-       #define __SC(x) ((x) << 10)
-       #define __UNSC(x) ((x) >> 10)
+       #define SC(x) ((x) << 10)
+       #define UNSC(x) ((x) >> 10)
 
        /* Make sure we are using a supported resolution */
        if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width,
@@ -1836,15 +1826,15 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
                goto error;
 
        /* Scaling factors */
-       fw = __SC(win.width) / cam->maxwidth;
-       fh = __SC(win.height) / cam->maxheight;
+       fw = SC(win.width) / cam->maxwidth;
+       fh = SC(win.height) / cam->maxheight;
 
        /* Set up the width and height values used by the chip */
        if ((win.width > cam->maxwidth) || (win.height > cam->maxheight)) {
                cam->vpp_flag |= VPP_UPSCALE;
                /* Calculate largest w,h mantaining the same w/h ratio */
-               w = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
-               h = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
+               w = (fw >= fh) ? cam->maxwidth : SC(win.width)/fh;
+               h = (fw >= fh) ? SC(win.height)/fw : cam->maxheight;
                if (w < cam->minwidth) /* just in case */
                        w = cam->minwidth;
                if (h < cam->minheight) /* just in case */
@@ -1861,8 +1851,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
 
        /* Calculate cropped area manteining the right w/h ratio */
        if (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) {
-               cw = (fw >= fh) ? cam->maxwidth : __SC(win.width)/fh;
-               ch = (fw >= fh) ? __SC(win.height)/fw : cam->maxheight;
+               cw = (fw >= fh) ? cam->maxwidth : SC(win.width)/fh;
+               ch = (fw >= fh) ? SC(win.height)/fw : cam->maxheight;
        } else {
                cw = w;
                ch = h;
@@ -1901,8 +1891,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
        /* We have to scale win.x and win.y offsets */
        if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
             || (cam->vpp_flag & VPP_UPSCALE) ) {
-               ax = __SC(win.x)/fw;
-               ay = __SC(win.y)/fh;
+               ax = SC(win.x)/fw;
+               ay = SC(win.y)/fh;
        } else {
                ax = win.x;
                ay = win.y;
@@ -1917,8 +1907,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
        /* Adjust win.x, win.y */
        if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
             || (cam->vpp_flag & VPP_UPSCALE) ) {
-               win.x = __UNSC(ax*fw);
-               win.y = __UNSC(ay*fh);
+               win.x = UNSC(ax*fw);
+               win.y = UNSC(ay*fh);
        } else {
                win.x = ax;
                win.y = ay;
@@ -2408,7 +2398,7 @@ error:
        cam->sensor = CC_UNKNOWN;
        DBG(1, "Image sensor initialization failed for %s (/dev/video%d). "
               "Try to detach and attach this device again",
-           symbolic(camlist, cam->id), cam->v4ldev->minor)
+           symbolic(camlist, cam->id), cam->v4ldev->num)
        return err;
 }
 
@@ -2654,7 +2644,7 @@ static void w9968cf_release_resources(struct w9968cf_device* cam)
 {
        mutex_lock(&w9968cf_devlist_mutex);
 
-       DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
+       DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->num)
 
        video_unregister_device(cam->v4ldev);
        list_del(&cam->v4llist);
@@ -2672,14 +2662,14 @@ static void w9968cf_release_resources(struct w9968cf_device* cam)
  * Video4Linux interface                                                    *
  ****************************************************************************/
 
-static int w9968cf_open(struct inode* inode, struct file* filp)
+static int w9968cf_open(struct file *filp)
 {
        struct w9968cf_device* cam;
        int err;
 
        /* This the only safe way to prevent race conditions with disconnect */
        if (!down_read_trylock(&w9968cf_disconnect))
-               return -ERESTARTSYS;
+               return -EAGAIN;
 
        cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
 
@@ -2689,7 +2679,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
                DBG(2, "No supported image sensor has been detected by the "
                       "'ovcamchip' module for the %s (/dev/video%d). Make "
                       "sure it is loaded *before* (re)connecting the camera.",
-                   symbolic(camlist, cam->id), cam->v4ldev->minor)
+                   symbolic(camlist, cam->id), cam->v4ldev->num)
                mutex_unlock(&cam->dev_mutex);
                up_read(&w9968cf_disconnect);
                return -ENODEV;
@@ -2697,7 +2687,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
 
        if (cam->users) {
                DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
-                   symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
+                   symbolic(camlist, cam->id), cam->v4ldev->num, cam->command)
                if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
                        mutex_unlock(&cam->dev_mutex);
                        up_read(&w9968cf_disconnect);
@@ -2719,7 +2709,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
        }
 
        DBG(5, "Opening '%s', /dev/video%d ...",
-           symbolic(camlist, cam->id), cam->v4ldev->minor)
+           symbolic(camlist, cam->id), cam->v4ldev->num)
 
        cam->streaming = 0;
        cam->misconfigured = 0;
@@ -2758,7 +2748,7 @@ deallocate_memory:
 }
 
 
-static int w9968cf_release(struct inode* inode, struct file* filp)
+static int w9968cf_release(struct file *filp)
 {
        struct w9968cf_device* cam;
 
@@ -2895,12 +2885,12 @@ static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma)
 }
 
 
-static int
-w9968cf_ioctl(struct inode* inode, struct file* filp,
+static long
+w9968cf_ioctl(struct file *filp,
              unsigned int cmd, unsigned long arg)
 {
        struct w9968cf_device* cam;
-       int err;
+       long err;
 
        cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
 
@@ -2919,15 +2909,15 @@ w9968cf_ioctl(struct inode* inode, struct file* filp,
                return -EIO;
        }
 
-       err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg);
+       err = w9968cf_v4l_ioctl(filp, cmd, (void __user *)arg);
 
        mutex_unlock(&cam->fileop_mutex);
        return err;
 }
 
 
-static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
-                            unsigned int cmd, void __user * arg)
+static long w9968cf_v4l_ioctl(struct file *filp,
+                            unsigned int cmd, void __user *arg)
 {
        struct w9968cf_device* cam;
        const char* v4l1_ioctls[] = {
@@ -2957,7 +2947,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
                        .minheight = cam->minheight,
                };
                sprintf(cap.name, "W996[87]CF USB Camera #%d",
-                       cam->v4ldev->minor);
+                       cam->v4ldev->num);
                cap.maxwidth = (cam->upscaling && w9968cf_vpp)
                               ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
                                 : cam->maxwidth;
@@ -3466,15 +3456,13 @@ ioctl_fail:
 }
 
 
-static struct file_operations w9968cf_fops = {
+static const struct v4l2_file_operations w9968cf_fops = {
        .owner =   THIS_MODULE,
        .open =    w9968cf_open,
        .release = w9968cf_release,
        .read =    w9968cf_read,
        .ioctl =   w9968cf_ioctl,
-       .compat_ioctl = v4l_compat_ioctl32,
        .mmap =    w9968cf_mmap,
-       .llseek =  no_llseek,
 };
 
 
@@ -3492,7 +3480,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        enum w9968cf_model_id mod_id;
        struct list_head* ptr;
        u8 sc = 0; /* number of simultaneous cameras */
-       static unsigned short dev_nr = 0; /* we are handling device number n */
+       static unsigned short dev_nr; /* 0 - we are handling device number n */
 
        if (le16_to_cpu(udev->descriptor.idVendor)  == winbond_id_table[0].idVendor &&
            le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
@@ -3558,14 +3546,11 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        }
 
        strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
-       cam->v4ldev->owner = THIS_MODULE;
-       cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
-       cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
        cam->v4ldev->fops = &w9968cf_fops;
        cam->v4ldev->minor = video_nr[dev_nr];
        cam->v4ldev->release = video_device_release;
        video_set_drvdata(cam->v4ldev, cam);
-       cam->v4ldev->dev = &cam->dev;
+       cam->v4ldev->parent = &cam->dev;
 
        err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
                                    video_nr[dev_nr]);
@@ -3578,7 +3563,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
                goto fail;
        }
 
-       DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->minor)
+       DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->num)
 
        /* Set some basic constants */
        w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
@@ -3629,7 +3614,7 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
                        DBG(2, "The device is open (/dev/video%d)! "
                               "Process name: %s. Deregistration and memory "
                               "deallocation are deferred on close.",
-                           cam->v4ldev->minor, cam->command)
+                           cam->v4ldev->num, cam->command)
                        cam->misconfigured = 1;
                        w9968cf_stop_transfer(cam);
                        wake_up_interruptible(&cam->wait_queue);