Next phase in the PCI subsystem cleanup.

- Move PCI core code to dev/pci.
 - Split bridge code out into separate modules.
 - Remove the descriptive strings from the bridge drivers.  If you
   want to know what a device is, use pciconf.  Add support for
   broadly identifying devices based on class/subclass, and for
   parsing a preloaded device identification database so that if
   you want to waste the memory, you can identify *anything* we know
   about.
 - Remove machine-dependant code from the core PCI code.  APIC interrupt
   mapping is performed by shadowing the intline register in machine-
   dependant code.
 - Bring interrupt routing support to the Alpha
   (although many platforms don't yet support routing or mapping
   interrupts entirely correctly).  This resulted in spamming
   <sys/bus.h> into more places than it really should have gone.
 - Put sys/dev on the kernel/modules include path.  This avoids
   having to change *all* the pci*.h includes.
This commit is contained in:
Mike Smith 2000-12-08 22:11:23 +00:00
parent baeb94c70d
commit bb0d0a8efc
50 changed files with 1441 additions and 4489 deletions

View File

@ -33,6 +33,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <machine/cpuconf.h>
#include <machine/rpb.h>

View File

@ -79,6 +79,7 @@
#include <sys/reboot.h>
#include <sys/systm.h>
#include <sys/termios.h>
#include <sys/bus.h>
#include <machine/rpb.h>
#include <machine/cpuconf.h>
@ -103,12 +104,12 @@ void dec_1000a_init __P((int));
static void dec_1000a_cons_init __P((void));
static void dec_1000_intr_map __P((void *));
static int dec_1000_intr_route __P((device_t, device_t, int));
static void dec_1000_intr_disable __P((int));
static void dec_1000_intr_enable __P((int));
static void dec_1000_intr_init __P((void));
static void dec_1000a_intr_map __P((void *));
static int dec_1000a_intr_route __P((device_t, device_t, int));
static void dec_1000a_intr_disable __P((int));
static void dec_1000a_intr_enable __P((int));
static void dec_1000a_intr_init __P((void));
@ -147,7 +148,7 @@ dec_1000a_init(int cputype)
case PCS_PROC_EV4:
case PCS_PROC_EV45:
platform.iobus = "apecs";
platform.pci_intr_map = dec_1000_intr_map;
platform.pci_intr_route = dec_1000_intr_route;
platform.pci_intr_disable = dec_1000_intr_disable;
platform.pci_intr_enable = dec_1000_intr_enable;
platform.pci_intr_init = dec_1000_intr_init;
@ -155,7 +156,7 @@ dec_1000a_init(int cputype)
default:
platform.iobus = "cia";
platform.pci_intr_map = dec_1000a_intr_map;
platform.pci_intr_route = dec_1000a_intr_route;
platform.pci_intr_disable = dec_1000a_intr_disable;
platform.pci_intr_enable = dec_1000a_intr_enable;
platform.pci_intr_init = dec_1000a_intr_init;
@ -228,34 +229,26 @@ dec_1000a_cons_init()
}
static void
dec_1000_intr_map(arg)
void *arg;
static int
dec_1000_intr_route(bus, dev, pin)
device_t bus, dev;
int pin;
{
pcicfgregs *cfg;
cfg = (pcicfgregs *)arg;
if (cfg->intpin == 0) /* No IRQ used. */
return;
if (!(1 <= cfg->intpin && cfg->intpin <= 4))
goto bad;
switch(cfg->slot) {
switch(pci_get_slot(dev)) {
case 6:
if(cfg->intpin != 1)
if (pin != 1)
break;
cfg->intline = 0xc; /* integrated ncr scsi */
return;
break;
return(0xc); /* integrated ncr scsi */
case 11:
case 12:
case 13:
cfg->intline = (cfg->slot - 11) * 4 + cfg->intpin - 1;
return((pci_get_slot(dev) - 11) * 4 + pin - 1);
return;
break;
}
bad: printf("dec_1000_intr_map: can't map dev %d pin %d\n",
cfg->slot, cfg->intpin);
pci_get_slot(dev), pin);
return(255);
}
@ -312,11 +305,12 @@ dec_1000_intr_init()
#define IMR2IRQ(bn) ((bn) - 1)
#define IRQ2IMR(irq) ((irq) + 1)
static void
dec_1000a_intr_map(arg)
void *arg;
static int
dec_1000a_intr_route(bus, dev, pin)
device_t bus, dev;
int pin;
{
pcicfgregs *cfg;
int device, imrbit;
/*
* Get bit number in mystery ICU imr.
@ -341,28 +335,17 @@ dec_1000a_intr_map(arg)
/* 14 */ IRQSPLIT(8) /* Corelle */
};
cfg = (pcicfgregs *)arg;
device = cfg->slot;
if (cfg->intpin == 0) /* No IRQ used. */
return;
if (!(1 <= cfg->intpin && cfg->intpin <= 4))
goto bad;
if (0 <= device && device < sizeof imrmap / sizeof imrmap[0]) {
imrbit = imrmap[device][cfg->intpin - 1];
if (imrbit) {
cfg->intline = IMR2IRQ(imrbit);
return;
}
if (0 <= pci_get_slot(dev) && pci_get_slot(dev) < sizeof imrmap / sizeof imrmap[0]) {
imrbit = imrmap[device][pin - 1];
if (imrbit)
return(IMR2IRQ(imrbit));
}
bad: printf("dec_1000a_intr_map: can't map dev %d pin %d\n",
device, cfg->intpin);
bad: printf("dec_1000a_intr_route: can't map dev %d pin %d\n",
pci_get_slot(dev), pin);
return(255);
}
static void
dec_1000a_intr_enable(irq)
int irq;

View File

@ -40,6 +40,7 @@
#include <sys/reboot.h>
#include <sys/systm.h>
#include <sys/termios.h>
#include <sys/bus.h>
#include <machine/rpb.h>
#include <machine/cpuconf.h>
@ -58,7 +59,7 @@ static int comcnrate = CONSPEED;
void dec_2100_a50_init __P((void));
static void dec_2100_a50_cons_init __P((void));
static void dec_2100_a50_intr_map __P((void *));
static int dec_2100_a50_intr_route __P((device_t, device_t, int));
void sio_intr_establish __P((int));
void sio_intr_disestablish __P((int));
void sio_intr_setup __P((void));
@ -97,7 +98,7 @@ dec_2100_a50_init()
platform.iobus = "apecs";
platform.cons_init = dec_2100_a50_cons_init;
platform.pci_intr_map = dec_2100_a50_intr_map;
platform.pci_intr_route = dec_2100_a50_intr_route;
}
/* XXX for forcing comconsole when srm serial console is used */
@ -158,35 +159,27 @@ dec_2100_a50_cons_init()
#define SIO_PCIREG_PIRQ_RTCTRL 0x60 /* PIRQ0 Route Control */
void
dec_2100_a50_intr_map(void *arg)
int
dec_2100_a50_intr_route(device_t bus, device_t dev, int pin)
{
u_int8_t pirqline;
u_int32_t pirqreg;
int pirq;
pcicfgregs *cfg;
pirq = 0; /* gcc -Wuninitialized XXX */
cfg = (pcicfgregs *)arg;
pirq = 255;
/*
* Slot->interrupt translation. Taken from NetBSD.
*/
if(cfg->intpin == 0)
return;
if(cfg->intpin > 4)
panic("dec_2100_a50_intr_map: bad intpin %d",cfg->intpin);
switch (cfg->slot) {
switch (pci_get_slot(dev)) {
case 6: /* NCR SCSI */
pirq = 3;
break;
case 11: /* slot 1 */
case 14: /* slot 3 */
switch(cfg->intpin) {
switch(pin) {
case 1:
case 4:
pirq = 0;
@ -198,13 +191,12 @@ dec_2100_a50_intr_map(void *arg)
pirq = 1;
break;
default:
panic("dec_2100_a50_intr_map bogus PCI pin %d\n",
cfg->intpin);
panic("dec_2100_a50_intr_map bogus PCI pin %d\n", pin);
}
break;
case 12: /* slot 2 */
switch (cfg->intpin) {
switch (pin) {
case 1:
case 4:
pirq = 1;
@ -216,14 +208,12 @@ dec_2100_a50_intr_map(void *arg)
pirq = 2;
break;
default:
panic("dec_2100_a50_intr_map bogus PCI pin %d\n",
cfg->intpin);
panic("dec_2100_a50_intr_map bogus PCI pin %d\n", pin);
};
break;
case 13: /* slot 3 */
switch (cfg->intpin) {
switch (pin) {
case 1:
case 4:
pirq = 2;
@ -237,8 +227,8 @@ dec_2100_a50_intr_map(void *arg)
};
break;
default:
printf("dec_2100_a50_intr_map: weird slot %d\n",
cfg->slot);
printf("dec_2100_a50_intr_map: weird slot %d\n",
pci_get_slot(dev));
/* return; */
}
@ -254,5 +244,5 @@ dec_2100_a50_intr_map(void *arg)
if ((pirqline & 0x80) != 0)
panic("bad pirqline %d",pirqline);
pirqline &= 0xf;
cfg->intline = pirqline;
return(pirqline);
}

View File

@ -32,6 +32,7 @@
#include <sys/reboot.h>
#include <sys/systm.h>
#include <sys/termios.h>
#include <sys/bus.h>
#include <machine/rpb.h>
#include <machine/cpuconf.h>
@ -80,7 +81,7 @@ dec_2100_a500_init(cputype)
platform.iobus = "t2";
platform.cons_init = dec_2100_a500_cons_init;
platform.pci_intr_map = t2_intr_map;
platform.pci_intr_route = t2_intr_route;
platform.pci_intr_init = dec_2100_a500_intr_init;
t2_init();

View File

@ -34,6 +34,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/termios.h>
#include <sys/bus.h>
#include <machine/rpb.h>
#include <machine/cpuconf.h>

View File

@ -34,6 +34,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/termios.h>
#include <sys/bus.h>
#include <machine/rpb.h>
#include <machine/cpuconf.h>

View File

@ -37,6 +37,7 @@
#include <sys/reboot.h>
#include <sys/systm.h>
#include <sys/termios.h>
#include <sys/bus.h>
#include <machine/rpb.h>
#include <machine/cpuconf.h>
@ -55,7 +56,7 @@ static int comcnrate = CONSPEED;
void dec_axppci_33_init __P((void));
static void dec_axppci_33_cons_init __P((void));
static void dec_axppci_33_intr_map __P((void *));
static int dec_axppci_33_intr_route __P((device_t, device_t, int));
extern int siocnattach __P((int, int));
extern int siogdbattach __P((int, int));
@ -93,7 +94,7 @@ dec_axppci_33_init()
platform.iobus = "lca";
platform.cons_init = dec_axppci_33_cons_init;
platform.pci_intr_map = dec_axppci_33_intr_map;
platform.pci_intr_route = dec_axppci_33_intr_route;
lca_init();
@ -167,16 +168,13 @@ dec_axppci_33_cons_init()
#define SIO_PCIREG_PIRQ_RTCTRL 0x60 /* PIRQ0 Route Control */
void
dec_axppci_33_intr_map(void *arg)
static int
dec_axppci_33_intr_route(device_t pcib, device_t dev, int pin)
{
pcicfgregs *cfg;
int pirq;
u_int32_t pirqreg;
u_int8_t pirqline;
cfg = (pcicfgregs *)arg;
#ifndef DIAGNOSTIC
pirq = 0; /* XXX gcc -Wuninitialized */
#endif
@ -185,23 +183,13 @@ dec_axppci_33_intr_map(void *arg)
* Slot->interrupt translation. Taken from NetBSD.
*/
if (cfg->intpin == 0) {
/* No IRQ used. */
return;
}
if (cfg->intpin > 4) {
printf("dec_axppci_33_intr_map: bad interrupt pin %d\n",
cfg->intpin);
return;
}
switch (cfg->slot) {
switch (pci_get_slot(dev)) {
case 6: /* NCR SCSI */
pirq = 3;
break;
case 11: /* slot 1 */
switch (cfg->intpin) {
switch (pin) {
case 1:
case 4:
pirq = 0;
@ -212,16 +200,11 @@ dec_axppci_33_intr_map(void *arg)
case 3:
pirq = 1;
break;
#ifdef DIAGNOSTIC
default: /* XXX gcc -Wuninitialized */
panic("dec_axppci_33_intr_map: bogus PCI pin %d\n",
cfg->intpin);
#endif
};
break;
case 12: /* slot 2 */
switch (cfg->intpin) {
switch (pin) {
case 1:
case 4:
pirq = 1;
@ -232,16 +215,11 @@ dec_axppci_33_intr_map(void *arg)
case 3:
pirq = 2;
break;
#ifdef DIAGNOSTIC
default: /* XXX gcc -Wuninitialized */
panic("dec_axppci_33_intr_map: bogus PCI pin %d\n",
cfg->intpin);
#endif
};
break;
case 8: /* slot 3 */
switch (cfg->intpin) {
switch (pin) {
case 1:
case 4:
pirq = 2;
@ -252,35 +230,22 @@ dec_axppci_33_intr_map(void *arg)
case 3:
pirq = 0;
break;
#ifdef DIAGNOSTIC
default: /* XXX gcc -Wuninitialized */
panic("dec_axppci_33_intr_map bogus: PCI pin %d\n",
cfg->intpin);
#endif
};
break;
default:
printf("dec_axppci_33_intr_map: weird device number %d\n",
cfg->slot);
return;
printf("dec_axppci_33_intr_map: weird slot number %d\n",
pci_get_slot(dev));
return(255);
}
pirqreg = lca_pcib_read_config(0, 0, 7, 0,
SIO_PCIREG_PIRQ_RTCTRL, 4);
#if 0
printf("dec_axppci_33_intr_map: device %d pin %c: pirq %d, reg = %x\n",
device, '@' + cfg->intpin, pirq, pirqreg);
#endif
pirqline = (pirqreg >> (pirq * 8)) & 0xff;
if ((pirqline & 0x80) != 0)
panic("bad pirqline %d",pirqline);
pirqline &= 0xf;
#if 0
printf("dec_axppci_33_intr_map: device %d pin %c: mapped to line %d\n",
device, '@' + cfg->intpin, pirqline);
#endif
cfg->intline = pirqline;
return(pirqline);
}

View File

@ -37,6 +37,7 @@
#include <sys/reboot.h>
#include <sys/systm.h>
#include <sys/termios.h>
#include <sys/bus.h>
#include <machine/rpb.h>
#include <machine/cpuconf.h>
@ -77,7 +78,7 @@ dec_eb164_init()
platform.iobus = "cia";
platform.cons_init = dec_eb164_cons_init;
platform.pci_intr_init = eb164_intr_init;
platform.pci_intr_map = NULL;
platform.pci_intr_route = NULL;
if (strncmp(platform.model, "Digital AlphaPC 164 ", 20) == 0) {
platform.pci_intr_disable = eb164_intr_disable_icsr;
platform.pci_intr_enable = eb164_intr_enable_icsr;

View File

@ -54,6 +54,7 @@
#include <sys/reboot.h>
#include <sys/systm.h>
#include <sys/termios.h>
#include <sys/bus.h>
#include <machine/rpb.h>
#include <machine/cpuconf.h>
@ -109,7 +110,7 @@ dec_eb64plus_init()
platform.cons_init = dec_eb64plus_cons_init;
platform.pci_intr_init = dec_eb64plus_intr_init;
/* SRM handles PCI interrupt mapping */
platform.pci_intr_map = NULL;
platform.pci_intr_route = NULL;
/* see ../pci/pci_eb64plus_intr.s for intr. dis/enable */
platform.pci_intr_disable = eb64plus_intr_disable;
platform.pci_intr_enable = eb64plus_intr_enable;

View File

@ -37,6 +37,7 @@
#include <sys/reboot.h>
#include <sys/systm.h>
#include <sys/termios.h>
#include <sys/bus.h>
#include <machine/rpb.h>
#include <machine/cpuconf.h>
@ -57,7 +58,7 @@ static int comcnrate = CONSPEED;
void dec_kn20aa_init __P((void));
static void dec_kn20aa_cons_init __P((void));
static void dec_kn20aa_intr_init __P((void));
static void dec_kn20aa_intr_map __P((void *));
static int dec_kn20aa_intr_route __P((device_t, device_t, int));
static void dec_kn20aa_intr_disable __P((int));
static void dec_kn20aa_intr_enable __P((int));
@ -92,7 +93,7 @@ dec_kn20aa_init()
platform.iobus = "cia";
platform.cons_init = dec_kn20aa_cons_init;
platform.pci_intr_init = dec_kn20aa_intr_init;
platform.pci_intr_map = dec_kn20aa_intr_map;
platform.pci_intr_route = dec_kn20aa_intr_route;
platform.pci_intr_disable = dec_kn20aa_intr_disable;
platform.pci_intr_enable = dec_kn20aa_intr_enable;
}
@ -276,12 +277,11 @@ dec_kn20aa_intr_init()
dec_kn20aa_intr_enable(31);
}
void
dec_kn20aa_intr_map(void *arg)
static int
dec_kn20aa_intr_route(device_t pcib, device_t dev, int pin)
{
pcicfgregs *cfg;
int intline;
cfg = (pcicfgregs *)arg;
/*
* Slot->interrupt translation. Appears to work, though it
* may not hold up forever.
@ -289,45 +289,46 @@ dec_kn20aa_intr_map(void *arg)
* The DEC engineers who did this hardware obviously engaged
* in random drug testing.
*/
switch (cfg->slot) {
switch (pci_get_slot(dev)) {
case 11:
case 12:
cfg->intline = ((cfg->slot - 11) + 0) * 4;
intline = ((pci_get_slot(dev) - 11) + 0) * 4;
break;
case 7:
cfg->intline = 8;
intline = 8;
break;
case 9:
cfg->intline = 12;
intline = 12;
break;
case 6: /* 21040 on AlphaStation 500 */
cfg->intline = 13;
intline = 13;
break;
case 8:
cfg->intline = 16;
intline = 16;
break;
case 10: /* 8275EB on AlphaStation 500 */
return;
return(255);
default:
if(!cfg->bus){
if (pci_get_bus(dev) == 0) {
printf("dec_kn20aa_intr_map: weird slot %d\n",
cfg->slot);
return;
pci_get_slot(dev));
return(255);
} else {
cfg->intline = cfg->slot;
intline = pci_get_slot(dev);
}
}
cfg->intline += cfg->bus*16;
if (cfg->intline > KN20AA_MAX_IRQ)
panic("dec_kn20aa_intr_map: cfg->intline too large (%d)\n",
cfg->intline);
intline += pci_get_bus(dev) * 16;
if (intline > KN20AA_MAX_IRQ)
panic("dec_kn20aa_intr_route: intline too large (%d)\n",
intline);
return(intline);
}
void

View File

@ -38,6 +38,7 @@
#include <sys/termios.h>
#include <sys/cons.h>
#include <sys/reboot.h>
#include <sys/bus.h>
#include <machine/rpb.h>
#include <machine/cpuconf.h>

View File

@ -67,7 +67,7 @@ static void pyxis_intr_enable __P((int));
static void pyxis_intr_disable __P((int));
static void st550_intr_enable __P((int));
static void st550_intr_disable __P((int));
static void st550_intr_map __P((void *));
static int st550_intr_route __P((device_t, device_t, int));
#define ST550_PCI_IRQ_BEGIN 8
#define ST550_PCI_MAX_IRQ 47
@ -89,7 +89,7 @@ st550_init()
platform.iobus = "cia";
platform.cons_init = st550_cons_init;
platform.pci_intr_init = st550_intr_init;
platform.pci_intr_map = st550_intr_map;
platform.pci_intr_route = st550_intr_route;
platform.pci_intr_disable = st550_intr_disable;
platform.pci_intr_enable = st550_intr_enable;
}
@ -159,12 +159,9 @@ st550_intr_init()
pyxis_intr_enable(7); /* enable ISA PIC cascade */
}
static void
st550_intr_map(void *arg)
static int
st550_intr_route(device_t pcib, device_t dev, int pin)
{
pcicfgregs *cfg;
cfg = (pcicfgregs *)arg;
/* There are two main variants of Miata: Miata 1 (Intel SIO)
* and Miata {1.5,2} (Cypress).
@ -179,25 +176,28 @@ st550_intr_map(void *arg)
* There will be no interrupt mapping for these devices, so just
* bail out now.
*/
if(cfg->bus == 0) {
/*
* XXX FIXME this code does not match the above description.
*/
if (pci_get_bus(dev) == 0) {
if ((hwrpb->rpb_variation & SV_ST_MASK) < SV_ST_MIATA_1_5) {
/* Miata 1 */
if (cfg->slot == 7)
return;
else if (cfg->func == 4)
return;
if (pci_get_slot(dev) == 7)
return(255);
else if (pci_get_function(dev) == 4)
return(255);
} else {
/* Miata 1.5 or Miata 2 */
if (cfg->slot == 7) {
if (cfg->func == 0)
return;
return;
if (pci_get_slot(dev) == 7) {
if (pci_get_function(dev) == 0)
return(255);
return(255);
}
}
}
/* Account for the PCI interrupt offset. */
/* cfg->intline += ST550_PCI_IRQ_BEGIN; */
return;
return(255);
}
/*

View File

@ -55,7 +55,7 @@ static int comcnrate = CONSPEED;
void st6600_init __P((void));
static void st6600_cons_init __P((void));
static void st6600_intr_init __P((void));
static void st6600_intr_map __P((void *));
static int st6600_intr_route __P((device_t, device_t, int));
#define ST6600_PCI_IRQ_BEGIN 8
#define ST6600_PCI_MAX_IRQ 63
@ -77,7 +77,7 @@ st6600_init()
platform.iobus = "tsunami";
platform.cons_init = st6600_cons_init;
platform.pci_intr_init = st6600_intr_init;
platform.pci_intr_map = st6600_intr_map;
platform.pci_intr_route = st6600_intr_route;
}
extern int comconsole;
@ -145,10 +145,10 @@ st6600_intr_init()
platform.pci_intr_enable(2);
}
static void
st6600_intr_map(void *arg)
static int
st6600_intr_route(device_t pcib, device_t dev, int pin)
{
return;
return(255);
}

View File

@ -107,6 +107,7 @@
#include <sys/reboot.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/bus.h>
#include <sys/mbuf.h>
#include <sys/vmmeter.h>
#include <sys/msgbuf.h>

View File

@ -72,7 +72,7 @@ extern struct platform {
void (*mcheck_handler) __P((unsigned long, struct trapframe *,
unsigned long, unsigned long));
void (*pci_intr_init) __P((void));
void (*pci_intr_map) __P((void *));
int (*pci_intr_route) __P((device_t, device_t, int));
void (*pci_intr_disable) __P((int));
void (*pci_intr_enable) __P((int));
int (*pci_setup_ide_intr) __P((struct device *dev,

View File

@ -71,7 +71,7 @@ int alpha_platform_pci_setup_intr(device_t dev, device_t child,
void **cookiep);
int alpha_platform_pci_teardown_intr(device_t dev, device_t child,
struct resource *irq, void *cookie);
int alpha_pci_route_interrupt(device_t bus, device_t dev, int pin);
#endif
void alpha_platform_assign_pciintr(struct pcicfg *cfg);
#endif /* !_MACHINE_MD_VAR_H_ */

View File

@ -64,6 +64,7 @@
#include <alpha/osf1/osf1.h>
#include <sys/proc.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <vm/vm.h>
#include <alpha/osf1/exec_ecoff.h>

View File

@ -44,6 +44,7 @@
#include <sys/reboot.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/bus.h>
#include <sys/mbuf.h>
#include <sys/vmmeter.h>
#include <sys/msgbuf.h>

View File

@ -35,6 +35,7 @@
#include <sys/rman.h>
#include <pci/pcivar.h>
#include <machine/swiz.h>
#include <machine/md_var.h>
#include <alpha/pci/apecsreg.h>
#include <alpha/pci/apecsvar.h>
@ -188,6 +189,7 @@ static device_method_t apecs_pcib_methods[] = {
DEVMETHOD(pcib_maxslots, apecs_pcib_maxslots),
DEVMETHOD(pcib_read_config, apecs_pcib_read_config),
DEVMETHOD(pcib_write_config, apecs_pcib_write_config),
DEVMETHOD(pcib_route_interrupt, alpha_pci_route_interrupt),
{ 0, 0 }
};

View File

@ -410,6 +410,7 @@ static device_method_t cia_pcib_methods[] = {
DEVMETHOD(pcib_maxslots, cia_pcib_maxslots),
DEVMETHOD(pcib_read_config, cia_pcib_read_config),
DEVMETHOD(pcib_write_config, cia_pcib_write_config),
DEVMETHOD(pcib_route_interrupt, alpha_pci_route_interrupt),
{ 0, 0 }
};

View File

@ -202,6 +202,8 @@ static device_method_t irongate_pcib_methods[] = {
DEVMETHOD(pcib_maxslots, irongate_pcib_maxslots),
DEVMETHOD(pcib_read_config, irongate_pcib_read_config),
DEVMETHOD(pcib_write_config, irongate_pcib_write_config),
DEVMETHOD(pcib_route_interrupt, alpha_pci_route_interrupt),
{ 0, 0 }
};

View File

@ -35,6 +35,7 @@
#include <sys/rman.h>
#include <pci/pcivar.h>
#include <machine/swiz.h>
#include <machine/md_var.h>
#include <alpha/pci/lcareg.h>
#include <alpha/pci/lcavar.h>
@ -184,6 +185,7 @@ static device_method_t lca_pcib_methods[] = {
DEVMETHOD(pcib_maxslots, lca_pcib_maxslots),
DEVMETHOD(pcib_read_config, lca_pcib_read_config),
DEVMETHOD(pcib_write_config, lca_pcib_write_config),
DEVMETHOD(pcib_route_interrupt, alpha_pci_route_interrupt),
{ 0, 0 }
};

View File

@ -76,11 +76,18 @@ SYSCTL_LONG(_hw_chipset, OID_AUTO, dense, CTLFLAG_RD, &chipset_dense, 0,
SYSCTL_LONG(_hw_chipset, OID_AUTO, hae_mask, CTLFLAG_RD, &chipset_hae_mask, 0,
"PCI chipset mask for HAE register");
void
alpha_platform_assign_pciintr(pcicfgregs *cfg)
int
alpha_pci_route_interrupt(device_t bus, device_t dev, int pin)
{
if(platform.pci_intr_map)
platform.pci_intr_map((void *)cfg);
/*
* Validate requested pin number.
*/
if ((pin < 1) || (pin > 4))
return(255);
if (platform.pci_intr_route)
return(platform.pci_intr_route(bus, dev, pin));
return(255);
}
#if NISA > 0

View File

@ -382,7 +382,7 @@ t2_attach(device_t dev)
*/
static int
t2_ICIC_slot_to_STDIO_irq(pcicfgregs *cfg)
t2_ICIC_slot_to_STDIO_irq(device_t bus, device_t dev, int pin)
{
int ret_irq = 0;
@ -391,36 +391,42 @@ t2_ICIC_slot_to_STDIO_irq(pcicfgregs *cfg)
* Return the interrupt pin number for the PCI slots.
*/
if ((cfg->intpin < 1) || (cfg->intpin > 4))
return(-1);
/* Generate the proper interrupt conversion for the physical
/*
* Generate the proper interrupt conversion for the physical
* PCI slots (for both the primary PCI slots and those behind
* a PPB). */
if ((cfg->slot >= 6) && (cfg->slot <= 9)) {
ret_irq = (32 + (4 * (cfg->slot - 6))) +
(cfg->intpin - 1) + (16 * cfg->secondarybus);
* a PPB).
*/
/*
* XXX This code is wrong; we need to determine the correct
* swizzle for devices behind the onboard PCI:PCI bridge
* and ensure that the generic bridge code doesn't try to
* reroute them.
*/
if ((pci_get_slot(dev) >= 6) && (pci_get_slot(dev) <= 9)) {
ret_irq = (32 + (4 * (pci_get_slot(dev) - 6))) +
(pin - 1) + (16 * pci_get_bus(dev));
return (ret_irq);
}
/* Convert the NCR810A chip behind the PPB */
if (cfg->slot == 1) {
if (pci_get_slot(dev) == 1) {
ret_irq = 28;
return (ret_irq);
}
/* Convert the NCR810A chip on the primary PCI bus or the
/*
* Convert the NCR810A chip on the primary PCI bus or the
* TULIP chip behind the PPB. There is no system that has
* both, so there really is no sharing going on although it
* looks like it. */
if ( (cfg->slot == 4) || (cfg->slot == 0) ) {
* looks like it.
*/
if ((pci_get_slot(dev) == 4) || (pci_get_slot(dev) == 0)) {
ret_irq = 24;
return (ret_irq);
}
printf("ICIC invalid pci slot: 0x%x intpin: 0x%x bus num:0x%x\n",
cfg->slot, cfg->intpin, cfg->bus);
pci_get_slot(dev), pin, pci_get_bus(dev));
return(-1);
}
@ -429,59 +435,54 @@ t2_ICIC_slot_to_STDIO_irq(pcicfgregs *cfg)
*/
static int
t2_pci0_slot_to_STDIO_irq(pcicfgregs *cfg)
t2_pci0_slot_to_STDIO_irq(device_t bus, device_t dev, int pin)
{
switch(cfg->slot) {
switch(pci_get_slot(dev)) {
case 0: /* ethernet (tulip) port */
return(0x2);
case 1: /* scsi 810 */
return(0x1);
case 6: /* optional slot 0 */
switch (cfg->intpin) {
switch (pin) {
case 1: return(0x0);
case 2: return(0x18);
case 3: return(0x1a);
case 4: return(0x1d);
}
case 7: /* optional slot 1 */
switch (cfg->intpin) {
switch (pin) {
case 1: return(0x4);
case 2: return(0x19);
case 3: return(0x1b);
case 4: return(0x1e);
}
case 8: /* optional slot 2 */
switch (cfg->intpin) {
switch (pin) {
case 1: return(0x5);
case 2: return(0x14);
case 3: return(0x1c);
case 4: return(0x1f);
}
default: /* invalid slot */
printf("PCI slot %d unknown\n", cfg->slot);
printf("PCI slot %d unknown\n", pci_get_slot(dev));
return(-1);
}
printf("invalid pci0 intpin slot: 0x%x intpin: 0x%x\n",
cfg->slot, cfg->intpin);
pci_get_slot(dev), pin);
return (-1);
}
void
t2_intr_map(void *arg)
int
t2_intr_route(device_t bus, device_t dev, int pin)
{
pcicfgregs *cfg;
cfg = (pcicfgregs *)arg;
if (pci_int_type[0]) {
t2_ICIC_slot_to_STDIO_irq(cfg);
return (t2_ICIC_slot_to_STDIO_irq(bus, dev, pin));
} else {
t2_pci0_slot_to_STDIO_irq(cfg);
return (t2_pci0_slot_to_STDIO_irq(bus, dev, pin));
}
}
/*
* magical mystery table partly obtained from Linux
* at least some of their values for PCI masks

View File

@ -35,6 +35,7 @@
#include <sys/rman.h>
#include <pci/pcivar.h>
#include <machine/swiz.h>
#include <machine/md_var.h>
#include <alpha/pci/t2reg.h>
#include <alpha/pci/t2var.h>
@ -190,6 +191,7 @@ static device_method_t t2_pcib_methods[] = {
DEVMETHOD(pcib_maxslots, t2_pcib_maxslots),
DEVMETHOD(pcib_read_config, t2_pcib_read_config),
DEVMETHOD(pcib_write_config, t2_pcib_write_config),
DEVMETHOD(pcib_route_interrupt, alpha_pci_route_interrupt),
{ 0, 0 }
};

View File

@ -29,4 +29,4 @@
extern vm_offset_t sable_lynx_base;
extern void t2_init(void);
void t2_intr_map(void *);
extern int t2_intr_route(device_t, device_t, int);

View File

@ -276,6 +276,7 @@ static device_method_t tsunami_pcib_methods[] = {
DEVMETHOD(pcib_maxslots, tsunami_pcib_maxslots),
DEVMETHOD(pcib_read_config, tsunami_pcib_read_config),
DEVMETHOD(pcib_write_config, tsunami_pcib_write_config),
DEVMETHOD(pcib_route_interrupt, alpha_pci_route_interrupt),
{ 0, 0 }
};

View File

@ -71,9 +71,9 @@ nexus_pcib_write_config(device_t dev, int bus, int slot, int func,
/* route interrupt */
static int
nexus_pcib_route_interrupt(device_t bus, int device, int pin)
nexus_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
{
return(pci_cfgintr(nexus_get_pcibus(bus), device, pin));
return(pci_cfgintr(pci_get_bus(dev), pci_get_slot(dev), pin));
}
static devclass_t pcib_devclass;

View File

@ -46,6 +46,10 @@
#include <machine/segments.h>
#include <machine/pc/bios.h>
#ifdef APIC_IO
#include <machine/smp.h>
#endif /* APIC_IO */
#include "pcib_if.h"
static int cfgmech;
@ -112,16 +116,62 @@ pci_cfgregopen(void)
}
/*
* Read configuration space register
* Read configuration space register
*/
u_int32_t
pci_cfgregread(int bus, int slot, int func, int reg, int bytes)
pci_do_cfgregread(int bus, int slot, int func, int reg, int bytes)
{
return(usebios ?
pcibios_cfgread(bus, slot, func, reg, bytes) :
pcireg_cfgread(bus, slot, func, reg, bytes));
}
u_int32_t
pci_cfgregread(int bus, int slot, int func, int reg, int bytes)
{
#ifdef APIC_IO
/*
* If we are using the APIC, the contents of the intline register will probably
* be wrong (since they are set up for use with the PIC.
* Rather than rewrite these registers (maybe that would be smarter) we trap
* attempts to read them and translate to our private vector numbers.
*/
if ((reg == PCIR_INTLINE) && (bytes == 1)) {
int pin, line, airq;
pin = pci_do_cfgregread(bus, slot, func, PCIR_INTPIN, 1);
line = pci_do_cfgregread(bus, slot, func, PCIR_INTLINE, 1);
if (pin != 0) {
int airq;
airq = pci_apic_irq(bus, slot, pin);
if (airq >= 0) {
/* PCI specific entry found in MP table */
if (airq != line)
undirect_pci_irq(line);
return(airq);
} else {
/*
* PCI interrupts might be redirected to the
* ISA bus according to some MP tables. Use the
* same methods as used by the ISA devices
* devices to find the proper IOAPIC int pin.
*/
airq = isa_apic_irq(line);
if ((airq >= 0) && (airq != line)) {
/* XXX: undirect_pci_irq() ? */
undirect_isa_irq(line);
return(airq);
}
}
}
return(line);
}
#endif /* APIC_IO */
return(pci_do_cfgregread(bus, slot, func, reg, bytes));
}
/*
* Write configuration space register
*/

128
sys/dev/pci/eisa_pci.c Normal file
View File

@ -0,0 +1,128 @@
/*-
* Copyright (c) 1994,1995 Stefan Esser, Wolfgang StanglMeier
* Copyright (c) 2000 Michael Smith <msmith@freebsd.org>
* Copyright (c) 2000 BSDi
* 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. The name of the author may not 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.
*
* $FreeBSD$
*/
/*
* PCI:EISA bridge support
*/
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
static int eisab_probe(device_t dev);
static int eisab_attach(device_t dev);
static device_method_t eisab_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, eisab_probe),
DEVMETHOD(device_attach, eisab_attach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
{ 0, 0 }
};
static driver_t eisab_driver = {
"eisab",
eisab_methods,
0,
};
static devclass_t eisab_devclass;
DRIVER_MODULE(eisab, pci, eisab_driver, eisab_devclass, 0, 0);
static int
eisab_probe(device_t dev)
{
int matched = 0;
/*
* Generic match by class/subclass.
*/
if ((pci_get_class(dev) == PCIC_BRIDGE) &&
(pci_get_subclass(dev) == PCIS_BRIDGE_EISA))
matched = 1;
/*
* Some bridges don't correctly report their class.
*/
switch (pci_get_devid(dev)) {
case 0x04828086: /* reports PCI-HOST class (!) */
matched = 1;
break;
default:
break;
}
if (matched) {
device_set_desc(dev, "PCI-EISA bridge");
return(-10000);
}
return(ENXIO);
}
static int
eisab_attach(device_t dev)
{
device_t child;
/*
* Attach an EISA bus. Note that we can only have one EISA bus.
*/
child = device_add_child(dev, "eisa", 0);
if (child != NULL)
return(bus_generic_attach(dev));
/*
* Attach an ISA bus as well (should this be a child of EISA?)
*/
child = device_add_child(dev, "isa", 0);
if (child != NULL)
bus_generic_attach(dev);
return(0);
}

116
sys/dev/pci/fixup_pci.c Normal file
View File

@ -0,0 +1,116 @@
/*-
* Copyright (c) 1994,1995 Stefan Esser, Wolfgang StanglMeier
* Copyright (c) 2000 Michael Smith <msmith@freebsd.org>
* Copyright (c) 2000 BSDi
* 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. The name of the author may not 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.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
/*
* Chipset fixups.
*
* These routines are invoked during the probe phase for devices which
* typically don't have specific device drivers, but which require
* some cleaning up.
*/
static int fixup_pci_probe(device_t dev);
static void fixbushigh_i1225(device_t dev);
static void fixwsc_natoma(device_t dev);
static device_method_t fixup_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, fixup_pci_probe),
DEVMETHOD(device_attach, bus_generic_attach),
{ 0, 0 }
};
static driver_t fixup_pci_driver = {
"fixup_pci",
fixup_pci_methods,
0,
};
static devclass_t fixup_pci_devclass;
DRIVER_MODULE(fixup_pci, pci, fixup_pci_driver, fixup_pci_devclass, 0, 0);
static int
fixup_pci_probe(device_t dev)
{
switch (pci_get_devid(dev)) {
case 0x12258086: /* Intel 82454KX/GX (Orion) */
fixbushigh_i1225(dev);
break;
case 0x12378086: /* Intel 82440FX (Natoma) */
fixwsc_natoma(dev);
break;
}
return(ENXIO);
}
static void
fixbushigh_i1225(device_t dev)
{
int supbus;
supbus = pci_read_config(dev, 0x41, 1);
if (supbus != 0xff) {
pci_set_secondarybus(dev, supbus + 1);
pci_set_subordinatebus(dev, supbus + 1);
}
}
static void
fixwsc_natoma(device_t dev)
{
int pmccfg;
pmccfg = pci_read_config(dev, 0x50, 2);
#if defined(SMP)
if (pmccfg & 0x8000) {
printf("Correcting Natoma config for SMP\n");
pmccfg &= ~0x8000;
pci_write_config(dev, 0x50, 2, pmccfg);
}
#else
if ((pmccfg & 0x8000) == 0) {
printf("Correcting Natoma config for non-SMP\n");
pmccfg |= 0x8000;
pci_write_config(dev, 0x50, 2, pmccfg);
}
#endif
}

70
sys/dev/pci/ignore_pci.c Normal file
View File

@ -0,0 +1,70 @@
/*-
* Copyright (c) 2000 Michael Smith <msmith@freebsd.org>
* Copyright (c) 2000 BSDi
* 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.
*
* $FreeBSD$
*/
/*
* 'Ignore' driver - eats devices that show up errnoeously on PCI
* but shouldn't ever be listed or handled by a driver.
*/
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <pci/pcivar.h>
static int ignore_pci_probe(device_t dev);
static device_method_t ignore_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ignore_pci_probe),
DEVMETHOD(device_attach, bus_generic_attach),
{ 0, 0 }
};
static driver_t ignore_pci_driver = {
"ignore_pci",
ignore_pci_methods,
0,
};
static devclass_t ignore_pci_devclass;
DRIVER_MODULE(ignore_pci, pci, ignore_pci_driver, ignore_pci_devclass, 0, 0);
static int
ignore_pci_probe(device_t dev)
{
switch (pci_get_devid(dev)) {
case 0x10001042ul: /* SMC 37C665 */
device_set_desc(dev, "ignored");
device_quiet(dev);
return(-10000);
}
return(ENXIO);
}

161
sys/dev/pci/isa_pci.c Normal file
View File

@ -0,0 +1,161 @@
/*-
* Copyright (c) 1994,1995 Stefan Esser, Wolfgang StanglMeier
* Copyright (c) 2000 Michael Smith <msmith@freebsd.org>
* Copyright (c) 2000 BSDi
* 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. The name of the author may not 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.
*
* $FreeBSD$
*/
/*
* PCI:ISA bridge support
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
static int isab_probe(device_t dev);
static int isab_attach(device_t dev);
static device_method_t isab_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, isab_probe),
DEVMETHOD(device_attach, isab_attach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
{ 0, 0 }
};
static driver_t isab_driver = {
"isab",
isab_methods,
0,
};
static devclass_t isab_devclass;
DRIVER_MODULE(isab, pci, isab_driver, isab_devclass, 0, 0);
/*
* XXX we need to add a quirk list here for bridges that don't correctly
* report themselves.
*/
static int
isab_probe(device_t dev)
{
int matched = 0;
/*
* Try for a generic match based on class/subclass.
*/
if ((pci_get_class(dev) == PCIC_BRIDGE) &&
(pci_get_subclass(dev) == PCIS_BRIDGE_ISA))
matched = 1;
/*
* Some bridges don't report the ISA bus correctly.
* (Note that some of the devices listed here probably do, we will
* kvetch about this below and request updates.)
*/
switch (pci_get_devid(dev)) {
case 0x04848086: /* Intel 82378ZB/82378IB */
case 0x122e8086: /* Intel 82371FB */
case 0x70008086: /* Intel 82371SB */
case 0x71108086: /* Intel 82371AB */
case 0x71988086: /* Intel 82443MX */
case 0x24108086: /* Intel 82801AA (ICH) */
case 0x24208086: /* Intel 82801AB (ICH0) */
case 0x24408086: /* Intel 82801BA (ICH2) */
case 0x00061004: /* VLSI 82C593 */
case 0x05861106: /* VIA 82C586 */
case 0x05961106: /* VIA 82C596 PCI-ISA */
case 0x06861106: /* VIA 82C686 PCI-ISA */
/* AcerLabs -- vendor 0x10b9 */
/* Funny : The datasheet told me vendor id is "10b8",sub-vendor */
/* id is '10b9" but the register always shows "10b9". -Foxfair */
case 0x153310b9: /* AcerLabs M1533 */
case 0x154310b9: /* AcerLabs M1543 */
case 0x00081039: /* SiS 85c503 */
case 0x00001078: /* Cyrix Cx5510 */
case 0x01001078: /* Cyrix Cx5530 */
case 0xc7001045: /* OPTi 82C700 (FireStar) */
case 0x00011033: /* NEC 0001 (C-bus) */
case 0x002c1033: /* NEC 002C (C-bus) */
case 0x003b1033: /* NEC 003B (C-bus) */
case 0x886a1060: /* UMC UM8886 ISA */
case 0x02001166: /* ServerWorks IB6566 PCI */
matched = 1;
/*
* Report redundant matches (debugging)
*/
if ((pci_get_class(dev) == PCIC_BRIDGE) &&
(pci_get_subclass(dev) == PCIS_BRIDGE_ISA)) {
printf("** REDUNDANT ISA BRIDGE MATCH FOR DEVICE 0x%08x\n", pci_get_devid(dev));
printf("** Please report to msmith@freebsd.org\n");
}
break;
default:
break;
}
if (matched) {
device_set_desc(dev, "PCI-ISA bridge");
return(-10000);
}
return(ENXIO);
}
static int
isab_attach(device_t dev)
{
device_t child;
/*
* Attach an ISA bus. Note that we can only have one ISA bus.
*/
child = device_add_child(dev, "isa", 0);
if (child != NULL)
return(bus_generic_attach(dev));
return(0);
}

View File

@ -29,13 +29,11 @@
#include "opt_bus.h"
#include "opt_simos.h"
#include "opt_compat_oldpci.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/linker.h>
#include <sys/fcntl.h>
#include <sys/conf.h>
#include <sys/kernel.h>
@ -50,7 +48,6 @@
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <machine/md_var.h> /* For the Alpha */
#include <sys/pciio.h>
#include <pci/pcireg.h>
@ -58,13 +55,9 @@
#include "pcib_if.h"
#ifdef __alpha__
#include <machine/rpb.h>
#endif
#ifdef APIC_IO
#include <machine/smp.h>
#endif /* APIC_IO */
static char *pci_vendordata;
static size_t pci_vendordata_size;
static char *pci_describe_device(device_t dev);
static devclass_t pci_devclass;
@ -178,52 +171,6 @@ pci_fixancient(pcicfgregs *cfg)
cfg->hdrtype = 1;
}
/* read config data specific to header type 1 device (PCI to PCI bridge) */
static void *
pci_readppb(device_t pcib, int b, int s, int f)
{
pcih1cfgregs *p;
p = malloc(sizeof (pcih1cfgregs), M_DEVBUF, M_WAITOK);
if (p == NULL)
return (NULL);
bzero(p, sizeof *p);
p->secstat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECSTAT_1, 2);
p->bridgectl = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_BRIDGECTL_1, 2);
p->seclat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECLAT_1, 1);
p->iobase = PCI_PPBIOBASE (PCIB_READ_CONFIG(pcib, b, s, f,
PCIR_IOBASEH_1, 2),
PCIB_READ_CONFIG(pcib, b, s, f,
PCIR_IOBASEL_1, 1));
p->iolimit = PCI_PPBIOLIMIT (PCIB_READ_CONFIG(pcib, b, s, f,
PCIR_IOLIMITH_1, 2),
PCIB_READ_CONFIG(pcib, b, s, f,
PCIR_IOLIMITL_1, 1));
p->membase = PCI_PPBMEMBASE (0,
PCIB_READ_CONFIG(pcib, b, s, f,
PCIR_MEMBASE_1, 2));
p->memlimit = PCI_PPBMEMLIMIT (0,
PCIB_READ_CONFIG(pcib, b, s, f,
PCIR_MEMLIMIT_1, 2));
p->pmembase = PCI_PPBMEMBASE (
(pci_addr_t)PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMBASEH_1, 4),
PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMBASEL_1, 2));
p->pmemlimit = PCI_PPBMEMLIMIT (
(pci_addr_t)PCIB_READ_CONFIG(pcib, b, s, f,
PCIR_PMLIMITH_1, 4),
PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMLIMITL_1, 2));
return (p);
}
/* read config data specific to header type 2 device (PCI to CardBus bridge) */
static void *
@ -231,12 +178,10 @@ pci_readpcb(device_t pcib, int b, int s, int f)
{
pcih2cfgregs *p;
p = malloc(sizeof (pcih2cfgregs), M_DEVBUF, M_WAITOK);
p = malloc(sizeof (pcih2cfgregs), M_DEVBUF, M_WAITOK | M_ZERO);
if (p == NULL)
return (NULL);
bzero(p, sizeof *p);
p->secstat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECSTAT_2, 2);
p->bridgectl = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_BRIDGECTL_2, 2);
@ -271,10 +216,7 @@ pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg)
case 1:
cfg->subvendor = REG(PCIR_SUBVEND_1, 2);
cfg->subdevice = REG(PCIR_SUBDEV_1, 2);
cfg->secondarybus = REG(PCIR_SECBUS_1, 1);
cfg->subordinatebus = REG(PCIR_SUBBUS_1, 1);
cfg->nummaps = PCI_MAXMAPS_1;
cfg->hdrspec = pci_readppb(pcib, b, s, f);
break;
case 2:
cfg->subvendor = REG(PCIR_SUBVEND_2, 2);
@ -304,10 +246,9 @@ pci_read_device(device_t pcib, int b, int s, int f)
if (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_DEVVENDOR, 4) != -1) {
devlist_entry = malloc(sizeof(struct pci_devinfo),
M_DEVBUF, M_WAITOK);
M_DEVBUF, M_WAITOK | M_ZERO);
if (devlist_entry == NULL)
return (NULL);
bzero(devlist_entry, sizeof *devlist_entry);
cfg = &devlist_entry->cfg;
@ -327,37 +268,6 @@ pci_read_device(device_t pcib, int b, int s, int f)
cfg->lattimer = REG(PCIR_LATTIMER, 1);
cfg->intpin = REG(PCIR_INTPIN, 1);
cfg->intline = REG(PCIR_INTLINE, 1);
#ifdef __alpha__
alpha_platform_assign_pciintr(cfg);
#endif
#ifdef APIC_IO
if (cfg->intpin != 0) {
int airq;
airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin);
if (airq >= 0) {
/* PCI specific entry found in MP table */
if (airq != cfg->intline) {
undirect_pci_irq(cfg->intline);
cfg->intline = airq;
}
} else {
/*
* PCI interrupts might be redirected to the
* ISA bus according to some MP tables. Use the
* same methods as used by the ISA devices
* devices to find the proper IOAPIC int pin.
*/
airq = isa_apic_irq(cfg->intline);
if ((airq >= 0) && (airq != cfg->intline)) {
/* XXX: undirect_pci_irq() ? */
undirect_isa_irq(cfg->intline);
cfg->intline = airq;
}
}
}
#endif /* APIC_IO */
cfg->mingnt = REG(PCIR_MINGNT, 1);
cfg->maxlat = REG(PCIR_MAXLAT, 1);
@ -1076,6 +986,7 @@ static int
pci_probe(device_t dev)
{
static int once, busno;
caddr_t vendordata, info;
device_set_desc(dev, "PCI bus");
@ -1095,6 +1006,14 @@ pci_probe(device_t dev)
if (!once) {
make_dev(&pcicdev, 0, UID_ROOT, GID_WHEEL, 0644, "pci");
if ((vendordata = preload_search_by_type("pci_vendor_data")) != NULL) {
info = preload_search_info(vendordata, MODINFO_ADDR);
pci_vendordata = *(char **)info;
info = preload_search_info(vendordata, MODINFO_SIZE);
pci_vendordata_size = *(size_t *)info;
/* terminate the database */
pci_vendordata[pci_vendordata_size] = '\n';
}
once++;
}
@ -1157,42 +1076,212 @@ pci_print_child(device_t dev, device_t child)
return (retval);
}
static struct
{
int class;
int subclass;
char *desc;
} pci_nomatch_tab[] = {
{PCIC_OLD, -1, "old"},
{PCIC_OLD, PCIS_OLD_NONVGA, "non-VGA display device"},
{PCIC_OLD, PCIS_OLD_VGA, "VGA-compatible display device"},
{PCIC_STORAGE, -1, "mass storage"},
{PCIC_STORAGE, PCIS_STORAGE_SCSI, "SCSI"},
{PCIC_STORAGE, PCIS_STORAGE_IDE, "ATA"},
{PCIC_STORAGE, PCIS_STORAGE_FLOPPY, "floppy disk"},
{PCIC_STORAGE, PCIS_STORAGE_IPI, "IPI"},
{PCIC_STORAGE, PCIS_STORAGE_RAID, "RAID"},
{PCIC_NETWORK, -1, "network"},
{PCIC_NETWORK, PCIS_NETWORK_ETHERNET, "ethernet"},
{PCIC_NETWORK, PCIS_NETWORK_TOKENRING, "token ring"},
{PCIC_NETWORK, PCIS_NETWORK_FDDI, "fddi"},
{PCIC_NETWORK, PCIS_NETWORK_ATM, "ATM"},
{PCIC_DISPLAY, -1, "display"},
{PCIC_DISPLAY, PCIS_DISPLAY_VGA, "VGA"},
{PCIC_DISPLAY, PCIS_DISPLAY_XGA, "XGA"},
{PCIC_MULTIMEDIA, -1, "multimedia"},
{PCIC_MULTIMEDIA, PCIS_MULTIMEDIA_VIDEO, "video"},
{PCIC_MULTIMEDIA, PCIS_MULTIMEDIA_AUDIO, "audio"},
{PCIC_MEMORY, -1, "memory"},
{PCIC_MEMORY, PCIS_MEMORY_RAM, "RAM"},
{PCIC_MEMORY, PCIS_MEMORY_FLASH, "flash"},
{PCIC_BRIDGE, -1, "bridge"},
{PCIC_BRIDGE, PCIS_BRIDGE_HOST, "HOST-PCI"},
{PCIC_BRIDGE, PCIS_BRIDGE_ISA, "PCI-ISA"},
{PCIC_BRIDGE, PCIS_BRIDGE_EISA, "PCI-EISA"},
{PCIC_BRIDGE, PCIS_BRIDGE_MCA, "PCI-MCA"},
{PCIC_BRIDGE, PCIS_BRIDGE_PCI, "PCI-PCI"},
{PCIC_BRIDGE, PCIS_BRIDGE_PCMCIA, "PCI-PCMCIA"},
{PCIC_BRIDGE, PCIS_BRIDGE_NUBUS, "PCI-NuBus"},
{PCIC_BRIDGE, PCIS_BRIDGE_CARDBUS, "PCI-CardBus"},
{PCIC_BRIDGE, PCIS_BRIDGE_OTHER, "PCI-unknown"},
{PCIC_SIMPLECOMM, -1, "simple comms"},
{PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_UART, "UART"}, /* could detect 16550 */
{PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_PAR, "parallel port"},
{PCIC_BASEPERIPH, -1, "base peripheral"},
{PCIC_BASEPERIPH, PCIS_BASEPERIPH_PIC, "interrupt controller"},
{PCIC_BASEPERIPH, PCIS_BASEPERIPH_DMA, "DMA controller"},
{PCIC_BASEPERIPH, PCIS_BASEPERIPH_TIMER, "timer"},
{PCIC_BASEPERIPH, PCIS_BASEPERIPH_RTC, "realtime clock"},
{PCIC_INPUTDEV, -1, "input device"},
{PCIC_INPUTDEV, PCIS_INPUTDEV_KEYBOARD, "keyboard"},
{PCIC_INPUTDEV, PCIS_INPUTDEV_DIGITIZER,"digitizer"},
{PCIC_INPUTDEV, PCIS_INPUTDEV_MOUSE, "mouse"},
{PCIC_DOCKING, -1, "docking station"},
{PCIC_PROCESSOR, -1, "processor"},
{PCIC_SERIALBUS, -1, "serial bus"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_FW, "FireWire"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_ACCESS, "AccessBus"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_SSA, "SSA"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_USB, "USB"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_FC, "Fibre Channel"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_SMBUS, "SMBus"},
{0, 0, NULL}
};
static void
pci_probe_nomatch(device_t dev, device_t child)
{
struct pci_devinfo *dinfo;
pcicfgregs *cfg;
const char *desc;
int unknown;
unknown = 0;
dinfo = device_get_ivars(child);
cfg = &dinfo->cfg;
desc = pci_ata_match(child);
if (!desc) desc = pci_usb_match(child);
if (!desc) desc = pci_vga_match(child);
if (!desc) desc = pci_chip_match(child);
if (!desc) {
desc = "unknown card";
unknown++;
int i;
char *cp, *scp, *device;
/*
* Look for a listing for this device in a loaded device database.
*/
if ((device = pci_describe_device(child)) != NULL) {
printf("<%s>", device);
free(device, M_DEVBUF);
} else {
/*
* Scan the class/subclass descriptions for a general description.
*/
cp = "unknown";
scp = NULL;
for (i = 0; pci_nomatch_tab[i].desc != NULL; i++) {
if (pci_nomatch_tab[i].class == pci_get_class(child)) {
if (pci_nomatch_tab[i].subclass == -1) {
cp = pci_nomatch_tab[i].desc;
} else if (pci_nomatch_tab[i].subclass == pci_get_subclass(child)) {
scp = pci_nomatch_tab[i].desc;
}
}
}
device_printf(dev, "<%s%s%s>",
cp ? : "",
((cp != NULL) && (scp != NULL)) ? ", " : "",
scp ? : "");
}
device_printf(dev, "<%s>", desc);
if (bootverbose || unknown) {
printf(" (vendor=0x%04x, dev=0x%04x)",
cfg->vendor,
cfg->device);
}
printf(" at %d.%d",
pci_get_slot(child),
pci_get_function(child));
if (cfg->intpin > 0 && cfg->intline != 255) {
printf(" irq %d", cfg->intline);
}
printf("\n");
printf(" at %d:%d (no driver attached)\n",
pci_get_slot(child),
pci_get_function(child));
return;
}
/*
* Parse the PCI device database, if loaded, and return a pointer to a
* description of the device.
*
* The database is flat text formatted as follows:
*
* Any line not in a valid format is ignored.
* Lines are terminated with newline '\n' characters.
*
* A VENDOR line consists of the 4 digit (hex) vendor code, a TAB, then
* the vendor name.
*
* A DEVICE line is entered immediately below the corresponding VENDOR ID.
* - devices cannot be listed without a corresponding VENDOR line.
* A DEVICE line consists of a TAB, the 4 digit (hex) device code,
* another TAB, then the device name.
*/
/*
* Assuming (ptr) points to the beginning of a line in the database,
* return the vendor or device and description of the next entry.
* The value of (vendor) or (device) inappropriate for the entry type
* is set to -1. Returns nonzero at the end of the database.
*
* Note that this is slightly unrobust in the face of corrupt data;
* we attempt to safeguard against this by spamming the end of the
* database with a newline when we initialise.
*/
static int
pci_describe_parse_line(char **ptr, int *vendor, int *device, char **desc)
{
char *cp = *ptr;
*device = -1;
*vendor = -1;
*desc = NULL;
for (;;) {
if ((cp - pci_vendordata) >= pci_vendordata_size)
return(1);
/* vendor entry? */
if (sscanf(cp, "%x\t%80[^\n]", vendor, *desc) == 2)
break;
/* device entry? */
if (sscanf(cp, "\t%x\t%80[^\n]", device, *desc) == 2)
break;
/* skip to next line */
while (*cp != '\n')
cp++;
cp++;
}
*ptr = cp;
return(0);
}
static char *
pci_describe_device(device_t dev)
{
int vendor, device;
char *desc, *vp, *dp, *line;
desc = vp = dp = NULL;
/*
* If we have no vendor data, we can't do anything.
*/
if (pci_vendordata == NULL)
goto out;
/*
* Scan the vendor data looking for this device
*/
line = pci_vendordata;
if ((vp = malloc(80, M_DEVBUF, M_NOWAIT)) == NULL)
goto out;
for (;;) {
if (pci_describe_parse_line(&line, &vendor, &device, &vp))
goto out;
if (vendor == pci_get_vendor(dev))
break;
}
if ((dp = malloc(80, M_DEVBUF, M_NOWAIT)) == NULL)
goto out;
for (;;) {
if (pci_describe_parse_line(&line, &vendor, &device, &dp))
goto out;
if (vendor != -1) {
*dp = 0;
break;
}
if (device == pci_get_device(dev))
break;
}
if ((desc = malloc(strlen(vp) + strlen(dp) + 3, M_DEVBUF, M_NOWAIT)) != NULL)
sprintf(desc, "%s%s%s", vp, (dp[0] != 0) ? ", " : "", dp);
out:
if (vp != NULL)
free(vp, M_DEVBUF);
if (dp != NULL)
free(dp, M_DEVBUF);
return(desc);
}
static int
pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
@ -1309,16 +1398,17 @@ pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
* XXX add support here for SYS_RES_IOPORT and SYS_RES_MEMORY
*/
if (device_get_parent(child) == dev) {
if ((type == SYS_RES_IRQ) && (cfg->intline == 255)) {
#ifdef __i386__
cfg->intline = PCIB_ROUTE_INTERRUPT(
device_get_parent(dev), pci_get_slot(child),
cfg->intpin);
#endif /* __i386__ */
/*
* If device doesn't have an interrupt routed, and is deserving of
* an interrupt, try to assign it one.
*/
if ((type == SYS_RES_IRQ) && (cfg->intline == 255) && (cfg->intpin != 0)) {
cfg->intline = PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child,
cfg->intpin);
if (cfg->intline != 255) {
pci_write_config(child, PCIR_INTLINE, cfg->intline, 1);
resource_list_add(rl, SYS_RES_IRQ, 0,
cfg->intline, cfg->intline, 1);
cfg->intline, cfg->intline, 1);
}
}
}
@ -1419,7 +1509,7 @@ static device_method_t pci_methods[] = {
static driver_t pci_driver = {
"pci",
pci_methods,
1, /* no softc */
0, /* no softc */
};
DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0);
DRIVER_MODULE(pci, acpi_pcib, pci_driver, pci_devclass, pci_modevent, 0);

