FreeBSD/sys/dev/drm/drm_pci.c
/**
 * \brief Allocate a physically contiguous DMA-accessible consistent 
 * memory block.
 */
\brief Allocate a physically contiguous DMA-accessible consistent
memory block.
\ brief Allocate a physically contiguous DMA - accessible consistent memory block .
drm_dma_handle_t *
drm_pci_alloc(struct drm_device *dev, size_t size,
	      size_t align, dma_addr_t maxaddr)
{
	drm_dma_handle_t *dmah;
	int ret;
	if ((align & (align - 1)) != 0) {
		DRM_ERROR("drm_pci_alloc with non-power-of-two alignment %d\n",
		    (int)align);
		return NULL;
	}
	dmah = malloc(sizeof(drm_dma_handle_t), DRM_MEM_DMA, M_ZERO | M_NOWAIT);
	if (dmah == NULL)
		return NULL;
	mtx_assert(&dev->dev_lock, MA_NOTOWNED);
	if (mtx_owned(&dev->dev_lock))
	    DRM_ERROR("called while holding dev_lock\n");
	mtx_assert(&dev->dma_lock, MA_NOTOWNED);
	if (mtx_owned(&dev->dma_lock))
	    DRM_ERROR("called while holding dma_lock\n");
	ret = bus_dma_tag_create(NULL, align, 0, 
	    maxaddr, BUS_SPACE_MAXADDR, 
	    NULL, NULL, 
	    size, 1, size, 
	    0, NULL, NULL, 
	    &dmah->tag);
	if (ret != 0) {
		free(dmah, DRM_MEM_DMA);
		return NULL;
	}
	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);
		return NULL;
	}
	ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr, size,
	    drm_pci_busdma_callback, dmah, 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);
		return NULL;
	}
	return dmah;
}
drm_dma_handle_t * drm_pci_alloc ( struct drm_device * dev , size_t size , size_t align , dma_addr_t maxaddr ) { drm_dma_handle_t * dmah ; int ret ; if ( ( align & ( align - 1 ) ) != 0 ) { DRM_ERROR ( " \n " , ( int ) align ) ; return NULL ; } dmah = malloc ( sizeof ( drm_dma_handle_t ) , DRM_MEM_DMA , M_ZERO | M_NOWAIT ) ; if ( dmah == NULL ) return NULL ; mtx_assert ( & dev -> dev_lock , MA_NOTOWNED ) ; if ( mtx_owned ( & dev -> dev_lock ) ) DRM_ERROR ( " \n " ) ; mtx_assert ( & dev -> dma_lock , MA_NOTOWNED ) ; if ( mtx_owned ( & dev -> dma_lock ) ) DRM_ERROR ( " \n " ) ; ret = bus_dma_tag_create ( NULL , align , 0 , maxaddr , BUS_SPACE_MAXADDR , NULL , NULL , size , 1 , size , 0 , NULL , NULL , & dmah -> tag ) ; if ( ret != 0 ) { free ( dmah , DRM_MEM_DMA ) ; return NULL ; } 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 ) ; return NULL ; } ret = bus_dmamap_load ( dmah -> tag , dmah -> map , dmah -> vaddr , size , drm_pci_busdma_callback , dmah , 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 ) ; return NULL ; } return dmah ; }
\brief Allocate a physically contiguous DMA-accessible consistent
 memory block.
\ brief Allocate a physically contiguous DMA - accessible consistent memory block .
/* Need power-of-two alignment, so fail the allocation if it isn't. */ /* Make sure we aren't holding locks here */ /* tag, align, boundary */ /* lowaddr, highaddr */ /* filtfunc, filtfuncargs */ /* maxsize, nsegs, maxsegsize */ /* flags, lockfunc, lockfuncargs */