From ddcaaa6129d2c66d69c4bd3d0c238ce813ed62d7 Mon Sep 17 00:00:00 2001 From: Hugo Santos Date: Sat, 5 May 2007 04:45:01 +0000 Subject: [PATCH] freebsd compat. layer: added open(), which calls into the driver's attach. when testing with PCNET, a interface is already presented to the stack, it is even able to obtain the MAC address from the device, but still more work to do. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21030 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/libs/compat/freebsd_network/bus.c | 4 +- src/libs/compat/freebsd_network/compat.c | 7 +- .../freebsd_network/compat/net/if_var.h | 3 + .../freebsd_network/compat/sys/haiku-module.h | 2 +- src/libs/compat/freebsd_network/device.c | 86 +++++++++++++------ src/libs/compat/freebsd_network/device.h | 8 +- src/libs/compat/freebsd_network/if.c | 21 ++++- 7 files changed, 95 insertions(+), 36 deletions(-) diff --git a/src/libs/compat/freebsd_network/bus.c b/src/libs/compat/freebsd_network/bus.c index 70b8d67dd0..24f0f111a6 100644 --- a/src/libs/compat/freebsd_network/bus.c +++ b/src/libs/compat/freebsd_network/bus.c @@ -183,7 +183,7 @@ bus_setup_intr(device_t dev, struct resource *res, int flags, intr->handler = handler; intr->arg = arg; - intr->irq = (int)res; + intr->irq = res->handle; status = install_io_interrupt_handler(intr->irq, intr_wrapper, intr, 0); if (status < B_OK) { @@ -193,7 +193,7 @@ bus_setup_intr(device_t dev, struct resource *res, int flags, *cookiep = intr; - return status; + return 0; } diff --git a/src/libs/compat/freebsd_network/compat.c b/src/libs/compat/freebsd_network/compat.c index 0781ff00b9..d9da749deb 100644 --- a/src/libs/compat/freebsd_network/compat.c +++ b/src/libs/compat/freebsd_network/compat.c @@ -96,7 +96,6 @@ int pci_enable_io(device_t dev, int space) { /* adapted from FreeBSD's pci_enable_io_method */ - uint16_t command; int bit = 0; switch (space) { @@ -144,10 +143,8 @@ device_set_desc(device_t dev, const char *desc) const char * device_get_name(device_t dev) { - /* - * if (dev != NULL && dev->devclass) - * return devclass_get_name(dev->devclass); - */ + if (dev) + return dev->dev_name; return NULL; } diff --git a/src/libs/compat/freebsd_network/compat/net/if_var.h b/src/libs/compat/freebsd_network/compat/net/if_var.h index ba7b067fd6..b66e080cef 100644 --- a/src/libs/compat/freebsd_network/compat/net/if_var.h +++ b/src/libs/compat/freebsd_network/compat/net/if_var.h @@ -105,6 +105,8 @@ struct ifqueue { struct mtx ifq_mtx; }; +struct device; + /* * Structure defining a network interface. * @@ -185,6 +187,7 @@ struct ifnet { /* Haiku additions */ struct sockaddr_dl if_lladdr; + struct device *if_dev; }; typedef void if_init_f_t(void *); diff --git a/src/libs/compat/freebsd_network/compat/sys/haiku-module.h b/src/libs/compat/freebsd_network/compat/sys/haiku-module.h index 5de2914227..0d408ec168 100644 --- a/src/libs/compat/freebsd_network/compat/sys/haiku-module.h +++ b/src/libs/compat/freebsd_network/compat/sys/haiku-module.h @@ -33,7 +33,7 @@ typedef struct device_method device_method_t; typedef struct { const char *name; device_method_t *methods; - size_t size; + size_t softc_size; } driver_t; #define BUS_PROBE_LOW_PRIORITY 10 diff --git a/src/libs/compat/freebsd_network/device.c b/src/libs/compat/freebsd_network/device.c index 43ff2f50f5..1636798ca1 100644 --- a/src/libs/compat/freebsd_network/device.c +++ b/src/libs/compat/freebsd_network/device.c @@ -27,8 +27,13 @@ device_t gDevices[MAX_DEVICES]; char *gDevNameList[MAX_DEVICES + 1]; +static device_probe_t *sDeviceProbe; +static device_attach_t *sDeviceAttach; +static device_detach_t *sDeviceDetach; + + static device_t -allocate_device() +allocate_device(driver_t *driver) { char semName[64]; @@ -40,8 +45,15 @@ allocate_device() snprintf(semName, sizeof(semName), "%s rcv", gDriverName); + dev->softc = malloc(driver->softc_size); + if (dev->softc == NULL) { + free(dev); + return NULL; + } + dev->receive_sem = create_sem(0, semName); if (dev->receive_sem < 0) { + free(dev->softc); free(dev); return NULL; } @@ -54,15 +66,55 @@ static void free_device(device_t dev) { delete_sem(dev->receive_sem); + free(dev->softc); free(dev); } +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; +} + + static status_t compat_open(const char *name, uint32 flags, void **cookie) { + status_t status; + device_t dev; + int i; + dprintf("%s, compat_open(%s, 0x%lx)\n", gDriverName, name, flags); - return B_ERROR; + + for (i = 0; gDevNameList[i] != NULL; i++) { + if (strcmp(gDevNameList[i], name) == 0) + break; + } + + if (gDevNameList[i] == NULL) + return B_ERROR; + + dev = gDevices[i]; + + if (atomic_or(&dev->flags, DEVICE_OPEN) & DEVICE_OPEN) + return B_BUSY; + + status = sDeviceAttach(dev); + if (status != 0) + dev->flags = 0; + + *cookie = dev; + + return status; } @@ -210,21 +262,6 @@ 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) { @@ -264,16 +301,17 @@ _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); - probe = (device_probe_t *)_resolve_method(driver, "device_probe"); + sDeviceProbe = (device_probe_t *)_resolve_method(driver, "device_probe"); + sDeviceAttach = (device_attach_t *)_resolve_method(driver, "device_attach"); + sDeviceDetach = (device_detach_t *)_resolve_method(driver, "device_detach"); - dev = allocate_device(); + dev = allocate_device(driver); if (dev == NULL) return B_NO_MEMORY; @@ -294,10 +332,10 @@ _fbsd_init_driver(driver_t *driver) 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", + if (sDeviceProbe(dev) >= 0) { + snprintf(dev->dev_name, sizeof(dev->dev_name), "net/%s/%i", gDriverName, ncards); - dprintf("%s, adding %s @%d -> %s\n", gDriverName, dev->description, + dprintf("%s, adding %s @%d -> /dev/%s\n", gDriverName, dev->description, i, dev->dev_name); gDevices[ncards] = dev; @@ -305,7 +343,7 @@ _fbsd_init_driver(driver_t *driver) ncards++; if (ncards < MAX_DEVICES) - dev = allocate_device(); + dev = allocate_device(driver); else dev = NULL; } diff --git a/src/libs/compat/freebsd_network/device.h b/src/libs/compat/freebsd_network/device.h index 7c871ea44f..20f4796a3e 100644 --- a/src/libs/compat/freebsd_network/device.h +++ b/src/libs/compat/freebsd_network/device.h @@ -42,8 +42,9 @@ struct device { enum { - DEVICE_CLOSED = 1 << 0, - DEVICE_NON_BLOCK = 1 << 1, + DEVICE_OPEN = 1 << 0, + DEVICE_CLOSED = 1 << 1, + DEVICE_NON_BLOCK = 1 << 2, }; @@ -60,4 +61,7 @@ void uninit_bounce_pages(void); extern struct net_stack_module_info *gStack; extern pci_module_info *gPci; +extern char *gDevNameList[]; +extern struct device *gDevices[]; + #endif diff --git a/src/libs/compat/freebsd_network/if.c b/src/libs/compat/freebsd_network/if.c index 5b1ced2e12..e094d336a5 100644 --- a/src/libs/compat/freebsd_network/if.c +++ b/src/libs/compat/freebsd_network/if.c @@ -47,11 +47,28 @@ if_free(struct ifnet *ifp) void if_initname(struct ifnet *ifp, const char *name, int unit) { + int i; + + dprintf("if_initname(%p, %s, %d)\n", ifp, name, unit); + + if (name == NULL) + panic("interface goes unamed"); + ifp->if_dname = name; ifp->if_dunit = unit; - /* XXX use a more Haiku friendly name here? */ - snprintf(ifp->if_xname, IFNAMSIZ, "%s%d", name, unit); + strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname)); + + for (i = 0; gDevNameList[i] != NULL; i++) { + if (strcmp(gDevNameList[i], name) == 0) + break; + } + + if (gDevNameList[i] == NULL) + panic("unknown interface"); + + ifp->if_dev = gDevices[i]; + ifp->if_dev->ifp = ifp; }