* 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, Hugo Santos. All Rights Reserved.
* Copyright 2007, Axel Dörfler, [email protected]. All Rights Reserved.
* Copyright 2004, Marcus Overhagen. All Rights Reserved. * Copyright 2004, Marcus Overhagen. All Rights Reserved.
* *
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@@ -28,12 +28,12 @@ compat_open(const char *name, uint32 flags, void **cookie)
struct ifreq ifr; struct ifreq ifr;
int i; int i;
for (i = 0; gDeviceNameList[i] != NULL; i++) { for (i = 0; i < MAX_DEVICES; i++) {
if (strcmp(gDeviceNameList[i], name) == 0) if (gDevices[i] != NULL && !strcmp(gDevices[i]->device_name, name))
break; break;
} }
if (gDeviceNameList[i] == NULL) if (i == MAX_DEVICES)
return B_ERROR; return B_ERROR;
if (get_module(NET_STACK_MODULE_NAME, (module_info **)&gStack) != B_OK) 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"); if_printf(ifp, "compat_free()\n");
/* TODO: empty out the send queue */ // TODO: empty out the send queue
atomic_and(&ifp->open_count, 0); atomic_and(&ifp->open_count, 0);
put_module(NET_STACK_MODULE_NAME); put_module(NET_STACK_MODULE_NAME);
@@ -161,7 +161,7 @@ compat_write(void *cookie, off_t position, const void *buffer,
if (mb == NULL) if (mb == NULL)
return ENOBUFS; 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); mb->m_pkthdr.len = mb->m_len = min_c(*numBytes, (size_t)MCLBYTES);
memcpy(mtod(mb, void *), buffer, mb->m_len); memcpy(mtod(mb, void *), buffer, mb->m_len);
+67 -10
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright 2007-2009, Axel Dörfler, [email protected].
* Copyright 2007, Hugo Santos. All Rights Reserved. * Copyright 2007, Hugo Santos. All Rights Reserved.
* Copyright 2007, Axel Dörfler, [email protected]. All Rights Reserved.
* Copyright 2004, Marcus Overhagen. All Rights Reserved. * Copyright 2004, Marcus Overhagen. All Rights Reserved.
* *
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@@ -24,10 +24,52 @@
#include <compat/net/ethernet.h> #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 * struct ifnet *
if_alloc(u_char type) if_alloc(u_char type)
{ {
char semName[64]; char semName[64];
int i;
struct ifnet *ifp = _kernel_malloc(sizeof(struct ifnet), M_ZERO); struct ifnet *ifp = _kernel_malloc(sizeof(struct ifnet), M_ZERO);
if (ifp == NULL) if (ifp == NULL)
@@ -50,9 +92,24 @@ if_alloc(u_char type)
ifp->link_state_sem = -1; ifp->link_state_sem = -1;
ifp->open_count = 0; ifp->open_count = 0;
ifp->flags = 0; ifp->flags = 0;
ifp->if_type = type;
ifq_init(&ifp->receive_queue, semName); 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); IF_ADDR_LOCK_INIT(ifp);
return ifp; return ifp;
@@ -67,6 +124,11 @@ err1:
void void
if_free(struct ifnet *ifp) if_free(struct ifnet *ifp)
{ {
remove_from_device_name_list(ifp);
gDevices[ifp->if_index] = NULL;
gDeviceCount--;
IF_ADDR_LOCK_DESTROY(ifp); IF_ADDR_LOCK_DESTROY(ifp);
if (ifp->if_type == IFT_ETHER) if (ifp->if_type == IFT_ETHER)
_kernel_free(ifp->if_l2com); _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); dprintf("if_initname(%p, %s, %d)\n", ifp, name, unit);
if (name == NULL) if (name == NULL || name[0] == '\0')
panic("interface goes unamed"); panic("interface goes unnamed");
if (gDeviceCount >= MAX_DEVICES)
panic("unit too large");
ifp->if_dname = name; ifp->if_dname = name;
ifp->if_dunit = unit; ifp->if_dunit = unit;
ifp->if_index = gDeviceCount++;
strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname)); 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); driver_printf("%s: /dev/%s\n", gDriverName, ifp->device_name);
gDeviceNameList[ifp->if_index] = ifp->device_name; insert_into_device_name_list(ifp);
gDevices[ifp->if_index] = ifp;
ifp->root_device = find_root_device(unit); ifp->root_device = find_root_device(unit);
} }