From owner-svn-src-head@FreeBSD.ORG Fri Jan 15 14:58:20 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4BCBB1065679; Fri, 15 Jan 2010 14:58:20 +0000 (UTC) (envelope-from netchild@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 390218FC22; Fri, 15 Jan 2010 14:58:20 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o0FEwKje005153; Fri, 15 Jan 2010 14:58:20 GMT (envelope-from netchild@svn.freebsd.org) Received: (from netchild@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0FEwKsO005151; Fri, 15 Jan 2010 14:58:20 GMT (envelope-from netchild@svn.freebsd.org) Message-Id: <201001151458.o0FEwKsO005151@svn.freebsd.org> From: Alexander Leidinger Date: Fri, 15 Jan 2010 14:58:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202364 - head/sys/compat/linux X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jan 2010 14:58:20 -0000 Author: netchild Date: Fri Jan 15 14:58:19 2010 New Revision: 202364 URL: http://svn.freebsd.org/changeset/base/202364 Log: This is v4l support for the linuxulator. This allows to access FreeBSD native devices which support the v4l API from processes running within the linuxulator, e.g. skype or flash can access the multimedia/pwcbsd driver. Not tested is firmware upload, framebuffer stuff and video tuner stuff due to lack of hardware. The clipping part (VIDIOCSWIN) needs a little bit of further work (partly in progress, but can not be tested due to lack of a suitable device). The submitter tested this sucessfully with Skype and flash apps on amd64 and i386 with the multimedia/pwcbsd driver. Submitted by: J.R. Oldroyd Modified: head/sys/compat/linux/linux_ioctl.c Modified: head/sys/compat/linux/linux_ioctl.c ============================================================================== --- head/sys/compat/linux/linux_ioctl.c Fri Jan 15 14:47:26 2010 (r202363) +++ head/sys/compat/linux/linux_ioctl.c Fri Jan 15 14:58:19 2010 (r202364) @@ -2624,7 +2624,6 @@ bsd_to_linux_v4l_tuner(struct video_tune return (0); } -#if 0 static int linux_to_bsd_v4l_clip(struct l_video_clip *lvc, struct video_clip *vc) { @@ -2635,7 +2634,6 @@ linux_to_bsd_v4l_clip(struct l_video_cli 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) @@ -2696,29 +2694,21 @@ linux_to_bsd_v4l_code(struct l_video_cod return (0); } -#if 0 static int -linux_v4l_cliplist_copy(struct l_video_window *lvw, struct video_window *vw) +linux_v4l_clip_copy(void *lvc, struct video_clip **ppvc) { + int error; 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); - } + error = copyin(lvc, &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)->next = NULL; return (0); } @@ -2734,7 +2724,71 @@ linux_v4l_cliplist_free(struct video_win } return (0); } -#endif + +static int +linux_v4l_cliplist_copy(struct l_video_window *lvw, struct video_window *vw) +{ + int error; + int clipcount; + void *plvc; + struct video_clip **ppvc; + + /* + * XXX: The cliplist is used to pass in a list of clipping + * rectangles or, if clipcount == VIDEO_CLIP_BITMAP, a + * clipping bitmap. Some Linux apps, however, appear to + * leave cliplist and clips uninitialized. In any case, + * the cliplist is not used by pwc(4), at the time of + * writing, FreeBSD's only V4L driver. When a driver + * that uses the cliplist is developed, this code may + * need re-examiniation. + */ + error = 0; + clipcount = vw->clipcount; + if (clipcount == VIDEO_CLIP_BITMAP) { + /* + * In this case, the pointer (clips) is overloaded + * to be a "void *" to a bitmap, therefore there + * is no struct video_clip to copy now. + */ + } else if (clipcount > 0 && clipcount <= 16384) { + /* + * Clips points to list of clip rectangles, so + * copy the list. + * + * XXX: Upper limit of 16384 was used here to try to + * avoid cases when clipcount and clips pointer + * are uninitialized and therefore have high random + * values, as is the case in the Linux Skype + * application. The value 16384 was chosen as that + * is what is used in the Linux stradis(4) MPEG + * decoder driver, the only place we found an + * example of cliplist use. + */ + plvc = PTRIN(lvw->clips); + ppvc = &(vw->clips); + while (clipcount-- > 0) { + if (plvc == 0) + error = EFAULT; + if (!error) + error = linux_v4l_clip_copy(plvc, ppvc); + if (error) { + linux_v4l_cliplist_free(vw); + break; + } + ppvc = &((*ppvc)->next); + plvc = PTRIN(((struct l_video_clip *) plvc)->next); + } + } else { + /* + * clipcount == 0 or negative (but not VIDEO_CLIP_BITMAP) + * Force cliplist to null. + */ + vw->clipcount = 0; + vw->clips = NULL; + } + return (error); +} static int linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) @@ -2805,21 +2859,14 @@ linux_ioctl_v4l(struct thread *td, struc 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); + if (error) { + fdrop(fp, td); + return (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: