freebsd compat. layer: a few more definitions, preparing for a DMA-using driver.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21067 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
d00539e3ba
commit
25d42ceb99
@ -18,4 +18,5 @@ Library libfreebsd_network.a :
|
||||
mbuf.c
|
||||
mii.c
|
||||
mutex.c
|
||||
taskqueue.c
|
||||
;
|
||||
|
@ -186,6 +186,18 @@ intr_wrapper(void *data)
|
||||
}
|
||||
|
||||
|
||||
static int32
|
||||
intr_fast_wrapper(void *data)
|
||||
{
|
||||
struct internal_intr *intr = data;
|
||||
|
||||
intr->handler(intr->arg);
|
||||
|
||||
/* no way to know, so let other devices get it as well */
|
||||
return B_UNHANDLED_INTERRUPT;
|
||||
}
|
||||
|
||||
|
||||
static int32
|
||||
intr_handler(void *data)
|
||||
{
|
||||
@ -209,9 +221,12 @@ intr_handler(void *data)
|
||||
static void
|
||||
free_internal_intr(struct internal_intr *intr)
|
||||
{
|
||||
status_t status;
|
||||
delete_sem(intr->sem);
|
||||
wait_for_thread(intr->thread, &status);
|
||||
if (intr->sem >= B_OK) {
|
||||
status_t status;
|
||||
delete_sem(intr->sem);
|
||||
wait_for_thread(intr->thread, &status);
|
||||
}
|
||||
|
||||
free(intr);
|
||||
}
|
||||
|
||||
@ -235,25 +250,35 @@ bus_setup_intr(device_t dev, struct resource *res, int flags,
|
||||
intr->arg = arg;
|
||||
intr->irq = res->handle;
|
||||
|
||||
snprintf(semName, sizeof(semName), "%s intr", dev->dev_name);
|
||||
if (flags & INTR_FAST) {
|
||||
intr->sem = -1;
|
||||
intr->thread = -1;
|
||||
|
||||
intr->sem = create_sem(0, semName);
|
||||
if (intr->sem < B_OK) {
|
||||
free(intr);
|
||||
return B_NO_MEMORY;
|
||||
status = install_io_interrupt_handler(intr->irq,
|
||||
intr_fast_wrapper, intr, 0);
|
||||
} else {
|
||||
snprintf(semName, sizeof(semName), "%s intr", dev->dev_name);
|
||||
|
||||
intr->sem = create_sem(0, semName);
|
||||
if (intr->sem < B_OK) {
|
||||
free(intr);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
snprintf(semName, sizeof(semName), "%s intr handler", dev->dev_name);
|
||||
|
||||
intr->thread = spawn_kernel_thread(intr_handler, semName,
|
||||
B_REAL_TIME_DISPLAY_PRIORITY, intr);
|
||||
if (intr->thread < B_OK) {
|
||||
delete_sem(intr->sem);
|
||||
free(intr);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
status = install_io_interrupt_handler(intr->irq,
|
||||
intr_wrapper, intr, 0);
|
||||
}
|
||||
|
||||
snprintf(semName, sizeof(semName), "%s intr handler", dev->dev_name);
|
||||
|
||||
intr->thread = spawn_kernel_thread(intr_handler, semName,
|
||||
B_REAL_TIME_DISPLAY_PRIORITY, intr);
|
||||
if (intr->thread < B_OK) {
|
||||
delete_sem(intr->sem);
|
||||
free(intr);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
status = install_io_interrupt_handler(intr->irq, intr_wrapper, intr, 0);
|
||||
if (status < B_OK) {
|
||||
free_internal_intr(intr);
|
||||
return status;
|
||||
@ -280,8 +305,23 @@ bus_teardown_intr(device_t dev, struct resource *res, void *arg)
|
||||
int
|
||||
bus_generic_detach(device_t dev)
|
||||
{
|
||||
/* TODO */
|
||||
UNIMPLEMENTED();
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
bus_generic_suspend(device_t dev)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
bus_generic_resume(device_t dev)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
@ -184,6 +184,14 @@ device_set_desc(device_t dev, const char *desc)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
device_set_desc_copy(device_t dev, const char *desc)
|
||||
{
|
||||
dev->description = strdup(desc);
|
||||
dev->flags |= DEVICE_DESC_ALLOCED;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
device_get_name(device_t dev)
|
||||
{
|
||||
@ -297,7 +305,7 @@ _kernel_contigmalloc(const char *file, int line, size_t size, int flags,
|
||||
if (area < 0)
|
||||
return NULL;
|
||||
|
||||
driver_printf("(%s) addr = %p, area = %d, size = %lu\n",
|
||||
driver_printf("(%s) addr = %p, area = %ld, size = %lu\n",
|
||||
name, addr, area, size);
|
||||
|
||||
return addr;
|
||||
|
@ -7,11 +7,13 @@
|
||||
#define PCIR_SUBVEND_0 0x2c
|
||||
#define PCIR_SUBDEV_0 0x2e
|
||||
|
||||
#define PCIM_CMD_PORTEN 0x0001
|
||||
#define PCIM_CMD_MEMEN 0x0002
|
||||
#define PCIM_CMD_MWRICEN 0x0010
|
||||
#define PCIM_CMD_PORTEN 0x0001
|
||||
#define PCIM_CMD_MEMEN 0x0002
|
||||
#define PCIM_CMD_BUSMASTEREN 0x0004
|
||||
#define PCIM_CMD_MWRICEN 0x0010
|
||||
|
||||
#define PCIR_BARS 0x10
|
||||
#define PCIR_BAR(x) (PCIR_BARS + (x) * 4)
|
||||
#define PCIR_CIS 0x28
|
||||
|
||||
#endif
|
||||
|
@ -59,6 +59,11 @@ struct vlanreq {
|
||||
#define SIOCGETVLAN SIOCGIFGENERIC
|
||||
|
||||
#ifdef _KERNEL
|
||||
#if 1
|
||||
#define VLAN_INPUT_TAG_NEW(_ifp, _m, _t) do { } while (0)
|
||||
#define VLAN_OUTPUT_TAG(_ifp, _m) NULL
|
||||
#define VLAN_TAG_VALUE(_mt) 0
|
||||
#else
|
||||
/*
|
||||
* Drivers that are capable of adding and removing the VLAN header
|
||||
* in hardware indicate they support this by marking IFCAP_VLAN_HWTAGGING
|
||||
@ -141,6 +146,7 @@ struct vlanreq {
|
||||
#define VLAN_OUTPUT_TAG(_ifp, _m) \
|
||||
((_m)->m_flags & M_VLANTAG ? \
|
||||
m_tag_locate((_m), MTAG_VLAN, MTAG_VLAN_TAG, NULL) : NULL)
|
||||
#endif
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NET_IF_VLAN_VAR_H_ */
|
||||
|
@ -0,0 +1,8 @@
|
||||
#ifndef _FBSD_COMPAT_NETINET_IF_ETHER_H_
|
||||
#define _FBSD_COMPAT_NETINET_IF_ETHER_H_
|
||||
|
||||
/* Haiku does it's own ARP management */
|
||||
|
||||
#define arp_ifinit(ifp, ifa)
|
||||
|
||||
#endif
|
@ -54,10 +54,13 @@ bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t handle,
|
||||
|
||||
enum intr_type {
|
||||
INTR_TYPE_NET = 4,
|
||||
INTR_FAST = 128,
|
||||
INTR_MPSAFE = 512,
|
||||
};
|
||||
|
||||
int bus_generic_detach(device_t dev);
|
||||
int bus_generic_suspend(device_t dev);
|
||||
int bus_generic_resume(device_t dev);
|
||||
|
||||
typedef void (*driver_intr_t)(void *);
|
||||
|
||||
@ -86,6 +89,7 @@ int device_get_unit(device_t dev);
|
||||
void *device_get_softc(device_t dev);
|
||||
int device_printf(device_t dev, const char *, ...) __printflike(2, 3);
|
||||
void device_set_desc(device_t dev, const char *desc);
|
||||
void device_set_desc_copy(device_t dev, const char *desc);
|
||||
|
||||
device_t device_add_child(device_t dev, const char *name, int unit);
|
||||
int device_delete_child(device_t dev, device_t child);
|
||||
|
@ -79,6 +79,12 @@ extern int __haiku_disable_interrupts(device_t dev);
|
||||
|
||||
#define HAIKU_CHECK_DISABLE_INTERRUPTS __haiku_disable_interrupts
|
||||
|
||||
#define NO_HAIKU_CHECK_DISABLE_INTERRUPTS() \
|
||||
int HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev) { \
|
||||
panic("should never be called."); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
#define HAIKU_INTR_REGISTER_ENTER(status) do { \
|
||||
status = disable_interrupts(); \
|
||||
acquire_spinlock(&__haiku_intr_spinlock); \
|
||||
|
@ -28,6 +28,8 @@ struct __system_init {
|
||||
#define SYSINIT(uniquifier, subsystem, order, func, ident) \
|
||||
struct __system_init __init_##uniquifier = { func }
|
||||
|
||||
#define TUNABLE_INT(path, var)
|
||||
|
||||
#define __packed __attribute__ ((packed))
|
||||
#define __printflike(a, b) __attribute__ ((format (__printf__, a, b)))
|
||||
|
||||
|
@ -31,4 +31,9 @@ void _kernel_contigfree(void *addr, unsigned long size);
|
||||
#define kernel_contigfree(addr, size, base) \
|
||||
_kernel_contigfree(addr, size)
|
||||
|
||||
#ifdef FBSD_DRIVER
|
||||
#define malloc(size, tag, flags) kernel_malloc(size, tag, flags)
|
||||
#define free(pointer, tag) kernel_free(pointer, tag)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -28,7 +28,7 @@ struct pkthdr {
|
||||
};
|
||||
|
||||
struct m_ext {
|
||||
void * ext_buf;
|
||||
caddr_t ext_buf;
|
||||
unsigned int ext_size;
|
||||
int ext_type;
|
||||
};
|
||||
@ -84,6 +84,7 @@ struct mbuf {
|
||||
#define CSUM_PSEUDO_HDR 0x0800
|
||||
#define CSUM_DELAY_DATA (CSUM_TCP | CSUM_UDP)
|
||||
|
||||
#define M_MOVE_PKTHDR(to, from) m_move_pkthdr((to), (from))
|
||||
#define MGET(m, how, type) ((m) = m_get((how), (type)))
|
||||
#define MGETHDR(m, how, type) ((m) = m_gethdr((how), (type)))
|
||||
#define MCLGET(m, how) m_clget((m), (how))
|
||||
@ -92,6 +93,10 @@ struct mbuf *m_getcl(int how, short type, int flags);
|
||||
void m_freem(struct mbuf *mbuf);
|
||||
struct mbuf *m_free(struct mbuf *m);
|
||||
struct mbuf *m_defrag(struct mbuf *m, int);
|
||||
void m_adj(struct mbuf *m, int);
|
||||
struct mbuf *m_pullup(struct mbuf *m, int len);
|
||||
struct mbuf *m_prepend(struct mbuf *m, int, int);
|
||||
void m_move_pkthdr(struct mbuf *, struct mbuf *);
|
||||
|
||||
u_int m_length(struct mbuf *m, struct mbuf **last);
|
||||
u_int m_fixhdr(struct mbuf *m);
|
||||
@ -104,11 +109,88 @@ void m_clget(struct mbuf *m, int how);
|
||||
|
||||
#define mtod(m, type) (type)((m)->m_data)
|
||||
|
||||
#define m_tag_delete(mb, tag) \
|
||||
panic("m_tag_delete unsupported.");
|
||||
|
||||
/* Check if the supplied mbuf has a packet header, or else panic. */
|
||||
#define M_ASSERTPKTHDR(m) \
|
||||
KASSERT(m != NULL && m->m_flags & M_PKTHDR, \
|
||||
("%s: no mbuf packet header!", __func__))
|
||||
|
||||
#define MBUF_CHECKSLEEP(how) do { } while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place
|
||||
* an object of the specified size at the end of the mbuf, longword aligned.
|
||||
*/
|
||||
#define M_ALIGN(m, len) do { \
|
||||
(m)->m_data += (MLEN - (len)) & ~(sizeof(long) - 1); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* As above, for mbufs allocated with m_gethdr/MGETHDR
|
||||
* or initialized by M_COPY_PKTHDR.
|
||||
*/
|
||||
#define MH_ALIGN(m, len) do { \
|
||||
(m)->m_data += (MHLEN - (len)) & ~(sizeof(long) - 1); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
#define MEXT_IS_REF(m) (((m)->m_ext.ref_cnt != NULL) \
|
||||
&& (*((m)->m_ext.ref_cnt) > 1))
|
||||
*/
|
||||
#define MEXT_IS_REF(m) 0
|
||||
|
||||
/*
|
||||
* Evaluate TRUE if it's safe to write to the mbuf m's data region (this
|
||||
* can be both the local data payload, or an external buffer area,
|
||||
* depending on whether M_EXT is set).
|
||||
*/
|
||||
|
||||
/*
|
||||
#define M_WRITABLE(m) (!((m)->m_flags & M_RDONLY) && (!((m)->m_flags \
|
||||
& M_EXT) || !MEXT_IS_REF(m)))
|
||||
*/
|
||||
#define M_WRITABLE(m) (!((m)->m_flags & M_EXT) || !MEXT_IS_REF(m))
|
||||
|
||||
/*
|
||||
* Compute the amount of space available
|
||||
* before the current start of data in an mbuf.
|
||||
*
|
||||
* The M_WRITABLE() is a temporary, conservative safety measure: the burden
|
||||
* of checking writability of the mbuf data area rests solely with the caller.
|
||||
*/
|
||||
#define M_LEADINGSPACE(m) \
|
||||
((m)->m_flags & M_EXT ? \
|
||||
(M_WRITABLE(m) ? (m)->m_data - (m)->m_ext.ext_buf : 0): \
|
||||
(m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \
|
||||
(m)->m_data - (m)->m_dat)
|
||||
|
||||
/*
|
||||
* Arrange to prepend space of size plen to mbuf m.
|
||||
* If a new mbuf must be allocated, how specifies whether to wait.
|
||||
* If the allocation fails, the original mbuf chain is freed and m is
|
||||
* set to NULL.
|
||||
*/
|
||||
#define M_PREPEND(m, plen, how) do { \
|
||||
struct mbuf **_mmp = &(m); \
|
||||
struct mbuf *_mm = *_mmp; \
|
||||
int _mplen = (plen); \
|
||||
int __mhow = (how); \
|
||||
\
|
||||
MBUF_CHECKSLEEP(how); \
|
||||
if (M_LEADINGSPACE(_mm) >= _mplen) { \
|
||||
_mm->m_data -= _mplen; \
|
||||
_mm->m_len += _mplen; \
|
||||
} else \
|
||||
_mm = m_prepend(_mm, _mplen, __mhow); \
|
||||
if (_mm != NULL && _mm->m_flags & M_PKTHDR) \
|
||||
_mm->m_pkthdr.len += _mplen; \
|
||||
*_mmp = _mm; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -53,6 +53,9 @@ static inline int mtx_initialized(struct mtx *mtx)
|
||||
void mtx_init(struct mtx *m, const char *name, const char *type, int opts);
|
||||
void mtx_destroy(struct mtx *m);
|
||||
|
||||
#define NET_LOCK_GIANT()
|
||||
#define NET_UNLOCK_GIANT()
|
||||
|
||||
extern struct mtx Giant;
|
||||
|
||||
#endif
|
||||
|
@ -33,4 +33,6 @@
|
||||
#define ALIGN_BYTES (sizeof(int) - 1)
|
||||
#define ALIGN(x) ((((unsigned)x) + ALIGN_BYTES) & ~ALIGN_BYTES)
|
||||
|
||||
#define roundup2(x, y) (((x) + ((y) - 1)) & (~((y) - 1)))
|
||||
|
||||
#endif
|
||||
|
35
src/libs/compat/freebsd_network/compat/sys/taskqueue.h
Normal file
35
src/libs/compat/freebsd_network/compat/sys/taskqueue.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef _FBSD_COMPAT_SYS_TASKQUEUE_H_
|
||||
#define _FBSD_COMPAT_SYS_TASKQUEUE_H_
|
||||
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#define PI_NET 0
|
||||
|
||||
struct task;
|
||||
struct taskqueue;
|
||||
|
||||
typedef void (*task_handler_t)(void *context, int pending);
|
||||
|
||||
#define TASK_INIT(taskp, prio, hand, arg) task_init(taskp, prio, hand, arg)
|
||||
|
||||
typedef void (*taskqueue_enqueue_fn)(void *context);
|
||||
|
||||
struct taskqueue *taskqueue_create(const char *name, int mflags,
|
||||
taskqueue_enqueue_fn enqueue, void *context, void **);
|
||||
int taskqueue_start_threads(struct taskqueue **tq, int count, int pri,
|
||||
const char *name, ...) __printflike(4, 5);
|
||||
void taskqueue_free(struct taskqueue *tq);
|
||||
void taskqueue_drain(struct taskqueue *tq, struct task *task);
|
||||
|
||||
int taskqueue_enqueue(struct taskqueue *tq, struct task *task);
|
||||
|
||||
void taskqueue_thread_enqueue(void *context);
|
||||
|
||||
extern struct taskqueue *taskqueue_fast;
|
||||
int taskqueue_enqueue_fast(struct taskqueue *queue, struct task *task);
|
||||
struct taskqueue *taskqueue_create_fast(const char *name, int mflags,
|
||||
taskqueue_enqueue_fn enqueue, void *context);
|
||||
|
||||
void task_init(struct task *, int prio, task_handler_t handler, void *arg);
|
||||
|
||||
#endif
|
8
src/libs/compat/freebsd_network/compat/sys/types.h
Normal file
8
src/libs/compat/freebsd_network/compat/sys/types.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _FBSD_COMPAT_SYS_TYPES_H_
|
||||
#define _FBSD_COMPAT_SYS_TYPES_H_
|
||||
|
||||
#include <posix/sys/types.h>
|
||||
|
||||
typedef int boolean_t;
|
||||
|
||||
#endif
|
0
src/libs/compat/freebsd_network/compat/vm/pmap.h
Normal file
0
src/libs/compat/freebsd_network/compat/vm/pmap.h
Normal file
@ -75,6 +75,8 @@ free_device(device_t dev)
|
||||
delete_sem(dev->receive_sem);
|
||||
ifq_uninit(&dev->receive_queue);
|
||||
free(dev->softc);
|
||||
if (dev->flags & DEVICE_DESC_ALLOCED)
|
||||
free((char *)dev->description);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@ -131,7 +133,7 @@ compat_open(const char *name, uint32 flags, void **cookie)
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_media = IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, 0);
|
||||
ifp->if_ioctl(ifp, SIOCSIFMEDIA, &ifr);
|
||||
ifp->if_ioctl(ifp, SIOCSIFMEDIA, (caddr_t)&ifr);
|
||||
|
||||
ifp->if_flags = IFF_UP;
|
||||
ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL);
|
||||
@ -300,7 +302,7 @@ compat_control(void *cookie, uint32 op, void *arg, size_t len)
|
||||
return EINVAL;
|
||||
|
||||
memset(&mediareq, 0, sizeof(mediareq));
|
||||
status = ifp->if_ioctl(ifp, SIOCGIFMEDIA, &mediareq);
|
||||
status = ifp->if_ioctl(ifp, SIOCGIFMEDIA, (caddr_t)&mediareq);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
@ -358,10 +360,14 @@ _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++) {
|
||||
if (probe(&fakeDevice) >= 0) {
|
||||
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);
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
|
@ -47,9 +47,13 @@ enum {
|
||||
DEVICE_OPEN = 1 << 0,
|
||||
DEVICE_CLOSED = 1 << 1,
|
||||
DEVICE_NON_BLOCK = 1 << 2,
|
||||
DEVICE_DESC_ALLOCED = 1 << 3,
|
||||
};
|
||||
|
||||
|
||||
#define UNIMPLEMENTED() \
|
||||
panic("fbsd compat, unimplemented: " __FUNCTION__)
|
||||
|
||||
status_t init_mbufs(void);
|
||||
void uninit_mbufs(void);
|
||||
|
||||
|
@ -20,15 +20,13 @@
|
||||
#include <compat/sys/kernel.h>
|
||||
|
||||
|
||||
#define MBUF_CHECKSLEEP(how) do { } while (0)
|
||||
#define MBTOM(how) (how)
|
||||
|
||||
|
||||
#define CHUNK_SIZE 2048
|
||||
|
||||
static object_cache *sMBufCache;
|
||||
static object_cache *sChunkCache;
|
||||
|
||||
static const int max_protohdr = 40 + 20; /* ip6 + tcp */
|
||||
|
||||
|
||||
static int
|
||||
m_to_oc_flags(int how)
|
||||
@ -374,6 +372,201 @@ nospace:
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
m_adj(struct mbuf *mp, int req_len)
|
||||
{
|
||||
int len = req_len;
|
||||
struct mbuf *m;
|
||||
int count;
|
||||
|
||||
if ((m = mp) == NULL)
|
||||
return;
|
||||
if (len >= 0) {
|
||||
/*
|
||||
* Trim from head.
|
||||
*/
|
||||
while (m != NULL && len > 0) {
|
||||
if (m->m_len <= len) {
|
||||
len -= m->m_len;
|
||||
m->m_len = 0;
|
||||
m = m->m_next;
|
||||
} else {
|
||||
m->m_len -= len;
|
||||
m->m_data += len;
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
m = mp;
|
||||
if (mp->m_flags & M_PKTHDR)
|
||||
m->m_pkthdr.len -= (req_len - len);
|
||||
} else {
|
||||
/*
|
||||
* Trim from tail. Scan the mbuf chain,
|
||||
* calculating its length and finding the last mbuf.
|
||||
* If the adjustment only affects this mbuf, then just
|
||||
* adjust and return. Otherwise, rescan and truncate
|
||||
* after the remaining size.
|
||||
*/
|
||||
len = -len;
|
||||
count = 0;
|
||||
for (;;) {
|
||||
count += m->m_len;
|
||||
if (m->m_next == (struct mbuf *)0)
|
||||
break;
|
||||
m = m->m_next;
|
||||
}
|
||||
if (m->m_len >= len) {
|
||||
m->m_len -= len;
|
||||
if (mp->m_flags & M_PKTHDR)
|
||||
mp->m_pkthdr.len -= len;
|
||||
return;
|
||||
}
|
||||
count -= len;
|
||||
if (count < 0)
|
||||
count = 0;
|
||||
/*
|
||||
* Correct length for chain is "count".
|
||||
* Find the mbuf with last data, adjust its length,
|
||||
* and toss data from remaining mbufs on chain.
|
||||
*/
|
||||
m = mp;
|
||||
if (m->m_flags & M_PKTHDR)
|
||||
m->m_pkthdr.len = count;
|
||||
for (; m; m = m->m_next) {
|
||||
if (m->m_len >= count) {
|
||||
m->m_len = count;
|
||||
if (m->m_next != NULL) {
|
||||
m_freem(m->m_next);
|
||||
m->m_next = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
count -= m->m_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Rearange an mbuf chain so that len bytes are contiguous
|
||||
* and in the data area of an mbuf (so that mtod and dtom
|
||||
* will work for a structure of size len). Returns the resulting
|
||||
* mbuf chain on success, frees it and returns null on failure.
|
||||
* If there is room, it will add up to max_protohdr-len extra bytes to the
|
||||
* contiguous region in an attempt to avoid being called next time.
|
||||
*/
|
||||
struct mbuf *
|
||||
m_pullup(struct mbuf *n, int len)
|
||||
{
|
||||
struct mbuf *m;
|
||||
int count;
|
||||
int space;
|
||||
|
||||
/*
|
||||
* If first mbuf has no cluster, and has room for len bytes
|
||||
* without shifting current data, pullup into it,
|
||||
* otherwise allocate a new mbuf to prepend to the chain.
|
||||
*/
|
||||
if ((n->m_flags & M_EXT) == 0 &&
|
||||
n->m_data + len < &n->m_dat[MLEN] && n->m_next) {
|
||||
if (n->m_len >= len)
|
||||
return (n);
|
||||
m = n;
|
||||
n = n->m_next;
|
||||
len -= m->m_len;
|
||||
} else {
|
||||
if (len > MHLEN)
|
||||
goto bad;
|
||||
MGET(m, M_DONTWAIT, n->m_type);
|
||||
if (m == NULL)
|
||||
goto bad;
|
||||
m->m_len = 0;
|
||||
if (n->m_flags & M_PKTHDR)
|
||||
M_MOVE_PKTHDR(m, n);
|
||||
}
|
||||
space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
|
||||
do {
|
||||
count = min(min(max(len, max_protohdr), space), n->m_len);
|
||||
bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
|
||||
(u_int)count);
|
||||
len -= count;
|
||||
m->m_len += count;
|
||||
n->m_len -= count;
|
||||
space -= count;
|
||||
if (n->m_len)
|
||||
n->m_data += count;
|
||||
else
|
||||
n = m_free(n);
|
||||
} while (len > 0 && n);
|
||||
if (len > 0) {
|
||||
(void) m_free(m);
|
||||
goto bad;
|
||||
}
|
||||
m->m_next = n;
|
||||
return (m);
|
||||
bad:
|
||||
m_freem(n);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Lesser-used path for M_PREPEND:
|
||||
* allocate new mbuf to prepend to chain,
|
||||
* copy junk along.
|
||||
*/
|
||||
struct mbuf *
|
||||
m_prepend(struct mbuf *m, int len, int how)
|
||||
{
|
||||
struct mbuf *mn;
|
||||
|
||||
if (m->m_flags & M_PKTHDR)
|
||||
MGETHDR(mn, how, m->m_type);
|
||||
else
|
||||
MGET(mn, how, m->m_type);
|
||||
if (mn == NULL) {
|
||||
m_freem(m);
|
||||
return (NULL);
|
||||
}
|
||||
if (m->m_flags & M_PKTHDR)
|
||||
M_MOVE_PKTHDR(mn, m);
|
||||
mn->m_next = m;
|
||||
m = mn;
|
||||
if (len < MHLEN)
|
||||
MH_ALIGN(m, len);
|
||||
m->m_len = len;
|
||||
return (m);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Move" mbuf pkthdr from "from" to "to".
|
||||
* "from" must have M_PKTHDR set, and "to" must be empty.
|
||||
*/
|
||||
void
|
||||
m_move_pkthdr(struct mbuf *to, struct mbuf *from)
|
||||
{
|
||||
#ifdef MAC
|
||||
/*
|
||||
* XXXMAC: It could be this should also occur for non-MAC?
|
||||
*/
|
||||
if (to->m_flags & M_PKTHDR)
|
||||
m_tag_delete_chain(to, NULL);
|
||||
#endif
|
||||
/* to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT); */
|
||||
/* we don't have M_COPYFLAGS -hugo */
|
||||
to->m_flags = to->m_flags & M_EXT;
|
||||
if ((to->m_flags & M_EXT) == 0)
|
||||
to->m_data = to->m_pktdat;
|
||||
to->m_pkthdr = from->m_pkthdr; /* especially tags */
|
||||
/* we don't have tags -hugo */
|
||||
#if 0
|
||||
SLIST_INIT(&from->m_pkthdr.tags); /* purge tags from src */
|
||||
#endif
|
||||
from->m_flags &= ~M_PKTHDR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
init_mbufs()
|
||||
{
|
||||
|
95
src/libs/compat/freebsd_network/taskqueue.c
Normal file
95
src/libs/compat/freebsd_network/taskqueue.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2007, Hugo Santos. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Hugo Santos, hugosantos@gmail.com
|
||||
*/
|
||||
|
||||
#include "device.h"
|
||||
|
||||
#include <compat/sys/taskqueue.h>
|
||||
|
||||
struct task {
|
||||
int priority;
|
||||
task_handler_t handler;
|
||||
void *argument;
|
||||
};
|
||||
|
||||
struct taskqueue {
|
||||
};
|
||||
|
||||
struct taskqueue *taskqueue_fast;
|
||||
|
||||
struct taskqueue *
|
||||
taskqueue_create(const char *name, int mflags, taskqueue_enqueue_fn enqueue,
|
||||
void *context, void **unused)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
taskqueue_start_threads(struct taskqueue **tq, int count, int pri,
|
||||
const char *name, ...)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
taskqueue_free(struct taskqueue *tq)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
taskqueue_drain(struct taskqueue *tq, struct task *task)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
taskqueue_enqueue(struct taskqueue *tq, struct task *task)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
taskqueue_thread_enqueue(void *context)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
taskqueue_enqueue_fast(struct taskqueue *queue, struct task *task)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
struct taskqueue *
|
||||
taskqueue_create_fast(const char *name, int mflags,
|
||||
taskqueue_enqueue_fn enqueue, void *context)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
task_init(struct task *t, int prio, task_handler_t handler, void *context)
|
||||
{
|
||||
t->priority = prio;
|
||||
t->handler = handler;
|
||||
t->argument = context;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user