Subject: kern/2632: audio system supports only one device
To: None <gnats-bugs@NetBSD.ORG>
From: Mike Long <mike.long@analog.com>
List: netbsd-bugs
Date: 07/16/1996 01:10:57
>Number:         2632
>Category:       kern
>Synopsis:       audio system supports only one device
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jul 16 01:35:01 1996
>Last-Modified:
>Originator:     Mike Long <mike.long@analog.com>
>Organization:
	Beta-Testers Anonymous
>Release:        1.2_BETA
>Environment:

System: NetBSD azathoth 1.2_BETA NetBSD 1.2_BETA (AZATHOTH) #90: Mon Jul 15 23:10:33 EDT 1996 root@azathoth:/usr/src/sys/arch/i386/compile/AZATHOTH i386


>Description:
	The conversion of the audio system to config.new was never
truly completed; NAUDIO is always 1, so only one attached device
is allowed.

>How-To-Repeat:
	Boot a GENERIC kernel on a i386 machine that contains multiple
audio devices, e.g.:

sb0 at isa0 port 0x220-0x22f irq 7 drq 1: dsp v2.01
wss0 at isa0 port 0x530-0x537 irq 10 drq 0: AD1848K (vers 4)

>Fix:
	Apply these patches.  Some cleanup remains, but I avoided
doing it in order to keep the patch size to a minimum.

	I fixed most of the ISA audio drivers and the SPARC audio
driver; if any others exist they will need to adjust to the change in
the declaration of struct audio_hw_if.open(). LKMs (Amiga?) also have
to watch out for the change in audio_hardware_detach().

	I couldn't quite figure out what the GUS driver was doing with
its audio_hw_if structures, so I got it to compile and otherwise left
it alone.  The PSS driver also needs help.  SB, PAS, & WSS should work.

*** /sys/dev/audio_if.h.orig	Fri Mar  8 07:25:43 1996
--- /sys/dev/audio_if.h	Sat Jul 13 17:51:44 1996
***************
*** 38,46 ****
   * Generic interface to hardware driver.
   */
! 
! struct audio_softc;
  
  struct audio_hw_if {
! 	int	(*open)__P((dev_t, int));	/* open hardware */
  	void	(*close)__P((void *));		/* close hardware */
  	int	(*drain)__P((void *));		/* Optional: drain buffers */
--- 38,46 ----
   * Generic interface to hardware driver.
   */
! #ifndef _DEV_AUDIO_IF_H_
! #define _DEV_AUDIO_IF_H_
  
  struct audio_hw_if {
! 	int	(*open)__P((void *, dev_t, int)); /* open hardware */
  	void	(*close)__P((void *));		/* close hardware */
  	int	(*drain)__P((void *));		/* Optional: drain buffers */
***************
*** 120,126 ****
  };
  
  /* Register / deregister hardware driver */
  extern int	audio_hardware_attach __P((struct audio_hw_if *, void *));
! extern int	audio_hardware_detach __P((struct audio_hw_if *));
  
  /* Device identity flags */
--- 120,128 ----
  };
  
+ #ifdef _KERNEL
  /* Register / deregister hardware driver */
  extern int	audio_hardware_attach __P((struct audio_hw_if *, void *));
! extern int	audio_hardware_detach __P((void *));
! #endif
  
  /* Device identity flags */
***************
*** 138,139 ****
--- 140,143 ----
  #define splaudio splbio		/* XXX */
  #define IPL_AUDIO IPL_BIO	/* XXX */
+ 
+ #endif /* _DEV_AUDIO_IF_H_ */

*** /sys/dev/audiovar.h.orig	Tue Feb 20 07:39:49 1996
--- /sys/dev/audiovar.h	Thu Jul 11 01:16:38 1996
***************
*** 36,39 ****
--- 36,44 ----
   */
  
+ #ifndef _DEV_AUDIOVAR_H_
+ #define _DEV_AUDIOVAR_H_
+ 
+ #include <sys/queue.h>
+ 
  /*
   * Initial/default block duration is both configurable and patchable.
***************
*** 84,90 ****
   * Software state, per audio device.
   */
! struct audio_softc {
! 	void	*hw_hdl;		/* Hardware driver handle */
  	struct	audio_hw_if *hw_if; /* Hardware interface */
  	u_char	sc_open;	/* single use device */
  #define AUOPEN_READ	0x01
--- 89,99 ----
   * Software state, per audio device.
   */
! struct audiodev {
! 	TAILQ_ENTRY(audiodev)
! 		ad_chain;	/* attached device chain */
! 
! 	void	*hw_hdl;	/* Hardware driver handle */
  	struct	audio_hw_if *hw_if; /* Hardware interface */
+ 
  	u_char	sc_open;	/* single use device */
  #define AUOPEN_READ	0x01
***************
*** 122,123 ****
--- 131,142 ----
  	int	sc_rencoding;	/* current encoding; record */
  };
+ 
+ /*
+  * Audio system state
+  */
+ struct audio_softc {
+ 	TAILQ_HEAD(, audiodev)
+ 		sc_subdevs;	/* list of all attached devices */
+ };
+ 
+ #endif /* _DEV_AUDIOVAR_H_ */


*** /sys/dev/audio.c.orig	Mon May 13 07:36:04 1996
--- /sys/dev/audio.c	Tue Jul 16 00:45:39 1996
***************
*** 64,70 ****
   */
  
- #include "audio.h"
- #if NAUDIO > 0
- 
  #include <sys/param.h>
  #include <sys/ioctl.h>
--- 64,67 ----
***************
*** 108,113 ****
  #endif
  
! int naudio;	/* Count of attached hardware drivers */
! 
  int audio_blk_ms = AUDIO_BLK_MS;
  int audio_backlog = AUDIO_BACKLOG;
--- 105,109 ----
  #endif
  
! /* XXX? */
  int audio_blk_ms = AUDIO_BLK_MS;
  int audio_backlog = AUDIO_BACKLOG;
***************
*** 117,124 ****
  char *auzero_block;
  
! struct audio_softc *audio_softc[NAUDIO];
  
! int	audiosetinfo __P((struct audio_softc *, struct audio_info *));
! int	audiogetinfo __P((struct audio_softc *, struct audio_info *));
  
  int	audio_open __P((dev_t, int, int, struct proc *));
--- 113,120 ----
  char *auzero_block;
  
! struct audio_softc *audio_softc; /* XXX? */
  
! int	audiosetinfo __P((struct audiodev *, struct audio_info *));
! int	audiogetinfo __P((struct audiodev *, struct audio_info *));
  
  int	audio_open __P((dev_t, int, int, struct proc *));
***************
*** 133,164 ****
  int	mixer_ioctl __P((dev_t, int, caddr_t, int, struct proc *));
      
! void	audio_init_record __P((struct audio_softc *));
! void	audio_init_play __P((struct audio_softc *));
! void	audiostartr __P((struct audio_softc *));
! void	audiostartp __P((struct audio_softc *));
  void	audio_rint __P((void *));
  void	audio_pint __P((void *));
  void	audio_rpint __P((void *));
  
! int	audio_calc_blksize __P((struct audio_softc *));
! void	audio_silence_fill __P((struct audio_softc *, u_char *, int));
! int	audio_silence_copyout __P((struct audio_softc *, int, struct uio *));
! void	audio_alloc_auzero __P((struct audio_softc *, int));
  
! void	audio_printsc __P((struct audio_softc *));
! void	audioattach __P((int));
  int	audio_hardware_attach __P((struct audio_hw_if *, void *));
  void	audio_init_ring __P((struct audio_buffer *, int));
! void	audio_initbufs __P((struct audio_softc *));
! static __inline int audio_sleep_timo __P((int *, char *, int));
! static __inline int audio_sleep __P((int *, char *));
! static __inline void audio_wakeup __P((int *));
! int	audio_drain __P((struct audio_softc *));
! void	audio_clear __P((struct audio_softc *));
  
  #ifdef AUDIO_DEBUG
  void
  audio_printsc(sc)
! 	struct audio_softc *sc;
  {
  	printf("hwhandle %p hw_if %p ", sc->hw_hdl, sc->hw_if);
--- 129,167 ----
  int	mixer_ioctl __P((dev_t, int, caddr_t, int, struct proc *));
      
! void	audio_init_record __P((struct audiodev *));
! void	audio_init_play __P((struct audiodev *));
! void	audiostartr __P((struct audiodev *));
! void	audiostartp __P((struct audiodev *));
  void	audio_rint __P((void *));
  void	audio_pint __P((void *));
  void	audio_rpint __P((void *));
  
! int	audio_calc_blksize __P((struct audiodev *));
! void	audio_silence_fill __P((struct audiodev *, u_char *, int));
! int	audio_silence_copyout __P((struct audiodev *, int, struct uio *));
! void	audio_alloc_auzero __P((struct audiodev *, int));
  
! #ifdef AUDIO_DEBUG
! void	audio_printsc __P((struct audiodev *));
! #endif
  int	audio_hardware_attach __P((struct audio_hw_if *, void *));
+ int	audio_hardware_detach __P((void *));
  void	audio_init_ring __P((struct audio_buffer *, int));
! void	audio_initbufs __P((struct audiodev *));
! static __inline int
! 	audio_sleep_timo __P((int *, char *, int));
! static __inline int
! 	audio_sleep __P((int *, char *));
! static __inline void
! 	audio_wakeup __P((int *));
! struct audiodev *
! 	audio_getdev __P((dev_t));
! int	audio_drain __P((struct audiodev *));
! void	audio_clear __P((struct audiodev *));
  
  #ifdef AUDIO_DEBUG
  void
  audio_printsc(sc)
! 	struct audiodev *sc;
  {
  	printf("hwhandle %p hw_if %p ", sc->hw_hdl, sc->hw_if);
***************
*** 174,183 ****
  #endif
  
- void
- audioattach(num)
- 	int num;
- {
- }
- 
  /*
   * Called from hardware driver.
--- 177,180 ----
***************
*** 188,206 ****
  	void *hdlp;
  {
! 	struct audio_softc *sc;
! 
! 	if (naudio >= NAUDIO) {
! 	    DPRINTF(("audio_hardware_attach: not enough audio devices: %d > %d\n",
! 		     naudio, NAUDIO));
! 	    return(EINVAL);
! 	}
! 
! 	/*
! 	 * Malloc a softc for the device
! 	 */
! 	/* XXX Find the first free slot */
! 	audio_softc[naudio] = malloc(sizeof(struct audio_softc), M_DEVBUF, M_WAITOK);
! 	sc = audio_softc[naudio];	
! 	bzero(sc, sizeof(struct audio_softc));
  
  	/* XXX too paranoid? */
--- 185,190 ----
  	void *hdlp;
  {
! 	struct audiodev *sc;
! 	int unit;
  
  	/* XXX too paranoid? */
***************
*** 236,239 ****
--- 220,246 ----
  		return(EINVAL);
  
+ 	/*
+ 	 * Find a softc for the device (and audio system, if first call)
+ 	 */
+ 	if (audio_softc == NULL) {
+ 		audio_softc = malloc(sizeof(struct audio_softc),
+ 				     M_DEVBUF, M_WAITOK);
+ 		TAILQ_INIT(&audio_softc->sc_subdevs);
+ 	}
+ 
+ 	unit = 0;
+ 	sc = audio_softc->sc_subdevs.tqh_first;
+ 	while (sc) {
+ 		if (sc->hw_if == NULL)
+ 			break;	/* reuse this one */
+ 		unit++;
+ 		sc = sc->ad_chain.tqe_next;
+ 	}
+ 	if (sc == NULL) {
+ 		sc = malloc(sizeof(struct audiodev), M_DEVBUF, M_WAITOK);
+ 		bzero(sc, sizeof(struct audiodev));
+ 		TAILQ_INSERT_TAIL(&audio_softc->sc_subdevs, sc, ad_chain);
+ 	}
+ 
  	sc->hw_if = hwp;
  	sc->hw_hdl = hdlp;
***************
*** 260,264 ****
  	 * Return the audio unit number
  	 */
! 	hwp->audio_unit = naudio++;
  
  #ifdef AUDIO_DEBUG
--- 267,271 ----
  	 * Return the audio unit number
  	 */
! 	hwp->audio_unit = unit;
  
  #ifdef AUDIO_DEBUG
***************
*** 270,295 ****
  
  int
! audio_hardware_detach(hwp)
! 	struct audio_hw_if *hwp;
  {
! 	struct audio_softc *sc;
! 	
  #ifdef DIAGNOSTIC
! 	if (!hwp)
! 	    panic("audio_hardware_detach: null hwp");
! 	
! 	if (hwp->audio_unit > naudio)
! 	    panic("audio_hardware_detach: invalid audio unit");
  #endif
  
! 	sc = audio_softc[hwp->audio_unit];
  
- 	if (hwp != sc->hw_if)
- 		return(EINVAL);
- 	
  	if (sc->sc_open != 0)
  		return(EBUSY);
  
  	sc->hw_if = 0;
  
  	/* Free audio buffers */
--- 277,310 ----
  
  int
! audio_hardware_detach(hdlp)
! 	void *hdlp;
  {
! 	struct audiodev *sc;
! 	int unit;
! 
  #ifdef DIAGNOSTIC
! 	if (!hdlp)
! 		panic("audio_hardware_detach: null handle");
! 
! 	if (!audio_softc)
! 		panic("audio_hardware_detach: none attached");
  #endif
  
! 	for (sc = audio_softc->sc_subdevs.tqh_first; sc;
! 	     sc = sc->ad_chain.tqe_next)
! 		if (sc->hw_hdl == hdlp)
! 			break;
! 
! #ifdef DIAGNOSTIC
! 	if (!sc)
! 		panic("audio_hardware_detach: invalid audio unit");
! #endif
  
  	if (sc->sc_open != 0)
  		return(EBUSY);
  
+ 	/* Free slot for re-use */
  	sc->hw_if = 0;
+ 	sc->hw_hdl = 0;
  
  	/* Free audio buffers */
***************
*** 297,302 ****
  	free(sc->pr.bp, M_DEVBUF);
  
! 	free(sc, M_DEVBUF);
! 	audio_softc[hwp->audio_unit] = NULL;
  
  	return(0);
--- 312,324 ----
  	free(sc->pr.bp, M_DEVBUF);
  
! #ifdef notyet
! 	/* Free structure if last in chain */
! 	if (!sc->ad_chain.tqe_next) {
! 		TAILQ_REMOVE(&audio_softc->sc_subdevs, sc, ad_chain);
! 		free(sc, M_DEVBUF);
! 		if (!audio_softc->sc_subdevs.tqh_first)
! 			free(audio_softc, M_DEVBUF);
! 	}
! #endif
  
  	return(0);
***************
*** 446,450 ****
  void
  audio_initbufs(sc)
! 	struct audio_softc *sc;
  {
  	int nblk = AU_RING_SIZE / sc->sc_blksize;
--- 468,472 ----
  void
  audio_initbufs(sc)
! 	struct audiodev *sc;
  {
  	int nblk = AU_RING_SIZE / sc->sc_blksize;
***************
*** 494,497 ****
--- 516,542 ----
  }
  
+ struct audiodev *
+ audio_getdev(dev)
+ 	dev_t dev;
+ {
+ 	int unit;
+ 	struct audiodev *ad;
+ 
+ 	if (!audio_softc) {
+ 		DPRINTF(("audio_getdev: invalid device unit - %d\n",
+ 			 AUDIOUNIT(dev)));
+ 		return NULL;
+ 	}
+ 
+ 	ad = audio_softc->sc_subdevs.tqh_first;
+ 	for (unit = AUDIOUNIT(dev); (unit > 0) && ad; unit--)
+ 		ad = ad->ad_chain.tqe_next;
+ 	if (!ad)
+ 		DPRINTF(("audio_getdev: invalid device unit - %d\n",
+ 			 AUDIOUNIT(dev)));
+ 
+ 	return ad;
+ }
+ 
  int
  audio_open(dev, flags, ifmt, p)
***************
*** 500,517 ****
  	struct proc *p;
  {
! 	int unit = AUDIOUNIT(dev);
! 	struct audio_softc *sc;
  	int s, error;
  	struct audio_hw_if *hw;
  
! 	if (unit >= NAUDIO || !audio_softc[unit]) {
! 	    DPRINTF(("audio_open: invalid device unit - %d\n", unit));
! 	    return (ENODEV);
! 	}
  
- 	sc = audio_softc[unit];
  	hw = sc->hw_if;
  
! 	DPRINTF(("audio_open: dev=0x%x flags=0x%x sc=0x%x hdl=0x%x\n", dev, flags, sc, sc->hw_hdl));
  	if (hw == 0)		/* Hardware has not attached to us... */
  		return (ENXIO);
--- 545,560 ----
  	struct proc *p;
  {
! 	struct audiodev *sc;
  	int s, error;
  	struct audio_hw_if *hw;
  
! 	sc = audio_getdev(dev);
! 	if (!sc)
! 		return (ENXIO);
  
  	hw = sc->hw_if;
  
! 	DPRINTF(("audio_open: dev=0x%x flags=0x%x sc=%p hdl=%p\n",
! 		 dev, flags, sc, sc->hw_hdl));
  	if (hw == 0)		/* Hardware has not attached to us... */
  		return (ENXIO);
***************
*** 520,524 ****
  		return (EBUSY);
  
! 	if ((error = hw->open(dev, flags)) != 0)
  		return (error);
  
--- 563,567 ----
  		return (EBUSY);
  
! 	if ((error = hw->open(sc->hw_hdl, dev, flags)) != 0)
  		return (error);
  
***************
*** 614,618 ****
  void
  audio_init_record(sc)
! 	struct audio_softc *sc;
  {
  	int s = splaudio();
--- 657,661 ----
  void
  audio_init_record(sc)
! 	struct audiodev *sc;
  {
  	int s = splaudio();
***************
*** 630,634 ****
  void
  audio_init_play(sc)
! 	struct audio_softc *sc;
  {
  	int s = splaudio();
--- 673,677 ----
  void
  audio_init_play(sc)
! 	struct audiodev *sc;
  {
  	int s = splaudio();
***************
*** 643,647 ****
  int
  audio_drain(sc)
! 	struct audio_softc *sc;
  {
  	int error;
--- 686,690 ----
  int
  audio_drain(sc)
! 	struct audiodev *sc;
  {
  	int error;
***************
*** 672,681 ****
  	struct proc *p;
  {
! 	int unit = AUDIOUNIT(dev);
! 	struct audio_softc *sc = audio_softc[unit];
! 	struct audio_hw_if *hw = sc->hw_if;
  	int s;
  
! 	DPRINTF(("audio_close: unit=%d\n", unit));
  
  	/*
--- 715,730 ----
  	struct proc *p;
  {
! 	struct audiodev *sc;
! 	struct audio_hw_if *hw;
  	int s;
  
! 	DPRINTF(("audio_close: unit=%d\n", AUDIOUNIT(dev)));
! 
! 	sc = audio_getdev(dev);
! #ifdef DIAGNOSTIC
! 	if (!sc)
! 		panic("audio_close: no hardware attached");
! #endif
! 	hw = sc->hw_if;
  
  	/*
***************
*** 712,722 ****
  	int ioflag;
  {
! 	int unit = AUDIOUNIT(dev);
! 	struct audio_softc *sc = audio_softc[unit];
! 	struct audio_hw_if *hw = sc->hw_if;
! 	struct audio_buffer *cb = &sc->rr;
  	u_char *hp;
! 	int blocksize = sc->sc_blksize;
! 	int error, s;
  
  	DPRINTF(("audio_read: cc=%d mode=%d rblks=%d\n",
--- 761,778 ----
  	int ioflag;
  {
! 	struct audiodev *sc;
! 	struct audio_hw_if *hw;
! 	struct audio_buffer *cb;
  	u_char *hp;
! 	int blocksize, error, s;
! 
! 	sc = audio_getdev(dev);
! #ifdef DIAGNOSTIC
! 	if (!sc)
! 		panic("audio_read: no hardware attached");
! #endif
! 	hw = sc->hw_if;
! 	cb = &sc->rr;
! 	blocksize = sc->sc_blksize;
  
  	DPRINTF(("audio_read: cc=%d mode=%d rblks=%d\n",
***************
*** 765,772 ****
  	do {
  		while (cb->nblk <= 0) {
! 			if (ioflag & IO_NDELAY) {
! 				error = EWOULDBLOCK;
! 				return (error);
! 			}
  			s = splaudio();
  			if (!sc->sc_rbus)
--- 821,826 ----
  	do {
  		while (cb->nblk <= 0) {
! 			if (ioflag & IO_NDELAY)
! 				return (EWOULDBLOCK);
  			s = splaudio();
  			if (!sc->sc_rbus)
***************
*** 795,799 ****
  void
  audio_clear(sc)
! 	struct audio_softc *sc;
  {
  	int s = splaudio();
--- 849,853 ----
  void
  audio_clear(sc)
! 	struct audiodev *sc;
  {
  	int s = splaudio();
***************
*** 814,818 ****
  int
  audio_calc_blksize(sc)
! 	struct audio_softc *sc;
  {
  	struct audio_hw_if *hw = sc->hw_if;
--- 868,872 ----
  int
  audio_calc_blksize(sc)
! 	struct audiodev *sc;
  {
  	struct audio_hw_if *hw = sc->hw_if;
***************
*** 835,839 ****
  void
  audio_silence_fill(sc, p, n)
! 	struct audio_softc *sc;
          u_char *p;
          int n;
--- 889,893 ----
  void
  audio_silence_fill(sc, p, n)
! 	struct audiodev *sc;
          u_char *p;
          int n;
***************
*** 850,854 ****
  int
  audio_silence_copyout(sc, n, uio)
! 	struct audio_softc *sc;
  	int n;
  	struct uio *uio;
--- 904,908 ----
  int
  audio_silence_copyout(sc, n, uio)
! 	struct audiodev *sc;
  	int n;
  	struct uio *uio;
***************
*** 890,894 ****
  void
  audio_alloc_auzero(sc, bs)
! 	struct audio_softc *sc;
  	int bs;
  {
--- 944,948 ----
  void
  audio_alloc_auzero(sc, bs)
! 	struct audiodev *sc;
  	int bs;
  {
***************
*** 923,935 ****
  	int ioflag;
  {
! 	int unit = AUDIOUNIT(dev);
! 	struct audio_softc *sc = audio_softc[unit];
! 	struct audio_hw_if *hw = sc->hw_if;
! 	struct audio_buffer *cb = &sc->pr;
  	u_char *tp;
! 	int error, s, cc;
! 	int blocksize = sc->sc_blksize;
  
! 	DPRINTF(("audio_write: cc=%d hiwat=%d\n", uio->uio_resid, sc->sc_hiwat));
  	/*
  	 * If half-duplex and currently recording, throw away data.
--- 977,997 ----
  	int ioflag;
  {
! 	struct audiodev *sc;
! 	struct audio_hw_if *hw;
! 	struct audio_buffer *cb;
  	u_char *tp;
! 	int error, s, cc, blocksize;
  
! 	sc = audio_getdev(dev);
! #ifdef DIAGNOSTIC
! 	if (!sc)
! 		panic("audio_write: no hardware attached");
! #endif
! 	hw = sc->hw_if;
! 	cb = &sc->pr;
! 	blocksize = sc->sc_blksize;
! 
! 	DPRINTF(("audio_write: cc=%d hiwat=%d\n",
! 		 uio->uio_resid, sc->sc_hiwat));
  	/*
  	 * If half-duplex and currently recording, throw away data.
***************
*** 1073,1083 ****
  	struct proc *p;
  {
! 	int unit = AUDIOUNIT(dev);
! 	struct audio_softc *sc = audio_softc[unit];
! 	struct audio_hw_if *hw = sc->hw_if;
  	int error = 0, s;
  
  	DPRINTF(("audio_ioctl(%d,'%c',%d)\n",
  	          IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff));
  	switch (cmd) {
  
--- 1135,1152 ----
  	struct proc *p;
  {
! 	struct audiodev *sc;
! 	struct audio_hw_if *hw;
  	int error = 0, s;
  
+ 	sc = audio_getdev(dev);
+ #ifdef DIAGNOSTIC
+ 	if (!sc)
+ 		panic("audio_ioctl: no hardware attached");
+ #endif
+ 	hw = sc->hw_if;
+ 
  	DPRINTF(("audio_ioctl(%d,'%c',%d)\n",
  	          IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff));
+ 
  	switch (cmd) {
  
***************
*** 1180,1186 ****
  	struct proc *p;
  {
! 	int unit = AUDIOUNIT(dev);
! 	struct audio_softc *sc = audio_softc[unit];
! 	int s = splaudio();
  
  #if 0
--- 1249,1261 ----
  	struct proc *p;
  {
! 	struct audiodev *sc;
! 	int s;
! 
! 	sc = audio_getdev(dev);
! #ifdef DIAGNOSTIC
! 	if (!sc)
! 		panic("audio_select: no hardware attached");
! #endif
! 	s = splaudio();
  
  #if 0
***************
*** 1188,1191 ****
--- 1263,1267 ----
  	         rw, sc->sc_mode, sc->sc_rblks, sc->rr.nblk));
  #endif
+ 
  	switch (rw) {
  
***************
*** 1228,1232 ****
  void
  audiostartr(sc)
! 	struct audio_softc *sc;
  {
  	int error;
--- 1304,1308 ----
  void
  audiostartr(sc)
! 	struct audiodev *sc;
  {
  	int error;
***************
*** 1246,1250 ****
  void
  audiostartp(sc)
! 	struct audio_softc *sc;
  {
  	int error;
--- 1322,1326 ----
  void
  audiostartp(sc)
! 	struct audiodev *sc;
  {
  	int error;
***************
*** 1277,1281 ****
  	void *v;
  {
! 	struct audio_softc *sc = v;
  	sc->pr.nblk--;
  	audio_pint(v);		/* 'twas a real audio block */
--- 1353,1358 ----
  	void *v;
  {
! 	struct audiodev *sc = v;
! 
  	sc->pr.nblk--;
  	audio_pint(v);		/* 'twas a real audio block */
***************
*** 1292,1296 ****
  	void *v;
  {
! 	struct audio_softc *sc = v;
  	u_char *hp;
  	int cc = sc->sc_blksize;
--- 1369,1373 ----
  	void *v;
  {
! 	struct audiodev *sc = v;
  	u_char *hp;
  	int cc = sc->sc_blksize;
***************
*** 1389,1393 ****
  	void *v;
  {
! 	struct audio_softc *sc = v;
  	u_char *tp;
  	int cc = sc->sc_blksize;
--- 1466,1470 ----
  	void *v;
  {
! 	struct audiodev *sc = v;
  	u_char *tp;
  	int cc = sc->sc_blksize;
***************
*** 1441,1445 ****
  int
  audiosetinfo(sc, ai)
! 	struct audio_softc *sc;
  	struct audio_info *ai;
  {
--- 1518,1522 ----
  int
  audiosetinfo(sc, ai)
! 	struct audiodev *sc;
  	struct audio_info *ai;
  {
***************
*** 1664,1668 ****
  int
  audiogetinfo(sc, ai)
! 	struct audio_softc *sc;
  	struct audio_info *ai;
  {
--- 1741,1745 ----
  int
  audiogetinfo(sc, ai)
! 	struct audiodev *sc;
  	struct audio_info *ai;
  {
***************
*** 1731,1747 ****
  	struct proc *p;
  {
! 	int unit = AUDIOUNIT(dev);
! 	struct audio_softc *sc;
  	struct audio_hw_if *hw;
  
! 	if (unit >= NAUDIO || !audio_softc[unit]) {
! 	    DPRINTF(("mixer_open: invalid device unit - %d\n", unit));
! 	    return (ENODEV);
! 	}
! 
! 	sc = audio_softc[unit];
  	hw = sc->hw_if;
  
! 	DPRINTF(("mixer_open: dev=%x flags=0x%x sc=0x%x\n", dev, flags, sc));
  	if (hw == 0)		/* Hardware has not attached to us... */
  		return (ENXIO);
--- 1808,1820 ----
  	struct proc *p;
  {
! 	struct audiodev *sc;
  	struct audio_hw_if *hw;
  
! 	sc = audio_getdev(dev);
! 	if (!sc)
! 		return (ENXIO);
  	hw = sc->hw_if;
  
! 	DPRINTF(("mixer_open: dev=%x flags=0x%x sc=%p\n", dev, flags, sc));
  	if (hw == 0)		/* Hardware has not attached to us... */
  		return (ENXIO);
***************
*** 1773,1785 ****
  	struct proc *p;
  {
! 	int unit = AUDIOUNIT(dev);
! 	struct audio_softc *sc = audio_softc[unit];
! 	struct audio_hw_if *hw = sc->hw_if;
  	int error = EINVAL;
  
  	DPRINTF(("mixer_ioctl(%d,'%c',%d)\n",
  	          IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff));
  
  	switch (cmd) {
  	case AUDIO_GETDEV:
  	    DPRINTF(("AUDIO_GETDEV\n"));
--- 1846,1865 ----
  	struct proc *p;
  {
! 	struct audiodev *sc;
! 	struct audio_hw_if *hw;
  	int error = EINVAL;
  
+ 	sc = audio_getdev(dev);
+ #ifdef DIAGNOSTIC
+ 	if (!sc)
+ 		panic("mixer_ioctl: no hardware attached");
+ #endif
+ 	hw = sc->hw_if;
+ 
  	DPRINTF(("mixer_ioctl(%d,'%c',%d)\n",
  	          IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff));
  
  	switch (cmd) {
+ 
  	case AUDIO_GETDEV:
  	    DPRINTF(("AUDIO_GETDEV\n"));
***************
*** 1812,1814 ****
  	return (error);
  }
- #endif
--- 1892,1893 ----


*** /sys/dev/isa/ad1848var.h.orig	Thu May  2 07:42:11 1996
--- /sys/dev/isa/ad1848var.h	Sun Jul 14 02:01:05 1996
***************
*** 106,110 ****
  void	ad1848_attach __P((struct ad1848_softc *));
  
! int	ad1848_open __P((struct ad1848_softc *, dev_t, int));
  void	ad1848_close __P((void *));
      
--- 102,106 ----
  void	ad1848_attach __P((struct ad1848_softc *));
  
! int	ad1848_open __P((void *, dev_t, int));
  void	ad1848_close __P((void *));
      

*** /sys/dev/isa/ad1848.c.orig	Thu May  2 07:42:11 1996
--- /sys/dev/isa/ad1848.c	Mon Jul 15 23:01:31 1996
***************
*** 1167,1175 ****
  
  int
! ad1848_open(sc, dev, flags)
!     struct ad1848_softc *sc;
      dev_t dev;
      int flags;
  {
      DPRINTF(("ad1848_open: sc=0x%x\n", sc));
  
--- 1168,1178 ----
  
  int
! ad1848_open(addr, dev, flags)
!     void *addr;
      dev_t dev;
      int flags;
  {
+     struct ad1848_softc *sc = addr;
+ 
      DPRINTF(("ad1848_open: sc=0x%x\n", sc));
  

*** /sys/dev/isa/gus.c.orig	Mon May 13 07:36:17 1996
--- /sys/dev/isa/gus.c	Sat Jul 13 18:39:36 1996
***************
*** 348,352 ****
   */
  
! int	gusopen __P((dev_t, int));
  void	gusclose __P((void *));
  void	gusmax_close __P((void *));
--- 348,352 ----
   */
  
! int	gusopen __P((void *, dev_t, int));
  void	gusclose __P((void *));
  void	gusmax_close __P((void *));
***************
*** 973,978 ****
  }
  
  int
! gusopen(dev, flags)
  	dev_t dev;
  	int flags;
--- 973,981 ----
  }
  
+ /* XXX true type of handle (addr) is unknown */
+ /*ARGSUSED*/
  int
! gusopen(addr, dev, flags)
! 	void *addr;
  	dev_t dev;
  	int flags;


*** /sys/dev/isa/pas.c.orig	Mon May 13 07:36:23 1996
--- /sys/dev/isa/pas.c	Sat Jul 13 18:29:54 1996
***************
*** 101,105 ****
  };
  
- int	pasopen __P((dev_t, int));
  int	pas_getdev __P((void *, struct audio_device *));
  void	pasconf __P((int, int, int, int));
--- 101,104 ----
***************
*** 111,115 ****
  
  struct audio_hw_if pas_hw_if = {
! 	pasopen,
  	sbdsp_close,
  	NULL,
--- 110,114 ----
  
  struct audio_hw_if pas_hw_if = {
! 	sbdsp_open,
  	sbdsp_close,
  	NULL,
***************
*** 454,479 ****
  
  int
- pasopen(dev, flags)
-     dev_t dev;
-     int flags;
- {
-     struct pas_softc *sc;
-     int unit = AUDIOUNIT(dev);
-     
-     if (unit >= pas_cd.cd_ndevs)
- 	return ENODEV;
-     
-     sc = pas_cd.cd_devs[unit];
-     if (!sc)
- 	return ENXIO;
-     
-     return sbdsp_open(&sc->sc_sbdsp, dev, flags);
- }
- 
- int
  pas_getdev(addr, retp)
  	void *addr;
  	struct audio_device *retp;
  {
  	*retp = pas_device;
  	return 0;
--- 453,461 ----
  
  int
  pas_getdev(addr, retp)
  	void *addr;
  	struct audio_device *retp;
  {
+ 
  	*retp = pas_device;
  	return 0;


*** /sys/dev/isa/pss.c.orig	Mon May 13 07:36:24 1996
--- /sys/dev/isa/pss.c	Sun Jul 14 02:29:52 1996
***************
*** 163,168 ****
  void	pcdattach __P((struct device *, struct device *, void *));
  
- int	spopen __P((dev_t, int));
- 
  int	pssintr __P((void *));
  int	mpuintr __P((void *));
--- 163,166 ----
***************
*** 208,212 ****
  
  struct audio_hw_if pss_audio_if = {
! 	spopen,
  	ad1848_close,
  	NULL,
--- 206,210 ----
  
  struct audio_hw_if pss_audio_if = {
! 	ad1848_open,
  	ad1848_close,
  	NULL,
***************
*** 1192,1213 ****
      }
      return(0);
- }
- 
- int
- spopen(dev, flags)
-     dev_t dev;
-     int flags;
- {
-     struct ad1848_softc *sc;
-     int unit = AUDIOUNIT(dev);
-     
-     if (unit >= sp_cd.cd_ndevs)
- 	return ENODEV;
-     
-     sc = sp_cd.cd_devs[unit];
-     if (!sc)
- 	return ENXIO;
-     
-     return ad1848_open(sc, dev, flags);
  }
  
--- 1192,1195 ----


*** /sys/dev/isa/sb.c.orig	Mon May 13 07:36:24 1996
--- /sys/dev/isa/sb.c	Sat Jul 13 18:45:09 1996
***************
*** 65,76 ****
  #endif
  
- struct sb_softc {
- 	struct	device sc_dev;		/* base device */
- 	struct	isadev sc_id;		/* ISA device */
- 	void	*sc_ih;			/* interrupt vectoring */
- 
- 	struct	sbdsp_softc sc_sbdsp;
- };
- 
  int	sbprobe __P((struct device *, void *, void *));
  void	sbattach __P((struct device *, struct device *, void *));
--- 65,68 ----
***************
*** 90,94 ****
  };
  
- int	sbopen __P((dev_t, int));
  int	sb_getdev __P((void *, struct audio_device *));
  
--- 82,85 ----
***************
*** 98,102 ****
  
  struct audio_hw_if sb_hw_if = {
! 	sbopen,
  	sbdsp_close,
  	NULL,
--- 89,93 ----
  
  struct audio_hw_if sb_hw_if = {
! 	sbdsp_open,
  	sbdsp_close,
  	NULL,
***************
*** 284,309 ****
  
  /*
!  * Various routines to interface to higher level audio driver
   */
  
  int
- sbopen(dev, flags)
-     dev_t dev;
-     int flags;
- {
-     struct sbdsp_softc *sc;
-     int unit = AUDIOUNIT(dev);
-     
-     if (unit >= sb_cd.cd_ndevs)
- 	return ENODEV;
-     
-     sc = sb_cd.cd_devs[unit];
-     if (!sc)
- 	return ENXIO;
-     
-     return sbdsp_open(sc, dev, flags);
- }
- 
- int
  sb_getdev(addr, retp)
  	void *addr;
--- 275,282 ----
  
  /*
!  * Routine to interface to higher level audio driver
   */
  
  int
  sb_getdev(addr, retp)
  	void *addr;
***************
*** 316,320 ****
  	else
  		strncpy(retp->name, "SoundBlaster", sizeof(retp->name));
! 	sprintf(retp->version, "%d.%d", 
  		SBVER_MAJOR(sc->sc_model),
  		SBVER_MINOR(sc->sc_model));
--- 289,293 ----
  	else
  		strncpy(retp->name, "SoundBlaster", sizeof(retp->name));
! 	sprintf(retp->version, "%d.%02d", 
  		SBVER_MAJOR(sc->sc_model),
  		SBVER_MINOR(sc->sc_model));

*** /sys/dev/isa/sbdspvar.h.orig	Thu May  2 07:43:18 1996
--- /sys/dev/isa/sbdspvar.h	Sat Jul 13 18:25:42 1996
***************
*** 141,145 ****
  
  #ifdef _KERNEL
! int	sbdsp_open __P((struct sbdsp_softc *, dev_t, int));
  void	sbdsp_close __P((void *));
  
--- 141,145 ----
  
  #ifdef _KERNEL
! int	sbdsp_open __P((void *, dev_t, int));
  void	sbdsp_close __P((void *));
  

*** /sys/dev/isa/sbdsp.c.orig	Mon May 13 07:36:25 1996
--- /sys/dev/isa/sbdsp.c	Sat Jul 13 18:26:16 1996
***************
*** 718,726 ****
  
  int
! sbdsp_open(sc, dev, flags)
! 	register struct sbdsp_softc *sc;
  	dev_t dev;
  	int flags;
  {
          DPRINTF(("sbdsp_open: sc=0x%x\n", sc));
  
--- 718,728 ----
  
  int
! sbdsp_open(addr, dev, flags)
! 	void *addr;
  	dev_t dev;
  	int flags;
  {
+ 	register struct sbdsp_softc *sc = addr;
+ 
          DPRINTF(("sbdsp_open: sc=0x%x\n", sc));
  

*** /sys/dev/isa/wss.c.orig	Mon May 13 07:36:28 1996
--- /sys/dev/isa/wss.c	Sun Jul 14 02:03:56 1996
***************
*** 103,107 ****
  };
  
- int	wssopen __P((dev_t, int));
  int	wss_getdev __P((void *, struct audio_device *));
  int	wss_setfd __P((void *, int));
--- 103,106 ----
***************
*** 122,126 ****
  
  struct audio_hw_if wss_hw_if = {
! 	wssopen,
  	ad1848_close,
  	NULL,
--- 121,125 ----
  
  struct audio_hw_if wss_hw_if = {
! 	ad1848_open,
  	ad1848_close,
  	NULL,
***************
*** 303,324 ****
      }
      return(0);
- }
- 
- int
- wssopen(dev, flags)
-     dev_t dev;
-     int flags;
- {
-     struct wss_softc *sc;
-     int unit = AUDIOUNIT(dev);
-     
-     if (unit >= wss_cd.cd_ndevs)
- 	return ENODEV;
-     
-     sc = wss_cd.cd_devs[unit];
-     if (!sc)
- 	return ENXIO;
-     
-     return ad1848_open(&sc->sc_ad1848, dev, flags);
  }
  
--- 302,305 ----


*** /sys/arch/sparc/dev/amd7930.c.orig	Mon Apr  1 07:33:28 1996
--- /sys/arch/sparc/dev/amd7930.c	Mon Jul 15 23:19:31 1996
***************
*** 31,37 ****
   */
  
- #include "audio.h"
- #if NAUDIO > 0
- 
  #include <sys/param.h>
  #include <sys/systm.h>
--- 31,34 ----
***************
*** 195,199 ****
   * Define our interface to the higher level audio driver.
   */
! int	amd7930_open __P((dev_t, int));
  void	amd7930_close __P((void *));
  int	amd7930_set_in_sr __P((void *, u_long));
--- 192,196 ----
   * Define our interface to the higher level audio driver.
   */
! int	amd7930_open __P((void *, dev_t, int));
  void	amd7930_close __P((void *));
  int	amd7930_set_in_sr __P((void *, u_long));
***************
*** 361,377 ****
  
  int
! amd7930_open(dev, flags)
  	dev_t dev;
  	int flags;
  {
! 	register struct amd7930_softc *sc;
! 	int unit = AUDIOUNIT(dev);
  
! 	DPRINTF(("sa_open: unit %d\n",unit));
  
- 	if (unit >= audio_cd.cd_ndevs)
- 		return (ENODEV);
- 	if ((sc = audio_cd.cd_devs[unit]) == NULL)
- 		return (ENXIO);
  	if (sc->sc_open)
  		return (EBUSY);
--- 358,370 ----
  
  int
! amd7930_open(addr, dev, flags)
! 	void *addr;
  	dev_t dev;
  	int flags;
  {
! 	register struct amd7930_softc *sc = addr;
  
! 	DPRINTF(("sa_open: unit %d\n",AUDIOUNIT(dev)));
  
  	if (sc->sc_open)
  		return (EBUSY);
***************
*** 949,951 ****
  	return (ret);
  }
- #endif /* NAUDIO > 0 */
--- 942,943 ----

>Audit-Trail:
>Unformatted: