All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gerd Knorr <kraxel@bytesex.org>
To: Linus Torvalds <torvalds@transmeta.com>,
	Kernel List <linux-kernel@vger.kernel.org>
Subject: [patch] 22_v4l1-compat-stack
Date: Wed, 2 Apr 2003 18:39:15 +0200	[thread overview]
Message-ID: <20030402163915.GA24748@bytesex.org> (raw)

  Hi,

This patch updates the v4l1-compat module.  Changes:
 * use f_op->poll() instead of do_select()
 * reduce stack usage of the v4l1_translate_ioctl function.
 * misc fixes here and there.

please apply,

  Gerd

diff -u linux-2.5.66/drivers/media/video/v4l1-compat.c linux/drivers/media/video/v4l1-compat.c
--- linux-2.5.66/drivers/media/video/v4l1-compat.c	2003-04-02 11:42:55.838088294 +0200
+++ linux/drivers/media/video/v4l1-compat.c	2003-04-02 11:49:36.309560581 +0200
@@ -145,16 +145,16 @@
 	[VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
 };
 
-static int
-palette_to_pixelformat(int palette)
+static unsigned int
+palette_to_pixelformat(unsigned int palette)
 {
-	if (palette < sizeof(palette2pixelformat)/sizeof(int))
+	if (palette < ARRAY_SIZE(palette2pixelformat))
 		return palette2pixelformat[palette];
 	else
 		return 0;
 }
 
-static int
+static unsigned int
 pixelformat_to_palette(int pixelformat)
 {
 	int	palette = 0;
@@ -199,66 +199,41 @@
 	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)