334
sys/dev/pci/pci_pci.c Normal file
View File

@ -0,0 +1,334 @@
/*-
* Copyright (c) 1994,1995 Stefan Esser, Wolfgang StanglMeier
* Copyright (c) 2000 Michael Smith <msmith@freebsd.org>
* Copyright (c) 2000 BSDi
* 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. The name of the author may not 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.
*
* $FreeBSD$
*/
/*
* PCI:PCI bridge support.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <machine/resource.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
#include "pcib_if.h"
/*
* Bridge-specific data.
*/
struct pcib_softc
{
device_t dev;
u_int8_t secbus; /* secondary bus number */
u_int8_t subbus; /* subordinate bus number */
pci_addr_t pmembase; /* base address of prefetchable memory */
pci_addr_t pmemlimit; /* topmost address of prefetchable memory */
u_int32_t membase; /* base address of memory window */
u_int32_t memlimit; /* topmost address of memory window */
u_int32_t iobase; /* base address of port window */
u_int32_t iolimit; /* topmost address of port window */
u_int16_t secstat; /* secondary bus status register */
u_int16_t bridgectl; /* bridge control register */
u_int8_t seclat; /* secondary bus latency timer */
};
static int pcib_probe(device_t dev);
static int pcib_attach(device_t dev);
static int pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result);
static int pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value);
static struct resource *pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags);
static int pcib_maxslots(device_t dev);
static u_int32_t pcib_read_config(device_t dev, int b, int s, int f, int reg, int width);
static void pcib_write_config(device_t dev, int b, int s, int f, int reg, u_int32_t val, int width);
static int pcib_route_interrupt(device_t pcib, device_t dev, int pin);
static device_method_t pcib_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pcib_probe),
DEVMETHOD(device_attach, pcib_attach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_read_ivar, pcib_read_ivar),
DEVMETHOD(bus_write_ivar, pcib_write_ivar),
DEVMETHOD(bus_alloc_resource, pcib_alloc_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
/* pcib interface */
DEVMETHOD(pcib_maxslots, pcib_maxslots),
DEVMETHOD(pcib_read_config, pcib_read_config),
DEVMETHOD(pcib_write_config, pcib_write_config),
DEVMETHOD(pcib_route_interrupt, pcib_route_interrupt),
{ 0, 0 }
};
static driver_t pcib_driver = {
"pcib",
pcib_methods,
sizeof(struct pcib_softc),
};
static devclass_t pcib_devclass;
DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, 0, 0);
/*
* Generic device interface
*/
static int
pcib_probe(device_t dev)
{
if ((pci_get_class(dev) == PCIC_BRIDGE) &&
(pci_get_subclass(dev) == PCIS_BRIDGE_PCI)) {
device_set_desc(dev, "PCI-PCI bridge");
return(-10000);
}
return(ENXIO);
}
static int
pcib_attach(device_t dev)
{
struct pcib_softc *sc;
device_t pcib, child;
int b, s, f;
sc = device_get_softc(dev);
sc->dev = dev;
pcib = device_get_parent(dev);
b = pci_get_bus(dev);
s = pci_get_slot(dev);
f = pci_get_function(dev);
sc->secbus = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECBUS_1, 1);
sc->subbus = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SUBBUS_1, 1);
sc->secstat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECSTAT_1, 2);
sc->bridgectl = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_BRIDGECTL_1, 2);
sc->seclat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECLAT_1, 1);
sc->iobase = PCI_PPBIOBASE(PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOBASEH_1, 2),
PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOBASEL_1, 1));
sc->iolimit = PCI_PPBIOLIMIT(PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOLIMITH_1, 2),
PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOLIMITL_1, 1));
sc->membase = PCI_PPBMEMBASE(0, PCIB_READ_CONFIG(pcib, b, s, f, PCIR_MEMBASE_1, 2));
sc->memlimit = PCI_PPBMEMLIMIT(0, PCIB_READ_CONFIG(pcib, b, s, f, PCIR_MEMLIMIT_1, 2));
sc->pmembase = PCI_PPBMEMBASE((pci_addr_t)PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMBASEH_1, 4),
PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMBASEL_1, 2));
sc->pmemlimit = PCI_PPBMEMLIMIT((pci_addr_t)PCIB_READ_CONFIG(pcib, b, s, f,PCIR_PMLIMITH_1, 4),
PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMLIMITL_1, 2));
if (bootverbose) {
device_printf(dev, " secondary bus %d\n", sc->secbus);
device_printf(dev, " subordinate bus %d\n", sc->subbus);
device_printf(dev, " I/O decode 0x%x-0x%x\n", sc->iobase, sc->iolimit);
device_printf(dev, " memory decode 0x%x-0x%x\n", sc->membase, sc->memlimit);
device_printf(dev, " prefetched decode 0x%x-0x%x\n", sc->pmembase, sc->pmemlimit);
}
/*
* XXX If the secondary bus number is zero, we should assign a bus number
* since the BIOS hasn't, then initialise the bridge.
*/
/*
* XXX If the subordinate bus number is less than the secondary bus number,
* we should pick a better value. One sensible alternative would be to
* pick 255; the only tradeoff here is that configuration transactions
* would be more widely routed than absolutely necessary.
*/
if (sc->secbus != 0) {
child = device_add_child(dev, "pci", -1);
if (child != NULL)
return(bus_generic_attach(dev));
}
/* no secondary bus; we should have fixed this */
return(0);
}
static int
pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pcib_softc *sc = device_get_softc(dev);
switch (which) {
case PCIB_IVAR_BUS:
*result = sc->secbus;
return(0);
}
return(ENOENT);
}
static int
pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
{
struct pcib_softc *sc = device_get_softc(dev);
switch (which) {
case PCIB_IVAR_BUS:
sc->secbus = value;
break;
}
return(ENOENT);
}
/*
* We have to trap resource allocation requests and ensure that the bridge
* is set up to, or capable of handling them.
*/
static struct resource *
pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct pcib_softc *sc = device_get_softc(dev);
/*
* If this is a "default" allocation against this rid, we can't work
* out where it's coming from (we should actually never see these) so we
* just have to punt.
*/
if ((start == 0) && (end == ~0)) {
device_printf(dev, "can't decode default resource id %d for %s%d, bypassing\n",
*rid, device_get_name(child), device_get_unit(child));
} else {
/*
* Fail the allocation for this range if it's not supported.
*
* XXX we should probably just fix up the bridge decode and soldier on.
*/
switch (type) {
case SYS_RES_IOPORT:
if ((start < sc->iobase) || (end > sc->iolimit)) {
device_printf(dev, "device %s%d requested unsupported I/O range 0x%lx-0x%lx"
" (decoding 0x%x-0x%x)\n",
device_get_name(child), device_get_unit(child), start, end,
sc->iobase, sc->iolimit);
return(NULL);
}
break;
/*
* XXX will have to decide whether the device making the request is asking
* for prefetchable memory or not. If it's coming from another bridge
* down the line, do we assume not, or ask the bridge to pass in another
* flag as the request bubbles up?
*/
case SYS_RES_MEMORY:
if (((start < sc->membase) || (end > sc->memlimit)) &&
((start < sc->pmembase) || (end > sc->pmemlimit))) {
device_printf(dev, "device %s%d requested unsupported memory range 0x%lx-0x%lx"
" (decoding 0x%x-0x%x, 0x%x-0x%x)\n",
device_get_name(child), device_get_unit(child), start, end,
sc->membase, sc->memlimit, sc->pmembase, sc->pmemlimit);
return(NULL);
}
default:
}
}
device_printf(sc->dev, "resource request type %d 0x%lx-0x%lx decodes OK\n",
type, start, end);
/*
* Bridge is OK decoding this resource, so pass it up.
*/
return(bus_generic_alloc_resource(dev, child, type, rid, start, end, count, flags));
}
/*
* PCIB interface.
*/
static int
pcib_maxslots(device_t dev)
{
return(31);
}
/*
* Since we are a child of a PCI bus, its parent must support the pcib interface.
*/
static u_int32_t
pcib_read_config(device_t dev, int b, int s, int f, int reg, int width)
{
return(PCIB_READ_CONFIG(device_get_parent(device_get_parent(dev)), b, s, f, reg, width));
}
static void
pcib_write_config(device_t dev, int b, int s, int f, int reg, u_int32_t val, int width)
{
PCIB_WRITE_CONFIG(device_get_parent(device_get_parent(dev)), b, s, f, reg, val, width);
}
/*
* Route an interrupt across a PCI bridge.
*/
static int
pcib_route_interrupt(device_t pcib, device_t dev, int pin)
{
device_t bus;
int parent_intpin;
int intnum;
/*
*
* The PCI standard defines a swizzle of the child-side device/intpin to
* the parent-side intpin as follows.
*
* device = device on child bus
* child_intpin = intpin on child bus slot (0-3)
* parent_intpin = intpin on parent bus slot (0-3)
*
* parent_intpin = (device + child_intpin) % 4
*/
parent_intpin = (pci_get_slot(pcib) + (pin - 1)) % 4;
/*
* Our parent is a PCI bus. Its parent must export the pcib interface
* which includes the ability to route interrupts.
*/
bus = device_get_parent(pcib);
intnum = PCIB_ROUTE_INTERRUPT(device_get_parent(bus), pcib, parent_intpin + 1);
device_printf(pcib, "routed slot %d INT%c to irq %d\n", pci_get_slot(dev),
'A' + pin - 1, intnum);
return(intnum);
}

View File

@ -144,13 +144,6 @@ struct pci_devinfo {
};
#endif
/* externally visible functions */
const char *pci_ata_match(struct device *dev);
const char *pci_usb_match(struct device *dev);
const char *pci_vga_match(struct device *dev);
const char *pci_chip_match(struct device *dev);
/* low level PCI config register functions provided by pcibus.c */
int pci_cfgread (pcicfgregs *cfg, int reg, int bytes);

75
sys/dev/pci/vga_pci.c Normal file
View File

@ -0,0 +1,75 @@
/*-
* Copyright (c) 2000 Michael Smith <msmith@freebsd.org>
* Copyright (c) 2000 BSDi
* 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.
*
* $FreeBSD$
*/
/*
* Stub handler for PCI VGA-compatible adapters.
*/
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
static int vga_pci_probe(device_t dev);
static device_method_t vga_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, vga_pci_probe),
DEVMETHOD(device_attach, bus_generic_attach),
{ 0, 0 }
};
static driver_t vga_pci_driver = {
"vga_pci",
vga_pci_methods,
0,
};
static devclass_t vga_pci_devclass;
DRIVER_MODULE(vga_pci, pci, vga_pci_driver, vga_pci_devclass, 0, 0);
static int
vga_pci_probe(device_t dev)
{
if ((pci_get_class(dev) == PCIC_OLD) &&
(pci_get_subclass(dev) == PCIS_OLD_VGA)) {
device_set_desc(dev, "VGA-compatible display device");
return(-10000);
}
if ((pci_get_class(dev) == PCIC_DISPLAY) &&
(pci_get_subclass(dev) == PCIS_DISPLAY_VGA)) {
device_set_desc(dev, "VGA-compatible display device");
return(-10000);
}
return(ENXIO);
}

View File

@ -71,9 +71,9 @@ nexus_pcib_write_config(device_t dev, int bus, int slot, int func,
/* route interrupt */
static int
nexus_pcib_route_interrupt(device_t bus, int device, int pin)
nexus_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
{
return(pci_cfgintr(nexus_get_pcibus(bus), device, pin));
return(pci_cfgintr(pci_get_bus(dev), pci_get_slot(dev), pin));
}
static devclass_t pcib_devclass;

View File

@ -46,6 +46,10 @@
#include <machine/segments.h>
#include <machine/pc/bios.h>
#ifdef APIC_IO
#include <machine/smp.h>
#endif /* APIC_IO */
#include "pcib_if.h"
static int cfgmech;
@ -112,16 +116,62 @@ pci_cfgregopen(void)
}
/*
* Read configuration space register
* Read configuration space register
*/
u_int32_t
pci_cfgregread(int bus, int slot, int func, int reg, int bytes)
pci_do_cfgregread(int bus, int slot, int func, int reg, int bytes)
{
return(usebios ?
pcibios_cfgread(bus, slot, func, reg, bytes) :
pcireg_cfgread(bus, slot, func, reg, bytes));
}
u_int32_t
pci_cfgregread(int bus, int slot, int func, int reg, int bytes)
{
#ifdef APIC_IO
/*
* If we are using the APIC, the contents of the intline register will probably
* be wrong (since they are set up for use with the PIC.
* Rather than rewrite these registers (maybe that would be smarter) we trap
* attempts to read them and translate to our private vector numbers.
*/
if ((reg == PCIR_INTLINE) && (bytes == 1)) {
int pin, line, airq;
pin = pci_do_cfgregread(bus, slot, func, PCIR_INTPIN, 1);
line = pci_do_cfgregread(bus, slot, func, PCIR_INTLINE, 1);
if (pin != 0) {
int airq;
airq = pci_apic_irq(bus, slot, pin);
if (airq >= 0) {
/* PCI specific entry found in MP table */
if (airq != line)
undirect_pci_irq(line);
return(airq);
} else {
/*
* PCI interrupts might be redirected to the
* ISA bus according to some MP tables. Use the
* same methods as used by the ISA devices
* devices to find the proper IOAPIC int pin.
*/
airq = isa_apic_irq(line);
if ((airq >= 0) && (airq != line)) {
/* XXX: undirect_pci_irq() ? */
undirect_isa_irq(line);
return(airq);
}
}
}
return(line);
}
#endif /* APIC_IO */
return(pci_do_cfgregread(bus, slot, func, reg, bytes));
}
/*
* Write configuration space register
*/

