From 244a4d1fa347dfe4c8247cea76393219eb79a8e0 Mon Sep 17 00:00:00 2001 From: Hugo Santos Date: Sat, 5 May 2007 03:40:07 +0000 Subject: [PATCH] freebsd compat. layer: we now init the several sub-parts through init_hardware, as well as allocate the available device_ts. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21029 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../compat/freebsd_network/busdma_machdep.c | 20 ++- src/libs/compat/freebsd_network/compat.c | 8 +- src/libs/compat/freebsd_network/device.c | 134 ++++++++++++++++-- src/libs/compat/freebsd_network/device.h | 14 +- src/libs/compat/freebsd_network/mbuf.c | 6 +- src/libs/compat/freebsd_network/mutex.c | 11 +- 6 files changed, 162 insertions(+), 31 deletions(-) diff --git a/src/libs/compat/freebsd_network/busdma_machdep.c b/src/libs/compat/freebsd_network/busdma_machdep.c index 005ead67ca..bc1e08b752 100644 --- a/src/libs/compat/freebsd_network/busdma_machdep.c +++ b/src/libs/compat/freebsd_network/busdma_machdep.c @@ -53,6 +53,8 @@ __FBSDID("$FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.74.2.4 2006/10/21 16: #define contigfree(a, b, c) kernel_contigfree(a, b, c) #define __unused void busdma_swi(void); +void init_bounce_pages(void); +void uninit_bounce_pages(void); /* */ struct bounce_zone; @@ -130,7 +132,6 @@ static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist; static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist; static struct bus_dmamap nobounce_dmamap; -static void init_bounce_pages(void *dummy); static int alloc_bounce_zone(bus_dma_tag_t dmat); static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages); static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map, @@ -936,8 +937,9 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) } } -static void -init_bounce_pages(void *dummy __unused) + +void +init_bounce_pages() { total_bpages = 0; @@ -946,7 +948,17 @@ init_bounce_pages(void *dummy __unused) STAILQ_INIT(&bounce_map_callbacklist); mtx_init(&bounce_lock, "bounce pages lock", NULL, MTX_DEF); } -SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL); + + +/* Haiku extension */ +void +uninit_bounce_pages() +{ + /* XXX deep free */ + + mtx_destroy(&bounce_lock); +} + static struct sysctl_ctx_list * busdma_sysctl_tree(struct bounce_zone *bz) diff --git a/src/libs/compat/freebsd_network/compat.c b/src/libs/compat/freebsd_network/compat.c index ec99196a1e..0781ff00b9 100644 --- a/src/libs/compat/freebsd_network/compat.c +++ b/src/libs/compat/freebsd_network/compat.c @@ -28,16 +28,16 @@ pci_module_info *gPci; uint32_t pci_read_config(device_t dev, int offset, int size) { - return gPci->read_pci_config(dev->pciInfo.bus, dev->pciInfo.device, - dev->pciInfo.function, offset, size); + return gPci->read_pci_config(dev->pci_info.bus, dev->pci_info.device, + dev->pci_info.function, offset, size); } void pci_write_config(device_t dev, int offset, uint32_t value, int size) { - gPci->write_pci_config(dev->pciInfo.bus, dev->pciInfo.device, - dev->pciInfo.function, offset, size, value); + gPci->write_pci_config(dev->pci_info.bus, dev->pci_info.device, + dev->pci_info.function, offset, size, value); } diff --git a/src/libs/compat/freebsd_network/device.c b/src/libs/compat/freebsd_network/device.c index b1dfccd03e..43ff2f50f5 100644 --- a/src/libs/compat/freebsd_network/device.c +++ b/src/libs/compat/freebsd_network/device.c @@ -23,12 +23,45 @@ #define MAX_DEVICES 8 +device_t gDevices[MAX_DEVICES]; char *gDevNameList[MAX_DEVICES + 1]; +static device_t +allocate_device() +{ + char semName[64]; + + device_t dev = (device_t)malloc(sizeof(struct device)); + if (dev == NULL) + return NULL; + + memset(dev, 0, sizeof(struct device)); + + snprintf(semName, sizeof(semName), "%s rcv", gDriverName); + + dev->receive_sem = create_sem(0, semName); + if (dev->receive_sem < 0) { + free(dev); + return NULL; + } + + return dev; +} + + +static void +free_device(device_t dev) +{ + delete_sem(dev->receive_sem); + free(dev); +} + + static status_t compat_open(const char *name, uint32 flags, void **cookie) { + dprintf("%s, compat_open(%s, 0x%lx)\n", gDriverName, name, flags); return B_ERROR; } @@ -37,6 +70,9 @@ static status_t compat_close(void *cookie) { device_t dev = cookie; + + dprintf("%s, compat_close(%p)\n", gDriverName, dev); + return B_ERROR; } @@ -45,7 +81,10 @@ static status_t compat_free(void *cookie) { device_t dev = cookie; - free(dev); + + dprintf("%s, compat_free(%p)\n", gDriverName, dev); + + free_device(dev); return B_ERROR; } @@ -106,7 +145,7 @@ compat_write(void *cookie, off_t position, const void *buffer, if (mb == NULL) return ENOBUFS; - /* if we are waiting, check after if the ifp is still valid */ + /* if we waited, check after if the ifp is still valid */ mb->m_len = min_c(*numBytes, (size_t)MCLBYTES); memcpy(mtod(mb, void *), buffer, mb->m_len); @@ -171,11 +210,26 @@ device_hooks gDeviceHooks = { }; +static device_method_signature_t +_resolve_method(driver_t *driver, const char *name) +{ + device_method_signature_t method = NULL; + int i; + + for (i = 0; method == NULL && driver->methods[i].name != NULL; i++) { + if (strcmp(driver->methods[i].name, name) == 0) + method = driver->methods[i].method; + } + + return method; +} + + status_t _fbsd_init_hardware(driver_t *driver) { - device_method_signature_t probe = NULL; struct device fakeDevice; + device_probe_t *probe; int i; dprintf("%s: init_hardware(%p)\n", gDriverName, driver); @@ -183,11 +237,7 @@ _fbsd_init_hardware(driver_t *driver) if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPci) < B_OK) return B_ERROR; - for (i = 0; probe == NULL && driver->methods[i].name != NULL; i++) { - if (strcmp(driver->methods[i].name, "device_probe") == 0) - probe = driver->methods[i].method; - } - + probe = (device_probe_t *)_resolve_method(driver, "device_probe"); if (probe == NULL) { dprintf("%s: driver has no device_probe method.\n", gDriverName); return B_ERROR; @@ -195,9 +245,9 @@ _fbsd_init_hardware(driver_t *driver) memset(&fakeDevice, 0, sizeof(struct device)); - for (i = 0; gPci->get_nth_pci_info(i, &fakeDevice.pciInfo) == B_OK; i++) { + for (i = 0; gPci->get_nth_pci_info(i, &fakeDevice.pci_info) == B_OK; i++) { if (probe(&fakeDevice) >= 0) { - dprintf("%s, found %s at %i\n", gDriverName, + dprintf("%s, found %s at %d\n", gDriverName, fakeDevice.description, i); put_module(B_PCI_MODULE_NAME); return B_OK; @@ -214,14 +264,76 @@ _fbsd_init_hardware(driver_t *driver) status_t _fbsd_init_driver(driver_t *driver) { + device_probe_t *probe; + int i, ncards = 0; + status_t status; + device_t dev; + dprintf("%s: init_driver(%p)\n", gDriverName, driver); - return B_ERROR; + probe = (device_probe_t *)_resolve_method(driver, "device_probe"); + + dev = allocate_device(); + if (dev == NULL) + return B_NO_MEMORY; + + status = init_mutexes(); + if (status < B_OK) { + free_device(dev); + return status; + } + + status = init_mbufs(); + if (status < B_OK) { + uninit_mutexes(); + free_device(dev); + return status; + } + + init_bounce_pages(); + + for (i = 0; dev != NULL + && gPci->get_nth_pci_info(i, &dev->pci_info) == B_OK; i++) { + if (probe(dev) >= 0) { + snprintf(dev->dev_name, sizeof(dev->dev_name), "/dev/net/%s/%i", + gDriverName, ncards); + dprintf("%s, adding %s @%d -> %s\n", gDriverName, dev->description, + i, dev->dev_name); + + gDevices[ncards] = dev; + gDevNameList[ncards] = dev->dev_name; + + ncards++; + if (ncards < MAX_DEVICES) + dev = allocate_device(); + else + dev = NULL; + } + } + + if (dev != NULL) + free_device(dev); + + dprintf("%s, ... %d cards.\n", gDriverName, ncards); + + gDevNameList[ncards + 1] = NULL; + + return B_OK; } void _fbsd_uninit_driver(driver_t *driver) { + int i; + dprintf("%s: uninit_driver(%p)\n", gDriverName, driver); + + for (i = 0; gDevNameList[i] != NULL; i++) { + free_device(gDevices[i]); + } + + uninit_bounce_pages(); + uninit_mbufs(); + uninit_mutexes(); } diff --git a/src/libs/compat/freebsd_network/device.h b/src/libs/compat/freebsd_network/device.h index 2580270ecd..7c871ea44f 100644 --- a/src/libs/compat/freebsd_network/device.h +++ b/src/libs/compat/freebsd_network/device.h @@ -24,8 +24,8 @@ struct ifnet; struct device { - int devId; - pci_info pciInfo; + pci_info pci_info; + char dev_name[128]; int32 flags; @@ -47,6 +47,16 @@ enum { }; +status_t init_mbufs(void); +void uninit_mbufs(void); + +status_t init_mutexes(void); +void uninit_mutexes(void); + +/* busdma_machdep.c */ +void init_bounce_pages(void); +void uninit_bounce_pages(void); + extern struct net_stack_module_info *gStack; extern pci_module_info *gPci; diff --git a/src/libs/compat/freebsd_network/mbuf.c b/src/libs/compat/freebsd_network/mbuf.c index 6f06396766..be933eec47 100644 --- a/src/libs/compat/freebsd_network/mbuf.c +++ b/src/libs/compat/freebsd_network/mbuf.c @@ -10,6 +10,8 @@ * `m_defrag' and friends are straight from FreeBSD 6.2. */ +#include "device.h" + #include #include #include @@ -22,10 +24,6 @@ #define MBTOM(how) (how) -status_t init_mbufs(void); -void uninit_mbufs(void); - - #define CHUNK_SIZE 2048 static object_cache *sMBufCache; diff --git a/src/libs/compat/freebsd_network/mutex.c b/src/libs/compat/freebsd_network/mutex.c index 300d961016..e27c4362cd 100644 --- a/src/libs/compat/freebsd_network/mutex.c +++ b/src/libs/compat/freebsd_network/mutex.c @@ -6,15 +6,11 @@ * Hugo Santos, hugosantos@gmail.com */ -#include +#include "device.h" #include -status_t init_mutexes(void); -void uninit_mutexes(void); - - // these methods are bit unfriendly, a bit too much panic() around struct mtx Giant; @@ -51,12 +47,15 @@ mtx_destroy(struct mtx *m) status_t init_mutexes() { - return B_ERROR; + mtx_init(&Giant, "Banana Giant", NULL, MTX_DEF); + + return B_OK; } void uninit_mutexes() { + mtx_destroy(&Giant); }