1/*- 2 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. 3 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation --- 15 unchanged lines hidden (view full) --- 24 * 25 * Authors: 26 * Rickard E. (Rik) Faith <faith@valinux.com> 27 * Gareth Hughes <gareth@valinux.com> 28 * 29 */ 30 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: head/sys/dev/drm/drm_bufs.c 207066 2010-04-22 18:21:25Z rnoland $"); |
33 34/** @file drm_bufs.c 35 * Implementation of the ioctls for setup of DRM mappings and DMA buffers. 36 */ 37 38#include "dev/pci/pcireg.h" 39 40#include "dev/drm/drmP.h" --- 110 unchanged lines hidden (view full) --- 151 DRM_LOCK(); 152 return ENOMEM; 153 } 154 155 map->offset = offset; 156 map->size = size; 157 map->type = type; 158 map->flags = flags; |
159 map->handle = (void *)((unsigned long)alloc_unr(dev->map_unrhdr) << 160 DRM_MAP_HANDLE_SHIFT); |
161 162 switch (map->type) { 163 case _DRM_REGISTERS: |
164 map->virtual = drm_ioremap(dev, map); |
165 if (!(map->flags & _DRM_WRITE_COMBINING)) 166 break; 167 /* FALLTHROUGH */ 168 case _DRM_FRAME_BUFFER: 169 if (drm_mtrr_add(map->offset, map->size, DRM_MTRR_WC) == 0) 170 map->mtrr = 1; 171 break; 172 case _DRM_SHM: |
173 map->virtual = malloc(map->size, DRM_MEM_MAPS, M_NOWAIT); |
174 DRM_DEBUG("%lu %d %p\n", |
175 map->size, drm_order(map->size), map->virtual); 176 if (!map->virtual) { |
177 free(map, DRM_MEM_MAPS); 178 DRM_LOCK(); 179 return ENOMEM; 180 } |
181 map->offset = (unsigned long)map->virtual; |
182 if (map->flags & _DRM_CONTAINS_LOCK) { 183 /* Prevent a 2nd X Server from creating a 2nd lock */ 184 DRM_LOCK(); 185 if (dev->lock.hw_lock != NULL) { 186 DRM_UNLOCK(); |
187 free(map->virtual, DRM_MEM_MAPS); |
188 free(map, DRM_MEM_MAPS); 189 return EBUSY; 190 } |
191 dev->lock.hw_lock = map->virtual; /* Pointer to lock */ |
192 DRM_UNLOCK(); 193 } 194 break; 195 case _DRM_AGP: 196 /*valid = 0;*/ 197 /* In some cases (i810 driver), user space may have already 198 * added the AGP base itself, because dev->agp->base previously 199 * only got set during AGP enable. So, only add the base --- 21 unchanged lines hidden (view full) --- 221 }*/ 222 break; 223 case _DRM_SCATTER_GATHER: 224 if (!dev->sg) { 225 free(map, DRM_MEM_MAPS); 226 DRM_LOCK(); 227 return EINVAL; 228 } |
229 map->virtual = (void *)(dev->sg->handle + offset); 230 map->offset = dev->sg->handle + offset; |
231 break; 232 case _DRM_CONSISTENT: 233 /* Unfortunately, we don't get any alignment specification from 234 * the caller, so we have to guess. drm_pci_alloc requires 235 * a power-of-two alignment, so try to align the bus address of 236 * the map to it size if possible, otherwise just assume 237 * PAGE_SIZE alignment. 238 */ 239 align = map->size; 240 if ((align & (align - 1)) != 0) 241 align = PAGE_SIZE; 242 map->dmah = drm_pci_alloc(dev, map->size, align, 0xfffffffful); 243 if (map->dmah == NULL) { 244 free(map, DRM_MEM_MAPS); 245 DRM_LOCK(); 246 return ENOMEM; 247 } |
248 map->virtual = map->dmah->vaddr; |
249 map->offset = map->dmah->busaddr; 250 break; 251 default: 252 DRM_ERROR("Bad map type %d\n", map->type); 253 free(map, DRM_MEM_MAPS); 254 DRM_LOCK(); 255 return EINVAL; 256 } --- 32 unchanged lines hidden (view full) --- 289 if (err != 0) 290 return err; 291 292 request->offset = map->offset; 293 request->size = map->size; 294 request->type = map->type; 295 request->flags = map->flags; 296 request->mtrr = map->mtrr; |
297 request->handle = (void *)map->handle; |
298 |
299 return 0; 300} 301 302void drm_rmmap(struct drm_device *dev, drm_local_map_t *map) 303{ 304 DRM_SPINLOCK_ASSERT(&dev->dev_lock); 305 306 if (map == NULL) --- 11 unchanged lines hidden (view full) --- 318 int __unused retcode; 319 320 retcode = drm_mtrr_del(0, map->offset, map->size, 321 DRM_MTRR_WC); 322 DRM_DEBUG("mtrr_del = %d\n", retcode); 323 } 324 break; 325 case _DRM_SHM: |
326 free(map->virtual, DRM_MEM_MAPS); |
327 break; 328 case _DRM_AGP: 329 case _DRM_SCATTER_GATHER: 330 break; 331 case _DRM_CONSISTENT: 332 drm_pci_free(dev, map->dmah); 333 break; 334 default: 335 DRM_ERROR("Bad map type %d\n", map->type); 336 break; 337 } 338 339 if (map->bsr != NULL) { 340 bus_release_resource(dev->device, SYS_RES_MEMORY, map->rid, 341 map->bsr); 342 } 343 |
344 DRM_UNLOCK(); 345 if (map->handle) 346 free_unr(dev->map_unrhdr, (unsigned long)map->handle >> 347 DRM_MAP_HANDLE_SHIFT); 348 DRM_LOCK(); 349 |
350 free(map, DRM_MEM_MAPS); 351} 352 353/* Remove a map private from list and deallocate resources if the mapping 354 * isn't in use. 355 */ 356 357int drm_rmmap_ioctl(struct drm_device *dev, void *data, --- 696 unchanged lines hidden (view full) --- 1054 (dma->flags & _DRM_DMA_USE_SG))) { 1055 drm_local_map_t *map = dev->agp_buffer_map; 1056 1057 if (map == NULL) { 1058 retcode = EINVAL; 1059 goto done; 1060 } 1061 size = round_page(map->size); |
1062 foff = (unsigned long)map->handle; |
1063 } else { 1064 size = round_page(dma->byte_count), 1065 foff = 0; 1066 } 1067 1068 vaddr = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ); 1069#if __FreeBSD_version >= 600023 1070 retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE, --- 60 unchanged lines hidden --- |