vfs: check userland buffers before reading them.
[haiku.git] / src / system / kernel / device_manager / io_resources.cpp
blob738c2a294711b54e8b570af1347eb2fd0a3f4f0e
1 /*
2 * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Copyright 2002-2004, Thomas Kurschel. All rights reserved.
5 * Distributed under the terms of the MIT License.
6 */
9 #include "io_resources.h"
11 #include <stdlib.h>
12 #include <string.h>
15 //#define TRACE_IO_RESOURCES
16 #ifdef TRACE_IO_RESOURCES
17 # define TRACE(x) dprintf x
18 #else
19 # define TRACE(x) ;
20 #endif
23 typedef DoublyLinkedList<io_resource_private,
24 DoublyLinkedListMemberGetLink<io_resource_private,
25 &io_resource_private::fTypeLink> > ResourceTypeList;
28 static ResourceTypeList sMemoryList;
29 static ResourceTypeList sPortList;
30 static ResourceTypeList sDMAChannelList;
33 io_resource_private::io_resource_private()
35 _Init();
39 io_resource_private::~io_resource_private()
41 Release();
45 void
46 io_resource_private::_Init()
48 type = 0;
49 base = 0;
50 length = 0;
54 status_t
55 io_resource_private::Acquire(const io_resource& resource)
57 if (!_IsValid(resource))
58 return B_BAD_VALUE;
60 type = resource.type;
61 base = resource.base;
63 if (type != B_ISA_DMA_CHANNEL)
64 length = resource.length;
65 else
66 length = 1;
68 ResourceTypeList* list = NULL;
70 switch (type) {
71 case B_IO_MEMORY:
72 list = &sMemoryList;
73 break;
74 case B_IO_PORT:
75 list = &sPortList;
76 break;
77 case B_ISA_DMA_CHANNEL:
78 list = &sDMAChannelList;
79 break;
82 ResourceTypeList::Iterator iterator = list->GetIterator();
83 while (iterator.HasNext()) {
84 io_resource* resource = iterator.Next();
86 // we need the "base + length - 1" trick to avoid wrap around at 4 GB
87 if (resource->base >= base
88 && resource->base + length - 1 <= base + length - 1) {
89 // This range is already covered by someone else
90 // TODO: we might want to ignore resources that belong to
91 // a node that isn't used.
92 _Init();
93 return B_RESOURCE_UNAVAILABLE;
97 list->Add(this);
98 return B_OK;
102 void
103 io_resource_private::Release()
105 if (type == 0)
106 return;
108 switch (type) {
109 case B_IO_MEMORY:
110 sMemoryList.Remove(this);
111 break;
112 case B_IO_PORT:
113 sPortList.Remove(this);
114 break;
115 case B_ISA_DMA_CHANNEL:
116 sDMAChannelList.Remove(this);
117 break;
120 _Init();
124 /*static*/ bool
125 io_resource_private::_IsValid(const io_resource& resource)
127 switch (resource.type) {
128 case B_IO_MEMORY:
129 return resource.base + resource.length > resource.base;
130 case B_IO_PORT:
131 return (uint16)resource.base == resource.base
132 && (uint16)resource.length == resource.length
133 && resource.base + resource.length > resource.base;
134 case B_ISA_DMA_CHANNEL:
135 return resource.base <= 8;
137 default:
138 return false;
143 // #pragma mark -
146 void
147 dm_init_io_resources(void)
149 new(&sMemoryList) ResourceTypeList;
150 new(&sPortList) ResourceTypeList;
151 new(&sDMAChannelList) ResourceTypeList;