drm_bufs.c (814aaaa7da4dab462d90e12e7b48b75f2093ccfd) drm_bufs.c (b4b4b5304bd22eab265c9c049cb7fc6b55c4ef3f)
1/**
2 * \file drm_bufs.c
3 * Generic buffer template
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8

--- 25 unchanged lines hidden (view full) ---

34 */
35
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD$");
38
39#include <sys/param.h>
40#include <sys/shm.h>
41
1/**
2 * \file drm_bufs.c
3 * Generic buffer template
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8

--- 25 unchanged lines hidden (view full) ---

34 */
35
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD$");
38
39#include <sys/param.h>
40#include <sys/shm.h>
41
42#include <linux/vmalloc.h>
43#include <linux/slab.h>
44
45#include <dev/pci/pcireg.h>
46
47#include <dev/drm2/drmP.h>
48
49/* Allocation of PCI memory resources (framebuffer, registers, etc.) for
50 * drm_get_resource_*. Note that they are not RF_ACTIVE, so there's no virtual
51 * address for accessing them. Cleaned up at unload.
52 */

--- 161 unchanged lines hidden (view full) ---

214{
215 struct drm_local_map *map;
216 struct drm_map_list *list;
217 drm_dma_handle_t *dmah;
218 unsigned long user_token;
219 int ret;
220 int align;
221
42#include <dev/pci/pcireg.h>
43
44#include <dev/drm2/drmP.h>
45
46/* Allocation of PCI memory resources (framebuffer, registers, etc.) for
47 * drm_get_resource_*. Note that they are not RF_ACTIVE, so there's no virtual
48 * address for accessing them. Cleaned up at unload.
49 */

--- 161 unchanged lines hidden (view full) ---

211{
212 struct drm_local_map *map;
213 struct drm_map_list *list;
214 drm_dma_handle_t *dmah;
215 unsigned long user_token;
216 int ret;
217 int align;
218
222 map = kmalloc(sizeof(*map), GFP_KERNEL);
219 map = malloc(sizeof(*map), DRM_MEM_MAPS, M_NOWAIT);
223 if (!map)
224 return -ENOMEM;
225
226 map->offset = offset;
227 map->size = size;
228 map->flags = flags;
229 map->type = type;
230
231 /* Only allow shared memory to be removable since we only keep enough
232 * book keeping information about shared memory to allow for removal
233 * when processes fork.
234 */
235 if ((map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM) {
220 if (!map)
221 return -ENOMEM;
222
223 map->offset = offset;
224 map->size = size;
225 map->flags = flags;
226 map->type = type;
227
228 /* Only allow shared memory to be removable since we only keep enough
229 * book keeping information about shared memory to allow for removal
230 * when processes fork.
231 */
232 if ((map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM) {
236 kfree(map);
233 free(map, DRM_MEM_MAPS);
237 return -EINVAL;
238 }
239 DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n",
240 (unsigned long long)map->offset, map->size, map->type);
241
242 /* page-align _DRM_SHM maps. They are allocated here so there is no security
243 * hole created by that and it works around various broken drivers that use
244 * a non-aligned quantity to map the SAREA. --BenH
245 */
246 if (map->type == _DRM_SHM)
247 map->size = PAGE_ALIGN(map->size);
248
249 /*
250 * FreeBSD port note: FreeBSD's PAGE_MASK is the inverse of
251 * Linux's one. That's why the test below doesn't inverse the
252 * constant.
253 */
254 if ((map->offset & ((resource_size_t)PAGE_MASK)) || (map->size & (PAGE_MASK))) {
234 return -EINVAL;
235 }
236 DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n",
237 (unsigned long long)map->offset, map->size, map->type);
238
239 /* page-align _DRM_SHM maps. They are allocated here so there is no security
240 * hole created by that and it works around various broken drivers that use
241 * a non-aligned quantity to map the SAREA. --BenH
242 */
243 if (map->type == _DRM_SHM)
244 map->size = PAGE_ALIGN(map->size);
245
246 /*
247 * FreeBSD port note: FreeBSD's PAGE_MASK is the inverse of
248 * Linux's one. That's why the test below doesn't inverse the
249 * constant.
250 */
251 if ((map->offset & ((resource_size_t)PAGE_MASK)) || (map->size & (PAGE_MASK))) {
255 kfree(map);
252 free(map, DRM_MEM_MAPS);
256 return -EINVAL;
257 }
258 map->mtrr = -1;
259 map->handle = NULL;
260
261 switch (map->type) {
262 case _DRM_REGISTERS:
263 case _DRM_FRAME_BUFFER:

--- 15 unchanged lines hidden (view full) ---

279 if (list->map->size != map->size) {
280 DRM_DEBUG("Matching maps of type %d with "
281 "mismatched sizes, (%ld vs %ld)\n",
282 map->type, map->size,
283 list->map->size);
284 list->map->size = map->size;
285 }
286
253 return -EINVAL;
254 }
255 map->mtrr = -1;
256 map->handle = NULL;
257
258 switch (map->type) {
259 case _DRM_REGISTERS:
260 case _DRM_FRAME_BUFFER:

--- 15 unchanged lines hidden (view full) ---

276 if (list->map->size != map->size) {
277 DRM_DEBUG("Matching maps of type %d with "
278 "mismatched sizes, (%ld vs %ld)\n",
279 map->type, map->size,
280 list->map->size);
281 list->map->size = map->size;
282 }
283
287 kfree(map);
284 free(map, DRM_MEM_MAPS);
288 *maplist = list;
289 return 0;
290 }
291
292 if (drm_core_has_MTRR(dev)) {
293 if (map->type == _DRM_FRAME_BUFFER ||
294 (map->flags & _DRM_WRITE_COMBINING)) {
295 if (drm_mtrr_add(
296 map->offset, map->size,
297 DRM_MTRR_WC) == 0)
298 map->mtrr = 1;
299 }
300 }
301 if (map->type == _DRM_REGISTERS) {
302 drm_core_ioremap(map, dev);
303 if (!map->handle) {
285 *maplist = list;
286 return 0;
287 }
288
289 if (drm_core_has_MTRR(dev)) {
290 if (map->type == _DRM_FRAME_BUFFER ||
291 (map->flags & _DRM_WRITE_COMBINING)) {
292 if (drm_mtrr_add(
293 map->offset, map->size,
294 DRM_MTRR_WC) == 0)
295 map->mtrr = 1;
296 }
297 }
298 if (map->type == _DRM_REGISTERS) {
299 drm_core_ioremap(map, dev);
300 if (!map->handle) {
304 kfree(map);
301 free(map, DRM_MEM_MAPS);
305 return -ENOMEM;
306 }
307 }
308
309 break;
310 case _DRM_SHM:
311 list = drm_find_matching_map(dev, map);
312 if (list != NULL) {
313 if(list->map->size != map->size) {
314 DRM_DEBUG("Matching maps of type %d with "
315 "mismatched sizes, (%ld vs %ld)\n",
316 map->type, map->size, list->map->size);
317 list->map->size = map->size;
318 }
319
302 return -ENOMEM;
303 }
304 }
305
306 break;
307 case _DRM_SHM:
308 list = drm_find_matching_map(dev, map);
309 if (list != NULL) {
310 if(list->map->size != map->size) {
311 DRM_DEBUG("Matching maps of type %d with "
312 "mismatched sizes, (%ld vs %ld)\n",
313 map->type, map->size, list->map->size);
314 list->map->size = map->size;
315 }
316
320 kfree(map);
317 free(map, DRM_MEM_MAPS);
321 *maplist = list;
322 return 0;
323 }
318 *maplist = list;
319 return 0;
320 }
324 map->handle = vmalloc_user(map->size);
321 map->handle = malloc(map->size, DRM_MEM_MAPS, M_NOWAIT);
325 DRM_DEBUG("%lu %d %p\n",
326 map->size, drm_order(map->size), map->handle);
327 if (!map->handle) {
322 DRM_DEBUG("%lu %d %p\n",
323 map->size, drm_order(map->size), map->handle);
324 if (!map->handle) {
328 kfree(map);
325 free(map, DRM_MEM_MAPS);
329 return -ENOMEM;
330 }
331 map->offset = (unsigned long)map->handle;
332 if (map->flags & _DRM_CONTAINS_LOCK) {
333 /* Prevent a 2nd X Server from creating a 2nd lock */
334 if (dev->primary->master->lock.hw_lock != NULL) {
326 return -ENOMEM;
327 }
328 map->offset = (unsigned long)map->handle;
329 if (map->flags & _DRM_CONTAINS_LOCK) {
330 /* Prevent a 2nd X Server from creating a 2nd lock */
331 if (dev->primary->master->lock.hw_lock != NULL) {
335 kfree(map->handle);
336 kfree(map);
332 free(map->handle, DRM_MEM_MAPS);
333 free(map, DRM_MEM_MAPS);
337 return -EBUSY;
338 }
339 dev->sigdata.lock = dev->primary->master->lock.hw_lock = map->handle; /* Pointer to lock */
340 }
341 break;
342 case _DRM_AGP: {
343 struct drm_agp_mem *entry;
344 int valid = 0;
345
346 if (!drm_core_has_AGP(dev)) {
334 return -EBUSY;
335 }
336 dev->sigdata.lock = dev->primary->master->lock.hw_lock = map->handle; /* Pointer to lock */
337 }
338 break;
339 case _DRM_AGP: {
340 struct drm_agp_mem *entry;
341 int valid = 0;
342
343 if (!drm_core_has_AGP(dev)) {
347 kfree(map);
344 free(map, DRM_MEM_MAPS);
348 return -EINVAL;
349 }
350#ifdef __linux__
351#ifdef __alpha__
352 map->offset += dev->hose->mem_space->start;
353#endif
354#endif
355 /* In some cases (i810 driver), user space may have already

--- 18 unchanged lines hidden (view full) ---

374 list_for_each_entry(entry, &dev->agp->memory, head) {
375 if ((map->offset >= entry->bound) &&
376 (map->offset + map->size <= entry->bound + entry->pages * PAGE_SIZE)) {
377 valid = 1;
378 break;
379 }
380 }
381 if (!list_empty(&dev->agp->memory) && !valid) {
345 return -EINVAL;
346 }
347#ifdef __linux__
348#ifdef __alpha__
349 map->offset += dev->hose->mem_space->start;
350#endif
351#endif
352 /* In some cases (i810 driver), user space may have already

--- 18 unchanged lines hidden (view full) ---

371 list_for_each_entry(entry, &dev->agp->memory, head) {
372 if ((map->offset >= entry->bound) &&
373 (map->offset + map->size <= entry->bound + entry->pages * PAGE_SIZE)) {
374 valid = 1;
375 break;
376 }
377 }
378 if (!list_empty(&dev->agp->memory) && !valid) {
382 kfree(map);
379 free(map, DRM_MEM_MAPS);
383 return -EPERM;
384 }
385 DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n",
386 (unsigned long long)map->offset, map->size);
387
388 break;
389 }
390 case _DRM_GEM:
391 DRM_ERROR("tried to addmap GEM object\n");
392 break;
393 case _DRM_SCATTER_GATHER:
394 if (!dev->sg) {
380 return -EPERM;
381 }
382 DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n",
383 (unsigned long long)map->offset, map->size);
384
385 break;
386 }
387 case _DRM_GEM:
388 DRM_ERROR("tried to addmap GEM object\n");
389 break;
390 case _DRM_SCATTER_GATHER:
391 if (!dev->sg) {
395 kfree(map);
392 free(map, DRM_MEM_MAPS);
396 return -EINVAL;
397 }
398 map->handle = (void *)(dev->sg->vaddr + offset);
399 map->offset += dev->sg->vaddr;
400 break;
401 case _DRM_CONSISTENT:
402 /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
403 * As we're limiting the address to 2^32-1 (or less),
404 * casting it down to 32 bits is no problem, but we
405 * need to point to a 64bit variable first. */
406 align = map->size;
407 if ((align & (align - 1)) != 0)
408 align = PAGE_SIZE;
409 dmah = drm_pci_alloc(dev, map->size, align, BUS_SPACE_MAXADDR);
410 if (!dmah) {
393 return -EINVAL;
394 }
395 map->handle = (void *)(dev->sg->vaddr + offset);
396 map->offset += dev->sg->vaddr;
397 break;
398 case _DRM_CONSISTENT:
399 /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
400 * As we're limiting the address to 2^32-1 (or less),
401 * casting it down to 32 bits is no problem, but we
402 * need to point to a 64bit variable first. */
403 align = map->size;
404 if ((align & (align - 1)) != 0)
405 align = PAGE_SIZE;
406 dmah = drm_pci_alloc(dev, map->size, align, BUS_SPACE_MAXADDR);
407 if (!dmah) {
411 kfree(map);
408 free(map, DRM_MEM_MAPS);
412 return -ENOMEM;
413 }
414 map->handle = dmah->vaddr;
415 map->offset = dmah->busaddr;
416 map->dmah = dmah;
417 break;
418 default:
409 return -ENOMEM;
410 }
411 map->handle = dmah->vaddr;
412 map->offset = dmah->busaddr;
413 map->dmah = dmah;
414 break;
415 default:
419 kfree(map);
416 free(map, DRM_MEM_MAPS);
420 return -EINVAL;
421 }
422
417 return -EINVAL;
418 }
419
423 list = kzalloc(sizeof(*list), GFP_KERNEL);
420 list = malloc(sizeof(*list), DRM_MEM_MAPS, M_ZERO | M_NOWAIT);
424 if (!list) {
425 if (map->type == _DRM_REGISTERS)
426 drm_core_ioremapfree(map, dev);
421 if (!list) {
422 if (map->type == _DRM_REGISTERS)
423 drm_core_ioremapfree(map, dev);
427 kfree(map);
424 free(map, DRM_MEM_MAPS);
428 return -EINVAL;
429 }
430 list->map = map;
431
432 DRM_LOCK(dev);
433 list_add(&list->head, &dev->maplist);
434
435 /* Assign a 32-bit handle */
436 /* We do it here so that dev->struct_mutex protects the increment */
437 user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle :
438 map->offset;
439 ret = drm_map_handle(dev, &list->hash, user_token, 0,
440 (map->type == _DRM_SHM));
441 if (ret) {
442 if (map->type == _DRM_REGISTERS)
443 drm_core_ioremapfree(map, dev);
425 return -EINVAL;
426 }
427 list->map = map;
428
429 DRM_LOCK(dev);
430 list_add(&list->head, &dev->maplist);
431
432 /* Assign a 32-bit handle */
433 /* We do it here so that dev->struct_mutex protects the increment */
434 user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle :
435 map->offset;
436 ret = drm_map_handle(dev, &list->hash, user_token, 0,
437 (map->type == _DRM_SHM));
438 if (ret) {
439 if (map->type == _DRM_REGISTERS)
440 drm_core_ioremapfree(map, dev);
444 kfree(map);
445 kfree(list);
441 free(map, DRM_MEM_MAPS);
442 free(list, DRM_MEM_MAPS);
446 DRM_UNLOCK(dev);
447 return ret;
448 }
449
450 list->user_token = list->hash.key << PAGE_SHIFT;
451 DRM_UNLOCK(dev);
452
453 if (!(map->flags & _DRM_DRIVER))

--- 67 unchanged lines hidden (view full) ---

521
522 /* Find the list entry for the map and remove it */
523 list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
524 if (r_list->map == map) {
525 master = r_list->master;
526 list_del(&r_list->head);
527 drm_ht_remove_key(&dev->map_hash,
528 r_list->user_token >> PAGE_SHIFT);
443 DRM_UNLOCK(dev);
444 return ret;
445 }
446
447 list->user_token = list->hash.key << PAGE_SHIFT;
448 DRM_UNLOCK(dev);
449
450 if (!(map->flags & _DRM_DRIVER))

--- 67 unchanged lines hidden (view full) ---

518
519 /* Find the list entry for the map and remove it */
520 list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
521 if (r_list->map == map) {
522 master = r_list->master;
523 list_del(&r_list->head);
524 drm_ht_remove_key(&dev->map_hash,
525 r_list->user_token >> PAGE_SHIFT);
529 kfree(r_list);
526 free(r_list, DRM_MEM_MAPS);
530 found = 1;
531 break;
532 }
533 }
534
535 if (!found)
536 return -EINVAL;
537

--- 5 unchanged lines hidden (view full) ---

543 if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
544 int retcode;
545 retcode = drm_mtrr_del(map->mtrr, map->offset,
546 map->size, DRM_MTRR_WC);
547 DRM_DEBUG("mtrr_del=%d\n", retcode);
548 }
549 break;
550 case _DRM_SHM:
527 found = 1;
528 break;
529 }
530 }
531
532 if (!found)
533 return -EINVAL;
534