View File

@ -46,6 +46,10 @@
#include <machine/segments.h>
#include <machine/pc/bios.h>
#ifdef APIC_IO
#include <machine/smp.h>
#endif /* APIC_IO */
#include "pcib_if.h"
static int cfgmech;
@ -112,16 +116,62 @@ pci_cfgregopen(void)
}
/*
* Read configuration space register
* Read configuration space register
*/
u_int32_t
pci_cfgregread(int bus, int slot, int func, int reg, int bytes)
pci_do_cfgregread(int bus, int slot, int func, int reg, int bytes)
{
return(usebios ?
pcibios_cfgread(bus, slot, func, reg, bytes) :
pcireg_cfgread(bus, slot, func, reg, bytes));
}
u_int32_t
pci_cfgregread(int bus, int slot, int func, int reg, int bytes)
{
#ifdef APIC_IO
/*
* If we are using the APIC, the contents of the intline register will probably
* be wrong (since they are set up for use with the PIC.
* Rather than rewrite these registers (maybe that would be smarter) we trap
* attempts to read them and translate to our private vector numbers.
*/
if ((reg == PCIR_INTLINE) && (bytes == 1)) {
int pin, line, airq;
pin = pci_do_cfgregread(bus, slot, func, PCIR_INTPIN, 1);
line = pci_do_cfgregread(bus, slot, func, PCIR_INTLINE, 1);
if (pin != 0) {
int airq;
airq = pci_apic_irq(bus, slot, pin);
if (airq >= 0) {
/* PCI specific entry found in MP table */
if (airq != line)
undirect_pci_irq(line);
return(airq);
} else {
/*
* PCI interrupts might be redirected to the
* ISA bus according to some MP tables. Use the
* same methods as used by the ISA devices
* devices to find the proper IOAPIC int pin.
*/
airq = isa_apic_irq(line);
if ((airq >= 0) && (airq != line)) {
/* XXX: undirect_pci_irq() ? */
undirect_isa_irq(line);
return(airq);
}
}
}
return(line);
}
#endif /* APIC_IO */
return(pci_do_cfgregread(bus, slot, func, reg, bytes));
}
/*
* Write configuration space register
*/

View File

@ -6,6 +6,6 @@ SRCS = agp.c agp_intel.c agp_via.c agp_sis.c agp_ali.c agp_amd.c
SRCS += agp_i810.c agp_if.c
SRCS += device_if.h bus_if.h agp_if.h pci_if.h
SRCS += opt_bdg.h opt_bus.h opt_pci.h
MFILES = kern/device_if.m kern/bus_if.m pci/agp_if.m pci/pci_if.m
MFILES = kern/device_if.m kern/bus_if.m pci/agp_if.m dev/pci/pci_if.m
.include <bsd.kmod.mk>

View File

@ -3,7 +3,7 @@
KMOD= ng_tty
SRCS= ng_tty.c device_if.h bus_if.h pci_if.h
MFILES= kern/device_if.m kern/bus_if.m pci/agp_if.m pci/pci_if.m
MFILES= kern/device_if.m kern/bus_if.m pci/agp_if.m dev/pci/pci_if.m
NOMAN=
.include <bsd.kmod.mk>

View File

@ -7,7 +7,7 @@ MAINTAINER= gallatin@FreeBSD.org
KMOD= osf1
SRCS= osf1_ioctl.c osf1_misc.c osf1_signal.c osf1_sysent.c \
osf1_mount.c imgact_osf1.c osf1_sysvec.c opt_compat.h \
opt_simos.h opt_nfs.h vnode_if.h
opt_simos.h opt_nfs.h device_if.h bus_if.h vnode_if.h
#CFLAGS+= -g
EXPORT_SYMS= _osf1

File diff suppressed because it is too large Load Diff

View File

@ -1,46 +0,0 @@
#
# Copyright (c) 1998 Doug Rabson
# 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.
#
# $FreeBSD$
#
#include <sys/bus.h>
INTERFACE pci;
METHOD u_int32_t read_config {
device_t dev;
device_t child;
int reg;
int width;
};
METHOD void write_config {
device_t dev;
device_t child;
int reg;
u_int32_t val;
int width;
};

View File

@ -1,81 +0,0 @@
#
# Copyright (c) 2000 Doug Rabson
# 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.
#
# $FreeBSD$
#
#include <sys/bus.h>
INTERFACE pcib;
#
# Return the number of slots on the attached PCI bus.
#
METHOD int maxslots {
device_t dev;
};
#
# Read configuration space on the PCI bus. The bus, slot and func
# arguments determine the device which is being read and the reg
# argument is a byte offset into configuration space for that
# device. The width argument (which should be 1, 2 or 4) specifies how
# many byte of configuration space to read from that offset.
#
METHOD u_int32_t read_config {
device_t dev;
u_int bus;
u_int slot;
u_int func;
u_int reg;
int width;
};
#
# Write configuration space on the PCI bus. The bus, slot and func
# arguments determine the device which is being written and the reg
# argument is a byte offset into configuration space for that
# device. The value field is written to the configuration space, with
# the number of bytes written depending on the width argument.
#
METHOD void write_config {
device_t dev;
u_int bus;
u_int slot;
u_int func;
u_int reg;
u_int32_t value;
int width;
};
#
# Route an interrupt. Returns a value suitable for stuffing into
# a device's interrupt register.
#
METHOD int route_interrupt {
device_t dev;
int device;
int pin;
};

View File

@ -1,261 +0,0 @@
/*
* Copyright (c) 1997, Stefan Esser <se@freebsd.org>
* 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 unmodified, 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 ``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 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.
*
* $FreeBSD$
*
*/
/*
* PCIM_xxx: mask to locate subfield in register
* PCIR_xxx: config register offset
* PCIC_xxx: device class
* PCIS_xxx: device subclass
* PCIP_xxx: device programming interface
* PCIV_xxx: PCI vendor ID (only required to fixup ancient devices)
* PCID_xxx: device ID
*/
/* some PCI bus constants */
#define PCI_BUSMAX 255
#define PCI_SLOTMAX 31
#define PCI_FUNCMAX 7
#define PCI_REGMAX 255
/* PCI config header registers for all devices */
#define PCIR_DEVVENDOR 0x00
#define PCIR_VENDOR 0x00
#define PCIR_DEVICE 0x02
#define PCIR_COMMAND 0x04
#define PCIM_CMD_PORTEN 0x0001
#define PCIM_CMD_MEMEN 0x0002
#define PCIM_CMD_MWRICEN 0x0010
#define PCIM_CMD_BUSMASTEREN 0x0004
#define PCIM_CMD_PERRESPEN 0x0040
#define PCIR_STATUS 0x06
#define PCIR_REVID 0x08
#define PCIR_PROGIF 0x09
#define PCIR_SUBCLASS 0x0a
#define PCIR_CLASS 0x0b
#define PCIR_CACHELNSZ 0x0c
#define PCIR_LATTIMER 0x0d
#define PCIR_HEADERTYPE 0x0e
#define PCIM_MFDEV 0x80
#define PCIR_BIST 0x0f
/* config registers for header type 0 devices */
#define PCIR_MAPS 0x10
#define PCIR_CARDBUSCIS 0x28
#define PCIR_SUBVEND_0 0x2c
#define PCIR_SUBDEV_0 0x2e
#define PCIR_BIOS 0x30
#define PCIM_BIOS_ENABLE 0x01
#define PCIR_INTLINE 0x3c
#define PCIR_INTPIN 0x3d
#define PCIR_MINGNT 0x3e
#define PCIR_MAXLAT 0x3f
/* config registers for header type 1 devices */
#define PCIR_SECSTAT_1 0 /**/
#define PCIR_PRIBUS_1 0x18
#define PCIR_SECBUS_1 0x19
#define PCIR_SUBBUS_1 0x1a
#define PCIR_SECLAT_1 0x1b
#define PCIR_IOBASEL_1 0x1c
#define PCIR_IOLIMITL_1 0x1d
#define PCIR_IOBASEH_1 0 /**/
#define PCIR_IOLIMITH_1 0 /**/
#define PCIR_MEMBASE_1 0x20
#define PCIR_MEMLIMIT_1 0x22
#define PCIR_PMBASEL_1 0x24
#define PCIR_PMLIMITL_1 0x26
#define PCIR_PMBASEH_1 0 /**/
#define PCIR_PMLIMITH_1 0 /**/
#define PCIR_BRIDGECTL_1 0 /**/
#define PCIR_SUBVEND_1 0x34
#define PCIR_SUBDEV_1 0x36
/* config registers for header type 2 devices */
#define PCIR_SECSTAT_2 0x16
#define PCIR_PRIBUS_2 0x18
#define PCIR_SECBUS_2 0x19
#define PCIR_SUBBUS_2 0x1a
#define PCIR_SECLAT_2 0x1b
#define PCIR_MEMBASE0_2 0x1c
#define PCIR_MEMLIMIT0_2 0x20
#define PCIR_MEMBASE1_2 0x24
#define PCIR_MEMLIMIT1_2 0x28
#define PCIR_IOBASE0_2 0x2c
#define PCIR_IOLIMIT0_2 0x30
#define PCIR_IOBASE1_2 0x34
#define PCIR_IOLIMIT1_2 0x38
#define PCIR_BRIDGECTL_2 0x3e
#define PCIR_SUBVEND_2 0x40
#define PCIR_SUBDEV_2 0x42
#define PCIR_PCCARDIF_2 0x44
/* PCI device class, subclass and programming interface definitions */
#define PCIC_OLD 0x00
#define PCIS_OLD_NONVGA 0x00
#define PCIS_OLD_VGA 0x01
#define PCIC_STORAGE 0x01
#define PCIS_STORAGE_SCSI 0x00
#define PCIS_STORAGE_IDE 0x01
#define PCIP_STORAGE_IDE_MODEPRIM 0x01
#define PCIP_STORAGE_IDE_PROGINDPRIM 0x02
#define PCIP_STORAGE_IDE_MODESEC 0x04
#define PCIP_STORAGE_IDE_PROGINDSEC 0x08
#define PCIP_STORAGE_IDE_MASTERDEV 0x80
#define PCIS_STORAGE_FLOPPY 0x02
#define PCIS_STORAGE_IPI 0x03
#define PCIS_STORAGE_RAID 0x04
#define PCIS_STORAGE_OTHER 0x80
#define PCIC_NETWORK 0x02
#define PCIS_NETWORK_ETHERNET 0x00
#define PCIS_NETWORK_TOKENRING 0x01
#define PCIS_NETWORK_FDDI 0x02
#define PCIS_NETWORK_ATM 0x03
#define PCIS_NETWORK_OTHER 0x80
#define PCIC_DISPLAY 0x03
#define PCIS_DISPLAY_VGA 0x00
#define PCIS_DISPLAY_XGA 0x01
#define PCIS_DISPLAY_OTHER 0x80
#define PCIC_MULTIMEDIA 0x04
#define PCIS_MULTIMEDIA_VIDEO 0x00
#define PCIS_MULTIMEDIA_AUDIO 0x01
#define PCIS_MULTIMEDIA_OTHER 0x80
#define PCIC_MEMORY 0x05
#define PCIS_MEMORY_RAM 0x00
#define PCIS_MEMORY_FLASH 0x01
#define PCIS_MEMORY_OTHER 0x80
#define PCIC_BRIDGE 0x06
#define PCIS_BRIDGE_HOST 0x00
#define PCIS_BRIDGE_ISA 0x01
#define PCIS_BRIDGE_EISA 0x02
#define PCIS_BRIDGE_MCA 0x03
#define PCIS_BRIDGE_PCI 0x04
#define PCIS_BRIDGE_PCMCIA 0x05
#define PCIS_BRIDGE_NUBUS 0x06
#define PCIS_BRIDGE_CARDBUS 0x07
#define PCIS_BRIDGE_OTHER 0x80
#define PCIC_SIMPLECOMM 0x07
#define PCIS_SIMPLECOMM_UART 0x00
#define PCIP_SIMPLECOMM_UART_16550A 0x02
#define PCIS_SIMPLECOMM_PAR 0x01
#define PCIS_SIMPLECOMM_OTHER 0x80
#define PCIC_BASEPERIPH 0x08
#define PCIS_BASEPERIPH_PIC 0x00
#define PCIS_BASEPERIPH_DMA 0x01
#define PCIS_BASEPERIPH_TIMER 0x02
#define PCIS_BASEPERIPH_RTC 0x03
#define PCIS_BASEPERIPH_OTHER 0x80
#define PCIC_INPUTDEV 0x09
#define PCIS_INPUTDEV_KEYBOARD 0x00
#define PCIS_INPUTDEV_DIGITIZER 0x01
#define PCIS_INPUTDEV_MOUSE 0x02
#define PCIS_INPUTDEV_OTHER 0x80
#define PCIC_DOCKING 0x0a
#define PCIS_DOCKING_GENERIC 0x00
#define PCIS_DOCKING_OTHER 0x80
#define PCIC_PROCESSOR 0x0b
#define PCIS_PROCESSOR_386 0x00
#define PCIS_PROCESSOR_486 0x01
#define PCIS_PROCESSOR_PENTIUM 0x02
#define PCIS_PROCESSOR_ALPHA 0x10
#define PCIS_PROCESSOR_POWERPC 0x20
#define PCIS_PROCESSOR_COPROC 0x40
#define PCIC_SERIALBUS 0x0c
#define PCIS_SERIALBUS_FW 0x00
#define PCIS_SERIALBUS_ACCESS 0x01
#define PCIS_SERIALBUS_SSA 0x02
#define PCIS_SERIALBUS_USB 0x03
#define PCIS_SERIALBUS_FC 0x04
#define PCIS_SERIALBUS_SMBUS 0x05
#define PCIC_OTHER 0xff
/* some PCI vendor definitions (only used to identify ancient devices !!! */
#define PCIV_INTEL 0x8086
#define PCID_INTEL_SATURN 0x0483
#define PCID_INTEL_ORION 0x84c4
/* for compatibility to FreeBSD-2.2 and 3.x versions of PCI code */
#if defined(_KERNEL) && !defined(KLD_MODULE)
#include "opt_compat_oldpci.h"
#endif
#ifdef COMPAT_OLDPCI
#define PCI_ID_REG 0x00
#define PCI_COMMAND_STATUS_REG 0x04
#define PCI_COMMAND_IO_ENABLE 0x00000001
#define PCI_COMMAND_MEM_ENABLE 0x00000002
#define PCI_CLASS_REG 0x08
#define PCI_CLASS_MASK 0xff000000
#define PCI_SUBCLASS_MASK 0x00ff0000
#define PCI_REVISION_MASK 0x000000ff
#define PCI_CLASS_PREHISTORIC 0x00000000
#define PCI_SUBCLASS_PREHISTORIC_VGA 0x00010000
#define PCI_CLASS_MASS_STORAGE 0x01000000
#define PCI_CLASS_DISPLAY 0x03000000
#define PCI_SUBCLASS_DISPLAY_VGA 0x00000000
#define PCI_CLASS_BRIDGE 0x06000000
#define PCI_MAP_REG_START 0x10
#define PCI_MAP_REG_END 0x28
#define PCI_MAP_IO 0x00000001
#define PCI_INTERRUPT_REG 0x3c
#endif /* COMPAT_OLDPCI */

File diff suppressed because it is too large Load Diff

View File

@ -1,332 +0,0 @@
/*
* Copyright (c) 1997, Stefan Esser <se@freebsd.org>
* 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 unmodified, 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 ``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 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.
*
* $FreeBSD$
*
*/
#ifndef _PCIVAR_H_
#define _PCIVAR_H_
#include <sys/queue.h>
/* some PCI bus constants */
#define PCI_BUSMAX 255 /* highest supported bus number */
#define PCI_SLOTMAX 31 /* highest supported slot number */
#define PCI_FUNCMAX 7 /* highest supported function number */
#define PCI_REGMAX 255 /* highest supported config register addr. */
#define PCI_MAXMAPS_0 6 /* max. no. of memory/port maps */
#define PCI_MAXMAPS_1 2 /* max. no. of maps for PCI to PCI bridge */
#define PCI_MAXMAPS_2 1 /* max. no. of maps for CardBus bridge */
/* pci_addr_t covers this system's PCI bus address space: 32 or 64 bit */
#ifdef PCI_A64
typedef u_int64_t pci_addr_t; /* u_int64_t for system with 64bit addresses */
#else
typedef u_int32_t pci_addr_t; /* u_int64_t for system with 64bit addresses */
#endif
/* config header information common to all header types */
typedef struct pcicfg {
struct device *dev; /* device which owns this */
void *hdrspec; /* pointer to header type specific data */
u_int16_t subvendor; /* card vendor ID */
u_int16_t subdevice; /* card device ID, assigned by card vendor */
u_int16_t vendor; /* chip vendor ID */
u_int16_t device; /* chip device ID, assigned by chip vendor */
u_int16_t cmdreg; /* disable/enable chip and PCI options */
u_int16_t statreg; /* supported PCI features and error state */
u_int8_t baseclass; /* chip PCI class */
u_int8_t subclass; /* chip PCI subclass */
u_int8_t progif; /* chip PCI programming interface */
u_int8_t revid; /* chip revision ID */
u_int8_t hdrtype; /* chip config header type */
u_int8_t cachelnsz; /* cache line size in 4byte units */
u_int8_t intpin; /* PCI interrupt pin */
u_int8_t intline; /* interrupt line (IRQ for PC arch) */
u_int8_t mingnt; /* min. useful bus grant time in 250ns units */
u_int8_t maxlat; /* max. tolerated bus grant latency in 250ns */
u_int8_t lattimer; /* latency timer in units of 30ns bus cycles */
u_int8_t mfdev; /* multi-function device (from hdrtype reg) */
u_int8_t nummaps; /* actual number of PCI maps used */
u_int8_t bus; /* config space bus address */
u_int8_t slot; /* config space slot address */
u_int8_t func; /* config space function number */
u_int8_t secondarybus; /* bus on secondary side of bridge, if any */
u_int8_t subordinatebus; /* topmost bus number behind bridge, if any */
} pcicfgregs;
/* additional type 1 device config header information (PCI to PCI bridge) */
#ifdef PCI_A64
#define PCI_PPBMEMBASE(h,l) ((((pci_addr_t)(h) << 32) + ((l)<<16)) & ~0xfffff)
#define PCI_PPBMEMLIMIT(h,l) ((((pci_addr_t)(h) << 32) + ((l)<<16)) | 0xfffff)
#else
#define PCI_PPBMEMBASE(h,l) (((l)<<16) & ~0xfffff)
#define PCI_PPBMEMLIMIT(h,l) (((l)<<16) | 0xfffff)
#endif /* PCI_A64 */
#define PCI_PPBIOBASE(h,l) ((((h)<<16) + ((l)<<8)) & ~0xfff)
#define PCI_PPBIOLIMIT(h,l) ((((h)<<16) + ((l)<<8)) | 0xfff)
typedef struct {
pci_addr_t pmembase; /* base address of prefetchable memory */
pci_addr_t pmemlimit; /* topmost address of prefetchable memory */
u_int32_t membase; /* base address of memory window */
u_int32_t memlimit; /* topmost address of memory window */
u_int32_t iobase; /* base address of port window */
u_int32_t iolimit; /* topmost address of port window */
u_int16_t secstat; /* secondary bus status register */
u_int16_t bridgectl; /* bridge control register */
u_int8_t seclat; /* CardBus latency timer */
} pcih1cfgregs;
/* additional type 2 device config header information (CardBus bridge) */
typedef struct {
u_int32_t membase0; /* base address of memory window */
u_int32_t memlimit0; /* topmost address of memory window */
u_int32_t membase1; /* base address of memory window */
u_int32_t memlimit1; /* topmost address of memory window */
u_int32_t iobase0; /* base address of port window */
u_int32_t iolimit0; /* topmost address of port window */
u_int32_t iobase1; /* base address of port window */
u_int32_t iolimit1; /* topmost address of port window */
u_int32_t pccardif; /* PC Card 16bit IF legacy more base addr. */
u_int16_t secstat; /* secondary bus status register */
u_int16_t bridgectl; /* bridge control register */
u_int8_t seclat; /* CardBus latency timer */
} pcih2cfgregs;
extern u_int32_t pci_numdevs;
/* Only if the prerequisites are present */
#if defined(_SYS_BUS_H_) && defined(_SYS_PCIIO_H_)
struct pci_devinfo {
STAILQ_ENTRY(pci_devinfo) pci_links;
struct resource_list resources;
pcicfgregs cfg;
struct pci_conf conf;
};
#endif
/* externally visible functions */
const char *pci_ata_match(struct device *dev);
const char *pci_usb_match(struct device *dev);
const char *pci_vga_match(struct device *dev);
const char *pci_chip_match(struct device *dev);
/* low level PCI config register functions provided by pcibus.c */
int pci_cfgread (pcicfgregs *cfg, int reg, int bytes);
void pci_cfgwrite (pcicfgregs *cfg, int reg, int data, int bytes);
#ifdef __alpha__
vm_offset_t pci_cvt_to_dense (vm_offset_t);
vm_offset_t pci_cvt_to_bwx (vm_offset_t);
#endif /* __alpha__ */
/* low level devlist operations for the 2.2 compatibility code in pci.c */
pcicfgregs * pci_devlist_get_parent(pcicfgregs *cfg);
#ifdef _SYS_BUS_H_
#include "pci_if.h"
/*
* Define pci-specific resource flags for accessing memory via dense
* or bwx memory spaces. These flags are ignored on i386.
*/
#define PCI_RF_DENSE 0x10000
#define PCI_RF_BWX 0x20000
enum pci_device_ivars {
PCI_IVAR_SUBVENDOR,
PCI_IVAR_SUBDEVICE,
PCI_IVAR_VENDOR,
PCI_IVAR_DEVICE,
PCI_IVAR_DEVID,
PCI_IVAR_CLASS,
PCI_IVAR_SUBCLASS,
PCI_IVAR_PROGIF,
PCI_IVAR_REVID,
PCI_IVAR_INTPIN,
PCI_IVAR_IRQ,
PCI_IVAR_BUS,
PCI_IVAR_SLOT,
PCI_IVAR_FUNCTION,
PCI_IVAR_SECONDARYBUS,
PCI_IVAR_SUBORDINATEBUS,
};
/*
* Simplified accessors for pci devices
*/
#define PCI_ACCESSOR(A, B, T) \
\
static __inline T pci_get_ ## A(device_t dev) \
{ \
uintptr_t v; \
BUS_READ_IVAR(device_get_parent(dev), dev, PCI_IVAR_ ## B, &v); \
return (T) v; \
} \
\
static __inline void pci_set_ ## A(device_t dev, T t) \
{ \
uintptr_t v = (uintptr_t) t; \
BUS_WRITE_IVAR(device_get_parent(dev), dev, PCI_IVAR_ ## B, v); \
}
PCI_ACCESSOR(subvendor, SUBVENDOR, u_int16_t)
PCI_ACCESSOR(subdevice, SUBDEVICE, u_int16_t)
PCI_ACCESSOR(vendor, VENDOR, u_int16_t)
PCI_ACCESSOR(device, DEVICE, u_int16_t)
PCI_ACCESSOR(devid, DEVID, u_int32_t)
PCI_ACCESSOR(class, CLASS, u_int8_t)
PCI_ACCESSOR(subclass, SUBCLASS, u_int8_t)
PCI_ACCESSOR(progif, PROGIF, u_int8_t)
PCI_ACCESSOR(revid, REVID, u_int8_t)
PCI_ACCESSOR(intpin, INTPIN, u_int8_t)
PCI_ACCESSOR(irq, IRQ, u_int8_t)
PCI_ACCESSOR(bus, BUS, u_int8_t)
PCI_ACCESSOR(slot, SLOT, u_int8_t)
PCI_ACCESSOR(function, FUNCTION, u_int8_t)
PCI_ACCESSOR(secondarybus, SECONDARYBUS, u_int8_t)
PCI_ACCESSOR(subordinatebus, SUBORDINATEBUS, u_int8_t)
#undef PCI_ACCESSOR
static __inline u_int32_t
pci_read_config(device_t dev, int reg, int width)
{
return PCI_READ_CONFIG(device_get_parent(dev), dev, reg, width);
}
static __inline void
pci_write_config(device_t dev, int reg, u_int32_t val, int width)
{
PCI_WRITE_CONFIG(device_get_parent(dev), dev, reg, val, width);
}
/*
* Ivars for pci bridges.
*/
/*typedef enum pci_device_ivars pcib_device_ivars;*/
enum pcib_device_ivars {
PCIB_IVAR_BUS
};
#define PCIB_ACCESSOR(A, B, T) \
\
static __inline T pcib_get_ ## A(device_t dev) \
{ \
uintptr_t v; \
BUS_READ_IVAR(device_get_parent(dev), dev, PCIB_IVAR_ ## B, &v); \
return (T) v; \
} \
\
static __inline void pcib_set_ ## A(device_t dev, T t) \
{ \
uintptr_t v = (uintptr_t) t; \
BUS_WRITE_IVAR(device_get_parent(dev), dev, PCIB_IVAR_ ## B, v); \
}
PCIB_ACCESSOR(bus, BUS, u_int32_t)
#undef PCIB_ACCESSOR
#endif
/* for compatibility to FreeBSD-2.2 and 3.x versions of PCI code */
#if defined(_KERNEL) && !defined(KLD_MODULE)
#include "opt_compat_oldpci.h"
#endif
#ifdef COMPAT_OLDPCI
/* all this is going some day */
typedef pcicfgregs *pcici_t;
typedef unsigned pcidi_t;
typedef void pci_inthand_t(void *arg);
#define pci_max_burst_len (3)
/* just copied from old PCI code for now ... */
struct pci_device {
char* pd_name;
const char* (*pd_probe ) (pcici_t tag, pcidi_t type);
void (*pd_attach) (pcici_t tag, int unit);
u_long *pd_count;
int (*pd_shutdown) (int, int);
};
#ifdef __i386__
typedef u_short pci_port_t;
#else
typedef u_int pci_port_t;
#endif
u_long pci_conf_read (pcici_t tag, u_long reg);
void pci_conf_write (pcici_t tag, u_long reg, u_long data);
int pci_map_port (pcici_t tag, u_long reg, pci_port_t* pa);
int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa);
int pci_map_int (pcici_t tag, pci_inthand_t *handler, void *arg,
intrmask_t *maskptr);
int pci_map_int_right(pcici_t cfg, pci_inthand_t *handler, void *arg,
intrmask_t *maskptr, u_int flags);
int pci_unmap_int (pcici_t tag);
pcici_t pci_get_parent_from_tag(pcici_t tag);
int pci_get_bus_from_tag(pcici_t tag);
struct module;
int compat_pci_handler (struct module *, int, void *);
#define COMPAT_PCI_DRIVER(name, pcidata) \
static moduledata_t name##_mod = { \
#name, \
compat_pci_handler, \
&pcidata \
}; \
DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_ANY)
#endif /* COMPAT_OLDPCI */
#endif /* _PCIVAR_H_ */

View File

@ -71,7 +71,7 @@ int alpha_platform_pci_setup_intr(device_t dev, device_t child,
void **cookiep);
int alpha_platform_pci_teardown_intr(device_t dev, device_t child,
struct resource *irq, void *cookie);
int alpha_pci_route_interrupt(device_t bus, device_t dev, int pin);
#endif
void alpha_platform_assign_pciintr(struct pcicfg *cfg);
#endif /* !_MACHINE_MD_VAR_H_ */