NetBSD Problem Report #6827

Received: (qmail 16878 invoked from network); 17 Jan 1999 12:48:21 -0000
Message-Id: <199901171248.OAA11729@guava.araneus.fi>
Date: Sun, 17 Jan 1999 14:48:09 +0200 (EET)
From: gson@araneus.fi (Andreas Gustafsson)
Reply-To: gson@araneus.fi (Andreas Gustafsson)
To: gnats-bugs@gnats.netbsd.org
Subject: /dev/audio does not support mmap for recording
X-Send-Pr-Version: 3.95

>Number:         6827
>Category:       kern
>Synopsis:       /dev/audio does not support mmap for recording
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Jan 17 04:50:00 +0000 1999
>Closed-Date:    
>Last-Modified:  Mon Feb 28 14:56:41 +0000 2011
>Originator:     Andreas Gustafsson
>Release:        current-19990115
>Organization:
Araneus Information Systems Oy
>Environment:

System: NetBSD gulag.araneus.fi 1.3H NetBSD 1.3H (GULAG) #0: Sun Nov 1 09:31:05 EET 1998 gson@gulag.araneus.fi:/usr/src/sys/arch/i386/compile/GULAG i386


>Description:

The audio(4) man page claims you can mmap /dev/audio for recording as
well as playback, but in fact the driver only supports the playback
case.

>How-To-Repeat:

Try to mmap /dev/audio for recording.

>Fix:

Apply the following patch.  It changes the semantics of mmap():ing the
audio device such that instead of mapping either the playback or the
recording buffer (and running into deep VM-related trouble trying to
find out which one the user wanted), it simply always maps both of
them, one after the other.  Because the playback buffer is still
mapped at the beginning of the mmap area, existing code using mmap for
playback will continue to work as before.

This patch does amount to an incompatible API change for the recording
case, but since said interface has never worked, that is not likely to
break existing software either.

*** src/sys/dev/audio.c.orig	Thu Jan 14 14:43:47 1999
--- src/sys/dev/audio.c	Thu Jan 14 14:47:51 1999
***************
*** 1595,1626 ****

  	if (!(hw->get_props(sc->hw_hdl) & AUDIO_PROP_MMAP) || !hw->mappage)
  		return -1;
- #if 0
- /* XXX
-  * The idea here was to use the protection to determine if
-  * we are mapping the read or write buffer, but it fails.
-  * The VM system is broken in (at least) two ways.
-  * 1) If you map memory VM_PROT_WRITE you SIGSEGV
-  *    when writing to it, so VM_PROT_READ|VM_PROT_WRITE
-  *    has to be used for mmapping the play buffer.
-  * 2) Even if calling mmap() with VM_PROT_READ|VM_PROT_WRITE
-  *    audio_mmap will get called at some point with VM_PROT_READ
-  *    only.
-  * So, alas, we always map the play buffer for now.
-  */
- 	if (prot == (VM_PROT_READ|VM_PROT_WRITE) ||
- 	    prot == VM_PROT_WRITE)
- 		cb = &sc->sc_pr;
- 	else if (prot == VM_PROT_READ)
- 		cb = &sc->sc_rr;
- 	else
- 		return -1;
- #else
- 	cb = &sc->sc_pr;
- #endif

! 	if ((u_int)off >= cb->bufsize)
! 		return -1;
  	if (!cb->mmapped) {
  		cb->mmapped = 1;
  		if (cb == &sc->sc_pr) {
--- 1595,1612 ----

  	if (!(hw->get_props(sc->hw_hdl) & AUDIO_PROP_MMAP) || !hw->mappage)
  		return -1;

! 	/* Map the play buffer followed by the record buffer. */
! 
!         if ((u_int)off < sc->sc_pr.bufsize) {
!         	cb = &sc->sc_pr;
!         } else if ((u_int) off < sc->sc_pr.bufsize + sc->sc_rr.bufsize) {
!         	cb = &sc->sc_rr;
!         	off -= sc->sc_pr.bufsize;
!         } else {
!         	return -1;
!         }
! 
  	if (!cb->mmapped) {
  		cb->mmapped = 1;
  		if (cb == &sc->sc_pr) {
*** src/share/man/man4/audio.4.orig	Wed Dec  9 14:13:41 1998
--- src/share/man/man4/audio.4	Thu Jan 14 14:05:47 1999
***************
*** 142,160 ****
  by read or write; all access is by reading and writing to
  the mapped memory.
  The device appears as a block of memory
! of size
  .Va buffersize
  (as available via
  .Dv AUDIO_GETINFO ).
  The device driver will continuously move data from this buffer
  from/to the audio hardware, wrapping around at the end of the buffer.
  To find out where the hardware is currently accessing data in the buffer the
  .Dv AUDIO_GETIOFFS
  and
  .Dv AUDIO_GETOOFFS
! calls can be used.
! The playing and recording buffers are distinct and must be
! mapped separately if both are to be used.
  Only encodings that are not emulated (i.e. where
  .Dv AUDIO_ENCODINGFLAG_EMULATED
  is not set) work properly for a mapped device.
--- 142,163 ----
  by read or write; all access is by reading and writing to
  the mapped memory.
  The device appears as a block of memory
! of size two times
  .Va buffersize
  (as available via
  .Dv AUDIO_GETINFO ).
+ The first half of this block is the playback buffer; the second half
+ is the recording buffer.  
  The device driver will continuously move data from this buffer
  from/to the audio hardware, wrapping around at the end of the buffer.
  To find out where the hardware is currently accessing data in the buffer the
  .Dv AUDIO_GETIOFFS
  and
  .Dv AUDIO_GETOOFFS
! calls can be used.  In the case of 
! .Dv AUDIO_GETOIFFS ,
! the offsets are relative to the beginning of the recording buffer,
! not the beginning of the mapped memory block.
  Only encodings that are not emulated (i.e. where
  .Dv AUDIO_ENCODINGFLAG_EMULATED
  is not set) work properly for a mapped device.
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: kern-bug-people->bjs
Responsible-Changed-By: dholland@NetBSD.org
Responsible-Changed-When: Sat, 03 May 2008 02:25:59 +0000
Responsible-Changed-Why:
could you take a quick look at this?


Responsible-Changed-From-To: bjs->kern-bug-people
Responsible-Changed-By: wiz@NetBSD.org
Responsible-Changed-When: Mon, 28 Feb 2011 14:56:41 +0000
Responsible-Changed-Why:
Reset responsible field for retired developer.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.