freebsd compat. layer: a couple more changes. a DMA-using driver (FreeBSD's em, Intel Pro 1000) now works without any modifications (it has a fast interrupt mode).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21076 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -344,8 +344,9 @@ bus_generic_resume(device_t dev)
|
|||||||
value = fun(handle + offset); \
|
value = fun(handle + offset); \
|
||||||
else \
|
else \
|
||||||
value = *(volatile type *)(handle + offset); \
|
value = *(volatile type *)(handle + offset); \
|
||||||
TRACE_BUS_SPACE_RW(("bus_space_read_%s(0x%lx, 0x%lx, 0x%lx) = 0x%lx\n", \
|
if (tag == I386_BUS_SPACE_IO) \
|
||||||
#size, (uint32)tag, (uint32)handle, (uint32)offset, (uint32)value)); \
|
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; \
|
return value; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,8 +354,9 @@ bus_generic_resume(device_t dev)
|
|||||||
void bus_space_write_##size(bus_space_tag_t tag, \
|
void bus_space_write_##size(bus_space_tag_t tag, \
|
||||||
bus_space_handle_t handle, bus_size_t offset, type value) \
|
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", \
|
if (tag == I386_BUS_SPACE_IO) \
|
||||||
#size, (uint32)tag, (uint32)handle, (uint32)offset, (uint32)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) \
|
if (tag == I386_BUS_SPACE_IO) \
|
||||||
fun(value, handle + offset); \
|
fun(value, handle + offset); \
|
||||||
else \
|
else \
|
||||||
|
|||||||
@@ -340,9 +340,3 @@ init_compat_layer()
|
|||||||
__haiku_intr_spinlock = 0;
|
__haiku_intr_spinlock = 0;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
module_dependency module_dependencies[] = {
|
|
||||||
{NET_STACK_MODULE_NAME, (module_info **)&gStack},
|
|
||||||
{B_PCI_MODULE_NAME, (module_info **)&gPci},
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ allocate_device(driver_t *driver)
|
|||||||
|
|
||||||
snprintf(semName, sizeof(semName), "%s rcv", gDriverName);
|
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) {
|
if (dev->softc == NULL) {
|
||||||
free(dev);
|
free(dev);
|
||||||
return NULL;
|
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);
|
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++) {
|
for (i = 0; gDevNameList[i] != NULL; i++) {
|
||||||
if (strcmp(gDevNameList[i], name) == 0)
|
if (strcmp(gDevNameList[i], name) == 0)
|
||||||
break;
|
break;
|
||||||
@@ -151,7 +155,7 @@ compat_close(void *cookie)
|
|||||||
device_t dev = cookie;
|
device_t dev = cookie;
|
||||||
|
|
||||||
device_printf(dev, "compat_close()\n");
|
device_printf(dev, "compat_close()\n");
|
||||||
|
UNIMPLEMENTED();
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +167,9 @@ compat_free(void *cookie)
|
|||||||
|
|
||||||
device_printf(dev, "compat_free()\n");
|
device_printf(dev, "compat_free()\n");
|
||||||
|
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
free_device(dev);
|
free_device(dev);
|
||||||
|
UNIMPLEMENTED();
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,6 +296,7 @@ compat_control(void *cookie, uint32 op, void *arg, size_t len)
|
|||||||
case ETHER_ADDMULTI:
|
case ETHER_ADDMULTI:
|
||||||
case ETHER_REMMULTI:
|
case ETHER_REMMULTI:
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
UNIMPLEMENTED();
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
case ETHER_GET_LINK_STATE:
|
case ETHER_GET_LINK_STATE:
|
||||||
@@ -360,16 +367,16 @@ _fbsd_init_hardware(driver_t *driver)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(&fakeDevice, 0, sizeof(struct device));
|
||||||
|
|
||||||
for (i = 0; gPci->get_nth_pci_info(i, &fakeDevice.pci_info) == B_OK; i++) {
|
for (i = 0; gPci->get_nth_pci_info(i, &fakeDevice.pci_info) == B_OK; i++) {
|
||||||
int result;
|
int result;
|
||||||
memset(&fakeDevice, 0, sizeof(struct device));
|
|
||||||
result = probe(&fakeDevice);
|
result = probe(&fakeDevice);
|
||||||
if (fakeDevice.flags & DEVICE_DESC_ALLOCED)
|
|
||||||
free((char *)fakeDevice.description);
|
|
||||||
if (result >= 0) {
|
if (result >= 0) {
|
||||||
dprintf("%s, found %s at %d\n", gDriverName,
|
dprintf("%s, found %s at %d\n", gDriverName,
|
||||||
fakeDevice.description, i);
|
fakeDevice.description, i);
|
||||||
|
if (fakeDevice.flags & DEVICE_DESC_ALLOCED)
|
||||||
|
free((char *)fakeDevice.description);
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_MODULE_NAME);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -391,31 +398,37 @@ _fbsd_init_driver(driver_t *driver)
|
|||||||
|
|
||||||
dprintf("%s: init_driver(%p)\n", gDriverName, 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");
|
sDeviceProbe = (device_probe_t *)_resolve_method(driver, "device_probe");
|
||||||
sDeviceAttach = (device_attach_t *)_resolve_method(driver, "device_attach");
|
sDeviceAttach = (device_attach_t *)_resolve_method(driver, "device_attach");
|
||||||
sDeviceDetach = (device_detach_t *)_resolve_method(driver, "device_detach");
|
sDeviceDetach = (device_detach_t *)_resolve_method(driver, "device_detach");
|
||||||
|
|
||||||
dev = allocate_device(driver);
|
dev = allocate_device(driver);
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
return B_NO_MEMORY;
|
goto err_1;
|
||||||
|
|
||||||
status = init_compat_layer();
|
status = init_compat_layer();
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err_1;
|
goto err_2;
|
||||||
|
|
||||||
status = init_mutexes();
|
status = init_mutexes();
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err_2;
|
goto err_3;
|
||||||
|
|
||||||
if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES)) {
|
if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES)) {
|
||||||
status = init_taskqueues();
|
status = init_taskqueues();
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err_3;
|
goto err_4;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = init_mbufs();
|
status = init_mbufs();
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err_4;
|
goto err_5;
|
||||||
|
|
||||||
init_bounce_pages();
|
init_bounce_pages();
|
||||||
|
|
||||||
@@ -447,14 +460,17 @@ _fbsd_init_driver(driver_t *driver)
|
|||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
err_4:
|
err_5:
|
||||||
if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES))
|
if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES))
|
||||||
uninit_taskqueues();
|
uninit_taskqueues();
|
||||||
err_3:
|
err_4:
|
||||||
uninit_mutexes();
|
uninit_mutexes();
|
||||||
|
err_3:
|
||||||
err_2:
|
err_2:
|
||||||
err_1:
|
|
||||||
free(dev);
|
free(dev);
|
||||||
|
err_1:
|
||||||
|
err_0:
|
||||||
|
put_module(B_PCI_MODULE_NAME);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,4 +491,6 @@ _fbsd_uninit_driver(driver_t *driver)
|
|||||||
if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES))
|
if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES))
|
||||||
uninit_taskqueues();
|
uninit_taskqueues();
|
||||||
uninit_mutexes();
|
uninit_mutexes();
|
||||||
|
|
||||||
|
put_module(B_PCI_MODULE_NAME);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
#include <compat/sys/taskqueue.h>
|
#include <compat/sys/taskqueue.h>
|
||||||
#include <compat/sys/haiku-module.h>
|
#include <compat/sys/haiku-module.h>
|
||||||
|
|
||||||
|
#define MAX_TASKQUEUE_THREADS 2
|
||||||
|
|
||||||
struct taskqueue {
|
struct taskqueue {
|
||||||
char tq_name[64];
|
char tq_name[64];
|
||||||
mutex tq_mutex;
|
mutex tq_mutex;
|
||||||
@@ -22,7 +24,7 @@ struct taskqueue {
|
|||||||
int tq_fast;
|
int tq_fast;
|
||||||
int32 tq_spinlock;
|
int32 tq_spinlock;
|
||||||
sem_id tq_sem;
|
sem_id tq_sem;
|
||||||
thread_id *tq_threads;
|
thread_id tq_threads[MAX_TASKQUEUE_THREADS];
|
||||||
int tq_threadcount;
|
int tq_threadcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,10 +42,17 @@ _taskqueue_create(const char *name, int mflags, int fast,
|
|||||||
|
|
||||||
tq->tq_fast = 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) {
|
if (fast) {
|
||||||
tq->tq_spinlock = 0;
|
tq->tq_spinlock = 0;
|
||||||
} else {
|
} else {
|
||||||
if (mutex_init(&tq->tq_mutex, name) < B_OK) {
|
if (mutex_init(&tq->tq_mutex, name) < B_OK) {
|
||||||
|
delete_sem(tq->tq_sem);
|
||||||
free(tq);
|
free(tq);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -54,8 +63,6 @@ _taskqueue_create(const char *name, int mflags, int fast,
|
|||||||
tq->tq_enqueue = enqueue;
|
tq->tq_enqueue = enqueue;
|
||||||
tq->tq_arg = context;
|
tq->tq_arg = context;
|
||||||
|
|
||||||
tq->tq_sem = -1;
|
|
||||||
tq->tq_threads = NULL;
|
|
||||||
tq->tq_threadcount = 0;
|
tq->tq_threadcount = 0;
|
||||||
|
|
||||||
return tq;
|
return tq;
|
||||||
@@ -101,15 +108,9 @@ tq_handle_thread(void *data)
|
|||||||
cpu_status cpu_state;
|
cpu_status cpu_state;
|
||||||
struct task *t;
|
struct task *t;
|
||||||
int pending;
|
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) {
|
while (1) {
|
||||||
status_t status = acquire_sem(sem);
|
status_t status = acquire_sem(tq->tq_sem);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -126,43 +127,18 @@ tq_handle_thread(void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
static int
|
||||||
taskqueue_start_threads(struct taskqueue **tqp, int count, int prio,
|
_taskqueue_start_threads(struct taskqueue **tqp, int count, int prio,
|
||||||
const char *format, ...)
|
const char *name)
|
||||||
{
|
{
|
||||||
struct taskqueue *tq = (*tqp);
|
struct taskqueue *tq = (*tqp);
|
||||||
cpu_status state;
|
|
||||||
char name[64];
|
|
||||||
va_list vl;
|
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
tq_lock(tq, &state);
|
if (count > MAX_TASKQUEUE_THREADS)
|
||||||
|
panic("_taskqueue_start_threads, too many threads requested");
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
tq->tq_threads[i] = spawn_kernel_thread(tq_handle_thread, tq->tq_name,
|
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];
|
status_t status = tq->tq_threads[i];
|
||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
kill_thread(tq->tq_threads[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;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,11 +156,36 @@ taskqueue_start_threads(struct taskqueue **tqp, int count, int prio,
|
|||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
resume_thread(tq->tq_threads[i]);
|
resume_thread(tq->tq_threads[i]);
|
||||||
|
|
||||||
tq_unlock(tq, state);
|
|
||||||
return 0;
|
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
|
void
|
||||||
taskqueue_free(struct taskqueue *tq)
|
taskqueue_free(struct taskqueue *tq)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user