Module Name:    src
Committed By:   christos
Date:           Tue Aug 18 02:17:09 UTC 2009

Modified Files:
        src/sys/dev: video.c
        src/sys/sys: videoio.h

Log Message:
1. some of the video24linux structs are not as machine independent as their
   authors want them to be. For the buffer ioctls, define new ioctls with
   the 32 bit buffer sizes. For the format struct, define it as packed
   so it is the same on 32 and 64 bit. (I might need to version this)
2. the mmapped buffers need to be page aligned, otherwise mmap(2) does
   not work. Make it so.
All this makes my ricoh camera work with emul-linux and skype running on
amd64. Next is sound!


To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/sys/dev/video.c
cvs rdiff -u -r1.5 -r1.6 src/sys/sys/videoio.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/video.c
diff -u src/sys/dev/video.c:1.21 src/sys/dev/video.c:1.22
--- src/sys/dev/video.c:1.21	Tue Jul  7 17:55:17 2009
+++ src/sys/dev/video.c	Mon Aug 17 22:17:09 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: video.c,v 1.21 2009/07/07 21:55:17 njoly Exp $ */
+/* $NetBSD: video.c,v 1.22 2009/08/18 02:17:09 christos Exp $ */
 
 /*
  * Copyright (c) 2008 Patrick Mahoney <p...@polycrystal.org>
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: video.c,v 1.21 2009/07/07 21:55:17 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: video.c,v 1.22 2009/08/18 02:17:09 christos Exp $");
 
 #include "video.h"
 #if NVIDEO > 0
@@ -69,6 +69,8 @@
 #define DPRINTFN(n,x)
 #endif
 
+#define PAGE_ALIGN(a)		(((a) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
+
 #define VIDEO_DRIVER_VERSION 1
 
 /* TODO: move to sys/intr.h */
@@ -1237,6 +1239,50 @@
 }
 
 
