freebsd compat. layer, a few more methods.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20987 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos 2007-05-03 00:46:07 +00:00
parent da1d4ee6b3
commit 522fc5d845
6 changed files with 317 additions and 15 deletions

View File

@ -3,10 +3,13 @@ SubDir HAIKU_TOP src libs compat freebsd_network ;
UsePrivateHeaders kernel net ;
UseHeaders [ FDirName $(SUBDIR) ] : true ;
UseHeaders [ FDirName $(SUBDIR) headers ] : true ;
UseHeaders [ FDirName $(SUBDIR) compat ] : true ;
SubDirCcFlags [ FDefines _KERNEL=1 ] ;
Library libfreebsd_network.a :
compat.c
device.c
mbuf.c
mutex.c
;

View File

@ -8,9 +8,11 @@
* Some of this code is based on previous work by Marcus Overhagen.
*/
#include "device.h"
#include <stdio.h>
#include <KernelExport.h>
#include <drivers/PCI.h>
#include <compat/dev/pci/pcivar.h>
#include <compat/sys/bus.h>
@ -21,28 +23,54 @@ status_t init_compat_layer(void);
pci_module_info *gPci;
struct device {
int devId;
pci_info * pciInfo;
uint8 pciBus;
uint8 pciDev;
uint8 pciFunc;
};
uint32_t
pci_read_config(device_t dev, int offset, int size)
{
return gPci->read_pci_config(dev->pciBus, dev->pciDev, dev->pciFunc,
offset, size);
return gPci->read_pci_config(dev->pciInfo->bus, dev->pciInfo->device,
dev->pciInfo->function, offset, size);
}
void
pci_write_config(device_t dev, int offset, uint32_t value, int size)
{
gPci->write_pci_config(dev->pciBus, dev->pciDev, dev->pciFunc, offset,
size, value);
gPci->write_pci_config(dev->pciInfo->bus, dev->pciInfo->device,
dev->pciInfo->function, offset, size, value);
}
uint16_t
pci_get_vendor(device_t dev)
{
return pci_read_config(dev, PCI_vendor_id, 2);
}
uint16_t
pci_get_device(device_t dev)
{
return pci_read_config(dev, PCI_device_id, 2);
}
uint8_t
pci_get_revid(device_t dev)
{
return pci_read_config(dev, PCI_revision, 1);
}
int
device_printf(device_t dev, const char *format, ...)
{
char buf[256];
va_list vl;
va_start(vl, format);
vsnprintf(buf, sizeof(buf), format, vl);
va_end(vl);
dprintf("[...] %s", buf);
return 0;
}

View File

@ -0,0 +1,96 @@
/*
* 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 "device.h"
#include <stdlib.h>
#include <compat/sys/bus.h>
#include <compat/sys/mbuf.h>
static status_t
compat_open(const char *name, uint32 flags, void **cookie)
{
return B_ERROR;
}
static status_t
compat_close(void *cookie)
{
device_t dev = cookie;
return B_ERROR;
}
static status_t
compat_free(void *cookie)
{
device_t dev = cookie;
free(dev);
return B_ERROR;
}
static status_t
compat_read(void *cookie, off_t position, void *buf, size_t *numBytes)
{
uint32 semFlags = B_CAN_INTERRUPT;
device_t dev = cookie;
status_t status;
struct mbuf *mb;
size_t len;
if (atomic_or(&dev->flags, 0) & DEVICE_CLOSED)
return B_INTERRUPTED;
if (atomic_or(&dev->flags, 0) & DEVICE_NON_BLOCK)
semFlags |= B_RELATIVE_TIMEOUT;
do {
status = acquire_sem_etc(dev->receive_sem, 1, semFlags, 0);
if (atomic_or(&dev->flags, 0) & DEVICE_CLOSED)
return B_INTERRUPTED;
if (status == B_WOULD_BLOCK) {
*numBytes = 0;
return B_OK;
} else if (status < B_OK)
return status;
IF_DEQUEUE(&dev->receive_queue, mb);
} while (mb == NULL);
len = min_c(max_c(mb->m_len, 0), *numBytes);
// TODO we need something that cna join various chunks
memcpy(buf, mtod(mb, const void *), len);
*numBytes = len;
m_freem(mb);
return B_OK;
}
static status_t
compat_write(void *cookie, off_t position, const void *buffer,
size_t *numBytes)
{
return B_ERROR;
}
static status_t
compat_control(void *cookie, uint32 op, void *arg, size_t len)
{
return B_ERROR;
}

View File

@ -0,0 +1,45 @@
/*
* 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.
*/
#ifndef _DEVICE_H_
#define _DEVICE_H_
#include <stdint.h>
#include <KernelExport.h>
#include <drivers/PCI.h>
#include <compat/sys/kernel.h>
#include <compat/net/if.h>
#include <compat/net/if_var.h>
struct ifnet;
struct device {
int devId;
pci_info * pciInfo;
int32 flags;
struct ifqueue receive_queue;
sem_id receive_sem;
struct ifnet * ifp;
};
enum {
DEVICE_CLOSED = 1 << 0,
DEVICE_NON_BLOCK = 1 << 1,
};
extern pci_module_info *gPci;
#endif

View File

@ -0,0 +1,68 @@
/*
* 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 <stdint.h>
#include <slab/Slab.h>
#include <compat/sys/mbuf.h>
status_t init_mbufs(void);
void uninit_mbufs(void);
#define CHUNK_SIZE 2048
static object_cache *sMBufCache;
static object_cache *sChunkCache;
void
m_freem(struct mbuf *mp)
{
struct mbuf *next = mp;
do {
mp = next;
next = next->m_next;
if (mp->m_flags & M_EXT)
object_cache_free(sChunkCache, mp->m_ext.ext_buf);
object_cache_free(sMBufCache, mp);
} while (next);
}
status_t
init_mbufs()
{
sMBufCache = create_object_cache("mbufs", sizeof(struct mbuf), 8, NULL,
NULL, NULL);
if (sMBufCache == NULL)
return B_NO_MEMORY;
sChunkCache = create_object_cache("mbuf chunks", CHUNK_SIZE, 0, NULL, NULL,
NULL);
if (sChunkCache == NULL) {
delete_object_cache(sMBufCache);
return B_NO_MEMORY;
}
return B_OK;
}
void
uninit_mbufs()
{
delete_object_cache(sMBufCache);
delete_object_cache(sChunkCache);
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Hugo Santos, hugosantos@gmail.com
*/
#include <KernelExport.h>
#include <compat/sys/mutex.h>
status_t init_mutexes(void);
void uninit_mutexes(void);
// these methods are bit unfriendly, a bit too much panic() around
struct mutex Giant;
void
mtx_init(struct mtx *m, const char *name, const char *type, int opts)
{
if (opts == MTX_DEF) {
if (mutex_init(&m->u.mutex, name) < B_OK)
panic("Panic! Dance like it's 1979, we ran out of semaphores");
} else if (opts == MTX_RECURSE) {
if (recursive_lock_init(&m->u.recursive, name) < B_OK)
panic("Hell just froze as someone was trying to init a recursive mutex.");
} else
panic("Uh-oh, someone is pressing the wrong buttons");
m->type = opts;
}
void
mtx_destroy(struct mtx *m)
{
if (m->type == MTX_DEF) {
mutex_destroy(&m->u.mutex);
} else if (m->type == MTX_RECURSE) {
recursive_lock_destroy(&m->u.recursive);
} else
panic("Uh-oh, someone is pressing the wrong buttons");
}
status_t
init_mutexes()
{
return B_ERROR;
}
void
uninit_mutexes()
{
}