patch-1.3.53 linux/drivers/net/skeleton.c
Next file: linux/drivers/scsi/aha1740.c
Previous file: linux/drivers/net/pt.c
Back to the patch index
Back to the overall index
- Lines: 485
- Date:
Sat Dec 30 21:00:40 1995
- Orig file:
v1.3.52/linux/drivers/net/skeleton.c
- Orig date:
Sat Nov 25 19:04:46 1995
diff -u --recursive --new-file v1.3.52/linux/drivers/net/skeleton.c linux/drivers/net/skeleton.c
@@ -1,43 +1,43 @@
-/* skeleton.c: A network driver outline for linux. */
-/*
- Written 1993-94 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- The author may be reached as [email protected], or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- This file is an outline for writing a network device driver for the
- the Linux operating system.
-
- To write (or understand) a driver, have a look at the "loopback.c" file to
- get a feel of what is going on, and then use the code below as a skeleton
- for the new driver.
-
-*/
+/* skeleton.c: A network driver outline for linux.
+ *
+ * Written 1993-94 by Donald Becker.
+ *
+ * Copyright 1993 United States Government as represented by the
+ * Director, National Security Agency.
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License, incorporated herein by reference.
+ *
+ * The author may be reached as [email protected], or C/O
+ * Center of Excellence in Space Data and Information Sciences
+ * Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
+ *
+ * This file is an outline for writing a network device driver for the
+ * the Linux operating system.
+ *
+ * To write (or understand) a driver, have a look at the "loopback.c" file to
+ * get a feel of what is going on, and then use the code below as a skeleton
+ * for the new driver.
+ *
+ */
static const char *version =
"skeleton.c:v1.51 9/24/94 Donald Becker ([email protected])\n";
/*
- Sources:
- List your sources of programming information to document that
- the driver is your own creation, and give due credit to others
- that contributed to the work. Remember that GNU project code
- cannot use proprietary or trade secret information. Interface
- definitions are generally considered non-copyrightable to the
- extent that the same names and structures must be used to be
- compatible.
-
- Finally, keep in mind that the Linux kernel is has an API, not
- ABI. Proprietary object-code-only distributions are not permitted
- under the GPL.
-*/
+ * Sources:
+ * List your sources of programming information to document that
+ * the driver is your own creation, and give due credit to others
+ * that contributed to the work. Remember that GNU project code
+ * cannot use proprietary or trade secret information. Interface
+ * definitions are generally considered non-copyrightable to the
+ * extent that the same names and structures must be used to be
+ * compatible.
+ *
+ * Finally, keep in mind that the Linux kernel is has an API, not
+ * ABI. Proprietary object-code-only distributions are not permitted
+ * under the GPL.
+ */
#include <linux/module.h>
@@ -61,12 +61,14 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-/* The name of the card. Is used for messages and in the requests for
+/*
+ * The name of the card. Is used for messages and in the requests for
* io regions, irqs and dma channels
*/
static const char* cardname = "netcard";
/* First, a few definitions that the brave might change. */
+
/* A zero-terminated list of I/O addresses to be probed. */
static unsigned int netcard_portlist[] =
{ 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
@@ -83,7 +85,7 @@
/* Information that need to be kept for each board. */
struct net_local {
struct enet_statistics stats;
- long open_time; /* Useless example local info. */
+ long open_time; /* Useless example local info. */
};
/* The station (ethernet) address prefix, used for IDing the board. */
@@ -109,16 +111,18 @@
extern void hardware_send_packet(short ioaddr, char *buf, int length);
extern void chipset_init(struct device *dev, int startp);
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, allocate space for the device and return success
- (detachable devices only).
- */
+/*
+ * Check for a network adaptor of this type, and return '0' iff one exists.
+ * If dev->base_addr == 0, probe all likely locations.
+ * If dev->base_addr == 1, always return failure.
+ * If dev->base_addr == 2, allocate space for the device and return success
+ * (detachable devices only).
+ */
#ifdef HAVE_DEVLIST
-/* Support for a alternate probe manager, which will eliminate the
- boilerplate below. */
+/*
+ * Support for a alternate probe manager,
+ * which will eliminate the boilerplate below.
+ */
struct netdev_entry netcard_drv =
{cardname, netcard_probe1, NETCARD_IO_EXTENT, netcard_portlist};
#else
@@ -128,9 +132,9 @@
int i;
int base_addr = dev ? dev->base_addr : 0;
- if (base_addr > 0x1ff) /* Check a single specified location. */
+ if (base_addr > 0x1ff) /* Check a single specified location. */
return netcard_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
+ else if (base_addr != 0) /* Don't probe at all. */
return -ENXIO;
for (i = 0; netcard_portlist[i]; i++) {
@@ -145,18 +149,21 @@
}
#endif
-/* This is the real probe routine. Linux has a history of friendly device
- probes on the ISA bus. A good device probes avoids doing writes, and
- verifies that the correct device exists and functions. */
-
+/*
+ * This is the real probe routine. Linux has a history of friendly device
+ * probes on the ISA bus. A good device probes avoids doing writes, and
+ * verifies that the correct device exists and functions.
+ */
static int netcard_probe1(struct device *dev, int ioaddr)
{
static unsigned version_printed = 0;
int i;
- /* For ethernet adaptors the first three octets of the station address
- contains the manufacturer's unique code. That might be a good probe
- method. Ideally you would add additional checks. */
+ /*
+ * For ethernet adaptors the first three octets of the station address
+ * contains the manufacturer's unique code. That might be a good probe
+ * method. Ideally you would add additional checks.
+ */
if (inb(ioaddr + 0) != SA_ADDR0
|| inb(ioaddr + 1) != SA_ADDR1
|| inb(ioaddr + 2) != SA_ADDR2) {
@@ -165,7 +172,8 @@
/* Allocate a new 'dev' if needed. */
if (dev == NULL) {
- /* Don't allocate the private data here, it is done later
+ /*
+ * Don't allocate the private data here, it is done later
* This makes it easier to free the memory when this driver
* is used as a module.
*/
@@ -187,14 +195,16 @@
printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
#ifdef jumpered_interrupts
- /* If this board has jumpered interrupts, snarf the interrupt vector
- now. There is no point in waiting since no other device can use
- the interrupt, and this marks the irq as busy.
- Jumpered interrupts are typically not reported by the boards, and
- we must used autoIRQ to find them. */
+ /*
+ * If this board has jumpered interrupts, allocate the interrupt
+ * vector now. There is no point in waiting since no other device
+ * can use the interrupt, and this marks the irq as busy. Jumpered
+ * interrupts are typically not reported by the boards, and we must
+ * used autoIRQ to find them.
+ */
if (dev->irq == -1)
- ; /* Do nothing: a user-level program will set it. */
+ ; /* Do nothing: a user-level program will set it. */
else if (dev->irq < 2) { /* "Auto-IRQ" */
autoirq_setup(0);
/* Trigger an interrupt here. */
@@ -203,8 +213,9 @@
if (net_debug >= 2)
printk(" autoirq is %d", dev->irq);
} else if (dev->irq == 2)
- /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
- * or don't know which one to set.
+ /*
+ * Fixup for users that don't know that IRQ 2 is really
+ * IRQ9, or don't know which one to set.
*/
dev->irq = 9;
@@ -218,8 +229,10 @@
}
#endif /* jumpered interrupt */
#ifdef jumpered_dma
- /* If we use a jumpered DMA channel, that should be probed for and
- allocated here as well. See lance.c for an example. */
+ /*
+ * If we use a jumpered DMA channel, that should be probed for and
+ * allocated here as well. See lance.c for an example.
+ */
if (dev->dma == 0) {
if (request_dma(dev->dma, cardname)) {
printk("DMA %d allocation failed.\n", dev->dma);
@@ -237,7 +250,10 @@
/* Re-read the DMA status registers. */
new_dma_status = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
(inb(DMA2_STAT_REG) & 0xf0);
- /* Eliminate the old and floating requests and DMA4, the cascade. */
+ /*
+ * Eliminate the old and floating requests,
+ * and DMA4 the cascade.
+ */
new_dma_status ^= dma_status;
new_dma_status &= ~0x10;
for (i = 7; i > 0; i--)
@@ -280,34 +296,37 @@
return 0;
}
-
-/* Open/initialize the board. This is called (in the current kernel)
- sometime after booting when the 'ifconfig' program is run.
-
- This routine should set everything up anew at each open, even
- registers that "should" only need to be set once at boot, so that
- there is non-reboot way to recover if something goes wrong.
- */
+/*
+ * Open/initialize the board. This is called (in the current kernel)
+ * sometime after booting when the 'ifconfig' program is run.
+ *
+ * This routine should set everything up anew at each open, even
+ * registers that "should" only need to be set once at boot, so that
+ * there is non-reboot way to recover if something goes wrong.
+ */
static int
net_open(struct device *dev)
{
struct net_local *lp = (struct net_local *)dev->priv;
int ioaddr = dev->base_addr;
-
- /* This is used if the interrupt line can turned off (shared).
- See 3c503.c for an example of selecting the IRQ at config-time. */
+ /*
+ * This is used if the interrupt line can turned off (shared).
+ * See 3c503.c for an example of selecting the IRQ at config-time.
+ */
if (request_irq(dev->irq, &net_interrupt, 0, cardname)) {
return -EAGAIN;
}
-
- /* Always snarf the DMA channel after the IRQ, and clean up on failure. */
+ /*
+ * Always allocate the DMA channel after the IRQ,
+ * and clean up on failure.
+ */
if (request_dma(dev->dma, cardname)) {
free_irq(dev->irq);
return -EAGAIN;
}
irq2dev_map[dev->irq] = dev;
- /* Reset the hardware here. Don't forget to set the station address. */
+ /* Reset the hardware here. Don't forget to set the station address. */
/*chipset_init(dev, 1);*/
outb(0x00, ioaddr);
lp->open_time = jiffies;
@@ -328,8 +347,10 @@
int ioaddr = dev->base_addr;
if (dev->tbusy) {
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
+ /*
+ * If we get here, some higher level has decided we are broken.
+ * There should really be a "kick me" function call instead.
+ */
int tickssofar = jiffies - dev->trans_start;
if (tickssofar < 5)
return 1;
@@ -340,17 +361,19 @@
dev->tbusy=0;
dev->trans_start = jiffies;
}
-
- /* If some higher layer thinks we've missed an tx-done interrupt
- we are passed NULL. Caution: dev_tint() handles the cli()/sti()
- itself. */
+ /*
+ * If some higher layer thinks we've missed an tx-done interrupt
+ * we are passed NULL. Caution: dev_tint() handles the cli()/sti()
+ * itself.
+ */
if (skb == NULL) {
dev_tint(dev);
return 0;
}
-
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
+ /*
+ * Block a timer-based transmit from overlapping. This could better be
+ * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
+ */
if (set_bit(0, (void*)&dev->tbusy) != 0)
printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
else {
@@ -368,9 +391,11 @@
return 0;
}
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
+
+/*
+ * The typical workload of the driver:
+ * Handle the network interface interrupts.
+ */
static void
net_interrupt(int irq, struct pt_regs * regs)
{
@@ -453,9 +478,11 @@
}
} while (--boguscount);
- /* If any worth-while packets have been received, dev_rint()
- has done a mark_bh(NET_BH) for us and will work on them
- when we get to the bottom-half routine. */
+ /*
+ * If any worth-while packets have been received, dev_rint()
+ * has done a mark_bh(NET_BH) for us and will work on them
+ * when we get to the bottom-half routine.
+ */
return;
}
@@ -476,7 +503,7 @@
disable_dma(dev->dma);
/* If not IRQ or DMA jumpered, free up the line. */
- outw(0x00, ioaddr+0); /* Release the physical interrupt line. */
+ outw(0x00, ioaddr+0); /* Release the physical interrupt line. */
free_irq(dev->irq);
free_dma(dev->dma);
@@ -491,8 +518,10 @@
}
-/* Get the current statistics. This may be called with the card open or
- closed. */
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
static struct enet_statistics *
net_get_stats(struct device *dev)
{
@@ -507,38 +536,45 @@
return &lp->stats;
}
-/* Set or clear the multicast filter for this adaptor.
- num_addrs == -1 Promiscuous mode, receive all packets
- num_addrs == 0 Normal mode, clear multicast list
- num_addrs > 0 Multicast mode, receive normal and MC packets, and do
- best-effort filtering.
+/*
+ * Set or clear the multicast filter for this adaptor.
+ * num_addrs == -1 Promiscuous mode, receive all packets
+ * num_addrs == 0 Normal mode, clear multicast list
+ * num_addrs > 0 Multicast mode, receive normal and MC packets,
+ * and do best-effort filtering.
*/
static void
set_multicast_list(struct device *dev)
{
short ioaddr = dev->base_addr;
- if (dev->flags&IFF_PROMISC) {
- outw(MULTICAST|PROMISC, ioaddr); /* Enable promiscuous mode */
+ if (dev->flags&IFF_PROMISC)
+ {
+ /* Enable promiscuous mode */
+ outw(MULTICAST|PROMISC, ioaddr);
}
else if((dev->flags&IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS)
{
+ /* Disable promiscuous mode, use normal mode. */
hardware_set_filter(NULL);
- outw(MULTICAST, ioaddr); /* Disable promiscuous mode, use normal mode */
+
+ outw(MULTICAST, ioaddr);
}
else if(dev->mc_count)
{
- hardware_set_filter(dev->mc_list); /* Walk the address list and load the filter */
+ /* Walk the address list, and load the filter */
+ hardware_set_filter(dev->mc_list);
+
outw(MULTICAST, ioaddr);
}
else
outw(0, ioaddr);
}
-
+
#ifdef MODULE
static char devicename[9] = { 0, };
static struct device this_device = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
+ devicename, /* will be inserted by linux/drivers/net/net_init.c */
0, 0, 0, 0,
0, 0, /* I/O address, IRQ */
0, 0, 0, NULL, netcard_probe };
@@ -556,7 +592,7 @@
printk(KERN_WARNING "%s: You shouldn't use auto-probing with insmod!\n",
cardname);
- /* copy the parameters from insmod into the device structure */
+ /* Copy the parameters from insmod into the device structure. */
this_device.base_addr = io;
this_device.irq = irq;
this_device.dma = dma;
@@ -572,12 +608,11 @@
cleanup_module(void)
{
/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
-
unregister_netdev(&this_device);
-
- /* If we don't do this, we can't re-insmod it later. */
- /* Release irq/dma here, when you have jumpered versions and snarfed
- * them in net_probe1().
+ /*
+ * If we don't do this, we can't re-insmod it later.
+ * Release irq/dma here, when you have jumpered versions and
+ * allocate them in net_probe1().
*/
/*
free_irq(this_device.irq);
@@ -590,10 +625,12 @@
}
#endif /* MODULE */
-
+
/*
* Local variables:
- * compile-command: "gcc -D__KERNEL__ -Wall -Wstrict-prototypes -Wwrite-strings -Wredundant-decls -O2 -m486 -c skeleton.c"
+ * compile-command:
+ * gcc -D__KERNEL__ -Wall -Wstrict-prototypes -Wwrite-strings
+ * -Wredundant-decls -O2 -m486 -c skeleton.c
* version-control: t
* kept-new-versions: 5
* tab-width: 4
FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen, [email protected]
with Sam's (original) version of this