Subject: kern/2237: panic initializing PAS driver, 3/17/96 sources
To: None <gnats-bugs@NetBSD.ORG>
From: John F. Woods <jfw@FunHouse.com>
List: netbsd-bugs
Date: 03/17/1996 22:01:23
>Number:         2237
>Category:       kern
>Synopsis:       panic initializing PAS driver, 3/17/96
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Mar 17 22:20:03 1996
>Last-Modified:
>Originator:     John F. Woods
>Organization:
>Release:        3/17/96
>Environment:
	
System: NetBSD jfwhome.funhouse.com 1.1B NetBSD 1.1B (JFW) #44: Sun Mar 17 17:01:52 EST 1996 jfw@jfwhome.funhouse.com:/usr/src/sys/arch/i386/compile/JFW i386


>Description:
/*      $NetBSD: pas.c,v 1.14 1996/03/17 00:53:47 thorpej Exp $ */
	The PAS driver of 3/17/96 panics during startup due to a null pointer
dereference.  The pas_softc structure contains the usual sc_dev, sc_id, etc.
bits a driver needs, and follows the lead of sb.c in containing an sbdsp_softc
for the use of sbdsp.c.  However, sb.c ONLY uses the sbdsp_softc structure
(despite having a declaration of sb_softc), and here the fun begins.  pas.c
initializes the sc_dev etc members of pas_softc (or has them initialized for
it), then calls sbdsp_probe() with a pointer to the sb_sbdsp member -- which
has its own sc_dev member that sbdsp_probe() expects will have been set up.
It wasn't, and hilarity ensues.
	An easy fix is to exterminate the duplicate members of pas_softc,
and rely on the sb_sbdsp items; the context diff below implements just that.


>How-To-Repeat:
	Compile 3/17/96 kernel with PAS support.
	Install PAS.
	Boot.
	Die.

>Fix:
*** pas.c.ORIG	Sun Mar 17 16:37:49 1996
--- pas.c	Sun Mar 17 17:19:50 1996
***************
*** 85,102 ****
   * most basic communications with the sb card.
   */
  struct pas_softc {
! 	struct	device sc_dev;		/* base device */
! 	struct	isadev sc_id;		/* ISA device */
! 	void	*sc_ih;			/* interrupt vectoring */
! 
! 	int	sc_iobase;		/* PAS iobase */
! 	int	sc_irq;			/* PAS irq */
! 	int	sc_drq;			/* PAS drq */
! 
! 	int model;
  	int rev;
  
- 	struct sbdsp_softc sc_sbdsp;
  };
  
  int	pasopen __P((dev_t, int));
--- 85,96 ----
   * most basic communications with the sb card.
   */
  struct pas_softc {
! 	struct sbdsp_softc sc_sbdsp;	/* use sc_dev, sc_id, sc_ih,
! 					 *     sc_iobase, sc_irq, sc_drq
! 					 * from here */
! 	int model;	/* unique to PAS */
  	int rev;
  
  };
  
  int	pasopen __P((dev_t, int));
***************
*** 346,352 ****
          }
  
  	/* Now a SoundBlaster */
! 	sc->sc_iobase = ia->ia_iobase;
  	/* and set the SB iobase into the DSP as well ... */
  	sc->sc_sbdsp.sc_iobase = ia->ia_iobase;
  	if (sbdsp_reset(&sc->sc_sbdsp) < 0) {
--- 340,346 ----
          }
  
  	/* Now a SoundBlaster */
! /*	sc->sc_iobase = ia->ia_iobase;
  	/* and set the SB iobase into the DSP as well ... */
  	sc->sc_sbdsp.sc_iobase = ia->ia_iobase;
  	if (sbdsp_reset(&sc->sc_sbdsp) < 0) {
***************
*** 433,440 ****
  	register int iobase = ia->ia_iobase;
  	int err;
  	
! 	sc->sc_iobase = iobase;
! 	sc->sc_ih = isa_intr_establish(ia->ia_irq, IST_EDGE, IPL_AUDIO,
  				       sbdsp_intr, &sc->sc_sbdsp);
  
  	printf(" ProAudio Spectrum %s [rev %d] ", pasnames[sc->model], sc->rev);
--- 427,434 ----
  	register int iobase = ia->ia_iobase;
  	int err;
  	
! 	sc->sc_sbdsp.sc_iobase = iobase;
! 	sc->sc_sbdsp.sc_ih = isa_intr_establish(ia->ia_irq, IST_EDGE, IPL_AUDIO,
  				       sbdsp_intr, &sc->sc_sbdsp);
  
  	printf(" ProAudio Spectrum %s [rev %d] ", pasnames[sc->model], sc->rev);

>Audit-Trail:
>Unformatted: