summaryrefslogtreecommitdiffstats
path: root/sys/pci/pci_compat.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1999-04-16 21:22:55 +0000
committerpeter <peter@FreeBSD.org>1999-04-16 21:22:55 +0000
commit087d4857e56f150a8f549600150404f273efb895 (patch)
treecf4e27432c59d956f4e5784207180115ee8fef9d /sys/pci/pci_compat.c
parentc5fe612b8411a32a8e6e426fc1a70cba0cca3d31 (diff)
downloadFreeBSD-src-087d4857e56f150a8f549600150404f273efb895.zip
FreeBSD-src-087d4857e56f150a8f549600150404f273efb895.tar.gz
Bring the 'new-bus' to the i386. This extensively changes the way the
i386 platform boots, it is no longer ISA-centric, and is fully dynamic. Most old drivers compile and run without modification via 'compatability shims' to enable a smoother transition. eisa, isapnp and pccard* are not yet using the new resource manager. Once fully converted, all drivers will be loadable, including PCI and ISA. (Some other changes appear to have snuck in, including a port of Soren's ATA driver to the Alpha. Soren, back this out if you need to.) This is a checkpoint of work-in-progress, but is quite functional. The bulk of the work was done over the last few years by Doug Rabson and Garrett Wollman. Approved by: core
Diffstat (limited to 'sys/pci/pci_compat.c')
-rw-r--r--sys/pci/pci_compat.c192
1 files changed, 84 insertions, 108 deletions
diff --git a/sys/pci/pci_compat.c b/sys/pci/pci_compat.c
index f107e54..bfa1d59 100644
--- a/sys/pci/pci_compat.c
+++ b/sys/pci/pci_compat.c
@@ -23,10 +23,12 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pci_compat.c,v 1.20 1999/01/19 23:29:19 se Exp $
+ * $Id: pci_compat.c,v 1.21 1999/04/11 02:46:20 eivind Exp $
*
*/
+#include "opt_bus.h"
+
#include "pci.h"
#if NPCI > 0
@@ -41,6 +43,11 @@
#include <vm/pmap.h>
#include <sys/interrupt.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
#include <pci/pcireg.h>
#include <pci/pcivar.h>
@@ -56,118 +63,45 @@
/* ------------------------------------------------------------------------- */
-static int
-pci_mapno(pcicfgregs *cfg, int reg)
-{
- int i, nummaps;
- pcimap *map;
-
- nummaps = cfg->nummaps;
- map = cfg->map;
-
- for (i = 0; i < nummaps; i++)
- if (map[i].reg == reg)
- return (i);
- return (-1);
-}
-
-static int
-pci_porten(pcicfgregs *cfg)
-{
- return ((cfg->cmdreg & PCIM_CMD_PORTEN) != 0);
-}
-
-static int
-pci_isportmap(pcicfgregs *cfg, int map)
-
-{
- return ((unsigned)map < cfg->nummaps
- && (cfg->map[map].type & PCI_MAPPORT) != 0);
-}
-
-static int
-pci_memen(pcicfgregs *cfg)
-{
- return ((cfg->cmdreg & PCIM_CMD_MEMEN) != 0);
-}
-
-static int
-pci_ismemmap(pcicfgregs *cfg, int map)
-{
- return ((unsigned)map < cfg->nummaps
- && (cfg->map[map].type & PCI_MAPMEM) != 0);
-}
-
-/* ------------------------------------------------------------------------- */
-
u_long
-pci_conf_read(pcici_t tag, u_long reg)
+pci_conf_read(pcici_t cfg, u_long reg)
{
- return (pci_cfgread(tag, reg, 4));
+ return (pci_read_config(cfg->dev, reg, 4));
}
void
-pci_conf_write(pcici_t tag, u_long reg, u_long data)
+pci_conf_write(pcici_t cfg, u_long reg, u_long data)
{
- pci_cfgwrite(tag, reg, data, 4);
+ pci_write_config(cfg->dev, reg, data, 4);
}
int pci_map_port(pcici_t cfg, u_long reg, pci_port_t* pa)
{
- int map;
-
- map = pci_mapno(cfg, reg);
- if (pci_porten(cfg) && pci_isportmap(cfg, map)) {
- u_int32_t iobase;
- u_int32_t iosize;
-
- iobase = cfg->map[map].base;
- iosize = 1 << cfg->map[map].ln2size;
-#ifdef RESOURCE_CHECK
- if (resource_claim(cfg, REST_PORT, RESF_NONE,
- iobase, iobase + iosize -1) == 0)
-#endif /* RESOURCE_CHECK */
- {
- *pa = iobase;
- return (1);
- }
+ int rid;
+ struct resource *res;
+
+ rid = reg;
+ res = bus_alloc_resource(cfg->dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (res) {
+ *pa = rman_get_start(res);
+ return (1);
}
return (0);
}
int pci_map_mem(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
{
- int map;
-
- map = pci_mapno(cfg, reg);
- if (pci_memen(cfg) && pci_ismemmap(cfg, map)) {
- u_int32_t paddr;
- u_int32_t psize;
-
- paddr = cfg->map[map].base;
- psize = 1 << cfg->map[map].ln2size;
-#ifdef RESOURCE_CHECK
- if (resource_claim(cfg, REST_MEM, RESF_NONE,
- paddr, paddr + psize -1) == 0)
-#endif /* RESOURCE_CHECK */
- {
- u_int32_t poffs;
- vm_offset_t vaddr;
-
- poffs = paddr - trunc_page(paddr);
-#ifdef __i386__
- vaddr = (vm_offset_t)pmap_mapdev(paddr-poffs, psize+poffs);
-#endif
-#ifdef __alpha__
- vaddr = paddr-poffs;
-#endif
- if (vaddr != NULL) {
- vaddr += poffs;
- *va = vaddr;
- *pa = paddr;
- return (1);
- }
- }
+ int rid;
+ struct resource *res;
+
+ rid = reg;
+ res = bus_alloc_resource(cfg->dev, SYS_RES_MEMORY, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (res) {
+ *pa = rman_get_start(res);
+ *va = (vm_offset_t) rman_get_virtual(res);
+ return (1);
}
return (0);
}
@@ -175,7 +109,7 @@ int pci_map_mem(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
int
pci_map_dense(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
{
- if(pci_map_mem(cfg, reg, va, pa)){
+ if (pci_map_mem(cfg, reg, va, pa)){
#ifdef __alpha__
vm_offset_t dense;
@@ -195,7 +129,7 @@ pci_map_dense(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
int
pci_map_bwx(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
{
- if(pci_map_mem(cfg, reg, va, pa)){
+ if (pci_map_mem(cfg, reg, va, pa)){
#ifdef __alpha__
vm_offset_t bwx;
@@ -228,14 +162,42 @@ pci_map_int_right(pcici_t cfg, pci_inthand_t *handler, void *arg,
#endif
if (cfg->intpin != 0) {
int irq = cfg->intline;
- void *dev_instance = (void *)-1; /* XXX use cfg->devdata */
- void *idesc;
+ driver_t *driver = device_get_driver(cfg->dev);
+ int rid = 0;
+ struct resource *res;
+ void *ih;
+ res = bus_alloc_resource(cfg->dev, SYS_RES_IRQ, &rid,
+ irq, irq, 1, RF_SHAREABLE|RF_ACTIVE);
+ if (!res) {
+ printf("pci_map_int: can't allocate interrupt\n");
+ return 0;
+ }
- idesc = intr_create(dev_instance, irq, handler, arg, maskptr,
- flags);
- error = intr_connect(idesc);
+ /*
+ * This is ugly. Translate the mask into a driver type.
+ */
+ if (maskptr == &tty_imask)
+ driver->type |= DRIVER_TYPE_TTY;
+ else if (maskptr == &bio_imask)
+ driver->type |= DRIVER_TYPE_BIO;
+ else if (maskptr == &net_imask)
+ driver->type |= DRIVER_TYPE_NET;
+ else if (maskptr == &cam_imask)
+ driver->type |= DRIVER_TYPE_CAM;
+
+ error = BUS_SETUP_INTR(device_get_parent(cfg->dev), cfg->dev,
+ res, handler, arg, &ih);
if (error != 0)
return 0;
+
+#ifdef NEW_BUS_PCI
+ /*
+ * XXX this apic stuff looks totally busted. It should
+ * move to the nexus code which actually registers the
+ * interrupt.
+ */
+#endif
+
#ifdef APIC_IO
nextpin = next_apic_irq(irq);
@@ -265,11 +227,21 @@ pci_map_int_right(pcici_t cfg, pci_inthand_t *handler, void *arg,
nextpin = next_apic_irq(irq);
while (nextpin >= 0) {
- idesc = intr_create(dev_instance, nextpin, handler,
- arg, maskptr, flags);
- error = intr_connect(idesc);
- if (error != 0)
+ rid = 0;
+ res = bus_alloc_resource(cfg->dev, SYS_RES_IRQ, &rid,
+ nextpin, nextpin, 1,
+ RF_SHAREABLE|RF_ACTIVE);
+ if (!res) {
+ printf("pci_map_int: can't allocate extra interrupt\n");
+ return 0;
+ }
+ error = BUS_SETUP_INTR(device_get_parent(cfg->dev),
+ cfg->dev, res, handler, arg,
+ &ih);
+ if (error != 0) {
+ printf("pci_map_int: BUS_SETUP_INTR failed\n");
return 0;
+ }
printf("Registered extra interrupt handler for int %d (in addition to int %d)\n", nextpin, irq);
nextpin = next_apic_irq(nextpin);
}
@@ -284,6 +256,7 @@ pci_unmap_int(pcici_t cfg)
return (0); /* not supported, yet, since cfg doesn't know about idesc */
}
+#if 0
/* ------------------------------------------------------------------------- */
/*
@@ -464,6 +437,7 @@ int pci_register_lkm (struct pci_device *dvp, int if_revision)
if (lkm == NULL) {
return (-1);
}
+ bzero(lkm, sizeof (*lkm));
lkm->dvp = dvp;
lkm->next = pci_lkm_head;
@@ -480,5 +454,7 @@ pci_configure(void)
/* ------------------------------------------------------------------------- */
+#endif
+
#endif /* PCI_COMPAT */
#endif /* NPCI > 0 */
OpenPOWER on IntegriCloud