I've replaced simple_select in v4l1-compat.c: the current implementation
is just way to ugly to remain in the kernel.

Unfortunately I don't have a test setup.
Could someone test that the patch doesn't break the compatibility layer?
The patch is against 2.5.58.

Thanks,

--
   Manfred


--- 2.5/drivers/media/video/v4l1-compat.c       2003-01-15 20:30:20.000000000 +0100
+++ build-2.5/drivers/media/video/v4l1-compat.c 2003-01-16 23:50:26.000000000 +0100
@@ -199,66 +199,33 @@
        return palette;
 }
 
-/*  Do an 'in' (wait for input) select on a single file descriptor  */
-/*  This stuff plaigarized from linux/fs/select.c     */
-#define __FD_IN(fds, n)        (fds->in + n)
-#define BIT(i)         (1UL << ((i)&(__NFDBITS-1)))
-#define SET(i,m)       (*(m) |= (i))
-extern int do_select(int n, fd_set_bits *fds, long *timeout);
-
-
 static int
 simple_select(struct file *file)
 {
-       fd_set_bits fds;
-       char *bits;
-       long timeout;
-       int i, fd, n, ret, size;
-
-       for (i = 0; i < current->files->max_fds; ++i)
-               if (file == current->files->fd[i])
-                       break;
-       if (i == current->files->max_fds)
-               return -EINVAL;
-       fd = i;
-       n = fd + 1;
-
-       timeout = MAX_SCHEDULE_TIMEOUT;
-       /*
-        * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
-        * since we used fdset we need to allocate memory in units of
-        * long-words. 
-        */
-       ret = -ENOMEM;
-       size = FDS_BYTES(n);
-       bits = kmalloc(6 * size, GFP_KERNEL);
-       if (!bits)
-               goto out_nofds;
-       fds.in      = (unsigned long *)  bits;
-       fds.out     = (unsigned long *) (bits +   size);
-       fds.ex      = (unsigned long *) (bits + 2*size);
-       fds.res_in  = (unsigned long *) (bits + 3*size);
-       fds.res_out = (unsigned long *) (bits + 4*size);
-       fds.res_ex  = (unsigned long *) (bits + 5*size);
-
-       /*  All zero except our one file descriptor bit, for input  */
-       memset(bits, 0, 6 * size);
-       SET(BIT(fd), __FD_IN((&fds), fd / __NFDBITS));
-
-       ret = do_select(n, &fds, &timeout);
-
-       if (ret < 0)
-               goto out;
-       if (!ret) {
-               ret = -ERESTARTNOHAND;
-               if (signal_pending(current))
-                       goto out;
-               ret = 0;
-       }
-out:
-       kfree(bits);
-out_nofds:
-       return ret;
+       int retval = 1;
+       struct poll_wqueues wait_table;
+       poll_table *table;
+
+       poll_initwait(&wait_table);
+       table = &wait_table.pt;
+       for (;;) {
+               int mask;
+               set_current_state(TASK_INTERRUPTIBLE);
+               mask = POLLIN;
+               if (file->f_op && file->f_op->poll)
+                       mask = file->f_op->poll(file, table);
+               if (mask & POLLIN)
+                       break;
+               table = NULL;
+               if (signal_pending(current)) {
+                       retval = -ERESTARTSYS;
+                       break;
+               }
+               schedule();
+       }
+       current->state = TASK_RUNNING;
+       poll_freewait(&wait_table);
+       return retval;
 }
 
 static int count_inputs(struct inode         *inode,

Reply via email to