xref: /openbmc/linux/drivers/net/arcnet/com90xx.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1 /*
2  * Linux ARCnet driver - COM90xx chipset (memory-mapped buffers)
3  *
4  * Written 1994-1999 by Avery Pennarun.
5  * Written 1999 by Martin Mares <mj@ucw.cz>.
6  * Derived from skeleton.c by Donald Becker.
7  *
8  * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
9  *  for sponsoring the further development of this driver.
10  *
11  * **********************
12  *
13  * The original copyright of skeleton.c was as follows:
14  *
15  * skeleton.c Written 1993 by Donald Becker.
16  * Copyright 1993 United States Government as represented by the
17  * Director, National Security Agency.  This software may only be used
18  * and distributed according to the terms of the GNU General Public License as
19  * modified by SRC, incorporated herein by reference.
20  *
21  * **********************
22  *
23  * For more details, see drivers/net/arcnet.c
24  *
25  * **********************
26  */
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
29 #include <linux/init.h>
30 #include <linux/ioport.h>
31 #include <linux/delay.h>
32 #include <linux/netdevice.h>
33 #include <asm/io.h>
34 #include <linux/arcdevice.h>
35 
36 
37 #define VERSION "arcnet: COM90xx chipset support\n"
38 
39 
40 /* Define this to speed up the autoprobe by assuming if only one io port and
41  * shmem are left in the list at Stage 5, they must correspond to each
42  * other.
43  *
44  * This is undefined by default because it might not always be true, and the
45  * extra check makes the autoprobe even more careful.  Speed demons can turn
46  * it on - I think it should be fine if you only have one ARCnet card
47  * installed.
48  *
49  * If no ARCnet cards are installed, this delay never happens anyway and thus
50  * the option has no effect.
51  */
52 #undef FAST_PROBE
53 
54 
55 /* Internal function declarations */
56 static int com90xx_found(int ioaddr, int airq, u_long shmem);
57 static void com90xx_command(struct net_device *dev, int command);
58 static int com90xx_status(struct net_device *dev);
59 static void com90xx_setmask(struct net_device *dev, int mask);
60 static int com90xx_reset(struct net_device *dev, int really_reset);
61 static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
62 				 void *buf, int count);
63 static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
64 				   void *buf, int count);
65 
66 /* Known ARCnet cards */
67 
68 static struct net_device *cards[16];
69 static int numcards;
70 
71 /* Handy defines for ARCnet specific stuff */
72 
73 /* The number of low I/O ports used by the card */
74 #define ARCNET_TOTAL_SIZE	16
75 
76 /* Amount of I/O memory used by the card */
77 #define BUFFER_SIZE (512)
78 #define MIRROR_SIZE (BUFFER_SIZE*4)
79 
80 /* COM 9026 controller chip --> ARCnet register addresses */
81 #define _INTMASK (ioaddr+0)	/* writable */
82 #define _STATUS  (ioaddr+0)	/* readable */
83 #define _COMMAND (ioaddr+1)	/* writable, returns random vals on read (?) */
84 #define _CONFIG  (ioaddr+2)	/* Configuration register */
85 #define _RESET   (ioaddr+8)	/* software reset (on read) */
86 #define _MEMDATA (ioaddr+12)	/* Data port for IO-mapped memory */
87 #define _ADDR_HI (ioaddr+15)	/* Control registers for said */
88 #define _ADDR_LO (ioaddr+14)
89 
90 #undef ASTATUS
91 #undef ACOMMAND
92 #undef AINTMASK
93 
94 #define ASTATUS()	inb(_STATUS)
95 #define ACOMMAND(cmd) 	outb((cmd),_COMMAND)
96 #define AINTMASK(msk)	outb((msk),_INTMASK)
97 
98 
99 static int com90xx_skip_probe __initdata = 0;
100 
101 /* Module parameters */
102 
103 static int io;			/* use the insmod io= irq= shmem= options */
104 static int irq;
105 static int shmem;
106 static char device[9];		/* use eg. device=arc1 to change name */
107 
108 module_param(io, int, 0);
109 module_param(irq, int, 0);
110 module_param(shmem, int, 0);
111 module_param_string(device, device, sizeof(device), 0);
112 
113 static void __init com90xx_probe(void)
114 {
115 	int count, status, ioaddr, numprint, airq, openparen = 0;
116 	unsigned long airqmask;
117 	int ports[(0x3f0 - 0x200) / 16 + 1] =
118 	{0};
119 	u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] =
120 	{0};
121 	int numports, numshmems, *port;
122 	u_long *p;
123 
124 	if (!io && !irq && !shmem && !*device && com90xx_skip_probe)
125 		return;
126 
127 	BUGLVL(D_NORMAL) printk(VERSION);
128 
129 	/* set up the arrays where we'll store the possible probe addresses */
130 	numports = numshmems = 0;
131 	if (io)
132 		ports[numports++] = io;
133 	else
134 		for (count = 0x200; count <= 0x3f0; count += 16)
135 			ports[numports++] = count;
136 	if (shmem)
137 		shmems[numshmems++] = shmem;
138 	else
139 		for (count = 0xA0000; count <= 0xFF800; count += 2048)
140 			shmems[numshmems++] = count;
141 
142 	/* Stage 1: abandon any reserved ports, or ones with status==0xFF
143 	 * (empty), and reset any others by reading the reset port.
144 	 */
145 	numprint = -1;
146 	for (port = &ports[0]; port - ports < numports; port++) {
147 		numprint++;
148 		numprint %= 8;
149 		if (!numprint) {
150 			BUGMSG2(D_INIT, "\n");
151 			BUGMSG2(D_INIT, "S1: ");
152 		}
153 		BUGMSG2(D_INIT, "%Xh ", *port);
154 
155 		ioaddr = *port;
156 
157 		if (!request_region(*port, ARCNET_TOTAL_SIZE, "arcnet (90xx)")) {
158 			BUGMSG2(D_INIT_REASONS, "(request_region)\n");
159 			BUGMSG2(D_INIT_REASONS, "S1: ");
160 			BUGLVL(D_INIT_REASONS) numprint = 0;
161 			*port-- = ports[--numports];
162 			continue;
163 		}
164 		if (ASTATUS() == 0xFF) {
165 			BUGMSG2(D_INIT_REASONS, "(empty)\n");
166 			BUGMSG2(D_INIT_REASONS, "S1: ");
167 			BUGLVL(D_INIT_REASONS) numprint = 0;
168 			release_region(*port, ARCNET_TOTAL_SIZE);
169 			*port-- = ports[--numports];
170 			continue;
171 		}
172 		inb(_RESET);	/* begin resetting card */
173 
174 		BUGMSG2(D_INIT_REASONS, "\n");
175 		BUGMSG2(D_INIT_REASONS, "S1: ");
176 		BUGLVL(D_INIT_REASONS) numprint = 0;
177 	}
178 	BUGMSG2(D_INIT, "\n");
179 
180 	if (!numports) {
181 		BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n");
182 		return;
183 	}
184 	/* Stage 2: we have now reset any possible ARCnet cards, so we can't
185 	 * do anything until they finish.  If D_INIT, print the list of
186 	 * cards that are left.
187 	 */
188 	numprint = -1;
189 	for (port = &ports[0]; port < ports + numports; port++) {
190 		numprint++;
191 		numprint %= 8;
192 		if (!numprint) {
193 			BUGMSG2(D_INIT, "\n");
194 			BUGMSG2(D_INIT, "S2: ");
195 		}
196 		BUGMSG2(D_INIT, "%Xh ", *port);
197 	}
198 	BUGMSG2(D_INIT, "\n");
199 	mdelay(RESETtime);
200 
201 	/* Stage 3: abandon any shmem addresses that don't have the signature
202 	 * 0xD1 byte in the right place, or are read-only.
203 	 */
204 	numprint = -1;
205 	for (p = &shmems[0]; p < shmems + numshmems; p++) {
206 		u_long ptr = *p;
207 
208 		numprint++;
209 		numprint %= 8;
210 		if (!numprint) {
211 			BUGMSG2(D_INIT, "\n");
212 			BUGMSG2(D_INIT, "S3: ");
213 		}
214 		BUGMSG2(D_INIT, "%lXh ", *p);
215 
216 		if (!request_mem_region(*p, BUFFER_SIZE, "arcnet (90xx)")) {
217 			BUGMSG2(D_INIT_REASONS, "(request_mem_region)\n");
218 			BUGMSG2(D_INIT_REASONS, "Stage 3: ");
219 			BUGLVL(D_INIT_REASONS) numprint = 0;
220 			*p-- = shmems[--numshmems];
221 			continue;
222 		}
223 		if (isa_readb(ptr) != TESTvalue) {
224 			BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n",
225 				isa_readb(ptr), TESTvalue);
226 			BUGMSG2(D_INIT_REASONS, "S3: ");
227 			BUGLVL(D_INIT_REASONS) numprint = 0;
228 			release_mem_region(*p, BUFFER_SIZE);
229 			*p-- = shmems[--numshmems];
230 			continue;
231 		}
232 		/* By writing 0x42 to the TESTvalue location, we also make
233 		 * sure no "mirror" shmem areas show up - if they occur
234 		 * in another pass through this loop, they will be discarded
235 		 * because *cptr != TESTvalue.
236 		 */
237 		isa_writeb(0x42, ptr);
238 		if (isa_readb(ptr) != 0x42) {
239 			BUGMSG2(D_INIT_REASONS, "(read only)\n");
240 			BUGMSG2(D_INIT_REASONS, "S3: ");
241 			release_mem_region(*p, BUFFER_SIZE);
242 			*p-- = shmems[--numshmems];
243 			continue;
244 		}
245 		BUGMSG2(D_INIT_REASONS, "\n");
246 		BUGMSG2(D_INIT_REASONS, "S3: ");
247 		BUGLVL(D_INIT_REASONS) numprint = 0;
248 	}
249 	BUGMSG2(D_INIT, "\n");
250 
251 	if (!numshmems) {
252 		BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n");
253 		for (port = &ports[0]; port < ports + numports; port++)
254 			release_region(*port, ARCNET_TOTAL_SIZE);
255 		return;
256 	}
257 	/* Stage 4: something of a dummy, to report the shmems that are
258 	 * still possible after stage 3.
259 	 */
260 	numprint = -1;
261 	for (p = &shmems[0]; p < shmems + numshmems; p++) {
262 		numprint++;
263 		numprint %= 8;
264 		if (!numprint) {
265 			BUGMSG2(D_INIT, "\n");
266 			BUGMSG2(D_INIT, "S4: ");
267 		}
268 		BUGMSG2(D_INIT, "%lXh ", *p);
269 	}
270 	BUGMSG2(D_INIT, "\n");
271 
272 	/* Stage 5: for any ports that have the correct status, can disable
273 	 * the RESET flag, and (if no irq is given) generate an autoirq,
274 	 * register an ARCnet device.
275 	 *
276 	 * Currently, we can only register one device per probe, so quit
277 	 * after the first one is found.
278 	 */
279 	numprint = -1;
280 	for (port = &ports[0]; port < ports + numports; port++) {
281 		int found = 0;
282 		numprint++;
283 		numprint %= 8;
284 		if (!numprint) {
285 			BUGMSG2(D_INIT, "\n");
286 			BUGMSG2(D_INIT, "S5: ");
287 		}
288 		BUGMSG2(D_INIT, "%Xh ", *port);
289 
290 		ioaddr = *port;
291 		status = ASTATUS();
292 
293 		if ((status & 0x9D)
294 		    != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
295 			BUGMSG2(D_INIT_REASONS, "(status=%Xh)\n", status);
296 			BUGMSG2(D_INIT_REASONS, "S5: ");
297 			BUGLVL(D_INIT_REASONS) numprint = 0;
298 			release_region(*port, ARCNET_TOTAL_SIZE);
299 			*port-- = ports[--numports];
300 			continue;
301 		}
302 		ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
303 		status = ASTATUS();
304 		if (status & RESETflag) {
305 			BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",
306 				status);
307 			BUGMSG2(D_INIT_REASONS, "S5: ");
308 			BUGLVL(D_INIT_REASONS) numprint = 0;
309 			release_region(*port, ARCNET_TOTAL_SIZE);
310 			*port-- = ports[--numports];
311 			continue;
312 		}
313 		/* skip this completely if an IRQ was given, because maybe
314 		 * we're on a machine that locks during autoirq!
315 		 */
316 		if (!irq) {
317 			/* if we do this, we're sure to get an IRQ since the
318 			 * card has just reset and the NORXflag is on until
319 			 * we tell it to start receiving.
320 			 */
321 			airqmask = probe_irq_on();
322 			AINTMASK(NORXflag);
323 			udelay(1);
324 			AINTMASK(0);
325 			airq = probe_irq_off(airqmask);
326 
327 			if (airq <= 0) {
328 				BUGMSG2(D_INIT_REASONS, "(airq=%d)\n", airq);
329 				BUGMSG2(D_INIT_REASONS, "S5: ");
330 				BUGLVL(D_INIT_REASONS) numprint = 0;
331 				release_region(*port, ARCNET_TOTAL_SIZE);
332 				*port-- = ports[--numports];
333 				continue;
334 			}
335 		} else {
336 			airq = irq;
337 		}
338 
339 		BUGMSG2(D_INIT, "(%d,", airq);
340 		openparen = 1;
341 
342 		/* Everything seems okay.  But which shmem, if any, puts
343 		 * back its signature byte when the card is reset?
344 		 *
345 		 * If there are multiple cards installed, there might be
346 		 * multiple shmems still in the list.
347 		 */
348 #ifdef FAST_PROBE
349 		if (numports > 1 || numshmems > 1) {
350 			inb(_RESET);
351 			mdelay(RESETtime);
352 		} else {
353 			/* just one shmem and port, assume they match */
354 			isa_writeb(TESTvalue, shmems[0]);
355 		}
356 #else
357 		inb(_RESET);
358 		mdelay(RESETtime);
359 #endif
360 
361 		for (p = &shmems[0]; p < shmems + numshmems; p++) {
362 			u_long ptr = *p;
363 
364 			if (isa_readb(ptr) == TESTvalue) {	/* found one */
365 				BUGMSG2(D_INIT, "%lXh)\n", *p);
366 				openparen = 0;
367 
368 				/* register the card */
369 				if (com90xx_found(*port, airq, *p) == 0)
370 					found = 1;
371 				numprint = -1;
372 
373 				/* remove shmem from the list */
374 				*p = shmems[--numshmems];
375 				break;	/* go to the next I/O port */
376 			} else {
377 				BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr));
378 			}
379 		}
380 
381 		if (openparen) {
382 			BUGLVL(D_INIT) printk("no matching shmem)\n");
383 			BUGLVL(D_INIT_REASONS) printk("S5: ");
384 			BUGLVL(D_INIT_REASONS) numprint = 0;
385 		}
386 		if (!found)
387 			release_region(*port, ARCNET_TOTAL_SIZE);
388 		*port-- = ports[--numports];
389 	}
390 
391 	BUGLVL(D_INIT_REASONS) printk("\n");
392 
393 	/* Now put back TESTvalue on all leftover shmems. */
394 	for (p = &shmems[0]; p < shmems + numshmems; p++) {
395 		isa_writeb(TESTvalue, *p);
396 		release_mem_region(*p, BUFFER_SIZE);
397 	}
398 }
399 
400 
401 /* Set up the struct net_device associated with this card.  Called after
402  * probing succeeds.
403  */
404 static int __init com90xx_found(int ioaddr, int airq, u_long shmem)
405 {
406 	struct net_device *dev = NULL;
407 	struct arcnet_local *lp;
408 	u_long first_mirror, last_mirror;
409 	int mirror_size;
410 
411 	/* allocate struct net_device */
412 	dev = alloc_arcdev(device);
413 	if (!dev) {
414 		BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n");
415 		release_mem_region(shmem, BUFFER_SIZE);
416 		return -ENOMEM;
417 	}
418 	lp = dev->priv;
419 	/* find the real shared memory start/end points, including mirrors */
420 
421 	/* guess the actual size of one "memory mirror" - the number of
422 	 * bytes between copies of the shared memory.  On most cards, it's
423 	 * 2k (or there are no mirrors at all) but on some, it's 4k.
424 	 */
425 	mirror_size = MIRROR_SIZE;
426 	if (isa_readb(shmem) == TESTvalue
427 	    && isa_readb(shmem - mirror_size) != TESTvalue
428 	    && isa_readb(shmem - 2 * mirror_size) == TESTvalue)
429 		mirror_size *= 2;
430 
431 	first_mirror = last_mirror = shmem;
432 	while (isa_readb(first_mirror) == TESTvalue)
433 		first_mirror -= mirror_size;
434 	first_mirror += mirror_size;
435 
436 	while (isa_readb(last_mirror) == TESTvalue)
437 		last_mirror += mirror_size;
438 	last_mirror -= mirror_size;
439 
440 	dev->mem_start = first_mirror;
441 	dev->mem_end = last_mirror + MIRROR_SIZE - 1;
442 
443 	release_mem_region(shmem, BUFFER_SIZE);
444 	if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)"))
445 		goto err_free_dev;
446 
447 	/* reserve the irq */
448 	if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
449 		BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
450 		goto err_release_mem;
451 	}
452 	dev->irq = airq;
453 
454 	/* Initialize the rest of the device structure. */
455 	lp->card_name = "COM90xx";
456 	lp->hw.command = com90xx_command;
457 	lp->hw.status = com90xx_status;
458 	lp->hw.intmask = com90xx_setmask;
459 	lp->hw.reset = com90xx_reset;
460 	lp->hw.owner = THIS_MODULE;
461 	lp->hw.copy_to_card = com90xx_copy_to_card;
462 	lp->hw.copy_from_card = com90xx_copy_from_card;
463 	lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
464 	if (!lp->mem_start) {
465 		BUGMSG(D_NORMAL, "Can't remap device memory!\n");
466 		goto err_free_irq;
467 	}
468 
469 	/* get and check the station ID from offset 1 in shmem */
470 	dev->dev_addr[0] = readb(lp->mem_start + 1);
471 
472 	dev->base_addr = ioaddr;
473 
474 	BUGMSG(D_NORMAL, "COM90xx station %02Xh found at %03lXh, IRQ %d, "
475 	       "ShMem %lXh (%ld*%xh).\n",
476 	       dev->dev_addr[0],
477 	       dev->base_addr, dev->irq, dev->mem_start,
478 	 (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
479 
480 	if (register_netdev(dev))
481 		goto err_unmap;
482 
483 	cards[numcards++] = dev;
484 	return 0;
485 
486 err_unmap:
487 	iounmap(lp->mem_start);
488 err_free_irq:
489 	free_irq(dev->irq, dev);
490 err_release_mem:
491 	release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
492 err_free_dev:
493 	free_netdev(dev);
494 	return -EIO;
495 }
496 
497 
498 static void com90xx_command(struct net_device *dev, int cmd)
499 {
500 	short ioaddr = dev->base_addr;
501 
502 	ACOMMAND(cmd);
503 }
504 
505 
506 static int com90xx_status(struct net_device *dev)
507 {
508 	short ioaddr = dev->base_addr;
509 
510 	return ASTATUS();
511 }
512 
513 
514 static void com90xx_setmask(struct net_device *dev, int mask)
515 {
516 	short ioaddr = dev->base_addr;
517 
518 	AINTMASK(mask);
519 }
520 
521 
522 /*
523  * Do a hardware reset on the card, and set up necessary registers.
524  *
525  * This should be called as little as possible, because it disrupts the
526  * token on the network (causes a RECON) and requires a significant delay.
527  *
528  * However, it does make sure the card is in a defined state.
529  */
530 int com90xx_reset(struct net_device *dev, int really_reset)
531 {
532 	struct arcnet_local *lp = dev->priv;
533 	short ioaddr = dev->base_addr;
534 
535 	BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS());
536 
537 	if (really_reset) {
538 		/* reset the card */
539 		inb(_RESET);
540 		mdelay(RESETtime);
541 	}
542 	ACOMMAND(CFLAGScmd | RESETclear);	/* clear flags & end reset */
543 	ACOMMAND(CFLAGScmd | CONFIGclear);
544 
545 	/* don't do this until we verify that it doesn't hurt older cards! */
546 	/* outb(inb(_CONFIG) | ENABLE16flag, _CONFIG); */
547 
548 	/* verify that the ARCnet signature byte is present */
549 	if (readb(lp->mem_start) != TESTvalue) {
550 		if (really_reset)
551 			BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
552 		return 1;
553 	}
554 	/* enable extended (512-byte) packets */
555 	ACOMMAND(CONFIGcmd | EXTconf);
556 
557 	/* clean out all the memory to make debugging make more sense :) */
558 	BUGLVL(D_DURING)
559 	    memset_io(lp->mem_start, 0x42, 2048);
560 
561 	/* done!  return success. */
562 	return 0;
563 }
564 
565 static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
566 				 void *buf, int count)
567 {
568 	struct arcnet_local *lp = dev->priv;
569 	void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
570 	TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
571 }
572 
573 
574 static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
575 				   void *buf, int count)
576 {
577 	struct arcnet_local *lp = dev->priv;
578 	void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
579 	TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
580 }
581 
582 
583 MODULE_LICENSE("GPL");
584 
585 static int __init com90xx_init(void)
586 {
587 	if (irq == 2)
588 		irq = 9;
589 	com90xx_probe();
590 	if (!numcards)
591 		return -EIO;
592 	return 0;
593 }
594 
595 static void __exit com90xx_exit(void)
596 {
597 	struct net_device *dev;
598 	struct arcnet_local *lp;
599 	int count;
600 
601 	for (count = 0; count < numcards; count++) {
602 		dev = cards[count];
603 		lp = dev->priv;
604 
605 		unregister_netdev(dev);
606 		free_irq(dev->irq, dev);
607 		iounmap(lp->mem_start);
608 		release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
609 		release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
610 		free_netdev(dev);
611 	}
612 }
613 
614 module_init(com90xx_init);
615 module_exit(com90xx_exit);
616 
617 #ifndef MODULE
618 static int __init com90xx_setup(char *s)
619 {
620 	int ints[8];
621 
622 	s = get_options(s, 8, ints);
623 	if (!ints[0] && !*s) {
624 		printk("com90xx: Disabled.\n");
625 		return 1;
626 	}
627 
628 	switch (ints[0]) {
629 	default:		/* ERROR */
630 		printk("com90xx: Too many arguments.\n");
631 	case 3:		/* Mem address */
632 		shmem = ints[3];
633 	case 2:		/* IRQ */
634 		irq = ints[2];
635 	case 1:		/* IO address */
636 		io = ints[1];
637 	}
638 
639 	if (*s)
640 		snprintf(device, sizeof(device), "%s", s);
641 
642 	return 1;
643 }
644 
645 __setup("com90xx=", com90xx_setup);
646 #endif
647