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)