The Universal Host Controller Interface is a standard by Intel for
accessing the USB hardware in the PC (which is also called the USB
host controller). If your USB host controller conforms to this
- standard, say Y. All recent boards with Intel PCI chipsets conform
- to this standard. If unsure, say Y.
+ standard, say Y. All recent boards with Intel PCI chipsets (like
+ intel 430TX, 440FX, 440LX, 440BX, i810, i820) conform to this standard.
+ Also all VIA PCI chipsets (like VIA VP2, VP3, MVP3, Apollo Pro, Apollo
+ Pro II or Apollo Pro 133).
+ If unsure, say Y.
This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called usb-uhci.o. If you want to compile it as a
module, say M here and read Documentation/modules.txt.
-OHCI-HCD (Compaq, iMacs, OPTi, SiS, and others) support?
+OHCI-HCD (Compaq, iMacs, OPTi, SiS, ALi, and others) support?
CONFIG_USB_OHCI_HCD
The Open Host Controller Interface is a standard by
Compaq/Microsoft/National for accessing the USB PC hardware (also
called USB host controller). If your USB host controller conforms
to this standard, say Y. The USB host controllers on most
- non-Intel architectures and on several x86 compatibles with
- non-Intel chipsets conform to this standard.
+ non-Intel architectures and on several x86 compatibles with non-Intel
+ chipsets - like SiS (aktual 610, 610 and so on) or ALi (ALi IV, ALi V,
+ Aladin Pro..) - conform to this standard.
You may want to read the file drivers/usb/README.ohci_hcd.
*
* **********************
*/
+
#include <linux/module.h>
-#include <linux/config.h> /* for CONFIG_INET */
+#include <linux/config.h> /* for CONFIG_INET */
#include <linux/init.h>
#include <linux/if_arp.h>
#include <net/arp.h>
static int build_header(struct sk_buff *skb, unsigned short type,
uint8_t daddr);
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
- int bufnum);
+ int bufnum);
-struct ArcProto rawmode_proto = {
+struct ArcProto rawmode_proto =
+{
'r',
XMTU,
rx,
void arcnet_raw_init(void)
{
- int count;
-
- for (count = 0; count < 256; count++)
- if (arc_proto_map[count] == arc_proto_default)
- arc_proto_map[count] = &rawmode_proto;
-
- /* for raw mode, we only set the bcast proto if there's no better one */
- if (arc_bcast_proto == arc_proto_default)
- arc_bcast_proto = &rawmode_proto;
-
- arc_proto_default = &rawmode_proto;
+ int count;
+
+ for (count = 0; count < 256; count++)
+ if (arc_proto_map[count] == arc_proto_default)
+ arc_proto_map[count] = &rawmode_proto;
+
+ /* for raw mode, we only set the bcast proto if there's no better one */
+ if (arc_bcast_proto == arc_proto_default)
+ arc_bcast_proto = &rawmode_proto;
+
+ arc_proto_default = &rawmode_proto;
}
int __init init_module(void)
{
- printk(VERSION);
- arcnet_raw_init();
- return 0;
+ printk(VERSION);
+ arcnet_raw_init();
+ return 0;
}
void cleanup_module(void)
{
- arcnet_unregister_proto(&rawmode_proto);
+ arcnet_unregister_proto(&rawmode_proto);
}
-#endif /* MODULE */
+#endif /* MODULE */
static void rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- struct sk_buff *skb;
- struct archdr *pkt = pkthdr;
- int ofs;
-
- BUGMSG(D_DURING, "it's a raw packet (length=%d)\n", length);
-
- if (length >= MinTU)
- ofs = 512 - length;
- else
- ofs = 256 - length;
-
- skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
- if (skb == NULL)
- {
- BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
- return;
- }
-
- skb_put(skb, length + ARC_HDR_SIZE);
- skb->dev = dev;
-
- pkt = (struct archdr *)skb->data;
-
- skb->mac.raw = skb->data;
- skb_pull(skb, ARC_HDR_SIZE);
-
- /* up to sizeof(pkt->soft) has already been copied from the card */
- memcpy(pkt, pkthdr, sizeof(struct archdr));
- if (length > sizeof(pkt->soft))
- lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
- pkt->soft.raw + sizeof(pkt->soft),
- length - sizeof(pkt->soft));
-
- BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
-
- skb->protocol = 0;
- netif_rx(skb);
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct sk_buff *skb;
+ struct archdr *pkt = pkthdr;
+ int ofs;
+
+ BUGMSG(D_DURING, "it's a raw packet (length=%d)\n", length);
+
+ if (length >= MinTU)
+ ofs = 512 - length;
+ else
+ ofs = 256 - length;
+
+ skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
+ if (skb == NULL) {
+ BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
+ lp->stats.rx_dropped++;
+ return;
+ }
+ skb_put(skb, length + ARC_HDR_SIZE);
+ skb->dev = dev;
+
+ pkt = (struct archdr *) skb->data;
+
+ skb->mac.raw = skb->data;
+ skb_pull(skb, ARC_HDR_SIZE);
+
+ /* up to sizeof(pkt->soft) has already been copied from the card */
+ memcpy(pkt, pkthdr, sizeof(struct archdr));
+ if (length > sizeof(pkt->soft))
+ lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
+ pkt->soft.raw + sizeof(pkt->soft),
+ length - sizeof(pkt->soft));
+
+ BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
+
+ skb->protocol = 0;
+ netif_rx(skb);
}
static int build_header(struct sk_buff *skb, unsigned short type,
uint8_t daddr)
{
- struct net_device *dev = skb->dev;
- int hdr_size = ARC_HDR_SIZE;
- struct archdr *pkt = (struct archdr *)skb_push(skb, hdr_size);
-
- /*
- * Set the source hardware address.
- *
- * This is pretty pointless for most purposes, but it can help in
- * debugging. ARCnet does not allow us to change the source address in
- * the actual packet sent)
- */
- pkt->hard.source = *dev->dev_addr;
-
- /* see linux/net/ethernet/eth.c to see where I got the following */
-
- if (dev->flags & (IFF_LOOPBACK|IFF_NOARP))
- {
- /*
- * FIXME: fill in the last byte of the dest ipaddr here to better
- * comply with RFC1051 in "noarp" mode.
+ struct net_device *dev = skb->dev;
+ int hdr_size = ARC_HDR_SIZE;
+ struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
+
+ /*
+ * Set the source hardware address.
+ *
+ * This is pretty pointless for most purposes, but it can help in
+ * debugging. ARCnet does not allow us to change the source address in
+ * the actual packet sent)
*/
- pkt->hard.dest = 0;
- return hdr_size;
- }
-
- /* otherwise, just fill it in and go! */
- pkt->hard.dest = daddr;
-
- return hdr_size; /* success */
+ pkt->hard.source = *dev->dev_addr;
+
+ /* see linux/net/ethernet/eth.c to see where I got the following */
+
+ if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
+ /*
+ * FIXME: fill in the last byte of the dest ipaddr here to better
+ * comply with RFC1051 in "noarp" mode.
+ */
+ pkt->hard.dest = 0;
+ return hdr_size;
+ }
+ /* otherwise, just fill it in and go! */
+ pkt->hard.dest = daddr;
+
+ return hdr_size; /* success */
}
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
- int bufnum)
+ int bufnum)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- struct arc_hardware *hard = &pkt->hard;
- int ofs;
-
- BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
- lp->next_tx, lp->cur_tx, bufnum);
-
- length -= ARC_HDR_SIZE; /* hard header is not included in packet length */
-
- if (length > XMTU)
- {
- /* should never happen! other people already check for this. */
- BUGMSG(D_NORMAL, "Bug! prepare_tx with size %d (> %d)\n",
- length, XMTU);
- length = XMTU;
- }
-
- if (length > MinTU)
- {
- hard->offset[0] = 0;
- hard->offset[1] = ofs = 512 - length;
- }
- else if (length > MTU)
- {
- hard->offset[0] = 0;
- hard->offset[1] = ofs = 512 - length - 3;
- }
- else
- hard->offset[0] = ofs = 256 - length;
-
- lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
- lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length);
-
- lp->lastload_dest = hard->dest;
-
- return 1; /* done */
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arc_hardware *hard = &pkt->hard;
+ int ofs;
+
+ BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
+ lp->next_tx, lp->cur_tx, bufnum);
+
+ length -= ARC_HDR_SIZE; /* hard header is not included in packet length */
+
+ if (length > XMTU) {
+ /* should never happen! other people already check for this. */
+ BUGMSG(D_NORMAL, "Bug! prepare_tx with size %d (> %d)\n",
+ length, XMTU);
+ length = XMTU;
+ }
+ if (length > MinTU) {
+ hard->offset[0] = 0;
+ hard->offset[1] = ofs = 512 - length;
+ } else if (length > MTU) {
+ hard->offset[0] = 0;
+ hard->offset[1] = ofs = 512 - length - 3;
+ } else
+ hard->offset[0] = ofs = 256 - length;
+
+ lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
+ lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length);
+
+ lp->lastload_dest = hard->dest;
+
+ return 1; /* done */
}
static int arcrimi_probe(struct net_device *dev);
static int arcrimi_found(struct net_device *dev);
-static void arcrimi_command (struct net_device *dev, int command);
-static int arcrimi_status (struct net_device *dev);
-static void arcrimi_setmask (struct net_device *dev, int mask);
-static int arcrimi_reset (struct net_device *dev, int really_reset);
+static void arcrimi_command(struct net_device *dev, int command);
+static int arcrimi_status(struct net_device *dev);
+static void arcrimi_setmask(struct net_device *dev, int mask);
+static int arcrimi_reset(struct net_device *dev, int really_reset);
static void arcrimi_openclose(struct net_device *dev, bool open);
-static void arcrimi_copy_to_card (struct net_device *dev, int bufnum, int offset,
- void *buf, int count);
+static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
+ void *buf, int count);
static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offset,
void *buf, int count);
{
BUGLVL(D_NORMAL) printk(VERSION);
BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n");
-
+
BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n",
dev->dev_addr[0], dev->mem_start, dev->irq);
"must specify the shmem and irq!\n");
return -ENODEV;
}
-
if (check_mem_region(dev->mem_start, BUFFER_SIZE)) {
BUGMSG(D_NORMAL, "Card memory already allocated\n");
return -ENODEV;
}
-
if (dev->dev_addr[0] == 0) {
BUGMSG(D_NORMAL, "You need to specify your card's station "
"ID!\n");
return -ENODEV;
}
-
return arcrimi_found(dev);
}
u_long first_mirror, last_mirror, shmem;
int mirror_size;
- /* reserve the irq */ {
- if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev))
- BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
+ /* reserve the irq */ {
+ if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev))
+ BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
return -ENODEV;
}
BUGMSG(D_NORMAL, "Can't allocate device data!\n");
goto err_free_irq;
}
- lp->hw.command = arcrimi_command;
- lp->hw.status = arcrimi_status;
- lp->hw.intmask = arcrimi_setmask;
- lp->hw.reset = arcrimi_reset;
- lp->hw.open_close = arcrimi_openclose;
- lp->hw.copy_to_card = arcrimi_copy_to_card;
+ lp->hw.command = arcrimi_command;
+ lp->hw.status = arcrimi_status;
+ lp->hw.intmask = arcrimi_setmask;
+ lp->hw.reset = arcrimi_reset;
+ lp->hw.open_close = arcrimi_openclose;
+ lp->hw.copy_to_card = arcrimi_copy_to_card;
lp->hw.copy_from_card = arcrimi_copy_from_card;
- lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+ lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
if (!lp->mem_start) {
BUGMSG(D_NORMAL, "Can't remap device memory!\n");
goto err_free_dev_priv;
}
-
/* Fill in the fields of the device structure with generic
* values.
*/
"ShMem %lXh (%ld*%d bytes).\n",
dev->dev_addr[0],
dev->irq, dev->mem_start,
- (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
+ (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
return 0;
-err_free_dev_priv:
+ err_free_dev_priv:
kfree(dev->priv);
-err_free_irq:
+ err_free_irq:
free_irq(dev->irq, dev);
return -EIO;
}
BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS());
if (really_reset) {
- writeb(TESTvalue, ioaddr-0x800); /* fake reset */
+ writeb(TESTvalue, ioaddr - 0x800); /* fake reset */
return 0;
}
-
ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */
ACOMMAND(CFLAGScmd | CONFIGclear);
void *buf, int count)
{
struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
- void *memaddr = lp->mem_start + 0x800 + bufnum*512 + offset;
+ void *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
}
void *buf, int count)
{
struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
- void *memaddr = lp->mem_start + 0x800 + bufnum*512 + offset;
+ void *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
}
{
struct net_device *dev;
int err;
-
+
dev = dev_alloc(device ? : "arc%d", &err);
if (!dev)
return err;
dev->irq = irq;
if (dev->irq == 2)
dev->irq = 9;
-
+
if (arcrimi_probe(dev))
return -EIO;
return 1;
dev = alloc_bootmem(sizeof(struct net_device) + 10);
memset(dev, 0, sizeof(struct net_device) + 10);
- dev->name = (char *)(dev+1);
+ dev->name = (char *) (dev + 1);
dev->init = arcrimi_probe;
switch (ints[0]) {
default: /* ERROR */
printk("arcrimi: Too many arguments.\n");
- case 3: /* Node ID */
+ case 3: /* Node ID */
dev->dev_addr[0] = ints[3];
- case 2: /* IRQ */
+ case 2: /* IRQ */
dev->irq = ints[2];
- case 1: /* IO address */
+ case 1: /* IO address */
dev->mem_start = ints[1];
}
if (*s)
static void null_rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length);
static int null_build_header(struct sk_buff *skb, unsigned short type,
- uint8_t daddr);
+ uint8_t daddr);
static int null_prepare_tx(struct net_device *dev, struct archdr *pkt,
- int length, int bufnum);
+ int length, int bufnum);
/*
*/
struct ArcProto *arc_proto_map[256], *arc_proto_default, *arc_bcast_proto;
-struct ArcProto arc_proto_null = {
- '?',
+struct ArcProto arc_proto_null =
+{
+ '?',
XMTU,
- null_rx,
+ null_rx,
null_build_header,
null_prepare_tx
};
void __init arcnet_init(void)
{
- static int arcnet_inited __initdata = 0;
- int count;
+ static int arcnet_inited __initdata = 0;
+ int count;
- if (arcnet_inited++)
- return;
+ if (arcnet_inited++)
+ return;
- printk(VERSION);
+ printk(VERSION);
#ifdef ALPHA_WARNING
- BUGLVL(D_EXTRA)
- {
- printk("arcnet: ***\n"
- "arcnet: * Read arcnet.txt for important release notes!\n"
- "arcnet: *\n"
- "arcnet: * This is an ALPHA version! (Last stable release: v3.02) E-mail\n"
- "arcnet: * me if you have any questions, comments, or bug reports.\n"
- "arcnet: ***\n");
- }
+ BUGLVL(D_EXTRA) {
+ printk("arcnet: ***\n"
+ "arcnet: * Read arcnet.txt for important release notes!\n"
+ "arcnet: *\n"
+ "arcnet: * This is an ALPHA version! (Last stable release: v3.02) E-mail\n"
+ "arcnet: * me if you have any questions, comments, or bug reports.\n"
+ "arcnet: ***\n");
+ }
#endif
-
- /* initialize the protocol map */
- arc_proto_default = arc_bcast_proto = &arc_proto_null;
- for (count = 0; count < 256; count++)
- arc_proto_map[count] = arc_proto_default;
-
- BUGLVL(D_DURING)
- printk("arcnet: struct sizes: %d %d %d %d %d\n",
- sizeof(struct arc_hardware), sizeof(struct arc_rfc1201),
- sizeof(struct arc_rfc1051), sizeof(struct arc_eth_encap),
- sizeof(struct archdr));
+
+ /* initialize the protocol map */
+ arc_proto_default = arc_bcast_proto = &arc_proto_null;
+ for (count = 0; count < 256; count++)
+ arc_proto_map[count] = arc_proto_default;
+
+ BUGLVL(D_DURING)
+ printk("arcnet: struct sizes: %d %d %d %d %d\n",
+ sizeof(struct arc_hardware), sizeof(struct arc_rfc1201),
+ sizeof(struct arc_rfc1051), sizeof(struct arc_eth_encap),
+ sizeof(struct archdr));
#ifdef CONFIG_ARCNET /* We're not built as a module */
- printk("arcnet: Available protocols:");
+ printk("arcnet: Available protocols:");
#ifdef CONFIG_ARCNET_1201
- printk(" RFC1201");
- arcnet_rfc1201_init();
+ printk(" RFC1201");
+ arcnet_rfc1201_init();
#endif
#ifdef CONFIG_ARCNET_1051
- printk(" RFC1051");
- arcnet_rfc1051_init();
+ printk(" RFC1051");
+ arcnet_rfc1051_init();
#endif
#ifdef CONFIG_ARCNET_RAW
- printk(" RAW");
- arcnet_raw_init();
+ printk(" RAW");
+ arcnet_raw_init();
#endif
- printk("\n");
+ printk("\n");
#ifdef CONFIG_ARCNET_COM90xx
- com90xx_probe(NULL);
+ com90xx_probe(NULL);
#endif
#ifdef CONFIG_ARCNET_COM20020_PCI
- com20020pci_probe_all();
+ com20020pci_probe_all();
#endif
#endif
}
int __init init_module(void)
{
- arcnet_debug = debug;
- arcnet_init();
- return 0;
+ arcnet_debug = debug;
+ arcnet_init();
+ return 0;
}
void cleanup_module(void)
#if ARCNET_DEBUG_MAX & D_SKB
void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc)
{
- int i;
- long flags;
-
- save_flags(flags);
- cli();
- printk(KERN_DEBUG "%6s: skb dump (%s) follows:", dev->name, desc);
- for (i = 0; i < skb->len; i++)
- {
- if (i % 16 == 0)
- printk("\n" KERN_DEBUG "[%04X] ", i);
- printk("%02X ", ((u_char *) skb->data)[i]);
- }
- printk("\n");
- restore_flags(flags);
+ int i;
+ long flags;
+
+ save_flags(flags);
+ cli();
+ printk(KERN_DEBUG "%6s: skb dump (%s) follows:", dev->name, desc);
+ for (i = 0; i < skb->len; i++) {
+ if (i % 16 == 0)
+ printk("\n" KERN_DEBUG "[%04X] ", i);
+ printk("%02X ", ((u_char *) skb->data)[i]);
+ }
+ printk("\n");
+ restore_flags(flags);
}
EXPORT_SYMBOL(arcnet_dump_skb);
#if (ARCNET_DEBUG_MAX & (D_RX | D_TX))
void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int i, length;
- long flags;
- static uint8_t buf[512];
-
- save_flags(flags);
- cli();
-
- lp->hw.copy_from_card(dev, bufnum, 0, buf, 512);
-
- /* if the offset[0] byte is nonzero, this is a 256-byte packet */
- length = (buf[2] ? 256 : 512);
-
- printk(KERN_DEBUG "%6s: packet dump (%s) follows:", dev->name, desc);
- for (i = 0; i < length; i++)
- {
- if (i % 16 == 0)
- printk("\n" KERN_DEBUG "[%04X] ", i);
- printk("%02X ", buf[i]);
- }
- printk("\n");
-
- restore_flags(flags);
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ int i, length;
+ long flags;
+ static uint8_t buf[512];
+
+ save_flags(flags);
+ cli();
+
+ lp->hw.copy_from_card(dev, bufnum, 0, buf, 512);
+
+ /* if the offset[0] byte is nonzero, this is a 256-byte packet */
+ length = (buf[2] ? 256 : 512);
+
+ printk(KERN_DEBUG "%6s: packet dump (%s) follows:", dev->name, desc);
+ for (i = 0; i < length; i++) {
+ if (i % 16 == 0)
+ printk("\n" KERN_DEBUG "[%04X] ", i);
+ printk("%02X ", buf[i]);
+ }
+ printk("\n");
+
+ restore_flags(flags);
}
EXPORT_SYMBOL(arcnet_dump_packet);
*/
void arcnet_unregister_proto(struct ArcProto *proto)
{
- int count;
-
- if (arc_proto_default == proto)
- arc_proto_default = &arc_proto_null;
- if (arc_bcast_proto == proto)
- arc_bcast_proto = arc_proto_default;
-
- for (count = 0; count < 256; count++)
- {
- if (arc_proto_map[count] == proto)
- arc_proto_map[count] = arc_proto_default;
- }
+ int count;
+
+ if (arc_proto_default == proto)
+ arc_proto_default = &arc_proto_null;
+ if (arc_bcast_proto == proto)
+ arc_bcast_proto = arc_proto_default;
+
+ for (count = 0; count < 256; count++) {
+ if (arc_proto_map[count] == proto)
+ arc_proto_map[count] = arc_proto_default;
+ }
}
*/
static void release_arcbuf(struct net_device *dev, int bufnum)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int i;
-
- lp->buf_queue[lp->first_free_buf++] = bufnum;
- lp->first_free_buf %= 5;
-
- BUGLVL(D_DURING)
- {
- BUGMSG(D_DURING, "release_arcbuf: freed #%d; buffer queue is now: ",
- bufnum);
- for (i = lp->next_buf; i != lp->first_free_buf; i = ++i % 5)
- BUGMSG2(D_DURING, "#%d ", lp->buf_queue[i]);
- BUGMSG2(D_DURING, "\n");
- }
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ int i;
+
+ lp->buf_queue[lp->first_free_buf++] = bufnum;
+ lp->first_free_buf %= 5;
+
+ BUGLVL(D_DURING) {
+ BUGMSG(D_DURING, "release_arcbuf: freed #%d; buffer queue is now: ",
+ bufnum);
+ for (i = lp->next_buf; i != lp->first_free_buf; i = ++i % 5)
+ BUGMSG2(D_DURING, "#%d ", lp->buf_queue[i]);
+ BUGMSG2(D_DURING, "\n");
+ }
}
*/
static int get_arcbuf(struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int buf = -1, i;
-
- if (!atomic_dec_and_test(&lp->buf_lock)) /* already in this function */
- BUGMSG(D_NORMAL, "get_arcbuf: overlap (%d)!\n", lp->buf_lock.counter);
- else /* we can continue */
- {
- if (lp->next_buf >= 5)
- lp->next_buf -= 5;
-
- if (lp->next_buf == lp->first_free_buf)
- BUGMSG(D_NORMAL, "get_arcbuf: BUG: no buffers are available??\n");
- else
- {
- buf = lp->buf_queue[lp->next_buf++];
- lp->next_buf %= 5;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ int buf = -1, i;
+
+ if (!atomic_dec_and_test(&lp->buf_lock)) /* already in this function */
+ BUGMSG(D_NORMAL, "get_arcbuf: overlap (%d)!\n", lp->buf_lock.counter);
+ else { /* we can continue */
+ if (lp->next_buf >= 5)
+ lp->next_buf -= 5;
+
+ if (lp->next_buf == lp->first_free_buf)
+ BUGMSG(D_NORMAL, "get_arcbuf: BUG: no buffers are available??\n");
+ else {
+ buf = lp->buf_queue[lp->next_buf++];
+ lp->next_buf %= 5;
+ }
+ }
+
+
+ BUGLVL(D_DURING) {
+ BUGMSG(D_DURING, "get_arcbuf: got #%d; buffer queue is now: ", buf);
+ for (i = lp->next_buf; i != lp->first_free_buf; i = ++i % 5)
+ BUGMSG2(D_DURING, "#%d ", lp->buf_queue[i]);
+ BUGMSG2(D_DURING, "\n");
}
- }
-
-
- BUGLVL(D_DURING)
- {
- BUGMSG(D_DURING, "get_arcbuf: got #%d; buffer queue is now: ", buf);
- for (i = lp->next_buf; i != lp->first_free_buf; i = ++i % 5)
- BUGMSG2(D_DURING, "#%d ", lp->buf_queue[i]);
- BUGMSG2(D_DURING, "\n");
- }
-
- atomic_inc(&lp->buf_lock);
- return buf;
+
+ atomic_inc(&lp->buf_lock);
+ return buf;
}
static int choose_mtu(void)
{
- int count, mtu = 65535;
-
- /* choose the smallest MTU of all available encaps */
- for (count = 0; count < 256; count++)
- {
- if (arc_proto_map[count] != &arc_proto_null
- && arc_proto_map[count]->mtu < mtu)
- {
- mtu = arc_proto_map[count]->mtu;
+ int count, mtu = 65535;
+
+ /* choose the smallest MTU of all available encaps */
+ for (count = 0; count < 256; count++) {
+ if (arc_proto_map[count] != &arc_proto_null
+ && arc_proto_map[count]->mtu < mtu) {
+ mtu = arc_proto_map[count]->mtu;
+ }
}
- }
-
- return mtu == 65535 ? XMTU : mtu;
+
+ return mtu == 65535 ? XMTU : mtu;
}
/* Setup a struct device for ARCnet. */
void arcdev_setup(struct net_device *dev)
{
- dev->type = ARPHRD_ARCNET;
- dev->hard_header_len = sizeof(struct archdr);
- dev->mtu = choose_mtu();
-
- dev->addr_len = 1;
- dev->tx_queue_len = 30;
- dev->broadcast[0] = 0x00; /* for us, broadcasts are address 0 */
-
- /* New-style flags. */
- dev->flags = IFF_BROADCAST;
-
- /*
- * Put in this stuff here, so we don't have to export the symbols to
- * the chipset drivers.
- */
- dev->open = arcnet_open;
- dev->stop = arcnet_close;
- dev->hard_start_xmit = arcnet_send_packet;
- dev->get_stats = arcnet_get_stats;
- dev->hard_header = arcnet_header;
- dev->rebuild_header = arcnet_rebuild_header;
-
- dev_init_buffers(dev);
+ dev->type = ARPHRD_ARCNET;
+ dev->hard_header_len = sizeof(struct archdr);
+ dev->mtu = choose_mtu();
+
+ dev->addr_len = 1;
+ dev->tx_queue_len = 30;
+ dev->broadcast[0] = 0x00; /* for us, broadcasts are address 0 */
+
+ /* New-style flags. */
+ dev->flags = IFF_BROADCAST;
+
+ /*
+ * Put in this stuff here, so we don't have to export the symbols to
+ * the chipset drivers.
+ */
+ dev->open = arcnet_open;
+ dev->stop = arcnet_close;
+ dev->hard_start_xmit = arcnet_send_packet;
+ dev->get_stats = arcnet_get_stats;
+ dev->hard_header = arcnet_header;
+ dev->rebuild_header = arcnet_rebuild_header;
+
+ dev_init_buffers(dev);
}
*/
static int arcnet_open(struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int count, newmtu;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ int count, newmtu;
+
+ BUGLVL(D_PROTO) {
+ int count;
+ BUGMSG(D_PROTO, "protocol map (default is '%c'): ",
+ arc_proto_default->suffix);
+ for (count = 0; count < 256; count++)
+ BUGMSG2(D_PROTO, "%c", arc_proto_map[count]->suffix);
+ BUGMSG2(D_PROTO, "\n");
+ }
- BUGLVL(D_PROTO)
- {
- int count;
- BUGMSG(D_PROTO, "protocol map (default is '%c'): ",
- arc_proto_default->suffix);
- for (count = 0; count < 256; count++)
- BUGMSG2(D_PROTO, "%c", arc_proto_map[count]->suffix);
- BUGMSG2(D_PROTO, "\n");
- }
-
-
- BUGMSG(D_INIT, "arcnet_open: resetting card.\n");
-
- /* try to put the card in a defined state - if it fails the first
- * time, actually reset it.
- */
- if (ARCRESET(0) && ARCRESET(1))
- return -ENODEV;
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 0;
-
- newmtu = choose_mtu();
- if (newmtu < dev->mtu)
- dev->mtu = newmtu;
-
- /* autodetect the encapsulation for each host. */
- memset(lp->default_proto, 0, sizeof(lp->default_proto));
-
- /* the broadcast address is special - use the 'bcast' protocol */
- for (count = 0; count < 256; count++)
- {
- if (arc_proto_map[count] == arc_bcast_proto)
- {
- lp->default_proto[0] = count;
- break;
+
+ BUGMSG(D_INIT, "arcnet_open: resetting card.\n");
+
+ /* try to put the card in a defined state - if it fails the first
+ * time, actually reset it.
+ */
+ if (ARCRESET(0) && ARCRESET(1))
+ return -ENODEV;
+
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 0;
+
+ newmtu = choose_mtu();
+ if (newmtu < dev->mtu)
+ dev->mtu = newmtu;
+
+ /* autodetect the encapsulation for each host. */
+ memset(lp->default_proto, 0, sizeof(lp->default_proto));
+
+ /* the broadcast address is special - use the 'bcast' protocol */
+ for (count = 0; count < 256; count++) {
+ if (arc_proto_map[count] == arc_bcast_proto) {
+ lp->default_proto[0] = count;
+ break;
+ }
}
- }
-
- /* initialize buffers */
- atomic_set(&lp->buf_lock, 1);
- lp->next_buf = lp->first_free_buf = 0;
- release_arcbuf(dev, 0);
- release_arcbuf(dev, 1);
- release_arcbuf(dev, 2);
- release_arcbuf(dev, 3);
- lp->cur_tx = lp->next_tx = -1;
- lp->cur_rx = -1;
-
- lp->rfc1201.sequence = 1;
-
- /* bring up the hardware driver */
- ARCOPEN(1);
-
- if (dev->dev_addr[0] == 0)
- BUGMSG(D_NORMAL, "WARNING! Station address 00 is reserved "
- "for broadcasts!\n");
- else if (dev->dev_addr[0] == 255)
- BUGMSG(D_NORMAL, "WARNING! Station address FF may confuse "
- "DOS networking programs!\n");
-
- if (ASTATUS() & RESETflag)
- ACOMMAND(CFLAGScmd | RESETclear);
-
- /* we're started */
- dev->start = 1;
-
- /* make sure we're ready to receive IRQ's. */
- AINTMASK(0);
- udelay(1); /* give it time to set the mask before
+
+ /* initialize buffers */
+ atomic_set(&lp->buf_lock, 1);
+ lp->next_buf = lp->first_free_buf = 0;
+ release_arcbuf(dev, 0);
+ release_arcbuf(dev, 1);
+ release_arcbuf(dev, 2);
+ release_arcbuf(dev, 3);
+ lp->cur_tx = lp->next_tx = -1;
+ lp->cur_rx = -1;
+
+ lp->rfc1201.sequence = 1;
+
+ /* bring up the hardware driver */
+ ARCOPEN(1);
+
+ if (dev->dev_addr[0] == 0)
+ BUGMSG(D_NORMAL, "WARNING! Station address 00 is reserved "
+ "for broadcasts!\n");
+ else if (dev->dev_addr[0] == 255)
+ BUGMSG(D_NORMAL, "WARNING! Station address FF may confuse "
+ "DOS networking programs!\n");
+
+ if (ASTATUS() & RESETflag)
+ ACOMMAND(CFLAGScmd | RESETclear);
+
+ /* we're started */
+ dev->start = 1;
+
+ /* make sure we're ready to receive IRQ's. */
+ AINTMASK(0);
+ udelay(1); /* give it time to set the mask before
* we reset it again. (may not even be
* necessary)
*/
- lp->intmask = NORXflag | RECONflag;
- AINTMASK(lp->intmask);
+ lp->intmask = NORXflag | RECONflag;
+ AINTMASK(lp->intmask);
- return 0;
+ return 0;
}
/* The inverse routine to arcnet_open - shuts down the card. */
static int arcnet_close(struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
-
- /* flush TX and disable RX */
- AINTMASK(0);
- ACOMMAND(NOTXcmd); /* stop transmit */
- ACOMMAND(NORXcmd); /* disable receive */
- mdelay(1);
-
- dev->tbusy = 1;
- dev->start = 0;
- dev->interrupt = 0;
-
- /* shut down the card */
- ARCOPEN(0);
-
- return 0;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+
+ /* flush TX and disable RX */
+ AINTMASK(0);
+ ACOMMAND(NOTXcmd); /* stop transmit */
+ ACOMMAND(NORXcmd); /* disable receive */
+ mdelay(1);
+
+ dev->tbusy = 1;
+ dev->start = 0;
+ dev->interrupt = 0;
+
+ /* shut down the card */
+ ARCOPEN(0);
+
+ return 0;
}
unsigned short type, void *daddr, void *saddr,
unsigned len)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- uint8_t _daddr, proto_num;
- struct ArcProto *proto;
-
- BUGMSG(D_DURING,
- "create header from %d to %d; protocol %d (%Xh); size %u.\n",
- saddr ? *(uint8_t *)saddr : -1,
- daddr ? *(uint8_t *)daddr : -1,
- type, type, len);
-
- if (len != skb->len)
- BUGMSG(D_NORMAL, "arcnet_header: Yikes! skb->len(%d) != len(%d)!\n",
- skb->len, len);
-
- /*
- * if the dest addr isn't provided, we can't choose an encapsulation!
- * Store the packet type (eg. ETH_P_IP) for now, and we'll push on a
- * real header when we do rebuild_header.
- */
- if (!daddr)
- {
- *(uint16_t *)skb_push(skb, 2) = type;
- if (skb->nh.raw - skb->mac.raw != 2)
- BUGMSG(D_NORMAL, "arcnet_header: Yikes! diff (%d) is not 2!\n",
- skb->nh.raw - skb->mac.raw);
- return -2; /* return error -- can't transmit yet! */
- }
-
- /* otherwise, we can just add the header as usual. */
- _daddr = *(uint8_t *)daddr;
- proto_num = lp->default_proto[_daddr];
- proto = arc_proto_map[proto_num];
- BUGMSG(D_DURING, "building header for %02Xh using protocol '%c'\n",
- proto_num, proto->suffix);
- if (proto == &arc_proto_null && arc_bcast_proto != proto)
- {
- BUGMSG(D_DURING, "actually, let's use '%c' instead.\n",
- arc_bcast_proto->suffix);
- proto = arc_bcast_proto;
- }
- return proto->build_header(skb, type, _daddr);
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ uint8_t _daddr, proto_num;
+ struct ArcProto *proto;
+
+ BUGMSG(D_DURING,
+ "create header from %d to %d; protocol %d (%Xh); size %u.\n",
+ saddr ? *(uint8_t *) saddr : -1,
+ daddr ? *(uint8_t *) daddr : -1,
+ type, type, len);
+
+ if (len != skb->len)
+ BUGMSG(D_NORMAL, "arcnet_header: Yikes! skb->len(%d) != len(%d)!\n",
+ skb->len, len);
+
+ /*
+ * if the dest addr isn't provided, we can't choose an encapsulation!
+ * Store the packet type (eg. ETH_P_IP) for now, and we'll push on a
+ * real header when we do rebuild_header.
+ */
+ if (!daddr) {
+ *(uint16_t *) skb_push(skb, 2) = type;
+ if (skb->nh.raw - skb->mac.raw != 2)
+ BUGMSG(D_NORMAL, "arcnet_header: Yikes! diff (%d) is not 2!\n",
+ skb->nh.raw - skb->mac.raw);
+ return -2; /* return error -- can't transmit yet! */
+ }
+ /* otherwise, we can just add the header as usual. */
+ _daddr = *(uint8_t *) daddr;
+ proto_num = lp->default_proto[_daddr];
+ proto = arc_proto_map[proto_num];
+ BUGMSG(D_DURING, "building header for %02Xh using protocol '%c'\n",
+ proto_num, proto->suffix);
+ if (proto == &arc_proto_null && arc_bcast_proto != proto) {
+ BUGMSG(D_DURING, "actually, let's use '%c' instead.\n",
+ arc_bcast_proto->suffix);
+ proto = arc_bcast_proto;
+ }
+ return proto->build_header(skb, type, _daddr);
}
*/
static int arcnet_rebuild_header(struct sk_buff *skb)
{
- struct net_device *dev = skb->dev;
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int status = 0; /* default is failure */
- unsigned short type;
- uint8_t daddr;
-
- if (skb->nh.raw - skb->mac.raw != 2)
- {
- BUGMSG(D_NORMAL,
- "rebuild_header: shouldn't be here! (hdrsize=%d)\n",
- skb->nh.raw - skb->mac.raw);
- return 0;
- }
+ struct net_device *dev = skb->dev;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ int status = 0; /* default is failure */
+ unsigned short type;
+ uint8_t daddr;
- type = *(uint16_t *)skb_pull(skb, 2);
-
- if (type == ETH_P_IP)
- {
+ if (skb->nh.raw - skb->mac.raw != 2) {
+ BUGMSG(D_NORMAL,
+ "rebuild_header: shouldn't be here! (hdrsize=%d)\n",
+ skb->nh.raw - skb->mac.raw);
+ return 0;
+ }
+ type = *(uint16_t *) skb_pull(skb, 2);
+
+ if (type == ETH_P_IP) {
#ifdef CONFIG_INET
- BUGMSG(D_DURING, "rebuild header for ethernet protocol %Xh\n", type);
- status = arp_find(&daddr, skb) ? 1 : 0;
- BUGMSG(D_DURING, " rebuilt: dest is %d; protocol %Xh\n",
- daddr, type);
+ BUGMSG(D_DURING, "rebuild header for ethernet protocol %Xh\n", type);
+ status = arp_find(&daddr, skb) ? 1 : 0;
+ BUGMSG(D_DURING, " rebuilt: dest is %d; protocol %Xh\n",
+ daddr, type);
#endif
- }
- else
- {
- BUGMSG(D_NORMAL,
- "I don't understand ethernet protocol %Xh addresses!\n", type);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
- }
-
- /* if we couldn't resolve the address... give up. */
- if (!status)
- return 0;
+ } else {
+ BUGMSG(D_NORMAL,
+ "I don't understand ethernet protocol %Xh addresses!\n", type);
+ lp->stats.tx_errors++;
+ lp->stats.tx_aborted_errors++;
+ }
+
+ /* if we couldn't resolve the address... give up. */
+ if (!status)
+ return 0;
- /* add the _real_ header this time! */
- arc_proto_map[lp->default_proto[daddr]]->build_header(skb, type, daddr);
+ /* add the _real_ header this time! */
+ arc_proto_map[lp->default_proto[daddr]]->build_header(skb, type, daddr);
- return 1; /* success */
+ return 1; /* success */
}
/* Called by the kernel in order to transmit a packet. */
static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- struct archdr *pkt;
- struct arc_rfc1201 *soft;
- struct ArcProto *proto;
- int txbuf;
-
- BUGMSG(D_DURING,
- "transmit requested (status=%Xh, txbufs=%d/%d, len=%d)\n",
- ASTATUS(), lp->cur_tx, lp->next_tx, skb->len);
-
- 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.
- */
- unsigned long flags;
- int tickssofar = jiffies - dev->trans_start, status = ASTATUS();
-
- if (tickssofar < TX_TIMEOUT)
- {
- BUGMSG(D_DURING, "premature kickme! (status=%Xh ticks=%d)\n",
- status, tickssofar);
- return 1; /* means "try again" */
- }
-
- save_flags(flags);
- cli();
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct archdr *pkt;
+ struct arc_rfc1201 *soft;
+ struct ArcProto *proto;
+ int txbuf;
+
+ BUGMSG(D_DURING,
+ "transmit requested (status=%Xh, txbufs=%d/%d, len=%d)\n",
+ ASTATUS(), lp->cur_tx, lp->next_tx, skb->len);
+
+ 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.
+ */
+ unsigned long flags;
+ int tickssofar = jiffies - dev->trans_start, status = ASTATUS();
- if (status & TXFREEflag) /* transmit _DID_ finish */
- {
- BUGMSG(D_NORMAL, "tx timeout - missed IRQ? (status=%Xh, ticks=%d, mask=%Xh, dest=%02Xh)\n",
- status, tickssofar, lp->intmask, lp->lasttrans_dest);
- lp->stats.tx_errors++;
- }
- else
- {
- BUGMSG(D_EXTRA, "tx timed out (status=%Xh, tickssofar=%d, intmask=%Xh, dest=%02Xh)\n",
- status, tickssofar, lp->intmask, lp->lasttrans_dest);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
-
- ACOMMAND(NOTXcmd | (lp->cur_tx << 3));
+ if (tickssofar < TX_TIMEOUT) {
+ BUGMSG(D_DURING, "premature kickme! (status=%Xh ticks=%d)\n",
+ status, tickssofar);
+ return 1; /* means "try again" */
+ }
+ save_flags(flags);
+ cli();
+
+ if (status & TXFREEflag) { /* transmit _DID_ finish */
+ BUGMSG(D_NORMAL, "tx timeout - missed IRQ? (status=%Xh, ticks=%d, mask=%Xh, dest=%02Xh)\n",
+ status, tickssofar, lp->intmask, lp->lasttrans_dest);
+ lp->stats.tx_errors++;
+ } else {
+ BUGMSG(D_EXTRA, "tx timed out (status=%Xh, tickssofar=%d, intmask=%Xh, dest=%02Xh)\n",
+ status, tickssofar, lp->intmask, lp->lasttrans_dest);
+ lp->stats.tx_errors++;
+ lp->stats.tx_aborted_errors++;
+
+ ACOMMAND(NOTXcmd | (lp->cur_tx << 3));
+ }
+
+ /*
+ * interrupt handler will set dev->tbusy = 0 when it notices the
+ * transmit has been canceled.
+ */
+
+ /* make sure we didn't miss a TX IRQ */
+ AINTMASK(0);
+ lp->intmask |= TXFREEflag;
+ AINTMASK(lp->intmask);
+
+ restore_flags(flags);
+ return 1;
}
+ pkt = (struct archdr *) skb->data;
+ soft = &pkt->soft.rfc1201;
+ proto = arc_proto_map[soft->proto];
+
+ BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "tx");
+ /* fits in one packet? */
+ if (skb->len - ARC_HDR_SIZE > XMTU && !proto->continue_tx) {
+ BUGMSG(D_NORMAL, "fixme: packet too large: compensating badly!\n");
+ dev_kfree_skb(skb);
+ return 0; /* don't try again */
+ }
/*
- * interrupt handler will set dev->tbusy = 0 when it notices the
- * transmit has been canceled.
+ * Block a timer-based transmit from overlapping. This could better be
+ * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
*/
-
- /* make sure we didn't miss a TX IRQ */
+ if (test_and_set_bit(0, (int *) &dev->tbusy)) {
+ BUGMSG(D_NORMAL, "transmitter called with busy bit set! "
+ "(status=%Xh, tickssofar=%ld)\n",
+ ASTATUS(), jiffies - dev->trans_start);
+ lp->stats.tx_errors++;
+ lp->stats.tx_fifo_errors++;
+ return 0; /* don't try again */
+ }
AINTMASK(0);
- lp->intmask |= TXFREEflag;
- AINTMASK(lp->intmask);
- restore_flags(flags);
- return 1;
- }
-
- pkt = (struct archdr *)skb->data;
- soft = &pkt->soft.rfc1201;
- proto = arc_proto_map[soft->proto];
-
- BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "tx");
-
- /* fits in one packet? */
- if (skb->len - ARC_HDR_SIZE > XMTU && !proto->continue_tx)
- {
- BUGMSG(D_NORMAL, "fixme: packet too large: compensating badly!\n");
- dev_kfree_skb(skb);
- return 0; /* don't try again */
- }
-
- /*
- * 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 (test_and_set_bit(0, (int *)&dev->tbusy))
- {
- BUGMSG(D_NORMAL, "transmitter called with busy bit set! "
- "(status=%Xh, tickssofar=%ld)\n",
- ASTATUS(), jiffies - dev->trans_start);
- lp->stats.tx_errors++;
- lp->stats.tx_fifo_errors++;
- return 0; /* don't try again */
- }
-
- AINTMASK(0);
-
- txbuf = get_arcbuf(dev);
- if (txbuf != -1)
- {
- if (proto->prepare_tx(dev, pkt, skb->len, txbuf))
- {
- /* done right away */
- lp->stats.tx_bytes += skb->len;
- dev_kfree_skb(skb);
- }
- else
- {
- /* do it the 'split' way */
- lp->outgoing.proto = proto;
- lp->outgoing.skb = skb;
- lp->outgoing.pkt = pkt;
-
- if (!proto->continue_tx)
- BUGMSG(D_NORMAL, "bug! prep_tx==0, but no continue_tx!\n");
- else if (proto->continue_tx(dev, txbuf))
- {
- BUGMSG(D_NORMAL,
- "bug! continue_tx finished the first time! "
- "(proto='%c')\n", proto->suffix);
- }
- }
+ txbuf = get_arcbuf(dev);
+ if (txbuf != -1) {
+ if (proto->prepare_tx(dev, pkt, skb->len, txbuf)) {
+ /* done right away */
+ lp->stats.tx_bytes += skb->len;
+ dev_kfree_skb(skb);
+ } else {
+ /* do it the 'split' way */
+ lp->outgoing.proto = proto;
+ lp->outgoing.skb = skb;
+ lp->outgoing.pkt = pkt;
+
+ if (!proto->continue_tx)
+ BUGMSG(D_NORMAL, "bug! prep_tx==0, but no continue_tx!\n");
+ else if (proto->continue_tx(dev, txbuf)) {
+ BUGMSG(D_NORMAL,
+ "bug! continue_tx finished the first time! "
+ "(proto='%c')\n", proto->suffix);
+ }
+ }
- lp->next_tx = txbuf;
- }
- else
- dev_kfree_skb(skb);
+ lp->next_tx = txbuf;
+ } else
+ dev_kfree_skb(skb);
- /* make sure we didn't ignore a TX IRQ while we were in here */
- AINTMASK(0);
- lp->intmask |= TXFREEflag;
- AINTMASK(lp->intmask);
+ /* make sure we didn't ignore a TX IRQ while we were in here */
+ AINTMASK(0);
+ lp->intmask |= TXFREEflag;
+ AINTMASK(lp->intmask);
- return 0; /* no need to try again */
+ return 0; /* no need to try again */
}
*/
static int go_tx(struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
- BUGMSG(D_DURING, "go_tx: status=%Xh, intmask=%Xh, next_tx=%d, cur_tx=%d\n",
- ASTATUS(), lp->intmask, lp->next_tx, lp->cur_tx);
-
- if (lp->cur_tx != -1 || lp->next_tx == -1)
- return 0;
-
- BUGLVL(D_TX) arcnet_dump_packet(dev, lp->next_tx, "go_tx");
+ BUGMSG(D_DURING, "go_tx: status=%Xh, intmask=%Xh, next_tx=%d, cur_tx=%d\n",
+ ASTATUS(), lp->intmask, lp->next_tx, lp->cur_tx);
- lp->cur_tx = lp->next_tx;
- lp->next_tx = -1;
+ if (lp->cur_tx != -1 || lp->next_tx == -1)
+ return 0;
- /* start sending */
- ACOMMAND(TXcmd | (lp->cur_tx << 3));
+ BUGLVL(D_TX) arcnet_dump_packet(dev, lp->next_tx, "go_tx");
- dev->trans_start = jiffies;
- lp->stats.tx_packets++;
- lp->lasttrans_dest = lp->lastload_dest;
- lp->lastload_dest = 0;
- lp->intmask |= TXFREEflag;
+ lp->cur_tx = lp->next_tx;
+ lp->next_tx = -1;
- return 1;
+ /* start sending */
+ ACOMMAND(TXcmd | (lp->cur_tx << 3));
+
+ dev->trans_start = jiffies;
+ lp->stats.tx_packets++;
+ lp->lasttrans_dest = lp->lastload_dest;
+ lp->lastload_dest = 0;
+ lp->intmask |= TXFREEflag;
+
+ return 1;
}
*/
void arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- struct net_device *dev = dev_id;
- struct arcnet_local *lp;
- int recbuf, status, didsomething, boguscount;
-
- BUGMSG(D_DURING, "\n");
-
- if (dev == NULL)
- {
- BUGMSG(D_DURING, "arcnet: irq %d for unknown device.\n", irq);
- return;
- }
-
- BUGMSG(D_DURING, "in arcnet_interrupt\n");
-
- lp = (struct arcnet_local *)dev->priv;
- if (!lp)
- {
- BUGMSG(D_DURING, "arcnet: irq ignored due to missing lp.\n");
- return;
- }
-
- /*
- * RESET flag was enabled - if !dev->start, we must clear it right
- * away (but nothing else).
- */
- if (!dev->start)
- {
- if (ASTATUS() & RESETflag)
- ACOMMAND(CFLAGScmd | RESETclear);
- AINTMASK(0);
- return;
- }
-
-
- if (dev->interrupt)
- {
- BUGMSG(D_NORMAL, "DRIVER PROBLEM! Nested arcnet interrupts!\n");
- return; /* don't even try. */
- }
-
- dev->interrupt = 1;
-
- BUGMSG(D_DURING, "in arcnet_inthandler (status=%Xh, intmask=%Xh)\n",
- ASTATUS(), lp->intmask);
-
- boguscount = 3;
- do
- {
- status = ASTATUS();
- didsomething = 0;
+ struct net_device *dev = dev_id;
+ struct arcnet_local *lp;
+ int recbuf, status, didsomething, boguscount;
+
+ BUGMSG(D_DURING, "\n");
+
+ if (dev == NULL) {
+ BUGMSG(D_DURING, "arcnet: irq %d for unknown device.\n", irq);
+ return;
+ }
+ BUGMSG(D_DURING, "in arcnet_interrupt\n");
+ lp = (struct arcnet_local *) dev->priv;
+ if (!lp) {
+ BUGMSG(D_DURING, "arcnet: irq ignored due to missing lp.\n");
+ return;
+ }
/*
- * RESET flag was enabled - card is resetting and if RX is
- * disabled, it's NOT because we just got a packet.
- *
- * The card is in an undefined state. Clear it out and start over.
+ * RESET flag was enabled - if !dev->start, we must clear it right
+ * away (but nothing else).
*/
- if (status & RESETflag)
- {
- BUGMSG(D_NORMAL, "spurious reset (status=%Xh)\n", status);
- arcnet_close(dev);
- arcnet_open(dev);
-
- /* get out of the interrupt handler! */
- break;
+ if (!dev->start) {
+ if (ASTATUS() & RESETflag)
+ ACOMMAND(CFLAGScmd | RESETclear);
+ AINTMASK(0);
+ return;
}
-
-
- /*
- * RX is inhibited - we must have received something. Prepare to
- * receive into the next buffer.
- *
- * We don't actually copy the received packet from the card until
- * after the transmit handler runs (and possibly launches the next
- * tx); this should improve latency slightly if we get both types
- * of interrupts at once.
- */
- recbuf = -1;
- if (status & lp->intmask & NORXflag)
- {
- recbuf = lp->cur_rx;
- BUGMSG(D_DURING, "Buffer #%d: receive irq (status=%Xh)\n",
- recbuf, status);
-
- lp->cur_rx = get_arcbuf(dev);
- if (lp->cur_rx != -1)
- {
- BUGMSG(D_DURING, "enabling receive to buffer #%d\n",
- lp->cur_rx);
- ACOMMAND(RXcmd | (lp->cur_rx << 3) | RXbcasts);
- }
-
- didsomething++;
+ if (dev->interrupt) {
+ BUGMSG(D_NORMAL, "DRIVER PROBLEM! Nested arcnet interrupts!\n");
+ return; /* don't even try. */
}
-
-
- /* a transmit finished, and we're interested in it. */
- if (status & lp->intmask & TXFREEflag)
- {
- lp->intmask &= ~TXFREEflag;
-
- BUGMSG(D_DURING, "TX IRQ (stat=%Xh)\n", status);
-
- if (lp->cur_tx != -1 && !(status & TXACKflag))
- {
- if (lp->lasttrans_dest != 0)
- {
- BUGMSG(D_EXTRA, "transmit was not acknowledged! "
- "(status=%Xh, dest=%02Xh)\n",
- status, lp->lasttrans_dest);
- lp->stats.tx_errors++;
- lp->stats.tx_carrier_errors++;
+ dev->interrupt = 1;
+
+ BUGMSG(D_DURING, "in arcnet_inthandler (status=%Xh, intmask=%Xh)\n",
+ ASTATUS(), lp->intmask);
+
+ boguscount = 3;
+ do {
+ status = ASTATUS();
+ didsomething = 0;
+
+ /*
+ * RESET flag was enabled - card is resetting and if RX is
+ * disabled, it's NOT because we just got a packet.
+ *
+ * The card is in an undefined state. Clear it out and start over.
+ */
+ if (status & RESETflag) {
+ BUGMSG(D_NORMAL, "spurious reset (status=%Xh)\n", status);
+ arcnet_close(dev);
+ arcnet_open(dev);
+
+ /* get out of the interrupt handler! */
+ break;
}
- else
- {
- BUGMSG(D_DURING,
- "broadcast was not acknowledged; that's normal "
- "(status=%Xh, dest=%02Xh)\n",
- status, lp->lasttrans_dest);
+ /*
+ * RX is inhibited - we must have received something. Prepare to
+ * receive into the next buffer.
+ *
+ * We don't actually copy the received packet from the card until
+ * after the transmit handler runs (and possibly launches the next
+ * tx); this should improve latency slightly if we get both types
+ * of interrupts at once.
+ */
+ recbuf = -1;
+ if (status & lp->intmask & NORXflag) {
+ recbuf = lp->cur_rx;
+ BUGMSG(D_DURING, "Buffer #%d: receive irq (status=%Xh)\n",
+ recbuf, status);
+
+ lp->cur_rx = get_arcbuf(dev);
+ if (lp->cur_rx != -1) {
+ BUGMSG(D_DURING, "enabling receive to buffer #%d\n",
+ lp->cur_rx);
+ ACOMMAND(RXcmd | (lp->cur_rx << 3) | RXbcasts);
+ }
+ didsomething++;
}
- }
-
- if (lp->cur_tx != -1)
- release_arcbuf(dev, lp->cur_tx);
-
- lp->cur_tx = -1;
- didsomething++;
-
- /* send another packet if there is one */
- go_tx(dev);
-
- /* continue a split packet, if any */
- if (lp->outgoing.proto && lp->outgoing.proto->continue_tx)
- {
- int txbuf = get_arcbuf(dev);
- if (txbuf != -1)
- {
- if (lp->outgoing.proto->continue_tx(dev, txbuf))
- {
- /* that was the last segment */
- lp->stats.tx_bytes += lp->outgoing.skb->len;
- dev_kfree_skb(lp->outgoing.skb);
- lp->outgoing.proto = NULL;
- }
-
- lp->next_tx = txbuf;
+ /* a transmit finished, and we're interested in it. */
+ if (status & lp->intmask & TXFREEflag) {
+ lp->intmask &= ~TXFREEflag;
+
+ BUGMSG(D_DURING, "TX IRQ (stat=%Xh)\n", status);
+
+ if (lp->cur_tx != -1 && !(status & TXACKflag)) {
+ if (lp->lasttrans_dest != 0) {
+ BUGMSG(D_EXTRA, "transmit was not acknowledged! "
+ "(status=%Xh, dest=%02Xh)\n",
+ status, lp->lasttrans_dest);
+ lp->stats.tx_errors++;
+ lp->stats.tx_carrier_errors++;
+ } else {
+ BUGMSG(D_DURING,
+ "broadcast was not acknowledged; that's normal "
+ "(status=%Xh, dest=%02Xh)\n",
+ status, lp->lasttrans_dest);
+ }
+ }
+ if (lp->cur_tx != -1)
+ release_arcbuf(dev, lp->cur_tx);
+
+ lp->cur_tx = -1;
+ didsomething++;
+
+ /* send another packet if there is one */
+ go_tx(dev);
+
+ /* continue a split packet, if any */
+ if (lp->outgoing.proto && lp->outgoing.proto->continue_tx) {
+ int txbuf = get_arcbuf(dev);
+ if (txbuf != -1) {
+ if (lp->outgoing.proto->continue_tx(dev, txbuf)) {
+ /* that was the last segment */
+ lp->stats.tx_bytes += lp->outgoing.skb->len;
+ dev_kfree_skb(lp->outgoing.skb);
+ lp->outgoing.proto = NULL;
+ }
+ lp->next_tx = txbuf;
+ }
+ }
+ /* inform upper layers of idleness, if necessary */
+ if (lp->cur_tx == -1) {
+ dev->tbusy = 0;
+ mark_bh(NET_BH);
+ }
}
- }
-
- /* inform upper layers of idleness, if necessary */
- if (lp->cur_tx == -1)
- {
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
- }
+ /* now process the received packet, if any */
+ if (recbuf != -1) {
+ BUGLVL(D_RX) arcnet_dump_packet(dev, recbuf, "rx irq");
- /* now process the received packet, if any */
- if (recbuf != -1)
- {
- BUGLVL(D_RX) arcnet_dump_packet(dev, recbuf, "rx irq");
-
- arcnet_rx(dev, recbuf);
- release_arcbuf(dev, recbuf);
+ arcnet_rx(dev, recbuf);
+ release_arcbuf(dev, recbuf);
- didsomething++;
- }
-
- if (status & lp->intmask & RECONflag)
- {
- ACOMMAND(CFLAGScmd | CONFIGclear);
- lp->stats.tx_carrier_errors++;
-
- BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n",
- status);
-
- /* is the RECON info empty or old? */
- if (!lp->first_recon || !lp->last_recon ||
- jiffies - lp->last_recon > HZ * 10)
- {
- if (lp->network_down)
- BUGMSG(D_NORMAL, "reconfiguration detected: cabling restored?\n");
- lp->first_recon = lp->last_recon = jiffies;
- lp->num_recons = lp->network_down = 0;
-
- BUGMSG(D_DURING, "recon: clearing counters.\n");
- }
- else
- { /* add to current RECON counter */
- lp->last_recon = jiffies;
- lp->num_recons++;
-
- BUGMSG(D_DURING, "recon: counter=%d, time=%lds, net=%d\n",
- lp->num_recons,
- (lp->last_recon - lp->first_recon) / HZ,
- lp->network_down);
-
- /* if network is marked up;
- * and first_recon and last_recon are 60+ apart;
- * and the average no. of recons counted is
- * > RECON_THRESHOLD/min;
- * then print a warning message.
- */
- if (!lp->network_down
- && (lp->last_recon - lp->first_recon) <= HZ * 60
- && lp->num_recons >= RECON_THRESHOLD)
- {
- lp->network_down = 1;
- BUGMSG(D_NORMAL, "many reconfigurations detected: cabling problem?\n");
+ didsomething++;
}
- else if (!lp->network_down
- && lp->last_recon - lp->first_recon > HZ * 60)
- {
- /* reset counters if we've gone for over a minute. */
- lp->first_recon = lp->last_recon;
- lp->num_recons = 1;
+ if (status & lp->intmask & RECONflag) {
+ ACOMMAND(CFLAGScmd | CONFIGclear);
+ lp->stats.tx_carrier_errors++;
+
+ BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n",
+ status);
+
+ /* is the RECON info empty or old? */
+ if (!lp->first_recon || !lp->last_recon ||
+ jiffies - lp->last_recon > HZ * 10) {
+ if (lp->network_down)
+ BUGMSG(D_NORMAL, "reconfiguration detected: cabling restored?\n");
+ lp->first_recon = lp->last_recon = jiffies;
+ lp->num_recons = lp->network_down = 0;
+
+ BUGMSG(D_DURING, "recon: clearing counters.\n");
+ } else { /* add to current RECON counter */
+ lp->last_recon = jiffies;
+ lp->num_recons++;
+
+ BUGMSG(D_DURING, "recon: counter=%d, time=%lds, net=%d\n",
+ lp->num_recons,
+ (lp->last_recon - lp->first_recon) / HZ,
+ lp->network_down);
+
+ /* if network is marked up;
+ * and first_recon and last_recon are 60+ apart;
+ * and the average no. of recons counted is
+ * > RECON_THRESHOLD/min;
+ * then print a warning message.
+ */
+ if (!lp->network_down
+ && (lp->last_recon - lp->first_recon) <= HZ * 60
+ && lp->num_recons >= RECON_THRESHOLD) {
+ lp->network_down = 1;
+ BUGMSG(D_NORMAL, "many reconfigurations detected: cabling problem?\n");
+ } else if (!lp->network_down
+ && lp->last_recon - lp->first_recon > HZ * 60) {
+ /* reset counters if we've gone for over a minute. */
+ lp->first_recon = lp->last_recon;
+ lp->num_recons = 1;
+ }
+ }
+ } else if (lp->network_down && jiffies - lp->last_recon > HZ * 10) {
+ if (lp->network_down)
+ BUGMSG(D_NORMAL, "cabling restored?\n");
+ lp->first_recon = lp->last_recon = 0;
+ lp->num_recons = lp->network_down = 0;
+
+ BUGMSG(D_DURING, "not recon: clearing counters anyway.\n");
}
- }
- }
- else if (lp->network_down && jiffies - lp->last_recon > HZ * 10)
- {
- if (lp->network_down)
- BUGMSG(D_NORMAL, "cabling restored?\n");
- lp->first_recon = lp->last_recon = 0;
- lp->num_recons = lp->network_down = 0;
-
- BUGMSG(D_DURING, "not recon: clearing counters anyway.\n");
}
- }
- while (--boguscount && didsomething);
+ while (--boguscount && didsomething);
- BUGMSG(D_DURING, "arcnet_interrupt complete (status=%Xh, count=%d)\n",
- ASTATUS(), boguscount);
- BUGMSG(D_DURING, "\n");
+ BUGMSG(D_DURING, "arcnet_interrupt complete (status=%Xh, count=%d)\n",
+ ASTATUS(), boguscount);
+ BUGMSG(D_DURING, "\n");
- AINTMASK(0);
- udelay(1);
- AINTMASK(lp->intmask);
+ AINTMASK(0);
+ udelay(1);
+ AINTMASK(lp->intmask);
- dev->interrupt = 0;
+ dev->interrupt = 0;
}
*/
void arcnet_rx(struct net_device *dev, int bufnum)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- struct archdr pkt;
- struct arc_rfc1201 *soft;
- int length, ofs;
-
- soft = &pkt.soft.rfc1201;
-
- lp->hw.copy_from_card(dev, bufnum, 0, &pkt, sizeof(ARC_HDR_SIZE));
- if (pkt.hard.offset[0])
- {
- ofs = pkt.hard.offset[0];
- length = 256 - ofs;
- }
- else
- {
- ofs = pkt.hard.offset[1];
- length = 512 - ofs;
- }
-
- /* get the full header, if possible */
- if (sizeof(pkt.soft) < length)
- lp->hw.copy_from_card(dev, bufnum, ofs, soft, sizeof(pkt.soft));
- else
- {
- memset(&pkt.soft, 0, sizeof(pkt.soft));
- lp->hw.copy_from_card(dev, bufnum, ofs, soft, length);
- }
-
- BUGMSG(D_DURING, "Buffer #%d: received packet from %02Xh to %02Xh "
- "(%d+4 bytes)\n",
- bufnum, pkt.hard.source, pkt.hard.dest, length);
-
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += length + ARC_HDR_SIZE;
-
- /* call the right receiver for the protocol */
- if (arc_proto_map[soft->proto] != &arc_proto_null)
- {
- BUGLVL(D_PROTO)
- {
- struct ArcProto
- *oldp = arc_proto_map[lp->default_proto[pkt.hard.source]],
- *newp = arc_proto_map[soft->proto];
-
- if (oldp != newp)
- {
- BUGMSG(D_PROTO,
- "got protocol %02Xh; encap for host %02Xh is now '%c'"
- " (was '%c')\n", soft->proto, pkt.hard.source,
- newp->suffix, oldp->suffix);
- }
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct archdr pkt;
+ struct arc_rfc1201 *soft;
+ int length, ofs;
+
+ soft = &pkt.soft.rfc1201;
+
+ lp->hw.copy_from_card(dev, bufnum, 0, &pkt, sizeof(ARC_HDR_SIZE));
+ if (pkt.hard.offset[0]) {
+ ofs = pkt.hard.offset[0];
+ length = 256 - ofs;
+ } else {
+ ofs = pkt.hard.offset[1];
+ length = 512 - ofs;
+ }
+
+ /* get the full header, if possible */
+ if (sizeof(pkt.soft) < length)
+ lp->hw.copy_from_card(dev, bufnum, ofs, soft, sizeof(pkt.soft));
+ else {
+ memset(&pkt.soft, 0, sizeof(pkt.soft));
+ lp->hw.copy_from_card(dev, bufnum, ofs, soft, length);
+ }
+
+ BUGMSG(D_DURING, "Buffer #%d: received packet from %02Xh to %02Xh "
+ "(%d+4 bytes)\n",
+ bufnum, pkt.hard.source, pkt.hard.dest, length);
+
+ lp->stats.rx_packets++;
+ lp->stats.rx_bytes += length + ARC_HDR_SIZE;
+
+ /* call the right receiver for the protocol */
+ if (arc_proto_map[soft->proto] != &arc_proto_null) {
+ BUGLVL(D_PROTO) {
+ struct ArcProto
+ *oldp = arc_proto_map[lp->default_proto[pkt.hard.source]],
+ *newp = arc_proto_map[soft->proto];
+
+ if (oldp != newp) {
+ BUGMSG(D_PROTO,
+ "got protocol %02Xh; encap for host %02Xh is now '%c'"
+ " (was '%c')\n", soft->proto, pkt.hard.source,
+ newp->suffix, oldp->suffix);
+ }
+ }
+
+ /* broadcasts will always be done with the last-used encap. */
+ lp->default_proto[0] = soft->proto;
+
+ /* in striking contrast, the following isn't a hack. */
+ lp->default_proto[pkt.hard.source] = soft->proto;
}
+ /* call the protocol-specific receiver. */
+ arc_proto_map[soft->proto]->rx(dev, bufnum, &pkt, length);
- /* broadcasts will always be done with the last-used encap. */
- lp->default_proto[0] = soft->proto;
-
- /* in striking contrast, the following isn't a hack. */
- lp->default_proto[pkt.hard.source] = soft->proto;
- }
-
- /* call the protocol-specific receiver. */
- arc_proto_map[soft->proto]->rx(dev, bufnum, &pkt, length);
-
- /*
- * If any worthwhile packets have been received, a mark_bh(NET_BH) has
- * been done by netif_rx and Linux will handle them after we return.
- */
+ /*
+ * If any worthwhile packets have been received, a mark_bh(NET_BH) has
+ * been done by netif_rx and Linux will handle them after we return.
+ */
}
*/
static struct net_device_stats *arcnet_get_stats(struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
- return &lp->stats;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ return &lp->stats;
}
static void null_rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length)
{
- BUGMSG(D_PROTO,
- "rx: don't know how to deal with proto %02Xh from host %02Xh.\n",
- pkthdr->soft.rfc1201.proto, pkthdr->hard.source);
+ BUGMSG(D_PROTO,
+ "rx: don't know how to deal with proto %02Xh from host %02Xh.\n",
+ pkthdr->soft.rfc1201.proto, pkthdr->hard.source);
}
static int null_build_header(struct sk_buff *skb, unsigned short type,
uint8_t daddr)
{
- struct net_device *dev = skb->dev;
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
-
- BUGMSG(D_PROTO,
- "tx: can't build header for encap %02Xh; load a protocol driver.\n",
- lp->default_proto[daddr]);
-
- /* always fails */
- return 0;
+ struct net_device *dev = skb->dev;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+
+ BUGMSG(D_PROTO,
+ "tx: can't build header for encap %02Xh; load a protocol driver.\n",
+ lp->default_proto[daddr]);
+
+ /* always fails */
+ return 0;
}
/* the "do nothing" prepare_tx function warns that there's nothing to do. */
static int null_prepare_tx(struct net_device *dev, struct archdr *pkt,
- int length, int bufnum)
+ int length, int bufnum)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- struct arc_hardware newpkt;
-
- BUGMSG(D_PROTO, "tx: no encap for this host; load a protocol driver.\n");
-
- /* send a packet to myself -- will never get received, of course */
- newpkt.source = newpkt.dest = dev->dev_addr[0];
-
- /* only one byte of actual data (and it's random) */
- newpkt.offset[0] = 0xFF;
-
- lp->hw.copy_to_card(dev, bufnum, 0, &newpkt, ARC_HDR_SIZE);
-
- return 1; /* done */
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arc_hardware newpkt;
+
+ BUGMSG(D_PROTO, "tx: no encap for this host; load a protocol driver.\n");
+
+ /* send a packet to myself -- will never get received, of course */
+ newpkt.source = newpkt.dest = dev->dev_addr[0];
+
+ /* only one byte of actual data (and it's random) */
+ newpkt.offset[0] = 0xFF;
+
+ lp->hw.copy_to_card(dev, bufnum, 0, &newpkt, ARC_HDR_SIZE);
+
+ return 1; /* done */
}
#define VERSION "arcnet: COM20020 ISA support (by David Woodhouse et al.)\n"
-
+
/*
* We cannot (yet) probe for an IO mapped card, although we can check that
*/
static int __init com20020isa_probe(struct net_device *dev)
{
- int ioaddr;
- unsigned long airqmask;
+ int ioaddr;
+ unsigned long airqmask;
#ifndef MODULE
- arcnet_init();
+ arcnet_init();
#endif
- BUGLVL(D_NORMAL) printk(VERSION);
-
- ioaddr = dev->base_addr;
- if (!ioaddr)
- {
- BUGMSG(D_NORMAL, "No autoprobe (yet) for IO mapped cards; you "
- "must specify the base address!\n");
- return -ENODEV;
- }
-
- if (check_region(ioaddr, ARCNET_TOTAL_SIZE))
- {
- BUGMSG(D_NORMAL, "IO region %xh-%xh already allocated.\n",
- ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
- return -ENXIO;
- }
-
- if (ASTATUS() == 0xFF)
- {
- BUGMSG(D_NORMAL, "IO address %x empty\n", ioaddr);
- return -ENODEV;
- }
-
- if (com20020_check(dev))
- return -ENODEV;
-
- if (!dev->irq)
- {
- /* if we do this, we're sure to get an IRQ since the
- * card has just reset and the NORXflag is on until
- * we tell it to start receiving.
- */
- BUGMSG(D_INIT_REASONS, "intmask was %02Xh\n", inb(_INTMASK));
- outb(0, _INTMASK);
- airqmask = probe_irq_on();
- outb(NORXflag, _INTMASK);
- udelay(1);
- outb(0, _INTMASK);
- dev->irq = probe_irq_off(airqmask);
-
- if (dev->irq <= 0)
- {
- BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed first time\n");
- airqmask = probe_irq_on();
- outb(NORXflag, _INTMASK);
- udelay(5);
- outb(0, _INTMASK);
- dev->irq = probe_irq_off(airqmask);
- if (dev->irq <= 0)
- {
- BUGMSG(D_NORMAL, "Autoprobe IRQ failed.\n");
+ BUGLVL(D_NORMAL) printk(VERSION);
+
+ ioaddr = dev->base_addr;
+ if (!ioaddr) {
+ BUGMSG(D_NORMAL, "No autoprobe (yet) for IO mapped cards; you "
+ "must specify the base address!\n");
+ return -ENODEV;
+ }
+ if (check_region(ioaddr, ARCNET_TOTAL_SIZE)) {
+ BUGMSG(D_NORMAL, "IO region %xh-%xh already allocated.\n",
+ ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
+ return -ENXIO;
+ }
+ if (ASTATUS() == 0xFF) {
+ BUGMSG(D_NORMAL, "IO address %x empty\n", ioaddr);
return -ENODEV;
- }
}
- }
+ if (com20020_check(dev))
+ return -ENODEV;
- return com20020_found(dev, 0);
+ if (!dev->irq) {
+ /* if we do this, we're sure to get an IRQ since the
+ * card has just reset and the NORXflag is on until
+ * we tell it to start receiving.
+ */
+ BUGMSG(D_INIT_REASONS, "intmask was %02Xh\n", inb(_INTMASK));
+ outb(0, _INTMASK);
+ airqmask = probe_irq_on();
+ outb(NORXflag, _INTMASK);
+ udelay(1);
+ outb(0, _INTMASK);
+ dev->irq = probe_irq_off(airqmask);
+
+ if (dev->irq <= 0) {
+ BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed first time\n");
+ airqmask = probe_irq_on();
+ outb(NORXflag, _INTMASK);
+ udelay(5);
+ outb(0, _INTMASK);
+ dev->irq = probe_irq_off(airqmask);
+ if (dev->irq <= 0) {
+ BUGMSG(D_NORMAL, "Autoprobe IRQ failed.\n");
+ return -ENODEV;
+ }
+ }
+ }
+ return com20020_found(dev, 0);
}
static void com20020isa_open_close(struct net_device *dev, bool open)
{
- if (open)
- MOD_INC_USE_COUNT;
- else
- MOD_DEC_USE_COUNT;
+ if (open)
+ MOD_INC_USE_COUNT;
+ else
+ MOD_DEC_USE_COUNT;
}
int init_module(void)
{
- struct net_device *dev;
- struct arcnet_local *lp;
- int err;
-
- dev = dev_alloc(device ? : "arc%d", &err);
- if (!dev)
- return err;
- lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
- if (!lp)
- return -ENOMEM;
- memset(lp, 0, sizeof(struct arcnet_local));
-
- if (node && node != 0xff)
- dev->dev_addr[0] = node;
-
- lp->backplane = backplane;
- lp->clock = clock & 7;
- lp->timeout = timeout & 3;
- lp->hw.open_close_ll = com20020isa_open_close;
-
- dev->base_addr = io;
- dev->irq = irq;
-
- if (dev->irq == 2)
- dev->irq = 9;
-
- if (com20020isa_probe(dev))
- return -EIO;
-
- my_dev = dev;
- return 0;
+ struct net_device *dev;
+ struct arcnet_local *lp;
+ int err;
+
+ dev = dev_alloc(device ? : "arc%d", &err);
+ if (!dev)
+ return err;
+ lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
+ if (!lp)
+ return -ENOMEM;
+ memset(lp, 0, sizeof(struct arcnet_local));
+
+ if (node && node != 0xff)
+ dev->dev_addr[0] = node;
+
+ lp->backplane = backplane;
+ lp->clock = clock & 7;
+ lp->timeout = timeout & 3;
+ lp->hw.open_close_ll = com20020isa_open_close;
+
+ dev->base_addr = io;
+ dev->irq = irq;
+
+ if (dev->irq == 2)
+ dev->irq = 9;
+
+ if (com20020isa_probe(dev))
+ return -EIO;
+
+ my_dev = dev;
+ return 0;
}
void cleanup_module(void)
return 1;
dev = alloc_bootmem(sizeof(struct net_device) + sizeof(struct arcnet_local) + 10);
memset(dev, 0, sizeof(struct net_device) + sizeof(struct arcnet_local) + 10);
- lp = dev->priv = (struct arcnet_local *)(dev+1);
- dev->name = (char *)(lp+1);
+ lp = dev->priv = (struct arcnet_local *) (dev + 1);
+ dev->name = (char *) (lp + 1);
dev->init = com20020isa_probe;
switch (ints[0]) {
default: /* ERROR */
printk("com90xx: Too many arguments.\n");
- case 6: /* Timeout */
+ case 6: /* Timeout */
lp->timeout = ints[6];
- case 5: /* CKP value */
+ case 5: /* CKP value */
lp->clock = ints[5];
- case 4: /* Backplane flag */
+ case 4: /* Backplane flag */
lp->backplane = ints[4];
- case 3: /* Node ID */
+ case 3: /* Node ID */
dev->dev_addr[0] = ints[3];
- case 2: /* IRQ */
+ case 2: /* IRQ */
dev->irq = ints[2];
- case 1: /* IO address */
+ case 1: /* IO address */
dev->base_addr = ints[1];
}
if (*s)
#define VERSION "arcnet: COM20020 PCI support\n"
#ifdef MODULE
-static struct net_device *cards[16];
+#define MAX_CARDS 16
+static struct net_device *cards[MAX_CARDS];
static int numcards;
#endif
static void com20020pci_open_close(struct net_device *dev, bool open)
{
- if (open)
- MOD_INC_USE_COUNT;
- else
- MOD_DEC_USE_COUNT;
+ if (open)
+ MOD_INC_USE_COUNT;
+ else
+ MOD_DEC_USE_COUNT;
}
/*
*/
static int __init com20020pci_probe(char *name_template, int node, int backplane, int clock, int timeout)
{
- struct net_device *dev;
- struct arcnet_local *lp;
- struct pci_dev *pdev = NULL;
- int ioaddr, gotone = 0, err;
-
- BUGLVL(D_NORMAL) printk(VERSION);
-
- while ((pdev = pci_find_device(0x1571, 0xa004, pdev)))
- {
- if (pci_enable_device(pdev))
- continue;
- dev = dev_alloc(name_template ? : "arc%d", &err);
- if (!dev)
- return err;
- lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
- if (!lp)
- return -ENOMEM;
- memset(lp, 0, sizeof(struct arcnet_local));
-
- ioaddr = pdev->resource[2].start;
- dev->base_addr = ioaddr;
- dev->irq = pdev->irq;
- dev->dev_addr[0] = node;
- lp->backplane = backplane;
- lp->clock = clock;
- lp->timeout = timeout;
- lp->hw.open_close_ll = com20020pci_open_close;
-
- BUGMSG(D_INIT, "PCI BIOS reports a device at %Xh, IRQ %d\n",
- ioaddr, dev->irq);
-
- if (check_region(ioaddr, ARCNET_TOTAL_SIZE))
- {
- BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
- ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
- continue;
- }
-
- if (ASTATUS() == 0xFF)
- {
- BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
- "but seems empty!\n", ioaddr);
- continue;
- }
-
- if (com20020_check(dev))
- continue;
-
- if (!com20020_found(dev, SA_SHIRQ))
- {
+ struct net_device *dev;
+ struct arcnet_local *lp;
+ struct pci_dev *pdev = NULL;
+ int ioaddr, gotone = 0, err;
+
+ BUGLVL(D_NORMAL) printk(VERSION);
+
+ while ((pdev = pci_find_device(0x1571, 0xa004, pdev))) {
+ if (pci_enable_device(pdev))
+ continue;
+ dev = dev_alloc(name_template ? : "arc%d", &err);
+ if (!dev)
+ return err;
+ lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
+ if (!lp)
+ return -ENOMEM;
+ memset(lp, 0, sizeof(struct arcnet_local));
+
+ ioaddr = pdev->resource[2].start;
+ dev->base_addr = ioaddr;
+ dev->irq = pdev->irq;
+ dev->dev_addr[0] = node;
+ lp->backplane = backplane;
+ lp->clock = clock;
+ lp->timeout = timeout;
+ lp->hw.open_close_ll = com20020pci_open_close;
+
+ BUGMSG(D_INIT, "PCI BIOS reports a device at %Xh, IRQ %d\n",
+ ioaddr, dev->irq);
+
+ if (check_region(ioaddr, ARCNET_TOTAL_SIZE)) {
+ BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
+ ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
+ continue;
+ }
+ if (ASTATUS() == 0xFF) {
+ BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
+ "but seems empty!\n", ioaddr);
+ continue;
+ }
+ if (com20020_check(dev))
+ continue;
+
+ if (!com20020_found(dev, SA_SHIRQ)) {
#ifdef MODULE
- cards[numcards++] = dev;
+ if(numcards==MAX_CARDS)
+ printk(KERN_WARNING "com20020pci: Too many cards. Ignoring.\n");
+ else
+ cards[numcards++] = dev;
#endif
- gotone++;
+ gotone++;
+ }
}
- }
-
- return gotone ? 0 : -ENODEV;
+
+ return gotone ? 0 : -ENODEV;
}
int init_module(void)
{
- return com20020pci_probe(device, node, backplane, clock & 7, timeout & 3);
+ return com20020pci_probe(device, node, backplane, clock & 7, timeout & 3);
}
void cleanup_module(void)
{
- struct net_device *dev;
- int count;
-
- for (count = 0; count < numcards; count++)
- {
- dev = cards[count];
-
- if (dev->start)
- dev->stop(dev);
-
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
- unregister_netdev(dev);
- kfree(dev->priv);
- kfree(dev);
- }
+ struct net_device *dev;
+ int count;
+
+ for (count = 0; count < numcards; count++) {
+ dev = cards[count];
+
+ if (dev->start)
+ dev->stop(dev);
+
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+ unregister_netdev(dev);
+ kfree(dev->priv);
+ kfree(dev);
+ }
}
#else
"156.25 Kb/s", "Reserved", "Reserved",
"Reserved"};
-static void com20020_command (struct net_device *dev, int command);
-static int com20020_status (struct net_device *dev);
-static void com20020_setmask (struct net_device *dev, int mask);
-static int com20020_reset (struct net_device *dev, int really_reset);
+static void com20020_command(struct net_device *dev, int command);
+static int com20020_status(struct net_device *dev);
+static void com20020_setmask(struct net_device *dev, int mask);
+static int com20020_reset(struct net_device *dev, int really_reset);
static void com20020_openclose(struct net_device *dev, bool open);
-static void com20020_copy_to_card (struct net_device *dev, int bufnum,
- int offset, void *buf, int count);
+static void com20020_copy_to_card(struct net_device *dev, int bufnum,
+ int offset, void *buf, int count);
static void com20020_copy_from_card(struct net_device *dev, int bufnum,
int offset, void *buf, int count);
static void com20020_set_mc_list(struct net_device *dev);
static void com20020_copy_from_card(struct net_device *dev, int bufnum,
int offset, void *buf, int count)
{
- int ioaddr = dev->base_addr, ofs = 512 * bufnum + offset;
-
- /* set up the address register */
- outb((ofs >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI);
- outb(ofs & 0xff, _ADDR_LO);
-
- /* copy the data */
- TIME("insb", count, insb(_MEMDATA, buf, count));
+ int ioaddr = dev->base_addr, ofs = 512 * bufnum + offset;
+
+ /* set up the address register */
+ outb((ofs >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI);
+ outb(ofs & 0xff, _ADDR_LO);
+
+ /* copy the data */
+ TIME("insb", count, insb(_MEMDATA, buf, count));
}
static void com20020_copy_to_card(struct net_device *dev, int bufnum,
int offset, void *buf, int count)
{
- int ioaddr = dev->base_addr, ofs = 512 * bufnum + offset;
-
- /* set up the address register */
- outb((ofs >> 8) | AUTOINCflag, _ADDR_HI);
- outb(ofs & 0xff, _ADDR_LO);
-
- /* copy the data */
- TIME("outsb", count, outsb(_MEMDATA, buf, count));
+ int ioaddr = dev->base_addr, ofs = 512 * bufnum + offset;
+
+ /* set up the address register */
+ outb((ofs >> 8) | AUTOINCflag, _ADDR_HI);
+ outb(ofs & 0xff, _ADDR_LO);
+
+ /* copy the data */
+ TIME("outsb", count, outsb(_MEMDATA, buf, count));
}
/* Reset the card and check some basic stuff during the detection stage. */
int __init com20020_check(struct net_device *dev)
{
- int ioaddr = dev->base_addr, status;
- struct arcnet_local *lp = dev->priv;
-
- ARCRESET0;
- mdelay(RESETtime);
-
- lp->setup = lp->clock << 1;
-
- REGSETUP;
- SETCONF(lp->config);
- outb(lp->setup, ioaddr + 7);
-
- lp->config = 0x21 | (lp->timeout << 3) | (lp->backplane << 2);
- /* set node ID to 0x42 (but transmitter is disabled, so it's okay) */
- SETCONF(lp->config);
- outb(0x42, ioaddr + 7);
-
- status = ASTATUS();
-
- if ((status & 0x99) != (NORXflag | TXFREEflag | RESETflag))
- {
- BUGMSG(D_NORMAL, "status invalid (%Xh).\n", status);
- return -ENODEV;
- }
-
- BUGMSG(D_INIT_REASONS, "status after reset: %X\n", status);
-
- /* Enable TX */
- outb(0x39, _CONFIG);
- outb(inb(ioaddr + 8), ioaddr + 7);
-
- ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
-
- status = ASTATUS();
- BUGMSG(D_INIT_REASONS, "status after reset acknowledged: %X\n",
- status);
-
- /* Read first location of memory */
- outb(0 | RDDATAflag | AUTOINCflag, _ADDR_HI);
- outb(0, _ADDR_LO);
-
- if ((status = inb(_MEMDATA)) != TESTvalue)
- {
- BUGMSG(D_NORMAL, "Signature byte not found (%02Xh != D1h).\n",
+ int ioaddr = dev->base_addr, status;
+ struct arcnet_local *lp = dev->priv;
+
+ ARCRESET0;
+ mdelay(RESETtime);
+
+ lp->setup = lp->clock << 1;
+
+ REGSETUP;
+ SETCONF(lp->config);
+ outb(lp->setup, ioaddr + 7);
+
+ lp->config = 0x21 | (lp->timeout << 3) | (lp->backplane << 2);
+ /* set node ID to 0x42 (but transmitter is disabled, so it's okay) */
+ SETCONF(lp->config);
+ outb(0x42, ioaddr + 7);
+
+ status = ASTATUS();
+
+ if ((status & 0x99) != (NORXflag | TXFREEflag | RESETflag)) {
+ BUGMSG(D_NORMAL, "status invalid (%Xh).\n", status);
+ return -ENODEV;
+ }
+ BUGMSG(D_INIT_REASONS, "status after reset: %X\n", status);
+
+ /* Enable TX */
+ outb(0x39, _CONFIG);
+ outb(inb(ioaddr + 8), ioaddr + 7);
+
+ ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
+
+ status = ASTATUS();
+ BUGMSG(D_INIT_REASONS, "status after reset acknowledged: %X\n",
status);
- return -ENODEV;
- }
-
- return 0;
+
+ /* Read first location of memory */
+ outb(0 | RDDATAflag | AUTOINCflag, _ADDR_HI);
+ outb(0, _ADDR_LO);
+
+ if ((status = inb(_MEMDATA)) != TESTvalue) {
+ BUGMSG(D_NORMAL, "Signature byte not found (%02Xh != D1h).\n",
+ status);
+ return -ENODEV;
+ }
+ return 0;
}
/* Set up the struct net_device associated with this card. Called after
*/
int __init com20020_found(struct net_device *dev, int shared)
{
- struct arcnet_local *lp;
- int ioaddr = dev->base_addr;
-
- /* Initialize the rest of the device structure. */
-
- lp = (struct arcnet_local *)dev->priv;
-
- lp->hw.command = com20020_command;
- lp->hw.status = com20020_status;
- lp->hw.intmask = com20020_setmask;
- lp->hw.reset = com20020_reset;
- lp->hw.open_close = com20020_openclose;
- lp->hw.copy_to_card = com20020_copy_to_card;
- lp->hw.copy_from_card = com20020_copy_from_card;
-
- dev->set_multicast_list = com20020_set_mc_list;
-
- /* Fill in the fields of the device structure with generic
- * values.
- */
- arcdev_setup(dev);
-
- if (!dev->dev_addr[0])
- dev->dev_addr[0] = inb(ioaddr + 8); /* FIXME: do this some other way! */
-
- lp->setup = lp->clock << 1;
-
- REGSETUP;
- SETCONF(lp->config);
- outb(lp->setup, ioaddr + 7);
-
- lp->config = 0x20 | (lp->timeout << 3) | (lp->backplane << 2) | 1;
- /* Default 0x38 + register: Node ID */
- SETCONF(lp->config);
- outb(dev->dev_addr[0], ioaddr + 7);
-
- /* reserve the irq */
- if (request_irq(dev->irq, &arcnet_interrupt, shared,
- "arcnet (COM20020)", dev))
- {
- BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
- return -ENODEV;
- }
-
- /* reserve the I/O region - guaranteed to work by check_region */
- request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)");
- dev->base_addr = ioaddr;
-
- BUGMSG(D_NORMAL, "COM20020: station %02Xh found at %03lXh, IRQ %d.\n",
- dev->dev_addr[0], dev->base_addr, dev->irq);
-
- if (lp->backplane)
- BUGMSG(D_NORMAL, "Using backplane mode.\n");
-
- if (lp->timeout != 3)
- BUGMSG(D_NORMAL, "Using extended timeout value of %d.\n", lp->timeout);
- if (lp->setup)
- {
- BUGMSG(D_NORMAL, "Using CKP %d - data rate %s.\n",
- lp->setup >> 1, clockrates[lp->setup >> 1]);
- }
-
- if (!dev->init && register_netdev(dev))
- {
- free_irq(dev->irq, dev);
- release_region(ioaddr, ARCNET_TOTAL_SIZE);
- return -EIO;
- }
-
- return 0;
+ struct arcnet_local *lp;
+ int ioaddr = dev->base_addr;
+
+ /* Initialize the rest of the device structure. */
+
+ lp = (struct arcnet_local *) dev->priv;
+
+ lp->hw.command = com20020_command;
+ lp->hw.status = com20020_status;
+ lp->hw.intmask = com20020_setmask;
+ lp->hw.reset = com20020_reset;
+ lp->hw.open_close = com20020_openclose;
+ lp->hw.copy_to_card = com20020_copy_to_card;
+ lp->hw.copy_from_card = com20020_copy_from_card;
+
+ dev->set_multicast_list = com20020_set_mc_list;
+
+ /* Fill in the fields of the device structure with generic
+ * values.
+ */
+ arcdev_setup(dev);
+
+ if (!dev->dev_addr[0])
+ dev->dev_addr[0] = inb(ioaddr + 8); /* FIXME: do this some other way! */
+
+ lp->setup = lp->clock << 1;
+
+ REGSETUP;
+ SETCONF(lp->config);
+ outb(lp->setup, ioaddr + 7);
+
+ lp->config = 0x20 | (lp->timeout << 3) | (lp->backplane << 2) | 1;
+ /* Default 0x38 + register: Node ID */
+ SETCONF(lp->config);
+ outb(dev->dev_addr[0], ioaddr + 7);
+
+ /* reserve the irq */
+ if (request_irq(dev->irq, &arcnet_interrupt, shared,
+ "arcnet (COM20020)", dev)) {
+ BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
+ return -ENODEV;
+ }
+ /* reserve the I/O region - guaranteed to work by check_region */
+ request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)");
+ dev->base_addr = ioaddr;
+
+ BUGMSG(D_NORMAL, "COM20020: station %02Xh found at %03lXh, IRQ %d.\n",
+ dev->dev_addr[0], dev->base_addr, dev->irq);
+
+ if (lp->backplane)
+ BUGMSG(D_NORMAL, "Using backplane mode.\n");
+
+ if (lp->timeout != 3)
+ BUGMSG(D_NORMAL, "Using extended timeout value of %d.\n", lp->timeout);
+ if (lp->setup) {
+ BUGMSG(D_NORMAL, "Using CKP %d - data rate %s.\n",
+ lp->setup >> 1, clockrates[lp->setup >> 1]);
+ }
+ if (!dev->init && register_netdev(dev)) {
+ free_irq(dev->irq, dev);
+ release_region(ioaddr, ARCNET_TOTAL_SIZE);
+ return -EIO;
+ }
+ return 0;
}
*/
static int com20020_reset(struct net_device *dev, int really_reset)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- short ioaddr = dev->base_addr;
- u_char inbyte;
-
- BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n",
- dev->name, ASTATUS());
-
- lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2);
- /* power-up defaults */
- SETCONF(lp->config);
-
- if (really_reset)
- {
- /* reset the card */
- ARCRESET;
- mdelay(RESETtime * 2); /* COM20020 seems to be slower sometimes */
- }
-
- /* clear flags & end reset */
- ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
-
- /* verify that the ARCnet signature byte is present */
-
- com20020_copy_from_card(dev, 0, 0, &inbyte, 1);
- if (inbyte != TESTvalue)
- {
- BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
- return 1;
- }
-
- /* enable extended (512-byte) packets */
- ACOMMAND(CONFIGcmd | EXTconf);
-
- /* done! return success. */
- return 0;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ short ioaddr = dev->base_addr;
+ u_char inbyte;
+
+ BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n",
+ dev->name, ASTATUS());
+
+ lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2);
+ /* power-up defaults */
+ SETCONF(lp->config);
+
+ if (really_reset) {
+ /* reset the card */
+ ARCRESET;
+ mdelay(RESETtime * 2); /* COM20020 seems to be slower sometimes */
+ }
+ /* clear flags & end reset */
+ ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
+
+ /* verify that the ARCnet signature byte is present */
+
+ com20020_copy_from_card(dev, 0, 0, &inbyte, 1);
+ if (inbyte != TESTvalue) {
+ BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
+ return 1;
+ }
+ /* enable extended (512-byte) packets */
+ ACOMMAND(CONFIGcmd | EXTconf);
+
+ /* done! return success. */
+ return 0;
}
static void com20020_setmask(struct net_device *dev, int mask)
{
- short ioaddr = dev->base_addr;
- AINTMASK(mask);
+ short ioaddr = dev->base_addr;
+ AINTMASK(mask);
}
static void com20020_command(struct net_device *dev, int cmd)
{
- short ioaddr = dev->base_addr;
- ACOMMAND(cmd);
+ short ioaddr = dev->base_addr;
+ ACOMMAND(cmd);
}
static int com20020_status(struct net_device *dev)
{
- short ioaddr = dev->base_addr;
- return ASTATUS();
+ short ioaddr = dev->base_addr;
+ return ASTATUS();
}
static void com20020_openclose(struct net_device *dev, bool open)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int ioaddr = dev->base_addr;
-
- if (open)
- MOD_INC_USE_COUNT;
- else
- {
- /* disable transmitter */
- lp->config &= ~TXENcfg;
- SETCONF(lp->config);
- MOD_DEC_USE_COUNT;
- }
- lp->hw.open_close_ll(dev, open);
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ int ioaddr = dev->base_addr;
+
+ if (open)
+ MOD_INC_USE_COUNT;
+ else {
+ /* disable transmitter */
+ lp->config &= ~TXENcfg;
+ SETCONF(lp->config);
+ MOD_DEC_USE_COUNT;
+ }
+ lp->hw.open_close_ll(dev, open);
}
*/
static void com20020_set_mc_list(struct net_device *dev)
{
- struct arcnet_local *lp = dev->priv;
- int ioaddr = dev->base_addr;
-
- if ((dev->flags & IFF_PROMISC) && (dev->flags & IFF_UP))
- { /* Enable promiscuous mode */
- if (!(lp->setup & PROMISCset))
- BUGMSG(D_NORMAL, "Setting promiscuous flag...\n");
- REGSETUP;
- SETCONF(lp->config);
- lp->setup |= PROMISCset;
- outb(lp->setup, _SETUP);
- }
- else
- /* Disable promiscuous mode, use normal mode */
- {
- if ((lp->setup & PROMISCset))
- BUGMSG(D_NORMAL, "Resetting promiscuous flag...\n");
- REGSETUP;
- SETCONF(lp->config);
- lp->setup &= ~PROMISCset;
- outb(lp->setup, _SETUP);
- }
+ struct arcnet_local *lp = dev->priv;
+ int ioaddr = dev->base_addr;
+
+ if ((dev->flags & IFF_PROMISC) && (dev->flags & IFF_UP)) { /* Enable promiscuous mode */
+ if (!(lp->setup & PROMISCset))
+ BUGMSG(D_NORMAL, "Setting promiscuous flag...\n");
+ REGSETUP;
+ SETCONF(lp->config);
+ lp->setup |= PROMISCset;
+ outb(lp->setup, _SETUP);
+ } else
+ /* Disable promiscuous mode, use normal mode */
+ {
+ if ((lp->setup & PROMISCset))
+ BUGMSG(D_NORMAL, "Resetting promiscuous flag...\n");
+ REGSETUP;
+ SETCONF(lp->config);
+ lp->setup &= ~PROMISCset;
+ outb(lp->setup, _SETUP);
+ }
}
/*
* FIXME: put this somewhere!
*
- if ((dstatus = inb(_DIAGSTAT)) & NEWNXTIDflag)
- {
- REGNXTID;
- SETCONF(lp->config);
- BUGMSG(D_EXTRA, "New NextID detected: %X\n", inb(ioaddr + 7));
- }
-*/
+ if ((dstatus = inb(_DIAGSTAT)) & NEWNXTIDflag)
+ {
+ REGNXTID;
+ SETCONF(lp->config);
+ BUGMSG(D_EXTRA, "New NextID detected: %X\n", inb(ioaddr + 7));
+ }
+ */
#ifdef MODULE
int init_module(void)
{
- BUGLVL(D_NORMAL) printk(VERSION);
- return 0;
+ BUGLVL(D_NORMAL) printk(VERSION);
+ return 0;
}
void cleanup_module(void)
/* Internal function declarations */
-static int com90io_found(struct net_device *dev);
-static void com90io_command (struct net_device *dev, int command);
-static int com90io_status (struct net_device *dev);
-static void com90io_setmask (struct net_device *dev, int mask);
-static int com90io_reset (struct net_device *dev, int really_reset);
+static int com90io_found(struct net_device *dev);
+static void com90io_command(struct net_device *dev, int command);
+static int com90io_status(struct net_device *dev);
+static void com90io_setmask(struct net_device *dev, int mask);
+static int com90io_reset(struct net_device *dev, int really_reset);
static void com90io_openclose(struct net_device *dev, bool open);
-static void com90io_copy_to_card (struct net_device *dev, int bufnum, int offset,
- void *buf, int count);
+static void com90io_copy_to_card(struct net_device *dev, int bufnum, int offset,
+ void *buf, int count);
static void com90io_copy_from_card(struct net_device *dev, int bufnum, int offset,
void *buf, int count);
outb(datum, _MEMDATA);
}
+
#endif
"must specify the base address!\n");
return -ENODEV;
}
-
if (check_region(ioaddr, ARCNET_TOTAL_SIZE)) {
BUGMSG(D_INIT_REASONS, "IO check_region %x-%x failed.\n",
ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
return -ENXIO;
}
-
if (ASTATUS() == 0xFF) {
BUGMSG(D_INIT_REASONS, "IO address %x empty\n", ioaddr);
return -ENODEV;
}
-
inb(_RESET);
mdelay(RESETtime);
BUGMSG(D_INIT_REASONS, "Status invalid (%Xh).\n", status);
return -ENODEV;
}
-
BUGMSG(D_INIT_REASONS, "Status after reset: %X\n", status);
ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
BUGMSG(D_INIT_REASONS, "Eternal reset (status=%Xh)\n", status);
return -ENODEV;
}
-
outb((0x16 | IOMAPflag) & ~ENABLE16flag, _CONFIG);
/* Read first loc'n of memory */
" (%Xh instead).\n", status);
return -ENODEV;
}
-
if (!dev->irq) {
/*
* if we do this, we're sure to get an IRQ since the
return -ENODEV;
}
}
-
return com90io_found(dev);
}
BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
return -ENODEV;
}
-
/* Reserve the I/O region - guaranteed to work by check_region */
request_region(dev->base_addr, ARCNET_TOTAL_SIZE, "arcnet (COM90xx-IO)");
memset(dev->priv, 0, sizeof(struct arcnet_local));
lp = (struct arcnet_local *) (dev->priv);
- lp->hw.command = com90io_command;
- lp->hw.status = com90io_status;
- lp->hw.intmask = com90io_setmask;
- lp->hw.reset = com90io_reset;
- lp->hw.open_close = com90io_openclose;
- lp->hw.copy_to_card = com90io_copy_to_card;
+ lp->hw.command = com90io_command;
+ lp->hw.status = com90io_status;
+ lp->hw.intmask = com90io_setmask;
+ lp->hw.reset = com90io_reset;
+ lp->hw.open_close = com90io_openclose;
+ lp->hw.copy_to_card = com90io_copy_to_card;
lp->hw.copy_from_card = com90io_copy_from_card;
/*
inb(_RESET);
mdelay(RESETtime);
}
-
/* Set the thing to IO-mapped, 8-bit mode */
lp->config = (0x1C | IOMAPflag) & ~ENABLE16flag;
SETCONF();
BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
return 1;
}
-
/* enable extended (512-byte) packets */
ACOMMAND(CONFIGcmd | EXTconf);
static void com90io_copy_to_card(struct net_device *dev, int bufnum, int offset,
void *buf, int count)
{
- TIME("put_whole_buffer", count, put_whole_buffer(dev, bufnum*512 + offset, count, buf));
+ TIME("put_whole_buffer", count, put_whole_buffer(dev, bufnum * 512 + offset, count, buf));
}
static void com90io_copy_from_card(struct net_device *dev, int bufnum, int offset,
void *buf, int count)
{
- TIME("get_whole_buffer", count, get_whole_buffer(dev, bufnum*512 + offset, count, buf));
+ TIME("get_whole_buffer", count, get_whole_buffer(dev, bufnum * 512 + offset, count, buf));
}
/* Module parameters */
static int io = 0x0; /* use the insmod io= irq= shmem= options */
-static int irq = 0;
+static int irq = 0;
static char *device; /* use eg. device=arc1 to change name */
MODULE_PARM(io, "i");
dev->irq = irq;
if (dev->irq == 2)
dev->irq = 9;
-
+
if (com90io_probe(dev))
return -EIO;
return 1;
dev = alloc_bootmem(sizeof(struct net_device) + 10);
memset(dev, 0, sizeof(struct net_device) + 10);
- dev->name = (char *)(dev+1);
+ dev->name = (char *) (dev + 1);
dev->init = com90io_probe;
switch (ints[0]) {
default: /* ERROR */
printk("com90io: Too many arguments.\n");
- case 2: /* IRQ */
+ case 2: /* IRQ */
dev->irq = ints[2];
- case 1: /* IO address */
+ case 1: /* IO address */
dev->base_addr = ints[1];
}
if (*s)
/* Internal function declarations */
-static int com90xx_found(struct net_device *dev, int ioaddr, int airq,
- u_long shmem);
-static void com90xx_command (struct net_device *dev, int command);
-static int com90xx_status (struct net_device *dev);
-static void com90xx_setmask (struct net_device *dev, int mask);
-static int com90xx_reset (struct net_device *dev, int really_reset);
+static int com90xx_found(struct net_device *dev, int ioaddr, int airq,
+ u_long shmem);
+static void com90xx_command(struct net_device *dev, int command);
+static int com90xx_status(struct net_device *dev);
+static void com90xx_setmask(struct net_device *dev, int mask);
+static int com90xx_reset(struct net_device *dev, int really_reset);
static void com90xx_openclose(struct net_device *dev, bool open);
-static void com90xx_copy_to_card (struct net_device *dev, int bufnum, int offset,
- void *buf, int count);
+static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
+ void *buf, int count);
static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
void *buf, int count);
int __init com90xx_probe(struct net_device *dev)
{
- int count, status, ioaddr, numprint, airq, retval = -ENODEV, openparen = 0;
- unsigned long airqmask;
- int ports[(0x3f0 - 0x200) / 16 + 1] = { 0 };
- u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] = { 0 };
- int numports, numshmems, *port;
- u_long *shmem;
-
- if (!dev && com90xx_skip_probe)
- return -ENODEV;
+ int count, status, ioaddr, numprint, airq, retval = -ENODEV,
+ openparen = 0;
+ unsigned long airqmask;
+ int ports[(0x3f0 - 0x200) / 16 + 1] =
+ {0};
+ u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] =
+ {0};
+ int numports, numshmems, *port;
+ u_long *shmem;
+
+ if (!dev && com90xx_skip_probe)
+ return -ENODEV;
#ifndef MODULE
- arcnet_init();
+ arcnet_init();
#endif
- BUGLVL(D_NORMAL) printk(VERSION);
-
- /* set up the arrays where we'll store the possible probe addresses */
- numports = numshmems = 0;
- if (dev && dev->base_addr)
- ports[numports++] = dev->base_addr;
- else
- for (count = 0x200; count <= 0x3f0; count += 16)
- ports[numports++] = count;
- if (dev && dev->mem_start)
- shmems[numshmems++] = dev->mem_start;
- else
- for (count = 0xA0000; count <= 0xFF800; count += 2048)
- shmems[numshmems++] = count;
-
- /* Stage 1: abandon any reserved ports, or ones with status==0xFF
- * (empty), and reset any others by reading the reset port.
- */
- numprint = -1;
- for (port = &ports[0]; port - ports < numports; port++)
- {
- numprint++;
- numprint %= 8;
- if (!numprint)
- {
- BUGMSG2(D_INIT, "\n");
- BUGMSG(D_INIT, "S1: ");
- }
- BUGMSG2(D_INIT, "%Xh ", *port);
-
- ioaddr = *port;
-
- if (check_region(*port, ARCNET_TOTAL_SIZE))
- {
- BUGMSG2(D_INIT_REASONS, "(check_region)\n");
- BUGMSG(D_INIT_REASONS, "S1: ");
- BUGLVL(D_INIT_REASONS) numprint = 0;
- *port = ports[numports - 1];
- numports--;
- port--;
- continue;
- }
- if (ASTATUS() == 0xFF)
- {
- BUGMSG2(D_INIT_REASONS, "(empty)\n");
- BUGMSG(D_INIT_REASONS, "S1: ");
- BUGLVL(D_INIT_REASONS) numprint = 0;
- *port = ports[numports - 1];
- numports--;
- port--;
- continue;
- }
-
- inb(_RESET); /* begin resetting card */
-
- BUGMSG2(D_INIT_REASONS, "\n");
- BUGMSG(D_INIT_REASONS, "S1: ");
- BUGLVL(D_INIT_REASONS) numprint = 0;
- }
- BUGMSG2(D_INIT, "\n");
-
- if (!numports)
- {
- BUGMSG(D_NORMAL, "S1: No ARCnet cards found.\n");
- return -ENODEV;
- }
-
- /* Stage 2: we have now reset any possible ARCnet cards, so we can't
- * do anything until they finish. If D_INIT, print the list of
- * cards that are left.
- */
- numprint = -1;
- for (port = &ports[0]; port - ports < numports; port++)
- {
- numprint++;
- numprint %= 8;
- if (!numprint)
- {
- BUGMSG2(D_INIT, "\n");
- BUGMSG(D_INIT, "S2: ");
- }
- BUGMSG2(D_INIT, "%Xh ", *port);
- }
- BUGMSG2(D_INIT, "\n");
- mdelay(RESETtime);
-
- /* Stage 3: abandon any shmem addresses that don't have the signature
- * 0xD1 byte in the right place, or are read-only.
- */
- numprint = -1;
- for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++)
- {
- u_long ptr = *shmem;
-
- numprint++;
- numprint %= 8;
- if (!numprint)
- {
- BUGMSG2(D_INIT, "\n");
- BUGMSG(D_INIT, "S3: ");
- }
- BUGMSG2(D_INIT, "%lXh ", *shmem);
-
- if (check_mem_region(*shmem, BUFFER_SIZE))
- {
- BUGMSG2(D_INIT_REASONS, "(check_mem_region)\n");
- BUGMSG(D_INIT_REASONS, "Stage 3: ");
- BUGLVL(D_INIT_REASONS) numprint = 0;
- *shmem = shmems[numshmems - 1];
- numshmems--;
- shmem--;
- continue;
- }
+ BUGLVL(D_NORMAL) printk(VERSION);
- if (isa_readb(ptr) != TESTvalue)
- {
- BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n",
- isa_readb(ptr), TESTvalue);
- BUGMSG(D_INIT_REASONS, "S3: ");
- BUGLVL(D_INIT_REASONS) numprint = 0;
- *shmem = shmems[numshmems - 1];
- numshmems--;
- shmem--;
- continue;
- }
- /* By writing 0x42 to the TESTvalue location, we also make
- * sure no "mirror" shmem areas show up - if they occur
- * in another pass through this loop, they will be discarded
- * because *cptr != TESTvalue.
+ /* set up the arrays where we'll store the possible probe addresses */
+ numports = numshmems = 0;
+ if (dev && dev->base_addr)
+ ports[numports++] = dev->base_addr;
+ else
+ for (count = 0x200; count <= 0x3f0; count += 16)
+ ports[numports++] = count;
+ if (dev && dev->mem_start)
+ shmems[numshmems++] = dev->mem_start;
+ else
+ for (count = 0xA0000; count <= 0xFF800; count += 2048)
+ shmems[numshmems++] = count;
+
+ /* Stage 1: abandon any reserved ports, or ones with status==0xFF
+ * (empty), and reset any others by reading the reset port.
*/
- isa_writeb(0x42, ptr);
- if (isa_readb(ptr) != 0x42)
- {
- BUGMSG2(D_INIT_REASONS, "(read only)\n");
- BUGMSG(D_INIT_REASONS, "S3: ");
- *shmem = shmems[numshmems - 1];
- numshmems--;
- shmem--;
- continue;
- }
- BUGMSG2(D_INIT_REASONS, "\n");
- BUGMSG(D_INIT_REASONS, "S3: ");
- BUGLVL(D_INIT_REASONS) numprint = 0;
- }
- BUGMSG2(D_INIT, "\n");
-
- if (!numshmems)
- {
- BUGMSG(D_NORMAL, "S3: No ARCnet cards found.\n");
- return -ENODEV;
- }
-
- /* Stage 4: something of a dummy, to report the shmems that are
- * still possible after stage 3.
- */
- numprint = -1;
- for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++)
- {
- numprint++;
- numprint %= 8;
- if (!numprint)
- {
- BUGMSG2(D_INIT, "\n");
- BUGMSG(D_INIT, "S4: ");
- }
- BUGMSG2(D_INIT, "%lXh ", *shmem);
- }
- BUGMSG2(D_INIT, "\n");
-
- /* Stage 5: for any ports that have the correct status, can disable
- * the RESET flag, and (if no irq is given) generate an autoirq,
- * register an ARCnet device.
- *
- * Currently, we can only register one device per probe, so quit
- * after the first one is found.
- */
- numprint = -1;
- for (port = &ports[0]; port - ports < numports; port++)
- {
- numprint++;
- numprint %= 8;
- if (!numprint)
- {
- BUGMSG2(D_INIT, "\n");
- BUGMSG(D_INIT, "S5: ");
+ numprint = -1;
+ for (port = &ports[0]; port - ports < numports; port++) {
+ numprint++;
+ numprint %= 8;
+ if (!numprint) {
+ BUGMSG2(D_INIT, "\n");
+ BUGMSG(D_INIT, "S1: ");
+ }
+ BUGMSG2(D_INIT, "%Xh ", *port);
+
+ ioaddr = *port;
+
+ if (check_region(*port, ARCNET_TOTAL_SIZE)) {
+ BUGMSG2(D_INIT_REASONS, "(check_region)\n");
+ BUGMSG(D_INIT_REASONS, "S1: ");
+ BUGLVL(D_INIT_REASONS) numprint = 0;
+ *port = ports[numports - 1];
+ numports--;
+ port--;
+ continue;
+ }
+ if (ASTATUS() == 0xFF) {
+ BUGMSG2(D_INIT_REASONS, "(empty)\n");
+ BUGMSG(D_INIT_REASONS, "S1: ");
+ BUGLVL(D_INIT_REASONS) numprint = 0;
+ *port = ports[numports - 1];
+ numports--;
+ port--;
+ continue;
+ }
+ inb(_RESET); /* begin resetting card */
+
+ BUGMSG2(D_INIT_REASONS, "\n");
+ BUGMSG(D_INIT_REASONS, "S1: ");
+ BUGLVL(D_INIT_REASONS) numprint = 0;
}
- BUGMSG2(D_INIT, "%Xh ", *port);
-
- ioaddr = *port;
- status = ASTATUS();
-
- if ((status & 0x9D)
- != (NORXflag | RECONflag | TXFREEflag | RESETflag))
- {
- BUGMSG2(D_INIT_REASONS, "(status=%Xh)\n", status);
- BUGMSG(D_INIT_REASONS, "S5: ");
- BUGLVL(D_INIT_REASONS) numprint = 0;
- *port = ports[numports - 1];
- numports--;
- port--;
- continue;
+ BUGMSG2(D_INIT, "\n");
+
+ if (!numports) {
+ BUGMSG(D_NORMAL, "S1: No ARCnet cards found.\n");
+ return -ENODEV;
}
-
- ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
- status = ASTATUS();
- if (status & RESETflag)
- {
- BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",
- status);
- BUGMSG(D_INIT_REASONS, "S5: ");
- BUGLVL(D_INIT_REASONS) numprint = 0;
- *port = ports[numports - 1];
- numports--;
- port--;
- continue;
+ /* Stage 2: we have now reset any possible ARCnet cards, so we can't
+ * do anything until they finish. If D_INIT, print the list of
+ * cards that are left.
+ */
+ numprint = -1;
+ for (port = &ports[0]; port - ports < numports; port++) {
+ numprint++;
+ numprint %= 8;
+ if (!numprint) {
+ BUGMSG2(D_INIT, "\n");
+ BUGMSG(D_INIT, "S2: ");
+ }
+ BUGMSG2(D_INIT, "%Xh ", *port);
}
- /* skip this completely if an IRQ was given, because maybe
- * we're on a machine that locks during autoirq!
+ BUGMSG2(D_INIT, "\n");
+ mdelay(RESETtime);
+
+ /* Stage 3: abandon any shmem addresses that don't have the signature
+ * 0xD1 byte in the right place, or are read-only.
*/
- if (!dev || !dev->irq)
- {
- /* if we do this, we're sure to get an IRQ since the
- * card has just reset and the NORXflag is on until
- * we tell it to start receiving.
- */
- airqmask = probe_irq_on();
- AINTMASK(NORXflag);
- udelay(1);
- AINTMASK(0);
- airq = probe_irq_off(airqmask);
-
- if (airq <= 0)
- {
- BUGMSG2(D_INIT_REASONS, "(airq=%d)\n", airq);
- BUGMSG(D_INIT_REASONS, "S5: ");
+ numprint = -1;
+ for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
+ u_long ptr = *shmem;
+
+ numprint++;
+ numprint %= 8;
+ if (!numprint) {
+ BUGMSG2(D_INIT, "\n");
+ BUGMSG(D_INIT, "S3: ");
+ }
+ BUGMSG2(D_INIT, "%lXh ", *shmem);
+
+ if (check_mem_region(*shmem, BUFFER_SIZE)) {
+ BUGMSG2(D_INIT_REASONS, "(check_mem_region)\n");
+ BUGMSG(D_INIT_REASONS, "Stage 3: ");
+ BUGLVL(D_INIT_REASONS) numprint = 0;
+ *shmem = shmems[numshmems - 1];
+ numshmems--;
+ shmem--;
+ continue;
+ }
+ if (isa_readb(ptr) != TESTvalue) {
+ BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n",
+ isa_readb(ptr), TESTvalue);
+ BUGMSG(D_INIT_REASONS, "S3: ");
+ BUGLVL(D_INIT_REASONS) numprint = 0;
+ *shmem = shmems[numshmems - 1];
+ numshmems--;
+ shmem--;
+ continue;
+ }
+ /* By writing 0x42 to the TESTvalue location, we also make
+ * sure no "mirror" shmem areas show up - if they occur
+ * in another pass through this loop, they will be discarded
+ * because *cptr != TESTvalue.
+ */
+ isa_writeb(0x42, ptr);
+ if (isa_readb(ptr) != 0x42) {
+ BUGMSG2(D_INIT_REASONS, "(read only)\n");
+ BUGMSG(D_INIT_REASONS, "S3: ");
+ *shmem = shmems[numshmems - 1];
+ numshmems--;
+ shmem--;
+ continue;
+ }
+ BUGMSG2(D_INIT_REASONS, "\n");
+ BUGMSG(D_INIT_REASONS, "S3: ");
BUGLVL(D_INIT_REASONS) numprint = 0;
- *port = ports[numports - 1];
- numports--;
- port--;
- continue;
- }
- }
- else
- {
- airq = dev->irq;
}
+ BUGMSG2(D_INIT, "\n");
- BUGMSG2(D_INIT, "(%d,", airq);
- openparen = 1;
+ if (!numshmems) {
+ BUGMSG(D_NORMAL, "S3: No ARCnet cards found.\n");
+ return -ENODEV;
+ }
+ /* Stage 4: something of a dummy, to report the shmems that are
+ * still possible after stage 3.
+ */
+ numprint = -1;
+ for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
+ numprint++;
+ numprint %= 8;
+ if (!numprint) {
+ BUGMSG2(D_INIT, "\n");
+ BUGMSG(D_INIT, "S4: ");
+ }
+ BUGMSG2(D_INIT, "%lXh ", *shmem);
+ }
+ BUGMSG2(D_INIT, "\n");
- /* Everything seems okay. But which shmem, if any, puts
- * back its signature byte when the card is reset?
+ /* Stage 5: for any ports that have the correct status, can disable
+ * the RESET flag, and (if no irq is given) generate an autoirq,
+ * register an ARCnet device.
*
- * If there are multiple cards installed, there might be
- * multiple shmems still in the list.
+ * Currently, we can only register one device per probe, so quit
+ * after the first one is found.
*/
+ numprint = -1;
+ for (port = &ports[0]; port - ports < numports; port++) {
+ numprint++;
+ numprint %= 8;
+ if (!numprint) {
+ BUGMSG2(D_INIT, "\n");
+ BUGMSG(D_INIT, "S5: ");
+ }
+ BUGMSG2(D_INIT, "%Xh ", *port);
+
+ ioaddr = *port;
+ status = ASTATUS();
+
+ if ((status & 0x9D)
+ != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
+ BUGMSG2(D_INIT_REASONS, "(status=%Xh)\n", status);
+ BUGMSG(D_INIT_REASONS, "S5: ");
+ BUGLVL(D_INIT_REASONS) numprint = 0;
+ *port = ports[numports - 1];
+ numports--;
+ port--;
+ continue;
+ }
+ ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
+ status = ASTATUS();
+ if (status & RESETflag) {
+ BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",
+ status);
+ BUGMSG(D_INIT_REASONS, "S5: ");
+ BUGLVL(D_INIT_REASONS) numprint = 0;
+ *port = ports[numports - 1];
+ numports--;
+ port--;
+ continue;
+ }
+ /* skip this completely if an IRQ was given, because maybe
+ * we're on a machine that locks during autoirq!
+ */
+ if (!dev || !dev->irq) {
+ /* if we do this, we're sure to get an IRQ since the
+ * card has just reset and the NORXflag is on until
+ * we tell it to start receiving.
+ */
+ airqmask = probe_irq_on();
+ AINTMASK(NORXflag);
+ udelay(1);
+ AINTMASK(0);
+ airq = probe_irq_off(airqmask);
+
+ if (airq <= 0) {
+ BUGMSG2(D_INIT_REASONS, "(airq=%d)\n", airq);
+ BUGMSG(D_INIT_REASONS, "S5: ");
+ BUGLVL(D_INIT_REASONS) numprint = 0;
+ *port = ports[numports - 1];
+ numports--;
+ port--;
+ continue;
+ }
+ } else {
+ airq = dev->irq;
+ }
+
+ BUGMSG2(D_INIT, "(%d,", airq);
+ openparen = 1;
+
+ /* Everything seems okay. But which shmem, if any, puts
+ * back its signature byte when the card is reset?
+ *
+ * If there are multiple cards installed, there might be
+ * multiple shmems still in the list.
+ */
#ifdef FAST_PROBE
- if (numports > 1 || numshmems > 1)
- {
- inb(_RESET);
- mdelay(RESETtime);
- }
- else
- {
- /* just one shmem and port, assume they match */
- isa_writeb(TESTvalue, shmems[0]);
- }
+ if (numports > 1 || numshmems > 1) {
+ inb(_RESET);
+ mdelay(RESETtime);
+ } else {
+ /* just one shmem and port, assume they match */
+ isa_writeb(TESTvalue, shmems[0]);
+ }
#else
- inb(_RESET);
- mdelay(RESETtime);
+ inb(_RESET);
+ mdelay(RESETtime);
#endif
- for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++)
- {
- u_long ptr = *shmem;
-
- if (isa_readb(ptr) == TESTvalue)
- { /* found one */
- BUGMSG2(D_INIT, "%lXh)\n", *shmem);
- openparen = 0;
-
- /* register the card */
- retval = com90xx_found(dev, *port, airq, *shmem);
- numprint = -1;
-
- /* remove shmem from the list */
- *shmem = shmems[numshmems - 1];
- numshmems--;
-
- break; /* go to the next I/O port */
- }
- else
- {
- BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr));
- }
- }
+ for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
+ u_long ptr = *shmem;
+
+ if (isa_readb(ptr) == TESTvalue) { /* found one */
+ BUGMSG2(D_INIT, "%lXh)\n", *shmem);
+ openparen = 0;
+
+ /* register the card */
+ retval = com90xx_found(dev, *port, airq, *shmem);
+ numprint = -1;
- if (openparen)
- {
- BUGLVL(D_INIT) printk("no matching shmem)\n");
- BUGLVL(D_INIT_REASONS) printk("S5: ");
- BUGLVL(D_INIT_REASONS) numprint = 0;
+ /* remove shmem from the list */
+ *shmem = shmems[numshmems - 1];
+ numshmems--;
+
+ break; /* go to the next I/O port */
+ } else {
+ BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr));
+ }
+ }
+
+ if (openparen) {
+ BUGLVL(D_INIT) printk("no matching shmem)\n");
+ BUGLVL(D_INIT_REASONS) printk("S5: ");
+ BUGLVL(D_INIT_REASONS) numprint = 0;
+ }
+ *port = ports[numports - 1];
+ numports--;
+ port--;
}
- *port = ports[numports - 1];
- numports--;
- port--;
- }
-
- BUGLVL(D_INIT_REASONS) printk("\n");
-
- /* Now put back TESTvalue on all leftover shmems. */
- for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++)
- isa_writeb(TESTvalue, *shmem);
-
- if (retval && dev && !numcards)
- BUGMSG(D_NORMAL, "S5: No ARCnet cards found.\n");
- return retval;
+
+ BUGLVL(D_INIT_REASONS) printk("\n");
+
+ /* Now put back TESTvalue on all leftover shmems. */
+ for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++)
+ isa_writeb(TESTvalue, *shmem);
+
+ if (retval && dev && !numcards)
+ BUGMSG(D_NORMAL, "S5: No ARCnet cards found.\n");
+ return retval;
}
static int __init com90xx_found(struct net_device *dev0, int ioaddr, int airq,
u_long shmem)
{
- struct net_device *dev = dev0;
- struct arcnet_local *lp;
- u_long first_mirror, last_mirror;
- int mirror_size, err;
-
- /* allocate struct net_device if we don't have one yet */
- if (!dev && !(dev = dev_alloc("arc%d", &err)))
- {
- BUGMSG(D_NORMAL, "Can't allocate device!\n");
- return err;
- }
- lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
- if (!lp)
- {
- BUGMSG(D_NORMAL, "Can't allocate device data!\n");
- goto err_free_dev;
- }
-
- /* find the real shared memory start/end points, including mirrors */
-
- /* guess the actual size of one "memory mirror" - the number of
- * bytes between copies of the shared memory. On most cards, it's
- * 2k (or there are no mirrors at all) but on some, it's 4k.
- */
- mirror_size = MIRROR_SIZE;
- if (isa_readb(shmem) == TESTvalue
- && isa_readb(shmem - mirror_size) != TESTvalue
- && isa_readb(shmem - 2 * mirror_size) == TESTvalue)
- mirror_size *= 2;
-
- first_mirror = last_mirror = shmem;
- while (isa_readb(first_mirror) == TESTvalue)
- first_mirror -= mirror_size;
- first_mirror += mirror_size;
-
- while (isa_readb(last_mirror) == TESTvalue)
- last_mirror += mirror_size;
- last_mirror -= mirror_size;
-
- dev->mem_start = first_mirror;
- dev->mem_end = last_mirror + MIRROR_SIZE - 1;
- dev->rmem_start = dev->mem_start + BUFFER_SIZE * 0;
- dev->rmem_end = dev->mem_start + BUFFER_SIZE * 2 - 1;
-
- /* Initialize the rest of the device structure. */
- memset(lp, 0, sizeof(struct arcnet_local));
- lp->hw.command = com90xx_command;
- lp->hw.status = com90xx_status;
- lp->hw.intmask = com90xx_setmask;
- lp->hw.reset = com90xx_reset;
- lp->hw.open_close = com90xx_openclose;
- lp->hw.copy_to_card = com90xx_copy_to_card;
- lp->hw.copy_from_card = com90xx_copy_from_card;
- lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
- if (!lp->mem_start)
- {
- BUGMSG(D_NORMAL, "Can't remap device memory!\n");
- goto err_free_dev_priv;
- }
-
- /* Fill in the fields of the device structure with generic values. */
- arcdev_setup(dev);
-
- /* get and check the station ID from offset 1 in shmem */
- dev->dev_addr[0] = readb(lp->mem_start + 1);
-
- /* reserve the irq */
- if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev))
- {
- BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
- goto err_unmap;
- }
- dev->irq = airq;
-
- /* reserve the I/O and memory regions - guaranteed to work by check_region */
- request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (90xx)");
- request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)");
- dev->base_addr = ioaddr;
-
- BUGMSG(D_NORMAL, "COM90xx station %02Xh found at %03lXh, IRQ %d, "
- "ShMem %lXh (%ld*%xh).\n",
- dev->dev_addr[0],
- dev->base_addr, dev->irq, dev->mem_start,
- (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
-
- if (!dev0 && register_netdev(dev))
- goto err_release;
-
- cards[numcards++] = dev;
- return 0;
-
-err_release:
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
- release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
-err_unmap:
- iounmap(lp->mem_start);
-err_free_dev_priv:
- kfree(dev->priv);
-err_free_dev:
- if (!dev0)
- kfree(dev);
- return -EIO;
+ struct net_device *dev = dev0;
+ struct arcnet_local *lp;
+ u_long first_mirror, last_mirror;
+ int mirror_size, err;
+
+ /* allocate struct net_device if we don't have one yet */
+ if (!dev && !(dev = dev_alloc("arc%d", &err))) {
+ BUGMSG(D_NORMAL, "Can't allocate device!\n");
+ return err;
+ }
+ lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
+ if (!lp) {
+ BUGMSG(D_NORMAL, "Can't allocate device data!\n");
+ goto err_free_dev;
+ }
+ /* find the real shared memory start/end points, including mirrors */
+
+ /* guess the actual size of one "memory mirror" - the number of
+ * bytes between copies of the shared memory. On most cards, it's
+ * 2k (or there are no mirrors at all) but on some, it's 4k.
+ */
+ mirror_size = MIRROR_SIZE;
+ if (isa_readb(shmem) == TESTvalue
+ && isa_readb(shmem - mirror_size) != TESTvalue
+ && isa_readb(shmem - 2 * mirror_size) == TESTvalue)
+ mirror_size *= 2;
+
+ first_mirror = last_mirror = shmem;
+ while (isa_readb(first_mirror) == TESTvalue)
+ first_mirror -= mirror_size;
+ first_mirror += mirror_size;
+
+ while (isa_readb(last_mirror) == TESTvalue)
+ last_mirror += mirror_size;
+ last_mirror -= mirror_size;
+
+ dev->mem_start = first_mirror;
+ dev->mem_end = last_mirror + MIRROR_SIZE - 1;
+ dev->rmem_start = dev->mem_start + BUFFER_SIZE * 0;
+ dev->rmem_end = dev->mem_start + BUFFER_SIZE * 2 - 1;
+
+ /* Initialize the rest of the device structure. */
+ memset(lp, 0, sizeof(struct arcnet_local));
+ lp->hw.command = com90xx_command;
+ lp->hw.status = com90xx_status;
+ lp->hw.intmask = com90xx_setmask;
+ lp->hw.reset = com90xx_reset;
+ lp->hw.open_close = com90xx_openclose;
+ lp->hw.copy_to_card = com90xx_copy_to_card;
+ lp->hw.copy_from_card = com90xx_copy_from_card;
+ lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+ if (!lp->mem_start) {
+ BUGMSG(D_NORMAL, "Can't remap device memory!\n");
+ goto err_free_dev_priv;
+ }
+ /* Fill in the fields of the device structure with generic values. */
+ arcdev_setup(dev);
+
+ /* get and check the station ID from offset 1 in shmem */
+ dev->dev_addr[0] = readb(lp->mem_start + 1);
+
+ /* reserve the irq */
+ if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
+ BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
+ goto err_unmap;
+ }
+ dev->irq = airq;
+
+ /* reserve the I/O and memory regions - guaranteed to work by check_region */
+ request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (90xx)");
+ request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)");
+ dev->base_addr = ioaddr;
+
+ BUGMSG(D_NORMAL, "COM90xx station %02Xh found at %03lXh, IRQ %d, "
+ "ShMem %lXh (%ld*%xh).\n",
+ dev->dev_addr[0],
+ dev->base_addr, dev->irq, dev->mem_start,
+ (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
+
+ if (!dev0 && register_netdev(dev))
+ goto err_release;
+
+ cards[numcards++] = dev;
+ return 0;
+
+ err_release:
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+ release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+ err_unmap:
+ iounmap(lp->mem_start);
+ err_free_dev_priv:
+ kfree(dev->priv);
+ err_free_dev:
+ if (!dev0)
+ kfree(dev);
+ return -EIO;
}
static void com90xx_command(struct net_device *dev, int cmd)
{
- short ioaddr = dev->base_addr;
+ short ioaddr = dev->base_addr;
- ACOMMAND(cmd);
+ ACOMMAND(cmd);
}
static int com90xx_status(struct net_device *dev)
{
- short ioaddr = dev->base_addr;
+ short ioaddr = dev->base_addr;
- return ASTATUS();
+ return ASTATUS();
}
static void com90xx_setmask(struct net_device *dev, int mask)
{
- short ioaddr = dev->base_addr;
+ short ioaddr = dev->base_addr;
- AINTMASK(mask);
+ AINTMASK(mask);
}
*/
int com90xx_reset(struct net_device *dev, int really_reset)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
- short ioaddr = dev->base_addr;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ short ioaddr = dev->base_addr;
- BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n",
- dev->name, ASTATUS());
+ BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n",
+ dev->name, ASTATUS());
- if (really_reset)
- {
- /* reset the card */
- inb(_RESET);
- mdelay(RESETtime);
- }
-
- ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */
- ACOMMAND(CFLAGScmd | CONFIGclear);
-
- /* don't do this until we verify that it doesn't hurt older cards! */
- /* outb(inb(_CONFIG) | ENABLE16flag, _CONFIG); */
-
- /* verify that the ARCnet signature byte is present */
- if (readb(lp->mem_start) != TESTvalue)
- {
- BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
- return 1;
- }
-
- /* enable extended (512-byte) packets */
- ACOMMAND(CONFIGcmd | EXTconf);
+ if (really_reset) {
+ /* reset the card */
+ inb(_RESET);
+ mdelay(RESETtime);
+ }
+ ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */
+ ACOMMAND(CFLAGScmd | CONFIGclear);
- /* clean out all the memory to make debugging make more sense :) */
- BUGLVL(D_DURING)
- memset_io(lp->mem_start, 0x42, 2048);
+ /* don't do this until we verify that it doesn't hurt older cards! */
+ /* outb(inb(_CONFIG) | ENABLE16flag, _CONFIG); */
- /* done! return success. */
- return 0;
+ /* verify that the ARCnet signature byte is present */
+ if (readb(lp->mem_start) != TESTvalue) {
+ BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
+ return 1;
+ }
+ /* enable extended (512-byte) packets */
+ ACOMMAND(CONFIGcmd | EXTconf);
+
+ /* clean out all the memory to make debugging make more sense :) */
+ BUGLVL(D_DURING)
+ memset_io(lp->mem_start, 0x42, 2048);
+
+ /* done! return success. */
+ return 0;
}
static void com90xx_openclose(struct net_device *dev, bool open)
{
- if (open)
- MOD_INC_USE_COUNT;
- else
- MOD_DEC_USE_COUNT;
+ if (open)
+ MOD_INC_USE_COUNT;
+ else
+ MOD_DEC_USE_COUNT;
}
static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
void *buf, int count)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
- void *memaddr = lp->mem_start + bufnum*512 + offset;
- TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ void *memaddr = lp->mem_start + bufnum * 512 + offset;
+ TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
}
static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
void *buf, int count)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
- void *memaddr = lp->mem_start + bufnum*512 + offset;
- TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ void *memaddr = lp->mem_start + bufnum * 512 + offset;
+ TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
}
/* Module parameters */
static int io = 0x0; /* use the insmod io= irq= shmem= options */
-static int irq = 0;
+static int irq = 0;
static int shmem = 0;
static char *device; /* use eg. device=arc1 to change name */
int init_module(void)
{
- struct net_device *dev;
- int err;
-
- if (io || irq || shmem || device)
- {
- dev = dev_alloc(device ? : "arc%d", &err);
- if (!dev)
- return err;
- dev->base_addr = io;
- dev->irq = irq;
- if (dev->irq == 2)
- dev->irq = 9;
- dev->mem_start = shmem;
- com90xx_probe(dev);
- }
- else com90xx_probe(NULL);
-
- if (!numcards)
- return -EIO;
- return 0;
+ struct net_device *dev;
+ int err;
+
+ if (io || irq || shmem || device) {
+ dev = dev_alloc(device ? : "arc%d", &err);
+ if (!dev)
+ return err;
+ dev->base_addr = io;
+ dev->irq = irq;
+ if (dev->irq == 2)
+ dev->irq = 9;
+ dev->mem_start = shmem;
+ com90xx_probe(dev);
+ } else
+ com90xx_probe(NULL);
+
+ if (!numcards)
+ return -EIO;
+ return 0;
}
void cleanup_module(void)
{
- struct net_device *dev;
- struct arcnet_local *lp;
- int count;
-
- for (count = 0; count < numcards; count++)
- {
- dev = cards[count];
- lp = (struct arcnet_local *) dev->priv;
-
- if (dev->start)
- dev->stop(dev);
- free_irq(dev->irq, dev);
- iounmap(lp->mem_start);
- release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
- release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
- unregister_netdev(dev);
- kfree(dev->priv);
- kfree(dev);
- }
+ struct net_device *dev;
+ struct arcnet_local *lp;
+ int count;
+
+ for (count = 0; count < numcards; count++) {
+ dev = cards[count];
+ lp = (struct arcnet_local *) dev->priv;
+
+ if (dev->start)
+ dev->stop(dev);
+ free_irq(dev->irq, dev);
+ iounmap(lp->mem_start);
+ release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+ release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+ unregister_netdev(dev);
+ kfree(dev->priv);
+ kfree(dev);
+ }
}
#else
printk("com90xx: Disabled.\n");
return 1;
}
-
dev = alloc_bootmem(sizeof(struct net_device) + 10);
memset(dev, 0, sizeof(struct net_device) + 10);
- dev->name = (char *)(dev+1);
+ dev->name = (char *) (dev + 1);
dev->init = com90xx_probe;
switch (ints[0]) {
- default: /* ERROR */
+ default: /* ERROR */
printk("com90xx: Too many arguments.\n");
case 3: /* Mem address */
dev->mem_start = ints[3];
* **********************
*/
#include <linux/module.h>
-#include <linux/config.h> /* for CONFIG_INET */
+#include <linux/config.h> /* for CONFIG_INET */
#include <linux/init.h>
#include <linux/if_arp.h>
#include <net/arp.h>
static int build_header(struct sk_buff *skb, unsigned short type,
uint8_t daddr);
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
- int bufnum);
+ int bufnum);
-struct ArcProto rfc1051_proto = {
+struct ArcProto rfc1051_proto =
+{
's',
XMTU - RFC1051_HDR_SIZE,
rx,
void __init arcnet_rfc1051_init(void)
{
- arc_proto_map[ARC_P_IP_RFC1051]
- = arc_proto_map[ARC_P_ARP_RFC1051]
- = &rfc1051_proto;
-
- /* if someone else already owns the broadcast, we won't take it */
- if (arc_bcast_proto == arc_proto_default)
- arc_bcast_proto = &rfc1051_proto;
-
+ arc_proto_map[ARC_P_IP_RFC1051]
+ = arc_proto_map[ARC_P_ARP_RFC1051]
+ = &rfc1051_proto;
+
+ /* if someone else already owns the broadcast, we won't take it */
+ if (arc_bcast_proto == arc_proto_default)
+ arc_bcast_proto = &rfc1051_proto;
+
}
int __init init_module(void)
{
- printk(VERSION);
- arcnet_rfc1051_init();
- return 0;
+ printk(VERSION);
+ arcnet_rfc1051_init();
+ return 0;
}
void cleanup_module(void)
{
- arcnet_unregister_proto(&rfc1051_proto);
+ arcnet_unregister_proto(&rfc1051_proto);
}
-#endif /* MODULE */
+#endif /* MODULE */
/*
*/
static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- struct archdr *pkt = (struct archdr *)skb->data;
- struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
- int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
-
- /* Pull off the arcnet header. */
- skb->mac.raw = skb->data;
- skb_pull(skb, hdr_size);
-
- if (pkt->hard.dest == 0)
- skb->pkt_type = PACKET_BROADCAST;
- else if (dev->flags & IFF_PROMISC)
- {
- /* if we're not sending to ourselves :) */
- if (pkt->hard.dest != dev->dev_addr[0])
- skb->pkt_type = PACKET_OTHERHOST;
- }
-
- /* now return the protocol number */
- switch (soft->proto)
- {
- case ARC_P_IP_RFC1051:
- return htons(ETH_P_IP);
- case ARC_P_ARP_RFC1051:
- return htons(ETH_P_ARP);
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct archdr *pkt = (struct archdr *) skb->data;
+ struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
+ int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
- default:
- lp->stats.rx_errors++;
- lp->stats.rx_crc_errors++;
- return 0;
- }
+ /* Pull off the arcnet header. */
+ skb->mac.raw = skb->data;
+ skb_pull(skb, hdr_size);
+
+ if (pkt->hard.dest == 0)
+ skb->pkt_type = PACKET_BROADCAST;
+ else if (dev->flags & IFF_PROMISC) {
+ /* if we're not sending to ourselves :) */
+ if (pkt->hard.dest != dev->dev_addr[0])
+ skb->pkt_type = PACKET_OTHERHOST;
+ }
+ /* now return the protocol number */
+ switch (soft->proto) {
+ case ARC_P_IP_RFC1051:
+ return htons(ETH_P_IP);
+ case ARC_P_ARP_RFC1051:
+ return htons(ETH_P_ARP);
+
+ default:
+ lp->stats.rx_errors++;
+ lp->stats.rx_crc_errors++;
+ return 0;
+ }
- return htons(ETH_P_IP);
+ return htons(ETH_P_IP);
}
static void rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- struct sk_buff *skb;
- struct archdr *pkt = pkthdr;
- int ofs;
-
- BUGMSG(D_DURING, "it's a raw packet (length=%d)\n", length);
-
- if (length >= MinTU)
- ofs = 512 - length;
- else
- ofs = 256 - length;
-
- skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
- if (skb == NULL)
- {
- BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
- return;
- }
-
- skb_put(skb, length + ARC_HDR_SIZE);
- skb->dev = dev;
-
- pkt = (struct archdr *)skb->data;
-
- /* up to sizeof(pkt->soft) has already been copied from the card */
- memcpy(pkt, pkthdr, sizeof(struct archdr));
- if (length > sizeof(pkt->soft))
- lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
- pkt->soft.raw + sizeof(pkt->soft),
- length - sizeof(pkt->soft));
-
- BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
-
- skb->protocol = type_trans(skb, dev);
- netif_rx(skb);
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct sk_buff *skb;
+ struct archdr *pkt = pkthdr;
+ int ofs;
+
+ BUGMSG(D_DURING, "it's a raw packet (length=%d)\n", length);
+
+ if (length >= MinTU)
+ ofs = 512 - length;
+ else
+ ofs = 256 - length;
+
+ skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
+ if (skb == NULL) {
+ BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
+ lp->stats.rx_dropped++;
+ return;
+ }
+ skb_put(skb, length + ARC_HDR_SIZE);
+ skb->dev = dev;
+
+ pkt = (struct archdr *) skb->data;
+
+ /* up to sizeof(pkt->soft) has already been copied from the card */
+ memcpy(pkt, pkthdr, sizeof(struct archdr));
+ if (length > sizeof(pkt->soft))
+ lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
+ pkt->soft.raw + sizeof(pkt->soft),
+ length - sizeof(pkt->soft));
+
+ BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
+
+ skb->protocol = type_trans(skb, dev);
+ netif_rx(skb);
}
static int build_header(struct sk_buff *skb, unsigned short type,
uint8_t daddr)
{
- struct net_device *dev = skb->dev;
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
- struct archdr *pkt = (struct archdr *)skb_push(skb, hdr_size);
- struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
-
- /* set the protocol ID according to RFC1051 */
- switch (type)
- {
- case ETH_P_IP:
- soft->proto = ARC_P_IP_RFC1051;
- break;
- case ETH_P_ARP:
- soft->proto = ARC_P_ARP_RFC1051;
- break;
- default:
- BUGMSG(D_NORMAL, "RFC1051: I don't understand protocol %d (%Xh)\n",
- type, type);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
- return 0;
- }
-
-
- /*
- * Set the source hardware address.
- *
- * This is pretty pointless for most purposes, but it can help in
- * debugging. ARCnet does not allow us to change the source address in
- * the actual packet sent)
- */
- pkt->hard.source = *dev->dev_addr;
-
- /* see linux/net/ethernet/eth.c to see where I got the following */
-
- if (dev->flags & (IFF_LOOPBACK|IFF_NOARP))
- {
- /*
- * FIXME: fill in the last byte of the dest ipaddr here to better
- * comply with RFC1051 in "noarp" mode.
+ struct net_device *dev = skb->dev;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
+ struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
+ struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
+
+ /* set the protocol ID according to RFC1051 */
+ switch (type) {
+ case ETH_P_IP:
+ soft->proto = ARC_P_IP_RFC1051;
+ break;
+ case ETH_P_ARP:
+ soft->proto = ARC_P_ARP_RFC1051;
+ break;
+ default:
+ BUGMSG(D_NORMAL, "RFC1051: I don't understand protocol %d (%Xh)\n",
+ type, type);
+ lp->stats.tx_errors++;
+ lp->stats.tx_aborted_errors++;
+ return 0;
+ }
+
+
+ /*
+ * Set the source hardware address.
+ *
+ * This is pretty pointless for most purposes, but it can help in
+ * debugging. ARCnet does not allow us to change the source address in
+ * the actual packet sent)
*/
- pkt->hard.dest = 0;
- return hdr_size;
- }
-
- /* otherwise, just fill it in and go! */
- pkt->hard.dest = daddr;
-
- return hdr_size; /* success */
+ pkt->hard.source = *dev->dev_addr;
+
+ /* see linux/net/ethernet/eth.c to see where I got the following */
+
+ if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
+ /*
+ * FIXME: fill in the last byte of the dest ipaddr here to better
+ * comply with RFC1051 in "noarp" mode.
+ */
+ pkt->hard.dest = 0;
+ return hdr_size;
+ }
+ /* otherwise, just fill it in and go! */
+ pkt->hard.dest = daddr;
+
+ return hdr_size; /* success */
}
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
- int bufnum)
+ int bufnum)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- struct arc_hardware *hard = &pkt->hard;
- int ofs;
-
- BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
- lp->next_tx, lp->cur_tx, bufnum);
-
- length -= ARC_HDR_SIZE; /* hard header is not included in packet length */
-
- if (length > XMTU)
- {
- /* should never happen! other people already check for this. */
- BUGMSG(D_NORMAL, "Bug! prepare_tx with size %d (> %d)\n",
- length, XMTU);
- length = XMTU;
- }
-
- if (length > MinTU)
- {
- hard->offset[0] = 0;
- hard->offset[1] = ofs = 512 - length;
- }
- else if (length > MTU)
- {
- hard->offset[0] = 0;
- hard->offset[1] = ofs = 512 - length - 3;
- }
- else
- hard->offset[0] = ofs = 256 - length;
-
- lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
- lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length);
-
- lp->lastload_dest = hard->dest;
-
- return 1; /* done */
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arc_hardware *hard = &pkt->hard;
+ int ofs;
+
+ BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
+ lp->next_tx, lp->cur_tx, bufnum);
+
+ length -= ARC_HDR_SIZE; /* hard header is not included in packet length */
+
+ if (length > XMTU) {
+ /* should never happen! other people already check for this. */
+ BUGMSG(D_NORMAL, "Bug! prepare_tx with size %d (> %d)\n",
+ length, XMTU);
+ length = XMTU;
+ }
+ if (length > MinTU) {
+ hard->offset[0] = 0;
+ hard->offset[1] = ofs = 512 - length;
+ } else if (length > MTU) {
+ hard->offset[0] = 0;
+ hard->offset[1] = ofs = 512 - length - 3;
+ } else
+ hard->offset[0] = ofs = 256 - length;
+
+ lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
+ lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length);
+
+ lp->lastload_dest = hard->dest;
+
+ return 1; /* done */
}
* **********************
*/
#include <linux/module.h>
-#include <linux/config.h> /* for CONFIG_INET */
+#include <linux/config.h> /* for CONFIG_INET */
#include <linux/init.h>
#include <linux/if_arp.h>
#include <linux/netdevice.h>
static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev);
static void rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length);
-static int build_header(struct sk_buff *skb, unsigned short type,
+static int build_header(struct sk_buff *skb, unsigned short type,
uint8_t daddr);
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
- int bufnum);
+ int bufnum);
static int continue_tx(struct net_device *dev, int bufnum);
-struct ArcProto rfc1201_proto = {
+struct ArcProto rfc1201_proto =
+{
'a',
- 1500, /* could be more, but some receivers can't handle it... */
+ 1500, /* could be more, but some receivers can't handle it... */
rx,
build_header,
prepare_tx,
void __init arcnet_rfc1201_init(void)
{
- arc_proto_map[ARC_P_IP]
- = arc_proto_map[ARC_P_ARP]
- = arc_proto_map[ARC_P_RARP]
- = arc_proto_map[ARC_P_IPX]
- = arc_proto_map[ARC_P_NOVELL_EC]
- = &rfc1201_proto;
-
- /* if someone else already owns the broadcast, we won't take it */
- if (arc_bcast_proto == arc_proto_default)
- arc_bcast_proto = &rfc1201_proto;
+ arc_proto_map[ARC_P_IP]
+ = arc_proto_map[ARC_P_ARP]
+ = arc_proto_map[ARC_P_RARP]
+ = arc_proto_map[ARC_P_IPX]
+ = arc_proto_map[ARC_P_NOVELL_EC]
+ = &rfc1201_proto;
+
+ /* if someone else already owns the broadcast, we won't take it */
+ if (arc_bcast_proto == arc_proto_default)
+ arc_bcast_proto = &rfc1201_proto;
}
int __init init_module(void)
{
- printk(VERSION);
- arcnet_rfc1201_init();
- return 0;
+ printk(VERSION);
+ arcnet_rfc1201_init();
+ return 0;
}
void cleanup_module(void)
{
- arcnet_unregister_proto(&rfc1201_proto);
+ arcnet_unregister_proto(&rfc1201_proto);
}
-#endif /* MODULE */
+#endif /* MODULE */
/*
*/
static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev)
{
- struct archdr *pkt = (struct archdr *)skb->data;
- struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
-
- /* Pull off the arcnet header. */
- skb->mac.raw = skb->data;
- skb_pull(skb, hdr_size);
-
- if (pkt->hard.dest == 0)
- skb->pkt_type = PACKET_BROADCAST;
- else if (dev->flags & IFF_PROMISC)
- {
- /* if we're not sending to ourselves :) */
- if (pkt->hard.dest != dev->dev_addr[0])
- skb->pkt_type = PACKET_OTHERHOST;
- }
-
- /* now return the protocol number */
- switch (soft->proto)
- {
- case ARC_P_IP:
- return htons(ETH_P_IP);
- case ARC_P_ARP:
- return htons(ETH_P_ARP);
- case ARC_P_RARP:
- return htons(ETH_P_RARP);
-
- case ARC_P_IPX:
- case ARC_P_NOVELL_EC:
- return htons(ETH_P_802_3);
- default:
- lp->stats.rx_errors++;
- lp->stats.rx_crc_errors++;
- return 0;
- }
+ struct archdr *pkt = (struct archdr *) skb->data;
+ struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
+
+ /* Pull off the arcnet header. */
+ skb->mac.raw = skb->data;
+ skb_pull(skb, hdr_size);
+
+ if (pkt->hard.dest == 0)
+ skb->pkt_type = PACKET_BROADCAST;
+ else if (dev->flags & IFF_PROMISC) {
+ /* if we're not sending to ourselves :) */
+ if (pkt->hard.dest != dev->dev_addr[0])
+ skb->pkt_type = PACKET_OTHERHOST;
+ }
+ /* now return the protocol number */
+ switch (soft->proto) {
+ case ARC_P_IP:
+ return htons(ETH_P_IP);
+ case ARC_P_ARP:
+ return htons(ETH_P_ARP);
+ case ARC_P_RARP:
+ return htons(ETH_P_RARP);
+
+ case ARC_P_IPX:
+ case ARC_P_NOVELL_EC:
+ return htons(ETH_P_802_3);
+ default:
+ lp->stats.rx_errors++;
+ lp->stats.rx_crc_errors++;
+ return 0;
+ }
- return htons(ETH_P_IP);
+ return htons(ETH_P_IP);
}
static void rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- struct sk_buff *skb;
- struct archdr *pkt = pkthdr;
- struct arc_rfc1201 *soft = &pkthdr->soft.rfc1201;
- int saddr = pkt->hard.source, ofs;
- struct Incoming *in = &lp->rfc1201.incoming[saddr];
-
- BUGMSG(D_DURING, "it's an RFC1201 packet (length=%d)\n", length);
-
- if (length >= MinTU)
- ofs = 512 - length;
- else
- ofs = 256 - length;
-
- if (soft->split_flag == 0xFF) /* Exception Packet */
- {
- if (length >= 4 + RFC1201_HDR_SIZE)
- BUGMSG(D_DURING, "compensating for exception packet\n");
- else
- {
- BUGMSG(D_EXTRA, "short RFC1201 exception packet from %02Xh",
- saddr);
- return;
- }
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct sk_buff *skb;
+ struct archdr *pkt = pkthdr;
+ struct arc_rfc1201 *soft = &pkthdr->soft.rfc1201;
+ int saddr = pkt->hard.source, ofs;
+ struct Incoming *in = &lp->rfc1201.incoming[saddr];
- /* skip over 4-byte junkola */
- length -= 4;
- ofs += 4;
- lp->hw.copy_from_card(dev, bufnum, 512 - length,
- soft, sizeof(pkt->soft));
- }
-
- if (!soft->split_flag) /* not split */
- {
- BUGMSG(D_RX, "incoming is not split (splitflag=%d)\n",
- soft->split_flag);
-
- if (in->skb) /* already assembling one! */
- {
- BUGMSG(D_EXTRA, "aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
- in->sequence, soft->split_flag, soft->sequence);
- lp->rfc1201.aborted_seq = soft->sequence;
- kfree_skb(in->skb);
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
- in->skb = NULL;
- }
+ BUGMSG(D_DURING, "it's an RFC1201 packet (length=%d)\n", length);
- in->sequence = soft->sequence;
+ if (length >= MinTU)
+ ofs = 512 - length;
+ else
+ ofs = 256 - length;
+
+ if (soft->split_flag == 0xFF) { /* Exception Packet */
+ if (length >= 4 + RFC1201_HDR_SIZE)
+ BUGMSG(D_DURING, "compensating for exception packet\n");
+ else {
+ BUGMSG(D_EXTRA, "short RFC1201 exception packet from %02Xh",
+ saddr);
+ return;
+ }
- skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
- if (skb == NULL)
- {
- BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
- return;
+ /* skip over 4-byte junkola */
+ length -= 4;
+ ofs += 4;
+ lp->hw.copy_from_card(dev, bufnum, 512 - length,
+ soft, sizeof(pkt->soft));
}
+ if (!soft->split_flag) { /* not split */
+ BUGMSG(D_RX, "incoming is not split (splitflag=%d)\n",
+ soft->split_flag);
- skb_put(skb, length + ARC_HDR_SIZE);
- skb->dev = dev;
-
- pkt = (struct archdr *)skb->data;
- soft = &pkt->soft.rfc1201;
-
- /* up to sizeof(pkt->soft) has already been copied from the card */
- memcpy(pkt, pkthdr, sizeof(struct archdr));
- if (length > sizeof(pkt->soft))
- lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
- pkt->soft.raw + sizeof(pkt->soft),
- length - sizeof(pkt->soft));
+ if (in->skb) { /* already assembling one! */
+ BUGMSG(D_EXTRA, "aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
+ in->sequence, soft->split_flag, soft->sequence);
+ lp->rfc1201.aborted_seq = soft->sequence;
+ kfree_skb(in->skb);
+ lp->stats.rx_errors++;
+ lp->stats.rx_missed_errors++;
+ in->skb = NULL;
+ }
+ in->sequence = soft->sequence;
- /*
- * ARP packets have problems when sent from some DOS systems: the
- * source address is always 0! So we take the hardware source addr
- * (which is impossible to fumble) and insert it ourselves.
- */
- if (soft->proto == ARC_P_ARP)
- {
- struct arphdr *arp = (struct arphdr *)soft->payload;
-
- /* make sure addresses are the right length */
- if (arp->ar_hln == 1 && arp->ar_pln == 4)
- {
- uint8_t *cptr = (uint8_t *)arp + sizeof(struct arphdr);
-
- if (!*cptr) /* is saddr = 00? */
- {
- BUGMSG(D_EXTRA,
- "ARP source address was 00h, set to %02Xh.\n",
- saddr);
- lp->stats.rx_crc_errors++;
- *cptr = saddr;
+ skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
+ if (skb == NULL) {
+ BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
+ lp->stats.rx_dropped++;
+ return;
}
- else
- {
- BUGMSG(D_DURING, "ARP source address (%Xh) is fine.\n",
- *cptr);
+ skb_put(skb, length + ARC_HDR_SIZE);
+ skb->dev = dev;
+
+ pkt = (struct archdr *) skb->data;
+ soft = &pkt->soft.rfc1201;
+
+ /* up to sizeof(pkt->soft) has already been copied from the card */
+ memcpy(pkt, pkthdr, sizeof(struct archdr));
+ if (length > sizeof(pkt->soft))
+ lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
+ pkt->soft.raw + sizeof(pkt->soft),
+ length - sizeof(pkt->soft));
+
+ /*
+ * ARP packets have problems when sent from some DOS systems: the
+ * source address is always 0! So we take the hardware source addr
+ * (which is impossible to fumble) and insert it ourselves.
+ */
+ if (soft->proto == ARC_P_ARP) {
+ struct arphdr *arp = (struct arphdr *) soft->payload;
+
+ /* make sure addresses are the right length */
+ if (arp->ar_hln == 1 && arp->ar_pln == 4) {
+ uint8_t *cptr = (uint8_t *) arp + sizeof(struct arphdr);
+
+ if (!*cptr) { /* is saddr = 00? */
+ BUGMSG(D_EXTRA,
+ "ARP source address was 00h, set to %02Xh.\n",
+ saddr);
+ lp->stats.rx_crc_errors++;
+ *cptr = saddr;
+ } else {
+ BUGMSG(D_DURING, "ARP source address (%Xh) is fine.\n",
+ *cptr);
+ }
+ } else {
+ BUGMSG(D_NORMAL, "funny-shaped ARP packet. (%Xh, %Xh)\n",
+ arp->ar_hln, arp->ar_pln);
+ lp->stats.rx_errors++;
+ lp->stats.rx_crc_errors++;
+ }
+ }
+ BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
+
+ skb->protocol = type_trans(skb, dev);
+ netif_rx(skb);
+ } else { /* split packet */
+ /*
+ * NOTE: MSDOS ARP packet correction should only need to apply to
+ * unsplit packets, since ARP packets are so short.
+ *
+ * My interpretation of the RFC1201 document is that if a packet is
+ * received out of order, the entire assembly process should be
+ * aborted.
+ *
+ * The RFC also mentions "it is possible for successfully received
+ * packets to be retransmitted." As of 0.40 all previously received
+ * packets are allowed, not just the most recent one.
+ *
+ * We allow multiple assembly processes, one for each ARCnet card
+ * possible on the network. Seems rather like a waste of memory,
+ * but there's no other way to be reliable.
+ */
+
+ BUGMSG(D_RX, "packet is split (splitflag=%d, seq=%d)\n",
+ soft->split_flag, in->sequence);
+
+ if (in->skb && in->sequence != soft->sequence) {
+ BUGMSG(D_EXTRA, "wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n",
+ saddr, in->sequence, soft->sequence,
+ soft->split_flag);
+ kfree_skb(in->skb);
+ in->skb = NULL;
+ lp->stats.rx_errors++;
+ lp->stats.rx_missed_errors++;
+ in->lastpacket = in->numpackets = 0;
+ }
+ if (soft->split_flag & 1) { /* first packet in split */
+ BUGMSG(D_RX, "brand new splitpacket (splitflag=%d)\n",
+ soft->split_flag);
+ if (in->skb) { /* already assembling one! */
+ BUGMSG(D_EXTRA, "aborting previous (seq=%d) assembly "
+ "(splitflag=%d, seq=%d)\n",
+ in->sequence, soft->split_flag,
+ soft->sequence);
+ lp->stats.rx_errors++;
+ lp->stats.rx_missed_errors++;
+ kfree_skb(in->skb);
+ }
+ in->sequence = soft->sequence;
+ in->numpackets = ((unsigned) soft->split_flag >> 1) + 2;
+ in->lastpacket = 1;
+
+ if (in->numpackets > 16) {
+ BUGMSG(D_EXTRA, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
+ soft->split_flag);
+ lp->stats.rx_errors++;
+ lp->stats.rx_length_errors++;
+ return;
+ }
+ in->skb = skb = alloc_skb(508 * in->numpackets + ARC_HDR_SIZE,
+ GFP_ATOMIC);
+ if (skb == NULL) {
+ BUGMSG(D_NORMAL, "(split) memory squeeze, dropping packet.\n");
+ lp->stats.rx_dropped++;
+ return;
+ }
+ skb->dev = dev;
+ pkt = (struct archdr *) skb->data;
+ soft = &pkt->soft.rfc1201;
+
+ memcpy(pkt, pkthdr, ARC_HDR_SIZE + RFC1201_HDR_SIZE);
+ skb_put(skb, ARC_HDR_SIZE + RFC1201_HDR_SIZE);
+
+ soft->split_flag = 0; /* end result won't be split */
+ } else { /* not first packet */
+ int packetnum = ((unsigned) soft->split_flag >> 1) + 1;
+
+ /*
+ * if we're not assembling, there's no point trying to
+ * continue.
+ */
+ if (!in->skb) {
+ if (lp->rfc1201.aborted_seq != soft->sequence) {
+ BUGMSG(D_EXTRA, "can't continue split without starting "
+ "first! (splitflag=%d, seq=%d, aborted=%d)\n",
+ soft->split_flag, soft->sequence,
+ lp->rfc1201.aborted_seq);
+ lp->stats.rx_errors++;
+ lp->stats.rx_missed_errors++;
+ }
+ return;
+ }
+ in->lastpacket++;
+ if (packetnum != in->lastpacket) { /* not the right flag! */
+ /* harmless duplicate? ignore. */
+ if (packetnum <= in->lastpacket - 1) {
+ BUGMSG(D_EXTRA, "duplicate splitpacket ignored! (splitflag=%d)\n",
+ soft->split_flag);
+ lp->stats.rx_errors++;
+ lp->stats.rx_frame_errors++;
+ return;
+ }
+ /* "bad" duplicate, kill reassembly */
+ BUGMSG(D_EXTRA, "out-of-order splitpacket, reassembly "
+ "(seq=%d) aborted (splitflag=%d, seq=%d)\n",
+ in->sequence, soft->split_flag, soft->sequence);
+ lp->rfc1201.aborted_seq = soft->sequence;
+ kfree_skb(in->skb);
+ in->skb = NULL;
+ lp->stats.rx_errors++;
+ lp->stats.rx_missed_errors++;
+ in->lastpacket = in->numpackets = 0;
+ return;
+ }
+ pkt = (struct archdr *) in->skb->data;
+ soft = &pkt->soft.rfc1201;
}
- }
- else
- {
- BUGMSG(D_NORMAL, "funny-shaped ARP packet. (%Xh, %Xh)\n",
- arp->ar_hln, arp->ar_pln);
- lp->stats.rx_errors++;
- lp->stats.rx_crc_errors++;
- }
- }
-
- BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
- skb->protocol = type_trans(skb, dev);
- netif_rx(skb);
- }
- else /* split packet */
- {
- /*
- * NOTE: MSDOS ARP packet correction should only need to apply to
- * unsplit packets, since ARP packets are so short.
- *
- * My interpretation of the RFC1201 document is that if a packet is
- * received out of order, the entire assembly process should be
- * aborted.
- *
- * The RFC also mentions "it is possible for successfully received
- * packets to be retransmitted." As of 0.40 all previously received
- * packets are allowed, not just the most recent one.
- *
- * We allow multiple assembly processes, one for each ARCnet card
- * possible on the network. Seems rather like a waste of memory,
- * but there's no other way to be reliable.
- */
+ skb = in->skb;
- BUGMSG(D_RX, "packet is split (splitflag=%d, seq=%d)\n",
- soft->split_flag, in->sequence);
-
- if (in->skb && in->sequence != soft->sequence)
- {
- BUGMSG(D_EXTRA, "wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n",
- saddr, in->sequence, soft->sequence,
- soft->split_flag);
- kfree_skb(in->skb);
- in->skb = NULL;
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
- in->lastpacket = in->numpackets = 0;
- }
+ lp->hw.copy_from_card(dev, bufnum, ofs + RFC1201_HDR_SIZE,
+ skb->data + skb->len,
+ length - RFC1201_HDR_SIZE);
+ skb_put(skb, length - RFC1201_HDR_SIZE);
- if (soft->split_flag & 1) /* first packet in split */
- {
- BUGMSG(D_RX, "brand new splitpacket (splitflag=%d)\n",
- soft->split_flag);
- if (in->skb) /* already assembling one! */
- {
- BUGMSG(D_EXTRA, "aborting previous (seq=%d) assembly "
- "(splitflag=%d, seq=%d)\n",
- in->sequence, soft->split_flag,
- soft->sequence);
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
- kfree_skb(in->skb);
- }
+ /* are we done? */
+ if (in->lastpacket == in->numpackets) {
+ in->skb = NULL;
+ in->lastpacket = in->numpackets = 0;
- in->sequence = soft->sequence;
- in->numpackets = ((unsigned)soft->split_flag >> 1) + 2;
- in->lastpacket = 1;
+ BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
- if (in->numpackets > 16)
- {
- BUGMSG(D_EXTRA, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
- soft->split_flag);
- lp->stats.rx_errors++;
- lp->stats.rx_length_errors++;
- return;
- }
-
- in->skb = skb = alloc_skb(508 * in->numpackets + ARC_HDR_SIZE,
- GFP_ATOMIC);
- if (skb == NULL)
- {
- BUGMSG(D_NORMAL, "(split) memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
- return;
- }
-
- skb->dev = dev;
- pkt = (struct archdr *)skb->data;
- soft = &pkt->soft.rfc1201;
-
- memcpy(pkt, pkthdr, ARC_HDR_SIZE + RFC1201_HDR_SIZE);
- skb_put(skb, ARC_HDR_SIZE + RFC1201_HDR_SIZE);
-
- soft->split_flag = 0; /* end result won't be split */
- }
- else /* not first packet */
- {
- int packetnum = ((unsigned)soft->split_flag >> 1) + 1;
-
- /*
- * if we're not assembling, there's no point trying to
- * continue.
- */
- if (!in->skb)
- {
- if (lp->rfc1201.aborted_seq != soft->sequence)
- {
- BUGMSG(D_EXTRA, "can't continue split without starting "
- "first! (splitflag=%d, seq=%d, aborted=%d)\n",
- soft->split_flag, soft->sequence,
- lp->rfc1201.aborted_seq);
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ skb->protocol = type_trans(skb, dev);
+ netif_rx(skb);
}
- return;
- }
-
- in->lastpacket++;
- if (packetnum != in->lastpacket) /* not the right flag! */
- {
- /* harmless duplicate? ignore. */
- if (packetnum <= in->lastpacket - 1)
- {
- BUGMSG(D_EXTRA, "duplicate splitpacket ignored! (splitflag=%d)\n",
- soft->split_flag);
- lp->stats.rx_errors++;
- lp->stats.rx_frame_errors++;
- return;
- }
-
- /* "bad" duplicate, kill reassembly */
- BUGMSG(D_EXTRA, "out-of-order splitpacket, reassembly "
- "(seq=%d) aborted (splitflag=%d, seq=%d)\n",
- in->sequence, soft->split_flag, soft->sequence);
- lp->rfc1201.aborted_seq = soft->sequence;
- kfree_skb(in->skb);
- in->skb = NULL;
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
- in->lastpacket = in->numpackets = 0;
- return;
- }
-
- pkt = (struct archdr *)in->skb->data;
- soft = &pkt->soft.rfc1201;
- }
-
- skb = in->skb;
-
- lp->hw.copy_from_card(dev, bufnum, ofs + RFC1201_HDR_SIZE,
- skb->data + skb->len,
- length - RFC1201_HDR_SIZE);
- skb_put(skb, length - RFC1201_HDR_SIZE);
-
- /* are we done? */
- if (in->lastpacket == in->numpackets)
- {
- in->skb = NULL;
- in->lastpacket = in->numpackets = 0;
-
- BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
-
- skb->protocol = type_trans(skb, dev);
- netif_rx(skb);
}
- }
}
static int build_header(struct sk_buff *skb, unsigned short type,
uint8_t daddr)
{
- struct net_device *dev = skb->dev;
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
- struct archdr *pkt = (struct archdr *)skb_push(skb, hdr_size);
- struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
-
- /* set the protocol ID according to RFC1201 */
- switch (type)
- {
- case ETH_P_IP:
- soft->proto = ARC_P_IP;
- break;
- case ETH_P_ARP:
- soft->proto = ARC_P_ARP;
- break;
- case ETH_P_RARP:
- soft->proto = ARC_P_RARP;
- break;
- case ETH_P_IPX:
- case ETH_P_802_3:
- case ETH_P_802_2:
- soft->proto = ARC_P_IPX;
- break;
- case ETH_P_ATALK:
- soft->proto = ARC_P_ATALK;
- break;
- default:
- BUGMSG(D_NORMAL, "RFC1201: I don't understand protocol %d (%Xh)\n",
- type, type);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
- return 0;
- }
-
- /*
- * Set the source hardware address.
- *
- * This is pretty pointless for most purposes, but it can help in
- * debugging. ARCnet does not allow us to change the source address in
- * the actual packet sent)
- */
- pkt->hard.source = *dev->dev_addr;
-
- soft->sequence = htons(lp->rfc1201.sequence++);
- soft->split_flag = 0; /* split packets are done elsewhere */
-
- /* see linux/net/ethernet/eth.c to see where I got the following */
-
- if (dev->flags & (IFF_LOOPBACK|IFF_NOARP))
- {
- /*
- * FIXME: fill in the last byte of the dest ipaddr here to better
- * comply with RFC1051 in "noarp" mode. For now, always broadcasting
- * will probably at least get packets sent out :)
+ struct net_device *dev = skb->dev;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
+ struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
+ struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
+
+ /* set the protocol ID according to RFC1201 */
+ switch (type) {
+ case ETH_P_IP:
+ soft->proto = ARC_P_IP;
+ break;
+ case ETH_P_ARP:
+ soft->proto = ARC_P_ARP;
+ break;
+ case ETH_P_RARP:
+ soft->proto = ARC_P_RARP;
+ break;
+ case ETH_P_IPX:
+ case ETH_P_802_3:
+ case ETH_P_802_2:
+ soft->proto = ARC_P_IPX;
+ break;
+ case ETH_P_ATALK:
+ soft->proto = ARC_P_ATALK;
+ break;
+ default:
+ BUGMSG(D_NORMAL, "RFC1201: I don't understand protocol %d (%Xh)\n",
+ type, type);
+ lp->stats.tx_errors++;
+ lp->stats.tx_aborted_errors++;
+ return 0;
+ }
+
+ /*
+ * Set the source hardware address.
+ *
+ * This is pretty pointless for most purposes, but it can help in
+ * debugging. ARCnet does not allow us to change the source address in
+ * the actual packet sent)
*/
- pkt->hard.dest = 0;
- return hdr_size;
- }
+ pkt->hard.source = *dev->dev_addr;
+
+ soft->sequence = htons(lp->rfc1201.sequence++);
+ soft->split_flag = 0; /* split packets are done elsewhere */
- /* otherwise, drop in the dest address */
- pkt->hard.dest = daddr;
- return hdr_size;
+ /* see linux/net/ethernet/eth.c to see where I got the following */
+
+ if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
+ /*
+ * FIXME: fill in the last byte of the dest ipaddr here to better
+ * comply with RFC1051 in "noarp" mode. For now, always broadcasting
+ * will probably at least get packets sent out :)
+ */
+ pkt->hard.dest = 0;
+ return hdr_size;
+ }
+ /* otherwise, drop in the dest address */
+ pkt->hard.dest = daddr;
+ return hdr_size;
}
static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
struct arc_rfc1201 *soft, int softlen, int bufnum)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- int ofs;
-
- /* assume length <= XMTU: someone should have handled that by now. */
-
- if (softlen > MinTU)
- {
- hard->offset[0] = 0;
- hard->offset[1] = ofs = 512 - softlen;
- }
- else if (softlen > MTU) /* exception packet - add an extra header */
- {
- struct arc_rfc1201 excsoft = { soft->proto, 0xFF, 0xFFFF };
-
- hard->offset[0] = 0;
- ofs = 512 - softlen;
- hard->offset[1] = ofs - RFC1201_HDR_SIZE;
- lp->hw.copy_to_card(dev, bufnum, ofs - RFC1201_HDR_SIZE,
- &excsoft, RFC1201_HDR_SIZE);
- }
- else
- hard->offset[0] = ofs = 256 - softlen;
-
- lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
- lp->hw.copy_to_card(dev, bufnum, ofs, soft, softlen);
-
- lp->lastload_dest = hard->dest;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ int ofs;
+
+ /* assume length <= XMTU: someone should have handled that by now. */
+
+ if (softlen > MinTU) {
+ hard->offset[0] = 0;
+ hard->offset[1] = ofs = 512 - softlen;
+ } else if (softlen > MTU) { /* exception packet - add an extra header */
+ struct arc_rfc1201 excsoft =
+ {soft->proto, 0xFF, 0xFFFF};
+
+ hard->offset[0] = 0;
+ ofs = 512 - softlen;
+ hard->offset[1] = ofs - RFC1201_HDR_SIZE;
+ lp->hw.copy_to_card(dev, bufnum, ofs - RFC1201_HDR_SIZE,
+ &excsoft, RFC1201_HDR_SIZE);
+ } else
+ hard->offset[0] = ofs = 256 - softlen;
+
+ lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
+ lp->hw.copy_to_card(dev, bufnum, ofs, soft, softlen);
+
+ lp->lastload_dest = hard->dest;
}
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
- int bufnum)
+ int bufnum)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- const int maxsegsize = XMTU - RFC1201_HDR_SIZE;
- struct Outgoing *out;
-
-
- BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
- lp->next_tx, lp->cur_tx, bufnum);
-
- length -= ARC_HDR_SIZE; /* hard header is not included in packet length */
- pkt->soft.rfc1201.split_flag = 0;
-
- /* need to do a split packet? */
- if (length > XMTU)
- {
- out = &lp->outgoing;
-
- out->length = length - RFC1201_HDR_SIZE;
- out->dataleft = lp->outgoing.length;
- out->numsegs = (out->dataleft + maxsegsize - 1) / maxsegsize;
- out->segnum = 0;
-
- BUGMSG(D_DURING, "rfc1201 prep_tx: ready for %d-segment split "
- "(%d bytes, seq=%d)\n", out->numsegs, out->length,
- pkt->soft.rfc1201.sequence);
-
- return 0; /* not done */
- }
-
- /* just load the packet into the buffers and send it off */
- load_pkt(dev, &pkt->hard, &pkt->soft.rfc1201, length, bufnum);
-
- return 1; /* done */
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ const int maxsegsize = XMTU - RFC1201_HDR_SIZE;
+ struct Outgoing *out;
+
+
+ BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
+ lp->next_tx, lp->cur_tx, bufnum);
+
+ length -= ARC_HDR_SIZE; /* hard header is not included in packet length */
+ pkt->soft.rfc1201.split_flag = 0;
+
+ /* need to do a split packet? */
+ if (length > XMTU) {
+ out = &lp->outgoing;
+
+ out->length = length - RFC1201_HDR_SIZE;
+ out->dataleft = lp->outgoing.length;
+ out->numsegs = (out->dataleft + maxsegsize - 1) / maxsegsize;
+ out->segnum = 0;
+
+ BUGMSG(D_DURING, "rfc1201 prep_tx: ready for %d-segment split "
+ "(%d bytes, seq=%d)\n", out->numsegs, out->length,
+ pkt->soft.rfc1201.sequence);
+
+ return 0; /* not done */
+ }
+ /* just load the packet into the buffers and send it off */
+ load_pkt(dev, &pkt->hard, &pkt->soft.rfc1201, length, bufnum);
+
+ return 1; /* done */
}
static int continue_tx(struct net_device *dev, int bufnum)
{
- struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
- struct Outgoing *out = &lp->outgoing;
- struct arc_hardware *hard = &out->pkt->hard;
- struct arc_rfc1201 *soft = &out->pkt->soft.rfc1201, *newsoft;
- int maxsegsize = XMTU - RFC1201_HDR_SIZE;
- int seglen;
-
- BUGMSG(D_DURING,
- "rfc1201 continue_tx: loading segment %d(+1) of %d (seq=%d)\n",
- out->segnum, out->numsegs, soft->sequence);
-
- /* the "new" soft header comes right before the data chunk */
- newsoft = (struct arc_rfc1201 *)
- (out->pkt->soft.raw + out->length - out->dataleft);
-
- if (!out->segnum) /* first packet; newsoft == soft */
- newsoft->split_flag = ((out->numsegs - 2) << 1) | 1;
- else
- {
- newsoft->split_flag = out->segnum << 1;
- newsoft->proto = soft->proto;
- newsoft->sequence = soft->sequence;
- }
-
- seglen = maxsegsize;
- if (seglen > out->dataleft)
- seglen = out->dataleft;
- out->dataleft -= seglen;
-
- load_pkt(dev, hard, newsoft, seglen + RFC1201_HDR_SIZE, bufnum);
-
- out->segnum++;
- if (out->segnum >= out->numsegs)
- return 1;
- else
- return 0;
+ struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct Outgoing *out = &lp->outgoing;
+ struct arc_hardware *hard = &out->pkt->hard;
+ struct arc_rfc1201 *soft = &out->pkt->soft.rfc1201, *newsoft;
+ int maxsegsize = XMTU - RFC1201_HDR_SIZE;
+ int seglen;
+
+ BUGMSG(D_DURING,
+ "rfc1201 continue_tx: loading segment %d(+1) of %d (seq=%d)\n",
+ out->segnum, out->numsegs, soft->sequence);
+
+ /* the "new" soft header comes right before the data chunk */
+ newsoft = (struct arc_rfc1201 *)
+ (out->pkt->soft.raw + out->length - out->dataleft);
+
+ if (!out->segnum) /* first packet; newsoft == soft */
+ newsoft->split_flag = ((out->numsegs - 2) << 1) | 1;
+ else {
+ newsoft->split_flag = out->segnum << 1;
+ newsoft->proto = soft->proto;
+ newsoft->sequence = soft->sequence;
+ }
+
+ seglen = maxsegsize;
+ if (seglen > out->dataleft)
+ seglen = out->dataleft;
+ out->dataleft -= seglen;
+
+ load_pkt(dev, hard, newsoft, seglen + RFC1201_HDR_SIZE, bufnum);
+
+ out->segnum++;
+ if (out->segnum >= out->numsegs)
+ return 1;
+ else
+ return 0;
}
first_dev = dev;
}
- DBG("PCI: %02x:%02x [%04x/%04x] %06x %02x\n", bus->number, dev->devfn, dev->vendor, dev->device, class, hdr_type);
+ DBG("PCI: %02x:%02x [%04x/%04x] %06x %02x\n", bus->number, dev->devfn, dev->vendor, dev->device, dev->class, hdr_type);
/*
* Put it into the global PCI device chain. It's used to
/* Not configured? Then set up temporary map */
br = (space == 7) ? CB_ROM_BASE : CB_BAR(space-1);
- pci_writel(s->cap.cardbus, 0, br, 0xffffffff);
- pci_readl(s->cap.cardbus, 0, br, &sz);
+ pci_writel(s->cap.cb_dev->subordinate->number, 0, br, 0xffffffff);
+ pci_readl(s->cap.cb_dev->subordinate->number, 0, br, &sz);
sz &= PCI_BASE_ADDRESS_MEM_MASK;
sz = FIND_FIRST_BIT(sz);
if (sz < PAGE_SIZE) sz = PAGE_SIZE;
s->cb_cis_virt = ioremap(base, sz);
DEBUG(1, " phys 0x%08lx-0x%08lx, virt 0x%08lx\n",
base, base+sz-1, (u_long)s->cb_cis_virt);
- pci_writel(s->cap.cardbus, 0, br, base | 1);
- pci_writeb(s->cap.cardbus, 0, PCI_COMMAND, PCI_COMMAND_MEMORY);
+ pci_writel(s->cap.cb_dev->subordinate->number, 0, br, base | 1);
+ pci_writeb(s->cap.cb_dev->subordinate->number, 0, PCI_COMMAND, PCI_COMMAND_MEMORY);
m->map = 0; m->flags = MAP_ACTIVE;
m->start = base; m->stop = base+sz-1;
s->ss_entry->set_bridge(s->sock, m);
CB_ROM_BASE : CB_BAR(s->cb_cis_space-1);
m->map = 0; m->flags = 0;
s->ss_entry->set_bridge(s->sock, m);
- pci_writeb(s->cap.cardbus, 0, PCI_COMMAND, 0);
- pci_writel(s->cap.cardbus, 0, br, 0);
+ pci_writeb(s->cap.cb_dev->subordinate->number, 0, PCI_COMMAND, 0);
+ pci_writel(s->cap.cb_dev->subordinate->number, 0, br, 0);
release_mem_region(m->start, m->stop - m->start + 1);
m->start = 0;
}
if (space == 0) {
if (addr+len > 0x100) goto fail;
for (; len; addr++, ptr++, len--)
- pci_readb(s->cap.cardbus, fn, addr, (u_char *)ptr);
+ pci_readb(s->cap.cb_dev->subordinate->number, fn, addr, (u_char *)ptr);
} else {
if (cb_setup_cis_mem(s, space) != 0) goto fail;
if (space == 7) {
int cb_alloc(socket_info_t *s)
{
+ struct pci_bus *bus;
struct pci_dev tmp;
u_short vend, v, dev;
- u_char i, hdr, fn, bus = s->cap.cardbus;
+ u_char i, hdr, fn;
cb_config_t *c;
+ bus = s->cap.cb_dev->subordinate;
memset(&tmp, 0, sizeof(tmp));
- tmp.bus = s->cap.cb_bus; tmp.devfn = 0;
-
+ tmp.bus = bus; tmp.devfn = 0;
+printk("bus=%p, number=%d\n", bus, bus->number);
pci_read_config_word(&tmp, PCI_VENDOR_ID, &vend);
pci_read_config_word(&tmp, PCI_DEVICE_ID, &dev);
printk(KERN_INFO "cs: cb_alloc(bus %d): vendor 0x%04x, "
- "device 0x%04x\n", bus, vend, dev);
+ "device 0x%04x\n", bus->number, vend, dev);
pci_read_config_byte(&tmp, PCI_HEADER_TYPE, &hdr);
+ fn = 1;
if (hdr & 0x80) {
- /* Count functions */
- for (fn = 0; fn < 8; fn++) {
+ do {
tmp.devfn = fn;
pci_read_config_word(&tmp, PCI_VENDOR_ID, &v);
if (v != vend) break;
- }
- } else fn = 1;
+ fn++;
+ } while (fn < 8);
+ }
s->functions = fn;
c = kmalloc(fn * sizeof(struct cb_config_t), GFP_ATOMIC);
if (!c) return CS_OUT_OF_RESOURCE;
memset(c, 0, fn * sizeof(struct cb_config_t));
- s->cb_config = c;
for (i = 0; i < fn; i++) {
- c[i].dev.bus = s->cap.cb_bus;
- c[i].dev.devfn = i;
+ struct pci_dev *dev = &c[i].dev;
+
+ dev->bus = bus;
+ dev->devfn = i;
if (i < fn-1) {
- c[i].dev.sibling = c[i].dev.next = &c[i+1].dev;
+ dev->sibling = dev->next = &c[i+1].dev;
}
+
+ dev->vendor = vend;
+ pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &dev->class);
+ dev->class >>= 8;
+ dev->hdr_type = hdr;
+#ifdef CONFIG_PROC_FS
+ pci_proc_attach_device(dev);
+#endif
}
- s->cap.cb_bus->devices = &c[0].dev;
+
/* Link into PCI device chain */
+ bus->devices = &c[0].dev;
c[fn-1].dev.next = pci_devices;
pci_devices = &c[0].dev;
- for (i = 0; i < fn; i++) {
- c[i].dev.vendor = vend;
- pci_readw(bus, i, PCI_DEVICE_ID, &c[i].dev.device);
- pci_readl(bus, i, PCI_CLASS_REVISION, &c[i].dev.class);
- c[i].dev.class >>= 8;
- c[i].dev.hdr_type = hdr;
-#ifdef CONFIG_PROC_FS
- pci_proc_attach_device(&c[i].dev);
-#endif
- }
+ s->cb_config = c;
return CS_SUCCESS;
}
void cb_free(socket_info_t *s)
{
cb_config_t *c = s->cb_config;
+ struct pci_bus *bus = s->cap.cb_dev->subordinate;
if (c) {
struct pci_dev **p;
p = &pci_devices;
while (*p) {
struct pci_dev * dev = *p;
- if (dev->bus != s->cap.cb_bus) {
+ if (dev->bus != bus) {
p = &dev->next;
continue;
}
pci_proc_detach_device(dev);
#endif
}
- s->cap.cb_bus->devices = NULL;
+ bus->devices = NULL;
kfree(s->cb_config);
s->cb_config = NULL;
- printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cardbus);
+ printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number);
}
}
{
cb_config_t *c = s->cb_config;
u_char fn = s->functions;
- u_char i, j, bus = s->cap.cardbus, *name;
+ u_char i, j, bus = s->cap.cb_dev->subordinate->number, *name;
u_int sz, align, m, mask[3], num[3], base[3];
int irq, try, ret;
- printk(KERN_INFO "cs: cb_config(bus %d)\n", s->cap.cardbus);
+ printk(KERN_INFO "cs: cb_config(bus %d)\n", s->cap.cb_dev->subordinate->number);
/* Determine IO and memory space needs */
num[B_IO] = num[B_M1] = num[B_M2] = 0;
{
cb_config_t *c = s->cb_config;
- DEBUG(0, "cs: cb_release(bus %d)\n", s->cap.cardbus);
+ DEBUG(0, "cs: cb_release(bus %d)\n", s->cap.cb_dev->subordinate->number);
if (s->win[0].size > 0)
release_mem_region(s->win[0].base, s->win[0].size);
void cb_enable(socket_info_t *s)
{
- u_char i, j, bus = s->cap.cardbus;
+ u_char i, j, bus = s->cap.cb_dev->subordinate->number;
cb_config_t *c = s->cb_config;
DEBUG(0, "cs: cb_enable(bus %d)\n", bus);
u_char i;
cb_bridge_map m = { 0, 0, 0, 0xffff };
- DEBUG(0, "cs: cb_disable(bus %d)\n", s->cap.cardbus);
+ DEBUG(0, "cs: cb_disable(bus %d)\n", s->cap.cb_dev->subordinate->number);
/* Turn off bridge windows */
if (s->cb_cis_map.start)
#ifdef CONFIG_CARDBUS
if (s->state & SOCKET_CARDBUS) {
u_int ptr;
- pcibios_read_config_dword(s->cap.cardbus, 0, 0x28, &ptr);
+ pcibios_read_config_dword(s->cap.cb_dev->subordinate->number, 0, 0x28, &ptr);
tuple->CISOffset = ptr & ~7;
SPACE(tuple->Flags) = (ptr & 7);
} else
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/compile.h>
+#include <linux/pci.h>
#include <asm/system.h>
#include <asm/irq.h>
config->Function = fn;
config->Vcc = s->socket.Vcc;
config->Vpp1 = config->Vpp2 = s->socket.Vpp;
- config->Option = s->cap.cardbus;
+ config->Option = s->cap.cb_dev->subordinate->number;
if (s->cb_config) {
config->Attributes = CONF_VALID_CLIENT;
config->IntType = INT_CARDBUS;
break;
}
request_mem_region(s->cb_phys, 0x1000, "i82365");
- s->cap.cb_bus = dev->subordinate;
+ s->cap.cb_dev = dev;
add_socket(0, 0, type);
}
if (ns == 0) return;
static struct pci_simple_probe_entry controller_list[] = {
{ PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1225, 0, 0, ¥ta_operations },
- { 0x1180, 0x0475, 0, 0, ¥ta_operations },
+ { 0x1180, 0x0475, 0, 0, &ricoh_operations },
{ 0, 0, 0, 0, NULL }
};
};
extern struct pci_socket_ops yenta_operations;
+extern struct pci_socket_ops ricoh_operations;
+
#include "yenta.h"
#include "i82365.h"
+#include "ricoh.h"
/* Don't ask.. */
#define to_cycles(ns) ((ns)/120)
#define to_ns(cycles) ((cycles)*120)
+/*
+ * Generate easy-to-use ways of reading a cardbus sockets
+ * regular memory space ("cb_xxx"), configuration space
+ * ("config_xxx") and compatibility space ("exca_xxxx")
+ */
+#define cb_readl(sock,reg) readl((sock)->base + (reg))
+#define cb_writel(sock,reg,val) writel(val,(sock)->base + (reg))
+
+static inline u8 config_readb(pci_socket_t *socket, unsigned offset)
+{
+ u8 val;
+ pci_read_config_byte(socket->dev, offset, &val);
+ return val;
+}
+
+static inline u16 config_readw(pci_socket_t *socket, unsigned offset)
+{
+ u16 val;
+ pci_read_config_word(socket->dev, offset, &val);
+ return val;
+}
+
+static inline u32 config_readl(pci_socket_t *socket, unsigned offset)
+{
+ u32 val;
+ pci_read_config_dword(socket->dev, offset, &val);
+ return val;
+}
+
+#define config_writeb(s,off,val) pci_write_config_byte((s)->dev, (off), (val))
+#define config_writew(s,off,val) pci_write_config_word((s)->dev, (off), (val))
+#define config_writel(s,off,val) pci_write_config_dword((s)->dev, (off), (val))
+
+#define exca_readb(sock,reg) readb((sock)->base + 0x800 + (reg))
+#define exca_writeb(sock,reg,v) writeb((v), (sock)->base + 0x800 + (reg))
+
+static u16 exca_readw(pci_socket_t *socket, unsigned reg)
+{
+ return exca_readb(socket, reg) | (exca_readb(socket, reg+1) << 8);
+}
+
+static void exca_writew(pci_socket_t *socket, unsigned reg, u16 val)
+{
+ exca_writeb(socket, reg, val);
+ exca_writeb(socket, reg+1, val >> 8);
+}
+
static int yenta_inquire(pci_socket_t *socket, socket_cap_t *cap)
{
*cap = socket->cap;
}
/*
- * Silly interface. We convert the cardbus status to a internal status,
- * and we probably really should keep it in cardbus status form and
- * only convert for old-style 16-bit PCMCIA cards..
+ * Ugh, mixed-mode cardbus and 16-bit pccard state: things depend
+ * on what kind of card is inserted..
*/
static int yenta_get_status(pci_socket_t *socket, unsigned int *value)
{
- u32 state = cb_readl(socket, CB_SOCKET_STATE);
unsigned int val;
+ u32 state = cb_readl(socket, CB_SOCKET_STATE);
- /* Convert from Yenta status to old-style status */
- val = (state & CB_CARDSTS) ? SS_STSCHG : 0;
- val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
- val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
- val |= (state & CB_CBCARD) ? SS_CARDBUS : 0;
- val |= (state & CB_3VCARD) ? SS_3VCARD : 0;
+ val = (state & CB_3VCARD) ? SS_3VCARD : 0;
val |= (state & CB_XVCARD) ? SS_XVCARD : 0;
- /* Get the old compatibility status too.. */
- if (!(state & CB_CBCARD)) {
+ if (state & CB_CBCARD) {
+ val |= SS_CARDBUS;
+ val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
+ val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
+ val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
+ } else {
u8 status = exca_readb(socket, I365_STATUS);
+ val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
+ if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
+ val |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
+ } else {
+ val |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
+ val |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
+ }
val |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
val |= (status & I365_CS_READY) ? SS_READY : 0;
val |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
}
-printk("yenta_get_status(%p)= %x\n", socket, val);
-
*value = val;
return 0;
}
static int yenta_Vcc_power(u32 control)
{
- switch ((control >> CB_VCCCTRL) & CB_PWRBITS) {
- case CB_PWR5V: return 50;
- case CB_PWR3V: return 33;
+ switch (control & CB_SC_VCC_MASK) {
+ case CB_SC_VCC_5V: return 50;
+ case CB_SC_VCC_3V: return 33;
default: return 0;
}
}
static int yenta_Vpp_power(u32 control)
{
- switch ((control >> CB_VPPCTRL) & CB_PWRBITS) {
- case CB_PWR12V: return 120;
- case CB_PWR5V: return 50;
- case CB_PWR3V: return 33;
+ switch (control & CB_SC_VPP_MASK) {
+ case CB_SC_VPP_12V: return 120;
+ case CB_SC_VPP_5V: return 50;
+ case CB_SC_VPP_3V: return 33;
default: return 0;
}
}
state->Vpp = yenta_Vpp_power(control);
state->io_irq = socket->io_irq;
- if (cb_readb(socket, CB_SOCKET_STATE) & CB_CBCARD) {
- u16 bridge = cb_readw(socket, CB_BRIDGE_CONTROL);
+ if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
+ u16 bridge = config_readw(socket, CB_BRIDGE_CONTROL);
if (bridge & CB_BRIDGE_CRST)
state->flags |= SS_RESET;
return 0;
static void yenta_set_power(pci_socket_t *socket, socket_state_t *state)
{
- u32 control = CB_STOPCLK;
-
+ u32 reg = 0; /* CB_SC_STPCLK? */
switch (state->Vcc) {
- case 33:
- control |= CB_PWR3V << CB_VCCCTRL;
- break;
- case 50:
- control |= CB_PWR5V << CB_VCCCTRL;
- break;
+ case 33: reg = CB_SC_VCC_3V; break;
+ case 50: reg = CB_SC_VCC_5V; break;
+ default: reg = 0; break;
}
switch (state->Vpp) {
- case 33:
- control |= CB_PWR3V << CB_VPPCTRL;
- break;
- case 50:
- control |= CB_PWR5V << CB_VPPCTRL;
- break;
- case 120:
- control |= CB_PWR12V << CB_VPPCTRL;
- break;
+ case 33: reg |= CB_SC_VPP_3V; break;
+ case 50: reg |= CB_SC_VPP_5V; break;
+ case 120: reg |= CB_SC_VPP_12V; break;
}
- cb_writel(socket, CB_SOCKET_CONTROL, control);
+ if (reg != cb_readl(socket, CB_SOCKET_CONTROL))
+ cb_writel(socket, CB_SOCKET_CONTROL, reg);
+}
+
+static void yenta_bridge_control(pci_socket_t *socket, u16 bridgectl)
+{
+ struct pci_dev *dev = socket->dev;
+
+ /* MAGIC NUMBERS! Fixme */
+ config_writew(socket, CB_BRIDGE_CONTROL, bridgectl);
+ config_writel(socket, CB_LEGACY_MODE_BASE, 0);
+
+ config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start);
+ config_writew(socket, PCI_COMMAND,
+ PCI_COMMAND_IO |
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER |
+ PCI_COMMAND_WAIT);
+ config_writeb(socket, PCI_CACHE_LINE_SIZE, 32);
+ config_writeb(socket, PCI_LATENCY_TIMER, 168);
+ config_writeb(socket, PCI_SEC_LATENCY_TIMER, 176);
+ config_writeb(socket, PCI_PRIMARY_BUS, dev->bus->number);
+ config_writeb(socket, PCI_SECONDARY_BUS, dev->subordinate->number);
+ config_writeb(socket, PCI_SUBORDINATE_BUS, dev->subordinate->number);
+ config_writew(socket, CB_BRIDGE_CONTROL, bridgectl);
}
static int yenta_set_socket(pci_socket_t *socket, socket_state_t *state)
bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_CRST;
- if (cb_readb(socket, CB_SOCKET_STATE) & CB_CBCARD) {
+ if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
bridge |= (state->flags & SS_RESET) ? CB_BRIDGE_CRST : 0;
/* ISA interrupt control? */
reg |= I365_PWR_NORESET;
if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
- exca_writeb(socket, I365_POWER, reg);
+ if (exca_readb(socket, I365_POWER) != reg)
+ exca_writeb(socket, I365_POWER, reg);
/* CSC interrupt: no ISA irq for CSC */
reg = I365_CSC_DETECT;
exca_writeb(socket, I365_CSCINT, reg);
exca_readb(socket, I365_CSC);
}
- config_writew(socket, CB_BRIDGE_CONTROL, bridge);
+ yenta_bridge_control(socket, bridge);
/* Socket event mask: get card insert/remove events.. */
cb_writel(socket, CB_SOCKET_EVENT, -1);
start = (start & 0x0fff) << 12;
stop = exca_readw(socket, I365_MEM(map) + I365_W_STOP);
- mem->speed = (stop & I365_MEM_WS0) ? 1 : 0;
- mem->speed += (stop & I365_MEM_WS1) ? 2 : 0;
- mem->speed = to_ns(mem->speed);
+ mem->speed = to_ns(stop >> 14);
stop = ((stop & 0x0fff) << 12) + 0x0fff;
offset = exca_readw(socket, I365_MEM(map) + I365_W_OFF);
stop = mem->sys_stop;
card_start = mem->card_start;
- if (map > 4 || start > stop || ((start ^ stop) >> 24) || (card_start >> 26) || mem->speed > 1000)
+ if (map > 4 || start > stop || ((start ^ stop) >> 24) ||
+ (card_start >> 26) || mem->speed > 1000)
return -EINVAL;
enable = I365_ENA_MEM(map);
events |= (csc & I365_CSC_READY) ? SS_READY : 0;
}
- printk("Socket interrupt event %08x (%08x %02x)\n", events, cb_event, csc);
-
if (events && socket->handler)
socket->handler(socket->info, events);
}
return probe_irq_mask(val);
}
-static void yenta_get_socket_capabilities(pci_socket_t *socket)
-{
- /* MAGIC NUMBERS! Fixme */
- config_writeb(socket, PCI_LATENCY_TIMER, 168);
- config_writeb(socket, PCI_SEC_LATENCY_TIMER, 176);
-
- socket->cap.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
- socket->cap.map_size = 0x1000;
- socket->cap.pci_irq = socket->cb_irq;
- socket->cap.irq_mask = yenta_probe_irq(socket);
- socket->cap.cardbus = config_readb(socket, PCI_CB_CARD_BUS);
- socket->cap.cb_bus = socket->dev->subordinate;
- socket->cap.bus = NULL;
-
- printk("Yenta IRQ list %04x\n", socket->cap.irq_mask);
-}
-
/* Called at resume and initialization events */
static int yenta_init(pci_socket_t *socket)
{
pci_set_power_state(socket->dev, 0);
- mem.sys_stop = 0x1000;
+ /* MAGIC NUMBERS! Fixme */
+ config_writeb(socket, PCI_LATENCY_TIMER, 168);
+ config_writeb(socket, PCI_SEC_LATENCY_TIMER, 176);
+
+ exca_writeb(socket, I365_GBLCTL, 0x00);
+ exca_writeb(socket, I365_GENCTL, 0x00);
+
+ mem.sys_stop = 0x0fff;
yenta_set_socket(socket, &dead_socket);
for (i = 0; i < 2; i++) {
io.map = i;
return 0;
}
+/*
+ * More of an example than anything else... The standard
+ * yenta init code works well enough - but this is how
+ * you'd do it if you wanted to have a special init sequence.
+ */
+static int ricoh_init(pci_socket_t *socket)
+{
+ u16 misc = config_readw(socket, RL5C4XX_MISC);
+ u16 ctl = config_readw(socket, RL5C4XX_16BIT_CTL);
+ u16 io = config_readw(socket, RL5C4XX_16BIT_IO_0);
+ u16 mem = config_readw(socket, RL5C4XX_16BIT_MEM_0);
+
+ ctl = RL5C4XX_16CTL_IO_TIMING | RL5C4XX_16CTL_MEM_TIMING;
+
+ config_writew(socket, RL5C4XX_MISC, misc);
+ config_writew(socket, RL5C4XX_16BIT_CTL, ctl);
+ config_writew(socket, RL5C4XX_16BIT_IO_0, io);
+ config_writew(socket, RL5C4XX_16BIT_MEM_0, mem);
+
+ return yenta_init(socket);
+}
+
+
static int yenta_suspend(pci_socket_t *socket)
{
yenta_set_socket(socket, &dead_socket);
return 0;
}
+/*
+ * Set static data that doesn't need re-initializing..
+ */
+static void yenta_get_socket_capabilities(pci_socket_t *socket)
+{
+ socket->cap.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
+ socket->cap.map_size = 0x1000;
+ socket->cap.pci_irq = socket->cb_irq;
+ socket->cap.irq_mask = yenta_probe_irq(socket);
+ socket->cap.cb_dev = socket->dev;
+ socket->cap.bus = NULL;
+
+ printk("Yenta IRQ list %04x\n", socket->cap.irq_mask);
+}
+
/*
* Initialize a cardbus controller. Make sure we have a usable
* interrupt, and that we can map the cardbus area. Fill in the
/* Figure out what the dang thing can do.. */
yenta_get_socket_capabilities(socket);
- /* Enable all events */
- writel(0x0f, socket->base + 4);
+ /* Disable all events */
+ cb_writel(socket, CB_SOCKET_MASK, 0x0);
- printk("Socket status: %08x\n", readl(socket->base + 8));
+ printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
return 0;
}
iounmap(sock->base);
}
+/*
+ * Standard plain cardbus - no frills, no extensions
+ */
struct pci_socket_ops yenta_operations = {
yenta_open,
yenta_close,
yenta_set_bridge,
yenta_proc_setup
};
+
+/*
+ * Ricoh cardbus bridge: standard cardbus, except it needs
+ * some extra init code to set timings etc.
+ */
+struct pci_socket_ops ricoh_operations = {
+ yenta_open,
+ yenta_close,
+ ricoh_init,
+ yenta_suspend,
+ yenta_inquire,
+ yenta_get_status,
+ yenta_get_socket,
+ yenta_set_socket,
+ yenta_get_io_map,
+ yenta_set_io_map,
+ yenta_get_mem_map,
+ yenta_set_mem_map,
+ yenta_get_bridge,
+ yenta_set_bridge,
+ yenta_proc_setup
+};
#include <asm/io.h>
#include "pci_socket.h"
-/*
- * Generate easy-to-use ways of reading a cardbus sockets
- * regular memory space ("cb_xxx"), configuration space
- * ("config_xxx") and compatibility space ("exca_xxxx")
- */
-
-#define cb_readb(sock,reg) readb((sock)->base + (reg))
-#define cb_readw(sock,reg) readw((sock)->base + (reg))
-#define cb_readl(sock,reg) readl((sock)->base + (reg))
-#define cb_writeb(sock,reg,val) writeb((val), (sock)->base + (reg))
-#define cb_writew(sock,reg,val) writew((val), (sock)->base + (reg))
-#define cb_writel(sock,reg,val) writel((val), (sock)->base + (reg))
-
-#define config_readb(sock,offset) ({ __u8 __val; pci_read_config_byte((sock)->dev, (offset), &__val); __val; })
-#define config_readw(sock,offset) ({ __u16 __val; pci_read_config_word((sock)->dev, (offset), &__val); __val; })
-#define config_readl(sock,offset) ({ __u32 __val; pci_read_config_dword((sock)->dev, (offset), &__val); __val; })
-
-#define config_writeb(sock,offset,val) pci_write_config_byte((sock)->dev, (offset), (val))
-#define config_writew(sock,offset,val) pci_write_config_word((sock)->dev, (offset), (val))
-#define config_writel(sock,offset,val) pci_write_config_dword((sock)->dev, (offset), (val))
-
-#define exca_readb(sock,reg) cb_readb((sock),(reg)+0x0800)
-#define exca_readw(sock,reg) cb_readw((sock),(reg)+0x0800)
-#define exca_readl(sock,reg) cb_readl((sock),(reg)+0x0800)
-
-#define exca_writeb(sock,reg,val) cb_writeb((sock),(reg)+0x0800,(val))
-#define exca_writew(sock,reg,val) cb_writew((sock),(reg)+0x0800,(val))
-#define exca_writel(sock,reg,val) cb_writel((sock),(reg)+0x0800,(val))
-
#define CB_SOCKET_EVENT 0x00
#define CB_CSTSEVENT 0x00000001 /* Card status event */
#define CB_CD1EVENT 0x00000002 /* Card detect 1 change event */
#define CB_CVSTEST 0x00004000 /* Card VS test */
#define CB_SOCKET_CONTROL 0x10
-#define CB_VPPCTRL 0 /* Shift for Vpp */
-#define CB_VCCCTRL 4 /* Shift for Vcc */
-#define CB_STOPCLK 0x00000080 /* CLKRUN can slow CB clock when idle */
-
-#define CB_PWRBITS 0x7
-#define CB_PWROFF 0x0
-#define CB_PWR12V 0x1 /* Only valid for Vpp */
-#define CB_PWR5V 0x2
-#define CB_PWR3V 0x3
-#define CB_PWRXV 0x4
-#define CB_PWRYV 0x5
+#define CB_SC_VPP_MASK 0x00000007
+#define CB_SC_VPP_OFF 0x00000000
+#define CB_SC_VPP_12V 0x00000001
+#define CB_SC_VPP_5V 0x00000002
+#define CB_SC_VPP_3V 0x00000003
+#define CB_SC_VPP_XV 0x00000004
+#define CB_SC_VPP_YV 0x00000005
+#define CB_SC_VCC_MASK 0x00000070
+#define CB_SC_VCC_OFF 0x00000000
+#define CB_SC_VCC_5V 0x00000020
+#define CB_SC_VCC_3V 0x00000030
+#define CB_SC_VCC_XV 0x00000040
+#define CB_SC_VCC_YV 0x00000050
+#define CB_SC_CCLK_STOP 0x00000080
#define CB_SOCKET_POWER 0x20
#define CB_SKTACCES 0x02000000 /* A PC card access has occurred (clear on read) */
#define CB_BRIDGE_PREFETCH0 0x00000100
#define CB_BRIDGE_PREFETCH1 0x00000200
#define CB_BRIDGE_POSTEN 0x00000400
+#define CB_LEGACY_MODE_BASE 0x44
/*
* ExCA area extensions in Yenta
dep_tristate ' UHCI (Intel PIIX4, VIA, and others) support' CONFIG_USB_UHCI \
$CONFIG_USB
- dep_tristate ' OHCI-HCD (Compaq, iMacs, OPTi, SiS, and others) support' \
+ dep_tristate ' OHCI-HCD (Compaq, iMacs, OPTi, SiS, ALi, and others) support' \
CONFIG_USB_OHCI_HCD $CONFIG_USB
comment 'Miscellaneous USB options'
+++ /dev/null
-#!/usr/bin/perl
-
-# Reads /proc/bus/usb/devices and selectively lists and/or
-# interprets it.
-
-$DEVFILENAME = "/proc/bus/usb/devices";
-$PROGNAME = $0;
-
-$TAGS = $ARGV[0]; # save user TAGS
-if (length ($TAGS) == 0)
-{
- print "usage: $PROGNAME tags\n";
- print " where 'tags' can be any number of 'TDPCIE' or 'A(LL)'\n";
- exit 1;
-}
-
-$ALL = ($TAGS =~ /all/i) || ($TAGS =~ /a/i);
-
-# TBD: Check that $TAGS is valid.
-if (! $ALL)
-{
-}
-
-if (! open (DEVNUM, "<$DEVFILENAME"))
-{
- print "$PROGNAME: cannot open '$DEVFILENAME'\n";
- exit 1;
-}
-
-while ($line = <DEVNUM>) # read a text line from DEVNUM
-{
- if (($ALL) || ($line =~ /^[$TAGS]:/i)) # any of TAGS at beg. of line?
- {
- print "$line"; # still has newline char on it
- # TBD: add more/paging functionality.
- }
-} # end while DEVNUM
-
-close (DEVNUM);
-
-# END.
#include <linux/smp_lock.h>
#include <linux/quotaops.h>
#include <linux/pagemap.h>
+#include <linux/dcache.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
return permission(dir,MAY_WRITE | MAY_EXEC);
}
-static inline struct dentry *get_parent(struct dentry *dentry)
-{
- return dget(dentry->d_parent);
-}
-
-static inline void unlock_dir(struct dentry *dir)
-{
- up(&dir->d_inode->i_sem);
- dput(dir);
-}
-
-/*
- * We need to do a check-parent every time
- * after we have locked the parent - to verify
- * that the parent is still our parent and
- * that we are still hashed onto it..
- *
- * This is requied in case two processes race
- * on removing (or moving) the same entry: the
- * parent lock will serialize them, but the
- * other process will be too late..
- */
-#define check_parent(dir, dentry) \
- ((dir) == (dentry)->d_parent && !list_empty(&dentry->d_hash))
-
-/*
- * Locking the parent is needed to:
- * - serialize directory operations
- * - make sure the parent doesn't change from
- * under us in the middle of an operation.
- *
- * NOTE! Right now we'd rather use a "struct inode"
- * for this, but as I expect things to move toward
- * using dentries instead for most things it is
- * probably better to start with the conceptually
- * better interface of relying on a path of dentries.
- */
-static inline struct dentry *lock_parent(struct dentry *dentry)
-{
- struct dentry *dir = dget(dentry->d_parent);
-
- down(&dir->d_inode->i_sem);
- return dir;
-}
-
-/*
- * Whee.. Deadlock country. Happily there are only two VFS
- * operations that do this..
- */
-static inline void double_lock(struct dentry *d1, struct dentry *d2)
-{
- struct semaphore *s1 = &d1->d_inode->i_sem;
- struct semaphore *s2 = &d2->d_inode->i_sem;
-
- if (s1 != s2) {
- if ((unsigned long) s1 < (unsigned long) s2) {
- struct semaphore *tmp = s2;
- s2 = s1; s1 = tmp;
- }
- down(s1);
- }
- down(s2);
-}
-
-static inline void double_unlock(struct dentry *d1, struct dentry *d2)
-{
- struct semaphore *s1 = &d1->d_inode->i_sem;
- struct semaphore *s2 = &d2->d_inode->i_sem;
-
- up(s1);
- if (s1 != s2)
- up(s2);
- dput(d1);
- dput(d2);
-}
-
-
/*
* Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
* reasons.
#ifdef __KERNEL__
#ifndef bool
-# define bool int
+#define bool int
#endif
x==D_NORMAL ? KERN_WARNING \
: x < D_DURING ? KERN_INFO : KERN_DEBUG, \
dev->name , ## args)
-
+
/* see how long a function call takes to run, expressed in CPU cycles */
#define TIME(name, bytes, call) BUGLVL(D_TIMING) { \
cycles_t _x, _y; \
/* information needed to define an encapsulation driver */
-struct ArcProto
-{
- char suffix; /* a for RFC1201, e for ether-encap, etc. */
- int mtu; /* largest possible packet */
-
- void (*rx)(struct net_device *dev, int bufnum,
- struct archdr *pkthdr, int length);
- int (*build_header)(struct sk_buff *skb, unsigned short ethproto,
- uint8_t daddr);
-
- /* these functions return '1' if the skb can now be freed */
- int (*prepare_tx)(struct net_device *dev, struct archdr *pkt, int length,
- int bufnum);
- int (*continue_tx)(struct net_device *dev, int bufnum);
+struct ArcProto {
+ char suffix; /* a for RFC1201, e for ether-encap, etc. */
+ int mtu; /* largest possible packet */
+
+ void (*rx) (struct net_device * dev, int bufnum,
+ struct archdr * pkthdr, int length);
+ int (*build_header) (struct sk_buff * skb, unsigned short ethproto,
+ uint8_t daddr);
+
+ /* these functions return '1' if the skb can now be freed */
+ int (*prepare_tx) (struct net_device * dev, struct archdr * pkt, int length,
+ int bufnum);
+ int (*continue_tx) (struct net_device * dev, int bufnum);
};
-extern struct ArcProto *arc_proto_map[256],
- *arc_proto_default, *arc_bcast_proto;
+extern struct ArcProto *arc_proto_map[256], *arc_proto_default, *arc_bcast_proto;
extern struct ArcProto arc_proto_null;
* "Incoming" is information needed for each address that could be sending
* to us. Mostly for partially-received split packets.
*/
-struct Incoming
-{
- struct sk_buff *skb; /* packet data buffer */
- uint16_t sequence; /* sequence number of assembly */
- uint8_t lastpacket, /* number of last packet (from 1) */
- numpackets; /* number of packets in split */
+struct Incoming {
+ struct sk_buff *skb; /* packet data buffer */
+ uint16_t sequence; /* sequence number of assembly */
+ uint8_t lastpacket, /* number of last packet (from 1) */
+ numpackets; /* number of packets in split */
};
/* only needed for RFC1201 */
-struct Outgoing
-{
- struct ArcProto *proto; /* protocol driver that owns this:
+struct Outgoing {
+ struct ArcProto *proto; /* protocol driver that owns this:
* if NULL, no packet is pending.
*/
- struct sk_buff *skb; /* buffer from upper levels */
- struct archdr *pkt; /* a pointer into the skb */
- uint16_t length, /* bytes total */
- dataleft, /* bytes left */
- segnum, /* segment being sent */
- numsegs; /* number of segments */
+ struct sk_buff *skb; /* buffer from upper levels */
+ struct archdr *pkt; /* a pointer into the skb */
+ uint16_t length, /* bytes total */
+ dataleft, /* bytes left */
+ segnum, /* segment being sent */
+ numsegs; /* number of segments */
};
-struct arcnet_local
-{
- struct net_device_stats stats;
-
- uint8_t config, /* current value of CONFIG register */
- timeout, /* Extended timeout for COM20020 */
- backplane, /* Backplane flag for COM20020 */
- clock, /* COM20020 clock speed flag */
- setup, /* Contents of setup register */
- intmask; /* current value of INTMASK register */
- uint8_t default_proto[256]; /* default encap to use for each host */
- int cur_tx, /* buffer used by current transmit, or -1 */
- next_tx, /* buffer where a packet is ready to send */
- cur_rx; /* current receive buffer */
- int lastload_dest, /* can last loaded packet be acked? */
- lasttrans_dest; /* can last TX'd packet be acked? */
- int basename_len; /* name length without suffix ('arc0e' -> 4) */
-
- /*
- * Buffer management: an ARCnet card has 4 x 512-byte buffers, each of
- * which can be used for either sending or receiving. The new dynamic
- * buffer management routines use a simple circular queue of available
- * buffers, and take them as they're needed. This way, we simplify
- * situations in which we (for example) want to pre-load a transmit
- * buffer, or start receiving while we copy a received packet to
- * memory.
- *
- * The rules: only the interrupt handler is allowed to _add_ buffers to
- * the queue; thus, this doesn't require a lock. Both the interrupt
- * handler and the transmit function will want to _remove_ buffers, so
- * we need to handle the situation where they try to do it at the same
- * time.
- *
- * If next_buf == first_free_buf, the queue is empty. Since there are
- * only four possible buffers, the queue should never be full.
- */
- atomic_t buf_lock;
- int buf_queue[5];
- int next_buf, first_free_buf;
-
- /* network "reconfiguration" handling */
- time_t first_recon, /* time of "first" RECON message to count */
- last_recon; /* time of most recent RECON */
- int num_recons; /* number of RECONs between first and last. */
- bool network_down; /* do we think the network is down? */
-
- struct {
- uint16_t sequence; /* sequence number (incs with each packet) */
- uint16_t aborted_seq;
-
- struct Incoming incoming[256]; /* one from each address */
- } rfc1201;
-
- /* really only used by rfc1201, but we'll pretend it's not */
- struct Outgoing outgoing; /* packet currently being sent */
-
- /* hardware-specific functions */
- struct {
- void (*command) (struct net_device *dev, int cmd);
- int (*status) (struct net_device *dev);
- void (*intmask) (struct net_device *dev, int mask);
- bool (*reset) (struct net_device *dev, bool really_reset);
- void (*open_close)(struct net_device *dev, bool open);
- void (*open_close_ll)(struct net_device *dev, bool open);
-
- void (*copy_to_card)(struct net_device *dev, int bufnum, int offset,
- void *buf, int count);
- void (*copy_from_card)(struct net_device *dev, int bufnum, int offset,
- void *buf, int count);
- } hw;
-
- void *mem_start; /* pointer to ioremap'ed MMIO */
+struct arcnet_local {
+ struct net_device_stats stats;
+
+ uint8_t config, /* current value of CONFIG register */
+ timeout, /* Extended timeout for COM20020 */
+ backplane, /* Backplane flag for COM20020 */
+ clock, /* COM20020 clock speed flag */
+ setup, /* Contents of setup register */
+ intmask; /* current value of INTMASK register */
+ uint8_t default_proto[256]; /* default encap to use for each host */
+ int cur_tx, /* buffer used by current transmit, or -1 */
+ next_tx, /* buffer where a packet is ready to send */
+ cur_rx; /* current receive buffer */
+ int lastload_dest, /* can last loaded packet be acked? */
+ lasttrans_dest; /* can last TX'd packet be acked? */
+ int basename_len; /* name length without suffix ('arc0e' -> 4) */
+
+ /*
+ * Buffer management: an ARCnet card has 4 x 512-byte buffers, each of
+ * which can be used for either sending or receiving. The new dynamic
+ * buffer management routines use a simple circular queue of available
+ * buffers, and take them as they're needed. This way, we simplify
+ * situations in which we (for example) want to pre-load a transmit
+ * buffer, or start receiving while we copy a received packet to
+ * memory.
+ *
+ * The rules: only the interrupt handler is allowed to _add_ buffers to
+ * the queue; thus, this doesn't require a lock. Both the interrupt
+ * handler and the transmit function will want to _remove_ buffers, so
+ * we need to handle the situation where they try to do it at the same
+ * time.
+ *
+ * If next_buf == first_free_buf, the queue is empty. Since there are
+ * only four possible buffers, the queue should never be full.
+ */
+ atomic_t buf_lock;
+ int buf_queue[5];
+ int next_buf, first_free_buf;
+
+ /* network "reconfiguration" handling */
+ time_t first_recon, /* time of "first" RECON message to count */
+ last_recon; /* time of most recent RECON */
+ int num_recons; /* number of RECONs between first and last. */
+ bool network_down; /* do we think the network is down? */
+
+ struct {
+ uint16_t sequence; /* sequence number (incs with each packet) */
+ uint16_t aborted_seq;
+
+ struct Incoming incoming[256]; /* one from each address */
+ } rfc1201;
+
+ /* really only used by rfc1201, but we'll pretend it's not */
+ struct Outgoing outgoing; /* packet currently being sent */
+
+ /* hardware-specific functions */
+ struct {
+ void (*command) (struct net_device * dev, int cmd);
+ int (*status) (struct net_device * dev);
+ void (*intmask) (struct net_device * dev, int mask);
+ bool (*reset) (struct net_device * dev, bool really_reset);
+ void (*open_close) (struct net_device * dev, bool open);
+ void (*open_close_ll) (struct net_device * dev, bool open);
+
+ void (*copy_to_card) (struct net_device * dev, int bufnum, int offset,
+ void *buf, int count);
+ void (*copy_from_card) (struct net_device * dev, int bufnum, int offset,
+ void *buf, int count);
+ } hw;
+
+ void *mem_start; /* pointer to ioremap'ed MMIO */
};
#if ARCNET_DEBUG_MAX & D_SKB
void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc);
#else
-# define arcnet_dump_skb(dev,skb,desc) ;
+#define arcnet_dump_skb(dev,skb,desc) ;
#endif
#if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX)
void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc);
#else
-# define arcnet_dump_packet(dev, bufnum, desc) ;
+#define arcnet_dump_packet(dev, bufnum, desc) ;
#endif
void arcnet_unregister_proto(struct ArcProto *proto);
int com90xx_probe(struct net_device *dev);
void com20020pci_probe_all(void);
-#endif /* __KERNEL__ */
+#endif /* __KERNEL__ */
-#endif /* _LINUX_ARCDEVICE_H */
+#endif /* _LINUX_ARCDEVICE_H */
extern int inode_change_ok(struct inode *, struct iattr *);
extern void inode_setattr(struct inode *, struct iattr *);
+/*
+ * Common dentry functions for inclusion in the VFS
+ * or in other stackable file systems. Some of these
+ * functions were in linux/fs/ C (VFS) files.
+ *
+ */
+
+/*
+ * We need to do a check-parent every time
+ * after we have locked the parent - to verify
+ * that the parent is still our parent and
+ * that we are still hashed onto it..
+ *
+ * This is required in case two processes race
+ * on removing (or moving) the same entry: the
+ * parent lock will serialize them, but the
+ * other process will be too late..
+ */
+#define check_parent(dir, dentry) \
+ ((dir) == (dentry)->d_parent && !list_empty(&dentry->d_hash))
+
+/*
+ * Locking the parent is needed to:
+ * - serialize directory operations
+ * - make sure the parent doesn't change from
+ * under us in the middle of an operation.
+ *
+ * NOTE! Right now we'd rather use a "struct inode"
+ * for this, but as I expect things to move toward
+ * using dentries instead for most things it is
+ * probably better to start with the conceptually
+ * better interface of relying on a path of dentries.
+ */
+static inline struct dentry *lock_parent(struct dentry *dentry)
+{
+ struct dentry *dir = dget(dentry->d_parent);
+
+ down(&dir->d_inode->i_sem);
+ return dir;
+}
+
+static inline struct dentry *get_parent(struct dentry *dentry)
+{
+ return dget(dentry->d_parent);
+}
+
+static inline void unlock_dir(struct dentry *dir)
+{
+ up(&dir->d_inode->i_sem);
+ dput(dir);
+}
+
+/*
+ * Whee.. Deadlock country. Happily there are only two VFS
+ * operations that does this..
+ */
+static inline void double_lock(struct dentry *d1, struct dentry *d2)
+{
+ struct semaphore *s1 = &d1->d_inode->i_sem;
+ struct semaphore *s2 = &d2->d_inode->i_sem;
+
+ if (s1 != s2) {
+ if ((unsigned long) s1 < (unsigned long) s2) {
+ struct semaphore *tmp = s2;
+ s2 = s1; s1 = tmp;
+ }
+ down(s1);
+ }
+ down(s2);
+}
+
+static inline void double_unlock(struct dentry *d1, struct dentry *d2)
+{
+ struct semaphore *s1 = &d1->d_inode->i_sem;
+ struct semaphore *s2 = &d2->d_inode->i_sem;
+
+ up(s1);
+ if (s1 != s2)
+ up(s2);
+ dput(d1);
+ dput(d2);
+}
+
+
+
#endif /* __KERNEL__ */
#endif /* _LINUX_FS_H */
extern int shrink_mmap(int, int);
extern void truncate_inode_pages(struct inode *, loff_t);
+/* generic vm_area_ops exported for stackable file systems */
+extern int filemap_swapout(struct page * page, struct file *file);
+extern pte_t filemap_swapin(struct vm_area_struct * vma,
+ unsigned long offset, unsigned long entry);
+extern int filemap_sync(struct vm_area_struct * vma, unsigned long address,
+ size_t size, unsigned int flags);
+extern struct page *filemap_nopage(struct vm_area_struct * area,
+ unsigned long address, int no_share);
+
/*
* GFP bitmasks..
*/
#define VIDEO_TYPE_PMAC 0x60 /* PowerMacintosh frame buffer. */
+#define VIDEO_TYPE_SGI 0x70 /* Various SGI graphics hardware */
+#define VIDEO_TYPE_MIPS_G364 0x71 /* MIPS Magnum 4000 G364 video */
+
/*
* This character is the same as _POSIX_VDISABLE: it cannot be used as
* a c_cc[] character, but indicates that a particular special character
u_int irq_mask;
u_int map_size;
u_char pci_irq;
- u_char cardbus;
- struct pci_bus *cb_bus;
+ struct pci_dev *cb_dev;
struct bus_operations *bus;
} socket_cap_t;
EXPORT_SYMBOL(page_follow_link);
EXPORT_SYMBOL(block_symlink);
+/* for stackable file systems (lofs, wrapfs, etc.) */
+EXPORT_SYMBOL(add_to_page_cache);
+EXPORT_SYMBOL(filemap_nopage);
+EXPORT_SYMBOL(filemap_swapout);
+EXPORT_SYMBOL(filemap_sync);
+EXPORT_SYMBOL(remove_inode_page);
+
#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
EXPORT_SYMBOL(do_nfsservctl);
#endif
/* library functions */
EXPORT_SYMBOL(strnicmp);
+/* init task, for moving kthread roots - ought to export a function ?? */
EXPORT_SYMBOL(init_task_union);
* it in the page cache, and handles the special cases reasonably without
* having a lot of duplicated code.
*/
-static struct page * filemap_nopage(struct vm_area_struct * area,
+struct page * filemap_nopage(struct vm_area_struct * area,
unsigned long address, int no_share)
{
int error;
return error;
}
-static int filemap_sync(struct vm_area_struct * vma, unsigned long address,
+int filemap_sync(struct vm_area_struct * vma, unsigned long address,
size_t size, unsigned int flags)
{
pgd_t * dir;
#include <linux/rtnetlink.h>
#include <net/br.h>
#include <linux/proc_fs.h>
-#include <linux/br.h>
+#include <linux/delay.h>
#ifndef min
#define min(a, b) (((a) <= (b)) ? (a) : (b))