Added poke driver, courtesy of Oscar Lesta. The "poke" command line application will follow.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13187 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
83265d84db
commit
8095208973
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2005, Oscar Lesta. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _POKE_DRIVER_H_
|
||||
#define _POKE_DRIVER_H_
|
||||
|
||||
#include <Drivers.h>
|
||||
#include <ISA.h>
|
||||
#include <PCI.h>
|
||||
|
||||
|
||||
#define POKE_DEVICE_NAME "poke"
|
||||
#define POKE_DEVICE_FULLNAME "/dev/misc/poke"
|
||||
#define POKE_SIGNATURE 'wltp' // "We Like To Poke"
|
||||
|
||||
|
||||
enum {
|
||||
POKE_PORT_READ = B_DEVICE_OP_CODES_END + 1,
|
||||
POKE_PORT_WRITE,
|
||||
POKE_PORT_INDEXED_READ,
|
||||
POKE_PORT_INDEXED_WRITE,
|
||||
POKE_PCI_READ_CONFIG,
|
||||
POKE_PCI_WRITE_CONFIG,
|
||||
POKE_GET_NTH_PCI_INFO,
|
||||
POKE_GET_PHYSICAL_ADDRESS,
|
||||
POKE_MAP_MEMORY,
|
||||
POKE_UNMAP_MEMORY
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32 signature;
|
||||
uint8 index;
|
||||
pci_info* info;
|
||||
status_t status;
|
||||
} pci_info_args;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32 signature;
|
||||
uint16 port;
|
||||
uint8 size; // == index for POKE_PORT_INDEXED_*
|
||||
uint16 value;
|
||||
} port_io_args;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32 signature;
|
||||
uint8 bus;
|
||||
uint8 device;
|
||||
uint8 function;
|
||||
uint8 size;
|
||||
uint8 offset;
|
||||
uint32 value;
|
||||
} pci_io_args;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32 signature;
|
||||
area_id area;
|
||||
const char* name;
|
||||
void* physical_address;
|
||||
size_t size;
|
||||
uint32 flags;
|
||||
uint32 protection;
|
||||
void* address;
|
||||
} mem_map_args;
|
||||
|
||||
#endif // _POKE_DRIVER_H_
|
|
@ -1,7 +1,12 @@
|
|||
SubDir OBOS_TOP src add-ons kernel drivers misc ;
|
||||
|
||||
UsePrivateHeaders drivers ;
|
||||
|
||||
|
||||
KernelAddon <driver>config : kernel drivers dev misc :
|
||||
config.c
|
||||
;
|
||||
|
||||
KernelObjects config.c : -fno-pic ;
|
||||
KernelAddon <driver>poke : kernel drivers dev misc :
|
||||
poke.c
|
||||
;
|
||||
|
|
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
* Copyright 2005, Oscar Lesta. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <Drivers.h>
|
||||
#include <KernelExport.h>
|
||||
#include <ISA.h>
|
||||
#include <PCI.h>
|
||||
|
||||
#include "poke.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static status_t poke_open(const char*, uint32, void**);
|
||||
static status_t poke_close(void*);
|
||||
static status_t poke_free(void*);
|
||||
static status_t poke_control(void*, uint32, void*, size_t);
|
||||
static status_t poke_read(void*, off_t, void*, size_t*);
|
||||
static status_t poke_write(void*, off_t, const void*, size_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const char* poke_name[] = {
|
||||
"misc/"POKE_DEVICE_NAME,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
device_hooks poke_hooks = {
|
||||
poke_open,
|
||||
poke_close,
|
||||
poke_free,
|
||||
poke_control,
|
||||
poke_read,
|
||||
poke_write,
|
||||
};
|
||||
|
||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
|
||||
isa_module_info* isa;
|
||||
pci_module_info* pci;
|
||||
|
||||
static uint32 open_count;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
status_t
|
||||
init_hardware(void)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
init_driver(void)
|
||||
{
|
||||
open_count = 0;
|
||||
|
||||
if (get_module(B_ISA_MODULE_NAME, (module_info**) &isa) < B_OK)
|
||||
return ENOSYS;
|
||||
if (get_module(B_PCI_MODULE_NAME, (module_info**) &pci) < B_OK)
|
||||
return ENOSYS;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uninit_driver(void)
|
||||
{
|
||||
if (isa) put_module(B_ISA_MODULE_NAME);
|
||||
if (pci) put_module(B_PCI_MODULE_NAME);
|
||||
}
|
||||
|
||||
|
||||
const char**
|
||||
publish_devices(void)
|
||||
{
|
||||
return poke_name;
|
||||
}
|
||||
|
||||
|
||||
device_hooks*
|
||||
find_device(const char* name)
|
||||
{
|
||||
return &poke_hooks;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
status_t
|
||||
poke_open(const char* name, uint32 flags, void** cookie)
|
||||
{
|
||||
*cookie = NULL;
|
||||
|
||||
if (atomic_add(&open_count, 1) != 0) {
|
||||
atomic_add(&open_count, -1);
|
||||
return B_BUSY;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
poke_close(void* cookie)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
poke_free(void* cookie)
|
||||
{
|
||||
atomic_add(&open_count, -1);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
poke_control(void* cookie, uint32 op, void* arg, size_t length)
|
||||
{
|
||||
switch (op) {
|
||||
case POKE_PORT_READ:
|
||||
{
|
||||
status_t result;
|
||||
port_io_args* ioctl = (port_io_args*) arg;
|
||||
if (ioctl->signature != POKE_SIGNATURE)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
result = B_OK;
|
||||
switch (ioctl->size) {
|
||||
case 1:
|
||||
ioctl->value = isa->read_io_8(ioctl->port);
|
||||
break;
|
||||
case 2:
|
||||
ioctl->value = isa->read_io_16(ioctl->port);
|
||||
break;
|
||||
case 4:
|
||||
ioctl->value = isa->read_io_32(ioctl->port);
|
||||
break;
|
||||
default:
|
||||
result = B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
case POKE_PORT_WRITE:
|
||||
{
|
||||
status_t result;
|
||||
port_io_args* ioctl = (port_io_args*) arg;
|
||||
if (ioctl->signature != POKE_SIGNATURE)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
result = B_OK;
|
||||
switch (ioctl->size) {
|
||||
case 1:
|
||||
isa->write_io_8(ioctl->port, ioctl->value);
|
||||
break;
|
||||
case 2:
|
||||
isa->write_io_16(ioctl->port, ioctl->value);
|
||||
break;
|
||||
case 4:
|
||||
isa->write_io_16(ioctl->port, ioctl->value);
|
||||
break;
|
||||
default:
|
||||
result = B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
case POKE_PORT_INDEXED_READ:
|
||||
{
|
||||
port_io_args* ioctl = (port_io_args*) arg;
|
||||
if (ioctl->signature != POKE_SIGNATURE)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
isa->write_io_8(ioctl->port, ioctl->size);
|
||||
ioctl->value = isa->read_io_8(ioctl->port + 1);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case POKE_PORT_INDEXED_WRITE:
|
||||
{
|
||||
port_io_args* ioctl = (port_io_args*) arg;
|
||||
if (ioctl->signature != POKE_SIGNATURE)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
isa->write_io_8(ioctl->port, ioctl->size);
|
||||
isa->write_io_8(ioctl->port + 1, ioctl->value);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case POKE_PCI_READ_CONFIG:
|
||||
{
|
||||
pci_io_args* ioctl = (pci_io_args*) arg;
|
||||
if (ioctl->signature != POKE_SIGNATURE)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
ioctl->value = pci->read_pci_config(ioctl->bus, ioctl->device,
|
||||
ioctl->function, ioctl->offset,
|
||||
ioctl->size);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case POKE_PCI_WRITE_CONFIG:
|
||||
{
|
||||
pci_io_args* ioctl = (pci_io_args*) arg;
|
||||
if (ioctl->signature != POKE_SIGNATURE)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
pci->write_pci_config(ioctl->bus, ioctl->device, ioctl->function,
|
||||
ioctl->offset, ioctl->size, ioctl->value);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case POKE_GET_NTH_PCI_INFO:
|
||||
{
|
||||
pci_info_args* ioctl = (pci_info_args*) arg;
|
||||
if (ioctl->signature != POKE_SIGNATURE)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
ioctl->status = pci->get_nth_pci_info(ioctl->index, ioctl->info);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case POKE_GET_PHYSICAL_ADDRESS:
|
||||
{
|
||||
mem_map_args* ioctl = (mem_map_args*) arg;
|
||||
physical_entry table;
|
||||
status_t result;
|
||||
|
||||
if (ioctl->signature != POKE_SIGNATURE)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
result = get_memory_map(ioctl->address, ioctl->size, &table, 1);
|
||||
ioctl->physical_address = table.address;
|
||||
ioctl->size = table.size;
|
||||
return result;
|
||||
}
|
||||
|
||||
case POKE_MAP_MEMORY:
|
||||
{
|
||||
mem_map_args* ioctl = (mem_map_args*) arg;
|
||||
if (ioctl->signature != POKE_SIGNATURE)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
ioctl->area = map_physical_memory(ioctl->name,
|
||||
ioctl->physical_address,
|
||||
ioctl->size,
|
||||
ioctl->flags,
|
||||
ioctl->protection,
|
||||
(void**) &ioctl->address);
|
||||
return ioctl->area;
|
||||
}
|
||||
|
||||
case POKE_UNMAP_MEMORY:
|
||||
{
|
||||
mem_map_args* ioctl = (mem_map_args*) arg;
|
||||
if (ioctl->signature != POKE_SIGNATURE)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return delete_area(ioctl->area);
|
||||
}
|
||||
}
|
||||
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
poke_read(void* cookie, off_t position, void* buffer, size_t* num_bytes)
|
||||
{
|
||||
*num_bytes = 0;
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
poke_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes)
|
||||
{
|
||||
*num_bytes = 0;
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
Loading…
Reference in New Issue