2 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
25 * Gareth Hughes <gareth@valinux.com>
26 * Eric Anholt <anholt@FreeBSD.org>
30 /** @file drm_scatter.c
31 * Allocation of memory for scatter-gather mappings by the graphics chip.
33 * The memory allocated here is then made into an aperture in the card
34 * by drm_ati_pcigart_init().
39 #define DEBUG_SCATTER 0
41 void drm_sg_cleanup(drm_sg_mem_t *entry)
43 free((void *)entry->handle, M_DRM);
44 free(entry->busaddr, M_DRM);
48 int drm_sg_alloc(struct drm_device * dev, drm_scatter_gather_t * request)
57 entry = malloc(sizeof(*entry), M_DRM, M_WAITOK | M_ZERO);
61 pages = round_page(request->size) / PAGE_SIZE;
62 DRM_DEBUG( "sg size=%ld pages=%ld\n", request->size, pages );
66 entry->busaddr = malloc(pages * sizeof(*entry->busaddr), M_DRM,
68 if ( !entry->busaddr ) {
69 drm_sg_cleanup(entry);
73 entry->handle = (long)malloc(pages << PAGE_SHIFT, M_DRM,
75 if (entry->handle == 0) {
76 drm_sg_cleanup(entry);
80 for (i = 0; i < pages; i++) {
81 entry->busaddr[i] = vtophys(entry->handle + i * PAGE_SIZE);
84 DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle );
86 entry->virtual = (void *)entry->handle;
87 request->handle = entry->handle;
92 drm_sg_cleanup(entry);
101 int drm_sg_alloc_ioctl(struct drm_device *dev, void *data,
102 struct drm_file *file_priv)
104 drm_scatter_gather_t *request = data;
107 DRM_DEBUG( "%s\n", __FUNCTION__ );
109 ret = drm_sg_alloc(dev, request);
113 int drm_sg_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
115 drm_scatter_gather_t *request = data;
123 if ( !entry || entry->handle != request->handle )
126 DRM_DEBUG( "sg free virtual = 0x%lx\n", entry->handle );
128 drm_sg_cleanup(entry);