patch-2.4.0-test2 linux/net/core/dev.c
Next file: linux/net/core/profile.c
Previous file: linux/net/bridge/br_stp.c
Back to the patch index
Back to the overall index
- Lines: 162
- Date:
Tue Jun 20 14:32:27 2000
- Orig file:
v2.4.0-test1/linux/net/core/dev.c
- Orig date:
Tue May 23 15:31:37 2000
diff -u --recursive --new-file v2.4.0-test1/linux/net/core/dev.c linux/net/core/dev.c
@@ -17,6 +17,7 @@
* David Hinds <dhinds@allegro.stanford.edu>
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
* Adam Sulmicki <adam@cfar.umd.edu>
+ * Pekka Riikonen <priikone@poesidon.pspt.fi>
*
* Changes:
* Alan Cox : device private ioctl copies fields back.
@@ -56,6 +57,7 @@
* A network device unload needs to purge
* the backlog queue.
* Paul Rusty Russell : SIOCSIFNAME
+ * Pekka Riikonen : Netdev boot-time settings code
*/
#include <asm/uaccess.h>
@@ -249,6 +251,120 @@
printk(KERN_WARNING "dev_remove_pack: %p not found.\n", pt);
}
+/******************************************************************************
+
+ Device Boot-time Settings Routines
+
+*******************************************************************************/
+
+/* Boot time configuration table */
+struct netdev_boot_setup dev_boot_setup[NETDEV_BOOT_SETUP_MAX];
+
+/**
+ * netdev_boot_setup_add - add new setup entry
+ * @name: name of the device
+ * @map: configured settings for the device
+ *
+ * Adds new setup entry to the dev_boot_setup list. The function
+ * returns 0 on error and 1 on success. This is a generic routine to
+ * all netdevices.
+ */
+int netdev_boot_setup_add(char *name, struct ifmap *map)
+{
+ struct netdev_boot_setup *s;
+ int i;
+
+ s = dev_boot_setup;
+ for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
+ if (s[i].name[0] == '\0' || s[i].name[0] == ' ') {
+ memset(s[i].name, 0, sizeof(s[i].name));
+ strcpy(s[i].name, name);
+ memcpy(&s[i].map, map, sizeof(s[i].map));
+ break;
+ }
+ }
+
+ if (i >= NETDEV_BOOT_SETUP_MAX)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * netdev_boot_setup_check - check boot time settings
+ * @dev: the netdevice
+ *
+ * Check boot time settings for the device. If device's name is a
+ * mask (eg. eth%d) and settings are found then this will allocate
+ * name for the device. The found settings are set for the device
+ * to be used later in the device probing. Returns 0 if no settings
+ * found, 1 if they are.
+ */
+int netdev_boot_setup_check(struct net_device *dev)
+{
+ struct netdev_boot_setup *s;
+ char buf[IFNAMSIZ + 1];
+ int i, mask = 0;
+
+ memset(buf, 0, sizeof(buf));
+ strcpy(buf, dev->name);
+ if (strchr(dev->name, '%')) {
+ *strchr(buf, '%') = '\0';
+ mask = 1;
+ }
+
+ s = dev_boot_setup;
+ for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
+ if (s[i].name[0] != '\0' && s[i].name[0] != ' ' &&
+ !strncmp(buf, s[i].name, mask ? strlen(buf) :
+ strlen(s[i].name))) {
+ if (__dev_get_by_name(s[i].name)) {
+ if (!mask)
+ return 0;
+ continue;
+ }
+ memset(dev->name, 0, IFNAMSIZ);
+ strcpy(dev->name, s[i].name);
+ dev->irq = s[i].map.irq;
+ dev->base_addr = s[i].map.base_addr;
+ dev->mem_start = s[i].map.mem_start;
+ dev->mem_end = s[i].map.mem_end;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Saves at boot time configured settings for any netdevice.
+ */
+static int __init netdev_boot_setup(char *str)
+{
+ int ints[5];
+ struct ifmap map;
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+ if (!str || !*str)
+ return 0;
+
+ /* Save settings */
+ memset(&map, -1, sizeof(map));
+ if (ints[0] > 0)
+ map.irq = ints[1];
+ if (ints[0] > 1)
+ map.base_addr = ints[2];
+ if (ints[0] > 2)
+ map.mem_start = ints[3];
+ if (ints[0] > 3)
+ map.mem_end = ints[4];
+
+ /* Add new entry to the list */
+ return netdev_boot_setup_add(str, &map);
+}
+
+__setup("netdev=", netdev_boot_setup);
+
/*****************************************************************************************
Device Interface Subroutines
@@ -2364,12 +2480,19 @@
dev->xmit_lock_owner = -1;
dev->iflink = -1;
dev_hold(dev);
- /*
- * We can allocate the name ahead of time. If the
- * init fails the name will be reissued correctly.
+
+ /*
+ * Check boot time settings for the device.
*/
- if (strchr(dev->name, '%'))
- dev_alloc_name(dev, dev->name);
+ if (!netdev_boot_setup_check(dev)) {
+ /*
+ * No settings found - allocate name. If the init()
+ * fails the name will be reissued correctly.
+ */
+ if (strchr(dev->name, '%'))
+ dev_alloc_name(dev, dev->name);
+ }
+
if (dev->init && dev->init(dev)) {
/*
* It failed to come up. Unhook it.
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)