--- 5 unchanged lines hidden (view full) ---

540 if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
541 int retcode;
542 retcode = drm_mtrr_del(map->mtrr, map->offset,
543 map->size, DRM_MTRR_WC);
544 DRM_DEBUG("mtrr_del=%d\n", retcode);
545 }
546 break;
547 case _DRM_SHM:
551 kfree(map->handle);
548 free(map->handle, DRM_MEM_MAPS);
552 if (master) {
553 if (dev->sigdata.lock == master->lock.hw_lock)
554 dev->sigdata.lock = NULL;
555 master->lock.hw_lock = NULL; /* SHM removed */
556 master->lock.file_priv = NULL;
557 DRM_WAKEUP_INT((void *)&master->lock.lock_queue);
558 }
559 break;
560 case _DRM_AGP:
561 case _DRM_SCATTER_GATHER:
562 break;
563 case _DRM_CONSISTENT:
564 drm_pci_free(dev, map->dmah);
565 break;
566 case _DRM_GEM:
567 DRM_ERROR("tried to rmmap GEM object\n");
568 break;
569 }
549 if (master) {
550 if (dev->sigdata.lock == master->lock.hw_lock)
551 dev->sigdata.lock = NULL;
552 master->lock.hw_lock = NULL; /* SHM removed */
553 master->lock.file_priv = NULL;
554 DRM_WAKEUP_INT((void *)&master->lock.lock_queue);
555 }
556 break;
557 case _DRM_AGP:
558 case _DRM_SCATTER_GATHER:
559 break;
560 case _DRM_CONSISTENT:
561 drm_pci_free(dev, map->dmah);
562 break;
563 case _DRM_GEM:
564 DRM_ERROR("tried to rmmap GEM object\n");
565 break;
566 }
570 kfree(map);
567 free(map, DRM_MEM_MAPS);
571
572 return 0;
573}
574EXPORT_SYMBOL(drm_rmmap_locked);
575
576int drm_rmmap(struct drm_device *dev, struct drm_local_map *map)
577{
578 int ret;

--- 74 unchanged lines hidden (view full) ---

653 int i;
654
655 if (entry->seg_count) {
656 for (i = 0; i < entry->seg_count; i++) {
657 if (entry->seglist[i]) {
658 drm_pci_free(dev, entry->seglist[i]);
659 }
660 }
568
569 return 0;
570}
571EXPORT_SYMBOL(drm_rmmap_locked);
572
573int drm_rmmap(struct drm_device *dev, struct drm_local_map *map)
574{
575 int ret;

--- 74 unchanged lines hidden (view full) ---

650 int i;
651
652 if (entry->seg_count) {
653 for (i = 0; i < entry->seg_count; i++) {
654 if (entry->seglist[i]) {
655 drm_pci_free(dev, entry->seglist[i]);
656 }
657 }
661 kfree(entry->seglist);
658 free(entry->seglist, DRM_MEM_SEGS);
662
663 entry->seg_count = 0;
664 }
665
666 if (entry->buf_count) {
667 for (i = 0; i < entry->buf_count; i++) {
659
660 entry->seg_count = 0;
661 }
662
663 if (entry->buf_count) {
664 for (i = 0; i < entry->buf_count; i++) {
668 kfree(entry->buflist[i].dev_private);
665 free(entry->buflist[i].dev_private, DRM_MEM_BUFS);
669 }
666 }
670 kfree(entry->buflist);
667 free(entry->buflist, DRM_MEM_BUFS);
671
672 entry->buf_count = 0;
673 }
674}
675
676#if __OS_HAS_AGP
677/**
678 * Add AGP buffers for DMA transfers.

--- 80 unchanged lines hidden (view full) ---

759 }
760
761 if (count < 0 || count > 4096) {
762 DRM_UNLOCK(dev);
763 atomic_dec(&dev->buf_alloc);
764 return -EINVAL;
765 }
766
668
669 entry->buf_count = 0;
670 }
671}
672
673#if __OS_HAS_AGP
674/**
675 * Add AGP buffers for DMA transfers.

--- 80 unchanged lines hidden (view full) ---

756 }
757
758 if (count < 0 || count > 4096) {
759 DRM_UNLOCK(dev);
760 atomic_dec(&dev->buf_alloc);
761 return -EINVAL;
762 }
763
767 entry->buflist = kcalloc(count, sizeof(*entry->buflist), GFP_KERNEL);
764 entry->buflist = malloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS,
765 M_NOWAIT | M_ZERO);
768 if (!entry->buflist) {
769 DRM_UNLOCK(dev);
770 atomic_dec(&dev->buf_alloc);
771 return -ENOMEM;
772 }
773
774 entry->buf_size = size;
775 entry->page_order = page_order;

--- 11 unchanged lines hidden (view full) ---

787 buf->bus_address = agp_offset + offset;
788 buf->address = (void *)(agp_offset + offset);
789 buf->next = NULL;
790 buf->waiting = 0;
791 buf->pending = 0;
792 buf->file_priv = NULL;
793
794 buf->dev_priv_size = dev->driver->dev_priv_size;
766 if (!entry->buflist) {
767 DRM_UNLOCK(dev);
768 atomic_dec(&dev->buf_alloc);
769 return -ENOMEM;
770 }
771
772 entry->buf_size = size;
773 entry->page_order = page_order;

--- 11 unchanged lines hidden (view full) ---

785 buf->bus_address = agp_offset + offset;
786 buf->address = (void *)(agp_offset + offset);
787 buf->next = NULL;
788 buf->waiting = 0;
789 buf->pending = 0;
790 buf->file_priv = NULL;
791
792 buf->dev_priv_size = dev->driver->dev_priv_size;
795 buf->dev_private = kzalloc(buf->dev_priv_size, GFP_KERNEL);
793 buf->dev_private = malloc(buf->dev_priv_size, DRM_MEM_BUFS,
794 M_NOWAIT | M_ZERO);
796 if (!buf->dev_private) {
797 /* Set count correctly so we free the proper amount. */
798 entry->buf_count = count;
799 drm_cleanup_buf_error(dev, entry);
800 DRM_UNLOCK(dev);
801 atomic_dec(&dev->buf_alloc);
802 return -ENOMEM;
803 }
804
805 DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
806
807 offset += alignment;
808 entry->buf_count++;
809 byte_count += PAGE_SIZE << page_order;
810 }
811
812 DRM_DEBUG("byte_count: %d\n", byte_count);
813
795 if (!buf->dev_private) {
796 /* Set count correctly so we free the proper amount. */
797 entry->buf_count = count;
798 drm_cleanup_buf_error(dev, entry);
799 DRM_UNLOCK(dev);
800 atomic_dec(&dev->buf_alloc);
801 return -ENOMEM;
802 }
803
804 DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
805
806 offset += alignment;
807 entry->buf_count++;
808 byte_count += PAGE_SIZE << page_order;
809 }
810
811 DRM_DEBUG("byte_count: %d\n", byte_count);
812
814 temp_buflist = krealloc(dma->buflist,
815 (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), GFP_KERNEL);
813 temp_buflist = realloc(dma->buflist,
814 (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist),
815 DRM_MEM_BUFS, M_NOWAIT);
816 if (!temp_buflist) {
817 /* Free the entry because it isn't valid */
818 drm_cleanup_buf_error(dev, entry);
819 DRM_UNLOCK(dev);
820 atomic_dec(&dev->buf_alloc);
821 return -ENOMEM;
822 }
823 dma->buflist = temp_buflist;

--- 83 unchanged lines hidden (view full) ---

907 }
908
909 if (count < 0 || count > 4096) {
910 DRM_UNLOCK(dev);
911 atomic_dec(&dev->buf_alloc);
912 return -EINVAL;
913 }
914
816 if (!temp_buflist) {
817 /* Free the entry because it isn't valid */
818 drm_cleanup_buf_error(dev, entry);
819 DRM_UNLOCK(dev);
820 atomic_dec(&dev->buf_alloc);
821 return -ENOMEM;
822 }
823 dma->buflist = temp_buflist;

--- 83 unchanged lines hidden (view full) ---

907 }
908
909 if (count < 0 || count > 4096) {
910 DRM_UNLOCK(dev);
911 atomic_dec(&dev->buf_alloc);
912 return -EINVAL;
913 }
914
915 entry->buflist = kcalloc(count, sizeof(*entry->buflist), GFP_KERNEL);
915 entry->buflist = malloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS,
916 M_NOWAIT | M_ZERO);
916 if (!entry->buflist) {
917 DRM_UNLOCK(dev);
918 atomic_dec(&dev->buf_alloc);
919 return -ENOMEM;
920 }
921
917 if (!entry->buflist) {
918 DRM_UNLOCK(dev);
919 atomic_dec(&dev->buf_alloc);
920 return -ENOMEM;
921 }
922
922 entry->seglist = kcalloc(count, sizeof(*entry->seglist), GFP_KERNEL);
923 entry->seglist = malloc(count * sizeof(*entry->seglist), DRM_MEM_SEGS,
924 M_NOWAIT | M_ZERO);
923 if (!entry->seglist) {
925 if (!entry->seglist) {
924 kfree(entry->buflist);
926 free(entry->buflist, DRM_MEM_BUFS);
925 DRM_UNLOCK(dev);
926 atomic_dec(&dev->buf_alloc);
927 return -ENOMEM;
928 }
929
930 /* Keep the original pagelist until we know all the allocations
931 * have succeeded
932 */
927 DRM_UNLOCK(dev);
928 atomic_dec(&dev->buf_alloc);
929 return -ENOMEM;
930 }
931
932 /* Keep the original pagelist until we know all the allocations
933 * have succeeded
934 */
933 temp_pagelist = kmalloc_array(dma->page_count + (count << page_order),
934 sizeof(*dma->pagelist),
935 GFP_KERNEL);
935 temp_pagelist = malloc((dma->page_count + (count << page_order)) *
936 sizeof(*dma->pagelist), DRM_MEM_PAGES, M_NOWAIT);
936 if (!temp_pagelist) {
937 if (!temp_pagelist) {
937 kfree(entry->buflist);
938 kfree(entry->seglist);
938 free(entry->buflist, DRM_MEM_BUFS);
939 free(entry->seglist, DRM_MEM_SEGS);
939 DRM_UNLOCK(dev);
940 atomic_dec(&dev->buf_alloc);
941 return -ENOMEM;
942 }
943 memcpy(temp_pagelist,
944 dma->pagelist, dma->page_count * sizeof(*dma->pagelist));
945 DRM_DEBUG("pagelist: %d entries\n",
946 dma->page_count + (count << page_order));

--- 7 unchanged lines hidden (view full) ---

954
955 dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, BUS_SPACE_MAXADDR);
956
957 if (!dmah) {
958 /* Set count correctly so we free the proper amount. */
959 entry->buf_count = count;
960 entry->seg_count = count;
961 drm_cleanup_buf_error(dev, entry);
940 DRM_UNLOCK(dev);
941 atomic_dec(&dev->buf_alloc);
942 return -ENOMEM;
943 }
944 memcpy(temp_pagelist,
945 dma->pagelist, dma->page_count * sizeof(*dma->pagelist));
946 DRM_DEBUG("pagelist: %d entries\n",
947 dma->page_count + (count << page_order));

--- 7 unchanged lines hidden (view full) ---

955
956 dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, BUS_SPACE_MAXADDR);
957
958 if (!dmah) {
959 /* Set count correctly so we free the proper amount. */
960 entry->buf_count = count;
961 entry->seg_count = count;
962 drm_cleanup_buf_error(dev, entry);
962 kfree(temp_pagelist);
963 free(temp_pagelist, DRM_MEM_PAGES);
963 DRM_UNLOCK(dev);
964 atomic_dec(&dev->buf_alloc);
965 return -ENOMEM;
966 }
967 entry->seglist[entry->seg_count++] = dmah;
968 for (i = 0; i < (1 << page_order); i++) {
969 DRM_DEBUG("page %d @ 0x%08lx\n",
970 dma->page_count + page_count,

--- 13 unchanged lines hidden (view full) ---

984 buf->address = (void *)((char *)dmah->vaddr + offset);
985 buf->bus_address = dmah->busaddr + offset;
986 buf->next = NULL;
987 buf->waiting = 0;
988 buf->pending = 0;
989 buf->file_priv = NULL;
990
991 buf->dev_priv_size = dev->driver->dev_priv_size;
964 DRM_UNLOCK(dev);
965 atomic_dec(&dev->buf_alloc);
966 return -ENOMEM;
967 }
968 entry->seglist[entry->seg_count++] = dmah;
969 for (i = 0; i < (1 << page_order); i++) {
970 DRM_DEBUG("page %d @ 0x%08lx\n",
971 dma->page_count + page_count,

--- 13 unchanged lines hidden (view full) ---

985 buf->address = (void *)((char *)dmah->vaddr + offset);
986 buf->bus_address = dmah->busaddr + offset;
987 buf->next = NULL;
988 buf->waiting = 0;
989 buf->pending = 0;
990 buf->file_priv = NULL;
991
992 buf->dev_priv_size = dev->driver->dev_priv_size;
992 buf->dev_private = kzalloc(buf->dev_priv_size,
993 GFP_KERNEL);
993 buf->dev_private = malloc(buf->dev_priv_size,
994 DRM_MEM_BUFS, M_NOWAIT | M_ZERO);
994 if (!buf->dev_private) {
995 /* Set count correctly so we free the proper amount. */
996 entry->buf_count = count;
997 entry->seg_count = count;
998 drm_cleanup_buf_error(dev, entry);
995 if (!buf->dev_private) {
996 /* Set count correctly so we free the proper amount. */
997 entry->buf_count = count;
998 entry->seg_count = count;
999 drm_cleanup_buf_error(dev, entry);
999 kfree(temp_pagelist);
1000 free(temp_pagelist, DRM_MEM_PAGES);
1000 DRM_UNLOCK(dev);
1001 atomic_dec(&dev->buf_alloc);
1002 return -ENOMEM;
1003 }
1004
1005 DRM_DEBUG("buffer %d @ %p\n",
1006 entry->buf_count, buf->address);
1007 }
1008 byte_count += PAGE_SIZE << page_order;
1009 }
1010
1001 DRM_UNLOCK(dev);
1002 atomic_dec(&dev->buf_alloc);
1003 return -ENOMEM;
1004 }
1005
1006 DRM_DEBUG("buffer %d @ %p\n",
1007 entry->buf_count, buf->address);
1008 }
1009 byte_count += PAGE_SIZE << page_order;
1010 }
1011
1011 temp_buflist = krealloc(dma->buflist,
1012 (dma->buf_count + entry->buf_count) *
1013 sizeof(*dma->buflist), GFP_KERNEL);
1012 temp_buflist = realloc(dma->buflist,
1013 (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist),
1014 DRM_MEM_BUFS, M_NOWAIT);
1014 if (!temp_buflist) {
1015 /* Free the entry because it isn't valid */
1016 drm_cleanup_buf_error(dev, entry);
1015 if (!temp_buflist) {
1016 /* Free the entry because it isn't valid */
1017 drm_cleanup_buf_error(dev, entry);
1017 kfree(temp_pagelist);
1018 free(temp_pagelist, DRM_MEM_PAGES);
1018 DRM_UNLOCK(dev);
1019 atomic_dec(&dev->buf_alloc);
1020 return -ENOMEM;
1021 }
1022 dma->buflist = temp_buflist;
1023
1024 for (i = 0; i < entry->buf_count; i++) {
1025 dma->buflist[i + dma->buf_count] = &entry->buflist[i];
1026 }
1027
1028 /* No allocations failed, so now we can replace the original pagelist
1029 * with the new one.
1030 */
1031 if (dma->page_count) {
1019 DRM_UNLOCK(dev);
1020 atomic_dec(&dev->buf_alloc);
1021 return -ENOMEM;
1022 }
1023 dma->buflist = temp_buflist;
1024
1025 for (i = 0; i < entry->buf_count; i++) {
1026 dma->buflist[i + dma->buf_count] = &entry->buflist[i];
1027 }
1028
1029 /* No allocations failed, so now we can replace the original pagelist
1030 * with the new one.
1031 */
1032 if (dma->page_count) {
1032 kfree(dma->pagelist);
1033 free(dma->pagelist, DRM_MEM_PAGES);
1033 }
1034 dma->pagelist = temp_pagelist;
1035
1036 dma->buf_count += entry->buf_count;
1037 dma->seg_count += entry->seg_count;
1038 dma->page_count += entry->seg_count << page_order;
1039 dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
1040

--- 77 unchanged lines hidden (view full) ---

1118 }
1119
1120 if (count < 0 || count > 4096) {
1121 DRM_UNLOCK(dev);
1122 atomic_dec(&dev->buf_alloc);
1123 return -EINVAL;
1124 }
1125
1034 }
1035 dma->pagelist = temp_pagelist;
1036
1037 dma->buf_count += entry->buf_count;
1038 dma->seg_count += entry->seg_count;
1039 dma->page_count += entry->seg_count << page_order;
1040 dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
1041

--- 77 unchanged lines hidden (view full) ---

1119 }
1120
1121 if (count < 0 || count > 4096) {
1122 DRM_UNLOCK(dev);
1123 atomic_dec(&dev->buf_alloc);
1124 return -EINVAL;
1125 }
1126
1126 entry->buflist = kcalloc(count, sizeof(*entry->buflist), GFP_KERNEL);
1127 entry->buflist = malloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS,
1128 M_NOWAIT | M_ZERO);
1127 if (!entry->buflist) {
1128 DRM_UNLOCK(dev);
1129 atomic_dec(&dev->buf_alloc);
1130 return -ENOMEM;
1131 }
1132
1133 entry->buf_size = size;
1134 entry->page_order = page_order;

--- 12 unchanged lines hidden (view full) ---

1147 buf->address = (void *)(agp_offset + offset
1148 + (unsigned long)dev->sg->vaddr);
1149 buf->next = NULL;
1150 buf->waiting = 0;
1151 buf->pending = 0;
1152 buf->file_priv = NULL;
1153
1154 buf->dev_priv_size = dev->driver->dev_priv_size;
1129 if (!entry->buflist) {
1130 DRM_UNLOCK(dev);
1131 atomic_dec(&dev->buf_alloc);
1132 return -ENOMEM;
1133 }
1134
1135 entry->buf_size = size;
1136 entry->page_order = page_order;

--- 12 unchanged lines hidden (view full) ---

1149 buf->address = (void *)(agp_offset + offset
1150 + (unsigned long)dev->sg->vaddr);
1151 buf->next = NULL;
1152 buf->waiting = 0;
1153 buf->pending = 0;
1154 buf->file_priv = NULL;
1155
1156 buf->dev_priv_size = dev->driver->dev_priv_size;
1155 buf->dev_private = kzalloc(buf->dev_priv_size, GFP_KERNEL);
1157 buf->dev_private = malloc(buf->dev_priv_size, DRM_MEM_BUFS,
1158 M_NOWAIT | M_ZERO);
1156 if (!buf->dev_private) {
1157 /* Set count correctly so we free the proper amount. */
1158 entry->buf_count = count;
1159 drm_cleanup_buf_error(dev, entry);
1160 DRM_UNLOCK(dev);
1161 atomic_dec(&dev->buf_alloc);
1162 return -ENOMEM;
1163 }
1164
1165 DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
1166
1167 offset += alignment;
1168 entry->buf_count++;
1169 byte_count += PAGE_SIZE << page_order;
1170 }
1171
1172 DRM_DEBUG("byte_count: %d\n", byte_count);
1173
1159 if (!buf->dev_private) {
1160 /* Set count correctly so we free the proper amount. */
1161 entry->buf_count = count;
1162 drm_cleanup_buf_error(dev, entry);
1163 DRM_UNLOCK(dev);
1164 atomic_dec(&dev->buf_alloc);
1165 return -ENOMEM;
1166 }
1167
1168 DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
1169
1170 offset += alignment;
1171 entry->buf_count++;
1172 byte_count += PAGE_SIZE << page_order;
1173 }
1174
1175 DRM_DEBUG("byte_count: %d\n", byte_count);
1176
1174 temp_buflist = krealloc(dma->buflist,
1175 (dma->buf_count + entry->buf_count) *
1176 sizeof(*dma->buflist), GFP_KERNEL);
1177 temp_buflist = realloc(dma->buflist,
1178 (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist),
1179 DRM_MEM_BUFS, M_NOWAIT);
1177 if (!temp_buflist) {
1178 /* Free the entry because it isn't valid */
1179 drm_cleanup_buf_error(dev, entry);
1180 DRM_UNLOCK(dev);
1181 atomic_dec(&dev->buf_alloc);
1182 return -ENOMEM;
1183 }
1184 dma->buflist = temp_buflist;