+static int poll_one(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;
+	poll_table *table;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,48)
+	poll_table wait_table;
+
+	poll_initwait(&wait_table);
+	table = &wait_table;
+#else
+	struct poll_wqueues pwq;
+
+	poll_initwait(&pwq);
+	table = &pwq.pt;
+#endif
+	for (;;) {
+		int mask;
+		set_current_state(TASK_INTERRUPTIBLE);
+		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;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,48)
+	poll_freewait(&wait_table);
+#else
+	poll_freewait(&pwq);
+#endif
+	return retval;
 }
 
 static int count_inputs(struct inode         *inode,
@@ -317,26 +292,36 @@
 			   void			*arg,
 			   v4l2_kioctl          drv)
 {
-	int	             err = -ENOIOCTLCMD;
+	struct v4l2_capability  *cap2 = NULL;
+	struct v4l2_format	*fmt2 = NULL;
 
-	switch (cmd)
-	{
+	struct v4l2_framebuffer fbuf2;
+	struct v4l2_input	input2;
+	struct v4l2_tuner	tun2;
+	struct v4l2_standard	std2;
+	struct v4l2_frequency   freq2;
+	struct v4l2_audio	aud2;
+	struct v4l2_queryctrl	qctrl2;
+	struct v4l2_buffer	buf2;
+	v4l2_std_id    		sid;
+	int i, err = 0;
+
+	switch (cmd) {
 	case VIDIOCGCAP:	/* capability */
 	{
 		struct video_capability *cap = arg;
-		struct v4l2_capability cap2;
-		struct v4l2_framebuffer fbuf2;
-		
+
+		cap2 = kmalloc(sizeof(*cap2),GFP_KERNEL);
 		memset(cap, 0, sizeof(*cap));
-		memset(&cap2, 0, sizeof(cap2));
+		memset(cap2, 0, sizeof(*cap2));
 		memset(&fbuf2, 0, sizeof(fbuf2));
 
-		err = drv(inode, file, VIDIOC_QUERYCAP, &cap2);
+		err = drv(inode, file, VIDIOC_QUERYCAP, cap2);
 		if (err < 0) {
 			dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n",err);
 			break;
 		}
-		if (cap2.capabilities & V4L2_CAP_VIDEO_OVERLAY) {
+		if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) {
 			err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
 			if (err < 0) {
 				dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n",err);
@@ -345,16 +330,16 @@
 			err = 0;
 		}
 
-		memcpy(cap->name, cap2.card, 
-		       min(sizeof(cap->name), sizeof(cap2.card)));
+		memcpy(cap->name, cap2->card, 
+		       min(sizeof(cap->name), sizeof(cap2->card)));
 		cap->name[sizeof(cap->name) - 1] = 0;
-		if (cap2.capabilities & V4L2_CAP_VIDEO_CAPTURE)
+		if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE)
 			cap->type |= VID_TYPE_CAPTURE;
-		if (cap2.capabilities & V4L2_CAP_TUNER)
+		if (cap2->capabilities & V4L2_CAP_TUNER)
 			cap->type |= VID_TYPE_TUNER;
-		if (cap2.capabilities & V4L2_CAP_VBI_CAPTURE)
+		if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE)
 			cap->type |= VID_TYPE_TELETEXT;
-		if (cap2.capabilities & V4L2_CAP_VIDEO_OVERLAY)
+		if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY)
 			cap->type |= VID_TYPE_OVERLAY;
 		if (fbuf2.capability & V4L2_FBUF_CAP_LIST_CLIPPING)
 			cap->type |= VID_TYPE_CLIPPING;
@@ -370,7 +355,6 @@
 	case VIDIOCGFBUF: /*  get frame buffer  */
 	{
 		struct video_buffer	*buffer = arg;
-		struct v4l2_framebuffer	fbuf2;
 
 		err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
 		if (err < 0) {
@@ -412,7 +396,6 @@
 	case VIDIOCSFBUF: /*  set frame buffer  */
 	{
 		struct video_buffer	*buffer = arg;
-		struct v4l2_framebuffer	fbuf2;
 
 		memset(&fbuf2, 0, sizeof(fbuf2));
 		fbuf2.base       = buffer->base;
@@ -444,36 +427,36 @@
 	case VIDIOCGWIN: /*  get window or capture dimensions  */
 	{
 		struct video_window	*win = arg;
-		struct v4l2_format	fmt2;
 
+		fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
 		memset(win,0,sizeof(*win));
-		memset(&fmt2,0,sizeof(fmt2));
+		memset(fmt2,0,sizeof(*fmt2));
 
-		fmt2.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
-		err = drv(inode, file, VIDIOC_G_FMT, &fmt2);
+		fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
+		err = drv(inode, file, VIDIOC_G_FMT, fmt2);
 		if (err < 0)
 			dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n",err);
 		if (err == 0) {
-			win->x         = fmt2.fmt.win.w.left;
-			win->y         = fmt2.fmt.win.w.top;
-			win->width     = fmt2.fmt.win.w.width;
-			win->height    = fmt2.fmt.win.w.height;
-			win->chromakey = fmt2.fmt.win.chromakey;
+			win->x         = fmt2->fmt.win.w.left;
+			win->y         = fmt2->fmt.win.w.top;
+			win->width     = fmt2->fmt.win.w.width;
+			win->height    = fmt2->fmt.win.w.height;
+			win->chromakey = fmt2->fmt.win.chromakey;
 			win->clips     = NULL;
 			win->clipcount = 0;
 			break;
 		}
 
-		fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		err = drv(inode, file, VIDIOC_G_FMT, &fmt2);
+		fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		err = drv(inode, file, VIDIOC_G_FMT, fmt2);
 		if (err < 0) {
 			dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n",err);
 			break;
 		}
 		win->x         = 0;
 		win->y         = 0;
-		win->width     = fmt2.fmt.pix.width;
-		win->height    = fmt2.fmt.pix.height;
+		win->width     = fmt2->fmt.pix.width;
+		win->height    = fmt2->fmt.pix.height;
 		win->chromakey = 0;
 		win->clips     = NULL;
 		win->clipcount = 0;
@@ -482,37 +465,41 @@
 	case VIDIOCSWIN: /*  set window and/or capture dimensions  */
 	{
 		struct video_window	*win = arg;
-		struct v4l2_format	fmt2;
+		int err1,err2;
 
-		memset(&fmt2,0,sizeof(fmt2));
-		fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		err = drv(inode, file, VIDIOC_G_FMT, &fmt2);
-		if (err < 0)
+		fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
+		memset(fmt2,0,sizeof(*fmt2));
+		fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		err1 = drv(inode, file, VIDIOC_G_FMT, fmt2);
+		if (err1 < 0)
 			dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n",err);
-		if (err == 0) {
-			fmt2.fmt.pix.width  = win->width;
-			fmt2.fmt.pix.height = win->height;
-			fmt2.fmt.pix.field  = V4L2_FIELD_ANY;
-			err = drv(inode, file, VIDIOC_S_FMT, &fmt2);
+		if (err1 == 0) {
+			fmt2->fmt.pix.width  = win->width;
+			fmt2->fmt.pix.height = win->height;
+			fmt2->fmt.pix.field  = V4L2_FIELD_ANY;
+			err = drv(inode, file, VIDIOC_S_FMT, fmt2);
 			if (err < 0)
 				dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n",
 					err);
-			win->width  = fmt2.fmt.pix.width;
-			win->height = fmt2.fmt.pix.height;
+			win->width  = fmt2->fmt.pix.width;
+			win->height = fmt2->fmt.pix.height;
 		}
 
-		memset(&fmt2,0,sizeof(fmt2));
-		fmt2.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
-		fmt2.fmt.win.w.left    = win->x;
-		fmt2.fmt.win.w.top     = win->y;
-		fmt2.fmt.win.w.width   = win->width;
-		fmt2.fmt.win.w.height  = win->height;
-		fmt2.fmt.win.chromakey = win->chromakey;
-		fmt2.fmt.win.clips     = (void *)win->clips;
-		fmt2.fmt.win.clipcount = win->clipcount;
-		err = drv(inode, file, VIDIOC_S_FMT, &fmt2);
-		if (err < 0)
+		memset(fmt2,0,sizeof(*fmt2));
+		fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
+		fmt2->fmt.win.w.left    = win->x;
+		fmt2->fmt.win.w.top     = win->y;
+		fmt2->fmt.win.w.width   = win->width;
+		fmt2->fmt.win.w.height  = win->height;
+		fmt2->fmt.win.chromakey = win->chromakey;
+		fmt2->fmt.win.clips     = (void *)win->clips;
+		fmt2->fmt.win.clipcount = win->clipcount;
+		err2 = drv(inode, file, VIDIOC_S_FMT, fmt2);
+		if (err2 < 0)
 			dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n",err);
+
+		if (err1 != 0 && err2 != 0)
+			err = err1;
 		break;
 	}
 	case VIDIOCCAPTURE: /*  turn on/off preview  */
@@ -525,8 +512,6 @@
 	case VIDIOCGCHAN: /*  get input information  */
 	{
 		struct video_channel	*chan = arg;
-		struct v4l2_input	input2;
-		v4l2_std_id    		sid;
 
 		memset(&input2,0,sizeof(input2));
 		input2.index = chan->channel;
@@ -568,16 +553,32 @@
 	case VIDIOCSCHAN: /*  set input  */
 	{
 		struct video_channel *chan = arg;
-		
+
+		sid = 0;
 		err = drv(inode, file, VIDIOC_S_INPUT, &chan->channel);
 		if (err < 0)
 			dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n",err);
+		switch (chan->norm) {
+		case VIDEO_MODE_PAL:
+			sid = V4L2_STD_PAL;
+			break;
+		case VIDEO_MODE_NTSC:
+			sid = V4L2_STD_NTSC;
+			break;
+		case VIDEO_MODE_SECAM:
+			sid = V4L2_STD_SECAM;
+			break;
+		}
+		if (0 != sid) {
+			err = drv(inode, file, VIDIOC_S_STD, &sid);
+			if (err < 0)
+				dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n",err);
+		}
 		break;
 	}
 	case VIDIOCGPICT: /*  get tone controls & partial capture format  */
 	{
 		struct video_picture	*pict = arg;
-		struct v4l2_format	fmt2;
 
 		pict->brightness = get_v4l_control(inode, file,
 						   V4L2_CID_BRIGHTNESS,drv);
@@ -590,25 +591,24 @@
 		pict->whiteness = get_v4l_control(inode, file,
 						  V4L2_CID_WHITENESS, drv);
 
-		memset(&fmt2,0,sizeof(fmt2));
-		fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		err = drv(inode, file, VIDIOC_G_FMT, &fmt2);
+		fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
+		memset(fmt2,0,sizeof(*fmt2));
+		fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		err = drv(inode, file, VIDIOC_G_FMT, fmt2);
 		if (err < 0) {
 			dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err);
 			break;
 		}
 #if 0 /* FIXME */
-		pict->depth   = fmt2.fmt.pix.depth;
+		pict->depth   = fmt2->fmt.pix.depth;
 #endif
 		pict->palette = pixelformat_to_palette(
-			fmt2.fmt.pix.pixelformat);
+			fmt2->fmt.pix.pixelformat);
 		break;
 	}
 	case VIDIOCSPICT: /*  set tone controls & partial capture format  */
 	{
 		struct video_picture	*pict = arg;
-		struct v4l2_format	fmt2;
-		struct v4l2_framebuffer	fbuf2;
 
 		set_v4l_control(inode, file,
 				V4L2_CID_BRIGHTNESS, pict->brightness, drv);
@@ -621,16 +621,17 @@
 		set_v4l_control(inode, file,
 				V4L2_CID_WHITENESS, pict->whiteness, drv);
 
-		memset(&fmt2,0,sizeof(fmt2));
-		fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		err = drv(inode, file, VIDIOC_G_FMT, &fmt2);
+		fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
+		memset(fmt2,0,sizeof(*fmt2));
+		fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		err = drv(inode, file, VIDIOC_G_FMT, fmt2);
 		if (err < 0)
 			dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
-		if (fmt2.fmt.pix.pixelformat != 
+		if (fmt2->fmt.pix.pixelformat != 
 		    palette_to_pixelformat(pict->palette)) {
-			fmt2.fmt.pix.pixelformat = palette_to_pixelformat(
+			fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
 				pict->palette);
-			err = drv(inode, file, VIDIOC_S_FMT, &fmt2);
+			err = drv(inode, file, VIDIOC_S_FMT, fmt2);
 			if (err < 0)
 				dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err);
 		}
@@ -652,8 +653,6 @@
 	case VIDIOCGTUNER: /*  get tuner information  */
 	{
 		struct video_tuner	*tun = arg;
-		struct v4l2_tuner	tun2;
-		v4l2_std_id    		sid;
 
 		memset(&tun2,0,sizeof(tun2));
 		err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
@@ -669,6 +668,19 @@
 		tun->flags = 0;
 		tun->mode = VIDEO_MODE_AUTO;
 
+		for (i = 0; i < 64; i++) {
+			memset(&std2,0,sizeof(std2));
+			std2.index = i;
+			if (0 != drv(inode, file, VIDIOC_ENUMSTD, &std2))
+				break;
+			if (std2.id & V4L2_STD_PAL)
+				tun->flags |= VIDEO_TUNER_PAL;
+			if (std2.id & V4L2_STD_NTSC)
+				tun->flags |= VIDEO_TUNER_NTSC;
+			if (std2.id & V4L2_STD_SECAM)
+				tun->flags |= VIDEO_TUNER_SECAM;
+		}
+
 		err = drv(inode, file, VIDIOC_G_STD, &sid);
 		if (err < 0)
 			dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n",err);
@@ -691,8 +703,6 @@
 #if 0 /* FIXME */
 	case VIDIOCSTUNER: /*  select a tuner input  */
 	{
-		int	i;
-
 		err = drv(inode, file, VIDIOC_S_INPUT, &i);
 		if (err < 0)
 			dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err);
@@ -702,7 +712,6 @@
 	case VIDIOCGFREQ: /*  get frequency  */
 	{
 		int *freq = arg;
-		struct v4l2_frequency freq2;
 		
 		err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
 		if (err < 0)
@@ -714,7 +723,6 @@
 	case VIDIOCSFREQ: /*  set frequency  */
 	{
 		int *freq = arg;
-		struct v4l2_frequency freq2;
 
 		drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
 		freq2.frequency = *freq;
@@ -726,10 +734,6 @@
 	case VIDIOCGAUDIO: /*  get audio properties/controls  */
 	{
 		struct video_audio	*aud = arg;
-		struct v4l2_audio	aud2;
-		struct v4l2_queryctrl	qctrl2;
-		struct v4l2_tuner	tun2;
-		int			v;
 
 		err = drv(inode, file, VIDIOC_G_AUDIO, &aud2);
 		if (err < 0) {
@@ -741,34 +745,29 @@
 		aud->name[sizeof(aud->name) - 1] = 0;
 		aud->audio = aud2.index;
 		aud->flags = 0;
-		v = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv);
-		if (v >= 0)
-		{
-			aud->volume = v;
+		i = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv);
+		if (i >= 0) {
+			aud->volume = i;
 			aud->flags |= VIDEO_AUDIO_VOLUME;
 		}
-		v = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv);
-		if (v >= 0)
-		{
-			aud->bass = v;
+		i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv);
+		if (i >= 0) {
+			aud->bass = i;
 			aud->flags |= VIDEO_AUDIO_BASS;
 		}
-		v = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv);
-		if (v >= 0)
-		{
-			aud->treble = v;
+		i = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv);
+		if (i >= 0) {
+			aud->treble = i;
 			aud->flags |= VIDEO_AUDIO_TREBLE;
 		}
-		v = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv);
-		if (v >= 0)
-		{
-			aud->balance = v;
+		i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv);
+		if (i >= 0) {
+			aud->balance = i;
 			aud->flags |= VIDEO_AUDIO_BALANCE;
 		}
-		v = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv);
-		if (v >= 0)
-		{
-			if (v)
+		i = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv);
+		if (i >= 0) {
+			if (i)
 				aud->flags |= VIDEO_AUDIO_MUTE;
 			aud->flags |= VIDEO_AUDIO_MUTABLE;
 		}
@@ -795,8 +794,6 @@
 	case VIDIOCSAUDIO: /*  set audio controls  */
 	{
 		struct video_audio	*aud = arg;
-		struct v4l2_audio	aud2;
-		struct v4l2_tuner	tun2;
 
 		memset(&aud2,0,sizeof(aud2));
 		memset(&tun2,0,sizeof(tun2));
@@ -844,83 +841,36 @@
 		break;
 	}
 #if 0
-	case VIDIOCGMBUF: /*  get mmap parameters  */
-	{
-		struct video_mbuf		*mbuf = arg;
-		struct v4l2_requestbuffers	reqbuf2;
-		struct v4l2_buffer		buf2;
-		struct v4l2_format		fmt2, fmt2o;
-		struct v4l2_capability		cap2;
-		int				i;
-
-		/*  Set the format to maximum dimensions  */
-		if ((err = drv(inode, file, VIDIOC_QUERYCAP, &cap2)) < 0)
-			break;
-		fmt2o.type = V4L2_BUF_TYPE_CAPTURE;
-		if ((err = drv(inode, file, VIDIOC_G_FMT, &fmt2o)) < 0)
-			break;
-		fmt2 = fmt2o;
-		fmt2.fmt.pix.width = cap2.maxwidth;
-		fmt2.fmt.pix.height = cap2.maxheight;
-		fmt2.fmt.pix.flags |= V4L2_FMT_FLAG_INTERLACED;
-		if ((err = drv(inode, file, VIDIOC_S_FMT, &fmt2)) < 0)
-			break;
-		reqbuf2.count = 2; /* v4l always used two buffers */
-		reqbuf2.type = V4L2_BUF_TYPE_CAPTURE | V4L2_BUF_REQ_CONTIG;
-		err = drv(inode, file, VIDIOC_REQBUFS, &reqbuf2);
-		if (err < 0 || reqbuf2.count < 2 || reqbuf2.type
-		    != (V4L2_BUF_TYPE_CAPTURE | V4L2_BUF_REQ_CONTIG))
-		{/*	Driver doesn't support v4l back-compatibility  */
-			fmt2o.fmt.pix.flags |= V4L2_FMT_FLAG_INTERLACED;
-			drv(inode, file, VIDIOC_S_FMT, &fmt2o);
-			reqbuf2.count = 1;
-			reqbuf2.type = V4L2_BUF_TYPE_CAPTURE;
-			err = drv(inode, file, VIDIOC_REQBUFS, &reqbuf2);
-			if (err < 0)
-			{
-				err = -EINVAL;
-				break;
-			}
-			printk(KERN_INFO"V4L2: Device \"%s\" doesn't support"
-			       " v4l memory mapping\n", vfl->name);
-		}
-		buf2.index = 0;
-		buf2.type = V4L2_BUF_TYPE_CAPTURE;
-		err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
-		mbuf->size = buf2.length * reqbuf2.count;
-		mbuf->frames = reqbuf2.count;
-		memset(mbuf->offsets, 0, sizeof(mbuf->offsets));
-		for (i = 0; i < mbuf->frames; ++i)
-			mbuf->offsets[i] = i * buf2.length;
-		break;
-	}
+	case VIDIOCGMBUF:
+		/* v4l2 drivers must implement that themself.  The
+		   mmap() differences can't be translated fully
+		   transparent, thus there is no point to try that */
 #endif
 	case VIDIOCMCAPTURE: /*  capture a frame  */
 	{
 		struct video_mmap	*mm = arg;
-		struct v4l2_buffer	buf2;
-		struct v4l2_format	fmt2;
 
+		fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
 		memset(&buf2,0,sizeof(buf2));
-		memset(&fmt2,0,sizeof(fmt2));
+		memset(fmt2,0,sizeof(*fmt2));
 		
-		fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		err = drv(inode, file, VIDIOC_G_FMT, &fmt2);
+		fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		err = drv(inode, file, VIDIOC_G_FMT, fmt2);
 		if (err < 0) {
 			dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n",err);
 			break;
 		}
-		if (mm->width   != fmt2.fmt.pix.width || 
-		    mm->height != fmt2.fmt.pix.height ||
+		if (mm->width   != fmt2->fmt.pix.width  || 
+		    mm->height  != fmt2->fmt.pix.height ||
 		    palette_to_pixelformat(mm->format) != 
-		    fmt2.fmt.pix.pixelformat)
+		    fmt2->fmt.pix.pixelformat)
 		{/* New capture format...  */
-			fmt2.fmt.pix.width = mm->width;
-			fmt2.fmt.pix.height = mm->height;
-			fmt2.fmt.pix.pixelformat =
+			fmt2->fmt.pix.width = mm->width;
+			fmt2->fmt.pix.height = mm->height;
+			fmt2->fmt.pix.pixelformat =
 				palette_to_pixelformat(mm->format);
-			fmt2.fmt.pix.field = V4L2_FIELD_ANY;
-			err = drv(inode, file, VIDIOC_S_FMT, &fmt2);
+			fmt2->fmt.pix.field = V4L2_FIELD_ANY;
+			err = drv(inode, file, VIDIOC_S_FMT, fmt2);
 			if (err < 0) {
 				dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n",err);
 				break;
@@ -946,7 +896,6 @@
 	case VIDIOCSYNC: /*  wait for a frame  */
 	{
 		int			*i = arg;
-		struct v4l2_buffer	buf2;
 
 		buf2.index = *i;
 		buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -967,7 +916,7 @@
 			(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
 		       == V4L2_BUF_FLAG_QUEUED)
 		{
-			err = simple_select(file);
+			err = poll_one(file);
 			if (err < 0 ||	/* error or sleep was interrupted  */
 			    err == 0)	/* timeout? Shouldn't occur.  */
 				break;
@@ -984,20 +933,43 @@
 		} while (err == 0 && buf2.index != *i);
 		break;
 	}
-	case VIDIOCGUNIT: /*  get related device minors  */
-		/*  No translation  */
-		break;
-	case VIDIOCGCAPTURE: /*    */
-		/*  No translation, yet...  */
-		printk(KERN_INFO"v4l1-compat: VIDIOCGCAPTURE not implemented."
-		       " Send patches to bdirks@pacbell.net :-)\n");
-		break;
-	case VIDIOCSCAPTURE: /*    */
-		/*  No translation, yet...  */
-		printk(KERN_INFO"v4l1-compat: VIDIOCSCAPTURE not implemented."
-		       " Send patches to bdirks@pacbell.net :-)\n");
+
+	case VIDIOCGVBIFMT: /* query VBI data capture format */
+	{
+		struct vbi_format      *fmt = arg;
+		
+		fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
+		memset(fmt2, 0, sizeof(*fmt2));
+		fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
+		
+		err = drv(inode, file, VIDIOC_G_FMT, fmt2);
+		if (err < 0) {
+			dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n", err);
+			break;
+		}
+		memset(fmt, 0, sizeof(*fmt));
+		fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
+		fmt->sampling_rate    = fmt2->fmt.vbi.sampling_rate;
+		fmt->sample_format    = VIDEO_PALETTE_RAW;
+		fmt->start[0]         = fmt2->fmt.vbi.start[0];
+		fmt->count[0]         = fmt2->fmt.vbi.count[0];
+		fmt->start[1]         = fmt2->fmt.vbi.start[1];
+		fmt->count[1]         = fmt2->fmt.vbi.count[1];
+		if (fmt2->fmt.vbi.flags & VBI_UNSYNC)
+			fmt->flags   |= V4L2_VBI_UNSYNC;
+		if (fmt2->fmt.vbi.flags & VBI_INTERLACED)
+			fmt->flags   |= V4L2_VBI_INTERLACED;
+                break;
+	}
+	default:
+		err = -ENOIOCTLCMD;
 		break;
 	}
+
+	if (cap2)
+		kfree(cap2);
+	if (fmt2)
+		kfree(fmt2);
 	return err;
 }
 

-- 
Michael Moore for president!

                 reply	other threads:[~2003-04-02 16:20 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030402163915.GA24748@bytesex.org \
    --to=kraxel@bytesex.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.