Deleted Added
full compact
32c32
< __FBSDID("$FreeBSD: head/sys/compat/linux/linux_ioctl.c 197176 2009-09-13 21:30:18Z zec $");
---
> __FBSDID("$FreeBSD: head/sys/compat/linux/linux_ioctl.c 200110 2009-12-04 21:06:54Z netchild $");
80a81,83
> #include <compat/linux/linux_videodev.h>
> #include <compat/linux/linux_videodev_compat.h>
>
93a97
> static linux_ioctl_function_t linux_ioctl_v4l;
117a122,123
> static struct linux_ioctl_handler video_handler =
> { linux_ioctl_v4l, LINUX_IOCTL_VIDEO_MIN, LINUX_IOCTL_VIDEO_MAX };
129a136
> DATA_SET(linux_ioctl_handler_set, video_handler);
2591a2599,2887
> * Video4Linux (V4L) ioctl handler
> */
> static int
> linux_to_bsd_v4l_tuner(struct l_video_tuner *lvt, struct video_tuner *vt)
> {
> vt->tuner = lvt->tuner;
> strlcpy(vt->name, lvt->name, LINUX_VIDEO_TUNER_NAME_SIZE);
> vt->rangelow = lvt->rangelow; /* possible long size conversion */
> vt->rangehigh = lvt->rangehigh; /* possible long size conversion */
> vt->flags = lvt->flags;
> vt->mode = lvt->mode;
> vt->signal = lvt->signal;
> return (0);
> }
>
> static int
> bsd_to_linux_v4l_tuner(struct video_tuner *vt, struct l_video_tuner *lvt)
> {
> lvt->tuner = vt->tuner;
> strlcpy(lvt->name, vt->name, LINUX_VIDEO_TUNER_NAME_SIZE);
> lvt->rangelow = vt->rangelow; /* possible long size conversion */
> lvt->rangehigh = vt->rangehigh; /* possible long size conversion */
> lvt->flags = vt->flags;
> lvt->mode = vt->mode;
> lvt->signal = vt->signal;
> return (0);
> }
>
> #if 0
> static int
> linux_to_bsd_v4l_clip(struct l_video_clip *lvc, struct video_clip *vc)
> {
> vc->x = lvc->x;
> vc->y = lvc->y;
> vc->width = lvc->width;
> vc->height = lvc->height;
> vc->next = PTRIN(lvc->next); /* possible pointer size conversion */
> return (0);
> }
> #endif
>
> static int
> linux_to_bsd_v4l_window(struct l_video_window *lvw, struct video_window *vw)
> {
> vw->x = lvw->x;
> vw->y = lvw->y;
> vw->width = lvw->width;
> vw->height = lvw->height;
> vw->chromakey = lvw->chromakey;
> vw->flags = lvw->flags;
> vw->clips = PTRIN(lvw->clips); /* possible pointer size conversion */
> vw->clipcount = lvw->clipcount;
> return (0);
> }
>
> static int
> bsd_to_linux_v4l_window(struct video_window *vw, struct l_video_window *lvw)
> {
> lvw->x = vw->x;
> lvw->y = vw->y;
> lvw->width = vw->width;
> lvw->height = vw->height;
> lvw->chromakey = vw->chromakey;
> lvw->flags = vw->flags;
> lvw->clips = PTROUT(vw->clips); /* possible pointer size conversion */
> lvw->clipcount = vw->clipcount;
> return (0);
> }
>
> static int
> linux_to_bsd_v4l_buffer(struct l_video_buffer *lvb, struct video_buffer *vb)
> {
> vb->base = PTRIN(lvb->base); /* possible pointer size conversion */
> vb->height = lvb->height;
> vb->width = lvb->width;
> vb->depth = lvb->depth;
> vb->bytesperline = lvb->bytesperline;
> return (0);
> }
>
> static int
> bsd_to_linux_v4l_buffer(struct video_buffer *vb, struct l_video_buffer *lvb)
> {
> lvb->base = PTROUT(vb->base); /* possible pointer size conversion */
> lvb->height = vb->height;
> lvb->width = vb->width;
> lvb->depth = vb->depth;
> lvb->bytesperline = vb->bytesperline;
> return (0);
> }
>
> static int
> linux_to_bsd_v4l_code(struct l_video_code *lvc, struct video_code *vc)
> {
> strlcpy(vc->loadwhat, lvc->loadwhat, LINUX_VIDEO_CODE_LOADWHAT_SIZE);
> vc->datasize = lvc->datasize;
> vc->data = PTRIN(lvc->data); /* possible pointer size conversion */
> return (0);
> }
>
> #if 0
> static int
> linux_v4l_cliplist_copy(struct l_video_window *lvw, struct video_window *vw)
> {
> struct video_clip vclip;
> struct l_video_clip l_vclip;
> struct video_clip **ppvc;
> struct l_video_clip *plvc;
> int error;
>
> ppvc = &(vw->clips);
> for (plvc = (struct l_video_clip *) PTRIN(lvw->clips);
> plvc != NULL;
> plvc = (struct l_video_clip *) PTRIN(plvc->next)) {
> error = copyin((void *) plvc, &l_vclip, sizeof(l_vclip));
> if (error) return (error);
> linux_to_bsd_v4l_clip(&l_vclip, &vclip);
> /* XXX: If there can be no concurrency: s/M_NOWAIT/M_WAITOK/ */
> if ((*ppvc = malloc(sizeof(**ppvc), M_LINUX, M_NOWAIT)) == NULL)
> return (ENOMEM); /* XXX: linux has no ENOMEM here */
> memcpy(&vclip, *ppvc, sizeof(vclip));
> ppvc = &((*ppvc)->next);
> }
> return (0);
> }
>
> static int
> linux_v4l_cliplist_free(struct video_window *vw)
> {
> struct video_clip **ppvc;
> struct video_clip **ppvc_next;
>
> for (ppvc = &(vw->clips); *ppvc != NULL; ppvc = ppvc_next) {
> ppvc_next = &((*ppvc)->next);
> free(*ppvc, M_LINUX);
> }
> return (0);
> }
> #endif
>
> static int
> linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args)
> {
> struct file *fp;
> int error;
> struct video_tuner vtun;
> struct video_window vwin;
> struct video_buffer vbuf;
> struct video_code vcode;
> struct l_video_tuner l_vtun;
> struct l_video_window l_vwin;
> struct l_video_buffer l_vbuf;
> struct l_video_code l_vcode;
>
> switch (args->cmd & 0xffff) {
> case LINUX_VIDIOCGCAP: args->cmd = VIDIOCGCAP; break;
> case LINUX_VIDIOCGCHAN: args->cmd = VIDIOCGCHAN; break;
> case LINUX_VIDIOCSCHAN: args->cmd = VIDIOCSCHAN; break;
>
> case LINUX_VIDIOCGTUNER:
> if ((error = fget(td, args->fd, &fp)) != 0)
> return (error);
> error = fo_ioctl(fp, VIDIOCGTUNER, &vtun, td->td_ucred, td);
> if (!error) {
> bsd_to_linux_v4l_tuner(&vtun, &l_vtun);
> error = copyout(&l_vtun, (void *) args->arg,
> sizeof(l_vtun));
> }
> fdrop(fp, td);
> return (error);
>
> case LINUX_VIDIOCSTUNER:
> if ((error = fget(td, args->fd, &fp)) != 0)
> return (error);
> error = copyin((void *) args->arg, &l_vtun, sizeof(l_vtun));
> if (error) {
> fdrop(fp, td);
> return (error);
> }
> linux_to_bsd_v4l_tuner(&l_vtun, &vtun);
> error = fo_ioctl(fp, VIDIOCSMICROCODE, &vtun, td->td_ucred, td);
> fdrop(fp, td);
> return (error);
>
> case LINUX_VIDIOCGPICT: args->cmd = VIDIOCGPICT; break;
> case LINUX_VIDIOCSPICT: args->cmd = VIDIOCSPICT; break;
> case LINUX_VIDIOCCAPTURE: args->cmd = VIDIOCCAPTURE; break;
>
> case LINUX_VIDIOCGWIN:
> if ((error = fget(td, args->fd, &fp)) != 0)
> return (error);
> error = fo_ioctl(fp, VIDIOCGWIN, &vwin, td->td_ucred, td);
> if (!error) {
> bsd_to_linux_v4l_window(&vwin, &l_vwin);
> error = copyout(&l_vwin, (void *) args->arg,
> sizeof(l_vwin));
> }
> fdrop(fp, td);
> return (error);
>
> case LINUX_VIDIOCSWIN:
> if ((error = fget(td, args->fd, &fp)) != 0)
> return (error);
> error = copyin((void *) args->arg, &l_vwin, sizeof(l_vwin));
> if (error) {
> fdrop(fp, td);
> return (error);
> }
> linux_to_bsd_v4l_window(&l_vwin, &vwin);
> #if 0
> /*
> * XXX: some Linux apps call SWIN but do not store valid
> * values in clipcount or in the clips pointer. Until
> * we have someone calling to support this, the code
> * to handle the list of video_clip structures is removed.
> */
> error = linux_v4l_cliplist_copy(&l_vwin, &vwin);
> #endif
> if (!error)
> error = fo_ioctl(fp, VIDIOCSWIN, &vwin, td->td_ucred, td);
> fdrop(fp, td);
> #if 0
> linux_v4l_cliplist_free(&vwin);
> #endif
> return (error);
>
> case LINUX_VIDIOCGFBUF:
> if ((error = fget(td, args->fd, &fp)) != 0)
> return (error);
> error = fo_ioctl(fp, VIDIOCGFBUF, &vbuf, td->td_ucred, td);
> if (!error) {
> bsd_to_linux_v4l_buffer(&vbuf, &l_vbuf);
> error = copyout(&l_vbuf, (void *) args->arg,
> sizeof(l_vbuf));
> }
> fdrop(fp, td);
> return (error);
>
> case LINUX_VIDIOCSFBUF:
> if ((error = fget(td, args->fd, &fp)) != 0)
> return (error);
> error = copyin((void *) args->arg, &l_vbuf, sizeof(l_vbuf));
> if (error) {
> fdrop(fp, td);
> return (error);
> }
> linux_to_bsd_v4l_buffer(&l_vbuf, &vbuf);
> error = fo_ioctl(fp, VIDIOCSFBUF, &vbuf, td->td_ucred, td);
> fdrop(fp, td);
> return (error);
>
> case LINUX_VIDIOCKEY: args->cmd = VIDIOCKEY; break;
> case LINUX_VIDIOCGFREQ: args->cmd = VIDIOCGFREQ; break;
> case LINUX_VIDIOCSFREQ: args->cmd = VIDIOCSFREQ; break;
> case LINUX_VIDIOCGAUDIO: args->cmd = VIDIOCGAUDIO; break;
> case LINUX_VIDIOCSAUDIO: args->cmd = VIDIOCSAUDIO; break;
> case LINUX_VIDIOCSYNC: args->cmd = VIDIOCSYNC; break;
> case LINUX_VIDIOCMCAPTURE: args->cmd = VIDIOCMCAPTURE; break;
> case LINUX_VIDIOCGMBUF: args->cmd = VIDIOCGMBUF; break;
> case LINUX_VIDIOCGUNIT: args->cmd = VIDIOCGUNIT; break;
> case LINUX_VIDIOCGCAPTURE: args->cmd = VIDIOCGCAPTURE; break;
> case LINUX_VIDIOCSCAPTURE: args->cmd = VIDIOCSCAPTURE; break;
> case LINUX_VIDIOCSPLAYMODE: args->cmd = VIDIOCSPLAYMODE; break;
> case LINUX_VIDIOCSWRITEMODE: args->cmd = VIDIOCSWRITEMODE; break;
> case LINUX_VIDIOCGPLAYINFO: args->cmd = VIDIOCGPLAYINFO; break;
>
> case LINUX_VIDIOCSMICROCODE:
> if ((error = fget(td, args->fd, &fp)) != 0)
> return (error);
> error = copyin((void *) args->arg, &l_vcode, sizeof(l_vcode));
> if (error) {
> fdrop(fp, td);
> return (error);
> }
> linux_to_bsd_v4l_code(&l_vcode, &vcode);
> error = fo_ioctl(fp, VIDIOCSTUNER, &vcode, td->td_ucred, td);
> fdrop(fp, td);
> return (error);
>
> case LINUX_VIDIOCGVBIFMT: args->cmd = VIDIOCGVBIFMT; break;
> case LINUX_VIDIOCSVBIFMT: args->cmd = VIDIOCSVBIFMT; break;
> default: return (ENOIOCTL);
> }
>
> error = ioctl(td, (struct ioctl_args *)args);
> return (error);
> }
>
> /*