File: /usr/src/linux/drivers/net/arcnet/com90io.c

1     /*
2      * Linux ARCnet driver - COM90xx chipset (IO-mapped buffers)
3      * 
4      * Written 1997 by David Woodhouse.
5      * Written 1994-1999 by Avery Pennarun.
6      * Written 1999-2000 by Martin Mares <mj@suse.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/kernel.h>
29     #include <linux/module.h>
30     #include <linux/ioport.h>
31     #include <linux/slab.h>
32     #include <linux/delay.h>
33     #include <linux/netdevice.h>
34     #include <linux/bootmem.h>
35     #include <linux/init.h>
36     #include <asm/io.h>
37     #include <linux/arcdevice.h>
38     
39     
40     #define VERSION "arcnet: COM90xx IO-mapped mode support (by David Woodhouse et el.)\n"
41     
42     
43     /* Internal function declarations */
44     
45     static int com90io_found(struct net_device *dev);
46     static void com90io_command(struct net_device *dev, int command);
47     static int com90io_status(struct net_device *dev);
48     static void com90io_setmask(struct net_device *dev, int mask);
49     static int com90io_reset(struct net_device *dev, int really_reset);
50     static void com90io_openclose(struct net_device *dev, bool open);
51     static void com90io_copy_to_card(struct net_device *dev, int bufnum, int offset,
52     				 void *buf, int count);
53     static void com90io_copy_from_card(struct net_device *dev, int bufnum, int offset,
54     				   void *buf, int count);
55     
56     
57     /* Handy defines for ARCnet specific stuff */
58     
59     /* The number of low I/O ports used by the card. */
60     #define ARCNET_TOTAL_SIZE 16
61     
62     /* COM 9026 controller chip --> ARCnet register addresses */
63     #define _INTMASK (ioaddr+0)	/* writable */
64     #define _STATUS  (ioaddr+0)	/* readable */
65     #define _COMMAND (ioaddr+1)	/* writable, returns random vals on read (?) */
66     #define _RESET  (ioaddr+8)	/* software reset (on read) */
67     #define _MEMDATA  (ioaddr+12)	/* Data port for IO-mapped memory */
68     #define _ADDR_HI  (ioaddr+15)	/* Control registers for said */
69     #define _ADDR_LO  (ioaddr+14)
70     #define _CONFIG  (ioaddr+2)	/* Configuration register */
71     
72     #undef ASTATUS
73     #undef ACOMMAND
74     #undef AINTMASK
75     
76     #define ASTATUS()	inb(_STATUS)
77     #define ACOMMAND(cmd) outb((cmd),_COMMAND)
78     #define AINTMASK(msk)	outb((msk),_INTMASK)
79     #define SETCONF() 	outb((lp->config),_CONFIG)
80     
81     
82     /****************************************************************************
83      *                                                                          *
84      * IO-mapped operation routines                                             *
85      *                                                                          *
86      ****************************************************************************/
87     
88     #undef ONE_AT_A_TIME_TX
89     #undef ONE_AT_A_TIME_RX
90     
91     static u_char get_buffer_byte(struct net_device *dev, unsigned offset)
92     {
93     	int ioaddr = dev->base_addr;
94     
95     	outb(offset >> 8, _ADDR_HI);
96     	outb(offset & 0xff, _ADDR_LO);
97     
98     	return inb(_MEMDATA);
99     }
100     
101     #ifdef ONE_AT_A_TIME_TX
102     static void put_buffer_byte(struct net_device *dev, unsigned offset, u_char datum)
103     {
104     	int ioaddr = dev->base_addr;
105     
106     	outb(offset >> 8, _ADDR_HI);
107     	outb(offset & 0xff, _ADDR_LO);
108     
109     	outb(datum, _MEMDATA);
110     }
111     
112     #endif
113     
114     
115     static void get_whole_buffer(struct net_device *dev, unsigned offset, unsigned length, char *dest)
116     {
117     	int ioaddr = dev->base_addr;
118     
119     	outb((offset >> 8) | AUTOINCflag, _ADDR_HI);
120     	outb(offset & 0xff, _ADDR_LO);
121     
122     	while (length--)
123     #ifdef ONE_AT_A_TIME_RX
124     		*(dest++) = get_buffer_byte(dev, offset++);
125     #else
126     		*(dest++) = inb(_MEMDATA);
127     #endif
128     }
129     
130     static void put_whole_buffer(struct net_device *dev, unsigned offset, unsigned length, char *dest)
131     {
132     	int ioaddr = dev->base_addr;
133     
134     	outb((offset >> 8) | AUTOINCflag, _ADDR_HI);
135     	outb(offset & 0xff, _ADDR_LO);
136     
137     	while (length--)
138     #ifdef ONE_AT_A_TIME_TX
139     		put_buffer_byte(dev, offset++, *(dest++));
140     #else
141     		outb(*(dest++), _MEMDATA);
142     #endif
143     }
144     
145     /*
146      * We cannot probe for an IO mapped card either, although we can check that
147      * it's where we were told it was, and even autoirq
148      */
149     static int __init com90io_probe(struct net_device *dev)
150     {
151     	int ioaddr = dev->base_addr, status;
152     	unsigned long airqmask;
153     
154     #ifndef MODULE
155     	arcnet_init();
156     #endif
157     
158     	BUGLVL(D_NORMAL) printk(VERSION);
159     	BUGLVL(D_NORMAL) printk("E-mail me if you actually test this driver, please!\n");
160     
161     	if (!ioaddr) {
162     		BUGMSG(D_NORMAL, "No autoprobe for IO mapped cards; you "
163     		       "must specify the base address!\n");
164     		return -ENODEV;
165     	}
166     	if (check_region(ioaddr, ARCNET_TOTAL_SIZE)) {
167     		BUGMSG(D_INIT_REASONS, "IO check_region %x-%x failed.\n",
168     		       ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
169     		return -ENXIO;
170     	}
171     	if (ASTATUS() == 0xFF) {
172     		BUGMSG(D_INIT_REASONS, "IO address %x empty\n", ioaddr);
173     		return -ENODEV;
174     	}
175     	inb(_RESET);
176     	mdelay(RESETtime);
177     
178     	status = ASTATUS();
179     
180     	if ((status & 0x9D) != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
181     		BUGMSG(D_INIT_REASONS, "Status invalid (%Xh).\n", status);
182     		return -ENODEV;
183     	}
184     	BUGMSG(D_INIT_REASONS, "Status after reset: %X\n", status);
185     
186     	ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
187     
188     	BUGMSG(D_INIT_REASONS, "Status after reset acknowledged: %X\n", status);
189     
190     	status = ASTATUS();
191     
192     	if (status & RESETflag) {
193     		BUGMSG(D_INIT_REASONS, "Eternal reset (status=%Xh)\n", status);
194     		return -ENODEV;
195     	}
196     	outb((0x16 | IOMAPflag) & ~ENABLE16flag, _CONFIG);
197     
198     	/* Read first loc'n of memory */
199     
200     	outb(AUTOINCflag, _ADDR_HI);
201     	outb(0, _ADDR_LO);
202     
203     	if ((status = inb(_MEMDATA)) != 0xd1) {
204     		BUGMSG(D_INIT_REASONS, "Signature byte not found"
205     		       " (%Xh instead).\n", status);
206     		return -ENODEV;
207     	}
208     	if (!dev->irq) {
209     		/*
210     		 * if we do this, we're sure to get an IRQ since the
211     		 * card has just reset and the NORXflag is on until
212     		 * we tell it to start receiving.
213     		 */
214     
215     		airqmask = probe_irq_on();
216     		outb(NORXflag, _INTMASK);
217     		udelay(1);
218     		outb(0, _INTMASK);
219     		dev->irq = probe_irq_off(airqmask);
220     
221     		if (dev->irq <= 0) {
222     			BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed\n");
223     			return -ENODEV;
224     		}
225     	}
226     	return com90io_found(dev);
227     }
228     
229     
230     /* Set up the struct net_device associated with this card.  Called after
231      * probing succeeds.
232      */
233     static int __init com90io_found(struct net_device *dev)
234     {
235     	struct arcnet_local *lp;
236     	int ioaddr = dev->base_addr;
237     
238     	/* Reserve the irq */
239     	if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (COM90xx-IO)", dev)) {
240     		BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
241     		return -ENODEV;
242     	}
243     	/* Reserve the I/O region - guaranteed to work by check_region */
244     	request_region(dev->base_addr, ARCNET_TOTAL_SIZE, "arcnet (COM90xx-IO)");
245     
246     	/* Initialize the rest of the device structure. */
247     	dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
248     	if (!dev->priv) {
249     		free_irq(dev->irq, dev);
250     		release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
251     		return -ENOMEM;
252     	}
253     	memset(dev->priv, 0, sizeof(struct arcnet_local));
254     
255     	lp = (struct arcnet_local *) (dev->priv);
256     	lp->card_name = "COM90xx I/O";
257     	lp->hw.command = com90io_command;
258     	lp->hw.status = com90io_status;
259     	lp->hw.intmask = com90io_setmask;
260     	lp->hw.reset = com90io_reset;
261     	lp->hw.open_close = com90io_openclose;
262     	lp->hw.copy_to_card = com90io_copy_to_card;
263     	lp->hw.copy_from_card = com90io_copy_from_card;
264     
265     	/*
266     	 * Fill in the fields of the device structure with generic
267     	 * values.
268     	 */
269     	arcdev_setup(dev);
270     
271     	lp->config = (0x16 | IOMAPflag) & ~ENABLE16flag;
272     	SETCONF();
273     
274     	/* get and check the station ID from offset 1 in shmem */
275     
276     	dev->dev_addr[0] = get_buffer_byte(dev, 1);
277     
278     	BUGMSG(D_NORMAL, "COM90IO: station %02Xh found at %03lXh, IRQ %d.\n",
279     	       dev->dev_addr[0], dev->base_addr, dev->irq);
280     
281     	return 0;
282     }
283     
284     
285     /*
286      * Do a hardware reset on the card, and set up necessary registers.
287      *
288      * This should be called as little as possible, because it disrupts the
289      * token on the network (causes a RECON) and requires a significant delay.
290      *
291      * However, it does make sure the card is in a defined state.
292      */
293     static int com90io_reset(struct net_device *dev, int really_reset)
294     {
295     	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
296     	short ioaddr = dev->base_addr;
297     
298     	BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS());
299     
300     	if (really_reset) {
301     		/* reset the card */
302     		inb(_RESET);
303     		mdelay(RESETtime);
304     	}
305     	/* Set the thing to IO-mapped, 8-bit  mode */
306     	lp->config = (0x1C | IOMAPflag) & ~ENABLE16flag;
307     	SETCONF();
308     
309     	ACOMMAND(CFLAGScmd | RESETclear);	/* clear flags & end reset */
310     	ACOMMAND(CFLAGScmd | CONFIGclear);
311     
312     	/* verify that the ARCnet signature byte is present */
313     	if (get_buffer_byte(dev, 0) != TESTvalue) {
314     		BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
315     		return 1;
316     	}
317     	/* enable extended (512-byte) packets */
318     	ACOMMAND(CONFIGcmd | EXTconf);
319     
320     	/* done!  return success. */
321     	return 0;
322     }
323     
324     
325     static void com90io_command(struct net_device *dev, int cmd)
326     {
327     	short ioaddr = dev->base_addr;
328     
329     	ACOMMAND(cmd);
330     }
331     
332     
333     static int com90io_status(struct net_device *dev)
334     {
335     	short ioaddr = dev->base_addr;
336     
337     	return ASTATUS();
338     }
339     
340     
341     static void com90io_setmask(struct net_device *dev, int mask)
342     {
343     	short ioaddr = dev->base_addr;
344     
345     	AINTMASK(mask);
346     }
347     
348     static void com90io_openclose(struct net_device *dev, int open)
349     {
350     	if (open)
351     		MOD_INC_USE_COUNT;
352     	else
353     		MOD_DEC_USE_COUNT;
354     }
355     
356     static void com90io_copy_to_card(struct net_device *dev, int bufnum, int offset,
357     				 void *buf, int count)
358     {
359     	TIME("put_whole_buffer", count, put_whole_buffer(dev, bufnum * 512 + offset, count, buf));
360     }
361     
362     
363     static void com90io_copy_from_card(struct net_device *dev, int bufnum, int offset,
364     				   void *buf, int count)
365     {
366     	TIME("get_whole_buffer", count, get_whole_buffer(dev, bufnum * 512 + offset, count, buf));
367     }
368     
369     
370     #ifdef MODULE
371     
372     static struct net_device *my_dev;
373     
374     /* Module parameters */
375     
376     static int io;			/* use the insmod io= irq= shmem= options */
377     static int irq;
378     static char *device;		/* use eg. device=arc1 to change name */
379     
380     MODULE_PARM(io, "i");
381     MODULE_PARM(irq, "i");
382     MODULE_PARM(device, "s");
383     
384     int init_module(void)
385     {
386     	struct net_device *dev;
387     	int err;
388     
389     	dev = dev_alloc(device ? : "arc%d", &err);
390     	if (!dev)
391     		return err;
392     
393     	dev->base_addr = io;
394     	dev->irq = irq;
395     	if (dev->irq == 2)
396     		dev->irq = 9;
397     
398     	if (com90io_probe(dev))
399     		return -EIO;
400     
401     	my_dev = dev;
402     	return 0;
403     }
404     
405     void cleanup_module(void)
406     {
407     	struct net_device *dev = my_dev;
408     	int ioaddr = dev->base_addr;
409     
410     	unregister_netdev(dev);
411     
412     	/* Set the thing back to MMAP mode, in case the old driver is loaded later */
413     	outb((inb(_CONFIG) & ~IOMAPflag), _CONFIG);
414     
415     	free_irq(dev->irq, dev);
416     	release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
417     	kfree(dev->priv);
418     	kfree(dev);
419     }
420     
421     #else
422     
423     static int __init com90io_setup(char *s)
424     {
425     	struct net_device *dev;
426     	int ints[4];
427     
428     	s = get_options(s, 4, ints);
429     	if (!ints[0])
430     		return 0;
431     	dev = alloc_bootmem(sizeof(struct net_device));
432     	memset(dev, 0, sizeof(struct net_device));
433     	dev->init = com90io_probe;
434     
435     	switch (ints[0]) {
436     	default:		/* ERROR */
437     		printk("com90io: Too many arguments.\n");
438     	case 2:		/* IRQ */
439     		dev->irq = ints[2];
440     	case 1:		/* IO address */
441     		dev->base_addr = ints[1];
442     	}
443     	if (*s)
444     		strncpy(dev->name, s, 9);
445     	else
446     		strcpy(dev->name, "arc%d");
447     	if (register_netdev(dev))
448     		printk(KERN_ERR "com90io: Cannot register arcnet device\n");
449     
450     	return 1;
451     }
452     
453     __setup("com90io=", com90io_setup);
454     
455     #endif				/* MODULE */
456