Index: drmP.h =================================================================== RCS file: /cvsroot/src/sys/external/bsd/drm/dist/bsd-core/drmP.h,v retrieving revision 1.9.10.2 diff -u -p -r1.9.10.2 drmP.h --- drmP.h 14 Aug 2009 21:40:49 -0000 1.9.10.2 +++ drmP.h 10 Jan 2010 23:32:26 -0000 @@ -650,6 +650,18 @@ typedef struct drm_sg_mem { typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t; +#if defined(__NetBSD__) +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 struct drm_local_map { unsigned long offset; /* Physical address (0 for SAREA)*/ unsigned long size; /* Physical size (bytes) */ @@ -667,7 +679,7 @@ typedef struct drm_local_map { bus_space_handle_t bsh; drm_dma_handle_t *dmah; #if defined(__NetBSD__) - int *cnt; + pci_map_data_t *fullmap; bus_size_t mapsize; #endif TAILQ_ENTRY(drm_local_map) link; @@ -784,18 +796,6 @@ struct drm_driver_info { /* Length for the array of resource pointers for drm_get_resource_*. */ #define DRM_MAX_PCI_RESOURCE 6 -#if defined(__NetBSD__) -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 - /** * DRM device functions structure */ Index: drm_bufs.c =================================================================== RCS file: /cvsroot/src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c,v retrieving revision 1.2.10.1 diff -u -p -r1.2.10.1 drm_bufs.c --- drm_bufs.c 20 Jun 2009 23:36:59 -0000 1.2.10.1 +++ drm_bufs.c 10 Jan 2010 23:32:26 -0000 @@ -159,16 +159,25 @@ int drm_addmap(struct drm_device * dev, map->size = size; map->type = type; map->flags = flags; -#ifdef __NetBSD__ - map->cnt = NULL; +#if defined(__NetBSD__) + map->fullmap = NULL; map->mapsize = 0; #endif switch (map->type) { case _DRM_REGISTERS: map->handle = drm_ioremap(dev, map); + if (map->handle == NULL) { + DRM_ERROR("drm_addmap couldn't ioremap registers with " + "base %lX, size %lX\n", + (long) offset, (long) size); + DRM_LOCK(); + return EINVAL; + } + if (!(map->flags & _DRM_WRITE_COMBINING)) break; + /* FALLTHROUGH */ case _DRM_FRAME_BUFFER: if (drm_mtrr_add(map->offset, map->size, DRM_MTRR_WC) == 0) Index: drm_memory.c =================================================================== RCS file: /cvsroot/src/sys/external/bsd/drm/dist/bsd-core/drm_memory.c,v retrieving revision 1.3.10.1 diff -u -p -r1.3.10.1 drm_memory.c --- drm_memory.c 20 Jun 2009 23:36:59 -0000 1.3.10.1 +++ drm_memory.c 10 Jan 2010 23:32:26 -0000 @@ -85,29 +85,55 @@ void drm_mem_uninit(void) static void * drm_netbsd_ioremap(struct drm_device *dev, drm_local_map_t *map, int wc) { + bus_space_handle_t h; int i, reg, reason; for(i = 0; ipci_map_data[i].maptype == PCI_MAPREG_TYPE_MEM || dev->pci_map_data[i].maptype == (PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT)) && - dev->pci_map_data[i].base == map->offset && - dev->pci_map_data[i].size >= map->size) + map->offset >= dev->pci_map_data[i].base && + map->offset + map->size <= dev->pci_map_data[i].base + + dev->pci_map_data[i].size) { map->bst = dev->pa.pa_memt; - map->cnt = &(dev->pci_map_data[i].mapped); - map->mapsize = dev->pci_map_data[i].size; + map->fullmap = &(dev->pci_map_data[i]); + map->mapsize = map->size; dev->pci_map_data[i].mapped++; + + /* If we've already mapped this resource in, handle + * submapping if needed, give caller a bus_space handle + * and pointer for the offest they asked for */ if (dev->pci_map_data[i].mapped > 1) { - map->bsh = dev->pci_map_data[i].bsh; - return dev->pci_map_data[i].vaddr; + if ((reason = bus_space_subregion( + dev->pa.pa_memt, + dev->pci_map_data[i].bsh, + map->offset - dev->pci_map_data[i].base, + map->size, &h)) != 0) { + DRM_DEBUG("ioremap failed to " + "bus_space_subregion: %d\n", + reason); + return NULL; + } + map->bsh = h; + map->handle = bus_space_vaddr(dev->pa.pa_memt, + h); + return map->handle; } + + /* Map in entirety of resource - full size and handle + * go in pci_map_data, specific mapping in callers + * drm_local_map_t */ DRM_DEBUG("ioremap%s: flags %d\n", wc ? "_wc" : "", dev->pci_map_data[i].flags); - if ((reason = bus_space_map(map->bst, map->offset, + if ((reason = bus_space_map(map->bst, + dev->pci_map_data[i].base, dev->pci_map_data[i].size, - dev->pci_map_data[i].flags, &map->bsh))) + dev->pci_map_data[i].flags, + &dev->pci_map_data[i].bsh))) { dev->pci_map_data[i].mapped--; #if NAGP_I810 > 0 /* XXX horrible kludge: agp might have mapped it */ @@ -118,13 +144,29 @@ drm_netbsd_ioremap(struct drm_device *de reason); return NULL; } - dev->pci_map_data[i].bsh = map->bsh; - dev->pci_map_data[i].vaddr = - bus_space_vaddr(map->bst, map->bsh); + + dev->pci_map_data[i].vaddr = bus_space_vaddr(map->bst, + dev->pci_map_data[i].bsh); + + /* Caller might have requested a submapping of that */ + if ((reason = bus_space_subregion( + dev->pa.pa_memt, + dev->pci_map_data[i].bsh, + map->offset - dev->pci_map_data[i].base, + map->size, &h)) != 0) { + DRM_DEBUG("ioremap failed to " + "bus_space_subregion: %d\n", + reason); + return NULL; + } + DRM_DEBUG("ioremap mem found for %lx, %lx: %p\n", map->offset, map->size, dev->agp_map_data[i].vaddr); - return dev->pci_map_data[i].vaddr; + + map->bsh = h; + map->handle = bus_space_vaddr(dev->pa.pa_memt, h); + return map->handle; } } /* failed to find a valid mapping; all hope isn't lost though */ @@ -133,7 +175,7 @@ drm_netbsd_ioremap(struct drm_device *de dev->agp_map_data[i].base == map->offset && dev->agp_map_data[i].size >= map->size) { map->bst = dev->pa.pa_memt; - map->cnt = &(dev->agp_map_data[i].mapped); + map->fullmap = &(dev->agp_map_data[i]); map->mapsize = dev->agp_map_data[i].size; dev->agp_map_data[i].mapped++; map->bsh = dev->agp_map_data[i].bsh; @@ -148,7 +190,7 @@ drm_netbsd_ioremap(struct drm_device *de dev->agp_map_data[i].size = map->size; dev->agp_map_data[i].flags = BUS_SPACE_MAP_LINEAR; dev->agp_map_data[i].maptype = PCI_MAPREG_TYPE_MEM; - map->cnt = &(dev->agp_map_data[i].mapped); + map->fullmap = &(dev->agp_map_data[i]); map->mapsize = dev->agp_map_data[i].size; DRM_DEBUG("ioremap%s: flags %d\n", wc ? "_wc" : "", @@ -201,14 +243,16 @@ void drm_ioremapfree(drm_local_map_t *ma #if defined(__FreeBSD__) pmap_unmapdev((vm_offset_t) map->handle, map->size); #elif defined(__NetBSD__) - if (map->cnt == NULL) { + if (map->fullmap == NULL) { DRM_INFO("drm_ioremapfree called for unknown map\n"); return; } - if (*(map->cnt) > 0) { - (*(map->cnt))--; - if(*(map->cnt) == 0) - bus_space_unmap(map->bst, map->bsh, map->mapsize); + + if (map->fullmap->mapped > 0) { + map->fullmap->mapped--; + if(map->fullmap->mapped == 0) + bus_space_unmap(map->bst, map->fullmap->bsh, + map->fullmap->size); } #endif }