- for DRM_NETBSD_HANDLE2ADDR/ADDR2HANDLE, do what uvm does to recover

the virtual address from a uoffset, e.g. uoffset + vm_map_min(kernel_map).

- Eliminate the bus_space_read/write-based DRM_READ/WRITE macros.  The
  memory we're reading/writing from is not always allocated with bus_space,
  and so this will not do.  Instead, since all of our bus_space maps are
  linear, volatile pointer dereferences will do just fine.

- Unify members of struct drm_dma_handle amongst freebsd and netbsd:
  the 'addr' member was superfluous; also, set dmah->tag from
  dev->pa.pa_dmat and use that.

- we don't need BUS_DMA_ALLOCNOW, as bus_dmamap_load is called immediately
  following bus_dmamap_create(), so there's no need to avoid deferring
  allocation to load time.

- Add check for nsegs != 1 in drm_pci_alloc().

- We don't need the DRM_PCI_DMAADDR macro right now--it was only
  used once.
This commit is contained in:
bjs 2008-07-25 06:54:33 +00:00
parent 8385c9b102
commit 8151294949
2 changed files with 30 additions and 44 deletions

View File

@ -329,8 +329,8 @@ extern drm_device_t *drm_units[];
#define DRM_MTRR_WC MTRR_TYPE_WC
#define jiffies hardclock_ticks
#ifdef __x86_64__
#define DRM_NETBSD_ADDR2HANDLE(addr) (addr & 0x7fffffffffffffff)
#define DRM_NETBSD_HANDLE2ADDR(handle) (handle | 0x8000000000000000)
#define DRM_NETBSD_ADDR2HANDLE(v) ((vaddr_t)(v) - vm_map_min(kernel_map))
#define DRM_NETBSD_HANDLE2ADDR(u) ((vaddr_t)(u) + vm_map_min(kernel_map))
#else
#define DRM_NETBSD_ADDR2HANDLE(addr) (addr)
#define DRM_NETBSD_HANDLE2ADDR(handle) (handle)
@ -402,7 +402,6 @@ typedef u_int8_t u8;
"lock; addl $0,0(%%rsp)" : : : "memory");
#endif
#ifdef __FreeBSD__
#define DRM_READ8(map, offset) \
*(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset))
#define DRM_READ16(map, offset) \
@ -416,31 +415,15 @@ typedef u_int8_t u8;
#define DRM_WRITE32(map, offset, val) \
*(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) = val
#ifdef __FreeBSD__
#define DRM_VERIFYAREA_READ( uaddr, size ) \
(!useracc(__DECONST(caddr_t, uaddr), size, VM_PROT_READ))
#else /* __FreeBSD__ */
#else
typedef vaddr_t vm_offset_t;
#define DRM_READ8(map, offset) \
bus_space_read_1( (map)->bst, (map)->bsh, (offset))
#define DRM_READ16(map, offset) \
bus_space_read_2( (map)->bst, (map)->bsh, (offset))
#define DRM_READ32(map, offset) \
bus_space_read_4( (map)->bst, (map)->bsh, (offset))
#define DRM_WRITE8(map, offset, val) \
bus_space_write_1((map)->bst, (map)->bsh, (offset), (val))
#define DRM_WRITE16(map, offset, val) \
bus_space_write_2((map)->bst, (map)->bsh, (offset), (val))
#define DRM_WRITE32(map, offset, val) \
bus_space_write_4((map)->bst, (map)->bsh, (offset), (val))
#define DRM_VERIFYAREA_READ( uaddr, size ) \
(!uvm_map_checkprot(&(curproc->p_vmspace->vm_map), \
(vaddr_t)uaddr, (vaddr_t)uaddr+size, UVM_PROT_READ))
#endif /* !__FreeBSD__ */
#endif
#define DRM_COPY_TO_USER(user, kern, size) \
copyout(kern, user, size)
@ -599,16 +582,11 @@ typedef struct drm_freelist {
typedef struct drm_dma_handle {
void *vaddr;
bus_addr_t busaddr;
#if defined(__FreeBSD__)
bus_dma_tag_t tag;
bus_dmamap_t map;
#elif defined(__NetBSD__)
bus_dma_tag_t dmat;
bus_dmamap_t map;
#define DRM_PCI_DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
#if defined(__NetBSD__)
bus_dma_segment_t segs[1];
size_t size;
void *addr;
#endif
} drm_dma_handle_t;

View File

@ -107,39 +107,46 @@ drm_pci_alloc(struct drm_device *dev, size_t size,
return dmah;
#elif defined(__NetBSD__)
if ((ret = bus_dmamem_alloc(dev->pa.pa_dmat, size, align, 0,
dmah->tag = dev->pa.pa_dmat;
if ((ret = bus_dmamem_alloc(dmah->tag, size, align, maxaddr,
dmah->segs, 1, &nsegs, BUS_DMA_NOWAIT)) != 0) {
printf("drm: Unable to allocate DMA, error %d\n", ret);
goto fail;
}
if ((ret = bus_dmamem_map(dev->pa.pa_dmat, dmah->segs, nsegs, size,
&dmah->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
/* XXX is there a better way to deal with this? */
if (nsegs != 1) {
printf("drm: bad segment count from bus_dmamem_alloc\n");
goto free;
}
if ((ret = bus_dmamem_map(dmah->tag, dmah->segs, nsegs, size,
&dmah->vaddr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
printf("drm: Unable to map DMA, error %d\n", ret);
goto free;
}
if ((ret = bus_dmamap_create(dev->pa.pa_dmat, size, 1, size, 0,
BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &dmah->map)) != 0) {
if ((ret = bus_dmamap_create(dmah->tag, size, 1, size, maxaddr,
BUS_DMA_NOWAIT, &dmah->map)) != 0) {
printf("drm: Unable to create DMA map, error %d\n", ret);
goto unmap;
}
if ((ret = bus_dmamap_load(dev->pa.pa_dmat, dmah->map, dmah->addr, size,
NULL, BUS_DMA_NOWAIT)) != 0) {
if ((ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr,
size, NULL, BUS_DMA_NOWAIT)) != 0) {
printf("drm: Unable to load DMA map, error %d\n", ret);
goto destroy;
}
dmah->busaddr = DRM_PCI_DMAADDR(dmah);
dmah->vaddr = dmah->addr;
dmah->busaddr = dmah->map->dm_segs[0].ds_addr;
dmah->size = size;
return dmah;
destroy:
bus_dmamap_destroy(dev->pa.pa_dmat, dmah->map);
bus_dmamap_destroy(dmah->tag, dmah->map);
unmap:
bus_dmamem_unmap(dev->pa.pa_dmat, dmah->addr, size);
bus_dmamem_unmap(dmah->tag, dmah->vaddr, size);
free:
bus_dmamem_free(dev->pa.pa_dmat, dmah->segs, 1);
bus_dmamem_free(dmah->tag, dmah->segs, 1);
fail:
dmah->tag = NULL;
free(dmah, M_DRM);
return NULL;
@ -161,10 +168,11 @@ drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah)
#elif defined(__NetBSD__)
if (dmah == NULL)
return;
bus_dmamap_unload(dev->pa.pa_dmat, dmah->map);
bus_dmamap_destroy(dev->pa.pa_dmat, dmah->map);
bus_dmamem_unmap(dev->pa.pa_dmat, dmah->addr, dmah->size);
bus_dmamem_free(dev->pa.pa_dmat, dmah->segs, 1);
bus_dmamap_unload(dmah->tag, dmah->map);
bus_dmamap_destroy(dmah->tag, dmah->map);
bus_dmamem_unmap(dmah->tag, dmah->vaddr, dmah->size);
bus_dmamem_free(dmah->tag, dmah->segs, 1);
dmah->tag = NULL;
#endif
free(dmah, M_DRM);