]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/lib/amm/amm_deallocate.c
c6df7f209bcdfc09928eb669979fb32f75698b2c
[l4.git] / kernel / fiasco / src / lib / amm / amm_deallocate.c
1 /*
2  * Copyright (c) 1996, 1998 University of Utah and the Flux Group.
3  * All rights reserved.
4  * 
5  * This file is part of the Flux OSKit.  The OSKit is free software, also known
6  * as "open source;" you can redistribute it and/or modify it under the terms
7  * of the GNU General Public License (GPL), version 2, as published by the Free
8  * Software Foundation (FSF).  To explore alternate licensing terms, contact
9  * the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271.
10  * 
11  * The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GPL for more details.  You should have
14  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
15  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
16  */
17
18 /*
19  * Simple address map deallocation routine, similar to what POSIX munmap or
20  * Mach vm_deallocate would require.
21  */
22 #include <errno.h>
23 #include "amm.h"
24
25 /*
26  * amm_deallocate frees a range of address space.
27  * Only AMM_ALLOCATED areas are freed, AMM_RESERVED/FREE regions are skipped.
28  *
29  * Addr and size define the range.
30  *
31  * Returns zero on success, error number on failure.
32  */
33 int
34 amm_deallocate(struct amm *amm, vm_offset_t addr, vm_size_t size)
35 {
36         vm_offset_t saddr, eaddr;
37         amm_entry_t *entry;
38         int rc;
39
40         saddr = addr;
41         eaddr = saddr + size;
42         while (saddr < eaddr) {
43                 /*
44                  * Find the next allocated entry and free the portion
45                  * covered by our range.
46                  */
47                 entry = amm_find_addr(amm, saddr);
48                 if ((amm_entry_flags(entry) & AMM_ALLOCATED) == AMM_ALLOCATED) {
49                         if (eaddr < amm_entry_end(entry))
50                                 size = eaddr - saddr;
51                         else
52                                 size = amm_entry_end(entry) - saddr;
53                         rc = amm_modify(amm, saddr, size, AMM_FREE, 0);
54                         if (rc)
55                                 return rc;
56                 }
57                 saddr = amm_entry_end(entry);
58         }
59         return 0;
60 }