freebsd compat. layer: resource allocation and interrupt setup

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20989 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos 2007-05-03 01:18:30 +00:00
parent 771c6b9355
commit 0490692add
3 changed files with 126 additions and 1 deletions

View File

@ -8,6 +8,7 @@ UseHeaders [ FDirName $(SUBDIR) compat ] : true ;
SubDirCcFlags [ FDefines _KERNEL=1 ] ;
Library libfreebsd_network.a :
bus.c
compat.c
device.c
mbuf.c

View File

@ -0,0 +1,124 @@
/*
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Hugo Santos, hugosantos@gmail.com
*
* Some of this code is based on previous work by Marcus Overhagen.
*/
#include <malloc.h>
#include <drivers/PCI.h>
#include <compat/dev/pci/pcivar.h>
#include <compat/machine/resource.h>
#include <compat/sys/bus.h>
struct internal_intr {
driver_intr_t handler;
void *arg;
int irq;
};
/* straight from Marcus' ipro1000 driver */
struct resource *
bus_alloc_resource(device_t dev, int type, int *rid, unsigned long start,
unsigned long end, unsigned long count, uint32 flags)
{
switch (type) {
case SYS_RES_IRQ:
{
uint8 res = pci_read_config(dev, PCI_interrupt_line, 1);
if (res == 0 || res == 0xff)
return NULL;
return (struct resource *)(int)res;
}
case SYS_RES_MEMORY:
{
uint32 res = pci_read_config(dev, *rid, 4)
& PCI_address_memory_32_mask;
uint32 size = 128 * 1024; // TODO get size from BAR
void *virtualAddr;
if (map_mem(&virtualAddr, (void *)res, size, 0, "bus_alloc_resource(MEMORY)") < 0)
return NULL;
return (struct resource *)virtualAddr;
}
case SYS_RES_IOPORT:
return (struct resource *)(pci_read_config(dev, *rid, 4)
& PCI_address_io_mask);
default:
return NULL;
}
}
int
bus_release_resource(device_t dev, int type, int rid, struct resource *res)
{
switch (type) {
case SYS_RES_IRQ:
case SYS_RES_IOPORT:
return 0;
case SYS_RES_MEMORY:
delete_area(area_for(res));
return 0;
default:
return B_ERROR;
}
}
static int32
intr_wrapper(void *data)
{
struct internal_intr *intr = data;
intr->handler(intr->arg);
return 0;
}
int
bus_setup_intr(device_t dev, struct resource *res, int flags,
driver_intr_t handler, void *arg, void **cookiep)
{
struct internal_intr *intr = (struct internal_intr *)malloc(
sizeof(struct internal_intr));
status_t status;
if (intr == NULL)
return B_NO_MEMORY;
intr->handler = handler;
intr->arg = arg;
intr->irq = (int)res;
status = install_io_interrupt_handler(intr->irq, intr_wrapper, intr, 0);
if (status < B_OK) {
free(intr);
return status;
}
*cookiep = intr;
return status;
}
int
bus_teardown_intr(device_t dev, struct resource *res, void *arg)
{
struct internal_intr *intr = arg;
remove_io_interrupt_handler(intr->irq, intr_wrapper, intr);
free(intr);
return 0;
}

View File

@ -111,7 +111,7 @@ enum intr_type {
int bus_generic_detach(device_t dev);
typedef void driver_intr_t(void *);
typedef void (*driver_intr_t)(void *);
struct resource;