1f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/* 2f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Copyright 2007 Nouveau Project 3f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * 4f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Permission is hereby granted, free of charge, to any person obtaining a 5f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * copy of this software and associated documentation files (the "Software"), 6f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * to deal in the Software without restriction, including without limitation 7f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * and/or sell copies of the Software, and to permit persons to whom the 9f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Software is furnished to do so, subject to the following conditions: 10f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * 11f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * The above copyright notice and this permission notice shall be included in 12f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * all copies or substantial portions of the Software. 13f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * 14f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * SOFTWARE. 21f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */ 22f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 23f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <stdlib.h> 24f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <errno.h> 25f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 26f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include "nouveau_private.h" 27f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 28f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint 29f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryunouveau_resource_init(struct nouveau_resource **heap, 30f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu unsigned start, unsigned size) 31f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{ 32f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu struct nouveau_resource *r; 33f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 34f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r = calloc(1, sizeof(struct nouveau_resource)); 35f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu if (!r) 36f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu return 1; 37f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 38f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->start = start; 39f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->size = size; 40f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *heap = r; 41f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu return 0; 42f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu} 43f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 44f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint 45f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryunouveau_resource_alloc(struct nouveau_resource *heap, unsigned size, void *priv, 46f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu struct nouveau_resource **res) 47f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{ 48f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu struct nouveau_resource *r; 49f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 50f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu if (!heap || !size || !res || *res) 51f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu return 1; 52f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 53f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu while (heap) { 54f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu if (!heap->in_use && heap->size >= size) { 55f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r = calloc(1, sizeof(struct nouveau_resource)); 56f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu if (!r) 57f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu return 1; 58f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 59f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->start = (heap->start + heap->size) - size; 60f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->size = size; 61f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->in_use = 1; 62f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->priv = priv; 63f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 64f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu heap->size -= size; 65f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 66f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->next = heap->next; 67f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu if (heap->next) 68f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu heap->next->prev = r; 69f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->prev = heap; 70f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu heap->next = r; 71f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 72f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *res = r; 73f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu return 0; 74f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu } 75f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 76f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu heap = heap->next; 77f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu } 78f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 79f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu return 1; 80f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu} 81f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 82f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuvoid 83f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryunouveau_resource_free(struct nouveau_resource **res) 84f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{ 85f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu struct nouveau_resource *r; 86f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 87f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu if (!res || !*res) 88f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu return; 89f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r = *res; 90f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *res = NULL; 91f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 92f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->in_use = 0; 93f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 94f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu if (r->next && !r->next->in_use) { 95f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu struct nouveau_resource *new = r->next; 96f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 97f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu new->prev = r->prev; 98f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu if (r->prev) 99f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->prev->next = new; 100f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu new->size += r->size; 101f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu new->start = r->start; 102f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 103f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu free(r); 104f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r = new; 105f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu } 106f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 107f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu if (r->prev && !r->prev->in_use) { 108f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->prev->next = r->next; 109f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu if (r->next) 110f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->next->prev = r->prev; 111f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu r->prev->size += r->size; 112f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu free(r); 113f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu } 114f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu 115f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu} 116