+static void
+buf32tobuf(const void *data, struct v4l2_buffer *buf)
+{
+	const struct v4l2_buffer32 *b32 = data;
+
+	buf->index = b32->index;
+	buf->type = b32->type;
+	buf->bytesused = b32->bytesused;
+	buf->flags = b32->flags;
+	buf->field = b32->field;
+	buf->timestamp.tv_sec = b32->timestamp.tv_sec;
+	buf->timestamp.tv_usec = b32->timestamp.tv_usec;
+	buf->timecode = b32->timecode;
+	buf->sequence = b32->sequence;
+	buf->memory = b32->memory;
+	buf->m.offset = b32->m.offset;
+	/* XXX: Handle userptr */
+	buf->length = b32->length;
+	buf->input = b32->input;
+	buf->reserved = b32->reserved;
+}
+
+static void
+buftobuf32(void *data, const struct v4l2_buffer *buf)
+{
+	struct v4l2_buffer32 *b32 = data;
+
+	b32->index = buf->index;
+	b32->type = buf->type;
+	b32->bytesused = buf->bytesused;
+	b32->flags = buf->flags;
+	b32->field = buf->field;
+	b32->timestamp.tv_sec = (uint32_t)buf->timestamp.tv_sec;
+	b32->timestamp.tv_usec = buf->timestamp.tv_usec;
+	b32->timecode = buf->timecode;
+	b32->sequence = buf->sequence;
+	b32->memory = buf->memory;
+	b32->m.offset = buf->m.offset;
+	/* XXX: Handle userptr */
+	b32->length = buf->length;
+	b32->input = buf->input;
+	b32->reserved = buf->reserved;
+}
+
 int
 videoioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
 {
@@ -1250,10 +1296,10 @@
 	struct v4l2_control *control;
 	struct v4l2_queryctrl *query;
 	struct v4l2_requestbuffers *reqbufs;
-	struct v4l2_buffer *buf;
+	struct v4l2_buffer *buf, bufspace;
 	v4l2_std_id *stdid;
 	enum v4l2_buf_type *typep;
-	int *ip;
+	int *ip, error;
 
 	sc = device_private(device_lookup(&video_cd, VIDEOUNIT(dev)));
 
@@ -1354,14 +1400,27 @@
 	case VIDIOC_QUERYBUF:
 		buf = data;
 		return video_query_buf(sc, buf);
+	case VIDIOC_QUERYBUF32:
+		buf32tobuf(data, buf = &bufspace);
+		if ((error = video_query_buf(sc, buf)) != 0)
+			return error;
+		buftobuf32(data, buf);
+		return 0;
 	case VIDIOC_QBUF:
 		buf = data;
 		return video_queue_buf(sc, buf);
-		break;
+	case VIDIOC_QBUF32:
+		buf32tobuf(data, buf = &bufspace);
+		return video_queue_buf(sc, buf);
 	case VIDIOC_DQBUF:
 		buf = data;
 		return video_dequeue_buf(sc, buf);
-		break;
+	case VIDIOC_DQBUF32:
+		buf32tobuf(data, buf = &bufspace);
+		if ((error = video_dequeue_buf(sc, buf)) != 0)
+			return error;
+		buftobuf32(data, buf);
+		return 0;
 	case VIDIOC_STREAMON:
 		typep = data;
 		return video_stream_on(sc, *typep);
@@ -1404,6 +1463,9 @@
 	case VIDIOC_QUERYBUF:
 		str = "VIDIOC_QUERYBUF";
 		break;
+	case VIDIOC_QUERYBUF32:
+		str = "VIDIOC_QUERYBUF32";
+		break;
 	case VIDIOC_G_FBUF:
 		str = "VIDIOC_G_FBUF";
 		break;
@@ -1416,9 +1478,15 @@
 	case VIDIOC_QBUF:
 		str = "VIDIOC_QBUF";
 		break;
+	case VIDIOC_QBUF32:
+		str = "VIDIOC_QBUF32";
+		break;
 	case VIDIOC_DQBUF:
 		str = "VIDIOC_DQBUF";
 		break;
+	case VIDIOC_DQBUF32:
+		str = "VIDIOC_DQBUF32";
+		break;
 	case VIDIOC_STREAMON:
 		str = "VIDIOC_STREAMON";
 		break;
@@ -1758,7 +1826,7 @@
 	struct video_buffer **oldbuf;
 	struct v4l2_buffer *buf;
 
-	size = vs->vs_format.sample_size * nbufs;
+	size = PAGE_ALIGN(vs->vs_format.sample_size) * nbufs;
 	err = scatter_buf_set_size(&vs->vs_data, size);
 	if (err != 0)
 		return err;
@@ -1809,7 +1877,7 @@
 		buf->sequence = 0;
 		buf->memory = V4L2_MEMORY_MMAP;
 		buf->m.offset = offset;
-		buf->length = vs->vs_format.sample_size;
+		buf->length = PAGE_ALIGN(vs->vs_format.sample_size);
 		buf->input = 0;
 		buf->reserved = 0;
 

Index: src/sys/sys/videoio.h
diff -u src/sys/sys/videoio.h:1.5 src/sys/sys/videoio.h:1.6
--- src/sys/sys/videoio.h:1.5	Sat Jun 13 06:05:55 2009
+++ src/sys/sys/videoio.h	Mon Aug 17 22:17:09 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: videoio.h,v 1.5 2009/06/13 10:05:55 njoly Exp $ */
+/* $NetBSD: videoio.h,v 1.6 2009/08/18 02:17:09 christos Exp $ */
 
 /*-
  * Copyright (c) 2005, 2008 Jared D. McNeill <jmcne...@invisible.ca>
@@ -153,6 +153,28 @@
 	uint32_t	reserved;
 };
 
+struct v4l2_buffer32 {
+	uint32_t	index;
+	enum v4l2_buf_type type;
+	uint32_t	bytesused;
+	uint32_t	flags;
+	enum v4l2_field	field;
+	struct {
+		uint32_t tv_sec;
+		uint32_t tv_usec;
+	} timestamp;
+	struct v4l2_timecode timecode;
+	uint32_t	sequence;
+	enum v4l2_memory memory;
+	union {
+		uint32_t offset;
+		uint32_t userptr;
+	} m;
+	uint32_t	length;
+	uint32_t	input;
+	uint32_t	reserved;
+};
+
 struct v4l2_rect {
 	int32_t		left;
 	int32_t		top;
@@ -301,7 +323,7 @@
 		struct v4l2_vbi_format vbi;
 		uint8_t		raw_data[200];
 	} fmt;
-};
+} __attribute__((__packed__));
 
 struct v4l2_frequency {
 	uint32_t	tuner;
@@ -673,11 +695,14 @@
 /* 6 and 7 are VIDIOC_[SG]_COMP, which are unsupported */
 #define VIDIOC_REQBUFS		_IOWR('V', 8, struct v4l2_requestbuffers)
 #define VIDIOC_QUERYBUF		_IOWR('V', 9, struct v4l2_buffer)
+#define VIDIOC_QUERYBUF32	_IOWR('V', 9, struct v4l2_buffer32)
 #define VIDIOC_G_FBUF		_IOR('V', 10, struct v4l2_framebuffer)
 #define VIDIOC_S_FBUF		_IOW('V', 11, struct v4l2_framebuffer)
 #define VIDIOC_OVERLAY		_IOW('V', 14, int)
 #define VIDIOC_QBUF		_IOWR('V', 15, struct v4l2_buffer)
+#define VIDIOC_QBUF32		_IOWR('V', 15, struct v4l2_buffer32)
 #define VIDIOC_DQBUF		_IOWR('V', 17, struct v4l2_buffer)
+#define VIDIOC_DQBUF32		_IOWR('V', 17, struct v4l2_buffer32)
 #define VIDIOC_STREAMON		_IOW('V', 18, int)
 #define VIDIOC_STREAMOFF	_IOW('V', 19, int)
 #define VIDIOC_G_PARM		_IOWR('V', 21, struct v4l2_streamparm)

Reply via email to