freebsd compat. layer: added swi taskqueue and a couple more methods that if_xl needs. also marked some as unimplemented so its clearer what is left to be done.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21080 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos
2007-05-09 04:21:47 +00:00
parent dcaf1f47c5
commit 0747d47e40
8 changed files with 68 additions and 379 deletions
+15
View File
@@ -326,6 +326,21 @@ bus_generic_resume(device_t dev)
}
int
bus_generic_print_child(device_t dev, device_t child)
{
UNIMPLEMENTED();
return B_ERROR;
}
void
bus_generic_driver_added(device_t dev, driver_t *driver)
{
UNIMPLEMENTED();
}
#define DEBUG_BUS_SPACE_RW
#ifdef DEBUG_BUS_SPACE_RW
+9
View File
@@ -225,6 +225,15 @@ device_get_softc(device_t dev)
int
device_delete_child(device_t dev, device_t child)
{
UNIMPLEMENTED();
return -1;
}
int
device_is_attached(device_t dev)
{
UNIMPLEMENTED();
return -1;
}
@@ -93,6 +93,9 @@ 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);
int device_is_attached(device_t dev);
int bus_generic_print_child(device_t dev, device_t child);
void bus_generic_driver_added(device_t dev, driver_t *driver);
static inline struct sysctl_ctx_list *
device_get_sysctl_ctx(device_t dev)
@@ -90,6 +90,7 @@ extern int __haiku_driver_requirements;
enum {
FBSD_TASKQUEUES = 1 << 0,
FBSD_FAST_TASKQUEUE = 1 << 1,
FBSD_SWI_TASKQUEUE = 1 << 2,
};
#define HAIKU_DRIVER_REQUIREMENTS(flags) \
@@ -24,6 +24,8 @@ int taskqueue_enqueue(struct taskqueue *tq, struct task *task);
void taskqueue_thread_enqueue(void *context);
extern struct taskqueue *taskqueue_fast;
extern struct taskqueue *taskqueue_swi;
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);
-374
View File
@@ -190,380 +190,6 @@ m_free(struct mbuf *m)
}
/*
* Copy data from an mbuf chain starting "off" bytes from the beginning,
* continuing for "len" bytes, into the indicated buffer.
*/
void
m_copydata(const struct mbuf *m, int off, int len, caddr_t cp)
{
u_int count;
KASSERT(off >= 0, ("m_copydata, negative off %d", off));
KASSERT(len >= 0, ("m_copydata, negative len %d", len));
while (off > 0) {
KASSERT(m != NULL, ("m_copydata, offset > size of mbuf chain"));
if (off < m->m_len)
break;
off -= m->m_len;
m = m->m_next;
}
while (len > 0) {
KASSERT(m != NULL, ("m_copydata, length > size of mbuf chain"));
count = min(m->m_len - off, len);
bcopy(mtod(m, caddr_t) + off, cp, count);
len -= count;
cp += count;
off = 0;
m = m->m_next;
}
}
/*
* Concatenate mbuf chain n to m.
* Both chains must be of the same type (e.g. MT_DATA).
* Any m_pkthdr is not updated.
*/
void
m_cat(struct mbuf *m, struct mbuf *n)
{
while (m->m_next)
m = m->m_next;
while (n) {
if (m->m_flags & M_EXT ||
m->m_data + m->m_len + n->m_len >= &m->m_dat[MLEN]) {
/* just join the two chains */
m->m_next = n;
return;
}
/* splat the data from one into the other */
bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
(u_int)n->m_len);
m->m_len += n->m_len;
n = m_free(n);
}
}
u_int
m_length(struct mbuf *m0, struct mbuf **last)
{
struct mbuf *m;
u_int len;
len = 0;
for (m = m0; m != NULL; m = m->m_next) {
len += m->m_len;
if (m->m_next == NULL)
break;
}
if (last != NULL)
*last = m;
return (len);
}
u_int
m_fixhdr(struct mbuf *m0)
{
u_int len;
len = m_length(m0, NULL);
m0->m_pkthdr.len = len;
return (len);
}
static int
m_tag_copy_chain(struct mbuf *to, struct mbuf *from, int how)
{
return 1;
}
/*
* Duplicate "from"'s mbuf pkthdr in "to".
* "from" must have M_PKTHDR set, and "to" must be empty.
* In particular, this does a deep copy of the packet tags.
*/
static int
m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how)
{
MBUF_CHECKSLEEP(how);
/* to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT); */
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;
/* SLIST_INIT(&to->m_pkthdr.tags); */
return (m_tag_copy_chain(to, from, MBTOM(how)));
}
/*
* Defragment a mbuf chain, returning the shortest possible
* chain of mbufs and clusters. If allocation fails and
* this cannot be completed, NULL will be returned, but
* the passed in chain will be unchanged. Upon success,
* the original chain will be freed, and the new chain
* will be returned.
*
* If a non-packet header is passed in, the original
* mbuf (chain?) will be returned unharmed.
*/
struct mbuf *
m_defrag(struct mbuf *m0, int how)
{
struct mbuf *m_new = NULL, *m_final = NULL;
int progress = 0, length;
MBUF_CHECKSLEEP(how);
if (!(m0->m_flags & M_PKTHDR))
return (m0);
m_fixhdr(m0); /* Needed sanity check */
if (m0->m_pkthdr.len > MHLEN)
m_final = m_getcl(how, MT_DATA, M_PKTHDR);
else
m_final = m_gethdr(how, MT_DATA);
if (m_final == NULL)
goto nospace;
if (m_dup_pkthdr(m_final, m0, how) == 0)
goto nospace;
m_new = m_final;
while (progress < m0->m_pkthdr.len) {
length = m0->m_pkthdr.len - progress;
if (length > MCLBYTES)
length = MCLBYTES;
if (m_new == NULL) {
if (length > MLEN)
m_new = m_getcl(how, MT_DATA, 0);
else
m_new = m_get(how, MT_DATA);
if (m_new == NULL)
goto nospace;
}
m_copydata(m0, progress, length, mtod(m_new, caddr_t));
progress += length;
m_new->m_len = length;
if (m_new != m_final)
m_cat(m_final, m_new);
m_new = NULL;
}
m_freem(m0);
m0 = m_final;
return (m0);
nospace:
if (m_final)
m_freem(m_final);
return (NULL);
}
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()
{
+4
View File
@@ -23,6 +23,7 @@ int
mii_phy_probe(device_t dev, device_t *miiDev, ifm_change_cb_t change,
ifm_stat_cb_t stat)
{
UNIMPLEMENTED();
return -1;
}
@@ -30,11 +31,13 @@ mii_phy_probe(device_t dev, device_t *miiDev, ifm_change_cb_t change,
void
mii_tick(struct mii_data *data)
{
UNIMPLEMENTED();
}
int
mii_mediachg(struct mii_data *data)
{
UNIMPLEMENTED();
return -1;
}
@@ -42,4 +45,5 @@ mii_mediachg(struct mii_data *data)
void
mii_pollstat(struct mii_data *data)
{
UNIMPLEMENTED();
}
+34 -5
View File
@@ -29,6 +29,7 @@ struct taskqueue {
struct taskqueue *taskqueue_fast = NULL;
struct taskqueue *taskqueue_swi = NULL;
static struct taskqueue *
@@ -296,26 +297,54 @@ task_init(struct task *t, int prio, task_handler_t handler, void *context)
status_t
init_taskqueues()
{
status_t status = B_NO_MEMORY;
if (HAIKU_DRIVER_REQUIRES(FBSD_FAST_TASKQUEUE)) {
taskqueue_fast = taskqueue_create_fast("fast taskq", 0,
taskqueue_thread_enqueue, NULL);
taskqueue_thread_enqueue, &taskqueue_fast);
if (taskqueue_fast == NULL)
return B_NO_MEMORY;
if (taskqueue_start_threads(&taskqueue_fast, 1, B_REAL_TIME_PRIORITY,
"fast taskq") < 0) {
taskqueue_free(taskqueue_fast);
return B_ERROR;
status = taskqueue_start_threads(&taskqueue_fast, 1,
B_REAL_TIME_PRIORITY, "fast taskq");
if (status < B_OK)
goto err_1;
}
if (HAIKU_DRIVER_REQUIRES(FBSD_SWI_TASKQUEUE)) {
taskqueue_swi = taskqueue_create_fast("swi taskq", 0,
taskqueue_thread_enqueue, &taskqueue_swi);
if (taskqueue_swi == NULL) {
status = B_NO_MEMORY;
goto err_1;
}
status = taskqueue_start_threads(&taskqueue_swi, 1,
B_REAL_TIME_PRIORITY, "swi taskq");
if (status < B_OK)
goto err_2;
}
return B_OK;
err_2:
if (taskqueue_swi)
taskqueue_free(taskqueue_swi);
err_1:
if (taskqueue_fast)
taskqueue_free(taskqueue_fast);
return status;
}
void
uninit_taskqueues()
{
if (HAIKU_DRIVER_REQUIRES(FBSD_SWI_TASKQUEUE))
taskqueue_free(taskqueue_swi);
if (HAIKU_DRIVER_REQUIRES(FBSD_FAST_TASKQUEUE))
taskqueue_free(taskqueue_fast);
}