Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 30 Jun 1996 23:21:20 -0400
From:      Thomas David Rivers <ponds!rivers@dg-rtp.dg.com>
To:        freebsd-hackers@freefall.FreeBSD.org, hasty@rah.star-gate.com, lakes!rivers, smpatel@xi.dorm.umd.edu
Subject:   Sound Blaster PNP - just how to do it (using Sujal's PNP & 2.1-RELEASE?)
Message-ID:  <199607010321.XAA00249@lakes>

next in thread | raw e-mail | index | archive | help

Ok - 

 I've chucked my Opti 8c929 card for a brand-new Sound Blaster PnP
card.... I got tired of wrestling with it...

 I had previously grabbed Sujal's PnP stuff, and now have it
"working" in a 2.1-RELEASE kernel.  (I made several fixes, which
I'm sure, by now, other people have reported... autoconf.c needs to
#include "pnp.h" - and several changes to pnp.c - which I've attached
below.)

 The problem is that something else isn't quite right yet.

 Here's the result of dmesg - (toward the top) - indicating
the PNP code is at least doing something:

   FreeBSD 2.1.0-RELEASE #8: Sun Jun 30 23:06:05 EDT 1996
       rivers@lakes.water.net:/usr/src/sys/compile/LAKES
   CPU: i486 DX2 (486-class CPU)
     Origin = "GenuineIntel"  Id = 0x435  Stepping=5
     Features=0x3<FPU,VME>
   real memory  = 12582912 (12288K bytes)
   avail memory = 10727424 (10476K bytes)
   Checking for Plug-n-Play devices...
   Board Vendor ID: CTL0028     Board Serial Number: 001c4a17
   Configuring This Card
   Configuring This Card
   Probing for devices on the ISA bus:
   sc0 at 0x60-0x6f irq 1 on motherboard


 Here's the result of dmesg - (toward the bottom) - indicating
that the card was at least activated:

   sb0 at 0x220 irq 5 drq 1 on isa
   sb0: <SoundBlaster 16 4.13>
   sbxvi0 at 0x0 drq 5 on isa
   sbxvo0: <SoundBlaster 16 4.13>
   sbmidi0 at 0x330 on isa
    <SoundBlaster MPU-401>
   opl0 at 0x388 on isa
   opl0: <Yamaha OPL-3 FM>
   

However, if I cat a .au file to /dev/audio0, all I get is a hung 'cat'
command (indicating the IRQ or DRQ or port isn't right yet...)

I've appended the result of running pnpinfo, and my version of
pnp.c (to get the fixes.) If you look toward the top; you'll
find my card's setup (the third one in the list.) The 4th
element in the list is my attempt to try and set up the OPL-3
port...

Note, this card contains an SoundBlaster Pro implementation,
a MIDI port, a game port, an IDE port and OPL-3....

 THanks for any help!

	- Dave Rivers -


--------------------- cut here ----------------------------

The sound-related lines in my config (I also have a "controller pnp0"
in there):

   # Controls all sound devices
   controller      snd0
   device sb0      at isa? port 0x220 irq 5 conflicts drq 1 vector sbintr
   device sbxvi0   at isa? drq 5
   device sbmidi0  at isa? port 0x330
   device opl0     at isa? port 0x388 conflicts


The result of pnpinfo:
   Checking for Plug-n-Play devices...
   Board Vendor ID: CTL0028
   Board Serial Number: 001c4a17
   PnP Version: 1.0
   Vendor Version: 16
   Device Description: Creative SB16 PnP
   Logical Device ID: CTL0031 (31008c0e)
   Register Support 00
   Device Description: Audio
   Start Dependent Function
   Good Configuration
   IRQ: 5 
   DMA: 0 1 
   DMA Stuff: 8
   DMA: 5 
   DMA Stuff: 12
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x220
   I/O Range maximum address: 0x220
   I/O alignment for minimum: 1
   I/O length: 16
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x330
   I/O Range maximum address: 0x330
   I/O alignment for minimum: 1
   I/O length: 2
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x388
   I/O Range maximum address: 0x388
   I/O alignment for minimum: 1
   I/O length: 4
   Start Dependent Function
   Acceptable Configuration
   IRQ: 5 7 10 
   DMA: 0 1 3 
   DMA Stuff: 8
   DMA: 5 6 7 
   DMA Stuff: 12
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x220
   I/O Range maximum address: 0x280
   I/O alignment for minimum: 32
   I/O length: 16
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x300
   I/O Range maximum address: 0x330
   I/O alignment for minimum: 48
   I/O length: 2
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x388
   I/O Range maximum address: 0x388
   I/O alignment for minimum: 1
   I/O length: 4
   Start Dependent Function
   Acceptable Configuration
   IRQ: 5 7 10 
   DMA: 0 1 3 
   DMA Stuff: 8
   DMA: 5 6 7 
   DMA Stuff: 12
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x220
   I/O Range maximum address: 0x280
   I/O alignment for minimum: 32
   I/O length: 16
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x300
   I/O Range maximum address: 0x330
   I/O alignment for minimum: 48
   I/O length: 2
   Start Dependent Function
   Sub-optimal Configuration
   IRQ: 5 7 10 
   DMA: 0 1 3 
   DMA Stuff: 8
   DMA: 5 6 7 
   DMA Stuff: 12
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x220
   I/O Range maximum address: 0x280
   I/O alignment for minimum: 32
   I/O length: 16
   Start Dependent Function
   Sub-optimal Configuration
   IRQ: 5 7 10 
   DMA: 0 1 3 
   DMA Stuff: 8
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x220
   I/O Range maximum address: 0x280
   I/O alignment for minimum: 32
   I/O length: 16
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x300
   I/O Range maximum address: 0x330
   I/O alignment for minimum: 48
   I/O length: 2
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x388
   I/O Range maximum address: 0x388
   I/O alignment for minimum: 1
   I/O length: 4
   Start Dependent Function
   Sub-optimal Configuration
   IRQ: 5 7 10 
   DMA: 0 1 3 
   DMA Stuff: 8
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x220
   I/O Range maximum address: 0x280
   I/O alignment for minimum: 32
   I/O length: 16
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x300
   I/O Range maximum address: 0x330
   I/O alignment for minimum: 48
   I/O length: 2
   Start Dependent Function
   Sub-optimal Configuration
   IRQ: 5 7 10 11 
   DMA: 0 1 3 
   DMA Stuff: 8
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x220
   I/O Range maximum address: 0x280
   I/O alignment for minimum: 32
   I/O length: 16
   End Dependent Function
   Logical Device ID: CTL2011 (11208c0e)
   Register Support 00
   Compatible Device ID: PNP0600 (0006d041)
   Device Description: IDE
   Start Dependent Function
   Good Configuration
   IRQ: 10 
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x168
   I/O Range maximum address: 0x168
   I/O alignment for minimum: 1
   I/O length: 8
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x36e
   I/O Range maximum address: 0x36e
   I/O alignment for minimum: 1
   I/O length: 2
   Start Dependent Function
   Acceptable Configuration
   IRQ: 11 
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x1e8
   I/O Range maximum address: 0x1e8
   I/O alignment for minimum: 1
   I/O length: 8
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x3ee
   I/O Range maximum address: 0x3ee
   I/O alignment for minimum: 1
   I/O length: 2
   Start Dependent Function
   Acceptable Configuration
   IRQ: 10 11 12 15 
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x100
   I/O Range maximum address: 0x1f8
   I/O alignment for minimum: 8
   I/O length: 8
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x300
   I/O Range maximum address: 0x3fe
   I/O alignment for minimum: 2
   I/O length: 2
   Start Dependent Function
   Sub-optimal Configuration
   IRQ: 15 
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x170
   I/O Range maximum address: 0x170
   I/O alignment for minimum: 1
   I/O length: 8
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x376
   I/O Range maximum address: 0x376
   I/O alignment for minimum: 1
   I/O length: 1
   End Dependent Function
   Logical Device ID: PNPffff (ffffd041)
   Register Support 00
   Device Description: Reserved
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x100
   I/O Range maximum address: 0x3f8
   I/O alignment for minimum: 8
   I/O length: 1
   Logical Device ID: CTL7001 (01708c0e)
   Register Support 00
   Compatible Device ID: PNPb02f (2fb0d041)
   Device Description: Game
   Device decodes the full 16-bit ISA address
   I/O Range maximum address: 0x200
   I/O Range maximum address: 0x200
   I/O alignment for minimum: 1
   I/O length: 8
   End Tag


My pnp.c:

/*
 * Copyright (c) 1996, Sujal M. Patel
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Sujal M. Patel
 * 4. Neither the name of the author nor the names of any co-contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      $Id: pnp.c,v 1.5 1996/01/12 20:16:26 smpatel Exp smpatel $
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <machine/clock.h>
#include <machine/cpufunc.h>

#include "pnp.h"


#define SEND(d, r)	outb (ADDRESS, d); outb (WRITE_DATA, r);


/* The READ_DATA port that we are using currently */
static int rd_port;


/*
 * Hard coded for now -- Will need to use resource information from
 * ISA, PCI, and EISA drivers to auto-configure the PnP-devices
 */
static struct cinfo cinfo[] = 
{
	{
		0x00008803, 		/* Serial Number */
		        -1,		/* Logical Device Number */
		{ 15, -1 },		/* IRQ Number */
		{ -1, -1 },		/* DRQ Number */
		{
			0x3e8,		/* Ports 1 */
			   -1,		/* Ports 2 */
			   -1,		/* Ports 3 */
			   -1,		/* Ports 4 */
			   -1,		/* Ports 5 */
			   -1,		/* Ports 6 */
			   -1,		/* Ports 7 */
		}
	},
	{
		0xb1f5acc0, 		/* Serial Number */
		        -1,		/* Logical Device Number */
		{ 11, -1 },		/* IRQ Number */
		{ -1, -1 },		/* DRQ Number */
		{
			0x340,		/* Ports 1 */
			   -1,		/* Ports 2 */
			   -1,		/* Ports 3 */
			   -1,		/* Ports 4 */
			   -1,		/* Ports 5 */
			   -1,		/* Ports 6 */
			   -1,		/* Ports 7 */
		}
	},
	{
		0x001c4a17, 		/* Serial Number */
		 	 0,		/* Logical Device Number */
		{  5, -1 },		/* IRQ Number */
		{  1, -1 },		/* DRQ Number */
		{
			0x220,		/* Ports 1 */
			   -1,		/* Ports 2 */
			   -1,		/* Ports 3 */
			   -1,		/* Ports 4 */
			   -1,		/* Ports 5 */
			   -1,		/* Ports 6 */
			   -1,		/* Ports 7 */
		}
	},
	{
		0x001c4a17, 		/* Serial Number */
		 	 2,		/* Logical Device Number */
		{  -1, -1 },		/* IRQ Number */
		{  -1, -1 },		/* DRQ Number */
		{
			0x388,		/* Ports 1 */
			   -1,		/* Ports 2 */
			   -1,		/* Ports 3 */
			   -1,		/* Ports 4 */
			   -1,		/* Ports 5 */
			   -1,		/* Ports 6 */
			   -1,		/* Ports 7 */
		}
	}
};


int pow __P((int base, int exp));
void send_Initiation_LFSR __P((void));
int get_serial __P((unsigned char *data));
int get_resource_info __P((char *buffer, int len));
int handle_small_res __P((unsigned char *resinfo, int item, int len));
void handle_large_res __P((unsigned char *resinfo, int item, int len));
void config_device __P((unsigned char *data, int csn));
int isolation_protocol __P((void));


int
pow(int base, int exp)
{
	if (exp <= 1)
		return base;
	else
		return base * pow(base, exp - 1);
}


/*
 * Send Initiation LFSR as described in "Plug and Play ISA Specification,
 * Intel May 94."
 */
void
send_Initiation_LFSR()
{
	int cur, i;

	/* Reset the LSFR */
	outb(ADDRESS, 0);
	outb(ADDRESS, 0);

	cur = 0x6a;
	outb(ADDRESS, cur);

	for (i = 1; i < 32; i++) {
		cur = (cur >> 1) | (((cur ^ (cur >> 1)) << 7) & 0xff);
		outb(ADDRESS, cur);
	}
}


/*
 * Get the device's serial number.  Returns 1 if the serial is valid.
 */
int
get_serial(data)
	unsigned char *data;
{
	int i, bit, valid = 0, sum = 0x6a;

	bzero(data, sizeof(char) * 9);

	for (i = 0; i < 72; i++) {
		bit = inb((rd_port << 2) | 0x3) == 0x55;
		DELAY(250);	/* Delay 250 usec */

		/* Can't Short Circuit the next evaluation, so 'and' is last */
		bit = (inb((rd_port << 2) | 0x3) == 0xaa) && bit;
		DELAY(250);	/* Delay 250 usec */

		valid = valid || bit;

		if (i < 64)
			sum = (sum >> 1) |
			    (((sum ^ (sum >> 1) ^ bit) << 7) & 0xff);

		data[i / 8] = (data[i / 8] >> 1) | (bit ? 0x80 : 0);
	}

	valid = valid && (data[8] == sum);

	return valid;
}


/*
 * Dump all the information about configurations.
 */
void
config_device(data, csn)
	unsigned char *data;
	int csn;
{
	struct cinfo *ci;
	int i;

#ifdef DEBUG
	printf("Card assigned CSN #%d\n", csn);
#endif
	printf("Board Vendor ID: %c%c%c%02x%02x",
	    ((data[0] & 0x7c) >> 2) + 64,
	    (((data[0] & 0x03) << 3) | ((data[1] & 0xe0) >> 5)) + 64,
	    (data[1] & 0x1f) + 64, data[2], data[3]);
	printf("     Board Serial Number: %08x\n", *(int *)&(data[4]));

	SEND(SET_CSN, csn); /* Move this out of this function XXX */
	outb(ADDRESS, STATUS);

	for (ci = cinfo; (int)ci < ((int)cinfo + sizeof (cinfo)); ci++) {
		if (ci->serial ==  *(int *)&(data[4])) {
			printf ("Configuring This Card\n");

			if (((int)ci->ldn) >= 0)
				SEND (SET_LDN, ci->ldn);

			for (i = 0; i < 8; i++)
				if (ci->port[i] > 0) {
					SEND (IO_CONFIG_BASE + i * 2,
						ci->port[i] >> 8);
					SEND (IO_CONFIG_BASE + i * 2 + 1,
						ci->port[i] & 0xff);
				}

			for (i = 0; i < 2; i++)
				if (ci->irq[i] > 0) {
					SEND (IRQ_CONFIG + i * 2,
						ci->irq[i]);
				}

			for (i = 0; i < 2; i++)
				if (ci->drq[i] > 0) {
					SEND (DRQ_CONFIG + i,
						ci->drq[i]);
				}
			SEND (IO_RANGE_CHECK, 0);
			SEND (ACTIVATE, 1);
		}
	}
}


/*
 * Run the isolation protocol. Use rd_port as the READ_DATA port value (caller
 * should try multiple READ_DATA locations before giving up). Upon exiting,
 * all cards are aware that they should use rd_port as the READ_DATA port;
 */
int
isolation_protocol()
{
	int csn;
	unsigned char data[9];

	send_Initiation_LFSR();

	/* Reset CSN for All Cards */
	SEND(0x02, 0x04);

	for (csn = 1; (csn < MAX_CARDS); csn++) {
		/* Wake up cards without a CSN */
		SEND(WAKE, 0);
		SEND(SET_RD_DATA, rd_port);
		outb(ADDRESS, SERIAL_ISOLATION);
		DELAY(1000);	/* Delay 1 msec */

		if (get_serial(data))
			config_device(data, csn);
		else
			break;
	}
	return csn - 1;
}


void
pnp_configure()
{
	int num_pnp_devs;

	printf("Checking for Plug-n-Play devices...\n");

	/* Try various READ_DATA ports from 0x203-0x3ff */
	for (rd_port = 0x80; (rd_port < 0xff); rd_port += 0x10) {
#ifdef DEBUG
		printf("Trying Read_Port at %x\n", (rd_port << 2) | 0x3);
#endif
		num_pnp_devs = isolation_protocol();
		if (num_pnp_devs)
			break;
	}
	if (!num_pnp_devs) {
		printf("No Plug-n-Play devices were found\n");
		return;
	}
}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199607010321.XAA00249>