patch-2.0.14 linux/drivers/net/depca.c
Next file: linux/drivers/net/ewrk3.c
Previous file: linux/drivers/net/de4x5.h
Back to the patch index
Back to the overall index
- Lines: 311
- Date:
Tue Aug 20 08:45:26 1996
- Orig file:
v2.0.13/linux/drivers/net/depca.c
- Orig date:
Mon Apr 29 17:11:39 1996
diff -u --recursive --new-file v2.0.13/linux/drivers/net/depca.c linux/drivers/net/depca.c
@@ -202,11 +202,13 @@
Add new multicasting code.
0.421 22-Apr-96 Fix alloc_device() bug <jari@markkus2.fimr.fi>
0.422 29-Apr-96 Fix depca_hw_init() bug <jari@markkus2.fimr.fi>
+ 0.423 7-Jun-96 Fix module load bug <kmg@barco.be>
+ 0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c
=========================================================================
*/
-static const char *version = "depca.c:v0.422 96/4/29 davies@wanton.lkg.dec.com\n";
+static const char *version = "depca.c:v0.43 96/8/16 davies@wanton.lkg.dec.com\n";
#include <linux/module.h>
@@ -231,6 +233,7 @@
#include <linux/time.h>
#include <linux/types.h>
#include <linux/unistd.h>
+#include <linux/ctype.h>
#include "depca.h"
@@ -407,6 +410,8 @@
static void isa_probe(struct device *dev, u_long iobase);
static void eisa_probe(struct device *dev, u_long iobase);
static struct device *alloc_device(struct device *dev, u_long iobase);
+static int depca_dev_index(char *s);
+static struct device *insert_device(struct device *dev, u_long iobase, int (*init)(struct device *));
static int load_packet(struct device *dev, struct sk_buff *skb);
static void depca_dbg_open(struct device *dev);
@@ -483,22 +488,13 @@
outb(nicsr, DEPCA_NICSR);
if (inw(DEPCA_DATA) == STOP) {
- if (mem == 0) {
- while (mem_base[mem_chkd]) {
- mem_start = mem_base[mem_chkd++];
- DepcaSignature(name, mem_start);
- if (*name != '\0') break;
- }
- } else {
- mem_start = mem;
- if (adapter_name) {
- strcpy(name, adapter_name);
- } else{
- DepcaSignature(name, mem_start);
- }
- }
+ do {
+ strcpy(name, (adapter_name ? adapter_name : ""));
+ mem_start = (mem ? mem & 0xf0000 : mem_base[mem_chkd++]);
+ DepcaSignature(name, mem_start);
+ } while (!mem && mem_base[mem_chkd] && (adapter == unknown));
- if ((*name != '\0') && mem_start) { /* found a DEPCA device */
+ if ((adapter != unknown) && mem_start) { /* found a DEPCA device */
dev->base_addr = ioaddr;
if ((ioaddr&0x0fff)==DEPCA_EISA_IO_PORTS) {/* EISA slot address */
@@ -650,6 +646,8 @@
printk(" which has an Ethernet PROM CRC error.\n");
status = -ENXIO;
}
+ } else {
+ status = -ENXIO;
}
if (!status) {
if (depca_debug > 0) {
@@ -1290,113 +1288,95 @@
}
/*
-** Allocate the device by pointing to the next available space in the
-** device structure. Should one not be available, it is created.
+** Search the entire 'eth' device list for a fixed probe. If a match isn't
+** found then check for an autoprobe or unused device location. If they
+** are not available then insert a new device structure at the end of
+** the current list.
*/
-static struct device *alloc_device(struct device *dev, u_long iobase)
+static struct device *
+alloc_device(struct device *dev, u_long iobase)
{
- int addAutoProbe = 0;
- struct device *tmp = NULL, *ret;
- int (*init)(struct device *) = NULL;
+ struct device *adev = NULL;
+ int fixed = 0, new_dev = 0;
- /*
- ** Check the device structures for an end of list or unused device
- */
- if (!loading_module) {
- while (dev->next != NULL) {
- if ((dev->base_addr == DEPCA_NDA) || (dev->base_addr == 0)) break;
- dev = dev->next; /* walk through eth device list */
- num_eth++; /* increment eth device number */
+ num_eth = depca_dev_index(dev->name);
+ if (loading_module) return dev;
+
+ while (1) {
+ if (((dev->base_addr == DEPCA_NDA) || (dev->base_addr==0)) && !adev) {
+ adev=dev;
+ } else if ((dev->priv == NULL) && (dev->base_addr==iobase)) {
+ fixed = 1;
+ } else {
+ if (dev->next == NULL) {
+ new_dev = 1;
+ } else if (strncmp(dev->next->name, "eth", 3) != 0) {
+ new_dev = 1;
+ }
+ }
+ if ((dev->next == NULL) || new_dev || fixed) break;
+ dev = dev->next;
+ num_eth++;
+ }
+ if (adev && !fixed) {
+ dev = adev;
+ num_eth = depca_dev_index(dev->name);
+ new_dev = 0;
}
- /*
- ** If an autoprobe is requested for another device, we must re-insert
- ** the request later in the list. Remember the current information.
- */
- if ((dev->base_addr == 0) && (num_depcas > 0)) {
- addAutoProbe++;
- tmp = dev->next; /* point to the next device */
- init = dev->init; /* remember the probe function */
+ if (((dev->next == NULL) &&
+ ((dev->base_addr != DEPCA_NDA) && (dev->base_addr != 0)) && !fixed) ||
+ new_dev) {
+ num_eth++; /* New device */
+ dev = insert_device(dev, iobase, depca_probe);
}
+
+ return dev;
+}
- /*
- ** If at end of list and can't use current entry, malloc one up.
- ** If memory could not be allocated, print an error message.
- */
- if ((dev->next == NULL) &&
- !((dev->base_addr == DEPCA_NDA) || (dev->base_addr == 0))){
- dev->next = (struct device *)kmalloc(sizeof(struct device) + 8,
- GFP_KERNEL);
-
- dev = dev->next; /* point to the new device */
- if (dev == NULL) {
- printk("eth%d: Device not initialised, insufficient memory\n",
- num_eth);
- } else {
- /*
- ** If the memory was allocated, point to the new memory area
- ** and initialize it (name, I/O address, next device (NULL) and
- ** initialisation probe routine).
- */
+/*
+** If at end of eth device list and can't use current entry, malloc
+** one up. If memory could not be allocated, print an error message.
+*/
+static struct device *
+insert_device(struct device *dev, u_long iobase, int (*init)(struct device *))
+{
+ struct device *new;
+
+ new = (struct device *)kmalloc(sizeof(struct device)+8, GFP_KERNEL);
+ if (new == NULL) {
+ printk("eth%d: Device not initialised, insufficient memory\n",num_eth);
+ return NULL;
+ } else {
+ new->next = dev->next;
+ dev->next = new;
+ dev = dev->next; /* point to the new device */
dev->name = (char *)(dev + 1);
if (num_eth > 9999) {
- sprintf(dev->name,"eth????"); /* New device name */
+ sprintf(dev->name,"eth????");/* New device name */
} else {
- sprintf(dev->name,"eth%d", num_eth);/* New device name */
+ sprintf(dev->name,"eth%d", num_eth);/* New device name */
}
- dev->base_addr = iobase; /* assign the io address */
- dev->next = NULL; /* mark the end of list */
- dev->init = &depca_probe; /* initialisation routine */
- num_depcas++;
- }
+ dev->base_addr = iobase; /* assign the io address */
+ dev->init = init; /* initialisation routine */
}
- ret = dev; /* return current struct, or NULL */
-
- /*
- ** Now figure out what to do with the autoprobe that has to be inserted.
- ** Firstly, search the (possibly altered) list for an empty space.
- */
- if (ret != NULL) {
- if (addAutoProbe) {
- for (;(tmp->next!=NULL) && (tmp->base_addr!=DEPCA_NDA); tmp=tmp->next);
-
- /*
- ** If no more device structures and can't use the current one, malloc
- ** one up. If memory could not be allocated, print an error message.
- */
- if ((tmp->next == NULL) && !(tmp->base_addr == DEPCA_NDA)) {
- tmp->next = (struct device *)kmalloc(sizeof(struct device) + 8,
- GFP_KERNEL);
- tmp = tmp->next; /* point to the new device */
- if (tmp == NULL) {
- printk("%s: Insufficient memory to extend the device list.\n",
- dev->name);
- } else {
- /*
- ** If the memory was allocated, point to the new memory area
- ** and initialize it (name, I/O address, next device (NULL) and
- ** initialisation probe routine).
- */
- tmp->name = (char *)(tmp + 1);
- if (num_eth > 9999) {
- sprintf(tmp->name,"eth????"); /* New device name */
- } else {
- sprintf(tmp->name,"eth%d", num_eth);/* New device name */
- }
- tmp->base_addr = 0; /* re-insert the io address */
- tmp->next = NULL; /* mark the end of list */
- tmp->init = init; /* initialisation routine */
- }
- } else { /* structure already exists */
- tmp->base_addr = 0; /* re-insert the io address */
- }
- }
+
+ return dev;
+}
+
+static int
+depca_dev_index(char *s)
+{
+ int i=0, j=0;
+
+ for (;*s; s++) {
+ if (isdigit(*s)) {
+ j=1;
+ i = (i * 10) + (*s - '0');
+ } else if (j) break;
}
- } else {
- ret = dev;
- }
- return ret;
+ return i;
}
/*
@@ -1410,12 +1390,13 @@
const char *signatures[] = DEPCA_SIGNATURE;
char tmpstr[16];
- for (i=0;i<16;i++) { /* copy the first 16 bytes of ROM to */
- tmpstr[i] = readb(paddr+0xc000+i); /* a temporary string */
+ /* Copy the first 16 bytes of ROM */
+ for (i=0;i<16;i++) {
+ tmpstr[i] = readb(paddr+0xc000+i);
}
- strcpy(name,"");
- for (i=0;*signatures[i]!='\0' && *name=='\0';i++) {
+ /* Check if PROM contains a valid string */
+ for (i=0;*signatures[i]!='\0';i++) {
for (j=0,k=0;j<16 && k<strlen(signatures[i]);j++) {
if (signatures[i][k] == tmpstr[j]) { /* track signature */
k++;
@@ -1423,12 +1404,19 @@
k=0;
}
}
- if (k == strlen(signatures[i])) {
- strcpy(name,signatures[i]);
+ if (k == strlen(signatures[i])) break;
+ }
+
+ /* Check if name string is valid, provided there's no PROM */
+ if (*name && (i == unknown)) {
+ for (i=0;*signatures[i]!='\0';i++) {
+ if (strcmp(name,signatures[i]) == 0) break;
}
}
- adapter = i - 1;
+ /* Update search results */
+ strcpy(name,signatures[i]);
+ adapter = i;
return;
}
@@ -1896,8 +1884,8 @@
/*
* Local variables:
- * kernel-compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -m486 -c depca.c"
+ * compile-command: "gcc -D__KERNEL__ -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c depca.c"
*
- * module-compile-command: "gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -m486 -c depca.c"
+ * compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c depca.c"
* End:
*/
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov