1/*
2 * Copyright 2005, Oscar Lesta. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include <Drivers.h>
8#include <KernelExport.h>
9#include <ISA.h>
10#include <PCI.h>
11
12#include "poke.h"
13
14
15////////////////////////////////////////////////////////////////////////////////
16
17static status_t poke_open(const char*, uint32, void**);
18static status_t poke_close(void*);
19static status_t poke_free(void*);
20static status_t poke_control(void*, uint32, void*, size_t);
21static status_t poke_read(void*, off_t, void*, size_t*);
22static status_t poke_write(void*, off_t, const void*, size_t*);
23
24////////////////////////////////////////////////////////////////////////////////
25
26static const char* poke_name[] = {
27    "misc/"POKE_DEVICE_NAME,
28    NULL
29};
30
31
32device_hooks poke_hooks = {
33	poke_open,
34	poke_close,
35	poke_free,
36	poke_control,
37	poke_read,
38	poke_write,
39};
40
41int32 api_version = B_CUR_DRIVER_API_VERSION;
42
43isa_module_info* isa;
44pci_module_info* pci;
45
46static vint32 open_count;
47
48////////////////////////////////////////////////////////////////////////////////
49
50
51status_t
52init_hardware(void)
53{
54	return B_OK;
55}
56
57
58status_t
59init_driver(void)
60{
61	open_count = 0;
62
63	if (get_module(B_ISA_MODULE_NAME, (module_info**)&isa) < B_OK)
64		return ENOSYS;
65
66	if (get_module(B_PCI_MODULE_NAME, (module_info**)&pci) < B_OK) {
67		put_module(B_ISA_MODULE_NAME);
68		return ENOSYS;
69	}
70
71	return B_OK;
72}
73
74
75void
76uninit_driver(void)
77{
78	put_module(B_ISA_MODULE_NAME);
79	put_module(B_PCI_MODULE_NAME);
80}
81
82
83const char**
84publish_devices(void)
85{
86	return poke_name;
87}
88
89
90device_hooks*
91find_device(const char* name)
92{
93	return &poke_hooks;
94}
95
96
97////////////////////////////////////////////////////////////////////////////////
98//	#pragma mark -
99
100
101status_t
102poke_open(const char* name, uint32 flags, void** cookie)
103{
104	*cookie = NULL;
105
106	if (atomic_add(&open_count, 1) != 0) {
107		atomic_add(&open_count, -1);
108		return B_BUSY;
109	}
110
111	return B_OK;
112}
113
114
115status_t
116poke_close(void* cookie)
117{
118	return B_OK;
119}
120
121
122status_t
123poke_free(void* cookie)
124{
125	atomic_add(&open_count, -1);
126	return B_OK;
127}
128
129
130status_t
131poke_control(void* cookie, uint32 op, void* arg, size_t length)
132{
133	switch (op) {
134		case POKE_PORT_READ:
135		{
136    		status_t result;
137			port_io_args* ioctl = (port_io_args*)arg;
138			if (ioctl->signature != POKE_SIGNATURE)
139				return B_BAD_VALUE;
140
141			result = B_OK;
142			switch (ioctl->size) {
143				case 1:
144					ioctl->value = isa->read_io_8(ioctl->port);
145				break;
146				case 2:
147	   				ioctl->value = isa->read_io_16(ioctl->port);
148				break;
149				case 4:
150	   				ioctl->value = isa->read_io_32(ioctl->port);
151				break;
152				default:
153					result = B_BAD_VALUE;
154			}
155
156			return result;
157   		}
158
159		case POKE_PORT_WRITE:
160		{
161    		status_t result;
162			port_io_args* ioctl = (port_io_args*)arg;
163			if (ioctl->signature != POKE_SIGNATURE)
164				return B_BAD_VALUE;
165
166			result = B_OK;
167			switch (ioctl->size) {
168				case 1:
169					isa->write_io_8(ioctl->port, ioctl->value);
170					break;
171				case 2:
172					isa->write_io_16(ioctl->port, ioctl->value);
173					break;
174				case 4:
175					isa->write_io_32(ioctl->port, ioctl->value);
176					break;
177				default:
178					result = B_BAD_VALUE;
179			}
180
181			return result;
182   		}
183
184		case POKE_PORT_INDEXED_READ:
185		{
186			port_io_args* ioctl = (port_io_args*)arg;
187			if (ioctl->signature != POKE_SIGNATURE)
188				return B_BAD_VALUE;
189
190			isa->write_io_8(ioctl->port, ioctl->size);
191			ioctl->value = isa->read_io_8(ioctl->port + 1);
192			return B_OK;
193		}
194
195		case POKE_PORT_INDEXED_WRITE:
196		{
197			port_io_args* ioctl = (port_io_args*)arg;
198			if (ioctl->signature != POKE_SIGNATURE)
199				return B_BAD_VALUE;
200
201			isa->write_io_8(ioctl->port, ioctl->size);
202			isa->write_io_8(ioctl->port + 1, ioctl->value);
203			return B_OK;
204		}
205
206		case POKE_PCI_READ_CONFIG:
207		{
208			pci_io_args* ioctl = (pci_io_args*)arg;
209			if (ioctl->signature != POKE_SIGNATURE)
210				return B_BAD_VALUE;
211
212			ioctl->value = pci->read_pci_config(ioctl->bus, ioctl->device,
213				ioctl->function, ioctl->offset, ioctl->size);
214			return B_OK;
215		}
216
217		case POKE_PCI_WRITE_CONFIG:
218		{
219			pci_io_args* ioctl = (pci_io_args*)arg;
220			if (ioctl->signature != POKE_SIGNATURE)
221				return B_BAD_VALUE;
222
223			pci->write_pci_config(ioctl->bus, ioctl->device, ioctl->function,
224				ioctl->offset, ioctl->size, ioctl->value);
225			return B_OK;
226		}
227
228		case POKE_GET_NTH_PCI_INFO:
229		{
230		    pci_info_args* ioctl = (pci_info_args*)arg;
231			if (ioctl->signature != POKE_SIGNATURE)
232				return B_BAD_VALUE;
233
234			ioctl->status = pci->get_nth_pci_info(ioctl->index, ioctl->info);
235			return B_OK;
236		}
237
238		case POKE_GET_PHYSICAL_ADDRESS:
239		{
240			mem_map_args* ioctl = (mem_map_args*)arg;
241			physical_entry table;
242			status_t result;
243
244			if (ioctl->signature != POKE_SIGNATURE)
245				return B_BAD_VALUE;
246
247			result = get_memory_map(ioctl->address, ioctl->size, &table, 1);
248			ioctl->physical_address = (void*)(addr_t)table.address;
249				// TODO: mem_map_args::physical_address should be phys_addr_t!
250			ioctl->size = table.size;
251			return result;
252		}
253
254		case POKE_MAP_MEMORY:
255		{
256			mem_map_args* ioctl = (mem_map_args*)arg;
257			if (ioctl->signature != POKE_SIGNATURE)
258				return B_BAD_VALUE;
259
260			ioctl->area = map_physical_memory(ioctl->name,
261				(addr_t)ioctl->physical_address, ioctl->size, ioctl->flags,
262				ioctl->protection, (void**)&ioctl->address);
263			return ioctl->area;
264		}
265
266		case POKE_UNMAP_MEMORY:
267		{
268			mem_map_args* ioctl = (mem_map_args*)arg;
269			if (ioctl->signature != POKE_SIGNATURE)
270				return B_BAD_VALUE;
271
272			return delete_area(ioctl->area);
273		}
274	}
275
276	return B_BAD_VALUE;
277}
278
279
280status_t
281poke_read(void* cookie, off_t position, void* buffer, size_t* numBytes)
282{
283	*numBytes = 0;
284	return B_NOT_ALLOWED;
285}
286
287
288status_t
289poke_write(void* cookie, off_t position, const void* buffer, size_t* numBytes)
290{
291	*numBytes = 0;
292	return B_NOT_ALLOWED;
293}
294