diff options
author | Eric Anholt <anholt@freebsd.org> | 2005-08-26 20:56:11 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2005-08-26 20:56:11 +0000 |
commit | c425ad1a34439d019edd589c32a7161d01b4d822 (patch) | |
tree | bbb5ce64e4b791cb01c62e144e3b3e7e4b86d829 /bsd-core/drm_bufs.c | |
parent | 5105f9ea59179c7129d3bf97734eb37e26ec68b0 (diff) |
Previously, drm_get_resource_start() and drm_get_resource_len() would
allocate the resource RF_ACTIVE, pull out the appropriate value, and
return it. However, allocating large framebuffers RF_ACTIVE would run
the system out of KVA, and this also left open the possibility of the
resource getting moved after getting the offset. Instead, when either
of these are called, allocate the resource if it isn't allocated
already (non-RF_ACTIVE) and store it in the DRM device, to be cleaned
up on lastclose.
Diffstat (limited to 'bsd-core/drm_bufs.c')
-rw-r--r-- | bsd-core/drm_bufs.c | 55 |
1 files changed, 28 insertions, 27 deletions
diff --git a/bsd-core/drm_bufs.c b/bsd-core/drm_bufs.c index 5ce2d4de..1df0238d 100644 --- a/bsd-core/drm_bufs.c +++ b/bsd-core/drm_bufs.c @@ -31,6 +31,8 @@ * */ +#include "dev/pci/pcireg.h" + #include "drmP.h" /* @@ -49,46 +51,45 @@ int drm_order(unsigned long size) return order; } -unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource) +/* Allocation of PCI memory resources (framebuffer, registers, etc.) for + * drm_get_resource_*. Note that they are not RF_ACTIVE, so there's no virtual + * address for accessing them. Cleaned up at lastclose. + */ +static int drm_alloc_resource(drm_device_t *dev, int resource) { - struct resource *bsr; - unsigned long offset; + if (resource >= DRM_MAX_PCI_RESOURCE) { + DRM_ERROR("Resource %d too large\n", resource); + return 1; + } + if (dev->pcir[resource] != NULL) + return 0; - resource = resource * 4 + 0x10; + dev->pcirid[resource] = PCIR_BAR(resource); + dev->pcir[resource] = bus_alloc_resource_any(dev->device, + SYS_RES_MEMORY, &dev->pcirid[resource], RF_SHAREABLE); - bsr = bus_alloc_resource_any(dev->device, SYS_RES_MEMORY, &resource, - RF_ACTIVE | RF_SHAREABLE); - if (bsr == NULL) { + if (dev->pcir[resource] == NULL) { DRM_ERROR("Couldn't find resource 0x%x\n", resource); - return 0; + return 1; } - offset = rman_get_start(bsr); + return 0; +} - bus_release_resource(dev->device, SYS_RES_MEMORY, resource, bsr); +unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource) +{ + if (drm_alloc_resource(dev, resource) != 0) + return 0; - return offset; + return rman_get_start(dev->pcir[resource]); } unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource) { - struct resource *bsr; - unsigned long len; - - resource = resource * 4 + 0x10; - - bsr = bus_alloc_resource_any(dev->device, SYS_RES_MEMORY, &resource, - RF_ACTIVE | RF_SHAREABLE); - if (bsr == NULL) { - DRM_ERROR("Couldn't find resource 0x%x\n", resource); - return ENOMEM; - } - - len = rman_get_size(bsr); - - bus_release_resource(dev->device, SYS_RES_MEMORY, resource, bsr); + if (drm_alloc_resource(dev, resource) != 0) + return 0; - return len; + return rman_get_size(dev->pcir[resource]); } int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size, |