From owner-svn-src-stable@FreeBSD.ORG Thu May 19 07:39:27 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3BF39106566B; Thu, 19 May 2011 07:39:27 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 386298FC13; Thu, 19 May 2011 07:39:27 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p4J79DoM027138; Thu, 19 May 2011 07:09:13 GMT (envelope-from avg@svn.freebsd.org) Received: (from avg@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p4J79Df7027136; Thu, 19 May 2011 07:09:13 GMT (envelope-from avg@svn.freebsd.org) Message-Id: <201105190709.p4J79Df7027136@svn.freebsd.org> From: Andriy Gapon Date: Thu, 19 May 2011 07:09:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r222092 - stable/7/sys/dev/sound/pcm X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 May 2011 07:39:27 -0000 Author: avg Date: Thu May 19 07:09:13 2011 New Revision: 222092 URL: http://svn.freebsd.org/changeset/base/222092 Log: MFC r221803,221809: dsp/pcm: allow to mmap both read and write buffers Modified: stable/7/sys/dev/sound/pcm/dsp.c Directory Properties: stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/dev/sound/pcm/dsp.c ============================================================================== --- stable/7/sys/dev/sound/pcm/dsp.c Thu May 19 07:03:42 2011 (r222091) +++ stable/7/sys/dev/sound/pcm/dsp.c Thu May 19 07:09:13 2011 (r222092) @@ -27,6 +27,11 @@ #include #include +#include +#include +#include +#include + SND_DECLARE_FILE("$FreeBSD$"); static int dsp_mmap_allow_prot_exec = 0; @@ -57,6 +62,7 @@ static d_write_t dsp_write; static d_ioctl_t dsp_ioctl; static d_poll_t dsp_poll; static d_mmap_t dsp_mmap; +static d_mmap_single_t dsp_mmap_single; struct cdevsw dsp_cdevsw = { .d_version = D_VERSION, @@ -67,6 +73,7 @@ struct cdevsw dsp_cdevsw = { .d_ioctl = dsp_ioctl, .d_poll = dsp_poll, .d_mmap = dsp_mmap, + .d_mmap_single = dsp_mmap_single, .d_name = "dsp", }; @@ -1851,6 +1858,16 @@ dsp_poll(struct cdev *i_dev, int events, static int dsp_mmap(struct cdev *i_dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot) { + + /* XXX memattr is not honored */ + *paddr = vtophys(offset); + return (0); +} + +static int +dsp_mmap_single(struct cdev *i_dev, vm_ooffset_t *offset, + vm_size_t size, struct vm_object **object, int nprot) +{ struct snddev_info *d; struct pcm_channel *wrch, *rdch, *c; @@ -1863,51 +1880,48 @@ dsp_mmap(struct cdev *i_dev, vm_offset_t * */ if ((nprot & PROT_EXEC) && dsp_mmap_allow_prot_exec == 0) - return (-1); + return (EINVAL); + + /* + * PROT_READ (alone) selects the input buffer. + * PROT_WRITE (alone) selects the output buffer. + * PROT_WRITE|PROT_READ together select the output buffer. + */ + if ((nprot & (PROT_READ | PROT_WRITE)) == 0) + return (EINVAL); d = dsp_get_info(i_dev); if (!DSP_REGISTERED(d, i_dev)) - return (-1); + return (EINVAL); PCM_GIANT_ENTER(d); getchns(i_dev, &rdch, &wrch, SD_F_PRIO_RD | SD_F_PRIO_WR); - /* - * XXX The linux api uses the nprot to select read/write buffer - * our vm system doesn't allow this, so force write buffer. - * - * This is just a quack to fool full-duplex mmap, so that at - * least playback _or_ recording works. If you really got the - * urge to make _both_ work at the same time, avoid O_RDWR. - * Just open each direction separately and mmap() it. - * - * Failure is not an option due to INVARIANTS check within - * device_pager.c, which means, we have to give up one over - * another. - */ - c = (wrch != NULL) ? wrch : rdch; - + c = ((nprot & PROT_WRITE) != 0) ? wrch : rdch; if (c == NULL || (c->flags & CHN_F_MMAP_INVALID) || - offset >= sndbuf_getsize(c->bufsoft) || + (*offset + size) > sndbuf_getsize(c->bufsoft) || (wrch != NULL && (wrch->flags & CHN_F_MMAP_INVALID)) || (rdch != NULL && (rdch->flags & CHN_F_MMAP_INVALID))) { relchns(i_dev, rdch, wrch, SD_F_PRIO_RD | SD_F_PRIO_WR); PCM_GIANT_EXIT(d); - return (-1); + return (EINVAL); } - /* XXX full-duplex quack. */ if (wrch != NULL) wrch->flags |= CHN_F_MAPPED; if (rdch != NULL) rdch->flags |= CHN_F_MAPPED; - *paddr = vtophys(sndbuf_getbufofs(c->bufsoft, offset)); + *offset = (uintptr_t)sndbuf_getbufofs(c->bufsoft, *offset); relchns(i_dev, rdch, wrch, SD_F_PRIO_RD | SD_F_PRIO_WR); + *object = vm_pager_allocate(OBJT_DEVICE, i_dev, + size, nprot, *offset, curthread->td_ucred); PCM_GIANT_LEAVE(d); + if (*object == NULL) + return (EINVAL); return (0); }