PageRenderTime 69ms CodeModel.GetById 15ms app.highlight 49ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/net/ethernet/8390/apne.c

http://github.com/mirrors/linux
C | 626 lines | 430 code | 114 blank | 82 comment | 75 complexity | 20a0e482900c290119f9f3b67ed84d24 MD5 | raw file
  1/*
  2 * Amiga Linux/68k 8390 based PCMCIA Ethernet Driver for the Amiga 1200
  3 *
  4 * (C) Copyright 1997 Alain Malek
  5 *                    (Alain.Malek@cryogen.com)
  6 *
  7 * ----------------------------------------------------------------------------
  8 *
  9 * This program is based on
 10 *
 11 * ne.c:       A general non-shared-memory NS8390 ethernet driver for linux
 12 *             Written 1992-94 by Donald Becker.
 13 *
 14 * 8390.c:     A general NS8390 ethernet driver core for linux.
 15 *             Written 1992-94 by Donald Becker.
 16 *
 17 * cnetdevice: A Sana-II ethernet driver for AmigaOS
 18 *             Written by Bruce Abbott (bhabbott@inhb.co.nz)
 19 *
 20 * ----------------------------------------------------------------------------
 21 *
 22 * This file is subject to the terms and conditions of the GNU General Public
 23 * License.  See the file COPYING in the main directory of the Linux
 24 * distribution for more details.
 25 *
 26 * ----------------------------------------------------------------------------
 27 *
 28 */
 29
 30
 31#include <linux/module.h>
 32#include <linux/kernel.h>
 33#include <linux/errno.h>
 34#include <linux/pci.h>
 35#include <linux/init.h>
 36#include <linux/delay.h>
 37#include <linux/netdevice.h>
 38#include <linux/etherdevice.h>
 39#include <linux/interrupt.h>
 40#include <linux/jiffies.h>
 41
 42#include <asm/io.h>
 43#include <asm/setup.h>
 44#include <asm/amigaints.h>
 45#include <asm/amigahw.h>
 46#include <asm/amigayle.h>
 47#include <asm/amipcmcia.h>
 48
 49#include "8390.h"
 50
 51/* ---- No user-serviceable parts below ---- */
 52
 53#define DRV_NAME "apne"
 54
 55#define NE_BASE	 (dev->base_addr)
 56#define NE_CMD	 		0x00
 57#define NE_DATAPORT		0x10            /* NatSemi-defined port window offset. */
 58#define NE_RESET		0x1f            /* Issue a read to reset, a write to clear. */
 59#define NE_IO_EXTENT	        0x20
 60
 61#define NE_EN0_ISR		0x07
 62#define NE_EN0_DCFG		0x0e
 63
 64#define NE_EN0_RSARLO	        0x08
 65#define NE_EN0_RSARHI	        0x09
 66#define NE_EN0_RCNTLO	        0x0a
 67#define NE_EN0_RXCR		0x0c
 68#define NE_EN0_TXCR		0x0d
 69#define NE_EN0_RCNTHI	        0x0b
 70#define NE_EN0_IMR		0x0f
 71
 72#define NE1SM_START_PG	0x20	/* First page of TX buffer */
 73#define NE1SM_STOP_PG 	0x40	/* Last page +1 of RX ring */
 74#define NESM_START_PG	0x40	/* First page of TX buffer */
 75#define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */
 76
 77
 78struct net_device * __init apne_probe(int unit);
 79static int apne_probe1(struct net_device *dev, int ioaddr);
 80
 81static void apne_reset_8390(struct net_device *dev);
 82static void apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
 83			  int ring_page);
 84static void apne_block_input(struct net_device *dev, int count,
 85								struct sk_buff *skb, int ring_offset);
 86static void apne_block_output(struct net_device *dev, const int count,
 87							const unsigned char *buf, const int start_page);
 88static irqreturn_t apne_interrupt(int irq, void *dev_id);
 89
 90static int init_pcmcia(void);
 91
 92/* IO base address used for nic */
 93
 94#define IOBASE 0x300
 95
 96/*
 97   use MANUAL_CONFIG and MANUAL_OFFSET for enabling IO by hand
 98   you can find the values to use by looking at the cnet.device
 99   config file example (the default values are for the CNET40BC card)
100*/
101
102/*
103#define MANUAL_CONFIG 0x20
104#define MANUAL_OFFSET 0x3f8
105
106#define MANUAL_HWADDR0 0x00
107#define MANUAL_HWADDR1 0x12
108#define MANUAL_HWADDR2 0x34
109#define MANUAL_HWADDR3 0x56
110#define MANUAL_HWADDR4 0x78
111#define MANUAL_HWADDR5 0x9a
112*/
113
114static const char version[] =
115    "apne.c:v1.1 7/10/98 Alain Malek (Alain.Malek@cryogen.ch)\n";
116
117static int apne_owned;	/* signal if card already owned */
118
119static u32 apne_msg_enable;
120module_param_named(msg_enable, apne_msg_enable, uint, 0444);
121MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
122
123struct net_device * __init apne_probe(int unit)
124{
125	struct net_device *dev;
126	struct ei_device *ei_local;
127
128#ifndef MANUAL_CONFIG
129	char tuple[8];
130#endif
131	int err;
132
133	if (!MACH_IS_AMIGA)
134		return ERR_PTR(-ENODEV);
135
136	if (apne_owned)
137		return ERR_PTR(-ENODEV);
138
139	if ( !(AMIGAHW_PRESENT(PCMCIA)) )
140		return ERR_PTR(-ENODEV);
141
142	pr_info("Looking for PCMCIA ethernet card : ");
143
144	/* check if a card is inserted */
145	if (!(PCMCIA_INSERTED)) {
146		pr_cont("NO PCMCIA card inserted\n");
147		return ERR_PTR(-ENODEV);
148	}
149
150	dev = alloc_ei_netdev();
151	if (!dev)
152		return ERR_PTR(-ENOMEM);
153	if (unit >= 0) {
154		sprintf(dev->name, "eth%d", unit);
155		netdev_boot_setup_check(dev);
156	}
157	ei_local = netdev_priv(dev);
158	ei_local->msg_enable = apne_msg_enable;
159
160	/* disable pcmcia irq for readtuple */
161	pcmcia_disable_irq();
162
163#ifndef MANUAL_CONFIG
164	if ((pcmcia_copy_tuple(CISTPL_FUNCID, tuple, 8) < 3) ||
165		(tuple[2] != CISTPL_FUNCID_NETWORK)) {
166		pr_cont("not an ethernet card\n");
167		/* XXX: shouldn't we re-enable irq here? */
168		free_netdev(dev);
169		return ERR_PTR(-ENODEV);
170	}
171#endif
172
173	pr_cont("ethernet PCMCIA card inserted\n");
174
175	if (!init_pcmcia()) {
176		/* XXX: shouldn't we re-enable irq here? */
177		free_netdev(dev);
178		return ERR_PTR(-ENODEV);
179	}
180
181	if (!request_region(IOBASE, 0x20, DRV_NAME)) {
182		free_netdev(dev);
183		return ERR_PTR(-EBUSY);
184	}
185
186	err = apne_probe1(dev, IOBASE);
187	if (err) {
188		release_region(IOBASE, 0x20);
189		free_netdev(dev);
190		return ERR_PTR(err);
191	}
192	err = register_netdev(dev);
193	if (!err)
194		return dev;
195
196	pcmcia_disable_irq();
197	free_irq(IRQ_AMIGA_PORTS, dev);
198	pcmcia_reset();
199	release_region(IOBASE, 0x20);
200	free_netdev(dev);
201	return ERR_PTR(err);
202}
203
204static int __init apne_probe1(struct net_device *dev, int ioaddr)
205{
206    int i;
207    unsigned char SA_prom[32];
208    int wordlength = 2;
209    const char *name = NULL;
210    int start_page, stop_page;
211#ifndef MANUAL_HWADDR0
212    int neX000, ctron;
213#endif
214    static unsigned version_printed;
215
216    if ((apne_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0))
217		netdev_info(dev, version);
218
219    netdev_info(dev, "PCMCIA NE*000 ethercard probe");
220
221    /* Reset card. Who knows what dain-bramaged state it was left in. */
222    {	unsigned long reset_start_time = jiffies;
223
224	outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
225
226	while ((inb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
227		if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
228			pr_cont(" not found (no reset ack).\n");
229			return -ENODEV;
230		}
231
232	outb(0xff, ioaddr + NE_EN0_ISR);		/* Ack all intr. */
233    }
234
235#ifndef MANUAL_HWADDR0
236
237    /* Read the 16 bytes of station address PROM.
238       We must first initialize registers, similar to NS8390_init(eifdev, 0).
239       We can't reliably read the SAPROM address without this.
240       (I learned the hard way!). */
241    {
242	struct {unsigned long value, offset; } program_seq[] = {
243	    {E8390_NODMA+E8390_PAGE0+E8390_STOP, NE_CMD}, /* Select page 0*/
244	    {0x48,	NE_EN0_DCFG},	/* Set byte-wide (0x48) access. */
245	    {0x00,	NE_EN0_RCNTLO},	/* Clear the count regs. */
246	    {0x00,	NE_EN0_RCNTHI},
247	    {0x00,	NE_EN0_IMR},	/* Mask completion irq. */
248	    {0xFF,	NE_EN0_ISR},
249	    {E8390_RXOFF, NE_EN0_RXCR},	/* 0x20  Set to monitor */
250	    {E8390_TXOFF, NE_EN0_TXCR},	/* 0x02  and loopback mode. */
251	    {32,	NE_EN0_RCNTLO},
252	    {0x00,	NE_EN0_RCNTHI},
253	    {0x00,	NE_EN0_RSARLO},	/* DMA starting at 0x0000. */
254	    {0x00,	NE_EN0_RSARHI},
255	    {E8390_RREAD+E8390_START, NE_CMD},
256	};
257	for (i = 0; i < ARRAY_SIZE(program_seq); i++) {
258	    outb(program_seq[i].value, ioaddr + program_seq[i].offset);
259	}
260
261    }
262    for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
263	SA_prom[i] = inb(ioaddr + NE_DATAPORT);
264	SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
265	if (SA_prom[i] != SA_prom[i+1])
266	    wordlength = 1;
267    }
268
269    /*	At this point, wordlength *only* tells us if the SA_prom is doubled
270	up or not because some broken PCI cards don't respect the byte-wide
271	request in program_seq above, and hence don't have doubled up values.
272	These broken cards would otherwise be detected as an ne1000.  */
273
274    if (wordlength == 2)
275	for (i = 0; i < 16; i++)
276		SA_prom[i] = SA_prom[i+i];
277
278    if (wordlength == 2) {
279	/* We must set the 8390 for word mode. */
280	outb(0x49, ioaddr + NE_EN0_DCFG);
281	start_page = NESM_START_PG;
282	stop_page = NESM_STOP_PG;
283    } else {
284	start_page = NE1SM_START_PG;
285	stop_page = NE1SM_STOP_PG;
286    }
287
288    neX000 = (SA_prom[14] == 0x57  &&  SA_prom[15] == 0x57);
289    ctron =  (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
290
291    /* Set up the rest of the parameters. */
292    if (neX000) {
293	name = (wordlength == 2) ? "NE2000" : "NE1000";
294    } else if (ctron) {
295	name = (wordlength == 2) ? "Ctron-8" : "Ctron-16";
296	start_page = 0x01;
297	stop_page = (wordlength == 2) ? 0x40 : 0x20;
298    } else {
299	pr_cont(" not found.\n");
300	return -ENXIO;
301
302    }
303
304#else
305    wordlength = 2;
306    /* We must set the 8390 for word mode. */
307    outb(0x49, ioaddr + NE_EN0_DCFG);
308    start_page = NESM_START_PG;
309    stop_page = NESM_STOP_PG;
310
311    SA_prom[0] = MANUAL_HWADDR0;
312    SA_prom[1] = MANUAL_HWADDR1;
313    SA_prom[2] = MANUAL_HWADDR2;
314    SA_prom[3] = MANUAL_HWADDR3;
315    SA_prom[4] = MANUAL_HWADDR4;
316    SA_prom[5] = MANUAL_HWADDR5;
317    name = "NE2000";
318#endif
319
320    dev->base_addr = ioaddr;
321    dev->irq = IRQ_AMIGA_PORTS;
322    dev->netdev_ops = &ei_netdev_ops;
323
324    /* Install the Interrupt handler */
325    i = request_irq(dev->irq, apne_interrupt, IRQF_SHARED, DRV_NAME, dev);
326    if (i) return i;
327
328    for (i = 0; i < ETH_ALEN; i++)
329	dev->dev_addr[i] = SA_prom[i];
330
331    pr_cont(" %pM\n", dev->dev_addr);
332
333    netdev_info(dev, "%s found.\n", name);
334
335    ei_status.name = name;
336    ei_status.tx_start_page = start_page;
337    ei_status.stop_page = stop_page;
338    ei_status.word16 = (wordlength == 2);
339
340    ei_status.rx_start_page = start_page + TX_PAGES;
341
342    ei_status.reset_8390 = &apne_reset_8390;
343    ei_status.block_input = &apne_block_input;
344    ei_status.block_output = &apne_block_output;
345    ei_status.get_8390_hdr = &apne_get_8390_hdr;
346
347    NS8390_init(dev, 0);
348
349    pcmcia_ack_int(pcmcia_get_intreq());		/* ack PCMCIA int req */
350    pcmcia_enable_irq();
351
352    apne_owned = 1;
353
354    return 0;
355}
356
357/* Hard reset the card.  This used to pause for the same period that a
358   8390 reset command required, but that shouldn't be necessary. */
359static void
360apne_reset_8390(struct net_device *dev)
361{
362    unsigned long reset_start_time = jiffies;
363    struct ei_device *ei_local = netdev_priv(dev);
364
365    init_pcmcia();
366
367    netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies);
368
369    outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
370
371    ei_status.txing = 0;
372    ei_status.dmaing = 0;
373
374    /* This check _should_not_ be necessary, omit eventually. */
375    while ((inb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0)
376	if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
377		netdev_err(dev, "ne_reset_8390() did not complete.\n");
378		break;
379	}
380    outb(ENISR_RESET, NE_BASE + NE_EN0_ISR);	/* Ack intr. */
381}
382
383/* Grab the 8390 specific header. Similar to the block_input routine, but
384   we don't need to be concerned with ring wrap as the header will be at
385   the start of a page, so we optimize accordingly. */
386
387static void
388apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
389{
390
391    int nic_base = dev->base_addr;
392    int cnt;
393    char *ptrc;
394    short *ptrs;
395
396    /* This *shouldn't* happen. If it does, it's the last thing you'll see */
397    if (ei_status.dmaing) {
398	netdev_err(dev, "DMAing conflict in ne_get_8390_hdr "
399		   "[DMAstat:%d][irqlock:%d][intr:%d].\n",
400		   ei_status.dmaing, ei_status.irqlock, dev->irq);
401	return;
402    }
403
404    ei_status.dmaing |= 0x01;
405    outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
406    outb(ENISR_RDC, nic_base + NE_EN0_ISR);
407    outb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO);
408    outb(0, nic_base + NE_EN0_RCNTHI);
409    outb(0, nic_base + NE_EN0_RSARLO);		/* On page boundary */
410    outb(ring_page, nic_base + NE_EN0_RSARHI);
411    outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
412
413    if (ei_status.word16) {
414        ptrs = (short*)hdr;
415        for(cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++)
416            *ptrs++ = inw(NE_BASE + NE_DATAPORT);
417    } else {
418        ptrc = (char*)hdr;
419        for(cnt = 0; cnt < sizeof(struct e8390_pkt_hdr); cnt++)
420            *ptrc++ = inb(NE_BASE + NE_DATAPORT);
421    }
422
423    outb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
424    ei_status.dmaing &= ~0x01;
425
426    le16_to_cpus(&hdr->count);
427}
428
429/* Block input and output, similar to the Crynwr packet driver.  If you
430   are porting to a new ethercard, look at the packet driver source for hints.
431   The NEx000 doesn't share the on-board packet memory -- you have to put
432   the packet out through the "remote DMA" dataport using outb. */
433
434static void
435apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
436{
437    int nic_base = dev->base_addr;
438    char *buf = skb->data;
439    char *ptrc;
440    short *ptrs;
441    int cnt;
442
443    /* This *shouldn't* happen. If it does, it's the last thing you'll see */
444    if (ei_status.dmaing) {
445		netdev_err(dev, "DMAing conflict in ne_block_input "
446			   "[DMAstat:%d][irqlock:%d][intr:%d].\n",
447			   ei_status.dmaing, ei_status.irqlock, dev->irq);
448	return;
449    }
450    ei_status.dmaing |= 0x01;
451    outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
452    outb(ENISR_RDC, nic_base + NE_EN0_ISR);
453    outb(count & 0xff, nic_base + NE_EN0_RCNTLO);
454    outb(count >> 8, nic_base + NE_EN0_RCNTHI);
455    outb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO);
456    outb(ring_offset >> 8, nic_base + NE_EN0_RSARHI);
457    outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
458    if (ei_status.word16) {
459      ptrs = (short*)buf;
460      for (cnt = 0; cnt < (count>>1); cnt++)
461        *ptrs++ = inw(NE_BASE + NE_DATAPORT);
462      if (count & 0x01) {
463	buf[count-1] = inb(NE_BASE + NE_DATAPORT);
464      }
465    } else {
466      ptrc = buf;
467      for (cnt = 0; cnt < count; cnt++)
468        *ptrc++ = inb(NE_BASE + NE_DATAPORT);
469    }
470
471    outb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
472    ei_status.dmaing &= ~0x01;
473}
474
475static void
476apne_block_output(struct net_device *dev, int count,
477		const unsigned char *buf, const int start_page)
478{
479    int nic_base = NE_BASE;
480    unsigned long dma_start;
481    char *ptrc;
482    short *ptrs;
483    int cnt;
484
485    /* Round the count up for word writes.  Do we need to do this?
486       What effect will an odd byte count have on the 8390?
487       I should check someday. */
488    if (ei_status.word16 && (count & 0x01))
489      count++;
490
491    /* This *shouldn't* happen. If it does, it's the last thing you'll see */
492    if (ei_status.dmaing) {
493		netdev_err(dev, "DMAing conflict in ne_block_output."
494			   "[DMAstat:%d][irqlock:%d][intr:%d]\n",
495			   ei_status.dmaing, ei_status.irqlock, dev->irq);
496	return;
497    }
498    ei_status.dmaing |= 0x01;
499    /* We should already be in page 0, but to be safe... */
500    outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
501
502    outb(ENISR_RDC, nic_base + NE_EN0_ISR);
503
504   /* Now the normal output. */
505    outb(count & 0xff, nic_base + NE_EN0_RCNTLO);
506    outb(count >> 8,   nic_base + NE_EN0_RCNTHI);
507    outb(0x00, nic_base + NE_EN0_RSARLO);
508    outb(start_page, nic_base + NE_EN0_RSARHI);
509
510    outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
511    if (ei_status.word16) {
512        ptrs = (short*)buf;
513        for (cnt = 0; cnt < count>>1; cnt++)
514            outw(*ptrs++, NE_BASE+NE_DATAPORT);
515    } else {
516        ptrc = (char*)buf;
517        for (cnt = 0; cnt < count; cnt++)
518	    outb(*ptrc++, NE_BASE + NE_DATAPORT);
519    }
520
521    dma_start = jiffies;
522
523    while ((inb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
524	if (time_after(jiffies, dma_start + 2*HZ/100)) {	/* 20ms */
525		netdev_warn(dev, "timeout waiting for Tx RDC.\n");
526		apne_reset_8390(dev);
527		NS8390_init(dev,1);
528		break;
529	}
530
531    outb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
532    ei_status.dmaing &= ~0x01;
533}
534
535static irqreturn_t apne_interrupt(int irq, void *dev_id)
536{
537    unsigned char pcmcia_intreq;
538
539    if (!(gayle.inten & GAYLE_IRQ_IRQ))
540        return IRQ_NONE;
541
542    pcmcia_intreq = pcmcia_get_intreq();
543
544    if (!(pcmcia_intreq & GAYLE_IRQ_IRQ)) {
545        pcmcia_ack_int(pcmcia_intreq);
546        return IRQ_NONE;
547    }
548    if (apne_msg_enable & NETIF_MSG_INTR)
549	pr_debug("pcmcia intreq = %x\n", pcmcia_intreq);
550    pcmcia_disable_irq();			/* to get rid of the sti() within ei_interrupt */
551    ei_interrupt(irq, dev_id);
552    pcmcia_ack_int(pcmcia_get_intreq());
553    pcmcia_enable_irq();
554    return IRQ_HANDLED;
555}
556
557#ifdef MODULE
558static struct net_device *apne_dev;
559
560static int __init apne_module_init(void)
561{
562	apne_dev = apne_probe(-1);
563	return PTR_ERR_OR_ZERO(apne_dev);
564}
565
566static void __exit apne_module_exit(void)
567{
568	unregister_netdev(apne_dev);
569
570	pcmcia_disable_irq();
571
572	free_irq(IRQ_AMIGA_PORTS, apne_dev);
573
574	pcmcia_reset();
575
576	release_region(IOBASE, 0x20);
577
578	free_netdev(apne_dev);
579}
580module_init(apne_module_init);
581module_exit(apne_module_exit);
582#endif
583
584static int init_pcmcia(void)
585{
586	u_char config;
587#ifndef MANUAL_CONFIG
588	u_char tuple[32];
589	int offset_len;
590#endif
591	u_long offset;
592
593	pcmcia_reset();
594	pcmcia_program_voltage(PCMCIA_0V);
595	pcmcia_access_speed(PCMCIA_SPEED_250NS);
596	pcmcia_write_enable();
597
598#ifdef MANUAL_CONFIG
599	config = MANUAL_CONFIG;
600#else
601	/* get and write config byte to enable IO port */
602
603	if (pcmcia_copy_tuple(CISTPL_CFTABLE_ENTRY, tuple, 32) < 3)
604		return 0;
605
606	config = tuple[2] & 0x3f;
607#endif
608#ifdef MANUAL_OFFSET
609	offset = MANUAL_OFFSET;
610#else
611	if (pcmcia_copy_tuple(CISTPL_CONFIG, tuple, 32) < 6)
612		return 0;
613
614	offset_len = (tuple[2] & 0x3) + 1;
615	offset = 0;
616	while(offset_len--) {
617		offset = (offset << 8) | tuple[4+offset_len];
618	}
619#endif
620
621	out_8(GAYLE_ATTRIBUTE+offset, config);
622
623	return 1;
624}
625
626MODULE_LICENSE("GPL");