vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / drivers / network / rtl8169 / util.c
blobf55587b10273a1443376d6b0cf80b416aea69782
1 /* Realtek RTL8169 Family Driver
2 * Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
4 * Permission to use, copy, modify and distribute this software and its
5 * documentation for any purpose and without fee is hereby granted, provided
6 * that the above copyright notice appear in all copies, and that both the
7 * copyright notice and this permission notice appear in supporting documentation.
9 * Marcus Overhagen makes no representations about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
12 * MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
13 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS
14 * OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
15 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <Errors.h>
20 #include <OS.h>
21 #include <string.h>
23 //#define DEBUG
25 #include "debug.h"
26 #include "util.h"
29 static inline uint32
30 round_to_pagesize(uint32 size)
32 return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
36 area_id
37 alloc_contiguous(void **virt, void **phy, size_t size, uint32 protection,
38 const char *name)
40 // TODO: phy should be phys_addr_t*!
41 physical_entry pe;
42 void * virtadr;
43 area_id areaid;
44 status_t rv;
46 TRACE("allocating %ld bytes for %s\n", size, name);
48 size = round_to_pagesize(size);
49 areaid = create_area(name, &virtadr, B_ANY_KERNEL_ADDRESS, size,
50 B_32_BIT_CONTIGUOUS, protection);
51 // TODO: The rest of the code doesn't deal correctly with physical
52 // addresses > 4 GB, so we have to force 32 bit addresses here.
53 if (areaid < B_OK) {
54 ERROR("couldn't allocate area %s\n", name);
55 return B_ERROR;
57 rv = get_memory_map(virtadr, size, &pe, 1);
58 if (rv < B_OK) {
59 delete_area(areaid);
60 ERROR("couldn't get mapping for %s\n", name);
61 return B_ERROR;
63 memset(virtadr, 0, size);
64 if (virt)
65 *virt = virtadr;
66 if (phy)
67 *phy = (void*)(addr_t)pe.address;
68 TRACE("area = %ld, size = %ld, virt = %p, phy = %p\n", areaid, size, virtadr, pe.address);
69 return areaid;
73 area_id
74 map_mem(void **virt, void *phy, size_t size, uint32 protection,
75 const char *name)
77 uint32 offset;
78 void *phyadr;
79 void *mapadr;
80 area_id area;
82 TRACE("mapping physical address %p with %ld bytes for %s\n", phy, size, name);
84 offset = (uint32)phy & (B_PAGE_SIZE - 1);
85 phyadr = (char *)phy - offset;
86 size = round_to_pagesize(size + offset);
87 area = map_physical_memory(name, (addr_t)phyadr, size, B_ANY_KERNEL_ADDRESS,
88 protection, &mapadr);
89 if (area < B_OK) {
90 ERROR("mapping '%s' failed, error 0x%lx (%s)\n", name, area, strerror(area));
91 return area;
94 *virt = (char *)mapadr + offset;
96 TRACE("physical = %p, virtual = %p, offset = %ld, phyadr = %p, mapadr = "
97 "%p, size = %ld, area = 0x%08lx\n", phy, *virt, offset, phyadr, mapadr,
98 size, area);
100 return area;