diff --git a/src/libs/compat/freebsd_network/bus.c b/src/libs/compat/freebsd_network/bus.c index 00d6942049..311a0ef4f4 100644 --- a/src/libs/compat/freebsd_network/bus.c +++ b/src/libs/compat/freebsd_network/bus.c @@ -344,8 +344,9 @@ bus_generic_resume(device_t dev) value = fun(handle + offset); \ else \ value = *(volatile type *)(handle + offset); \ - TRACE_BUS_SPACE_RW(("bus_space_read_%s(0x%lx, 0x%lx, 0x%lx) = 0x%lx\n", \ - #size, (uint32)tag, (uint32)handle, (uint32)offset, (uint32)value)); \ + if (tag == I386_BUS_SPACE_IO) \ + TRACE_BUS_SPACE_RW(("bus_space_read_%s(0x%lx, 0x%lx, 0x%lx) = 0x%lx\n", \ + #size, (uint32)tag, (uint32)handle, (uint32)offset, (uint32)value)); \ return value; \ } @@ -353,8 +354,9 @@ bus_generic_resume(device_t dev) void bus_space_write_##size(bus_space_tag_t tag, \ bus_space_handle_t handle, bus_size_t offset, type value) \ { \ - TRACE_BUS_SPACE_RW(("bus_space_write_%s(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", \ - #size, (uint32)tag, (uint32)handle, (uint32)offset, (uint32)value)); \ + if (tag == I386_BUS_SPACE_IO) \ + TRACE_BUS_SPACE_RW(("bus_space_write_%s(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", \ + #size, (uint32)tag, (uint32)handle, (uint32)offset, (uint32)value)); \ if (tag == I386_BUS_SPACE_IO) \ fun(value, handle + offset); \ else \ diff --git a/src/libs/compat/freebsd_network/compat.c b/src/libs/compat/freebsd_network/compat.c index af2ed1ef7d..a14f09ca98 100644 --- a/src/libs/compat/freebsd_network/compat.c +++ b/src/libs/compat/freebsd_network/compat.c @@ -340,9 +340,3 @@ init_compat_layer() __haiku_intr_spinlock = 0; return B_OK; } - -module_dependency module_dependencies[] = { - {NET_STACK_MODULE_NAME, (module_info **)&gStack}, - {B_PCI_MODULE_NAME, (module_info **)&gPci}, - {} -}; diff --git a/src/libs/compat/freebsd_network/device.c b/src/libs/compat/freebsd_network/device.c index 73079960c1..037691ae5d 100644 --- a/src/libs/compat/freebsd_network/device.c +++ b/src/libs/compat/freebsd_network/device.c @@ -48,7 +48,7 @@ allocate_device(driver_t *driver) snprintf(semName, sizeof(semName), "%s rcv", gDriverName); - dev->softc = malloc(driver->softc_size); + dev->softc = _kernel_malloc(driver->softc_size, M_ZERO); if (dev->softc == NULL) { free(dev); return NULL; @@ -105,6 +105,10 @@ compat_open(const char *name, uint32 flags, void **cookie) driver_printf("compat_open(%s, 0x%lx)\n", name, flags); + status = get_module(NET_STACK_MODULE_NAME, (module_info **)&gStack); + if (status < B_OK) + return status; + for (i = 0; gDevNameList[i] != NULL; i++) { if (strcmp(gDevNameList[i], name) == 0) break; @@ -151,7 +155,7 @@ compat_close(void *cookie) device_t dev = cookie; device_printf(dev, "compat_close()\n"); - + UNIMPLEMENTED(); return B_ERROR; } @@ -163,7 +167,9 @@ compat_free(void *cookie) device_printf(dev, "compat_free()\n"); + put_module(NET_STACK_MODULE_NAME); free_device(dev); + UNIMPLEMENTED(); return B_ERROR; } @@ -290,6 +296,7 @@ compat_control(void *cookie, uint32 op, void *arg, size_t len) case ETHER_ADDMULTI: case ETHER_REMMULTI: /* TODO */ + UNIMPLEMENTED(); return B_ERROR; case ETHER_GET_LINK_STATE: @@ -360,16 +367,16 @@ _fbsd_init_hardware(driver_t *driver) return B_ERROR; } + memset(&fakeDevice, 0, sizeof(struct device)); for (i = 0; gPci->get_nth_pci_info(i, &fakeDevice.pci_info) == B_OK; i++) { int result; - memset(&fakeDevice, 0, sizeof(struct device)); result = probe(&fakeDevice); - if (fakeDevice.flags & DEVICE_DESC_ALLOCED) - free((char *)fakeDevice.description); if (result >= 0) { dprintf("%s, found %s at %d\n", gDriverName, fakeDevice.description, i); + if (fakeDevice.flags & DEVICE_DESC_ALLOCED) + free((char *)fakeDevice.description); put_module(B_PCI_MODULE_NAME); return B_OK; } @@ -391,31 +398,37 @@ _fbsd_init_driver(driver_t *driver) dprintf("%s: init_driver(%p)\n", gDriverName, driver); + status = get_module(B_PCI_MODULE_NAME, (module_info **)&gPci); + if (status < B_OK) { + driver_printf("Failed to load PCI module.\n"); + return status; + } + 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(driver); if (dev == NULL) - return B_NO_MEMORY; + goto err_1; status = init_compat_layer(); if (status < B_OK) - goto err_1; + goto err_2; status = init_mutexes(); if (status < B_OK) - goto err_2; + goto err_3; if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES)) { status = init_taskqueues(); if (status < B_OK) - goto err_3; + goto err_4; } status = init_mbufs(); if (status < B_OK) - goto err_4; + goto err_5; init_bounce_pages(); @@ -447,14 +460,17 @@ _fbsd_init_driver(driver_t *driver) return B_OK; -err_4: +err_5: if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES)) uninit_taskqueues(); -err_3: +err_4: uninit_mutexes(); +err_3: err_2: -err_1: free(dev); +err_1: +err_0: + put_module(B_PCI_MODULE_NAME); return status; } @@ -475,4 +491,6 @@ _fbsd_uninit_driver(driver_t *driver) if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES)) uninit_taskqueues(); uninit_mutexes(); + + put_module(B_PCI_MODULE_NAME); } diff --git a/src/libs/compat/freebsd_network/taskqueue.c b/src/libs/compat/freebsd_network/taskqueue.c index c725ad2425..1c6583bea8 100644 --- a/src/libs/compat/freebsd_network/taskqueue.c +++ b/src/libs/compat/freebsd_network/taskqueue.c @@ -13,6 +13,8 @@ #include #include +#define MAX_TASKQUEUE_THREADS 2 + struct taskqueue { char tq_name[64]; mutex tq_mutex; @@ -22,7 +24,7 @@ struct taskqueue { int tq_fast; int32 tq_spinlock; sem_id tq_sem; - thread_id *tq_threads; + thread_id tq_threads[MAX_TASKQUEUE_THREADS]; int tq_threadcount; }; @@ -40,10 +42,17 @@ _taskqueue_create(const char *name, int mflags, int fast, tq->tq_fast = fast; + tq->tq_sem = create_sem(0, tq->tq_name); + if (tq->tq_sem < B_OK) { + free(tq); + return tq->tq_sem; + } + if (fast) { tq->tq_spinlock = 0; } else { if (mutex_init(&tq->tq_mutex, name) < B_OK) { + delete_sem(tq->tq_sem); free(tq); return NULL; } @@ -54,8 +63,6 @@ _taskqueue_create(const char *name, int mflags, int fast, tq->tq_enqueue = enqueue; tq->tq_arg = context; - tq->tq_sem = -1; - tq->tq_threads = NULL; tq->tq_threadcount = 0; return tq; @@ -101,15 +108,9 @@ tq_handle_thread(void *data) cpu_status cpu_state; struct task *t; int pending; - sem_id sem; - - /* just a synchronization point */ - tq_lock(tq, &cpu_state); - sem = tq->tq_sem; - tq_unlock(tq, cpu_state); while (1) { - status_t status = acquire_sem(sem); + status_t status = acquire_sem(tq->tq_sem); if (status < B_OK) break; @@ -126,43 +127,18 @@ tq_handle_thread(void *data) } -int -taskqueue_start_threads(struct taskqueue **tqp, int count, int prio, - const char *format, ...) +static int +_taskqueue_start_threads(struct taskqueue **tqp, int count, int prio, + const char *name) { struct taskqueue *tq = (*tqp); - cpu_status state; - char name[64]; - va_list vl; int i, j; if (count == 0) return -1; - tq_lock(tq, &state); - - if (tq->tq_threads != NULL) { - tq_unlock(tq, state); - return -1; - } - - va_start(vl, format); - vsnprintf(name, sizeof(name), format, vl); - va_end(vl); - - tq->tq_threads = malloc(sizeof(thread_id) * count); - if (tq->tq_threads == NULL) { - tq_unlock(tq, state); - return B_NO_MEMORY; - } - - tq->tq_sem = create_sem(0, tq->tq_name); - if (tq->tq_sem < B_OK) { - free(tq->tq_threads); - tq->tq_threads = NULL; - tq_unlock(tq, state); - return tq->tq_sem; - } + if (count > MAX_TASKQUEUE_THREADS) + panic("_taskqueue_start_threads, too many threads requested"); for (i = 0; i < count; i++) { tq->tq_threads[i] = spawn_kernel_thread(tq_handle_thread, tq->tq_name, @@ -171,10 +147,6 @@ taskqueue_start_threads(struct taskqueue **tqp, int count, int prio, status_t status = tq->tq_threads[i]; for (j = 0; j < i; j++) kill_thread(tq->tq_threads[j]); - free(tq->tq_threads); - tq->tq_threads = NULL; - delete_sem(tq->tq_sem); - tq_unlock(tq, state); return status; } } @@ -184,11 +156,36 @@ taskqueue_start_threads(struct taskqueue **tqp, int count, int prio, for (i = 0; i < count; i++) resume_thread(tq->tq_threads[i]); - tq_unlock(tq, state); return 0; } +int +taskqueue_start_threads(struct taskqueue **tqp, int count, int prio, + const char *format, ...) +{ + /* we assume that start_threads is called in a sane place, and + * thus don't lock. This is mostly due to the fact that if the + * TQ is 'fast', locking it disables interrupts... and then we + * can't create semaphores, threads and bananas. */ + + /* cpu_status state; */ + char name[64]; + int result; + va_list vl; + + va_start(vl, format); + vsnprintf(name, sizeof(name), format, vl); + va_end(vl); + + /*tq_lock(*tqp, &state);*/ + result = _taskqueue_start_threads(tqp, count, prio, name); + /*tq_unlock(*tqp, state);*/ + + return result; +} + + void taskqueue_free(struct taskqueue *tq) {