--- 87 unchanged lines hidden (view full) ---

1272 }
1273
1274 if (count < 0 || count > 4096) {
1275 DRM_UNLOCK(dev);
1276 atomic_dec(&dev->buf_alloc);
1277 return -EINVAL;
1278 }
1279
1180 if (!temp_buflist) {
1181 /* Free the entry because it isn't valid */
1182 drm_cleanup_buf_error(dev, entry);
1183 DRM_UNLOCK(dev);
1184 atomic_dec(&dev->buf_alloc);
1185 return -ENOMEM;
1186 }
1187 dma->buflist = temp_buflist;

--- 87 unchanged lines hidden (view full) ---

1275 }
1276
1277 if (count < 0 || count > 4096) {
1278 DRM_UNLOCK(dev);
1279 atomic_dec(&dev->buf_alloc);
1280 return -EINVAL;
1281 }
1282
1280 entry->buflist = kzalloc(count * sizeof(*entry->buflist), GFP_KERNEL);
1283 entry->buflist = malloc(count * sizeof(*entry->buflist), DRM_MEM_BUFS,
1284 M_NOWAIT | M_ZERO);
1281 if (!entry->buflist) {
1282 DRM_UNLOCK(dev);
1283 atomic_dec(&dev->buf_alloc);
1284 return -ENOMEM;
1285 }
1286
1287 entry->buf_size = size;
1288 entry->page_order = page_order;

