From 0490692add2c4fd629739feaff601d87c8b309d6 Mon Sep 17 00:00:00 2001 From: Hugo Santos Date: Thu, 3 May 2007 01:18:30 +0000 Subject: [PATCH] freebsd compat. layer: resource allocation and interrupt setup git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20989 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/libs/compat/freebsd_network/Jamfile | 1 + src/libs/compat/freebsd_network/bus.c | 124 ++++++++++++++++++ .../compat/freebsd_network/compat/sys/bus.h | 2 +- 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/libs/compat/freebsd_network/bus.c diff --git a/src/libs/compat/freebsd_network/Jamfile b/src/libs/compat/freebsd_network/Jamfile index 7629f56505..0693c52063 100644 --- a/src/libs/compat/freebsd_network/Jamfile +++ b/src/libs/compat/freebsd_network/Jamfile @@ -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 diff --git a/src/libs/compat/freebsd_network/bus.c b/src/libs/compat/freebsd_network/bus.c new file mode 100644 index 0000000000..8d9100b1fc --- /dev/null +++ b/src/libs/compat/freebsd_network/bus.c @@ -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 + +#include + +#include +#include +#include + + +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; +} + diff --git a/src/libs/compat/freebsd_network/compat/sys/bus.h b/src/libs/compat/freebsd_network/compat/sys/bus.h index 82896fd192..4cfb1e280d 100644 --- a/src/libs/compat/freebsd_network/compat/sys/bus.h +++ b/src/libs/compat/freebsd_network/compat/sys/bus.h @@ -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;