diff options
author | Robert Noland <rnoland@FreeBSD.org> | 2009-10-30 18:02:10 +0000 |
---|---|---|
committer | Robert Noland <rnoland@FreeBSD.org> | 2009-10-30 18:02:10 +0000 |
commit | 615fb6e9bcb4bd27ff6de0af0eb5d886402d71dc (patch) | |
tree | 0afd3bdf0c920ce537eaaf75e78d2abc91d3bdf8 | |
parent | 6d68455174d85948edc5e1728204c3c3e3a888e1 (diff) |
Notes
-rw-r--r-- | sys/dev/drm/drm_scatter.c | 69 |
1 files changed, 25 insertions, 44 deletions
diff --git a/sys/dev/drm/drm_scatter.c b/sys/dev/drm/drm_scatter.c index 5f8b29b001b7..7fbf37182e41 100644 --- a/sys/dev/drm/drm_scatter.c +++ b/sys/dev/drm/drm_scatter.c @@ -47,35 +47,20 @@ drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request) { struct drm_sg_mem *entry; struct drm_dma_handle *dmah; - unsigned long pages; int ret; if (dev->sg) return EINVAL; entry = malloc(sizeof(*entry), DRM_MEM_SGLISTS, M_WAITOK | M_ZERO); - if (!entry) - return ENOMEM; - - pages = round_page(request->size) / PAGE_SIZE; - DRM_DEBUG("sg size=%ld pages=%ld\n", request->size, pages); - - entry->pages = pages; - - entry->busaddr = malloc(pages * sizeof(*entry->busaddr), DRM_MEM_PAGES, - M_WAITOK | M_ZERO); - if (!entry->busaddr) { - free(entry, DRM_MEM_SGLISTS); - return ENOMEM; - } + entry->pages = round_page(request->size) / PAGE_SIZE; + DRM_DEBUG("sg size=%ld pages=%d\n", request->size, entry->pages); + entry->busaddr = malloc(entry->pages * sizeof(*entry->busaddr), + DRM_MEM_PAGES, M_WAITOK | M_ZERO); dmah = malloc(sizeof(struct drm_dma_handle), DRM_MEM_DMA, - M_ZERO | M_NOWAIT); - if (dmah == NULL) { - free(entry->busaddr, DRM_MEM_PAGES); - free(entry, DRM_MEM_SGLISTS); - return ENOMEM; - } + M_WAITOK | M_ZERO); + entry->dmah = dmah; ret = bus_dma_tag_create(NULL, PAGE_SIZE, 0, /* tag, align, boundary */ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, /* lowaddr, highaddr */ @@ -85,41 +70,27 @@ drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request) NULL, NULL, /* lockfunc, lockfuncargs */ &dmah->tag); if (ret != 0) { - free(dmah, DRM_MEM_DMA); - free(entry->busaddr, DRM_MEM_PAGES); - free(entry, DRM_MEM_SGLISTS); + drm_sg_cleanup(entry); return ENOMEM; } ret = bus_dmamem_alloc(dmah->tag, &dmah->vaddr, BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE, &dmah->map); if (ret != 0) { - bus_dma_tag_destroy(dmah->tag); - free(dmah, DRM_MEM_DMA); - free(entry->busaddr, DRM_MEM_PAGES); - free(entry, DRM_MEM_SGLISTS); + drm_sg_cleanup(entry); return ENOMEM; } + entry->handle = (unsigned long)dmah->vaddr; + entry->virtual = dmah->vaddr; + ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr, request->size, drm_sg_alloc_cb, entry, BUS_DMA_NOWAIT); if (ret != 0) { - bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); - bus_dma_tag_destroy(dmah->tag); - free(dmah, DRM_MEM_DMA); - free(entry->busaddr, DRM_MEM_PAGES); - free(entry, DRM_MEM_SGLISTS); + drm_sg_cleanup(entry); return ENOMEM; } - entry->dmah = dmah; - entry->handle = (unsigned long)dmah->vaddr; - - DRM_DEBUG("sg alloc handle = %08lx\n", entry->handle); - - entry->virtual = (void *)entry->handle; - request->handle = entry->handle; - DRM_LOCK(); if (dev->sg) { DRM_UNLOCK(); @@ -129,6 +100,11 @@ drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request) dev->sg = entry; DRM_UNLOCK(); + DRM_DEBUG("handle=%08lx, kva=%p, contents=%08lx\n", entry->handle, + entry->virtual, *(unsigned long *)entry->virtual); + + request->handle = entry->handle; + return 0; } @@ -143,6 +119,8 @@ drm_sg_alloc_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) for(i = 0 ; i < nsegs ; i++) { entry->busaddr[i] = segs[i].ds_addr; + DRM_DEBUG("segment %d @ 0x%016lx\n", i, + (unsigned long)segs[i].ds_addr); } } @@ -162,9 +140,12 @@ drm_sg_cleanup(struct drm_sg_mem *entry) { struct drm_dma_handle *dmah = entry->dmah; - bus_dmamap_unload(dmah->tag, dmah->map); - bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); - bus_dma_tag_destroy(dmah->tag); + if (dmah->map != NULL) + bus_dmamap_unload(dmah->tag, dmah->map); + if (dmah->vaddr != NULL) + bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map); + if (dmah->tag != NULL) + bus_dma_tag_destroy(dmah->tag); free(dmah, DRM_MEM_DMA); free(entry->busaddr, DRM_MEM_PAGES); free(entry, DRM_MEM_SGLISTS); |