--- 11 unchanged lines hidden (view full) ---

1300 buf->bus_address = agp_offset + offset;
1301 buf->address = (void *)(agp_offset + offset);
1302 buf->next = NULL;
1303 buf->waiting = 0;
1304 buf->pending = 0;
1305 buf->file_priv = NULL;
1306
1307 buf->dev_priv_size = dev->driver->dev_priv_size;
1285 if (!entry->buflist) {
1286 DRM_UNLOCK(dev);
1287 atomic_dec(&dev->buf_alloc);
1288 return -ENOMEM;
1289 }
1290
1291 entry->buf_size = size;
1292 entry->page_order = page_order;

--- 11 unchanged lines hidden (view full) ---

1304 buf->bus_address = agp_offset + offset;
1305 buf->address = (void *)(agp_offset + offset);
1306 buf->next = NULL;
1307 buf->waiting = 0;
1308 buf->pending = 0;
1309 buf->file_priv = NULL;
1310
1311 buf->dev_priv_size = dev->driver->dev_priv_size;
1308 buf->dev_private = kmalloc(buf->dev_priv_size, GFP_KERNEL);
1312 buf->dev_private = malloc(buf->dev_priv_size, DRM_MEM_BUFS,
1313 M_NOWAIT | M_ZERO);
1309 if (!buf->dev_private) {
1310 /* Set count correctly so we free the proper amount. */
1311 entry->buf_count = count;
1312 drm_cleanup_buf_error(dev, entry);
1313 DRM_UNLOCK(dev);
1314 atomic_dec(&dev->buf_alloc);
1315 return -ENOMEM;
1316 }
1317
1318 DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
1319
1320 offset += alignment;
1321 entry->buf_count++;
1322 byte_count += PAGE_SIZE << page_order;
1323 }
1324
1325 DRM_DEBUG("byte_count: %d\n", byte_count);
1326
1314 if (!buf->dev_private) {
1315 /* Set count correctly so we free the proper amount. */
1316 entry->buf_count = count;
1317 drm_cleanup_buf_error(dev, entry);
1318 DRM_UNLOCK(dev);
1319 atomic_dec(&dev->buf_alloc);
1320 return -ENOMEM;
1321 }
1322
1323 DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
1324
1325 offset += alignment;
1326 entry->buf_count++;
1327 byte_count += PAGE_SIZE << page_order;
1328 }
1329
1330 DRM_DEBUG("byte_count: %d\n", byte_count);
1331
1327 temp_buflist = krealloc(dma->buflist,
1328 (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), GFP_KERNEL);
1332 temp_buflist = realloc(dma->buflist,
1333 (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist),
1334 DRM_MEM_BUFS, M_NOWAIT);
1329 if (!temp_buflist) {
1330 /* Free the entry because it isn't valid */
1331 drm_cleanup_buf_error(dev, entry);
1332 DRM_UNLOCK(dev);
1333 atomic_dec(&dev->buf_alloc);
1334 return -ENOMEM;
1335 }
1336 dma->buflist = temp_buflist;

--- 366 unchanged lines hidden ---
1335 if (!temp_buflist) {
1336 /* Free the entry because it isn't valid */
1337 drm_cleanup_buf_error(dev, entry);
1338 DRM_UNLOCK(dev);
1339 atomic_dec(&dev->buf_alloc);
1340 return -ENOMEM;
1341 }
1342 dma->buflist = temp_buflist;

--- 366 unchanged lines hidden ---