From owner-freebsd-hackers Mon Jul 1 05:50:48 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id FAA24972 for hackers-outgoing; Mon, 1 Jul 1996 05:50:48 -0700 (PDT) Received: from dg-rtp.dg.com (dg-rtp.rtp.dg.com [128.222.1.2]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id FAA24964 for ; Mon, 1 Jul 1996 05:50:42 -0700 (PDT) Received: by dg-rtp.dg.com (5.4R3.10/dg-rtp-v02) id AA00032; Mon, 1 Jul 1996 08:50:06 -0400 Received: from ponds by dg-rtp.dg.com.rtp.dg.com; Mon, 1 Jul 1996 08:50 EDT Received: from lakes (lakes [192.96.3.39]) by ponds.UUCP (8.6.12/8.6.5) with ESMTP id XAA01618; Sun, 30 Jun 1996 23:18:24 -0400 Received: (from rivers@localhost) by lakes (8.6.12/8.6.9) id XAA00249; Sun, 30 Jun 1996 23:21:20 -0400 Date: Sun, 30 Jun 1996 23:21:20 -0400 From: Thomas David Rivers Message-Id: <199607010321.XAA00249@lakes> 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?) Content-Type: text Sender: owner-hackers@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk 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 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: sbxvi0 at 0x0 drq 5 on isa sbxvo0: sbmidi0 at 0x330 on isa opl0 at 0x388 on isa opl0: 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 #include #include #include #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; } }