patch-1.3.28 linux/drivers/net/plip.c
Next file: linux/drivers/net/ppp.c
Previous file: linux/drivers/net/eexpress.c
Back to the patch index
Back to the overall index
- Lines: 223
- Date:
Mon Sep 18 08:24:53 1995
- Orig file:
v1.3.27/linux/drivers/net/plip.c
- Orig date:
Sat Sep 9 15:26:52 1995
diff -u --recursive --new-file v1.3.27/linux/drivers/net/plip.c linux/drivers/net/plip.c
@@ -1,4 +1,4 @@
-/* $Id: plip.c,v 1.12 1995/02/11 10:26:05 gniibe Exp $ */
+/* $Id: plip.c,v 1.14 1995/09/18 04:57:24 gniibe Exp $ */
/* PLIP: A parallel port "network" driver for Linux. */
/* This driver is for parallel port with 5-bit cable (LapLink (R) cable). */
/*
@@ -12,6 +12,19 @@
* Modularization and ifreq/ifmap support by Alan Cox.
* Rewritten by Niibe Yutaka.
*
+ * Fixes:
+ * 9-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
+ * - only claim 3 bytes of I/O space for port at 0x3bc
+ * - treat NULL return from register_netdev() as success in
+ * init_module()
+ * - added message if driver loaded as a module but no
+ * interfaces present.
+ * - release claimed I/O ports if malloc() fails during init.
+ *
+ * Niibe Yutaka
+ * - Module initialization. You can specify I/O addr and IRQ:
+ * # insmod plip.o io=0x3bc irq=7
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
@@ -32,7 +45,7 @@
* So, this PLIP can't communicate the PLIP of Linux v1.0.
*/
-static const char *version = "NET3 PLIP version 2.0 gniibe@mri.co.jp\n";
+static const char *version = "NET3 PLIP version 2.1 gniibe@mri.co.jp\n";
/*
Sources:
@@ -205,9 +218,10 @@
plip_init(struct device *dev)
{
struct net_local *nl;
+ int iosize = (PAR_DATA(dev) == 0x3bc) ? 3 : 8;
/* Check region before the probe */
- if (check_region(PAR_DATA(dev), (PAR_DATA(dev) == 0x3bc)? 4 : 8) < 0)
+ if (check_region(PAR_DATA(dev), iosize) < 0)
return -ENODEV;
/* Check that there is something at base_addr. */
@@ -244,7 +258,7 @@
" Please set IRQ by ifconfig.\n", irq);
}
- request_region(PAR_DATA(dev), (PAR_DATA(dev) == 0x3bc)? 4 : 8, dev->name);
+ request_region(PAR_DATA(dev), iosize, dev->name);
/* Fill in the generic fields of the device structure. */
ether_setup(dev);
@@ -260,8 +274,11 @@
/* Set the private structure */
dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL);
- if (dev->priv == NULL)
+ if (dev->priv == NULL) {
+ printk(KERN_ERR "%s: out of memory\n", dev->name);
+ release_region(PAR_DATA(dev), iosize);
return -ENOMEM;
+ }
memset(dev->priv, 0, sizeof(struct net_local));
nl = (struct net_local *) dev->priv;
@@ -467,12 +484,10 @@
outb(0x00, --status_addr); /* send ACK */
status_addr++;
*ns_p = PLIP_NB_BEGIN;
- return OK;
-
case PLIP_NB_2:
break;
}
- return TIMEOUT; /* XX: ?? */
+ return OK;
}
/* PLIP_RECEIVE_PACKET --- receive a packet */
@@ -634,7 +649,7 @@
*ns_p = PLIP_NB_BEGIN;
return OK;
}
- return TIMEOUT;
+ return OK;
}
/* PLIP_SEND_PACKET --- send a packet */
@@ -1036,67 +1051,84 @@
#ifdef MODULE
char kernel_version[] = UTS_RELEASE;
+int io[] = {0, 0, 0};
+int irq[] = {0, 0, 0};
-static struct device dev_plip0 =
-{
- "plip0" /*"plip"*/,
- 0, 0, 0, 0, /* memory */
- 0x3BC, 5, /* base, irq */
- 0, 0, 0, NULL, plip_init
-};
-
-static struct device dev_plip1 =
-{
- "plip1" /*"plip"*/,
- 0, 0, 0, 0, /* memory */
- 0x378, 7, /* base, irq */
- 0, 0, 0, NULL, plip_init
-};
-
-static struct device dev_plip2 =
-{
- "plip2" /*"plip"*/,
- 0, 0, 0, 0, /* memory */
- 0x278, 2, /* base, irq */
- 0, 0, 0, NULL, plip_init
+static struct device dev_plip[] = {
+ {
+ "plip0",
+ 0, 0, 0, 0, /* memory */
+ 0x3BC, 5, /* base, irq */
+ 0, 0, 0, NULL, plip_init
+ },
+ {
+ "plip1",
+ 0, 0, 0, 0, /* memory */
+ 0x378, 7, /* base, irq */
+ 0, 0, 0, NULL, plip_init
+ },
+ {
+ "plip2",
+ 0, 0, 0, 0, /* memory */
+ 0x278, 2, /* base, irq */
+ 0, 0, 0, NULL, plip_init
+ }
};
int
init_module(void)
{
+ int no_parameters=1;
int devices=0;
+ int i;
+
+ /* When user feeds parameters, use them */
+ for (i=0; i < 3; i++) {
+ int specified=0;
+
+ if (io[i] != 0) {
+ dev_plip[i].base_addr = io[i];
+ specified++;
+ }
+ if (irq[i] != 0) {
+ dev_plip[i].irq = irq[i];
+ specified++;
+ }
+ if (specified) {
+ if (register_netdev(&dev_plip[i]) != 0) {
+ printk(KERN_INFO "plip%d: Not found\n", i);
+ return -EIO;
+ }
+ no_parameters = 0;
+ }
+ }
+ if (!no_parameters)
+ return 0;
- if (register_netdev(&dev_plip0) != 0)
- devices++;
- if (register_netdev(&dev_plip1) != 0)
- devices++;
- if (register_netdev(&dev_plip2) != 0)
- devices++;
- if (devices == 0)
+ /* No parameters. Default action is probing all interfaces. */
+ for (i=0; i < 3; i++) {
+ if (register_netdev(&dev_plip[i]) == 0)
+ devices++;
+ }
+ if (devices == 0) {
+ printk(KERN_INFO "plip: no interfaces found\n");
return -EIO;
+ }
return 0;
}
void
cleanup_module(void)
{
- if (dev_plip0.priv) {
- unregister_netdev(&dev_plip0);
- release_region(PAR_DATA(&dev_plip0), (PAR_DATA(&dev_plip0) == 0x3bc)? 4 : 8);
- kfree_s(dev_plip0.priv, sizeof(struct net_local));
- dev_plip0.priv = NULL;
- }
- if (dev_plip1.priv) {
- unregister_netdev(&dev_plip1);
- release_region(PAR_DATA(&dev_plip1), (PAR_DATA(&dev_plip1) == 0x3bc)? 4 : 8);
- kfree_s(dev_plip1.priv, sizeof(struct net_local));
- dev_plip1.priv = NULL;
- }
- if (dev_plip2.priv) {
- unregister_netdev(&dev_plip2);
- release_region(PAR_DATA(&dev_plip2), (PAR_DATA(&dev_plip2) == 0x3bc)? 4 : 8);
- kfree_s(dev_plip2.priv, sizeof(struct net_local));
- dev_plip2.priv = NULL;
+ int i;
+
+ for (i=0; i < 3; i++) {
+ if (dev_plip[i].priv) {
+ unregister_netdev(&dev_plip[i]);
+ release_region(PAR_DATA(&dev_plip[i]), (PAR_DATA(&dev_plip[i]) == 0x3bc)? 3 : 8);
+ kfree_s(dev_plip[i].priv, sizeof(struct net_local));
+ dev_plip[i].priv = NULL;
+ }
}
}
#endif /* MODULE */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this