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