1 /* 2 * c 2001 PPC 64 Team, IBM Corp 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 */ 9 10 #include <linux/slab.h> 11 #include <linux/vmalloc.h> 12 #include <linux/spinlock.h> 13 14 #include <asm/uaccess.h> 15 #include <asm/pgalloc.h> 16 17 rwlock_t imlist_lock = RW_LOCK_UNLOCKED; 18 struct vm_struct * imlist = NULL; 19 get_im_area(unsigned long size)20struct vm_struct *get_im_area(unsigned long size) 21 { 22 unsigned long addr; 23 struct vm_struct **p, *tmp, *area; 24 25 area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL); 26 if (!area) 27 return NULL; 28 addr = IMALLOC_START; 29 write_lock(&imlist_lock); 30 for (p = &imlist; (tmp = *p) ; p = &tmp->next) { 31 if (size + addr < (unsigned long) tmp->addr) 32 break; 33 addr = tmp->size + (unsigned long) tmp->addr; 34 if (addr > IMALLOC_END-size) { 35 write_unlock(&imlist_lock); 36 kfree(area); 37 return NULL; 38 } 39 } 40 area->flags = 0; 41 area->addr = (void *)addr; 42 area->size = size; 43 area->next = *p; 44 *p = area; 45 write_unlock(&imlist_lock); 46 return area; 47 } 48 ifree(void * addr)49void ifree(void * addr) 50 { 51 struct vm_struct **p, *tmp; 52 53 if (!addr) 54 return; 55 if ((PAGE_SIZE-1) & (unsigned long) addr) { 56 printk(KERN_ERR "Trying to ifree() bad address (%p)\n", addr); 57 return; 58 } 59 write_lock(&imlist_lock); 60 for (p = &imlist ; (tmp = *p) ; p = &tmp->next) { 61 if (tmp->addr == addr) { 62 *p = tmp->next; 63 kfree(tmp); 64 write_unlock(&imlist_lock); 65 return; 66 } 67 } 68 write_unlock(&imlist_lock); 69 printk(KERN_ERR "Trying to ifree() nonexistent area (%p)\n", addr); 70 } 71 72