===== lib/idr.c 1.10 vs edited ===== --- 1.10/lib/idr.c 2004-08-23 16:14:51 +08:00 +++ edited/lib/idr.c 2004-09-17 15:53:47 +08:00 @@ -39,8 +39,10 @@ static struct idr_layer *alloc_layer(str struct idr_layer *p; spin_lock(&idp->lock); - if (!(p = idp->id_free)) + if (!(p = idp->id_free)) { + spin_unlock(&idp->lock); return NULL; + } idp->id_free = p->ary[0]; idp->id_free_cnt--; p->ary[0] = NULL; ===== include/linux/netdevice.h 1.89 vs edited ===== --- 1.89/include/linux/netdevice.h 2004-09-13 07:52:49 +08:00 +++ edited/include/linux/netdevice.h 2004-09-17 15:54:41 +08:00 @@ -154,6 +154,7 @@ enum { #include #include +#include struct neighbour; struct neigh_parms; @@ -503,6 +504,16 @@ static inline void *netdev_priv(struct n * if set prior to registration will cause a symlink during initialization. */ #define SET_NETDEV_DEV(net, pdev) ((net)->class_dev.dev = (pdev)) + +struct net_boards { + struct idr idr; + int max_boards; + spinlock_t lock; +}; + +void net_boards_init(struct net_boards *board, int max_boards); +int net_boards_alloc(struct net_boards *board); +int net_boards_free(struct net_boards *board, int board_no); struct packet_type { unsigned short type; /* This is really htons(ether_type). */ ===== net/core/dev.c 1.165 vs edited ===== --- 1.165/net/core/dev.c 2004-09-13 07:23:46 +08:00 +++ edited/net/core/dev.c 2004-09-17 15:52:43 +08:00 @@ -3220,6 +3220,53 @@ static int dev_cpu_callback(struct notif } #endif /* CONFIG_HOTPLUG_CPU */ +void net_boards_init(struct net_boards *board, int max_boards) +{ + if (!board || (max_boards < 0)) + return; + idr_init(&board->idr); + board->max_boards = max_boards; + spin_lock_init(&board->lock); +} + +/* + * return -1 on error, >= 0 on success + */ +int net_boards_alloc(struct net_boards *board) +{ + int ret, error; + + if (!board) + return -1; +retry: + if (idr_pre_get(&board->idr, GFP_KERNEL) == 0) + return -1; + + spin_lock(&board->lock); + error = idr_get_new(&board->idr, NULL, &ret); + spin_unlock(&board->lock); + if (error == -EAGAIN) + goto retry; + else if (error) + return -1; + if (ret > board->max_boards) { + spin_lock(&board->lock); + idr_remove(&board->idr, ret); + spin_unlock(&board->lock); + return -1; + } + return ret; +} + +int net_boards_free(struct net_boards *board, int board_no) +{ + if ((board_no < 0) || (board_no > board->max_boards)) + return -1; + spin_lock(&board->lock); + idr_remove(&board->idr, board_no); + spin_unlock(&board->lock); + return 0; +} /* * Initialize the DEV module. At boot time this walks the device list and @@ -3296,6 +3343,9 @@ out: subsys_initcall(net_dev_init); +EXPORT_SYMBOL(net_boards_init); +EXPORT_SYMBOL(net_boards_alloc); +EXPORT_SYMBOL(net_boards_free); EXPORT_SYMBOL(__dev_get); EXPORT_SYMBOL(__dev_get_by_flags); EXPORT_SYMBOL(__dev_get_by_index);