summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/agp.c4
-rw-r--r--sys/dev/pci/agp_i810.c24
-rw-r--r--sys/dev/pci/agpvar.h4
-rw-r--r--sys/dev/pci/drm/drmP.h23
-rw-r--r--sys/dev/pci/drm/drm_bufs.c29
-rw-r--r--sys/dev/pci/drm/drm_drv.c6
-rw-r--r--sys/dev/pci/drm/drm_memory.c52
-rw-r--r--sys/dev/pci/drm/i915_drv.c3
-rw-r--r--sys/dev/pci/drm/mach64_drv.c2
-rw-r--r--sys/dev/pci/drm/mga_drv.c2
-rw-r--r--sys/dev/pci/drm/r128_drv.c2
-rw-r--r--sys/dev/pci/drm/radeon_drv.c2
-rw-r--r--sys/dev/pci/drm/savage_drv.c2
-rw-r--r--sys/dev/pci/drm/sis_drv.c2
-rw-r--r--sys/dev/pci/drm/tdfx_drv.c2
-rw-r--r--sys/dev/pci/drm/via_drv.c2
-rw-r--r--sys/dev/pci/vga_pci.c110
-rw-r--r--sys/dev/pci/vga_pcivar.h29
18 files changed, 218 insertions, 82 deletions
diff --git a/sys/dev/pci/agp.c b/sys/dev/pci/agp.c
index 6c297f9031a..15f31704d45 100644
--- a/sys/dev/pci/agp.c
+++ b/sys/dev/pci/agp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp.c,v 1.20 2008/04/09 18:59:58 oga Exp $ */
+/* $OpenBSD: agp.c,v 1.21 2008/05/06 19:19:02 oga Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
@@ -176,6 +176,8 @@ agp_attach(struct device *parent, struct device *self, void *aux)
pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_AGP,
&sc->sc_capoff, NULL);
+ sc->vga_softc = (struct vga_pci_softc *)parent;
+
printf(": ");
ret = (*ap->ap_attach)(sc, pa);
if (ret == 0)
diff --git a/sys/dev/pci/agp_i810.c b/sys/dev/pci/agp_i810.c
index 67fbb6ee66c..cb7e1c013b0 100644
--- a/sys/dev/pci/agp_i810.c
+++ b/sys/dev/pci/agp_i810.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp_i810.c,v 1.34 2008/03/23 19:54:47 oga Exp $ */
+/* $OpenBSD: agp_i810.c,v 1.35 2008/05/06 19:19:02 oga Exp $ */
/* $NetBSD: agp_i810.c,v 1.15 2003/01/31 00:07:39 thorpej Exp $ */
/*-
@@ -157,6 +157,7 @@ agp_i810_attach(struct agp_softc *sc, struct pci_attach_args *pa)
struct agp_i810_softc *isc;
struct agp_gatt *gatt;
bus_addr_t mmaddr, gmaddr;
+ struct vga_pci_bar *map;
int error;
u_int memtype = 0;
@@ -251,26 +252,27 @@ agp_i810_attach(struct agp_softc *sc, struct pci_attach_args *pa)
return (error);
}
- if (isc->chiptype == CHIP_I965)
- memtype = pci_mapreg_type(isc->vga_pa.pa_pc,
- isc->vga_pa.pa_tag, mmaddr);
-
- error = pci_mapreg_map(&isc->vga_pa, mmaddr, memtype, 0,
- &isc->bst, &isc->bsh, NULL, &isc->bsz, 0);
- if (error != 0) {
+ map = vga_pci_bar_map(sc->vga_softc, mmaddr, 0,
+ BUS_SPACE_MAP_LINEAR);
+ if (map == NULL) {
printf("can't map mmadr registers\n");
agp_generic_detach(sc);
return (error);
}
+ isc->bst = map->bst;
+ isc->bsh = map->bsh;
+ isc->bsz = map->size;
if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33) {
- error = pci_mapreg_map(&isc->vga_pa, AGP_I915_GTTADR, memtype,
- 0, &isc->gtt_bst, &isc->gtt_bsh, NULL, NULL, 0);
- if (error != 0) {
+ map = vga_pci_bar_map(sc->vga_softc, AGP_I915_GTTADR,
+ 0, BUS_SPACE_MAP_LINEAR);
+ if (map == NULL) {
printf("can't map gatt registers\n");
agp_generic_detach(sc);
return (error);
}
+ isc->gtt_bst = map->bst;
+ isc->gtt_bsh = map->bsh;
}
isc->initial_aperture = AGP_GET_APERTURE(sc);
diff --git a/sys/dev/pci/agpvar.h b/sys/dev/pci/agpvar.h
index 5c5a0de6686..8f80f7769eb 100644
--- a/sys/dev/pci/agpvar.h
+++ b/sys/dev/pci/agpvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: agpvar.h,v 1.12 2008/03/23 19:54:47 oga Exp $ */
+/* $OpenBSD: agpvar.h,v 1.13 2008/05/06 19:19:02 oga Exp $ */
/* $NetBSD: agpvar.h,v 1.4 2001/10/01 21:54:48 fvdl Exp $ */
/*-
@@ -146,6 +146,8 @@ struct agp_softc {
u_int32_t sc_allocated; /* amount allocated */
enum agp_acquire_state sc_state;
struct agp_memory_list sc_memory; /* list of allocated memory */
+
+ struct vga_pci_softc *vga_softc; /* needed for shared mappings */
};
struct agp_gatt {
diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h
index 07fd6976d4a..f93246c0e93 100644
--- a/sys/dev/pci/drm/drmP.h
+++ b/sys/dev/pci/drm/drmP.h
@@ -676,18 +676,6 @@ typedef struct drm_sg_mem {
drm_dma_handle_t *dmah; /* Handle to PCI memory for ATI PCIGART table */
} drm_sg_mem_t;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-typedef struct {
- int mapped;
- int maptype;
- bus_addr_t base;
- bus_size_t size;
- bus_space_handle_t bsh;
- int flags;
- void * vaddr;
-} pci_map_data_t;
-#endif
-
typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t;
typedef struct drm_local_map {
@@ -703,7 +691,7 @@ typedef struct drm_local_map {
#ifdef __FreeBSD__
struct resource *bsr;
#else
- pci_map_data_t *bsr;
+ struct vga_pci_bar *bsr;
#endif
bus_space_tag_t bst;
bus_space_handle_t bsh;
@@ -832,6 +820,7 @@ struct drm_device {
#endif
#ifdef __OpenBSD__
dev_t kdev; /* used by uvm_mmap, this is just a placeholder */
+ struct vga_pci_softc *vga_softc;
#endif
int if_version; /* Highest interface version set */
@@ -885,10 +874,10 @@ struct drm_device {
/* Storage of resource pointers for drm_get_resource_* */
#ifdef __FreeBSD__
struct resource *pcir[DRM_MAX_PCI_RESOURCE];
+ int pcirid[DRM_MAX_PCI_RESOURCE];
#else
- pci_map_data_t *pcir[DRM_MAX_PCI_RESOURCE];
+ struct vga_pci_bar *pcir[DRM_MAX_PCI_RESOURCE];
#endif
- int pcirid[DRM_MAX_PCI_RESOURCE];
int pci_domain;
int pci_bus;
@@ -950,8 +939,8 @@ d_poll_t drm_poll;
d_mmap_t drm_mmap;
#elif defined(__NetBSD__) || defined(__OpenBSD__)
int drm_probe(struct pci_attach_args *, drm_pci_id_list_t * );
-void drm_attach(struct device *kdev, struct pci_attach_args *pa,
- drm_pci_id_list_t *idlist);
+void drm_attach(struct device *kdev, struct device *parent,
+ struct pci_attach_args *pa, drm_pci_id_list_t *idlist);
int drm_detach(struct device *self, int flags);
int drm_activate(struct device *self, enum devact act);
dev_type_ioctl(drm_ioctl);
diff --git a/sys/dev/pci/drm/drm_bufs.c b/sys/dev/pci/drm/drm_bufs.c
index 64e32082e22..3451b7c63f1 100644
--- a/sys/dev/pci/drm/drm_bufs.c
+++ b/sys/dev/pci/drm/drm_bufs.c
@@ -67,9 +67,6 @@ drm_order(unsigned long size)
int
drm_alloc_resource(drm_device_t *dev, int resource)
{
-#ifdef __OpenBSD__
-#define PCIR_BAR(x) (PCI_MAPS + (x) * 4)
-#endif
if (resource >= DRM_MAX_PCI_RESOURCE) {
DRM_ERROR("Resource %d too large\n", resource);
return 1;
@@ -81,8 +78,8 @@ drm_alloc_resource(drm_device_t *dev, int resource)
return 0;
}
- dev->pcirid[resource] = PCIR_BAR(resource);
#if defined (__FreeBSD__)
+ dev->pcirid[resource] = PCIR_BAR(resource);
dev->pcir[resource] = bus_alloc_resource_any(dev->device,
SYS_RES_MEMORY, &dev->pcirid[resource], RF_SHAREABLE);
@@ -92,27 +89,12 @@ drm_alloc_resource(drm_device_t *dev, int resource)
return 1;
}
#elif defined (__OpenBSD__)
- dev->pcir[resource] = malloc(sizeof(*(dev->pcir)), M_DRM, M_NOWAIT | M_ZERO);
+ dev->pcir[resource] = vga_pci_bar_info(dev->vga_softc, resource);
+ DRM_LOCK();
if (dev->pcir[resource] == NULL) {
- DRM_ERROR("Couldn't allocate memory for resource 0x%x\n", resource);
- DRM_LOCK();
+ DRM_ERROR("Can't get bar info for resource 0x%x\n", resource);
return 1;
}
- dev->pcir[resource]->maptype =
- pci_mapreg_type(dev->pa.pa_pc, dev->pa.pa_tag,
- dev->pcirid[resource]);
- if(pci_mapreg_info(dev->pa.pa_pc, dev->pa.pa_tag,
- dev->pcirid[resource],
- dev->pcir[resource]->maptype,
- &(dev->pcir[resource]->base),
- &(dev->pcir[resource]->size),
- &(dev->pcir[resource]->flags))) {
- dev->pcir[resource]->base = 0;
- dev->pcir[resource]->size = 0;
- }
- if(dev->pcir[resource]->maptype == PCI_MAPREG_TYPE_MEM)
- dev->pcir[resource]->flags |= BUS_SPACE_MAP_LINEAR;
- DRM_LOCK();
#endif
return 0;
@@ -141,7 +123,7 @@ drm_get_resource_len(drm_device_t *dev, unsigned int resource)
#ifdef __FreeBSD__
return rman_get_size(dev->pcir[resource]);
#elif defined(__NetBSD__) || defined(__OpenBSD__)
- return dev->pcir[resource]->size;
+ return dev->pcir[resource]->maxsize;
#endif
}
@@ -211,7 +193,6 @@ drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
switch ( map->type ) {
case _DRM_REGISTERS:
- map->bst = dev->pa.pa_iot;
map->handle = drm_ioremap(dev, map);
if (!map->handle) {
DRM_LOCK();
diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c
index 7eaf8358810..bb0dcc82b7c 100644
--- a/sys/dev/pci/drm/drm_drv.c
+++ b/sys/dev/pci/drm/drm_drv.c
@@ -267,8 +267,8 @@ drm_probe(struct pci_attach_args *pa, drm_pci_id_list_t *idlist)
}
void
-drm_attach(struct device *kdev, struct pci_attach_args *pa,
- drm_pci_id_list_t *idlist)
+drm_attach(struct device *parent, struct device *kdev,
+ struct pci_attach_args *pa, drm_pci_id_list_t *idlist)
{
int unit;
drm_device_t *dev;
@@ -288,7 +288,9 @@ drm_attach(struct device *kdev, struct pci_attach_args *pa,
dev = drm_units[unit] = (drm_device_t*)kdev;
dev->unit = unit;
+ /* needed for pci_mapreg_* */
memcpy(&dev->pa, pa, sizeof(dev->pa));
+ dev->vga_softc = (struct vga_pci_softc *)parent;
dev->irq = pa->pa_intrline;
dev->pci_bus = pa->pa_bus;
diff --git a/sys/dev/pci/drm/drm_memory.c b/sys/dev/pci/drm/drm_memory.c
index 8d3ae1d4a5f..5900b431d17 100644
--- a/sys/dev/pci/drm/drm_memory.c
+++ b/sys/dev/pci/drm/drm_memory.c
@@ -97,13 +97,48 @@ drm_ioremap(drm_device_t *dev, drm_local_map_t *map)
#ifdef __FreeBSD__
return pmap_mapdev(map->offset, map->size);
#elif defined(__NetBSD__) || defined(__OpenBSD__)
- int ret;
- if (!map->bst)
- map->bst = dev->pa.pa_memt;
- if ((ret = bus_space_map(map->bst, map->offset, map->size,
- BUS_SPACE_MAP_LINEAR, &map->bsh))) {
- return NULL;
+ struct vga_pci_bar *bar = NULL;
+ int i;
+
+ DRM_DEBUG("offset: 0x%x size: 0x%x type: %d\n", map->offset, map->size,
+ map->type);
+
+ if (map->type == _DRM_AGP || map->type == _DRM_FRAME_BUFFER) {
+ /*
+ * there can be multiple agp maps in the same BAR, agp also
+ * quite possibly isn't the same as the vga device, just try
+ * to map it.
+ */
+ DRM_DEBUG("AGP map\n");
+ map->bst = dev->pa.pa_memt;
+ if (bus_space_map(map->bst, map->offset,
+ map->size, BUS_SPACE_MAP_LINEAR, &map->bsh)) {
+ DRM_ERROR("ioremap fail\n");
+ return (NULL);
+ }
+ goto done;
+ } else {
+ for (i = 0 ; i < DRM_MAX_PCI_RESOURCE; ++i) {
+ bar = vga_pci_bar_info(dev->vga_softc, i);
+ if (bar == NULL)
+ continue;
+
+ if (bar->base == map->offset) {
+ DRM_DEBUG("REGISTERS map\n");
+ map->bsr = vga_pci_bar_map(dev->vga_softc,
+ bar->addr, map->size, BUS_SPACE_MAP_LINEAR);
+ if (map->bsr == NULL) {
+ DRM_ERROR("ioremap fail\n");
+ return (NULL);
+ }
+ map->bst = map->bsr->bst;
+ map->bsh = map->bsr->bsh;
+ goto done;
+ }
+ }
}
+done:
+ /* handles are still supposed to be kernel virtual addresses */
return bus_space_vaddr(map->bst, map->bsh);
#endif
}
@@ -114,7 +149,10 @@ drm_ioremapfree(drm_local_map_t *map)
#ifdef __FreeBSD__
pmap_unmapdev((vm_offset_t) map->handle, map->size);
#elif defined(__NetBSD__) || defined(__OpenBSD__)
- bus_space_unmap(map->bst, map->bsh, map->size);
+ if (map != NULL && map->bsr != NULL)
+ vga_pci_bar_unmap(map->bsr);
+ else
+ bus_space_unmap(map->bst, map->bsh, map->size);
#endif
}
diff --git a/sys/dev/pci/drm/i915_drv.c b/sys/dev/pci/drm/i915_drv.c
index 61a3ba4218b..6b9be6b8200 100644
--- a/sys/dev/pci/drm/i915_drv.c
+++ b/sys/dev/pci/drm/i915_drv.c
@@ -129,7 +129,6 @@ i915drm_probe(struct device *parent, void *match, void *aux)
i915drm_probe(struct device *parent, struct cfdata *match, void *aux)
#endif
{
- DRM_DEBUG("\n");
return drm_probe((struct pci_attach_args *)aux, i915_pciidlist);
}
@@ -141,7 +140,7 @@ i915drm_attach(struct device *parent, struct device *self, void *aux)
i915_configure(dev);
- drm_attach(self, pa, i915_pciidlist);
+ drm_attach(parent, self, pa, i915_pciidlist);
}
#if defined(__OpenBSD__)
diff --git a/sys/dev/pci/drm/mach64_drv.c b/sys/dev/pci/drm/mach64_drv.c
index 78ef1bded92..9065840850f 100644
--- a/sys/dev/pci/drm/mach64_drv.c
+++ b/sys/dev/pci/drm/mach64_drv.c
@@ -138,7 +138,7 @@ mach64drm_attach(struct device *parent, struct device *self, void *aux)
drm_device_t *dev = (drm_device_t *)self;
mach64_configure(dev);
- return drm_attach(self, pa, mach64_pciidlist);
+ return drm_attach(parent, self, pa, mach64_pciidlist);
}
#if defined(__OpenBSD__)
diff --git a/sys/dev/pci/drm/mga_drv.c b/sys/dev/pci/drm/mga_drv.c
index 8732c31aaf5..d18a7845063 100644
--- a/sys/dev/pci/drm/mga_drv.c
+++ b/sys/dev/pci/drm/mga_drv.c
@@ -188,7 +188,7 @@ mgadrm_attach(struct device *parent, struct device *self, void *aux)
drm_device_t *dev = (drm_device_t *)self;
mga_configure(dev);
- return drm_attach(self, pa, mga_pciidlist);
+ return drm_attach(parent, self, pa, mga_pciidlist);
}
#if defined(__OpenBSD__)
diff --git a/sys/dev/pci/drm/r128_drv.c b/sys/dev/pci/drm/r128_drv.c
index c6b32790ade..9c16396f383 100644
--- a/sys/dev/pci/drm/r128_drv.c
+++ b/sys/dev/pci/drm/r128_drv.c
@@ -138,7 +138,7 @@ r128drm_attach(struct device *parent, struct device *self, void *aux)
drm_device_t *dev = (drm_device_t *)self;
r128_configure(dev);
- return drm_attach(self, pa, r128_pciidlist);
+ return drm_attach(parent, self, pa, r128_pciidlist);
}
#if defined(__OpenBSD__)
diff --git a/sys/dev/pci/drm/radeon_drv.c b/sys/dev/pci/drm/radeon_drv.c
index 2ccd48818bc..082a4844db5 100644
--- a/sys/dev/pci/drm/radeon_drv.c
+++ b/sys/dev/pci/drm/radeon_drv.c
@@ -143,7 +143,7 @@ radeondrm_attach(struct device *parent, struct device *self, void *aux)
drm_device_t *dev = (drm_device_t *)self;
radeon_configure(dev);
- return drm_attach(self, pa, radeon_pciidlist);
+ return drm_attach(parent, self, pa, radeon_pciidlist);
}
#if defined(__OpenBSD__)
diff --git a/sys/dev/pci/drm/savage_drv.c b/sys/dev/pci/drm/savage_drv.c
index 557bdbb1775..585fe9a9538 100644
--- a/sys/dev/pci/drm/savage_drv.c
+++ b/sys/dev/pci/drm/savage_drv.c
@@ -128,7 +128,7 @@ savagedrm_attach(struct device *parent, struct device *self, void *aux)
drm_device_t *dev = (drm_device_t *)self;
savage_configure(dev);
- return drm_attach(self, pa, savage_pciidlist);
+ return drm_attach(parent, self, pa, savage_pciidlist);
}
#if defined(__OpenBSD__)
diff --git a/sys/dev/pci/drm/sis_drv.c b/sys/dev/pci/drm/sis_drv.c
index a986437aac8..072e1afdd0d 100644
--- a/sys/dev/pci/drm/sis_drv.c
+++ b/sys/dev/pci/drm/sis_drv.c
@@ -121,7 +121,7 @@ sisdrm_attach(struct device *parent, struct device *self, void *aux)
drm_device_t *dev = (drm_device_t *)self;
sis_configure(dev);
- return drm_attach(self, pa, sis_pciidlist);
+ return drm_attach(parent, self, pa, sis_pciidlist);
}
#if defined(__OpenBSD__)
diff --git a/sys/dev/pci/drm/tdfx_drv.c b/sys/dev/pci/drm/tdfx_drv.c
index 954446c475d..37bf6075c16 100644
--- a/sys/dev/pci/drm/tdfx_drv.c
+++ b/sys/dev/pci/drm/tdfx_drv.c
@@ -122,7 +122,7 @@ tdfxdrm_attach(struct device *parent, struct device *self, void *aux)
drm_device_t *dev = (drm_device_t *)self;
tdfx_configure(dev);
- return drm_attach(self, pa, tdfx_pciidlist);
+ return drm_attach(parent, self, pa, tdfx_pciidlist);
}
#if defined(__OpenBSD__)
diff --git a/sys/dev/pci/drm/via_drv.c b/sys/dev/pci/drm/via_drv.c
index 82a2374b296..86aa2b550ec 100644
--- a/sys/dev/pci/drm/via_drv.c
+++ b/sys/dev/pci/drm/via_drv.c
@@ -130,7 +130,7 @@ viadrm_attach(struct device *parent, struct device *self, void *opaque)
drm_device_t *dev = (drm_device_t *)self;
viadrm_configure(dev);
- drm_attach(self, pa, via_pciidlist);
+ drm_attach(parent, self, pa, via_pciidlist);
}
#if defined(__OpenBSD__)
diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c
index 7caf597c200..b6fcceaa91e 100644
--- a/sys/dev/pci/vga_pci.c
+++ b/sys/dev/pci/vga_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vga_pci.c,v 1.30 2008/03/16 19:00:28 oga Exp $ */
+/* $OpenBSD: vga_pci.c,v 1.31 2008/05/06 19:19:02 oga Exp $ */
/* $NetBSD: vga_pci.c,v 1.3 1998/06/08 06:55:58 thorpej Exp $ */
/*
@@ -101,6 +101,7 @@
int vga_pci_match(struct device *, void *, void *);
void vga_pci_attach(struct device *, struct device *, void *);
paddr_t vga_pci_mmap(void* v, off_t off, int prot);
+void vga_pci_bar_init(struct vga_pci_softc *, struct pci_attach_args *);
#if NAGP > 0
int agpsubmatch(struct device *, void *, void *);
@@ -169,9 +170,7 @@ vga_pci_attach(struct device *parent, struct device *self, void *aux)
struct agpbus_attach_args aba;
#endif
pcireg_t reg;
-#ifdef VESAFB
struct vga_pci_softc *sc = (struct vga_pci_softc *)self;
-#endif
/*
* Enable bus master; X might need this for accelerated graphics.
@@ -193,6 +192,8 @@ vga_pci_attach(struct device *parent, struct device *self, void *aux)
vga_common_attach(self, pa->pa_iot, pa->pa_memt,
WSDISPLAY_TYPE_PCIVGA);
+ vga_pci_bar_init(sc, pa);
+
#if NAGP > 0
/*
* attach agp here instead of pchb so it can share mappings
@@ -373,3 +374,106 @@ vga_pci_close(void *v)
{
}
#endif
+
+/*
+ * Prepare dev->bars to be used for information. we do this at startup
+ * so we can do the whole array at once, dealing with 64-bit BARs correctly.
+ */
+void
+vga_pci_bar_init(struct vga_pci_softc *dev, struct pci_attach_args *pa)
+{
+ pcireg_t type;
+ int addr = PCI_MAPREG_START, i = 0;
+ memcpy(&dev->pa, pa, sizeof(dev->pa));
+
+ while (i < VGA_PCI_MAX_BARS) {
+ dev->bars[i] = malloc(sizeof((*dev->bars[i])), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ if (dev->bars[i] == NULL) {
+ return;
+ }
+
+ dev->bars[i]->addr = addr;
+
+ type = dev->bars[i]->maptype = pci_mapreg_type(pa->pa_pc,
+ pa->pa_tag, addr);
+ if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, addr,
+ dev->bars[i]->maptype, &dev->bars[i]->base,
+ &dev->bars[i]->maxsize, &dev->bars[i]->flags) != 0) {
+ free(dev->bars[i], M_DEVBUF);
+ dev->bars[i] = NULL;
+ }
+
+ addr+=4;
+ ++i;
+ }
+}
+
+/*
+ * Get the vga_pci_bar struct for the address in question. returns NULL if
+ * invalid BAR is passed.
+ */
+struct vga_pci_bar*
+vga_pci_bar_info(struct vga_pci_softc *dev, int no)
+{
+ if (dev == NULL || no > VGA_PCI_MAX_BARS)
+ return (NULL);
+ return (dev->bars[no]);
+}
+
+/*
+ * map the BAR in question, returning the vga_pci_bar struct in case any more
+ * processing needs to be done. Returns NULL on failure. Can be called multiple
+ * times.
+ */
+struct vga_pci_bar*
+vga_pci_bar_map(struct vga_pci_softc *dev, int addr, bus_size_t size,
+ int busflags)
+{
+ struct vga_pci_bar *bar = NULL;
+ int i;
+
+ if (dev == NULL)
+ return (NULL);
+
+ for (i = 0; i < VGA_PCI_MAX_BARS; i++) {
+ if (dev->bars[i] && dev->bars[i]->addr == addr) {
+ bar = dev->bars[i];
+ break;
+ }
+ }
+ if (bar == NULL) {
+ printf("vga_pci_bar_map: given invalid address 0x%x\n", addr);
+ return (NULL);
+ }
+
+ if (bar->mapped == 0) {
+ switch (bar->maptype) {
+ case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
+ case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
+ if (pci_mapreg_map(&dev->pa, bar->addr, bar->maptype,
+ bar->flags | busflags, &bar->bst, &bar->bsh, NULL,
+ &bar->size, size) == 0)
+ break;
+ default:
+ printf("vga_pci_bar_map: can't map bar 0x%x\n", addr);
+ return (NULL);
+ }
+ }
+
+ bar->mapped++;
+ return (bar);
+}
+
+/*
+ * "unmap" the BAR referred to by argument. If more than one place has mapped it
+ * we just decrement the reference counter so nothing untoward happens.
+ */
+void
+vga_pci_bar_unmap(struct vga_pci_bar *bar)
+{
+ if (bar != NULL && bar->mapped != 0) {
+ if (--bar->mapped == 0)
+ bus_space_unmap(bar->bst, bar->bsh, bar->size);
+ }
+}
diff --git a/sys/dev/pci/vga_pcivar.h b/sys/dev/pci/vga_pcivar.h
index 44aad8df68a..47f10b4b72c 100644
--- a/sys/dev/pci/vga_pcivar.h
+++ b/sys/dev/pci/vga_pcivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vga_pcivar.h,v 1.9 2007/11/25 17:11:12 oga Exp $ */
+/* $OpenBSD: vga_pcivar.h,v 1.10 2008/05/06 19:19:02 oga Exp $ */
/* $NetBSD: vga_pcivar.h,v 1.1 1998/03/22 15:16:19 drochner Exp $ */
/*
@@ -37,13 +37,26 @@
(PCI_CLASS(class) == PCI_CLASS_PREHISTORIC && \
PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA)) ? 1 : 0)
+#define VGA_PCI_MAX_BARS 4
+struct vga_pci_bar {
+ int addr;
+ u_int mapped;
+ pcireg_t maptype;
+ bus_addr_t base;
+ bus_size_t size;
+ bus_size_t maxsize;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ int flags;
+ void *vaddr;
+};
+
struct vga_pci_softc {
struct device sc_dev;
-#if 0
- struct vga_config *sc_vc; /* VGA configuration */
-#endif
+ struct pci_attach_args pa;
+ struct vga_pci_bar *bars[VGA_PCI_MAX_BARS];
#ifdef VESAFB
int sc_width;
int sc_height;
@@ -60,8 +73,12 @@ struct vga_pci_softc {
#endif
};
-int vga_pci_cnattach(bus_space_tag_t, bus_space_tag_t,
- pci_chipset_tag_t, int, int, int);
+int vga_pci_cnattach(bus_space_tag_t, bus_space_tag_t,
+ pci_chipset_tag_t, int, int, int);
+struct vga_pci_bar *vga_pci_bar_info(struct vga_pci_softc *, int);
+struct vga_pci_bar *vga_pci_bar_map(struct vga_pci_softc *, int,
+ bus_size_t, int);
+void vga_pci_bar_unmap(struct vga_pci_bar*);
#ifdef VESAFB
int vesafb_find_mode(struct vga_pci_softc *, int, int, int);