1 /* 2 * Linux ARCnet driver - COM20020 chipset support 3 * 4 * Written 1997 by David Woodhouse. 5 * Written 1994-1999 by Avery Pennarun. 6 * Written 1999-2000 by Martin Mares <mj@ucw.cz>. 7 * Derived from skeleton.c by Donald Becker. 8 * 9 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com) 10 * for sponsoring the further development of this driver. 11 * 12 * ********************** 13 * 14 * The original copyright of skeleton.c was as follows: 15 * 16 * skeleton.c Written 1993 by Donald Becker. 17 * Copyright 1993 United States Government as represented by the 18 * Director, National Security Agency. This software may only be used 19 * and distributed according to the terms of the GNU General Public License as 20 * modified by SRC, incorporated herein by reference. 21 * 22 * ********************** 23 * 24 * For more details, see drivers/net/arcnet.c 25 * 26 * ********************** 27 */ 28 #include <linux/module.h> 29 #include <linux/moduleparam.h> 30 #include <linux/kernel.h> 31 #include <linux/types.h> 32 #include <linux/ioport.h> 33 #include <linux/errno.h> 34 #include <linux/delay.h> 35 #include <linux/netdevice.h> 36 #include <linux/init.h> 37 #include <linux/interrupt.h> 38 #include <linux/bootmem.h> 39 #include <linux/arcdevice.h> 40 #include <linux/com20020.h> 41 42 #include <asm/io.h> 43 44 #define VERSION "arcnet: COM20020 ISA support (by David Woodhouse et al.)\n" 45 46 47 /* 48 * We cannot (yet) probe for an IO mapped card, although we can check that 49 * it's where we were told it was, and even do autoirq. 50 */ 51 static int __init com20020isa_probe(struct net_device *dev) 52 { 53 int ioaddr; 54 unsigned long airqmask; 55 struct arcnet_local *lp = netdev_priv(dev); 56 int err; 57 58 BUGLVL(D_NORMAL) printk(VERSION); 59 60 ioaddr = dev->base_addr; 61 if (!ioaddr) { 62 BUGMSG(D_NORMAL, "No autoprobe (yet) for IO mapped cards; you " 63 "must specify the base address!\n"); 64 return -ENODEV; 65 } 66 if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)")) { 67 BUGMSG(D_NORMAL, "IO region %xh-%xh already allocated.\n", 68 ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1); 69 return -ENXIO; 70 } 71 if (ASTATUS() == 0xFF) { 72 BUGMSG(D_NORMAL, "IO address %x empty\n", ioaddr); 73 err = -ENODEV; 74 goto out; 75 } 76 if (com20020_check(dev)) { 77 err = -ENODEV; 78 goto out; 79 } 80 81 if (!dev->irq) { 82 /* if we do this, we're sure to get an IRQ since the 83 * card has just reset and the NORXflag is on until 84 * we tell it to start receiving. 85 */ 86 BUGMSG(D_INIT_REASONS, "intmask was %02Xh\n", inb(_INTMASK)); 87 outb(0, _INTMASK); 88 airqmask = probe_irq_on(); 89 outb(NORXflag, _INTMASK); 90 udelay(1); 91 outb(0, _INTMASK); 92 dev->irq = probe_irq_off(airqmask); 93 94 if ((int)dev->irq <= 0) { 95 BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed first time\n"); 96 airqmask = probe_irq_on(); 97 outb(NORXflag, _INTMASK); 98 udelay(5); 99 outb(0, _INTMASK); 100 dev->irq = probe_irq_off(airqmask); 101 if ((int)dev->irq <= 0) { 102 BUGMSG(D_NORMAL, "Autoprobe IRQ failed.\n"); 103 err = -ENODEV; 104 goto out; 105 } 106 } 107 } 108 109 lp->card_name = "ISA COM20020"; 110 if ((err = com20020_found(dev, 0)) != 0) 111 goto out; 112 113 return 0; 114 115 out: 116 release_region(ioaddr, ARCNET_TOTAL_SIZE); 117 return err; 118 } 119 120 static int node = 0; 121 static int io = 0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */ 122 static int irq = 0; /* or use the insmod io= irq= shmem= options */ 123 static char device[9]; /* use eg. device="arc1" to change name */ 124 static int timeout = 3; 125 static int backplane = 0; 126 static int clockp = 0; 127 static int clockm = 0; 128 129 module_param(node, int, 0); 130 module_param(io, int, 0); 131 module_param(irq, int, 0); 132 module_param_string(device, device, sizeof(device), 0); 133 module_param(timeout, int, 0); 134 module_param(backplane, int, 0); 135 module_param(clockp, int, 0); 136 module_param(clockm, int, 0); 137 138 MODULE_LICENSE("GPL"); 139 140 static struct net_device *my_dev; 141 142 static int __init com20020_init(void) 143 { 144 struct net_device *dev; 145 struct arcnet_local *lp; 146 147 dev = alloc_arcdev(device); 148 if (!dev) 149 return -ENOMEM; 150 151 if (node && node != 0xff) 152 dev->dev_addr[0] = node; 153 154 dev->netdev_ops = &com20020_netdev_ops; 155 156 lp = netdev_priv(dev); 157 lp->backplane = backplane; 158 lp->clockp = clockp & 7; 159 lp->clockm = clockm & 3; 160 lp->timeout = timeout & 3; 161 lp->hw.owner = THIS_MODULE; 162 163 dev->base_addr = io; 164 dev->irq = irq; 165 166 if (dev->irq == 2) 167 dev->irq = 9; 168 169 if (com20020isa_probe(dev)) { 170 free_netdev(dev); 171 return -EIO; 172 } 173 174 my_dev = dev; 175 return 0; 176 } 177 178 static void __exit com20020_exit(void) 179 { 180 unregister_netdev(my_dev); 181 free_irq(my_dev->irq, my_dev); 182 release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE); 183 free_netdev(my_dev); 184 } 185 186 #ifndef MODULE 187 static int __init com20020isa_setup(char *s) 188 { 189 int ints[8]; 190 191 s = get_options(s, 8, ints); 192 if (!ints[0]) 193 return 1; 194 195 switch (ints[0]) { 196 default: /* ERROR */ 197 printk("com90xx: Too many arguments.\n"); 198 case 6: /* Timeout */ 199 timeout = ints[6]; 200 case 5: /* CKP value */ 201 clockp = ints[5]; 202 case 4: /* Backplane flag */ 203 backplane = ints[4]; 204 case 3: /* Node ID */ 205 node = ints[3]; 206 case 2: /* IRQ */ 207 irq = ints[2]; 208 case 1: /* IO address */ 209 io = ints[1]; 210 } 211 if (*s) 212 snprintf(device, sizeof(device), "%s", s); 213 return 1; 214 } 215 216 __setup("com20020=", com20020isa_setup); 217 218 #endif /* MODULE */ 219 220 module_init(com20020_init) 221 module_exit(com20020_exit) 222