summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshawn <shawn@cvs.openbsd.org>1996-08-11 15:48:56 +0000
committershawn <shawn@cvs.openbsd.org>1996-08-11 15:48:56 +0000
commite31e41944e84283ef4b7e2dee575abb222435c9c (patch)
tree0769b2e54153f8b1cd5de7ecb03c5f6622e73e43
parent2da8eeaa7a58bf7bbe288cae1a6a7a740d0c13fa (diff)
pnpinfo utility from freebsd, the author is Sujal M. Patel.
-rw-r--r--usr.bin/pnpinfo/Makefile8
-rw-r--r--usr.bin/pnpinfo/pnpinfo.858
-rw-r--r--usr.bin/pnpinfo/pnpinfo.c583
-rw-r--r--usr.bin/pnpinfo/pnpinfo.h73
4 files changed, 722 insertions, 0 deletions
diff --git a/usr.bin/pnpinfo/Makefile b/usr.bin/pnpinfo/Makefile
new file mode 100644
index 00000000000..91c10e0f1ca
--- /dev/null
+++ b/usr.bin/pnpinfo/Makefile
@@ -0,0 +1,8 @@
+# $OpenBSD: Makefile,v 1.1 1996/08/11 15:48:55 shawn Exp $
+
+PROG= pnpinfo
+CFLAGS+= -Wall
+MAN= pnpinfo.8
+LDADD= -li386
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/pnpinfo/pnpinfo.8 b/usr.bin/pnpinfo/pnpinfo.8
new file mode 100644
index 00000000000..9e1208c0343
--- /dev/null
+++ b/usr.bin/pnpinfo/pnpinfo.8
@@ -0,0 +1,58 @@
+.\" $OpenBSD: pnpinfo.8,v 1.1 1996/08/11 15:48:55 shawn Exp $
+.\" 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.
+.\"
+.Dd January 7, 1996
+.Dt PNPINFO 8
+.Os
+.Sh NAME
+.Nm pnpinfo
+.Nd "Reports information about Plug-n-Play ISA devices"
+.Sh SYNOPSIS
+.Nm pnpinfo
+.Sh DESCRIPTION
+.Nm pnpinfo
+reports information about Plug-n-Play ISA devices. Some of the information,
+such as the vendor ID, serial number, I/O ports, IRQ, etc. are useful when
+configuring a kernel with ISA PnP devices.
+.Sh BUGS
+A few of the tags are unimplemented (Enough exist for 99% of PnP cards).
+.Sh SEE ALSO
+.Xr pnp 4
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Tn FreeBSD
+2.2.
+.Sh AUTHOR
+.Bl -tag
+Sujal M. Patel, smpatel@umiacs.umd.edu
+.El
diff --git a/usr.bin/pnpinfo/pnpinfo.c b/usr.bin/pnpinfo/pnpinfo.c
new file mode 100644
index 00000000000..40ef429f655
--- /dev/null
+++ b/usr.bin/pnpinfo/pnpinfo.c
@@ -0,0 +1,583 @@
+/* $OpenBSD: pnpinfo.c,v 1.1 1996/08/11 15:48:55 shawn Exp $ */
+/*
+ * 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.
+ *
+ * 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.
+ */
+
+#include <sys/time.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <machine/cpufunc.h>
+
+#if defined(__OpenBSD__)
+#include <i386/sysarch.h>
+#include <machine/pio.h>
+#endif
+
+#include "pnpinfo.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;
+
+
+void DELAY __P((int i));
+int power __P((int base, int exp));
+void send_Initiation_LFSR();
+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 dump_resdata __P((unsigned char *data, int csn));
+int isolation_protocol();
+
+
+/*
+ * DELAY does accurate delaying in user-space.
+ * This function busy-waits.
+ */
+void
+DELAY (i)
+ int i;
+{
+ struct timeval t;
+ long start, stop;
+
+ gettimeofday (&t, NULL);
+ start = t.tv_sec * 1000000 + t.tv_usec;
+ do {
+ gettimeofday (&t, NULL);
+ stop = t.tv_sec * 1000000 + t.tv_usec;
+ } while (start + i > stop);
+}
+
+
+int
+power(base, exp)
+ int base, exp;
+{
+ if (exp <= 1)
+ return base;
+ else
+ return base * power(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;
+}
+
+
+/*
+ * Fill's the buffer with resource info from the device.
+ * Returns 0 if the device fails to report
+ */
+int
+get_resource_info(buffer, len)
+ char *buffer;
+ int len;
+{
+ int i, j;
+
+ for (i = 0; i < len; i++) {
+ outb(ADDRESS, STATUS);
+ for (j = 0; j < 100; j++) {
+ if ((inb((rd_port << 2) | 0x3)) & 0x1)
+ break;
+ DELAY(1);
+ }
+ if (j == 100) {
+ printf("PnP device failed to report resource data\n");
+ return 0;
+ }
+ outb(ADDRESS, RESOURCE_DATA);
+ buffer[i] = inb((rd_port << 2) | 0x3);
+ }
+ return 1;
+}
+
+
+void
+report_dma_info (x)
+ int x;
+{
+ switch (x & 0x3) {
+ case 0:
+ printf ("DMA: 8-bit only\n");
+ break;
+ case 1:
+ printf ("DMA: 8-bit and 16-bit\n");
+ break;
+ case 2:
+ printf ("DMA: 16-bit only\n");
+ break;
+#ifdef DIAGNOSTIC
+ case 3:
+ printf ("DMA: Reserved\n");
+ break;
+#endif
+ }
+
+ if (x & 0x4)
+ printf ("DMA: Device is a bus master\n");
+ else
+ printf ("DMA: Device is not a bus master\n");
+
+ if (x & 0x8)
+ printf ("DMA: May execute in count by byte mode\n");
+ else
+ printf ("DMA: May not execute in count by byte mode\n");
+
+ if (x & 0x10)
+ printf ("DMA: May execute in count by word mode\n");
+ else
+ printf ("DMA: May not execute in count by word mode\n");
+
+ switch ((x & 0x60) >> 5) {
+ case 0:
+ printf ("DMA: Compatibility mode\n");
+ break;
+ case 1:
+ printf ("DMA: Type A DMA channel\n");
+ break;
+ case 2:
+ printf ("DMA: Type B DMA channel\n");
+ break;
+ case 3:
+ printf ("DMA: Type F DMA channel\n");
+ break;
+ }
+}
+
+
+void
+report_memory_info (x)
+ int x;
+{
+ if (x & 0x1)
+ printf ("Memory Range: Writeable\n");
+ else
+ printf ("Memory Range: Not writeable (ROM)\n");
+
+ if (x & 0x2)
+ printf ("Memory Range: Read-cacheable, write-through\n");
+ else
+ printf ("Memory Range: Non-cacheable\n");
+
+ if (x & 0x4)
+ printf ("Memory Range: Decode supports high address\n");
+ else
+ printf ("Memory Range: Decode supports range length\n");
+
+ switch ((x & 0x18) >> 3) {
+ case 0:
+ printf ("Memory Range: 8-bit memory only\n");
+ break;
+ case 1:
+ printf ("Memory Range: 16-bit memory only\n");
+ break;
+ case 2:
+ printf ("Memory Range: 8-bit and 16-bit memory supported\n");
+ break;
+#ifdef DIAGNOSTIC
+ case 3:
+ printf ("Memory Range: Reserved\n");
+ break;
+#endif
+ }
+
+ if (x & 0x20)
+ printf ("Memory Range: Memory is shadowable\n");
+ else
+ printf ("Memory Range: Memory is not shadowable\n");
+
+ if (x & 0x40)
+ printf ("Memory Range: Memory is an expansion ROM\n");
+ else
+ printf ("Memory Range: Memory is not an expansion ROM\n");
+
+#ifdef DIAGNOSTIC
+ if (x & 0x80)
+ printf ("Memory Range: Reserved (Device is brain-damaged)\n");
+#endif
+}
+
+
+/*
+ * Small Resource Tag Handler
+ *
+ * Returns 1 if checksum was valid (and an END_TAG was received).
+ * Returns -1 if checksum was invalid (and an END_TAG was received).
+ * Returns 0 for other tags.
+ */
+int
+handle_small_res(resinfo, item, len)
+ int item, len;
+ unsigned char *resinfo;
+{
+ int i;
+
+ switch (item) {
+ case PNP_VERSION:
+ printf("PnP Version: %d.%d\n",
+ resinfo[0] >> 4,
+ resinfo[0] & (0xf));
+ printf("Vendor Version: %d\n", resinfo[1]);
+ break;
+ case LOG_DEVICE_ID:
+ printf("Logical Device ID: %c%c%c%02x%02x (%08x)\n",
+ ((resinfo[0] & 0x7c) >> 2) + 64,
+ (((resinfo[0] & 0x03) << 3) |
+ ((resinfo[1] & 0xe0) >> 5)) + 64,
+ (resinfo[1] & 0x1f) + 64,
+ resinfo[2], resinfo[3], *(int *)resinfo);
+
+ if (resinfo[4] & 0x1)
+ printf ("Device powers up active\n");
+ if (resinfo[4] & 0x2)
+ printf ("Device supports I/O Range Check\n");
+ if (resinfo[4] > 0x3)
+ printf ("Reserved register funcs %02x\n",
+ resinfo[4]);
+
+ if (len == 6)
+ printf("Vendor register funcs %02x\n", resinfo[5]);
+ break;
+ case COMP_DEVICE_ID:
+ printf("Compatible Device ID: %c%c%c%02x%02x (%08x)\n",
+ ((resinfo[0] & 0x7c) >> 2) + 64,
+ (((resinfo[0] & 0x03) << 3) |
+ ((resinfo[1] & 0xe0) >> 5)) + 64,
+ (resinfo[1] & 0x1f) + 64,
+ resinfo[2], resinfo[3], *(int *)resinfo);
+ break;
+ case IRQ_FORMAT:
+ printf("IRQ: ");
+
+ for (i = 0; i < 8; i++)
+ if (resinfo[0] & (char) (power(2, i)))
+ printf("%d ", i);
+ for (i = 0; i < 8; i++)
+ if (resinfo[1] & (char) (power(2, i)))
+ printf("%d ", i + 8);
+ printf("\n");
+ if (len == 3) {
+ if (resinfo[2] & 0x1)
+ printf("IRQ: High true edge sensitive\n");
+ if (resinfo[2] & 0x2)
+ printf("IRQ: Low true edge sensitive\n");
+ if (resinfo[2] & 0x4)
+ printf("IRQ: High true level sensitive\n");
+ if (resinfo[2] & 0x8)
+ printf("IRQ: Low true level sensitive\n");
+ }
+ break;
+ case DMA_FORMAT:
+ printf("DMA: ");
+ for (i = 0; i < 8; i++)
+ if (resinfo[0] & (char) (power(2, i)))
+ printf("%d ", i);
+ printf ("\n");
+ report_dma_info (resinfo[1]);
+ break;
+ case START_DEPEND_FUNC:
+ printf("Start Dependent Function\n");
+ if (len == 1) {
+ switch (resinfo[0]) {
+ case 0:
+ printf("Good Configuration\n");
+ break;
+ case 1:
+ printf("Acceptable Configuration\n");
+ break;
+ case 2:
+ printf("Sub-optimal Configuration\n");
+ break;
+ }
+ }
+ break;
+ case END_DEPEND_FUNC:
+ printf("End Dependent Function\n");
+ break;
+ case IO_PORT_DESC:
+ if (resinfo[0])
+ printf("Device decodes the full 16-bit ISA address\n");
+ else
+ printf("Device does not decode the full 16-bit ISA address\n");
+ printf("I/O Range maximum address: 0x%x\n",
+ resinfo[1] + (resinfo[2] << 8));
+ printf("I/O Range maximum address: 0x%x\n",
+ resinfo[3] + (resinfo[4] << 8));
+ printf("I/O alignment for minimum: %d\n",
+ resinfo[5]);
+ printf("I/O length: %d\n", resinfo[6]);
+ break;
+ case FIXED_IO_PORT_DESC:
+ printf ("I/O Range base address: 0x%x\n",
+ resinfo[1] + (resinfo[2] << 8));
+ printf("I/O length: %d\n", resinfo[3]);
+ break;
+#ifdef DIAGNOSTIC
+ case SM_RES_RESERVED:
+ printf("Reserved Tag Detected\n");
+ break;
+#endif
+ case SM_VENDOR_DEFINED:
+ printf("*** Small Vendor Tag Detected\n");
+ break;
+ case END_TAG:
+ printf("End Tag\n\n");
+ /* XXX Record and Verify Checksum */
+ return 1;
+ break;
+ }
+ return 0;
+}
+
+
+void
+handle_large_res(resinfo, item, len)
+ int item, len;
+ unsigned char *resinfo;
+{
+ int i;
+
+ switch (item) {
+ case MEMORY_RANGE_DESC:
+ report_memory_info(resinfo[0]);
+ printf("Memory range minimum address: 0x%x\n",
+ (resinfo[1] << 8) + (resinfo[2] << 16));
+ printf("Memory range maximum address: 0x%x\n",
+ (resinfo[3] << 8) + (resinfo[4] << 16));
+ printf("Memory range base alignment: 0x%x\n",
+ (i = (resinfo[5] + (resinfo[6] << 8))) ? i : (1 << 16));
+ printf("Memory range length: 0x%x\n",
+ (resinfo[7] + (resinfo[8] << 8)) * 256);
+ break;
+ case ID_STRING_ANSI:
+ printf("Device Description: ");
+
+ for (i = 0; i < len; i++) {
+ printf("%c", resinfo[i]);
+ }
+ printf("\n");
+ break;
+ case ID_STRING_UNICODE:
+ printf("ID String Unicode Detected (Undefined)\n");
+ break;
+ case LG_VENDOR_DEFINED:
+ printf("Large Vendor Defined Detected\n");
+ break;
+ case _32BIT_MEM_RANGE_DESC:
+ printf("32bit Memory Range Desc Unimplemented\n");
+ break;
+ case _32BIT_FIXED_LOC_DESC:
+ printf("32bit Fixed Location Desc Unimplemented\n");
+ break;
+ case LG_RES_RESERVED:
+ printf("Large Reserved Tag Detected\n");
+ break;
+ }
+}
+
+
+/*
+ * Dump all the information about configurations.
+ */
+void
+dump_resdata(data, csn)
+ unsigned char *data;
+ int csn;
+{
+ int i, large_len;
+ unsigned char tag, *resinfo;
+
+#ifdef DEBUG
+ printf("Card assigned CSN #%d\n", csn);
+#endif
+ printf("Board Vendor ID: %c%c%c%02x%02x\n",
+ ((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);
+
+ /* Allows up to 1kb of Resource Info, Should be plenty */
+ for (i = 0; i < 1024; i++) {
+ if (!get_resource_info(&tag, 1))
+ return;
+
+#define TYPE (tag >> 7)
+#define S_ITEM (tag >> 3)
+#define S_LEN (tag & 0x7)
+#define L_ITEM (tag & 0x7f)
+
+ if (TYPE == 0) {
+ /* Handle small resouce data types */
+
+ resinfo = malloc(S_LEN);
+ if (!get_resource_info(resinfo, S_LEN))
+ return;
+
+ if (handle_small_res(resinfo, S_ITEM, S_LEN) == 1)
+ return;
+ free(resinfo);
+ } else {
+ /* Handle large resouce data types */
+
+ if (!get_resource_info((char *) &large_len, 2))
+ return;
+
+ resinfo = malloc(large_len);
+ if (!get_resource_info(resinfo, large_len))
+ return;
+
+ handle_large_res(resinfo, L_ITEM, large_len);
+ free(resinfo);
+ }
+ }
+}
+
+
+/*
+ * 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))
+ dump_resdata(data, csn);
+ else
+ break;
+ }
+ return csn - 1;
+}
+
+
+void
+main()
+{
+ int num_pnp_devs;
+
+#if defined(__OpenBSD__)
+ if (i386_iopl(1)) {
+ perror("i386_iopl");
+ exit(1);
+ }
+#endif
+ 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(rd_port);
+ if (num_pnp_devs)
+ break;
+ }
+ if (!num_pnp_devs) {
+ printf("No Plug-n-Play devices were found\n");
+ return;
+ }
+}
diff --git a/usr.bin/pnpinfo/pnpinfo.h b/usr.bin/pnpinfo/pnpinfo.h
new file mode 100644
index 00000000000..8e5a664fcba
--- /dev/null
+++ b/usr.bin/pnpinfo/pnpinfo.h
@@ -0,0 +1,73 @@
+/* $OpenBSD: pnpinfo.h,v 1.1 1996/08/11 15:48:55 shawn Exp $ */
+/*
+ * 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.
+ */
+
+
+/* Maximum Number of PnP Devices. 6 should be plenty */
+#define MAX_CARDS 6
+
+
+/* Static ports */
+#define ADDRESS 0x279
+#define WRITE_DATA 0xa79
+
+
+/* PnP Registers. Write to ADDRESS and then use WRITE/READ_DATA */
+#define SET_RD_DATA 0x00
+#define SERIAL_ISOLATION 0x01
+#define WAKE 0x03
+#define RESOURCE_DATA 0x04
+#define STATUS 0x05
+#define SET_CSN 0x06
+
+/* Small Resource Item names */
+#define PNP_VERSION 0x1
+#define LOG_DEVICE_ID 0x2
+#define COMP_DEVICE_ID 0x3
+#define IRQ_FORMAT 0x4
+#define DMA_FORMAT 0x5
+#define START_DEPEND_FUNC 0x6
+#define END_DEPEND_FUNC 0x7
+#define IO_PORT_DESC 0x8
+#define FIXED_IO_PORT_DESC 0x9
+#define SM_RES_RESERVED 0xa-0xd
+#define SM_VENDOR_DEFINED 0xe
+#define END_TAG 0xf
+
+/* Large Resource Item names */
+#define MEMORY_RANGE_DESC 0x1
+#define ID_STRING_ANSI 0x2
+#define ID_STRING_UNICODE 0x3
+#define LG_VENDOR_DEFINED 0x4
+#define _32BIT_MEM_RANGE_DESC 0x5
+#define _32BIT_FIXED_LOC_DESC 0x6
+#define LG_RES_RESERVED 0x7-0x7f