* 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:
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user