aboutsummaryrefslogtreecommitdiff
path: root/sys/pci
diff options
context:
space:
mode:
authorDavid Greenman <dg@FreeBSD.org>1995-02-02 13:12:18 +0000
committerDavid Greenman <dg@FreeBSD.org>1995-02-02 13:12:18 +0000
commit6398cf311391af65694520c14dd5fd802fda9806 (patch)
tree8d1b00d546148364ba291540f1d0241cc58fde5e /sys/pci
parent77e50733d821b6eaaece214ce20890dda262cf92 (diff)
downloadsrc-6398cf311391af65694520c14dd5fd802fda9806.tar.gz
src-6398cf311391af65694520c14dd5fd802fda9806.zip
Reapplied all of Stefan's changes. What a mess - the files were modified
and moved at the same time. This made it *very* difficult to fix the revision log lossage that happend when the files were moved. SIGH.
Notes
Notes: svn path=/head/; revision=6132
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/aic7870.c8
-rw-r--r--sys/pci/if_de.c15
-rw-r--r--sys/pci/ncr.c192
-rw-r--r--sys/pci/ncrreg.h3
-rw-r--r--sys/pci/pci.c313
-rw-r--r--sys/pci/pcireg.h287
-rw-r--r--sys/pci/pcisupport.c25
7 files changed, 380 insertions, 463 deletions
diff --git a/sys/pci/aic7870.c b/sys/pci/aic7870.c
index 6c565faf7546..edac4a2c3dfa 100644
--- a/sys/pci/aic7870.c
+++ b/sys/pci/aic7870.c
@@ -19,7 +19,7 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: aic7870.c,v 1.3 1995/01/22 00:47:50 gibbs Exp $
+ * $Id: aic7870.c,v 1.4 1995/02/02 12:36:14 davidg Exp $
*/
#include <pci.h>
@@ -29,6 +29,7 @@
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
#include <pci/pcireg.h>
+#include <pci/pcivar.h>
#include <i386/scsi/aic7xxx.h>
#define PCI_BASEADR0 PCI_MAP_REG_START
@@ -40,12 +41,15 @@ void aic7870_attach __P((pcici_t config_id, int unit));
static u_long aic7870_count;
-struct pci_driver ahc_device = {
+struct pci_device ahc_device = {
+ "ahc",
aic7870_probe,
aic7870_attach,
&aic7870_count
};
+DATA_SET (pcidevice_set, ahc_device);
+
static char*
aic7870_probe (pcici_t tag, pcidi_t type)
{
diff --git a/sys/pci/if_de.c b/sys/pci/if_de.c
index 78840277c40e..c7887a23d7da 100644
--- a/sys/pci/if_de.c
+++ b/sys/pci/if_de.c
@@ -21,7 +21,7 @@
* (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: if_de.c,v 1.13 1994/12/22 23:42:25 davidg Exp $
+ * $Id: if_de.c,v 1.14 1995/02/02 12:36:15 davidg Exp $
*
*/
@@ -46,6 +46,8 @@
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <machine/clock.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -78,9 +80,9 @@
#include <pci.h>
#if NPCI > 0
-#include <pci/pcireg.h>
+#include <pci/pcivar.h>
#endif
-#include <i386/isa/icu.h>
+
#include <pci/dc21040.h>
/*
@@ -840,6 +842,8 @@ tulip_addr_filter(
}
}
+/*extern void arp_ifinit(struct arpcom *, struct ifaddr*);*/
+
static int
tulip_ioctl(
struct ifnet *ifp,
@@ -1041,12 +1045,15 @@ static char* tulip_pci_probe (pcici_t config_id, pcidi_t device_id);
static void tulip_pci_attach(pcici_t config_id, int unit);
static u_long tulip_count;
-struct pci_driver dedevice = {
+struct pci_device dedevice = {
+ "de",
tulip_pci_probe,
tulip_pci_attach,
&tulip_count,
};
+DATA_SET (pcidevice_set, dedevice);
+
#define PCI_CFID 0x00 /* Configuration ID */
#define PCI_CFCS 0x04 /* Configurtion Command/Status */
#define PCI_CFRV 0x08 /* Configuration Revision */
diff --git a/sys/pci/ncr.c b/sys/pci/ncr.c
index bf6ab03934dc..d21664c3761a 100644
--- a/sys/pci/ncr.c
+++ b/sys/pci/ncr.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: ncr.c,v 1.14 1995/01/12 14:01:13 se Exp $
+** $Id: ncr.c,v 1.15 1995/02/02 12:36:16 davidg Exp $
**
** Device driver for the NCR 53C810 PCI-SCSI-Controller.
**
@@ -44,15 +44,21 @@
***************************************************************************
*/
+#define NCR_PATCHLEVEL "pl4 95/01/27"
+
#define NCR_VERSION (2)
#define MAX_UNITS (16)
+#ifndef LDSC
+ /* belongs to sstat2 in ncrreg.h */
+ #define LDSC 0x02 /* sta: disconnect & reconnect */
+#endif
/*==========================================================
**
** Configuration and Debugging
**
-** May be overwritten in <i386/conf/XXXXX>
+** May be overwritten in <arch/conf/XXXXX>
**
**==========================================================
*/
@@ -139,12 +145,6 @@
*/
#define MAX_SIZE ((MAX_SCATTER-1) * NBPG)
-
-/*
-** Write disk status information to dkstat ?
-*/
-
-/* #define DK */
/*==========================================================
**
@@ -163,19 +163,23 @@
#include <sys/malloc.h>
#include <sys/buf.h>
#include <sys/kernel.h>
-#ifdef DK
-#include <sys/dkstat.h>
-#endif /* DK */
+#ifndef __NetBSD__
+#include <machine/clock.h>
+#endif
#include <vm/vm.h>
#endif /* KERNEL */
-#include <pci/ncrreg.h>
-#ifdef __NetBSD__
+#ifndef __NetBSD__
+#include <pci/pcivar.h>
+#include <pci/pcireg.h>
+#include <pci/ncrreg.h>
+#else
#include <sys/device.h>
+#include <i386/pci/ncrreg.h>
#include <i386/pci/pcivar.h>
+#include <i386/pci/pcireg.h>
#endif /* __NetBSD */
-#include <pci/pcireg.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
@@ -1152,7 +1156,7 @@ struct script {
ncrcmd data_in [MAX_SCATTER * 4 + 7];
ncrcmd data_out [MAX_SCATTER * 4 + 7];
ncrcmd aborttag [ 4];
- ncrcmd abort [ 20];
+ ncrcmd abort [ 22];
ncrcmd snooptest [ 11];
};
@@ -1222,7 +1226,7 @@ static void ncr_attach (pcici_t tag, int unit);
static char ident[] =
- "\n$Id: ncr.c,v 1.14 1995/01/12 14:01:13 se Exp $\n";
+ "\n$Id: ncr.c,v 1.15 1995/02/02 12:36:16 davidg Exp $\n";
u_long ncr_version = NCR_VERSION
+ (u_long) sizeof (struct ncb)
@@ -1258,7 +1262,6 @@ static u_char rs_cmd [6] =
*/
#define NCR_810_ID (0x00011000ul)
-#define NCR_815_ID (0x00041000ul)
#define NCR_825_ID (0x00031000ul)
#ifdef __NetBSD__
@@ -1271,12 +1274,15 @@ struct cfdriver ncrcd = {
static u_long ncr_count;
-struct pci_driver ncr_device = {
+struct pci_device ncr_device = {
+ "ncr",
ncr_probe,
ncr_attach,
&ncr_count
};
+DATA_SET (pcidevice_set, ncr_device);
+
#endif /* !__NetBSD__ */
#ifndef ANCIENT
@@ -2345,7 +2351,8 @@ static struct script script0 = {
/*
** DISCONNECTing ...
**
- ** Disable the "unexpected disconnect" feature.
+ ** disable the "unexpected disconnect" feature,
+ ** and remove the ACK signal.
*/
SCR_REG_REG (scntl2, SCR_AND, 0x7f),
0,
@@ -2383,8 +2390,6 @@ static struct script script0 = {
}/*-------------------------< MSG_OUT >-------------------*/,{
/*
** The target requests a message.
- ** First remove ATN so the target will
- ** not continue fetching messages.
*/
SCR_MOVE_ABS (1) ^ SCR_MSG_OUT,
NADDR (msgout),
@@ -2824,6 +2829,8 @@ static struct script script0 = {
SCR_COPY (1),
RADDR (sfbr),
NADDR (lastmsg),
+ SCR_CLR (SCR_ACK),
+ 0,
SCR_WAIT_DISC,
0,
SCR_JUMP,
@@ -3119,7 +3126,6 @@ ncr_probe(parent, self, aux)
if (!pci_targmatch(cf, pa))
return 0;
if (pa->pa_id != NCR_810_ID &&
- pa->pa_id != NCR_815_ID &&
pa->pa_id != NCR_825_ID)
return 0;
@@ -3136,9 +3142,6 @@ static char* ncr_probe (pcici_t tag, pcidi_t type)
case NCR_810_ID:
return ("ncr 53c810 scsi");
- case NCR_815_ID:
- return ("ncr 53c815 scsi");
-
case NCR_825_ID:
return ("ncr 53c825 wide scsi");
}
@@ -3247,7 +3250,6 @@ static void ncr_attach (pcici_t config_id, int unit)
case NCR_810_ID:
np->maxwide = 0;
break;
- case NCR_815_ID:
case NCR_825_ID:
np->maxwide = 1;
break;
@@ -3296,6 +3298,31 @@ static void ncr_attach (pcici_t config_id, int unit)
OUTB (nc_istat, SRST);
OUTB (nc_istat, 0 );
+#ifdef NCR_DUMP_REG
+ /*
+ ** Log the initial register contents
+ */
+ {
+ int reg;
+#ifdef __NetBSD__
+ u_long config_id = pa->pa_tag;
+#endif
+ for (reg=0; reg<256; reg+=4) {
+ if (reg%16==0) printf ("reg[%2x]", reg);
+ printf (" %08x", (int)pci_conf_read (config_id, reg));
+ if (reg%16==12) printf ("\n");
+ }
+ }
+
+ /*
+ ** Reset chip, once again.
+ */
+
+ OUTB (nc_istat, SRST);
+ OUTB (nc_istat, 0 );
+
+#endif NCR_DUMP_REG
+
/*
** Now check the cache handling of the pci chipset.
*/
@@ -3333,8 +3360,12 @@ static void ncr_attach (pcici_t config_id, int unit)
ncr_name (np));
DELAY (1000000);
#endif
- printf ("%s scanning for targets 0..%d ($Revision: 1.14 $)\n",
- ncr_name (np), MAX_TARGET-1);
+#ifdef NCR_PATCHLEVEL
+ printf ("%s scanning for targets 0..%d (V%d " NCR_PATCHLEVEL ")\n",
+#else
+ printf ("%s scanning for targets 0..%d (V%d)\n",
+#endif
+ ncr_name (np), MAX_TARGET-1, NCR_VERSION);
/*
** Now let the generic SCSI driver
@@ -3668,7 +3699,22 @@ static INT32 ncr_start (struct scsi_xfer * xp)
**----------------------------------------------------
*/
- idmsg = (cp==&np->ccb ? 0x80 : 0xc0) | xp->LUN;
+#ifndef NCR_NO_DISCONNECT
+ idmsg = (cp==&np->ccb ? M_IDENTIFY : 0xc0) | xp->LUN;
+#else
+ /*---------------------------------------------------------------------
+ ** Some users have problems with this driver.
+ ** I assume that the current problems relate to a conflict between
+ ** a disconnect and an immediately following reconnect operation.
+ ** With this option you can prevent the driver from using disconnects.
+ ** If this removes the problems, I would know where to search further..
+ ** Of course this is no solution.
+ ** Without disconnects the performance will be severely degraded.
+ ** But it may help to trace down the core problem.
+ **---------------------------------------------------------------------
+ */
+ idmsg = M_IDENTIFY | xp->LUN;
+#endif
cp -> scsi_smsg [0] = idmsg;
msglen=1;
@@ -3957,7 +4003,7 @@ void ncr_complete (ncb_p np, ccb_p cp)
** Sanity check
*/
- if (!cp || !cp->magic || !cp->xfer) return;
+ if (!cp || (cp->magic!=CCB_MAGIC) || !cp->xfer) return;
cp->magic = 1;
cp->tlimit= 0;
@@ -4084,12 +4130,6 @@ void ncr_complete (ncb_p np, ccb_p cp)
ncr_opennings (np, lp, xp);
};
-#ifdef DK
- dk_xfer[DK] ++;
- dk_wds [DK] += xp->datalen/64;
- dk_wpms[DK] = 1000000;
-#endif /* DK */
-
tp->bytes += xp->datalen;
tp->transfers ++;
@@ -4306,7 +4346,7 @@ void ncr_init (ncb_p np, char * msg, u_long code)
OUTB (nc_scntl0, 0xca ); /* full arb., ena parity, par->ATN */
OUTB (nc_scntl1, 0x00 ); /* odd parity, and remove CRST!! */
OUTB (nc_scntl3, np->rv_scntl3);/* timing prescaler */
- OUTB (nc_scid , 0x40|np->myaddr);/* host adapter SCSI address */
+ OUTB (nc_scid , RRE|np->myaddr);/* host adapter SCSI address */
OUTW (nc_respid, 1ul<<np->myaddr);/* id to respond to */
OUTB (nc_istat , SIGP ); /* Signal Process */
OUTB (nc_dmode , 0xc0 ); /* Burst length = 16 transfer */
@@ -4684,6 +4724,10 @@ static void ncr_timeout (ncb_p np)
ccb_p cp;
if (np->lasttime != thistime) {
+ /*
+ ** block ncr interupts
+ */
+ int oldspl = splbio();
np->lasttime = thistime;
ncr_usercmd (np);
@@ -4781,12 +4825,9 @@ static void ncr_timeout (ncb_p np)
/*
** wakeup this ccb.
*/
- {
- int oldspl = splbio();
- ncr_complete (np, cp);
- splx (oldspl);
- };
+ ncr_complete (np, cp);
};
+ splx (oldspl);
}
timeout (TIMEOUT ncr_timeout, (caddr_t) np, step ? step : 1);
@@ -4819,6 +4860,7 @@ void ncr_exception (ncb_p np)
u_char istat, dstat;
u_short sist;
u_long dsp;
+ int i;
/*
** interrupt on the fly ?
@@ -4935,13 +4977,47 @@ void ncr_exception (ncb_p np)
np->regdump.nc_dstat = dstat;
np->regdump.nc_sist = sist;
};
+
+ /*=========================================
+ ** log message for real hard errors
+ **=========================================
- printf ("%s targ %d?: ERROR (%x:%x:%x) (%x/%x) @ (%x:%x).\n",
+ "ncr0 targ 0?: ERROR (ds:si) (so-si-sd) (sxfer/scntl3) @ (dsp:dbc)."
+ " reg: r0 r1 r2 r3 r4 r5 r6 ..... rf."
+
+ exception register:
+ ds: dstat
+ si: sist
+
+ SCSI bus lines:
+ so: control lines as driver by NCR.
+ si: control lines as seen by NCR.
+ sd: scsi data lines as seen by NCR.
+
+ wide/fastmode:
+ sxfer: (see the manual)
+ scntl3: (see the manual)
+
+ current script command:
+ dsp: script adress (relative to start of script).
+ dbc: first word of script command.
+
+ First 16 register of the chip:
+ r0..rf
+
+ =============================================
+ */
+
+ printf ("%s targ %d?: ERROR (%x:%x) (%x-%x-%x) (%x/%x) @ (%x:%x).\n",
ncr_name (np), INB (nc_ctest0)&7, dstat, sist,
- INB (nc_sbcl),
+ INB (nc_socl), INB (nc_sbcl), INB (nc_sbdl),
INB (nc_sxfer),INB (nc_scntl3),
- (unsigned) (dsp = INL (nc_dsp)),
+ ((unsigned) (dsp = INL (nc_dsp))) - (unsigned) np->p_script,
(unsigned) INL (nc_dbc));
+ printf (" reg:");
+ for (i=0; i<16;i++)
+ printf (" %x", ((u_char*)np->reg)[i]);
+ printf (".\n");
/*----------------------------------------
** clean up the dma fifo
@@ -4980,15 +5056,27 @@ void ncr_exception (ncb_p np)
!(dstat & (MDPE|BF|ABRT|SIR)) &&
((INL(nc_dbc) & 0xf8000000) == SCR_WAIT_DISC)) {
/*
- ** Data cycles while waiting for disconnect.
- ** Force disconnect.
+ ** Unexpected data cycle while waiting for disconnect.
*/
- OUTB (nc_scntl1, 0);
+ if (INB(nc_sstat2) & LDSC) {
+ /*
+ ** It's an early reconnect.
+ ** Let's continue ...
+ */
+ OUTB (nc_dcntl, (STD|NOCOM));
+ /*
+ ** info message
+ */
+ printf ("%s: XXX INFO: LDSC while IID.\n",
+ ncr_name (np));
+ return;
+ };
+ printf ("%s: target %d? doesn't release the bus.\n",
+ ncr_name (np), INB (nc_ctest0)&7);
/*
- ** System may hang, but timeout will handle that.
- ** In fact, timeout can handle ALL problems :-)
+ ** return without restarting the NCR.
+ ** timeout will do the real work.
*/
- OUTB (nc_dcntl, (STD|NOCOM));
return;
};
@@ -5914,7 +6002,7 @@ static ccb_p ncr_get_ccb
while (cp->magic) {
if (flags & SCSI_NOSLEEP) break;
- if (tsleep ((caddr_t)cp, PZERO|PCATCH, "ncr", 0))
+ if (tsleep ((caddr_t)cp, PRIBIO|PCATCH, "ncr", 0))
break;
};
diff --git a/sys/pci/ncrreg.h b/sys/pci/ncrreg.h
index 1a22aee38d24..d5800612a5ed 100644
--- a/sys/pci/ncrreg.h
+++ b/sys/pci/ncrreg.h
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: ncrreg.h,v 2.3 94/10/09 21:10:34 wolf Oct11 $
+** $Id: ncrreg.h,v 1.1 1994/10/12 02:21:56 se Exp $
**
** Device driver for the NCR 53C810 PCI-SCSI-Controller.
**
@@ -123,6 +123,7 @@ struct ncr_reg {
#define ILF1 0x80 /* sta: data in SIDL register msb[W]*/
#define ORF1 0x40 /* sta: data in SODR register msb[W]*/
#define OLF1 0x20 /* sta: data in SODL register msb[W]*/
+ #define LDSC 0x02 /* sta: disconnect & reconnect */
/*10*/ u_long nc_dsa; /* --> Base page */
diff --git a/sys/pci/pci.c b/sys/pci/pci.c
index 8bbd36ea3eae..61e546f68986 100644
--- a/sys/pci/pci.c
+++ b/sys/pci/pci.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: pci.c,v 1.9 1994/11/02 23:47:13 se Exp $
+** $Id: pci.c,v 1.10 1995/02/02 12:36:18 davidg Exp $
**
** General subroutines for the PCI bus on 80*86 systems.
** pci_configure ()
@@ -56,62 +56,38 @@
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/errno.h>
+#include <sys/kernel.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/icu.h>
+#include <pci/pcivar.h>
#include <pci/pcireg.h>
+#include <pci/pcibus.h>
#ifdef __FreeBSD2__
#include <sys/devconf.h>
-
+
struct pci_devconf {
struct kern_devconf pdc_kdc;
struct pci_info pdc_pi;
};
-#endif
+
+static int
+pci_externalize (struct proc *, struct kern_devconf *, void *, size_t);
+
+static int
+pci_internalize (struct proc *, struct kern_devconf *, void *, size_t);
+#else /* __FreeBSD2__ */
/*
** Function prototypes missing in system headers
*/
-#ifndef __FreeBSD2__
extern pmap_t pmap_kernel(void);
static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize);
+#endif /* __FreeBSD2__ */
-/*
- * Type of the first (asm) part of an interrupt handler.
- */
-typedef void inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss));
-
-/*
- * Usual type of the second (C) part of an interrupt handler. Some bogus
- * ones need the arg to be the interrupt frame (and not a copy of it, which
- * is all that is possible in C).
- */
-typedef void inthand2_t __P((int unit));
-
-/*
-** XXX @FreeBSD2@
-**
-** Unfortunately, the mptr argument is _no_ pointer in 2.0 FreeBSD.
-** We would prefer a pointer because it enables us to install
-** new interrupt handlers at any time.
-** (This is just going to be changed ... <se> :)
-** In 2.0 FreeBSD later installed interrupt handlers may change
-** the xyz_imask, but this would not be recognized by handlers
-** which are installed before.
-*/
-
-static int
-register_intr __P((int intr, int device_id, unsigned int flags,
- inthand2_t *handler, unsigned int * mptr, int unit));
-extern unsigned intr_mask[ICU_LEN];
-
-#endif /* !__FreeBSD2__ */
/*========================================================
**
@@ -140,6 +116,20 @@ static vm_offset_t pci_paddr = PCI_PMEM_START;
/*--------------------------------------------------------
**
+** The pci ports can be mapped to any address.
+** As default we start at 0x400
+**
+**--------------------------------------------------------
+*/
+
+#ifndef PCI_PORT_START
+#define PCI_PORT_START 0x0400
+#endif
+
+static u_short pci_ioaddr = PCI_PORT_START;
+
+/*--------------------------------------------------------
+**
** The pci device interrupt lines should have been
** assigned by the bios. But if the bios failed to
** to it, we set it.
@@ -172,15 +162,6 @@ static unsigned long pci_seen[NPCI];
static int pci_conf_count;
-#ifdef __FreeBSD2__
-static int
-pci_externalize (struct proc *, struct kern_devconf *, void *, size_t);
-
-static int
-pci_internalize (struct proc *, struct kern_devconf *, void *, size_t);
-
-#endif /* __FreeBSD2__ */
-
void pci_configure()
{
u_char device,last_device;
@@ -194,19 +175,28 @@ void pci_configure()
int irq;
char* name=0;
vm_offset_t old_addr=pci_paddr;
+ u_short old_ioaddr=pci_ioaddr;
- struct pci_driver *drp=0;
- struct pci_device *dvp;
+ int dvi;
+ struct pci_device *dvp=0;
#ifdef __FreeBSD2__
struct pci_devconf *pdcp;
#endif
/*
+ ** first check pci bus driver available
+ */
+
+ if (pcibus_set.ls_length <= 0)
+ return;
+
+#define pcibus (*((struct pcibus*) pcibus_set.ls_items[0]))
+ /*
** check pci bus present
*/
- pci_mechanism = pci_conf_mode ();
+ pci_mechanism = pcibus.pb_mode ();
if (!pci_mechanism) return;
last_device = pci_mechanism==1 ? 31 : 15;
@@ -217,16 +207,16 @@ void pci_configure()
for (bus=0;bus<NPCI;bus++) {
#ifndef PCI_QUIET
- printf ("pci%d: scanning device 0..%d, mechanism=%d.\n",
- bus, last_device, pci_mechanism);
+ printf ("%s%d: scanning device 0..%d, mechanism=%d.\n",
+ pcibus.pb_name, bus, last_device, pci_mechanism);
#endif
for (device=0; device<=last_device; device ++) {
if (pci_seen[bus] & (1ul << device))
continue;
- tag = pcitag (bus, device, 0);
- type = pci_conf_read (tag, PCI_ID_REG);
+ tag = pcibus.pb_tag (bus, device, 0);
+ type = pcibus.pb_read (tag, PCI_ID_REG);
if ((!type) || (type==0xfffffffful)) continue;
@@ -234,19 +224,18 @@ void pci_configure()
** lookup device in ioconfiguration:
*/
- for (dvp = pci_devtab; dvp->pd_name; dvp++) {
- drp = dvp->pd_driver;
- if (!drp)
- continue;
- if ((name=(*drp->probe)(tag, type)))
+ for (dvi=0; dvi<pcidevice_set.ls_length; dvi++) {
+ dvp = (struct pci_device*) pcidevice_set.ls_items[dvi];
+ if ((name=(*dvp->pd_probe)(tag, type)))
break;
+ dvp = NULL;
};
- if (!dvp->pd_name) {
+ if (dvp==NULL) {
#ifndef PCI_QUIET
if (pci_conf_count)
continue;
- printf("pci%d:%d: ", bus, device);
+ printf("%s%d:%d: ", pcibus.pb_name, bus, device);
not_supported (tag, type);
#endif
continue;
@@ -257,7 +246,7 @@ void pci_configure()
** Get and increment the unit.
*/
- unit = (*drp->count)++;
+ unit = (*dvp->pd_count)++;
/*
** ignore device ?
@@ -276,7 +265,7 @@ void pci_configure()
** from the pci configuration space.
*/
- data = pci_conf_read (tag, PCI_INTERRUPT_REG);
+ data = pcibus.pb_read (tag, PCI_INTERRUPT_REG);
pciint = PCI_INTERRUPT_PIN_EXTRACT(data);
if (pciint) {
@@ -295,7 +284,7 @@ void pci_configure()
data = PCI_INTERRUPT_LINE_INSERT(data, irq);
printf (" (config)");
- pci_conf_write (tag, PCI_INTERRUPT_REG, data);
+ pcibus.pb_write (tag, PCI_INTERRUPT_REG, data);
};
irq = PCI_INTERRUPT_LINE_EXTRACT(data);
@@ -315,10 +304,10 @@ void pci_configure()
** enable memory access
*/
- data = (pci_conf_read (tag, PCI_COMMAND_STATUS_REG)
+ data = (pcibus.pb_read (tag, PCI_COMMAND_STATUS_REG)
& 0xffff) | PCI_COMMAND_MEM_ENABLE;
- pci_conf_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data);
+ pcibus.pb_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data);
/*
** show pci slot.
@@ -333,7 +322,7 @@ void pci_configure()
*/
pdcp = (struct pci_devconf *)
- malloc (sizeof (struct pci_devconf),M_DEVBUF,M_WAITOK);
+ malloc (sizeof (struct pci_devconf),M_DEVBUF,M_WAITOK);
/*
** Fill in.
@@ -378,7 +367,7 @@ void pci_configure()
** i.e. when installing subdevices.
*/
- (*drp->attach) (tag, unit);
+ (*dvp->pd_attach) (tag, unit);
};
};
@@ -386,10 +375,43 @@ void pci_configure()
if (pci_paddr != old_addr)
printf ("pci uses physical addresses from 0x%lx to 0x%lx\n",
(u_long)PCI_PMEM_START, (u_long)pci_paddr);
+ if (pci_ioaddr != old_ioaddr)
+ printf ("pci devices use ioports from 0x%x to 0x%x\n",
+ (unsigned)PCI_PORT_START, (unsigned)pci_ioaddr);
#endif
pci_conf_count++;
}
+/*-----------------------------------------------------------------
+**
+** The following functions are provided for the device driver
+** to read/write the configuration space.
+**
+** pci_conf_read():
+** Read a long word from the pci configuration space.
+** Requires a tag (from pcitag) and the register
+** number (should be a long word alligned one).
+**
+** pci_conf_write():
+** Writes a long word to the pci configuration space.
+** Requires a tag (from pcitag), the register number
+** (should be a long word alligned one), and a value.
+**
+**-----------------------------------------------------------------
+*/
+
+u_long
+pci_conf_read (pcici_t tag, u_long reg)
+{
+ return (pcibus.pb_read (tag, reg));
+}
+
+void
+pci_conf_write (pcici_t tag, u_long reg, u_long data)
+{
+ pcibus.pb_write (tag, reg, data);
+}
+
/*-----------------------------------------------------------------------
**
** Map device into port space.
@@ -401,11 +423,78 @@ void pci_configure()
int pci_map_port (pcici_t tag, u_long reg, u_short* pa)
{
+ u_long data;
+ u_short size;
+
/*
- ** @MAPIO@ not yet implemented.
+ ** sanity check
*/
- printf ("pci_map_port failed: not yet implemented\n");
- return (0);
+
+ if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) {
+ printf ("pci_map_port failed: bad register=0x%x\n",
+ (unsigned)reg);
+ return (0);
+ };
+
+ /*
+ ** get size and type of port
+ **
+ ** type is in the lowest two bits.
+ ** If device requires 2^n bytes, the next
+ ** n-2 bits are hardwired as 0.
+ */
+
+ pcibus.pb_write (tag, reg, 0xfffffffful);
+ data = pcibus.pb_read (tag, reg);
+
+ switch (data & 0x03) {
+
+ case PCI_MAP_IO:
+ break;
+
+ default: /* unknown */
+ printf ("pci_map_port failed: bad port type=0x%x\n",
+ (unsigned) data);
+ return (0);
+ };
+
+ /*
+ ** get the size
+ */
+
+ size = -(data & PCI_MAP_IO_ADDRESS_MASK);
+
+ if (!size) return (0);
+
+ /*
+ ** align physical address to virtual size
+ */
+
+ if ((data = pci_ioaddr % size))
+ pci_ioaddr += size - data;
+
+#ifndef PCI_QUIET
+ /*
+ ** display values.
+ */
+
+ printf ("\treg%d: ioaddr=0x%x size=0x%x\n",
+ (unsigned) reg, (unsigned) pci_ioaddr, (unsigned) size);
+#endif
+
+ /*
+ ** return them to the driver
+ */
+
+ *pa = pci_ioaddr;
+
+ /*
+ ** and don't forget to increment pci_ioaddr
+ */
+
+ pci_ioaddr += size;
+
+ return (1);
}
/*-----------------------------------------------------------------------
@@ -427,10 +516,10 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa)
** sanity check
*/
- if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) {
- printf ("pci_map_mem failed: bad register=0x%x\n",
- (unsigned)reg);
- return (0);
+ if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) {
+ printf ("pci_map_mem failed: bad register=0x%x\n",
+ (unsigned)reg);
+ return (0);
};
/*
@@ -441,8 +530,8 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa)
** n-4 bits are read as 0.
*/
- pci_conf_write (tag, reg, 0xfffffffful);
- data = pci_conf_read (tag, reg);
+ pcibus.pb_write (tag, reg, 0xfffffffful);
+ data = pcibus.pb_read (tag, reg);
switch (data & 0x0f) {
@@ -450,9 +539,9 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa)
break;
default: /* unknown */
- printf ("pci_map_mem failed: bad memory type=0x%x\n",
- (unsigned) data);
- return (0);
+ printf ("pci_map_mem failed: bad memory type=0x%x\n",
+ (unsigned) data);
+ return (0);
};
/*
@@ -496,7 +585,7 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa)
** set device address
*/
- pci_conf_write (tag, reg, pci_paddr);
+ pcibus.pb_write (tag, reg, pci_paddr);
/*
** and don't forget to increment pci_paddr
@@ -519,29 +608,29 @@ pci_externalize (struct proc *p, struct kern_devconf *kdcp, void *u, size_t l)
{
struct pci_externalize_buffer buffer;
struct pci_info * pip = kdcp->kdc_parentdata;
- pcici_t tag;
+ pcici_t tag;
int i;
if (l < sizeof buffer) {
- return ENOMEM;
+ return ENOMEM;
};
- tag = pcitag (pip->pi_bus, pip->pi_device, 0);
+ tag = pcibus.pb_tag (pip->pi_bus, pip->pi_device, 0);
buffer.peb_pci_info = *pip;
for (i=0; i<PCI_EXT_CONF_LEN; i++) {
- buffer.peb_config[i] = pci_conf_read (tag, i*4);
+ buffer.peb_config[i] = pcibus.pb_read (tag, i*4);
};
- return copyout(&buffer, u, sizeof buffer);
+ return copyout(&buffer, u, sizeof buffer);
}
static int
pci_internalize (struct proc *p, struct kern_devconf *kdcp, void *u, size_t s)
{
- return EOPNOTSUPP;
+ return EOPNOTSUPP;
}
/*-----------------------------------------------------------------------
@@ -551,60 +640,24 @@ pci_internalize (struct proc *p, struct kern_devconf *kdcp, void *u, size_t s)
**-----------------------------------------------------------------------
*/
-static unsigned int pci_int_mask [16];
-
int pci_map_int (pcici_t tag, int(*func)(), void* arg, unsigned* maskptr)
{
- int irq;
- unsigned mask;
+ int irq, result;
irq = PCI_INTERRUPT_LINE_EXTRACT(
- pci_conf_read (tag, PCI_INTERRUPT_REG));
+ pcibus.pb_read (tag, PCI_INTERRUPT_REG));
if (irq >= 16 || irq <= 0) {
printf ("pci_map_int failed: no int line set.\n");
return (0);
}
- mask = 1ul << irq;
-
- if (!maskptr)
- maskptr = &pci_int_mask[irq];
-
- INTRMASK (*maskptr, mask);
-
- register_intr(
- irq, /* isa irq */
- 0, /* deviced?? */
- 0, /* flags? */
- (inthand2_t*) func, /* handler */
- maskptr, /* mask pointer */
- (int) arg); /* handler arg */
+ result = pcibus.pb_regint (tag, func, arg, maskptr);
-#ifdef __FreeBSD2__
- /*
- ** XXX See comment at beginning of file.
- **
- ** Have to update all the interrupt masks ... Grrrrr!!!
- */
- {
- unsigned * mp = &intr_mask[0];
- /*
- ** update the isa interrupt masks.
- */
- for (mp=&intr_mask[0]; mp<&intr_mask[ICU_LEN]; mp++)
- if (*mp & *maskptr)
- *mp |= mask;
- /*
- ** update the pci interrupt masks.
- */
- for (mp=&pci_int_mask[0]; mp<&pci_int_mask[16]; mp++)
- if (*mp & *maskptr)
- *mp |= mask;
+ if (!result) {
+ printf ("pci_map_int failed.\n");
+ return (0);
};
-#endif
-
- INTREN (mask);
return (1);
}
@@ -659,14 +712,14 @@ void not_supported (pcici_t tag, u_long type)
printf (", device=0x%lx", type >> 16);
- data = (pci_conf_read(tag, PCI_CLASS_REG) >> 24) & 0xff;
+ data = (pcibus.pb_read(tag, PCI_CLASS_REG) >> 24) & 0xff;
if (data < sizeof(majclasses) / sizeof(majclasses[0]))
printf(", class=%s", majclasses[data]);
printf (" [not supported]\n");
for (reg=PCI_MAP_REG_START; reg<PCI_MAP_REG_END; reg+=4) {
- data = pci_conf_read (tag, reg);
+ data = pcibus.pb_read (tag, reg);
if (!data) continue;
switch (data&7) {
diff --git a/sys/pci/pcireg.h b/sys/pci/pcireg.h
index dd1f1ccf3280..595e59f172af 100644
--- a/sys/pci/pcireg.h
+++ b/sys/pci/pcireg.h
@@ -1,10 +1,12 @@
/**************************************************************************
**
-** $Id: pcireg.h,v 1.1 1994/10/12 02:25:03 se Exp $
+** $Id: pcireg.h,v 1.1 1995/02/01 22:56:50 se Exp $
**
-** Declarations for pci bus drivers.
+** Names for PCI configuration space registers.
**
-** 386bsd / FreeBSD
+** Copyright (c) 1994 Charles Hannum. All rights reserved.
+**
+** FreeBSD
**
**-------------------------------------------------------------------------
**
@@ -38,271 +40,16 @@
#ifndef __PCI_REG_H__
#define __PCI_REG_H__
-/*-----------------------------------------------------------------
-**
-** main pci initialization function.
-** called at boot time from autoconf.c
-**
-**-----------------------------------------------------------------
-*/
-
-void pci_configure (void);
-
-/*-----------------------------------------------------------------
-**
-** The pci configuration id describes a pci device on the bus.
-** It is constructed from: bus, device & function numbers.
-**
-**-----------------------------------------------------------------
-*/
-
-typedef union {
- u_long cfg1;
- struct {
- u_char enable;
- u_char forward;
- u_short port;
- } cfg2;
- } pcici_t;
-
-/*-----------------------------------------------------------------
-**
-** Each pci device has an unique device id.
-** It is used to find a matching driver.
-**
-**-----------------------------------------------------------------
-*/
-
-typedef u_long pcidi_t;
-
-/*-----------------------------------------------------------------
-**
-** The pci driver structure.
-**
-** probe: Checks if the driver can support a device
-** with this type. The tag may be used to get
-** more info with pci_read_conf(). See below.
-** It returns a string with the devices name,
-** or a NULL pointer, if the driver cannot
-** support this device.
-**
-** attach: Allocate a control structure and prepare
-** it. This function may use the pci mapping
-** functions. See below.
-** (configuration id) or type.
-**
-** count: A pointer to a unit counter.
-** It's used by the pci configurator to
-** allocate unit numbers.
-**
-**-----------------------------------------------------------------
-*/
-
-struct pci_driver {
- char* (*probe ) (pcici_t tag, pcidi_t type);
- void (*attach) (pcici_t tag, int unit);
- u_long *count;
-};
-
-/*-----------------------------------------------------------------
-**
-** The pci-devconf interface.
-**
-**-----------------------------------------------------------------
-*/
-
-struct pci_info {
- u_short pi_bus;
- u_short pi_device;
-};
-
-#define PCI_EXT_CONF_LEN (16)
-#define PCI_EXTERNAL_LEN (sizeof(struct pci_externalize_buffer))
-
-struct pci_externalize_buffer {
- struct pci_info peb_pci_info;
- u_long peb_config[PCI_EXT_CONF_LEN];
-};
-
-
-/*-----------------------------------------------------------------
-**
-** Per device structure.
-**
-** An array of this structure should be created by the
-** config utility and live in "ioconf.c".
-**
-** At the moment it's created by hand and lives in
-** pci_config.c
-**
-** pd_driver:
-** a pointer to the driver structure.
-**
-** pd_name:
-** the name of the devices which are supported
-** by this driver for kernel messages.
-**
-** pd_flags:
-** for further study.
-**
-**-----------------------------------------------------------------
-*/
-
-struct pci_device {
- struct
- pci_driver* pd_driver;
- const char * pd_name;
- int pd_flags;
-};
-
-/*-----------------------------------------------------------------
-**
-** This table should be generated in file "ioconf.c"
-** by the config program.
-** It is used at boot time by the configuration function
-** pci_configure()
-**
-**-----------------------------------------------------------------
-*/
-
-extern struct pci_device pci_devtab[];
-
-/*-----------------------------------------------------------------
-**
-** Map a pci device to physical and virtual memory.
-**
-** The va and pa addresses are "in/out" parameters.
-** If they are 0 on entry, the function assigns an address.
-**
-** Entry selects the register in the pci configuration
-** space, which supplies the size of the region, and
-** receives the physical address.
-**
-** If there is any error, a message is written, and
-** the function returns with zero.
-** Else it returns with a value different to zero.
-**
-**-----------------------------------------------------------------
-*/
-
-int pci_map_mem (pcici_t tag, u_long entry, u_long * va, u_long * pa);
-
-/*-----------------------------------------------------------------
-**
-** Map a pci device to an io port area.
-**
-** *pa is an "in/out" parameter.
-** If it's 0 on entry, the function assigns an port number..
-**
-** Entry selects the register in the pci configuration
-** space, which supplies the size of the region, and
-** receives the port number.
-**
-** If there is any error, a message is written, and
-** the function returns with zero.
-** Else it returns with a value different to zero.
-**
-**-----------------------------------------------------------------
-*/
-
-int pci_map_port(pcici_t tag, u_long entry, u_short * pa);
-
-/*-----------------------------------------------------------------
-**
-** Map a pci interrupt to an isa irq line,
-** and enable the interrupt.
-**
-** func is the interrupt handler, arg is the argument
-** to this function.
-**
-** The maskptr argument should be &bio_imask,
-** &net_imask etc. or NULL.
-**
-** If there is any error, a message is written, and
-** the function returns with zero.
-** Else it returns with a value different to zero.
-**
-** A word of caution for FreeBSD 2.0:
-**
-** We use the register_intr() function.
-**
-** The interrupt line of the selected device is included
-** into the supplied mask: after the corresponding splXXX
-** this drivers interrupts are blocked.
-**
-** But in the interrupt handlers startup code ONLY
-** the interrupt of the driver is blocked, and NOT
-** all interrupts of the spl group.
-**
-** It may be required to additional block the group
-** interrupts by splXXX() inside the interrupt handler.
-**
-** In pre 2.0 kernels we emulate the register_intr
-** function. The emulating function blocks all interrupts
-** of the group in the interrupt handler prefix code.
-**
-**-----------------------------------------------------------------
-*/
-
-int pci_map_int (pcici_t tag, int (*func)(), void* arg, unsigned * maskptr);
-
-/*-----------------------------------------------------------------
-**
-** The following functions are provided by the pci bios.
-** They are used only by the pci configuration.
-**
-** pci_conf_mode():
-** Probes for a pci system.
-** Returns 1 or 2 for pci configuration mechanism.
-** Returns 0 if no pci system.
-**
-** pcitag():
-** Gets a handle for accessing the pci configuration
-** space.
-** This handle is given to the mapping functions (see
-** above) or to the read/write functions.
-**
-** pci_conf_read():
-** Read a long word from the pci configuration space.
-** Requires a tag (from pcitag) and the register
-** number (should be a long word alligned one).
-**
-** pci_conf_write():
-** Writes a long word to the pci configuration space.
-** Requires a tag (from pcitag), the register number
-** (should be a long word alligned one), and a value.
-**
-**-----------------------------------------------------------------
-*/
-
-int pci_conf_mode (void);
-
-pcici_t pcitag (unsigned char bus,
- unsigned char device,
- unsigned char func);
-
-u_long pci_conf_read (pcici_t tag, u_long reg );
-void pci_conf_write (pcici_t tag, u_long reg, u_long data);
-
-
-/*------------------------------------------------------------------
-**
-** Names for PCI configuration space registers.
-**
-** Copyright (c) 1994 Charles Hannum. All rights reserved.
-**
-**------------------------------------------------------------------
-*/
/*
- * Device identification register; contains a vendor ID and a device ID.
- * We have little need to distinguish the two parts.
- */
+** Device identification register; contains a vendor ID and a device ID.
+** We have little need to distinguish the two parts.
+*/
#define PCI_ID_REG 0x00
/*
- * Command and status register.
- */
+** Command and status register.
+*/
#define PCI_COMMAND_STATUS_REG 0x04
#define PCI_COMMAND_IO_ENABLE 0x00000001
@@ -329,8 +76,8 @@ void pci_conf_write (pcici_t tag, u_long reg, u_long data);
#define PCI_STATUS_PARITY_DETECT 0x80000000
/*
- * Class register; defines basic type of device.
- */
+** Class register; defines basic type of device.
+*/
#define PCI_CLASS_REG 0x08
#define PCI_CLASS_MASK 0xff000000
@@ -388,8 +135,8 @@ void pci_conf_write (pcici_t tag, u_long reg, u_long data);
#define PCI_SUBCLASS_BRIDGE_MISC 0x00800000
/*
- * Mapping registers
- */
+** Mapping registers
+*/
#define PCI_MAP_REG_START 0x10
#define PCI_MAP_REG_END 0x28
@@ -403,9 +150,11 @@ void pci_conf_write (pcici_t tag, u_long reg, u_long data);
#define PCI_MAP_MEMORY_CACHABLE 0x00000008
#define PCI_MAP_MEMORY_ADDRESS_MASK 0xfffffff0
+#define PCI_MAP_IO_ADDRESS_MASK 0xfffffffc
+
/*
- * Interrupt configuration register
- */
+** Interrupt configuration register
+*/
#define PCI_INTERRUPT_REG 0x3c
#define PCI_INTERRUPT_PIN_MASK 0x0000ff00
diff --git a/sys/pci/pcisupport.c b/sys/pci/pcisupport.c
index 16694653bc0d..933ca54a460a 100644
--- a/sys/pci/pcisupport.c
+++ b/sys/pci/pcisupport.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: pcisupport.c,v 1.6 1994/12/22 21:20:39 se Exp $
+** $Id: pcisupport.c,v 1.7 1995/02/02 12:36:19 davidg Exp $
**
** Device driver for INTEL PCI chipsets.
**
@@ -50,7 +50,10 @@
*/
#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <pci/pcivar.h>
#include <pci/pcireg.h>
extern void printf();
@@ -69,12 +72,15 @@ static char* chipset_probe (pcici_t tag, pcidi_t type);
static void chipset_attach(pcici_t tag, int unit);
static u_long chipset_count;
-struct pci_driver chipset_device = {
+struct pci_device chipset_device = {
+ "chip",
chipset_probe,
chipset_attach,
&chipset_count
};
+DATA_SET (pcidevice_set, chipset_device);
+
static char confread(pcici_t config_id, int port);
struct condmsg {
@@ -296,12 +302,15 @@ static char* vga_probe (pcici_t tag, pcidi_t type);
static void vga_attach(pcici_t tag, int unit);
static u_long vga_count;
-struct pci_driver vga_device = {
+struct pci_device vga_device = {
+ "vga",
vga_probe,
vga_attach,
&vga_count
};
+DATA_SET (pcidevice_set, vga_device);
+
static char* vga_probe (pcici_t tag, pcidi_t type)
{
int data = pci_conf_read(tag, PCI_CLASS_REG);
@@ -345,12 +354,15 @@ static char* lkm_probe (pcici_t tag, pcidi_t type);
static void lkm_attach(pcici_t tag, int unit);
static u_long lkm_count;
-struct pci_driver lkm_device = {
+struct pci_device lkm_device = {
+ "lkm",
lkm_probe,
lkm_attach,
&lkm_count
};
+DATA_SET (pcidevice_set, lkm_device);
+
static char* lkm_probe (pcici_t tag, pcidi_t type)
{
/*
@@ -375,12 +387,15 @@ static char* ign_probe (pcici_t tag, pcidi_t type);
static void ign_attach(pcici_t tag, int unit);
static u_long ign_count;
-struct pci_driver ign_device = {
+struct pci_device ign_device = {
+ NULL,
ign_probe,
ign_attach,
&ign_count
};
+DATA_SET (pcidevice_set, ign_device);
+
static char* ign_probe (pcici_t tag, pcidi_t type)
{
switch (type) {