* Applied cleaned patch by Adrian: the gDevices[] can now have empty entries,

the gDeviceNameList[] entries are no longer in the same order.
* This fixes bug #3124.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29593 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-03-18 16:36:51 +00:00
parent e72a9b541a
commit 3e9b338ea7
2 changed files with 73 additions and 16 deletions
+6 -6
View File
@@ -1,6 +1,6 @@
/*
* Copyright 2007-2009, Axel Dörfler, [email protected].
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Copyright 2007, Axel Dörfler, [email protected]. All Rights Reserved.
* Copyright 2004, Marcus Overhagen. All Rights Reserved.
*
* Distributed under the terms of the MIT License.
@@ -28,12 +28,12 @@ compat_open(const char *name, uint32 flags, void **cookie)
struct ifreq ifr;
int i;
for (i = 0; gDeviceNameList[i] != NULL; i++) {
if (strcmp(gDeviceNameList[i], name) == 0)
for (i = 0; i < MAX_DEVICES; i++) {
if (gDevices[i] != NULL && !strcmp(gDevices[i]->device_name, name))
break;
}
if (gDeviceNameList[i] == NULL)
if (i == MAX_DEVICES)
return B_ERROR;
if (get_module(NET_STACK_MODULE_NAME, (module_info **)&gStack) != B_OK)
@@ -85,7 +85,7 @@ compat_free(void *cookie)
if_printf(ifp, "compat_free()\n");
/* TODO: empty out the send queue */
// TODO: empty out the send queue
atomic_and(&ifp->open_count, 0);
put_module(NET_STACK_MODULE_NAME);
@@ -161,7 +161,7 @@ compat_write(void *cookie, off_t position, const void *buffer,
if (mb == NULL)
return ENOBUFS;
/* if we waited, check after if the ifp is still valid */
// if we waited, check after if the ifp is still valid
mb->m_pkthdr.len = mb->m_len = min_c(*numBytes, (size_t)MCLBYTES);
memcpy(mtod(mb, void *), buffer, mb->m_len);
+67 -10
View File
@@ -1,6 +1,6 @@
/*
* Copyright 2007-2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved.
* Copyright 2004, Marcus Overhagen. All Rights Reserved.
*
* Distributed under the terms of the MIT License.
@@ -24,10 +24,52 @@
#include <compat/net/ethernet.h>
static void
insert_into_device_name_list(struct ifnet* ifp)
{
int i;
for (i = 0; i < MAX_DEVICES; i++) {
if (gDeviceNameList[i] == NULL) {
gDeviceNameList[i] = ifp->device_name;
return;
}
}
panic("too many devices");
}
static void
remove_from_device_name_list(struct ifnet* ifp)
{
int i;
for (i = 0; i < MAX_DEVICES; i++) {
if (ifp->device_name == gDeviceNameList[i]) {
int last;
for (last = i + 1; last < MAX_DEVICES; last++) {
if (gDeviceNameList[last] == NULL)
break;
}
last--;
if (i == last)
gDeviceNameList[i] = NULL;
else {
// switch positions with the last entry
gDeviceNameList[i] = gDeviceNameList[last];
gDeviceNameList[last] = NULL;
}
break;
}
}
}
struct ifnet *
if_alloc(u_char type)
{
char semName[64];
int i;
struct ifnet *ifp = _kernel_malloc(sizeof(struct ifnet), M_ZERO);
if (ifp == NULL)
@@ -50,9 +92,24 @@ if_alloc(u_char type)
ifp->link_state_sem = -1;
ifp->open_count = 0;
ifp->flags = 0;
ifp->if_type = type;
ifq_init(&ifp->receive_queue, semName);
ifp->if_type = type;
// Search for the first free device slot, and use that one
for (i = 0; i < MAX_DEVICES; i++) {
if (gDevices[i] == NULL) {
ifp->if_index = i;
gDevices[i] = ifp;
gDeviceCount++;
break;
}
}
if (i == MAX_DEVICES) {
panic("too many devices");
return NULL;
}
IF_ADDR_LOCK_INIT(ifp);
return ifp;
@@ -67,6 +124,11 @@ err1:
void
if_free(struct ifnet *ifp)
{
remove_from_device_name_list(ifp);
gDevices[ifp->if_index] = NULL;
gDeviceCount--;
IF_ADDR_LOCK_DESTROY(ifp);
if (ifp->if_type == IFT_ETHER)
_kernel_free(ifp->if_l2com);
@@ -83,15 +145,11 @@ if_initname(struct ifnet *ifp, const char *name, int unit)
{
dprintf("if_initname(%p, %s, %d)\n", ifp, name, unit);
if (name == NULL)
panic("interface goes unamed");
if (gDeviceCount >= MAX_DEVICES)
panic("unit too large");
if (name == NULL || name[0] == '\0')
panic("interface goes unnamed");
ifp->if_dname = name;
ifp->if_dunit = unit;
ifp->if_index = gDeviceCount++;
strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname));
@@ -100,8 +158,7 @@ if_initname(struct ifnet *ifp, const char *name, int unit)
driver_printf("%s: /dev/%s\n", gDriverName, ifp->device_name);
gDeviceNameList[ifp->if_index] = ifp->device_name;
gDevices[ifp->if_index] = ifp;
insert_into_device_name_list(ifp);
ifp->root_device = find_root_device(unit);
}