netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] remove comx drivers from tree
@ 2004-05-07 11:17 Christoph Hellwig
  2004-05-14 17:32 ` Jeff Garzik
  0 siblings, 1 reply; 4+ messages in thread
From: Christoph Hellwig @ 2004-05-07 11:17 UTC (permalink / raw)
  To: netdev

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=unknown-8bit, Size: 275453 bytes --]

the drivers have been broken since pre-2.4.0, like referencing a symbol
that was made procfs-internal in 2.3.x, haven't received maintainer
updates for about the same period and MOD_{INC,DEC}_USE_COUNT usage that
pretty much unfixable (inside warts of _horrible_ procfs abuse).

I'd say just kill them.


--- 1.21/drivers/net/wan/Kconfig	Thu Feb 19 04:42:35 2004
+++ edited/drivers/net/wan/Kconfig	Fri May  7 13:06:20 2004
@@ -57,119 +57,6 @@
 	  The driver will be compiled as a module: the
 	  module will be called cosa.
 
-#
-# COMX drivers
-#
-# Not updated to 2.6.
-config COMX
-	tristate "MultiGate (COMX) synchronous serial boards support"
-	depends on WAN && (ISA || PCI) && BROKEN
-	---help---
-	  Drivers for the PC synchronous serial adapters by
-	  ITConsult-Pro Co, Hungary.
-
-	  Read <file:Documentation/networking/comx.txt> for help on configuring
-	  and using COMX interfaces. Further info on these cards can be found
-	  at <http://www.itc.hu/> or <info@itc.hu>.
-
-	  Say Y if you want to use any board from the MultiGate (COMX)
-	  family, you must also say Y to "/proc file system support"
-	  (CONFIG_PROC_FS) in order to use these drivers.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called comx.
-
-config COMX_HW_COMX
-	tristate "Support for COMX/CMX/HiCOMX boards"
-	depends on COMX
-	help
-	  Driver for the 'CMX', 'COMX' and 'HiCOMX' boards.
-
-	  You will need additional firmware to use these cards, which are
-	  downloadable from <ftp://ftp.itc.hu/>.
-
-	  Say Y if you have a board like this.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called comx-hw-comx.
-
-config COMX_HW_LOCOMX
-	tristate "Support for LoCOMX board"
-	depends on COMX
-	help
-	  Driver for the 'LoCOMX' board.
-
-	  Say Y if you have a board like this.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called comx-hw-locomx.
-
-config COMX_HW_MIXCOM
-	tristate "Support for MixCOM board"
-	depends on COMX
-	---help---
-	  Driver for the 'MixCOM' board.
-
-	  If you want to use the watchdog device on this card, you should
-	  select it in the Watchdog Cards section of the Character Devices
-	  configuration. The ISDN interface of this card is Teles 16.3
-	  compatible, you should enable it in the ISDN configuration menu. The
-	  driver for the flash ROM of this card is available separately on
-	  <ftp://ftp.itc.hu/>.
-
-	  Say Y if you have a board like this.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called comx-hw-mixcom.
-
-config COMX_HW_MUNICH
-	tristate "Support for MUNICH based boards: SliceCOM, PCICOM (WelCOM)"
-	depends on COMX
-	---help---
-	  Driver for the 'SliceCOM' (channelized E1) and 'PciCOM' (X21) boards.
-
-	  Read <file:Documentation/networking/slicecom.txt> for help on
-	  configuring and using SliceCOM interfaces. Further info on these
-	  cards can be found at <http://www.itc.hu> or <info@itc.hu>.
-
-	  Say Y if you have a board like this.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called comx-hw-munich.
-
-config COMX_PROTO_PPP
-	tristate "Support for HDLC and syncPPP protocols on MultiGate boards"
-	depends on COMX
-	help
-	  Cisco-HDLC and synchronous PPP protocol driver.
-
-	  Say Y if you want to use either protocol.
-
-	  To compile this as a module, choose M here: the
-	  module will be called comx-proto-ppp.
-
-config COMX_PROTO_LAPB
-	tristate "Support for LAPB protocol on MultiGate boards"
-	depends on WAN && (COMX!=n && LAPB=m && LAPB || LAPB=y && COMX)
-	help
-	  LAPB protocol driver.
-
-	  Say Y if you want to use this protocol.
-
-	  To compile this as a module, choose M here: the
-	  module will be called comx-proto-lapb.
-
-config COMX_PROTO_FR
-	tristate "Support for Frame Relay on MultiGate boards"
-	depends on COMX
-	help
-	  Frame Relay protocol driver.
-
-	  Say Y if you want to use this protocol.
-
-	  To compile this as a module, choose M here: the
-	  module will be called comx-proto-fr.
-
 config DSCC4
 	tristate "Etinc PCISYNC serial board support"
 	depends on WAN && PCI && m
===== drivers/net/wan/Makefile 1.18 vs edited =====
--- 1.18/drivers/net/wan/Makefile	Sat Jan 10 17:14:26 2004
+++ edited/drivers/net/wan/Makefile	Fri May  7 13:06:05 2004
@@ -32,14 +32,6 @@
 
 obj-$(CONFIG_HOSTESS_SV11)	+= z85230.o	syncppp.o	hostess_sv11.o
 obj-$(CONFIG_SEALEVEL_4021)	+= z85230.o	syncppp.o	sealevel.o
-obj-$(CONFIG_COMX)		+= 				comx.o
-obj-$(CONFIG_COMX_HW_COMX)	+= 				comx-hw-comx.o
-obj-$(CONFIG_COMX_HW_LOCOMX)	+= z85230.o	syncppp.o	comx-hw-locomx.o
-obj-$(CONFIG_COMX_HW_MIXCOM)	+=				comx-hw-mixcom.o
-obj-$(CONFIG_COMX_HW_MUNICH)	+=				comx-hw-munich.o
-obj-$(CONFIG_COMX_PROTO_PPP)	+=		syncppp.o	comx-proto-ppp.o
-obj-$(CONFIG_COMX_PROTO_LAPB)	+=				comx-proto-lapb.o
-obj-$(CONFIG_COMX_PROTO_FR)	+=				comx-proto-fr.o
 obj-$(CONFIG_COSA)		+=		syncppp.o	cosa.o
 obj-$(CONFIG_FARSYNC)		+=		syncppp.o	farsync.o
 obj-$(CONFIG_DSCC4)             +=				dscc4.o
===== drivers/net/wan/comx-hw-comx.c 1.13 vs edited =====
--- 1.13/drivers/net/wan/comx-hw-comx.c	Thu Sep 11 19:40:53 2003
+++ edited/drivers/net/wan/comx-hw-comx.c	Fri May  7 13:05:52 2004
@@ -1,1450 +1 @@
-/*
- * Hardware-level driver for the COMX and HICOMX cards
- * for Linux kernel 2.2.X
- *
- * Original authors:  Arpad Bakay <bakay.arpad@synergon.hu>,
- *                    Peter Bajan <bajan.peter@synergon.hu>,
- * Rewritten by: Tivadar Szemethy <tiv@itc.hu>
- * Currently maintained by: Gergely Madarasz <gorgo@itc.hu>
- *
- * Copyright (C) 1995-2000 ITConsult-Pro Co. <info@itc.hu>
- *
- * Contributors:
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 0.86
- * Daniele Bellucci         <bellucda@tiscali.it>   - 0.87
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Version 0.80 (99/06/11):
- *		- port back to kernel, add support builtin driver 
- *		- cleaned up the source code a bit
- *
- * Version 0.81 (99/06/22):
- *		- cleaned up the board load functions, no more long reset
- *		  timeouts
- *		- lower modem lines on close
- *		- some interrupt handling fixes
- *
- * Version 0.82 (99/08/24):
- *		- fix multiple board support
- *
- * Version 0.83 (99/11/30):
- *		- interrupt handling and locking fixes during initalization
- *		- really fix multiple board support
- * 
- * Version 0.84 (99/12/02):
- *		- some workarounds for problematic hardware/firmware
- *
- * Version 0.85 (00/01/14):
- *		- some additional workarounds :/
- *		- printk cleanups
- * Version 0.86 (00/08/15):
- * 		- resource release on failure at COMX_init
- *
- * Version 0.87 (03/07/09)
- *              - audit copy_from_user in comxhw_write_proc
- */
 
-#define VERSION "0.87"
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#include "comx.h"
-#include "comxhw.h"
-
-MODULE_AUTHOR("Gergely Madarasz <gorgo@itc.hu>, Tivadar Szemethy <tiv@itc.hu>, Arpad Bakay");
-MODULE_DESCRIPTION("Hardware-level driver for the COMX and HICOMX adapters\n");
-MODULE_LICENSE("GPL");
-
-#define	COMX_readw(dev, offset)	(readw(dev->mem_start + offset + \
-	(unsigned int)(((struct comx_privdata *)\
-	((struct comx_channel *)dev->priv)->HW_privdata)->channel) \
-	* COMX_CHANNEL_OFFSET))
-
-#define COMX_WRITE(dev, offset, value)	(writew(value, dev->mem_start + offset \
-	+ (unsigned int)(((struct comx_privdata *) \
-	((struct comx_channel *)dev->priv)->HW_privdata)->channel) \
-	* COMX_CHANNEL_OFFSET))
-
-#define COMX_CMD(dev, cmd)	(COMX_WRITE(dev, OFF_A_L2_CMD, cmd))
-
-struct comx_firmware {
-	int	len;
-	unsigned char *data;
-};
-
-struct comx_privdata {
-	struct comx_firmware *firmware;
-	u16	clock;
-	char	channel;		// channel no.
-	int	memory_size;
-	short	io_extent;
-	u_long	histogram[5];
-};
-
-static struct net_device *memory_used[(COMX_MEM_MAX - COMX_MEM_MIN) / 0x10000];
-extern struct comx_hardware hicomx_hw;
-extern struct comx_hardware comx_hw;
-extern struct comx_hardware cmx_hw;
-
-static irqreturn_t COMX_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
-static void COMX_board_on(struct net_device *dev)
-{
-	outb_p( (byte) (((dev->mem_start & 0xf0000) >> 16) | 
-	    COMX_ENABLE_BOARD_IT | COMX_ENABLE_BOARD_MEM), dev->base_addr);
-}
-
-static void COMX_board_off(struct net_device *dev)
-{
-	outb_p( (byte) (((dev->mem_start & 0xf0000) >> 16) | 
-	   COMX_ENABLE_BOARD_IT), dev->base_addr);
-}
-
-static void HICOMX_board_on(struct net_device *dev)
-{
-	outb_p( (byte) (((dev->mem_start & 0xf0000) >> 12) | 
-	   HICOMX_ENABLE_BOARD_MEM), dev->base_addr);
-}
-
-static void HICOMX_board_off(struct net_device *dev)
-{
-	outb_p( (byte) (((dev->mem_start & 0xf0000) >> 12) | 
-	   HICOMX_DISABLE_BOARD_MEM), dev->base_addr);
-}
-
-static void COMX_set_clock(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct comx_privdata *hw = ch->HW_privdata;
-
-	COMX_WRITE(dev, OFF_A_L1_CLKINI, hw->clock);
-}
-
-static struct net_device *COMX_access_board(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct net_device *ret;
-	int mempos = (dev->mem_start - COMX_MEM_MIN) >> 16;
-	unsigned long flags;
-
-
-	save_flags(flags); cli();
-	
-	ret = memory_used[mempos];
-
-	if(ret == dev) {
-		goto out;
-	}
-
-	memory_used[mempos] = dev;
-
-	if (!ch->twin || ret != ch->twin) {
-		if (ret) ((struct comx_channel *)ret->priv)->HW_board_off(ret);
-		ch->HW_board_on(dev);
-	}
-out:
-	restore_flags(flags);
-	return ret;
-}
-
-static void COMX_release_board(struct net_device *dev, struct net_device *savep)
-{
-	unsigned long flags;
-	int mempos = (dev->mem_start - COMX_MEM_MIN) >> 16;
-	struct comx_channel *ch = dev->priv;
-
-	save_flags(flags); cli();
-
-	if (memory_used[mempos] == savep) {
-		goto out;
-	}
-
-	memory_used[mempos] = savep;
-	if (!ch->twin || ch->twin != savep) {
-		ch->HW_board_off(dev);
-		if (savep) ((struct comx_channel*)savep->priv)->HW_board_on(savep);
-	}
-out:
-	restore_flags(flags);
-}
-
-static int COMX_txe(struct net_device *dev) 
-{
-	struct net_device *savep;
-	struct comx_channel *ch = dev->priv;
-	int rc = 0;
-
-	savep = ch->HW_access_board(dev);
-	if (COMX_readw(dev,OFF_A_L2_LINKUP) == LINKUP_READY) {
-		rc = COMX_readw(dev,OFF_A_L2_TxEMPTY);
-	} 
-	ch->HW_release_board(dev,savep);
-	if(rc==0xffff) {
-		printk(KERN_ERR "%s, OFF_A_L2_TxEMPTY is %d\n",dev->name, rc);
-	}
-	return rc;
-}
-
-static int COMX_send_packet(struct net_device *dev, struct sk_buff *skb)
-{
-	struct net_device *savep;
-	struct comx_channel *ch = dev->priv;
-	struct comx_privdata *hw = ch->HW_privdata;
-	int ret = FRAME_DROPPED;
-	word tmp;
-
-	savep = ch->HW_access_board(dev);	
-
-	if (ch->debug_flags & DEBUG_HW_TX) {
-		comx_debug_bytes(dev, skb->data, skb->len,"COMX_send packet");
-	}
-
-	if (skb->len > COMX_MAX_TX_SIZE) {
-		ret=FRAME_DROPPED;
-		goto out;
-	}
-
-	tmp=COMX_readw(dev, OFF_A_L2_TxEMPTY);
-	if ((ch->line_status & LINE_UP) && tmp==1) {
-		int lensave = skb->len;
-		int dest = COMX_readw(dev, OFF_A_L2_TxBUFP);
-		word *data = (word *)skb->data;
-
-		if(dest==0xffff) {
-			printk(KERN_ERR "%s: OFF_A_L2_TxBUFP is %d\n", dev->name, dest);
-			ret=FRAME_DROPPED;
-			goto out;
-		}
-					
-		writew((unsigned short)skb->len, dev->mem_start + dest);
-		dest += 2;
-		while (skb->len > 1) {
-			writew(*data++, dev->mem_start + dest);
-			dest += 2; skb->len -= 2;
-		}
-		if (skb->len == 1) {
-			writew(*((byte *)data), dev->mem_start + dest);
-		}
-		writew(0, dev->mem_start + (int)hw->channel * 
-		   COMX_CHANNEL_OFFSET + OFF_A_L2_TxEMPTY);
-		ch->stats.tx_packets++;	
-		ch->stats.tx_bytes += lensave; 
-		ret = FRAME_ACCEPTED;
-	} else {
-		ch->stats.tx_dropped++;
-		printk(KERN_INFO "%s: frame dropped\n",dev->name);
-		if(tmp) {
-			printk(KERN_ERR "%s: OFF_A_L2_TxEMPTY is %d\n",dev->name,tmp);
-		}
-	}
-	
-out:
-	ch->HW_release_board(dev, savep);
-	dev_kfree_skb(skb);
-	return ret;
-}
-
-static inline int comx_read_buffer(struct net_device *dev) 
-{
-	struct comx_channel *ch = dev->priv;
-	word rbuf_offs;
-	struct sk_buff *skb;
-	word len;
-	int i=0;
-	word *writeptr;
-
-	i = 0;
-	rbuf_offs = COMX_readw(dev, OFF_A_L2_RxBUFP);
-	if(rbuf_offs == 0xffff) {
-		printk(KERN_ERR "%s: OFF_A_L2_RxBUFP is %d\n",dev->name,rbuf_offs);
-		return 0;
-	}
-	len = readw(dev->mem_start + rbuf_offs);
-	if(len > COMX_MAX_RX_SIZE) {
-		printk(KERN_ERR "%s: packet length is %d\n",dev->name,len);
-		return 0;
-	}
-	if ((skb = dev_alloc_skb(len + 16)) == NULL) {
-		ch->stats.rx_dropped++;
-		COMX_WRITE(dev, OFF_A_L2_DAV, 0);
-		return 0;
-	}
-	rbuf_offs += 2;
-	skb_reserve(skb, 16);
-	skb_put(skb, len);
-	skb->dev = dev;
-	writeptr = (word *)skb->data;
-	while (i < len) {
-		*writeptr++ = readw(dev->mem_start + rbuf_offs);
-		rbuf_offs += 2; 
-		i += 2;
-	}
-	COMX_WRITE(dev, OFF_A_L2_DAV, 0);
-	ch->stats.rx_packets++;
-	ch->stats.rx_bytes += len;
-	if (ch->debug_flags & DEBUG_HW_RX) {
-		comx_debug_skb(dev, skb, "COMX_interrupt receiving");
-	}
-	ch->LINE_rx(dev, skb);
-	return 1;
-}
-
-static inline char comx_line_change(struct net_device *dev, char linestat)
-{
-	struct comx_channel *ch=dev->priv;
-	char idle=1;
-	
-	
-	if (linestat & LINE_UP) { /* Vonal fol */
-		if (ch->lineup_delay) {
-			if (!test_and_set_bit(0, &ch->lineup_pending)) {
-				ch->lineup_timer.function = comx_lineup_func;
-				ch->lineup_timer.data = (unsigned long)dev;
-				ch->lineup_timer.expires = jiffies +
-					HZ*ch->lineup_delay;
-				add_timer(&ch->lineup_timer);
-				idle=0;
-			}
-		} else {
-			idle=0;
-			ch->LINE_status(dev, ch->line_status |= LINE_UP);
-		}
-	} else { /* Vonal le */
-		idle=0;
-		if (test_and_clear_bit(0, &ch->lineup_pending)) {
-			del_timer(&ch->lineup_timer);
-		} else {
-			ch->line_status &= ~LINE_UP;
-			if (ch->LINE_status) {
-				ch->LINE_status(dev, ch->line_status);
-			}
-		}
-	}
-	return idle;
-}
-
-
-
-static irqreturn_t COMX_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct net_device *dev = dev_id;
-	struct comx_channel *ch = dev->priv;
-	struct comx_privdata *hw = ch->HW_privdata;
-	struct net_device *interrupted;
-	unsigned long jiffs;
-	char idle = 0;
-	int count = 0;
-	word tmp;
-
-	if (dev == NULL) {
-		printk(KERN_ERR "COMX_interrupt: irq %d for unknown device\n", irq);
-		return IRQ_NONE;
-	}
-
-	jiffs = jiffies;
-
-	interrupted = ch->HW_access_board(dev);
-
-	while (!idle && count < 5000) {
-		char channel = 0;
-		idle = 1;
-
-		while (channel < 2) {
-			char linestat = 0;
-			char buffers_emptied = 0;
-
-			if (channel == 1) {
-				if (ch->twin) {
-					dev = ch->twin;
-					ch = dev->priv;
-					hw = ch->HW_privdata;
-				} else {
-					break;
-				}
-			} else {
-				COMX_WRITE(dev, OFF_A_L1_REPENA, 
-				    COMX_readw(dev, OFF_A_L1_REPENA) & 0xFF00);
-			}
-			channel++;
-
-			if ((ch->init_status & (HW_OPEN | LINE_OPEN)) != 
-			   (HW_OPEN | LINE_OPEN)) {
-				continue;
-			}
-	
-			/* Collect stats */
-			tmp = COMX_readw(dev, OFF_A_L1_ABOREC);
-			COMX_WRITE(dev, OFF_A_L1_ABOREC, 0);
-			if(tmp==0xffff) {
-				printk(KERN_ERR "%s: OFF_A_L1_ABOREC is %d\n",dev->name,tmp);
-				break;
-			} else {
-				ch->stats.rx_missed_errors += (tmp >> 8) & 0xff;
-				ch->stats.rx_over_errors += tmp & 0xff;
-			}
-			tmp = COMX_readw(dev, OFF_A_L1_CRCREC);
-			COMX_WRITE(dev, OFF_A_L1_CRCREC, 0);
-			if(tmp==0xffff) {
-				printk(KERN_ERR "%s: OFF_A_L1_CRCREC is %d\n",dev->name,tmp);
-				break;
-			} else {
-				ch->stats.rx_crc_errors += (tmp >> 8) & 0xff;
-				ch->stats.rx_missed_errors += tmp & 0xff;
-			}
-			
-			if ((ch->line_status & LINE_UP) && ch->LINE_rx) {
-				tmp=COMX_readw(dev, OFF_A_L2_DAV); 
-				while (tmp==1) {
-					idle=0;
-					buffers_emptied+=comx_read_buffer(dev);
-					tmp=COMX_readw(dev, OFF_A_L2_DAV); 
-				}
-				if(tmp) {
-					printk(KERN_ERR "%s: OFF_A_L2_DAV is %d\n", dev->name, tmp);
-					break;
-				}
-			}
-
-			tmp=COMX_readw(dev, OFF_A_L2_TxEMPTY);
-			if (tmp==1 && ch->LINE_tx) {
-				ch->LINE_tx(dev);
-			} 
-			if(tmp==0xffff) {
-				printk(KERN_ERR "%s: OFF_A_L2_TxEMPTY is %d\n", dev->name, tmp);
-				break;
-			}
-
-			if (COMX_readw(dev, OFF_A_L1_PBUFOVR) >> 8) {
-				linestat &= ~LINE_UP;
-			} else {
-				linestat |= LINE_UP;
-			}
-
-			if ((linestat & LINE_UP) != (ch->line_status & LINE_UP)) {
-				ch->stats.tx_carrier_errors++;
-				idle &= comx_line_change(dev,linestat);
-			}
-				
-			hw->histogram[(int)buffers_emptied]++;
-		}
-		count++;
-	}
-
-	if(count==5000) {
-		printk(KERN_WARNING "%s: interrupt stuck\n",dev->name);
-	}
-
-	ch->HW_release_board(dev, interrupted);
-	return IRQ_HANDLED;
-}
-
-static int COMX_open(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct comx_privdata *hw = ch->HW_privdata;
-	struct proc_dir_entry *procfile = ch->procdir->subdir;
-	unsigned long jiffs;
-	int twin_open=0;
-	int retval;
-	struct net_device *savep;
-
-	if (!dev->base_addr || !dev->irq || !dev->mem_start) {
-		return -ENODEV;
-	}
-
-	if (ch->twin && (((struct comx_channel *)(ch->twin->priv))->init_status & HW_OPEN)) {
-		twin_open=1;
-	}
-
-	if (!twin_open) {
-		if (!request_region(dev->base_addr, hw->io_extent, dev->name)) {
-			return -EAGAIN;
-		}
-		if (request_irq(dev->irq, COMX_interrupt, 0, dev->name, 
-		   (void *)dev)) {
-			printk(KERN_ERR "comx-hw-comx: unable to obtain irq %d\n", dev->irq);
-			release_region(dev->base_addr, hw->io_extent);
-			return -EAGAIN;
-		}
-		ch->init_status |= IRQ_ALLOCATED;
-		if (!ch->HW_load_board || ch->HW_load_board(dev)) {
-			ch->init_status &= ~IRQ_ALLOCATED;
-			retval=-ENODEV;
-			goto error;
-		}
-	}
-
-	savep = ch->HW_access_board(dev);
-	COMX_WRITE(dev, OFF_A_L2_LINKUP, 0);
-
-	if (ch->HW_set_clock) {
-		ch->HW_set_clock(dev);
-	}
-
-	COMX_CMD(dev, COMX_CMD_INIT); 
-	jiffs = jiffies;
-	while (COMX_readw(dev, OFF_A_L2_LINKUP) != 1 && time_before(jiffies, jiffs + HZ)) {
-		schedule_timeout(1);
-	}
-	
-	if (time_after_eq(jiffies, jiffs + HZ)) {
-		printk(KERN_ERR "%s: board timeout on INIT command\n", dev->name);
-		ch->HW_release_board(dev, savep);
-		retval=-EIO;
-		goto error;
-	}
-	udelay(1000);
-
-	COMX_CMD(dev, COMX_CMD_OPEN);
-
-	jiffs = jiffies;
-	while (COMX_readw(dev, OFF_A_L2_LINKUP) != 3 && time_before(jiffies, jiffs + HZ)) {
-		schedule_timeout(1);
-	}
-	
-	if (time_after_eq(jiffies, jiffs + HZ)) {
-		printk(KERN_ERR "%s: board timeout on OPEN command\n", dev->name);
-		ch->HW_release_board(dev, savep);
-		retval=-EIO;
-		goto error;
-	}
-	
-	ch->init_status |= HW_OPEN;
-	
-	/* Ez eleg ciki, de ilyen a rendszer */
-	if (COMX_readw(dev, OFF_A_L1_PBUFOVR) >> 8) {
-		ch->line_status &= ~LINE_UP;
-	} else {
-		ch->line_status |= LINE_UP;
-	}
-	
-	if (ch->LINE_status) {
-		ch->LINE_status(dev, ch->line_status);
-	}
-
-	ch->HW_release_board(dev, savep);
-
-	for ( ; procfile ; procfile = procfile->next) {
-		if (strcmp(procfile->name, FILENAME_IRQ) == 0 
-		    || strcmp(procfile->name, FILENAME_IO) == 0
-		    || strcmp(procfile->name, FILENAME_MEMADDR) == 0
-		    || strcmp(procfile->name, FILENAME_CHANNEL) == 0
-		    || strcmp(procfile->name, FILENAME_FIRMWARE) == 0
-		    || strcmp(procfile->name, FILENAME_CLOCK) == 0) {
-			procfile->mode = S_IFREG | 0444;
-		
-		}
-	}	
-	
-	return 0;	
-
-error:
-	if(!twin_open) {
-		release_region(dev->base_addr, hw->io_extent);
-		free_irq(dev->irq, (void *)dev);
-	}
-	return retval;
-
-}
-
-static int COMX_close(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct proc_dir_entry *procfile = ch->procdir->subdir;
-	struct comx_privdata *hw = ch->HW_privdata;
-	struct comx_channel *twin_ch;
-	struct net_device *savep;
-
-	savep = ch->HW_access_board(dev);
-
-	COMX_CMD(dev, COMX_CMD_CLOSE);
-	udelay(1000);
-	COMX_CMD(dev, COMX_CMD_EXIT);
-
-	ch->HW_release_board(dev, savep);
-
-	if (ch->init_status & IRQ_ALLOCATED) {
-		free_irq(dev->irq, (void *)dev);
-		ch->init_status &= ~IRQ_ALLOCATED;
-	}
-	release_region(dev->base_addr, hw->io_extent);
-
-	if (ch->twin && (twin_ch = ch->twin->priv) && 
-	    (twin_ch->init_status & HW_OPEN)) {
-		/* Pass the irq to the twin */
-		if (request_irq(dev->irq, COMX_interrupt, 0, ch->twin->name, 
-		   (void *)ch->twin) == 0) {
-			twin_ch->init_status |= IRQ_ALLOCATED;
-		}
-	}
-
-	for ( ; procfile ; procfile = procfile->next) {
-		if (strcmp(procfile->name, FILENAME_IRQ) == 0 
-		    || strcmp(procfile->name, FILENAME_IO) == 0
-		    || strcmp(procfile->name, FILENAME_MEMADDR) == 0
-		    || strcmp(procfile->name, FILENAME_CHANNEL) == 0
-		    || strcmp(procfile->name, FILENAME_FIRMWARE) == 0
-		    || strcmp(procfile->name, FILENAME_CLOCK) == 0) {
-			procfile->mode = S_IFREG | 0644;
-		}
-	}
-	
-	ch->init_status &= ~HW_OPEN;
-	return 0;
-}
-
-static int COMX_statistics(struct net_device *dev, char *page)
-{
-	struct comx_channel *ch = dev->priv;
-	struct comx_privdata *hw = ch->HW_privdata;
-	struct net_device *savep;
-	int len = 0;
-
-	savep = ch->HW_access_board(dev);
-
-	len += sprintf(page + len, "Board data: %s %s %s %s\nPBUFOVR: %02x, "
-		"MODSTAT: %02x, LINKUP: %02x, DAV: %02x\nRxBUFP: %02x, "
-		"TxEMPTY: %02x, TxBUFP: %02x\n",
-		(ch->init_status & HW_OPEN) ? "HW_OPEN" : "",
-		(ch->init_status & LINE_OPEN) ? "LINE_OPEN" : "",
-		(ch->init_status & FW_LOADED) ? "FW_LOADED" : "",
-		(ch->init_status & IRQ_ALLOCATED) ? "IRQ_ALLOCATED" : "",
-		COMX_readw(dev, OFF_A_L1_PBUFOVR) & 0xff,
-		(COMX_readw(dev, OFF_A_L1_PBUFOVR) >> 8) & 0xff,
-		COMX_readw(dev, OFF_A_L2_LINKUP) & 0xff,
-		COMX_readw(dev, OFF_A_L2_DAV) & 0xff,
-		COMX_readw(dev, OFF_A_L2_RxBUFP) & 0xff,
-		COMX_readw(dev, OFF_A_L2_TxEMPTY) & 0xff,
-		COMX_readw(dev, OFF_A_L2_TxBUFP) & 0xff);
-
-	len += sprintf(page + len, "hist[0]: %8lu hist[1]: %8lu hist[2]: %8lu\n"
-		"hist[3]: %8lu hist[4]: %8lu\n",hw->histogram[0],hw->histogram[1],
-		hw->histogram[2],hw->histogram[3],hw->histogram[4]);
-
-	ch->HW_release_board(dev, savep);
-
-	return len;
-}
-
-static int COMX_load_board(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct comx_privdata *hw = ch->HW_privdata;
-	struct comx_firmware *fw = hw->firmware;
-	word board_segment = dev->mem_start >> 16;
-	int mempos = (dev->mem_start - COMX_MEM_MIN) >> 16;
-	unsigned long flags;
-	unsigned char id1, id2;
-	struct net_device *saved;
-	int retval;
-	int loopcount;
-	int len;
-	byte *COMX_address;
-
-	if (!fw || !fw->len) {
-		struct comx_channel *twin_ch = ch->twin ? ch->twin->priv : NULL;
-		struct comx_privdata *twin_hw;
-
-		if (!twin_ch || !(twin_hw = twin_ch->HW_privdata)) {
-			return -EAGAIN;
-		}
-
-		if (!(fw = twin_hw->firmware) || !fw->len) {
-			return -EAGAIN;
-		}
-	}
-
-	id1 = fw->data[OFF_FW_L1_ID]; 
-	id2 = fw->data[OFF_FW_L1_ID + 1];
-
-	if (id1 != FW_L1_ID_1 || id2 != FW_L1_ID_2_COMX) {
-		printk(KERN_ERR "%s: incorrect firmware, load aborted\n", 
-			dev->name);
-		return -EAGAIN;
-	}
-
-	printk(KERN_INFO "%s: Loading COMX Layer 1 firmware %s\n", dev->name, 
-		(char *)(fw->data + OFF_FW_L1_ID + 2));
-
-	id1 = fw->data[OFF_FW_L2_ID]; 
-	id2 = fw->data[OFF_FW_L2_ID + 1];
-	if (id1 == FW_L2_ID_1 && (id2 == 0xc0 || id2 == 0xc1 || id2 == 0xc2)) {
-		printk(KERN_INFO "with Layer 2 code %s\n", 
-			(char *)(fw->data + OFF_FW_L2_ID + 2));
-	}
-
-	outb_p(board_segment | COMX_BOARD_RESET, dev->base_addr);
-	/* 10 usec should be enough here */
-	udelay(100);
-
-	save_flags(flags); cli();
-	saved=memory_used[mempos];
-	if(saved) {
-		((struct comx_channel *)saved->priv)->HW_board_off(saved);
-	}
-	memory_used[mempos]=dev;
-
-	outb_p(board_segment | COMX_ENABLE_BOARD_MEM, dev->base_addr);
-
-	writeb(0, dev->mem_start + COMX_JAIL_OFFSET);	
-
-	loopcount=0;
-	while(loopcount++ < 10000 && 
-	    readb(dev->mem_start + COMX_JAIL_OFFSET) != COMX_JAIL_VALUE) {
-		udelay(100);
-	}	
-	
-	if (readb(dev->mem_start + COMX_JAIL_OFFSET) != COMX_JAIL_VALUE) {
-		printk(KERN_ERR "%s: Can't reset board, JAIL value is %02x\n",
-			dev->name, readb(dev->mem_start + COMX_JAIL_OFFSET));
-		retval=-ENODEV;
-		goto out;
-	}
-
-	writeb(0x55, dev->mem_start + 0x18ff);
-	
-	loopcount=0;
-	while(loopcount++ < 10000 && readb(dev->mem_start + 0x18ff) != 0) {
-		udelay(100);
-	}
-
-	if(readb(dev->mem_start + 0x18ff) != 0) {
-		printk(KERN_ERR "%s: Can't reset board, reset timeout\n",
-			dev->name);
-		retval=-ENODEV;
-		goto out;
-	}		
-
-	len = 0;
-	COMX_address = (byte *)dev->mem_start;
-	while (fw->len > len) {
-		writeb(fw->data[len++], COMX_address++);
-	}
-
-	len = 0;
-	COMX_address = (byte *)dev->mem_start;
-	while (len != fw->len && readb(COMX_address++) == fw->data[len]) {
-		len++;
-	}
-
-	if (len != fw->len) {
-		printk(KERN_ERR "%s: error loading firmware: [%d] is 0x%02x "
-			"instead of 0x%02x\n", dev->name, len, 
-			readb(COMX_address - 1), fw->data[len]);
-		retval=-EAGAIN;
-		goto out;
-	}
-
-	writeb(0, dev->mem_start + COMX_JAIL_OFFSET);
-
-	loopcount = 0;
-	while ( loopcount++ < 10000 && COMX_readw(dev, OFF_A_L2_LINKUP) != 1 ) {
-		udelay(100);
-	}
-
-	if (COMX_readw(dev, OFF_A_L2_LINKUP) != 1) {
-		printk(KERN_ERR "%s: error starting firmware, linkup word is %04x\n",
-			dev->name, COMX_readw(dev, OFF_A_L2_LINKUP));
-		retval=-EAGAIN;
-		goto out;
-	}
-
-
-	ch->init_status |= FW_LOADED;
-	retval=0;
-
-out: 
-	outb_p(board_segment | COMX_DISABLE_ALL, dev->base_addr);
-	if(saved) {
-		((struct comx_channel *)saved->priv)->HW_board_on(saved);
-	}
-	memory_used[mempos]=saved;
-	restore_flags(flags);
-	return retval;
-}
-
-static int CMX_load_board(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct comx_privdata *hw = ch->HW_privdata;
-	struct comx_firmware *fw = hw->firmware;
-	word board_segment = dev->mem_start >> 16;
-	int mempos = (dev->mem_start - COMX_MEM_MIN) >> 16;
-	#if 0
-	unsigned char id1, id2;
-	#endif
-	struct net_device *saved;
-	unsigned long flags;
-	int retval;
-	int loopcount;
-	int len;
-	byte *COMX_address;
-
-	if (!fw || !fw->len) {
-		struct comx_channel *twin_ch = ch->twin ? ch->twin->priv : NULL;
-		struct comx_privdata *twin_hw;
-
-		if (!twin_ch || !(twin_hw = twin_ch->HW_privdata)) {
-			return -EAGAIN;
-		}
-
-		if (!(fw = twin_hw->firmware) || !fw->len) {
-			return -EAGAIN;
-		}
-	}
-
-	/* Ide kell olyat tenni, hogy ellenorizze az ID-t */
-
-	if (inb_p(dev->base_addr) != CMX_ID_BYTE) {
-		printk(KERN_ERR "%s: CMX id byte is invalid(%02x)\n", dev->name,
-			inb_p(dev->base_addr));
-		return -ENODEV;
-	}
-
-	printk(KERN_INFO "%s: Loading CMX Layer 1 firmware %s\n", dev->name, 
-		(char *)(fw->data + OFF_FW_L1_ID + 2));
-
-	save_flags(flags); cli();
-	saved=memory_used[mempos];
-	if(saved) {
-		((struct comx_channel *)saved->priv)->HW_board_off(saved);
-	}
-	memory_used[mempos]=dev;
-	
-	outb_p(board_segment | COMX_ENABLE_BOARD_MEM | COMX_BOARD_RESET, 
-		dev->base_addr);
-
-	len = 0;
-	COMX_address = (byte *)dev->mem_start;
-	while (fw->len > len) {
-		writeb(fw->data[len++], COMX_address++);
-	}
-
-	len = 0;
-	COMX_address = (byte *)dev->mem_start;
-	while (len != fw->len && readb(COMX_address++) == fw->data[len]) {
-		len++;
-	}
-
-	outb_p(board_segment | COMX_ENABLE_BOARD_MEM, dev->base_addr);
-
-	if (len != fw->len) {
-		printk(KERN_ERR "%s: error loading firmware: [%d] is 0x%02x "
-			"instead of 0x%02x\n", dev->name, len, 
-			readb(COMX_address - 1), fw->data[len]);
-		retval=-EAGAIN;
-		goto out;
-	}
-
-	loopcount=0;
-	while( loopcount++ < 10000 && COMX_readw(dev, OFF_A_L2_LINKUP) != 1 ) {
-		udelay(100);
-	}
-
-	if (COMX_readw(dev, OFF_A_L2_LINKUP) != 1) {
-		printk(KERN_ERR "%s: error starting firmware, linkup word is %04x\n",
-			dev->name, COMX_readw(dev, OFF_A_L2_LINKUP));
-		retval=-EAGAIN;
-		goto out;
-	}
-
-	ch->init_status |= FW_LOADED;
-	retval=0;
-
-out: 
-	outb_p(board_segment | COMX_DISABLE_ALL, dev->base_addr);
-	if(saved) {
-		((struct comx_channel *)saved->priv)->HW_board_on(saved);
-	}
-	memory_used[mempos]=saved;
-	restore_flags(flags);
-	return retval;
-}
-
-static int HICOMX_load_board(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct comx_privdata *hw = ch->HW_privdata;
-	struct comx_firmware *fw = hw->firmware;
-	word board_segment = dev->mem_start >> 12;
-	int mempos = (dev->mem_start - COMX_MEM_MIN) >> 16;
-	struct net_device *saved;
-	unsigned char id1, id2;
-	unsigned long flags;
-	int retval;
-	int loopcount;
-	int len;
-	word *HICOMX_address;
-	char id = 1;
-
-	if (!fw || !fw->len) {
-		struct comx_channel *twin_ch = ch->twin ? ch->twin->priv : NULL;
-		struct comx_privdata *twin_hw;
-
-		if (!twin_ch || !(twin_hw = twin_ch->HW_privdata)) {
-			return -EAGAIN;
-		}
-
-		if (!(fw = twin_hw->firmware) || !fw->len) {
-			return -EAGAIN;
-		}
-	}
-
-	while (id != 4) {
-		if (inb_p(dev->base_addr + id++) != HICOMX_ID_BYTE) {
-			break;
-		}
-	}
-
-	if (id != 4) {
-		printk(KERN_ERR "%s: can't find HICOMX at 0x%04x, id[%d] = %02x\n",
-			dev->name, (unsigned int)dev->base_addr, id - 1,
-			inb_p(dev->base_addr + id - 1));
-		return -1;	
-	}
-
-	id1 = fw->data[OFF_FW_L1_ID]; 
-	id2 = fw->data[OFF_FW_L1_ID + 1];
-	if (id1 != FW_L1_ID_1 || id2 != FW_L1_ID_2_HICOMX) {
-		printk(KERN_ERR "%s: incorrect firmware, load aborted\n", dev->name);
-		return -EAGAIN;
-	}
-
-	printk(KERN_INFO "%s: Loading HICOMX Layer 1 firmware %s\n", dev->name, 
-		(char *)(fw->data + OFF_FW_L1_ID + 2));
-
-	id1 = fw->data[OFF_FW_L2_ID]; 
-	id2 = fw->data[OFF_FW_L2_ID + 1];
-	if (id1 == FW_L2_ID_1 && (id2 == 0xc0 || id2 == 0xc1 || id2 == 0xc2)) {
-		printk(KERN_INFO "with Layer 2 code %s\n", 
-			(char *)(fw->data + OFF_FW_L2_ID + 2));
-	}
-
-	outb_p(board_segment | HICOMX_BOARD_RESET, dev->base_addr);
-	udelay(10);	
-
-	save_flags(flags); cli();
-	saved=memory_used[mempos];
-	if(saved) {
-		((struct comx_channel *)saved->priv)->HW_board_off(saved);
-	}
-	memory_used[mempos]=dev;
-
-	outb_p(board_segment | HICOMX_ENABLE_BOARD_MEM, dev->base_addr);
-	outb_p(HICOMX_PRG_MEM, dev->base_addr + 1);
-
-	len = 0;
-	HICOMX_address = (word *)dev->mem_start;
-	while (fw->len > len) {
-		writeb(fw->data[len++], HICOMX_address++);
-	}
-
-	len = 0;
-	HICOMX_address = (word *)dev->mem_start;
-	while (len != fw->len && (readw(HICOMX_address++) & 0xff) == fw->data[len]) {
-		len++;
-	}
-
-	if (len != fw->len) {
-		printk(KERN_ERR "%s: error loading firmware: [%d] is 0x%02x "
-			"instead of 0x%02x\n", dev->name, len, 
-			readw(HICOMX_address - 1) & 0xff, fw->data[len]);
-		retval=-EAGAIN;
-		goto out;
-	}
-
-	outb_p(board_segment | HICOMX_BOARD_RESET, dev->base_addr);
-	outb_p(HICOMX_DATA_MEM, dev->base_addr + 1);
-
-	outb_p(board_segment | HICOMX_ENABLE_BOARD_MEM, dev->base_addr);
-
-	loopcount=0;
-	while(loopcount++ < 10000 && COMX_readw(dev, OFF_A_L2_LINKUP) != 1) {
-		udelay(100);
-	}
-
-	if ( COMX_readw(dev, OFF_A_L2_LINKUP) != 1 ) {
-		printk(KERN_ERR "%s: error starting firmware, linkup word is %04x\n",
-			dev->name, COMX_readw(dev, OFF_A_L2_LINKUP));
-		retval=-EAGAIN;
-		goto out;
-	}
-
-	ch->init_status |= FW_LOADED;
-	retval=0;
-
-out:
-	outb_p(board_segment | HICOMX_DISABLE_ALL, dev->base_addr);
-	outb_p(HICOMX_DATA_MEM, dev->base_addr + 1);
-
-	if(saved) {
-		((struct comx_channel *)saved->priv)->HW_board_on(saved);
-	}
-	memory_used[mempos]=saved;
-	restore_flags(flags);
-	return retval;
-}
-
-static struct net_device *comx_twin_check(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct proc_dir_entry *procfile = ch->procdir->parent->subdir;
-	struct comx_privdata *hw = ch->HW_privdata;
-
-	struct net_device *twin;
-	struct comx_channel *ch_twin;
-	struct comx_privdata *hw_twin;
-
-
-	for ( ; procfile ; procfile = procfile->next) {
-	
-		if(!S_ISDIR(procfile->mode)) {
-			continue;
-		}
-	
-		twin=procfile->data;
-		ch_twin=twin->priv;
-		hw_twin=ch_twin->HW_privdata;
-
-
-		if (twin != dev && dev->irq && dev->base_addr && dev->mem_start &&
-		   dev->irq == twin->irq && dev->base_addr == twin->base_addr &&
-	  	   dev->mem_start == twin->mem_start &&
-		   hw->channel == (1 - hw_twin->channel) &&
-		   ch->hardware == ch_twin->hardware) {
-		   	return twin;
-		}
-	}
-	return NULL;
-}
-
-static int comxhw_write_proc(struct file *file, const char *buffer, 
-	u_long count, void *data)
-{
-	struct proc_dir_entry *entry = (struct proc_dir_entry *)data;
-	struct net_device *dev = entry->parent->data;
-	struct comx_channel *ch = dev->priv;
-	struct comx_privdata *hw = ch->HW_privdata;
-	char *page;
-
-
-	if(ch->init_status & HW_OPEN) {
-		return -EAGAIN;	
-	}
-	
-	if (strcmp(FILENAME_FIRMWARE, entry->name) != 0) {
-		if (!(page = (char *)__get_free_page(GFP_KERNEL))) {
-			return -ENOMEM;
-		}
-		if(copy_from_user(page, buffer, count = (min_t(int, count, PAGE_SIZE))))
-		{
-			count = -EFAULT;
-			goto out;
-		}
-		if (page[count-1] == '\n')
-			page[count-1] = '\0';
-		else if (count < PAGE_SIZE)
-			page[count] = '\0';
-		else if (page[count]) {
- 			count = -EINVAL;
-			goto out;
-		}
-		page[count]=0;	/* Null terminate */
-	} else {
-		byte *tmp;
-
-		if (!hw->firmware) {
-			if ((hw->firmware = kmalloc(sizeof(struct comx_firmware), 
-			    GFP_KERNEL)) == NULL) {
-			    	return -ENOMEM;
-			}
-			hw->firmware->len = 0;
-			hw->firmware->data = NULL;
-		}
-		
-		if ((tmp = kmalloc(count + file->f_pos, GFP_KERNEL)) == NULL) {
-			return -ENOMEM;
-		}
-		
-		/* Ha nem 0 a fpos, akkor meglevo file-t irunk. Gyenge trukk. */
-		if (hw->firmware && hw->firmware->len && file->f_pos 
-		    && hw->firmware->len < count + file->f_pos) {
-			memcpy(tmp, hw->firmware->data, hw->firmware->len);
-		}
-		if (hw->firmware->data) {
-			kfree(hw->firmware->data);
-		}
-		if (copy_from_user(tmp + file->f_pos, buffer, count))
-			return -EFAULT;
-		hw->firmware->len = entry->size = file->f_pos + count;
-		hw->firmware->data = tmp;
-		file->f_pos += count;
-		return count;
-	}
-
-	if (strcmp(entry->name, FILENAME_CHANNEL) == 0) {
-		hw->channel = simple_strtoul(page, NULL, 0);
-		if (hw->channel >= MAX_CHANNELNO) {
-			printk(KERN_ERR "Invalid channel number\n");
-			hw->channel = 0;
-		}
-		if ((ch->twin = comx_twin_check(dev)) != NULL) {
-			struct comx_channel *twin_ch = ch->twin->priv;
-			twin_ch->twin = dev;
-		}
-	} else if (strcmp(entry->name, FILENAME_IRQ) == 0) {
-		dev->irq = simple_strtoul(page, NULL, 0);
-		if (dev->irq == 2) {
-			dev->irq = 9;
-		}
-		if (dev->irq < 3 || dev->irq > 15) {
-			printk(KERN_ERR "comxhw: Invalid irq number\n");
-			dev->irq = 0;
-		}
-		if ((ch->twin = comx_twin_check(dev)) != NULL) {
-			struct comx_channel *twin_ch = ch->twin->priv;
-			twin_ch->twin = dev;
-		}
-	} else if (strcmp(entry->name, FILENAME_IO) == 0) {
-		dev->base_addr = simple_strtoul(page, NULL, 0);
-		if ((dev->base_addr & 3) != 0 || dev->base_addr < 0x300 
-		   || dev->base_addr > 0x3fc) {
-			printk(KERN_ERR "Invalid io value\n");
-			dev->base_addr = 0;
-		}
-		if ((ch->twin = comx_twin_check(dev)) != NULL) {
-			struct comx_channel *twin_ch = ch->twin->priv;
-
-			twin_ch->twin = dev;
-		}
-	} else if (strcmp(entry->name, FILENAME_MEMADDR) == 0) {
-		dev->mem_start = simple_strtoul(page, NULL, 0);
-		if (dev->mem_start <= 0xf000 && dev->mem_start >= 0xa000) {
-			dev->mem_start *= 16;
-		}
-		if ((dev->mem_start & 0xfff) != 0 || dev->mem_start < COMX_MEM_MIN
-		    || dev->mem_start + hw->memory_size > COMX_MEM_MAX) {
-			printk(KERN_ERR "Invalid memory page\n");
-			dev->mem_start = 0;
-		}
-		dev->mem_end = dev->mem_start + hw->memory_size;
-		if ((ch->twin = comx_twin_check(dev)) != NULL) {
-			struct comx_channel *twin_ch = ch->twin->priv;
-
-			twin_ch->twin = dev;
-		}
-	} else if (strcmp(entry->name, FILENAME_CLOCK) == 0) {
-		if (strncmp("ext", page, 3) == 0) {
-			hw->clock = 0;
-		} else {
-			int kbps;
-
-			kbps = simple_strtoul(page, NULL, 0);
-			hw->clock = kbps ? COMX_CLOCK_CONST/kbps : 0;
-		}
-	}
-out:
-	free_page((unsigned long)page);
-	return count;
-}
-
-static int comxhw_read_proc(char *page, char **start, off_t off, int count,
-	int *eof, void *data)
-{
-	struct proc_dir_entry *file = (struct proc_dir_entry *)data;
-	struct net_device *dev = file->parent->data;
-	struct comx_channel *ch = dev->priv;
-	struct comx_privdata *hw = ch->HW_privdata;
-	int len = 0;
-
-
-	if (strcmp(file->name, FILENAME_IO) == 0) {
-		len = sprintf(page, "0x%03x\n", (unsigned int)dev->base_addr);
-	} else if (strcmp(file->name, FILENAME_IRQ) == 0) {
-		len = sprintf(page, "0x%02x\n", dev->irq == 9 ? 2 : dev->irq);
-	} else if (strcmp(file->name, FILENAME_CHANNEL) == 0) {
-		len = sprintf(page, "%01d\n", hw->channel);
-	} else if (strcmp(file->name, FILENAME_MEMADDR) == 0) {
-		len = sprintf(page, "0x%05x\n", (unsigned int)dev->mem_start);
-	} else if (strcmp(file->name, FILENAME_TWIN) == 0) {
-		len = sprintf(page, "%s\n", ch->twin ? ch->twin->name : "none");
-	} else if (strcmp(file->name, FILENAME_CLOCK) == 0) {
-		if (hw->clock) {
-			len = sprintf(page, "%-8d\n", COMX_CLOCK_CONST/hw->clock);
-		} else {
-			len = sprintf(page, "external\n");
-		}
-	} else if (strcmp(file->name, FILENAME_FIRMWARE) == 0) {
-		len = min_t(int, FILE_PAGESIZE,
-			  min_t(int, count, 
-			      hw->firmware ?
-			      (hw->firmware->len - off) : 0));
-		if (len < 0) {
-			len = 0;
-		}
-		*start = hw->firmware ? (hw->firmware->data + off) : NULL;
-		if (off + len >= (hw->firmware ? hw->firmware->len : 0) || len == 0) {
-			*eof = 1;
-		}
-		return len;
-	}	
-
-	if (off >= len) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = page + off;
-	if (count >= len - off) {
-		*eof = 1;
-	}
-	return min_t(int, count, len - off);
-}
-
-/* Called on echo comx >boardtype */
-static int COMX_init(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct comx_privdata *hw;
-	struct proc_dir_entry *new_file;
-
-	if ((ch->HW_privdata = kmalloc(sizeof(struct comx_privdata), 
-	    GFP_KERNEL)) == NULL) {
-	    	return -ENOMEM;
-	}
-	memset(hw = ch->HW_privdata, 0, sizeof(struct comx_privdata));
-
-	if (ch->hardware == &comx_hw || ch->hardware == &cmx_hw) {
-		hw->memory_size = COMX_MEMORY_SIZE;
-		hw->io_extent = COMX_IO_EXTENT;
-		dev->base_addr = COMX_DEFAULT_IO;
-		dev->irq = COMX_DEFAULT_IRQ;
-		dev->mem_start = COMX_DEFAULT_MEMADDR;
-		dev->mem_end = COMX_DEFAULT_MEMADDR + COMX_MEMORY_SIZE;
-	} else if (ch->hardware == &hicomx_hw) {
-		hw->memory_size = HICOMX_MEMORY_SIZE;
-		hw->io_extent = HICOMX_IO_EXTENT;
-		dev->base_addr = HICOMX_DEFAULT_IO;
-		dev->irq = HICOMX_DEFAULT_IRQ;
-		dev->mem_start = HICOMX_DEFAULT_MEMADDR;
-		dev->mem_end = HICOMX_DEFAULT_MEMADDR + HICOMX_MEMORY_SIZE;
-	} else {
-		printk(KERN_ERR "SERIOUS INTERNAL ERROR in %s, line %d\n", __FILE__, __LINE__);
-	}
-
-	if ((new_file = create_proc_entry(FILENAME_IO, S_IFREG | 0644, ch->procdir))
-	    == NULL) {
-	    goto cleanup_HW_privdata;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &comxhw_read_proc;
-	new_file->write_proc = &comxhw_write_proc;
-	new_file->size = 6;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_IRQ, S_IFREG | 0644, ch->procdir))
-	    == NULL) {
-	    goto cleanup_filename_io;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &comxhw_read_proc;
-	new_file->write_proc = &comxhw_write_proc;
-	new_file->size = 5;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_CHANNEL, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-	    goto cleanup_filename_irq;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &comxhw_read_proc;
-	new_file->write_proc = &comxhw_write_proc;
-	new_file->size = 2;		// Ezt tudjuk
-	new_file->nlink = 1;
-
-	if (ch->hardware == &hicomx_hw || ch->hardware == &cmx_hw) {
-		if ((new_file = create_proc_entry(FILENAME_CLOCK, S_IFREG | 0644, 
-		   ch->procdir)) == NULL) {
-		    goto cleanup_filename_channel;
-		}
-		new_file->data = (void *)new_file;
-		new_file->read_proc = &comxhw_read_proc;
-		new_file->write_proc = &comxhw_write_proc;
-		new_file->size = 9;
-		new_file->nlink = 1;
-	}
-
-	if ((new_file = create_proc_entry(FILENAME_MEMADDR, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-		    goto cleanup_filename_clock;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &comxhw_read_proc;
-	new_file->write_proc = &comxhw_write_proc;
-	new_file->size = 8;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_TWIN, S_IFREG | 0444, 
-	    ch->procdir)) == NULL) {
-		    goto cleanup_filename_memaddr;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &comxhw_read_proc;
-	new_file->write_proc = NULL;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_FIRMWARE, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-		    goto cleanup_filename_twin;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &comxhw_read_proc;
-	new_file->write_proc = &comxhw_write_proc;
-	new_file->nlink = 1;
-
-	if (ch->hardware == &comx_hw) {
-		ch->HW_board_on = COMX_board_on;
-		ch->HW_board_off = COMX_board_off;
-		ch->HW_load_board = COMX_load_board;
-	} else if (ch->hardware == &cmx_hw) {
-		ch->HW_board_on = COMX_board_on;
-		ch->HW_board_off = COMX_board_off;
-		ch->HW_load_board = CMX_load_board;
-		ch->HW_set_clock = COMX_set_clock;
-	} else if (ch->hardware == &hicomx_hw) {
-		ch->HW_board_on = HICOMX_board_on;
-		ch->HW_board_off = HICOMX_board_off;
-		ch->HW_load_board = HICOMX_load_board;
-		ch->HW_set_clock = COMX_set_clock;
-	} else {
-		printk(KERN_ERR "SERIOUS INTERNAL ERROR in %s, line %d\n", __FILE__, __LINE__);
-	}
-
-	ch->HW_access_board = COMX_access_board;
-	ch->HW_release_board = COMX_release_board;
-	ch->HW_txe = COMX_txe;
-	ch->HW_open = COMX_open;
-	ch->HW_close = COMX_close;
-	ch->HW_send_packet = COMX_send_packet;
-	ch->HW_statistics = COMX_statistics;
-
-	if ((ch->twin = comx_twin_check(dev)) != NULL) {
-		struct comx_channel *twin_ch = ch->twin->priv;
-
-		twin_ch->twin = dev;
-	}
-
-	MOD_INC_USE_COUNT;
-	return 0;
-
-cleanup_filename_twin:
-	remove_proc_entry(FILENAME_TWIN, ch->procdir);
-cleanup_filename_memaddr:
-	remove_proc_entry(FILENAME_MEMADDR, ch->procdir);
-cleanup_filename_clock:
-	if (ch->hardware == &hicomx_hw || ch->hardware == &cmx_hw)
-		remove_proc_entry(FILENAME_CLOCK, ch->procdir);
-cleanup_filename_channel:
-	remove_proc_entry(FILENAME_CHANNEL, ch->procdir);
-cleanup_filename_irq:
-	remove_proc_entry(FILENAME_IRQ, ch->procdir);
-cleanup_filename_io:
-	remove_proc_entry(FILENAME_IO, ch->procdir);
-cleanup_HW_privdata:
-	kfree(ch->HW_privdata);
-	return -EIO;
-}
-
-/* Called on echo valami >boardtype */
-static int COMX_exit(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct comx_privdata *hw = ch->HW_privdata;
-
-	if (hw->firmware) {
-		if (hw->firmware->data) kfree(hw->firmware->data);
-		kfree(hw->firmware);
-	} if (ch->twin) {
-		struct comx_channel *twin_ch = ch->twin->priv;
-
-		twin_ch->twin = NULL;
-	}
-	
-	kfree(ch->HW_privdata);
-	remove_proc_entry(FILENAME_IO, ch->procdir);
-	remove_proc_entry(FILENAME_IRQ, ch->procdir);
-	remove_proc_entry(FILENAME_CHANNEL, ch->procdir);
-	remove_proc_entry(FILENAME_MEMADDR, ch->procdir);
-	remove_proc_entry(FILENAME_FIRMWARE, ch->procdir);
-	remove_proc_entry(FILENAME_TWIN, ch->procdir);
-	if (ch->hardware == &hicomx_hw || ch->hardware == &cmx_hw) {
-		remove_proc_entry(FILENAME_CLOCK, ch->procdir);
-	}
-
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-static int COMX_dump(struct net_device *dev)
-{
-	printk(KERN_INFO "%s: COMX_dump called, why ?\n", dev->name);
-	return 0;
-}
-
-static struct comx_hardware comx_hw = {
-	"comx",
-	VERSION,
-	COMX_init,
-	COMX_exit,
-	COMX_dump,
-	NULL
-};
-
-static struct comx_hardware cmx_hw = {
-	"cmx",
-	VERSION,
-	COMX_init,
-	COMX_exit,
-	COMX_dump,
-	NULL
-};
-
-static struct comx_hardware hicomx_hw = {
-	"hicomx",
-	VERSION,
-	COMX_init,
-	COMX_exit,
-	COMX_dump,
-	NULL
-};
-
-static int __init comx_hw_comx_init(void)
-{
-	comx_register_hardware(&comx_hw);
-	comx_register_hardware(&cmx_hw);
-	comx_register_hardware(&hicomx_hw);
-	return 0;
-}
-
-static void __exit comx_hw_comx_exit(void)
-{
-	comx_unregister_hardware("comx");
-	comx_unregister_hardware("cmx");
-	comx_unregister_hardware("hicomx");
-}
-
-module_init(comx_hw_comx_init);
-module_exit(comx_hw_comx_exit);
===== drivers/net/wan/comx-hw-locomx.c 1.10 vs edited =====
--- 1.10/drivers/net/wan/comx-hw-locomx.c	Wed Mar  3 18:42:59 2004
+++ edited/drivers/net/wan/comx-hw-locomx.c	Fri May  7 13:05:52 2004
@@ -1,496 +1 @@
-/*
- * Hardware driver for the LoCOMX card, using the generic z85230
- * functions
- *
- * Author: Gergely Madarasz <gorgo@itc.hu>
- *
- * Based on skeleton code and old LoCOMX driver by Tivadar Szemethy <tiv@itc.hu> 
- * and the hostess_sv11 driver
- *
- * Contributors:
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br> (0.14)
- *
- * Copyright (C) 1999 ITConsult-Pro Co. <info@itc.hu>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Version 0.10 (99/06/17):
- *		- rewritten for the z85230 layer
- *
- * Version 0.11 (99/06/21):
- *		- some printk's fixed
- *		- get rid of a memory leak (it was impossible though :))
- * 
- * Version 0.12 (99/07/07):
- *		- check CTS for modem lines, not DCD (which is always high
- *		  in case of this board)
- * Version 0.13 (99/07/08):
- *		- Fix the transmitter status check
- *		- Handle the net device statistics better
- * Version 0.14 (00/08/15):
- * 		- resource release on failure at LOCOMX_init
- */
 
-#define VERSION "0.14"
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-
-#include <asm/types.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include "comx.h"
-#include "z85230.h"
-
-MODULE_AUTHOR("Gergely Madarasz <gorgo@itc.hu>");
-MODULE_DESCRIPTION("Hardware driver for the LoCOMX board");
-MODULE_LICENSE("GPL");
-
-#define RX_DMA 3
-#define TX_DMA 1
-#define LOCOMX_ID 0x33
-#define LOCOMX_IO_EXTENT 8
-#define LOCOMX_DEFAULT_IO 0x368
-#define LOCOMX_DEFAULT_IRQ 7
-
-u8 z8530_locomx[] = {
-	11,     TCRTxCP,
-	14,     DTRREQ,
-	255
-};
-
-struct locomx_data {
-	int	io_extent;
-	struct	z8530_dev board;
-	struct timer_list status_timer;
-};
-
-static int LOCOMX_txe(struct net_device *dev)
-{
-	struct comx_channel *ch = netdev_priv(dev);
-	struct locomx_data *hw = ch->HW_privdata;
-
-	return (!hw->board.chanA.tx_next_skb);
-}
-
-
-static void locomx_rx(struct z8530_channel *c, struct sk_buff *skb)
-{
-	struct net_device *dev = c->netdevice;
-	struct comx_channel *ch = netdev_priv(dev);
-	
-	if (ch->debug_flags & DEBUG_HW_RX) {
-		comx_debug_skb(dev, skb, "locomx_rx receiving");
-	}
-	ch->LINE_rx(dev,skb);
-}
-
-static int LOCOMX_send_packet(struct net_device *dev, struct sk_buff *skb) 
-{
-	struct comx_channel *ch = netdev_priv(dev);
-	struct locomx_data *hw = ch->HW_privdata;
-
-	if (ch->debug_flags & DEBUG_HW_TX) {
-		comx_debug_bytes(dev, skb->data, skb->len, "LOCOMX_send_packet");
-	}
-
-	if (!(ch->line_status & LINE_UP)) {
-		return FRAME_DROPPED;
-	}
-
-	if(z8530_queue_xmit(&hw->board.chanA,skb)) {
-		printk(KERN_WARNING "%s: FRAME_DROPPED\n",dev->name);
-		return FRAME_DROPPED;
-	}
-
-	if (ch->debug_flags & DEBUG_HW_TX) {
-		comx_debug(dev, "%s: LOCOMX_send_packet was successful\n\n", dev->name);
-	}
-
-	if(!hw->board.chanA.tx_next_skb) {
-		return FRAME_QUEUED;
-	} else {
-		return FRAME_ACCEPTED;
-	}
-}
-
-static void locomx_status_timerfun(unsigned long d)
-{
-	struct net_device *dev = (struct net_device *)d;
-	struct comx_channel *ch = netdev_priv(dev);
-	struct locomx_data *hw = ch->HW_privdata;
-
-	if(!(ch->line_status & LINE_UP) &&
-	    (hw->board.chanA.status & CTS)) {
-		ch->LINE_status(dev, ch->line_status | LINE_UP);
-	}
-	if((ch->line_status & LINE_UP) &&
-	    !(hw->board.chanA.status & CTS)) {
-		ch->LINE_status(dev, ch->line_status & ~LINE_UP);
-	}
-	mod_timer(&hw->status_timer,jiffies + ch->lineup_delay * HZ);
-}
-
-
-static int LOCOMX_open(struct net_device *dev)
-{
-	struct comx_channel *ch = netdev_priv(dev);
-	struct locomx_data *hw = ch->HW_privdata;
-	struct proc_dir_entry *procfile = ch->procdir->subdir;
-	unsigned long flags;
-	int ret;
-
-	if (!dev->base_addr || !dev->irq) {
-		return -ENODEV;
-	}
-
-	if (!request_region(dev->base_addr, hw->io_extent, dev->name)) {
-		return -EAGAIN;
-	}
-
-	hw->board.chanA.ctrlio=dev->base_addr + 5;
-	hw->board.chanA.dataio=dev->base_addr + 7;
-	
-	hw->board.irq=dev->irq;
-	hw->board.chanA.netdevice=dev;
-	hw->board.chanA.dev=&hw->board;
-	hw->board.name=dev->name;
-	hw->board.chanA.txdma=TX_DMA;
-	hw->board.chanA.rxdma=RX_DMA;
-	hw->board.chanA.irqs=&z8530_nop;
-	hw->board.chanB.irqs=&z8530_nop;
-
-	if(request_irq(dev->irq, z8530_interrupt, SA_INTERRUPT, 
-	    dev->name, &hw->board)) {
-		printk(KERN_ERR "%s: unable to obtain irq %d\n", dev->name, 
-			dev->irq);
-		ret=-EAGAIN;
-		goto irq_fail;
-	}
-	if(request_dma(TX_DMA,"LoCOMX (TX)")) {
-		printk(KERN_ERR "%s: unable to obtain TX DMA (DMA channel %d)\n", 
-			dev->name, TX_DMA);
-		ret=-EAGAIN;
-		goto dma1_fail;
-	}
-
-	if(request_dma(RX_DMA,"LoCOMX (RX)")) {
-		printk(KERN_ERR "%s: unable to obtain RX DMA (DMA channel %d)\n", 
-			dev->name, RX_DMA);
-		ret=-EAGAIN;
-		goto dma2_fail;
-	}
-	
-	save_flags(flags); 
-	cli();
-
-	if(z8530_init(&hw->board)!=0)
-	{
-		printk(KERN_ERR "%s: Z8530 device not found.\n",dev->name);
-		ret=-ENODEV;
-		goto z8530_fail;
-	}
-
-	hw->board.chanA.dcdcheck=CTS;
-
-	z8530_channel_load(&hw->board.chanA, z8530_hdlc_kilostream_85230);
-	z8530_channel_load(&hw->board.chanA, z8530_locomx);
-	z8530_channel_load(&hw->board.chanB, z8530_dead_port);
-
-	z8530_describe(&hw->board, "I/O", dev->base_addr);
-
-	if((ret=z8530_sync_dma_open(dev, &hw->board.chanA))!=0) {
-		goto z8530_fail;
-	}
-
-	restore_flags(flags);
-
-
-	hw->board.active=1;
-	hw->board.chanA.rx_function=locomx_rx;
-
-	ch->init_status |= HW_OPEN;
-	if (hw->board.chanA.status & DCD) {
-		ch->line_status |= LINE_UP;
-	} else {
-		ch->line_status &= ~LINE_UP;
-	}
-
-	comx_status(dev, ch->line_status);
-
-	init_timer(&hw->status_timer);
-	hw->status_timer.function=locomx_status_timerfun;
-	hw->status_timer.data=(unsigned long)dev;
-	hw->status_timer.expires=jiffies + ch->lineup_delay * HZ;
-	add_timer(&hw->status_timer);
-
-	for (; procfile ; procfile = procfile->next) {
-		if (strcmp(procfile->name, FILENAME_IO) == 0 ||
-		     strcmp(procfile->name, FILENAME_IRQ) == 0) {
-			procfile->mode = S_IFREG |  0444;
-		}
-	}
-	return 0;
-
-z8530_fail:
-	restore_flags(flags);
-	free_dma(RX_DMA);
-dma2_fail:
-	free_dma(TX_DMA);
-dma1_fail:
-	free_irq(dev->irq, &hw->board);
-irq_fail:
-	release_region(dev->base_addr, hw->io_extent);
-	return ret;
-}
-
-static int LOCOMX_close(struct net_device *dev)
-{
-	struct comx_channel *ch = netdev_priv(dev);
-	struct locomx_data *hw = ch->HW_privdata;
-	struct proc_dir_entry *procfile = ch->procdir->subdir;
-
-	hw->board.chanA.rx_function=z8530_null_rx;
-	netif_stop_queue(dev);
-	z8530_sync_dma_close(dev, &hw->board.chanA);
-
-	z8530_shutdown(&hw->board);
-
-	del_timer(&hw->status_timer);
-	free_dma(RX_DMA);
-	free_dma(TX_DMA);
-	free_irq(dev->irq,&hw->board);
-	release_region(dev->base_addr,8);
-
-	for (; procfile ; procfile = procfile->next) {
-		if (strcmp(procfile->name, FILENAME_IO) == 0 ||
-		    strcmp(procfile->name, FILENAME_IRQ) == 0) {
-			procfile->mode = S_IFREG |  0644;
-		}
-	}
-
-	ch->init_status &= ~HW_OPEN;
-	return 0;
-}
-
-static int LOCOMX_statistics(struct net_device *dev,char *page)
-{
-	int len = 0;
-
-	len += sprintf(page + len, "Hello\n");
-
-	return len;
-}
-
-static int LOCOMX_dump(struct net_device *dev) {
-	printk(KERN_INFO "LOCOMX_dump called\n");
-	return(-1);
-}
-
-static int locomx_read_proc(char *page, char **start, off_t off, int count,
-	int *eof, void *data)
-{
-	struct proc_dir_entry *file = (struct proc_dir_entry *)data;
-	struct net_device *dev = file->parent->data;
-	int len = 0;
-
-	if (strcmp(file->name, FILENAME_IO) == 0) {
-		len = sprintf(page, "0x%x\n", (unsigned int)dev->base_addr);
-	} else if (strcmp(file->name, FILENAME_IRQ) == 0) {
-		len = sprintf(page, "%d\n", (unsigned int)dev->irq);
-	} else {
-		printk(KERN_ERR "hw_read_proc: internal error, filename %s\n", 
-			file->name);
-		return -EBADF;
-	}
-
-	if (off >= len) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = page + off;
-	if (count >= len - off) {
-		*eof = 1;
-	}
-	return min_t(int, count, len - off);
-}
-
-static int locomx_write_proc(struct file *file, const char *buffer,
-	u_long count, void *data)
-{
-	struct proc_dir_entry *entry = (struct proc_dir_entry *)data;
-	struct net_device *dev = (struct net_device *)entry->parent->data;
-	int val;
-	char *page;
-
-	if (!(page = (char *)__get_free_page(GFP_KERNEL))) {
-		return -ENOMEM;
-	}
-
-	if (copy_from_user(page, buffer, count = min_t(unsigned long, count, PAGE_SIZE))) {
-		free_page((unsigned long)page);
-		return -EBADF;
-	}
-	if (*(page + count - 1) == '\n') {
-		*(page + count - 1) = 0;
-	}
-
-	if (strcmp(entry->name, FILENAME_IO) == 0) {
-		val = simple_strtoul(page, NULL, 0);
-		if (val != 0x360 && val != 0x368 && val != 0x370 && 
-		   val != 0x378) {
-			printk(KERN_ERR "LoCOMX: incorrect io address!\n");	
-		} else {
-			dev->base_addr = val;
-		}
-	} else if (strcmp(entry->name, FILENAME_IRQ) == 0) {
-		val = simple_strtoul(page, NULL, 0);
-		if (val != 3 && val != 4 && val != 5 && val != 6 && val != 7) {
-			printk(KERN_ERR "LoCOMX: incorrect irq value!\n");
-		} else {
-			dev->irq = val;
-		}	
-	} else {
-		printk(KERN_ERR "locomx_write_proc: internal error, filename %s\n", 
-			entry->name);
-		free_page((unsigned long)page);
-		return -EBADF;
-	}
-
-	free_page((unsigned long)page);
-	return count;
-}
-
-
-
-static int LOCOMX_init(struct net_device *dev) 
-{
-	struct comx_channel *ch = netdev_priv(dev);
-	struct locomx_data *hw;
-	struct proc_dir_entry *new_file;
-
-	/* Alloc data for private structure */
-	if ((ch->HW_privdata = kmalloc(sizeof(struct locomx_data), 
-	   GFP_KERNEL)) == NULL) {
-	   	return -ENOMEM;
-	}
-
-	memset(hw = ch->HW_privdata, 0, sizeof(struct locomx_data));
-	hw->io_extent = LOCOMX_IO_EXTENT;
-
-	/* Register /proc files */
-	if ((new_file = create_proc_entry(FILENAME_IO, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-		goto cleanup_HW_privdata;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &locomx_read_proc;
-	new_file->write_proc = &locomx_write_proc;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_IRQ, S_IFREG | 0644, 
-	    ch->procdir)) == NULL)  {
-		goto cleanup_filename_io;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &locomx_read_proc;
-	new_file->write_proc = &locomx_write_proc;
-	new_file->nlink = 1;
-
-/* 	No clock yet */
-/*
-	if ((new_file = create_proc_entry(FILENAME_CLOCK, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-		return -EIO;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &locomx_read_proc;
-	new_file->write_proc = &locomx_write_proc;
-	new_file->nlink = 1;
-*/
-
-	ch->HW_access_board = NULL;
-	ch->HW_release_board = NULL;
-	ch->HW_txe = LOCOMX_txe;
-	ch->HW_open = LOCOMX_open;
-	ch->HW_close = LOCOMX_close;
-	ch->HW_send_packet = LOCOMX_send_packet;
-	ch->HW_statistics = LOCOMX_statistics;
-	ch->HW_set_clock = NULL;
-
-	ch->current_stats = &hw->board.chanA.stats;
-	memcpy(ch->current_stats, &ch->stats, sizeof(struct net_device_stats));
-
-	dev->base_addr = LOCOMX_DEFAULT_IO;
-	dev->irq = LOCOMX_DEFAULT_IRQ;
-	
-	
-	/* O.K. Count one more user on this module */
-	MOD_INC_USE_COUNT;
-	return 0;
-cleanup_filename_io:
-	remove_proc_entry(FILENAME_IO, ch->procdir);
-cleanup_HW_privdata:
-	kfree(ch->HW_privdata);
-	return -EIO;
-}
-
-
-static int LOCOMX_exit(struct net_device *dev)
-{
-	struct comx_channel *ch = netdev_priv(dev);
-
-	ch->HW_access_board = NULL;
-	ch->HW_release_board = NULL;
-	ch->HW_txe = NULL;
-	ch->HW_open = NULL;
-	ch->HW_close = NULL;
-	ch->HW_send_packet = NULL;
-	ch->HW_statistics = NULL;
-	ch->HW_set_clock = NULL;
-	memcpy(&ch->stats, ch->current_stats, sizeof(struct net_device_stats));
-	ch->current_stats = &ch->stats;
-
-	kfree(ch->HW_privdata);
-
-	remove_proc_entry(FILENAME_IO, ch->procdir);
-	remove_proc_entry(FILENAME_IRQ, ch->procdir);
-//	remove_proc_entry(FILENAME_CLOCK, ch->procdir);
-
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-static struct comx_hardware locomx_hw = {
-	"locomx",
-	VERSION,
-	LOCOMX_init, 
-	LOCOMX_exit,
-	LOCOMX_dump,
-	NULL
-};
-	
-static int __init comx_hw_locomx_init(void)
-{
-	comx_register_hardware(&locomx_hw);
-	return 0;
-}
-
-static void __exit comx_hw_locomx_exit(void)
-{
-	comx_unregister_hardware("locomx");
-}
-
-module_init(comx_hw_locomx_init);
-module_exit(comx_hw_locomx_exit);
===== drivers/net/wan/comx-hw-mixcom.c 1.12 vs edited =====
--- 1.12/drivers/net/wan/comx-hw-mixcom.c	Thu Sep 11 19:40:53 2003
+++ edited/drivers/net/wan/comx-hw-mixcom.c	Fri May  7 13:05:52 2004
@@ -1,960 +1 @@
-/* 
- * Hardware driver for the MixCom synchronous serial board 
- *
- * Author: Gergely Madarasz <gorgo@itc.hu>
- *
- * based on skeleton driver code and a preliminary hscx driver by 
- * Tivadar Szemethy <tiv@itc.hu>
- *
- * Copyright (C) 1998-1999 ITConsult-Pro Co. <info@itc.hu>
- *
- * Contributors:
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br> (0.65)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Version 0.60 (99/06/11):
- *		- ported to the kernel, now works as builtin code
- *
- * Version 0.61 (99/06/11):
- *		- recognize the one-channel MixCOM card (id byte = 0x13)
- *		- printk fixes
- * 
- * Version 0.62 (99/07/15):
- *		- fixes according to the new hw docs 
- *		- report line status when open
- *
- * Version 0.63 (99/09/21):
- *		- line status report fixes
- *
- * Version 0.64 (99/12/01):
- *		- some more cosmetical fixes
- *
- * Version 0.65 (00/08/15)
- *		- resource release on failure at MIXCOM_init
- */
 
-#define VERSION "0.65"
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-
-#include <asm/types.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#include "comx.h"
-#include "mixcom.h"
-#include "hscx.h"
-
-MODULE_AUTHOR("Gergely Madarasz <gorgo@itc.hu>");
-MODULE_DESCRIPTION("Hardware-level driver for the serial port of the MixCom board");
-MODULE_LICENSE("GPL");
-
-#define MIXCOM_DATA(d) ((struct mixcom_privdata *)(COMX_CHANNEL(d)-> \
-	HW_privdata))
-
-#define MIXCOM_BOARD_BASE(d) (d->base_addr - MIXCOM_SERIAL_OFFSET - \
-	(1 - MIXCOM_DATA(d)->channel) * MIXCOM_CHANNEL_OFFSET)
-
-#define MIXCOM_DEV_BASE(port,channel) (port + MIXCOM_SERIAL_OFFSET + \
-	(1 - channel) * MIXCOM_CHANNEL_OFFSET)
-
-/* Values used to set the IRQ line */
-static unsigned char mixcom_set_irq[]={0xFF, 0xFF, 0xFF, 0x0, 0xFF, 0x2, 0x4, 0x6, 0xFF, 0xFF, 0x8, 0xA, 0xC, 0xFF, 0xE, 0xFF};
-
-static unsigned char* hscx_versions[]={"A1", NULL, "A2", NULL, "A3", "2.1"};
-
-struct mixcom_privdata {
-	u16	clock;
-	char	channel;
-	long	txbusy;
-	struct sk_buff *sending;
-	unsigned tx_ptr;
-	struct sk_buff *recving;
-	unsigned rx_ptr;
-	unsigned char status;
-	char	card_has_status;
-};
-
-static inline void wr_hscx(struct net_device *dev, int reg, unsigned char val) 
-{
-	outb(val, dev->base_addr + reg);
-}
-
-static inline unsigned char rd_hscx(struct net_device *dev, int reg)
-{
-	return inb(dev->base_addr + reg);
-}
-
-static inline void hscx_cmd(struct net_device *dev, int cmd)
-{
-	unsigned long jiffs = jiffies;
-	unsigned char cec;
-	unsigned delay = 0;
-
-	while ((cec = (rd_hscx(dev, HSCX_STAR) & HSCX_CEC) != 0) && 
-	    time_before(jiffies, jiffs + HZ)) {
-		udelay(1);
-		if (++delay > (100000 / HZ)) break;
-	}
-	if (cec) {
-		printk(KERN_WARNING "%s: CEC stuck, probably no clock!\n",dev->name);
-	} else {
-		wr_hscx(dev, HSCX_CMDR, cmd);
-	}
-}
-
-static inline void hscx_fill_fifo(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct mixcom_privdata *hw = ch->HW_privdata;
-	register word to_send = hw->sending->len - hw->tx_ptr;
-
-
-	outsb(dev->base_addr + HSCX_FIFO,
-        	&(hw->sending->data[hw->tx_ptr]), min_t(unsigned int, to_send, 32));
-	if (to_send <= 32) {
-        	hscx_cmd(dev, HSCX_XTF | HSCX_XME);
-	        kfree_skb(hw->sending);
-        	hw->sending = NULL; 
-        	hw->tx_ptr = 0;
-        } else {
-	        hscx_cmd(dev, HSCX_XTF);
-        	hw->tx_ptr += 32;
-        }
-}
-
-static inline void hscx_empty_fifo(struct net_device *dev, int cnt)
-{
-	struct comx_channel *ch = dev->priv;
-	struct mixcom_privdata *hw = ch->HW_privdata;
-
-	if (hw->recving == NULL) {
-        	if (!(hw->recving = dev_alloc_skb(HSCX_MTU + 16))) {
-	                ch->stats.rx_dropped++;
-        	        hscx_cmd(dev, HSCX_RHR);
-                } else {
-	                skb_reserve(hw->recving, 16);
-        	        skb_put(hw->recving, HSCX_MTU);
-                }
-	        hw->rx_ptr = 0;
-        }
-	if (cnt > 32 || !cnt || hw->recving == NULL) {
-        	printk(KERN_ERR "hscx_empty_fifo: cnt is %d, hw->recving %p\n",
-		        cnt, (void *)hw->recving);
-	        return;
-        }
-        
-	insb(dev->base_addr + HSCX_FIFO, &(hw->recving->data[hw->rx_ptr]),cnt);
-	hw->rx_ptr += cnt;
-	hscx_cmd(dev, HSCX_RMC);
-}
-
-
-static int MIXCOM_txe(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct mixcom_privdata *hw = ch->HW_privdata;
-
-	return !test_bit(0, &hw->txbusy);
-}
-
-static int mixcom_probe(struct net_device *dev)
-{
-	unsigned long flags;
-	int id, vstr, ret=0;
-
-	save_flags(flags); cli();
-
-	id=inb_p(MIXCOM_BOARD_BASE(dev) + MIXCOM_ID_OFFSET) & 0x7f;
-
- 	if (id != MIXCOM_ID ) {
-		ret=-ENODEV;
-		printk(KERN_WARNING "%s: no MixCOM board found at 0x%04lx\n",dev->name, dev->base_addr);
-		goto out;
-	}
-
-	vstr=inb_p(dev->base_addr + HSCX_VSTR) & 0x0f;
-	if(vstr>=sizeof(hscx_versions)/sizeof(char*) || 
-	    hscx_versions[vstr]==NULL) {
-		printk(KERN_WARNING "%s: board found but no HSCX chip detected at 0x%4lx (vstr = 0x%1x)\n",dev->name,dev->base_addr,vstr);
-		ret = -ENODEV;
-	} else {
-		printk(KERN_INFO "%s: HSCX chip version %s\n",dev->name,hscx_versions[vstr]);
-		ret = 0;
-	}
-
-out:
-
-	restore_flags(flags);
-	return ret;
-}
-
-#if 0
-static void MIXCOM_set_clock(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct mixcom_privdata *hw = ch->HW_privdata;
-
-	if (hw->clock) {
-		;
-	} else {
-		;
-	}
-}
-#endif
-
-static void mixcom_board_on(struct net_device *dev)
-{
-	outb_p(MIXCOM_OFF , MIXCOM_BOARD_BASE(dev) + MIXCOM_IT_OFFSET);
-	udelay(1000);
-	outb_p(mixcom_set_irq[dev->irq] | MIXCOM_ON, 
-		MIXCOM_BOARD_BASE(dev) + MIXCOM_IT_OFFSET);
-	udelay(1000);
-}
-
-static void mixcom_board_off(struct net_device *dev)
-{
-	outb_p(MIXCOM_OFF , MIXCOM_BOARD_BASE(dev) + MIXCOM_IT_OFFSET);
-	udelay(1000);
-}
-
-static void mixcom_off(struct net_device *dev)
-{
-	wr_hscx(dev, HSCX_CCR1, 0x0);
-}
-
-static void mixcom_on(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-
-	wr_hscx(dev, HSCX_CCR1, HSCX_PU | HSCX_ODS | HSCX_ITF); // power up, push-pull
-	wr_hscx(dev, HSCX_CCR2, HSCX_CIE /* | HSCX_RIE */ );
-	wr_hscx(dev, HSCX_MODE, HSCX_TRANS | HSCX_ADM8 | HSCX_RAC | HSCX_RTS );
-	wr_hscx(dev, HSCX_RLCR, HSCX_RC | 47); // 1504 bytes
-	wr_hscx(dev, HSCX_MASK, HSCX_RSC | HSCX_TIN );
-	hscx_cmd(dev, HSCX_XRES | HSCX_RHR);
-
-	if (ch->HW_set_clock) ch->HW_set_clock(dev);
-
-}
-
-static int MIXCOM_send_packet(struct net_device *dev, struct sk_buff *skb) 
-{
-	struct comx_channel *ch = dev->priv;
-	struct mixcom_privdata *hw = ch->HW_privdata;
-	unsigned long flags;
-
-	if (ch->debug_flags & DEBUG_HW_TX) {
-		comx_debug_bytes(dev, skb->data, skb->len, "MIXCOM_send_packet");
-	}
-
-	if (!(ch->line_status & LINE_UP)) {
-		return FRAME_DROPPED;
-	}
-
-	if (skb->len > HSCX_MTU) {
-		ch->stats.tx_errors++;	
-		return FRAME_ERROR;
-	}
-
-	save_flags(flags); cli();
-
-	if (test_and_set_bit(0, &hw->txbusy)) {
-		printk(KERN_ERR "%s: transmitter called while busy... dropping frame (length %d)\n", dev->name, skb->len);
-		restore_flags(flags);
-		return FRAME_DROPPED;
-	}
-
-
-	hw->sending = skb;
-	hw->tx_ptr = 0;
-	hw->txbusy = 1;
-//	atomic_inc(&skb->users);	// save it
-	hscx_fill_fifo(dev);
-	restore_flags(flags);
-
-	ch->stats.tx_packets++;
-	ch->stats.tx_bytes += skb->len; 
-
-	if (ch->debug_flags & DEBUG_HW_TX) {
-		comx_debug(dev, "MIXCOM_send_packet was successful\n\n");
-	}
-
-	return FRAME_ACCEPTED;
-}
-
-static inline void mixcom_receive_frame(struct net_device *dev) 
-{
-	struct comx_channel *ch=dev->priv;
-	struct mixcom_privdata *hw=ch->HW_privdata;
-	register byte rsta;
-	register word length;
-
-	rsta = rd_hscx(dev, HSCX_RSTA) & (HSCX_VFR | HSCX_RDO | 
-		HSCX_CRC | HSCX_RAB);
-	length = ((rd_hscx(dev, HSCX_RBCH) & 0x0f) << 8) | 
-		rd_hscx(dev, HSCX_RBCL);
-
-	if ( length > hw->rx_ptr ) {
-		hscx_empty_fifo(dev, length - hw->rx_ptr);
-	}
-	
-	if (!(rsta & HSCX_VFR)) {
-		ch->stats.rx_length_errors++;
-	}
-	if (rsta & HSCX_RDO) {
-		ch->stats.rx_over_errors++;
-	}
-	if (!(rsta & HSCX_CRC)) {
-		ch->stats.rx_crc_errors++;
-	}
-	if (rsta & HSCX_RAB) {
-		ch->stats.rx_frame_errors++;
-	}
-	ch->stats.rx_packets++; 
-	ch->stats.rx_bytes += length;
-
-	if (rsta == (HSCX_VFR | HSCX_CRC) && hw->recving) {
-		skb_trim(hw->recving, hw->rx_ptr - 1);
-		if (ch->debug_flags & DEBUG_HW_RX) {
-			comx_debug_skb(dev, hw->recving,
-				"MIXCOM_interrupt receiving");
-		}
-		hw->recving->dev = dev;
-		if (ch->LINE_rx) {
-			ch->LINE_rx(dev, hw->recving);
-		}
-	}
-	else if(hw->recving) {
-		kfree_skb(hw->recving);
-	}
-	hw->recving = NULL; 
-	hw->rx_ptr = 0;
-}
-
-
-static inline void mixcom_extended_interrupt(struct net_device *dev) 
-{
-	struct comx_channel *ch=dev->priv;
-	struct mixcom_privdata *hw=ch->HW_privdata;
-	register byte exir;
-
-	exir = rd_hscx(dev, HSCX_EXIR) & (HSCX_XDU | HSCX_RFO | HSCX_CSC );
-
-	if (exir & HSCX_RFO) {
-		ch->stats.rx_over_errors++;
-		if (hw->rx_ptr) {
-			kfree_skb(hw->recving);
-			hw->recving = NULL; hw->rx_ptr = 0;
-		}
-		printk(KERN_ERR "MIXCOM: rx overrun\n");
-		hscx_cmd(dev, HSCX_RHR);
-	}
-
-	if (exir & HSCX_XDU) { // xmit underrun
-		ch->stats.tx_errors++;
-		ch->stats.tx_aborted_errors++;
-		if (hw->tx_ptr) {
-			kfree_skb(hw->sending);
-			hw->sending = NULL; 
-			hw->tx_ptr = 0;
-		}
-		hscx_cmd(dev, HSCX_XRES);
-		clear_bit(0, &hw->txbusy);
-		if (ch->LINE_tx) {
-			ch->LINE_tx(dev);
-		}
-		printk(KERN_ERR "MIXCOM: tx underrun\n");
-	}
-
-	if (exir & HSCX_CSC) {        
-		ch->stats.tx_carrier_errors++;
-		if ((rd_hscx(dev, HSCX_STAR) & HSCX_CTS) == 0) { // Vonal le
-			if (test_and_clear_bit(0, &ch->lineup_pending)) {
-               			del_timer(&ch->lineup_timer);
-			} else if (ch->line_status & LINE_UP) {
-        		       	ch->line_status &= ~LINE_UP;
-                		if (ch->LINE_status) {
-                      			ch->LINE_status(dev,ch->line_status);
-                      		}
-		      	}
-		}
-		if (!(ch->line_status & LINE_UP) && (rd_hscx(dev, HSCX_STAR) & 
-		    HSCX_CTS)) { // Vonal fol
-			if (!test_and_set_bit(0,&ch->lineup_pending)) {
-				ch->lineup_timer.function = comx_lineup_func;
-	        	        ch->lineup_timer.data = (unsigned long)dev;
-        	        	ch->lineup_timer.expires = jiffies + HZ * 
-        	        		ch->lineup_delay;
-	                	add_timer(&ch->lineup_timer);
-		                hscx_cmd(dev, HSCX_XRES);
-        		        clear_bit(0, &hw->txbusy);
-                		if (hw->sending) {
-					kfree_skb(hw->sending);
-				}
-				hw->sending=NULL;
-				hw->tx_ptr = 0;
-			}
-		}
-	}
-}
-
-
-static irqreturn_t MIXCOM_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	unsigned long flags;
-	struct net_device *dev = (struct net_device *)dev_id;
-	struct comx_channel *ch, *twin_ch;
-	struct mixcom_privdata *hw, *twin_hw;
-	register unsigned char ista;
-
-	if (dev==NULL) {
-		printk(KERN_ERR "comx_interrupt: irq %d for unknown device\n",irq);
-		return IRQ_NONE;
-	}
-
-	ch = dev->priv; 
-	hw = ch->HW_privdata;
-
-	save_flags(flags); cli(); 
-
-	while((ista = (rd_hscx(dev, HSCX_ISTA) & (HSCX_RME | HSCX_RPF | 
-	    HSCX_XPR | HSCX_EXB | HSCX_EXA | HSCX_ICA)))) {
-		register byte ista2 = 0;
-
-		if (ista & HSCX_RME) {
-			mixcom_receive_frame(dev);
-		}
-		if (ista & HSCX_RPF) {
-			hscx_empty_fifo(dev, 32);
-		}
-		if (ista & HSCX_XPR) {
-			if (hw->tx_ptr) {
-				hscx_fill_fifo(dev);
-			} else {
-				clear_bit(0, &hw->txbusy);
-               			ch->LINE_tx(dev);
-			}
-		}
-		
-		if (ista & HSCX_EXB) {
-			mixcom_extended_interrupt(dev);
-		}
-		
-		if ((ista & HSCX_EXA) && ch->twin)  {
-			mixcom_extended_interrupt(ch->twin);
-		}
-	
-		if ((ista & HSCX_ICA) && ch->twin &&
-		    (ista2 = rd_hscx(ch->twin, HSCX_ISTA) &
-		    (HSCX_RME | HSCX_RPF | HSCX_XPR ))) {
-			if (ista2 & HSCX_RME) {
-				mixcom_receive_frame(ch->twin);
-			}
-			if (ista2 & HSCX_RPF) {
-				hscx_empty_fifo(ch->twin, 32);
-			}
-			if (ista2 & HSCX_XPR) {
-				twin_ch=ch->twin->priv;
-				twin_hw=twin_ch->HW_privdata;
-				if (twin_hw->tx_ptr) {
-					hscx_fill_fifo(ch->twin);
-				} else {
-					clear_bit(0, &twin_hw->txbusy);
-					ch->LINE_tx(ch->twin);
-				}
-			}
-		}
-	}
-
-	restore_flags(flags);
-	return IRQ_HANDLED;
-}
-
-static int MIXCOM_open(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct mixcom_privdata *hw = ch->HW_privdata;
-	struct proc_dir_entry *procfile = ch->procdir->subdir;
-	unsigned long flags; 
-	int ret = -ENODEV;
-
-	if (!dev->base_addr || !dev->irq)
-		goto err_ret;
-
-
-	if(hw->channel==1) {
-		if(!TWIN(dev) || !(COMX_CHANNEL(TWIN(dev))->init_status & 
-		    IRQ_ALLOCATED)) {
-			printk(KERN_ERR "%s: channel 0 not yet initialized\n",dev->name);
-			ret = -EAGAIN;
-			goto err_ret;
-		}
-	}
-
-
-	/* Is our hw present at all ? Not checking for channel 0 if it is already 
-	   open */
-	if(hw->channel!=0 || !(ch->init_status & IRQ_ALLOCATED)) {
-		if (!request_region(dev->base_addr, MIXCOM_IO_EXTENT, dev->name)) {
-			ret = -EAGAIN;
-			goto err_ret;
-		}
-		if (mixcom_probe(dev)) {
-			ret = -ENODEV;
-			goto err_release_region;
-		}
-	}
-
-	if(hw->channel==0 && !(ch->init_status & IRQ_ALLOCATED)) {
-		if (request_irq(dev->irq, MIXCOM_interrupt, 0, 
-		    dev->name, (void *)dev)) {
-			printk(KERN_ERR "MIXCOM: unable to obtain irq %d\n", dev->irq);
-			ret = -EAGAIN;
-			goto err_release_region;
-		}
-	}
-
-	save_flags(flags); cli();
-
-	if(hw->channel==0 && !(ch->init_status & IRQ_ALLOCATED)) {
-		ch->init_status|=IRQ_ALLOCATED;
-		mixcom_board_on(dev);
-	}
-
-	mixcom_on(dev);
-
-
-	hw->status=inb(MIXCOM_BOARD_BASE(dev) + MIXCOM_STATUS_OFFSET);
-	if(hw->status != 0xff) {
-		printk(KERN_DEBUG "%s: board has status register, good\n", dev->name);
-		hw->card_has_status=1;
-	}
-
-	hw->txbusy = 0;
-	ch->init_status |= HW_OPEN;
-	
-	if (rd_hscx(dev, HSCX_STAR) & HSCX_CTS) {
-		ch->line_status |= LINE_UP;
-	} else {
-		ch->line_status &= ~LINE_UP;
-	}
-
-	restore_flags(flags);
-
-	ch->LINE_status(dev, ch->line_status);
-
-	for (; procfile ; procfile = procfile->next) {
-		if (strcmp(procfile->name, FILENAME_IO) == 0 ||
-		    strcmp(procfile->name, FILENAME_CHANNEL) == 0 ||
-		    strcmp(procfile->name, FILENAME_CLOCK) == 0 ||
-		    strcmp(procfile->name, FILENAME_IRQ) == 0) {
-			procfile->mode = S_IFREG |  0444;
-		}
-	}
-
-	return 0;
-	
-err_release_region:
-	release_region(dev->base_addr, MIXCOM_IO_EXTENT);
-err_ret:
-	return ret;
-}
-
-static int MIXCOM_close(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct mixcom_privdata *hw = ch->HW_privdata;
-	struct proc_dir_entry *procfile = ch->procdir->subdir;
-	unsigned long flags;
-
-
-	save_flags(flags); cli();
-
-	mixcom_off(dev);
-
-	/* This is channel 0, twin is not open, we can safely turn off everything */
-	if(hw->channel==0 && (!(TWIN(dev)) || 
-	    !(COMX_CHANNEL(TWIN(dev))->init_status & HW_OPEN))) {
-		mixcom_board_off(dev);
-		free_irq(dev->irq, dev);
-		release_region(dev->base_addr, MIXCOM_IO_EXTENT);
-		ch->init_status &= ~IRQ_ALLOCATED;
-	}
-
-	/* This is channel 1, channel 0 has already been shutdown, we can release
-	   this one too */
-	if(hw->channel==1 && !(COMX_CHANNEL(TWIN(dev))->init_status & HW_OPEN)) {
-		if(COMX_CHANNEL(TWIN(dev))->init_status & IRQ_ALLOCATED) {
-			mixcom_board_off(TWIN(dev));
-			free_irq(TWIN(dev)->irq, TWIN(dev));
-			release_region(TWIN(dev)->base_addr, MIXCOM_IO_EXTENT);
-			COMX_CHANNEL(TWIN(dev))->init_status &= ~IRQ_ALLOCATED;
-		}
-	}
-
-	/* the ioports for channel 1 can be safely released */
-	if(hw->channel==1) {
-		release_region(dev->base_addr, MIXCOM_IO_EXTENT);
-	}
-
-	restore_flags(flags);
-
-	/* If we don't hold any hardware open */
-	if(!(ch->init_status & IRQ_ALLOCATED)) {
-		for (; procfile ; procfile = procfile->next) {
-			if (strcmp(procfile->name, FILENAME_IO) == 0 ||
-			    strcmp(procfile->name, FILENAME_CHANNEL) == 0 ||
-			    strcmp(procfile->name, FILENAME_CLOCK) == 0 ||
-			    strcmp(procfile->name, FILENAME_IRQ) == 0) {
-				procfile->mode = S_IFREG |  0644;
-			}
-		}
-	}
-
-	/* channel 0 was only waiting for us to close channel 1 
-	   close it completely */
-   
-	if(hw->channel==1 && !(COMX_CHANNEL(TWIN(dev))->init_status & HW_OPEN)) {
-		for (procfile=COMX_CHANNEL(TWIN(dev))->procdir->subdir; 
-		    procfile ; procfile = procfile->next) {
-			if (strcmp(procfile->name, FILENAME_IO) == 0 ||
-			    strcmp(procfile->name, FILENAME_CHANNEL) == 0 ||
-			    strcmp(procfile->name, FILENAME_CLOCK) == 0 ||
-			    strcmp(procfile->name, FILENAME_IRQ) == 0) {
-				procfile->mode = S_IFREG |  0644;
-			}
-		}
-	}
-	
-	ch->init_status &= ~HW_OPEN;
-	return 0;
-}
-
-static int MIXCOM_statistics(struct net_device *dev,char *page)
-{
-	struct comx_channel *ch = dev->priv;
-	// struct mixcom_privdata *hw = ch->HW_privdata;
-	int len = 0;
-
-	if(ch->init_status && IRQ_ALLOCATED) {
-		len += sprintf(page + len, "Mixcom board: hardware open\n");
-	}
-
-	return len;
-}
-
-static int MIXCOM_dump(struct net_device *dev) {
-	return 0;
-}
-
-static int mixcom_read_proc(char *page, char **start, off_t off, int count,
-	int *eof, void *data)
-{
-	struct proc_dir_entry *file = (struct proc_dir_entry *)data;
-	struct net_device *dev = file->parent->data;
-	struct comx_channel *ch = dev->priv;
-	struct mixcom_privdata *hw = ch->HW_privdata;
-	int len = 0;
-
-	if (strcmp(file->name, FILENAME_IO) == 0) {
-		len = sprintf(page, "0x%x\n", 
-			(unsigned int)MIXCOM_BOARD_BASE(dev));
-	} else if (strcmp(file->name, FILENAME_IRQ) == 0) {
-		len = sprintf(page, "%d\n", (unsigned int)dev->irq);
-	} else if (strcmp(file->name, FILENAME_CLOCK) == 0) {
-		if (hw->clock) len = sprintf(page, "%d\n", hw->clock);
-			else len = sprintf(page, "external\n");
-	} else if (strcmp(file->name, FILENAME_CHANNEL) == 0) {
-		len = sprintf(page, "%01d\n", hw->channel);
-	} else if (strcmp(file->name, FILENAME_TWIN) == 0) {
-		if (ch->twin) {
-			len = sprintf(page, "%s\n",ch->twin->name);
-		} else {
-			len = sprintf(page, "none\n");
-		}
-	} else {
-		printk(KERN_ERR "mixcom_read_proc: internal error, filename %s\n", file->name);
-		return -EBADF;
-	}
-
-	if (off >= len) {
-		*eof = 1;
-		return 0;
-	}
-	*start = page + off;
-	if (count >= len - off) *eof = 1;
-	return min_t(int, count, len - off);
-}
-
-
-static struct net_device *mixcom_twin_check(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct proc_dir_entry *procfile = ch->procdir->parent->subdir;
-	struct mixcom_privdata *hw = ch->HW_privdata;
-
-	struct net_device *twin;
-	struct comx_channel *ch_twin;
-	struct mixcom_privdata *hw_twin;
-
-
-	for ( ; procfile ; procfile = procfile->next) {
-		if(!S_ISDIR(procfile->mode)) continue;
-                
-        	twin = procfile->data;
-	        ch_twin = twin->priv;
-        	hw_twin = ch_twin->HW_privdata;
-
-
-	        if (twin != dev && dev->irq && dev->base_addr && 
-        	    dev->irq == twin->irq && 
-        	    ch->hardware == ch_twin->hardware &&
-		    dev->base_addr == twin->base_addr + 
-		    (1-2*hw->channel)*MIXCOM_CHANNEL_OFFSET &&
-		    hw->channel == (1 - hw_twin->channel)) {
-	        	if  (!TWIN(twin) || TWIN(twin)==dev) {
-	        		return twin;
-	        	}
-		}
-        }
-	return NULL;
-}
-
-
-static void setup_twin(struct net_device* dev) 
-{
-
-	if(TWIN(dev) && TWIN(TWIN(dev))) {
-		TWIN(TWIN(dev))=NULL;
-	}
-	if ((TWIN(dev) = mixcom_twin_check(dev)) != NULL) {
-		if (TWIN(TWIN(dev)) && TWIN(TWIN(dev)) != dev) {
-			TWIN(dev)=NULL;
-		} else {
-			TWIN(TWIN(dev))=dev;
-		}
-	}	
-}
-
-static int mixcom_write_proc(struct file *file, const char *buffer,
-	u_long count, void *data)
-{
-	struct proc_dir_entry *entry = (struct proc_dir_entry *)data;
-	struct net_device *dev = (struct net_device *)entry->parent->data;
-	struct comx_channel *ch = dev->priv;
-	struct mixcom_privdata *hw = ch->HW_privdata;
-	char *page;
-	int value;
-
-	if (!(page = (char *)__get_free_page(GFP_KERNEL))) {
-		return -ENOMEM;
-	}
-
-	if (copy_from_user(page, buffer, count = min_t(unsigned long, count, PAGE_SIZE))) {
-		free_page((unsigned long)page);
-		return -EFAULT;
-	}
-	if (*(page + count - 1) == '\n') {
-		*(page + count - 1) = 0;
-	}
-
-	if (strcmp(entry->name, FILENAME_IO) == 0) {
-		value = simple_strtoul(page, NULL, 0);
-		if (value != 0x180 && value != 0x280 && value != 0x380) {
-			printk(KERN_ERR "MIXCOM: incorrect io address!\n");
-		} else {
-			dev->base_addr = MIXCOM_DEV_BASE(value,hw->channel);
-		}
-	} else if (strcmp(entry->name, FILENAME_IRQ) == 0) {
-		value = simple_strtoul(page, NULL, 0); 
-		if (value < 0 || value > 15 || mixcom_set_irq[value]==0xFF) {
-			printk(KERN_ERR "MIXCOM: incorrect irq value!\n");
-		} else {
-			dev->irq = value;	
-		}
-	} else if (strcmp(entry->name, FILENAME_CLOCK) == 0) {
-		if (strncmp("ext", page, 3) == 0) {
-			hw->clock = 0;
-		} else {
-			int kbps;
-
-			kbps = simple_strtoul(page, NULL, 0);
-			if (!kbps) {
-				hw->clock = 0;
-			} else {
-				hw->clock = kbps;
-			}
-			if (hw->clock < 32 || hw->clock > 2000) {
-				hw->clock = 0;
-				printk(KERN_ERR "MIXCOM: invalid clock rate!\n");
-			}
-		}
-		if (ch->init_status & HW_OPEN && ch->HW_set_clock) {
-			ch->HW_set_clock(dev);
-		}
-	} else if (strcmp(entry->name, FILENAME_CHANNEL) == 0) {
-		value = simple_strtoul(page, NULL, 0);
-        	if (value > 2) {
-                	printk(KERN_ERR "Invalid channel number\n");
-	        } else {
-        		dev->base_addr+=(hw->channel - value) * MIXCOM_CHANNEL_OFFSET;
-	        	hw->channel = value;
-		}	        
-	} else {
-		printk(KERN_ERR "hw_read_proc: internal error, filename %s\n", 
-			entry->name);
-		return -EBADF;
-	}
-
-	setup_twin(dev);
-
-	free_page((unsigned long)page);
-	return count;
-}
-
-static int MIXCOM_init(struct net_device *dev) {
-	struct comx_channel *ch = dev->priv;
-	struct mixcom_privdata *hw;
-	struct proc_dir_entry *new_file;
-
-	if ((ch->HW_privdata = kmalloc(sizeof(struct mixcom_privdata), 
-	    GFP_KERNEL)) == NULL) {
-	    	return -ENOMEM;
-	}
-
-	memset(hw = ch->HW_privdata, 0, sizeof(struct mixcom_privdata));
-
-	if ((new_file = create_proc_entry(FILENAME_IO, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-		goto cleanup_HW_privdata;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &mixcom_read_proc;
-	new_file->write_proc = &mixcom_write_proc;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_IRQ, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-	    	goto cleanup_filename_io;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &mixcom_read_proc;
-	new_file->write_proc = &mixcom_write_proc;
-	new_file->nlink = 1;
-
-#if 0
-	if ((new_file = create_proc_entry(FILENAME_CLOCK, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-	    	return -EIO;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &mixcom_read_proc;
-	new_file->write_proc = &mixcom_write_proc;
-	new_file->nlink = 1;
-#endif
-
-	if ((new_file = create_proc_entry(FILENAME_CHANNEL, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-	    	goto cleanup_filename_irq;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &mixcom_read_proc;
-	new_file->write_proc = &mixcom_write_proc;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_TWIN, S_IFREG | 0444, 
-	    ch->procdir)) == NULL) {
-	    	goto cleanup_filename_channel;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &mixcom_read_proc;
-	new_file->write_proc = &mixcom_write_proc;
-	new_file->nlink = 1;
-
-	setup_twin(dev);
-
-	/* Fill in ch_struct hw specific pointers */
-	ch->HW_access_board = NULL;
-	ch->HW_release_board = NULL;
-	ch->HW_txe = MIXCOM_txe;
-	ch->HW_open = MIXCOM_open;
-	ch->HW_close = MIXCOM_close;
-	ch->HW_send_packet = MIXCOM_send_packet;
-	ch->HW_statistics = MIXCOM_statistics;
-	ch->HW_set_clock = NULL;
-
-	dev->base_addr = MIXCOM_DEV_BASE(MIXCOM_DEFAULT_IO,0);
-	dev->irq = MIXCOM_DEFAULT_IRQ;
-
-	MOD_INC_USE_COUNT;
-	return 0;
-cleanup_filename_channel:
-	remove_proc_entry(FILENAME_CHANNEL, ch->procdir);
-cleanup_filename_irq:
-	remove_proc_entry(FILENAME_IRQ, ch->procdir);
-cleanup_filename_io:
-	remove_proc_entry(FILENAME_IO, ch->procdir);
-cleanup_HW_privdata:
-	kfree(ch->HW_privdata);
-	return -EIO;
-}
-
-static int MIXCOM_exit(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct mixcom_privdata *hw = ch->HW_privdata;
-
-	if(hw->channel==0 && TWIN(dev)) {
-		return -EBUSY;
-	}
-
-	if(hw->channel==1 && TWIN(dev)) {
-		TWIN(TWIN(dev))=NULL;
-	}
-
-	kfree(ch->HW_privdata);
-	remove_proc_entry(FILENAME_IO, ch->procdir);
-	remove_proc_entry(FILENAME_IRQ, ch->procdir);
-#if 0
-	remove_proc_entry(FILENAME_CLOCK, ch->procdir);
-#endif
-	remove_proc_entry(FILENAME_CHANNEL, ch->procdir);
-	remove_proc_entry(FILENAME_TWIN, ch->procdir);
-
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-static struct comx_hardware mixcomhw = {
-	"mixcom",
-	VERSION,
-	MIXCOM_init, 
-	MIXCOM_exit,
-	MIXCOM_dump,
-	NULL
-};
-	
-static int __init comx_hw_mixcom_init(void)
-{
-	return comx_register_hardware(&mixcomhw);
-}
-
-static void __exit comx_hw_mixcom_exit(void)
-{
-	comx_unregister_hardware("mixcom");
-}
-
-module_init(comx_hw_mixcom_init);
-module_exit(comx_hw_mixcom_exit);
===== drivers/net/wan/comx-hw-munich.c 1.17 vs edited =====
--- 1.17/drivers/net/wan/comx-hw-munich.c	Wed Mar  3 18:32:01 2004
+++ edited/drivers/net/wan/comx-hw-munich.c	Fri May  7 13:05:52 2004
@@ -1,2854 +1 @@
-/*
- * Hardware-level driver for the SliceCOM board for Linux kernels 2.4.X
- *
- * Current maintainer / latest changes: Pasztor Szilard <don@itc.hu>
- *
- * Original author: Bartok Istvan <bartoki@itc.hu>
- * Based on skeleton by Tivadar Szemethy <tiv@itc.hu>
- *
- * 0.51:
- *      - port for 2.4.x
- *	- clean up some code, make it more portable
- *	- busted direct hardware access through mapped memory
- *	- fix a possible race
- *	- prevent procfs buffer overflow
- *
- * 0.50:
- *	- support for the pcicom board, lots of rearrangements
- *	- handle modem status lines
- *
- * 0.50a:
- *	- fix for falc version 1.0
- *
- * 0.50b: T&t
- *	- fix for bad localbus
- */
 
-#define VERSION		"0.51"
-#define VERSIONSTR	"SliceCOM v" VERSION ", 2002/01/07\n"
-
-#include <linux/config.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-
-#include <asm/delay.h>
-#include <asm/types.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#define COMX_NEW
-
-#ifndef COMX_NEW
-#include "../include/comx.h"
-#include "../include/munich32x.h"
-#include "../include/falc-lh.h"
-#else
-#include "comx.h"
-#include "munich32x.h"
-#include "falc-lh.h"
-#endif
-
-MODULE_AUTHOR("Bartok Istvan <bartoki@itc.hu>, Gergely Madarasz <gorgo@itc.hu>, Szilard Pasztor <don@itc.hu>");
-MODULE_DESCRIPTION("Hardware-level driver for the SliceCOM and PciCOM (WelCOM) adapters");
-MODULE_LICENSE("GPL");
-/*
- *	TODO: az ilyenek a comxhw.h -ban szoktak lenni, idovel menjenek majd oda:
- */
-
-#define FILENAME_BOARDNUM	"boardnum"	/* /proc/comx/comx0.1/boardnum          */
-#define FILENAME_TIMESLOTS	"timeslots"	/* /proc/comx/comx0.1/timeslots         */
-#define FILENAME_FRAMING	"framing"	/* /proc/comx/comx0.1/framing           */
-#define FILENAME_LINECODE	"linecode"	/* /proc/comx/comx0.1/linecode          */
-#define FILENAME_CLOCK_SOURCE	"clock_source"	/* /proc/comx/comx0.1/clock_source      */
-#define FILENAME_LOOPBACK	"loopback"	/* /proc/comx/comx0.1/loopback          */
-#define FILENAME_REG		"reg"		/* /proc/comx/comx0.1/reg               */
-#define FILENAME_LBIREG		"lbireg"	/* /proc/comx/comx0.1/lbireg            */
-
-#define SLICECOM_BOARDNUM_DEFAULT	0
-
-#define SLICECOM_FRAMING_CRC4		1
-#define SLICECOM_FRAMING_NO_CRC4	2
-#define SLICECOM_FRAMING_DEFAULT	SLICECOM_FRAMING_CRC4
-
-#define SLICECOM_LINECODE_HDB3		1
-#define SLICECOM_LINECODE_AMI		2
-#define SLICECOM_LINECODE_DEFAULT	SLICECOM_LINECODE_HDB3
-
-#define SLICECOM_CLOCK_SOURCE_LINE	1
-#define SLICECOM_CLOCK_SOURCE_INTERNAL	2
-#define SLICECOM_CLOCK_SOURCE_DEFAULT	SLICECOM_CLOCK_SOURCE_LINE
-
-#define SLICECOM_LOOPBACK_NONE		1
-#define SLICECOM_LOOPBACK_LOCAL		2
-#define SLICECOM_LOOPBACK_REMOTE	3
-#define SLICECOM_LOOPBACK_DEFAULT	SLICECOM_LOOPBACK_NONE
-
-#define MUNICH_VIRT(addr) (void *)(&bar1[addr])
-
-struct slicecom_stringtable
-{
-    char *name;
-    int value;
-};
-
-/* A convention: keep "default" the last not NULL when reading from /proc,
-   "error" is an indication that something went wrong, we have an undefined value */
-
-struct slicecom_stringtable slicecom_framings[] =
-{
-    {"crc4", SLICECOM_FRAMING_CRC4},
-    {"no-crc4", SLICECOM_FRAMING_NO_CRC4},
-    {"default", SLICECOM_FRAMING_DEFAULT},
-    {"error", 0}
-};
-
-struct slicecom_stringtable slicecom_linecodes[] =
-{
-    {"hdb3", SLICECOM_LINECODE_HDB3},
-    {"ami", SLICECOM_LINECODE_AMI},
-    {"default", SLICECOM_LINECODE_DEFAULT},
-    {"error", 0}
-};
-
-struct slicecom_stringtable slicecom_clock_sources[] =
-{
-    {"line", SLICECOM_CLOCK_SOURCE_LINE},
-    {"internal", SLICECOM_CLOCK_SOURCE_INTERNAL},
-    {"default", SLICECOM_CLOCK_SOURCE_DEFAULT},
-    {"error", 0}
-};
-
-struct slicecom_stringtable slicecom_loopbacks[] =
-{
-    {"none", SLICECOM_LOOPBACK_NONE},
-    {"local", SLICECOM_LOOPBACK_LOCAL},
-    {"remote", SLICECOM_LOOPBACK_REMOTE},
-    {"default", SLICECOM_LOOPBACK_DEFAULT},
-    {"error", 0}
-};
-
-/*
- *	Some tunable values...
- *
- *	Note: when tuning values which change the length of text in
- *	/proc/comx/comx[n]/status, keep in mind that it must be shorter then
- *	PAGESIZE !
- */
-
-#define MAX_BOARDS	4	/* ezzel 4 kartya lehet a gepben: 0..3          */
-#define RX_DESC_MAX	8	/* Rx ring size, must be >= 4                   */
-#define TX_DESC_MAX	4	/* Tx ring size, must be >= 2                   */
-				/* a sokkal hosszabb Tx ring mar ronthatja a nem-FIFO packet    */
-				/* schedulerek (fair queueing, stb.) hatekonysagat.             */
-#define MAX_WORK	10	/* TOD: update the info max. ennyi-1 esemenyt dolgoz fel egy interrupt hivasnal */
-
-/*
- *	These are tunable too, but don't touch them without fully understanding what is happening
- */
-
-#define UDELAY		20	/* We wait UDELAY usecs with disabled interrupts before and     */
-				/* after each command to avoid writing into each other's        */
-				/* ccb->action_spec. A _send_packet nem var, mert azt az        */
-				/* _interrupt()-bol is meghivhatja a LINE_tx()                  */
-
-/*
- *	Just to avoid warnings about implicit declarations:
- */
-
-static int MUNICH_close(struct net_device *dev);
-static struct comx_hardware slicecomhw;
-static struct comx_hardware pcicomhw;
-
-static unsigned long flags;
-static spinlock_t mister_lock = SPIN_LOCK_UNLOCKED;
-
-typedef volatile struct		/* Time Slot Assignment */
-{
-    u32 rxfillmask:8,		// ----------------------------+------+
-				//                             |      |
-      rxchannel:5,		// ----------------------+---+ |      |
-      rti:1,			// ---------------------+|   | |      |
-      res2:2,			// -------------------++||   | |      |
-				//                    ||||   | |      |
-      txfillmask:8,		// ----------+------+ ||||   | |      |
-				//           |      | ||||   | |      |
-      txchannel:5,		// ----+---+ |      | ||||   | |      |
-      tti:1,			// ---+|   | |      | ||||   | |      |
-      res1:2;			// -++||   | |      | ||||   | |      |
-				//   3          2          1
-    				//  10987654 32109876 54321098 76543210
-} timeslot_spec_t;
-
-typedef volatile struct		/* Receive Descriptor */
-{
-    u32 zero1:16, no:13, hi:1, hold:1, zero2:1;
-
-    u32 next;
-    u32 data;
-
-    u32 zero3:8, status:8, bno:13, zero4:1, c:1, fe:1;
-} rx_desc_t;
-
-typedef volatile struct		/* Transmit Descriptor */
-{
-    u32 fnum:11, csm:1, no13:1, zero1:2, v110:1, no:13, hi:1, hold:1, fe:1;
-
-    u32 next;
-    u32 data;
-
-} tx_desc_t;
-
-typedef volatile struct		/* Channel Specification */
-{
-    u32 iftf:1, mode:2, fa:1, trv:2, crc:1, inv:1, cs:1, tflag:7, ra:1, ro:1,
-	th:1, ta:1, to:1, ti:1, ri:1, nitbs:1, fit:1, fir:1, re:1, te:1, ch:1,
-	ifc:1, sfe:1, fe2:1;
-
-    u32 frda;
-    u32 ftda;
-
-    u32 itbs:6, zero1:26;
-
-} channel_spec_t;
-
-typedef volatile struct		/* Configuration Control Block */
-{
-    u32 action_spec;
-    u32 reserved1;
-    u32 reserved2;
-    timeslot_spec_t timeslot_spec[32];
-    channel_spec_t channel_spec[32];
-    u32 current_rx_desc[32];
-    u32 current_tx_desc[32];
-    u32 csa;			/* Control Start Address. CSA = *CCBA; CCB = *CSA */
-				/* MUNICH does it like: CCB = *( *CCBA )          */
-} munich_ccb_t;
-
-typedef volatile struct		/* Entry in the interrupt queue */
-{
-    u32 all;
-} munich_intq_t;
-
-#define MUNICH_INTQLEN	63	/* Rx/Tx Interrupt Queue Length
-				   (not the real len, but the TIQL/RIQL value)  */
-#define MUNICH_INTQMAX	( 16*(MUNICH_INTQLEN+1) )	/* Rx/Tx/Periph Interrupt Queue size in munich_intq_t's */
-#define MUNICH_INTQSIZE	( 4*MUNICH_INTQMAX )	/* Rx/Tx/Periph Interrupt Queue size in bytes           */
-
-#define MUNICH_PIQLEN	4	/* Peripheral Interrupt Queue Length. Unlike the RIQL/TIQL, */
-#define MUNICH_PIQMAX	( 4*MUNICH_PIQLEN )	/* PIQL register needs it like this                     */
-#define MUNICH_PIQSIZE	( 4*MUNICH_PIQMAX )
-
-typedef volatile u32 vol_u32;	/* TOD: ezek megszunnek ha atirom readw()/writew()-re - kész */
-typedef volatile u8 vol_u8;
-
-typedef volatile struct		/* counters of E1-errors and errored seconds, see rfc2495 */
-{
-    /* use here only unsigned ints, we depend on it when calculating the sum for the last N intervals */
-
-    unsigned line_code_violations,	/* AMI: bipolar violations, HDB3: hdb3 violations                       */
-      path_code_violations,	/* FAS errors and CRC4 errors                                                   */
-      e_bit_errors,		/* E-Bit Errors (the remote side received from us with CRC4-error) */
-      slip_secs,		/* number of seconds with (receive) Controlled Slip(s)          */
-      fr_loss_secs,		/* number of seconds an Out Of Frame defect was detected                */
-      line_err_secs,		/* number of seconds with one or more Line Code Violations              */
-      degraded_mins,		/* Degraded Minute - the estimated error rate is >1E-6, but <1E-3       */
-      errored_secs,		/* Errored Second - at least one of these happened:
-				   - Path Code Violation
-				   - Out Of Frame defect
-				   - Slip
-				   - receiving AIS
-				   - not incremented during an Unavailable Second                       */
-      bursty_err_secs,		/* Bursty Errored Second: (rfc2495 says it does not apply to E1)
-				   - Path Code Violations >1, but <320
-				   - not a Severely Errored Second
-				   - no AIS
-				   - not incremented during an Unavailabla Second                       */
-      severely_err_secs,	/* Severely Errored Second:
-				   - CRC4: >=832 Path COde Violations || >0 Out Of Frame defects
-				   - noCRC4: >=2048 Line Code Violations
-				   - not incremented during an Unavailable Second                       */
-      unavail_secs;		/* number of Unavailable Seconds. Unavailable state is said after:
-				   - 10 contiguous Severely Errored Seconds
-				   - or RAI || AIS || LOF || LOS 
-				   - (any) loopback has been set                                                */
-
-    /*
-     * we do not strictly comply to the rfc: we do not retroactively reduce errored_secs,
-     * bursty_err_secs, severely_err_secs when 'unavailable state' is reached
-     */
-
-} e1_stats_t;
-
-typedef volatile struct		/* ezek board-adatok, nem lehetnek a slicecom_privdata -ban     */
-{
-    int use_count;		/* num. of interfaces using the board                           */
-    int irq;			/* a kartya irq-ja. belemasoljuk a dev->irq -kba is, de csak hogy       */
-    /* szebb legyen az ifconfig outputja                            */
-    /* ha != 0, az azt jelenti hogy az az irq most nekunk sikeresen */
-    /* le van foglalva                                              */
-    struct pci_dev *pci;	/* a kartya PCI strukturaja. NULL, ha nincs kartya              */
-    u32 *bar1;			/* pci->base_address[0] ioremap()-ed by munich_probe(),         */
-    /* on x86 can be used both as a bus or virtual address.         */
-    /* These are the Munich's registers                             */
-    u8 *lbi;			/* pci->base_address[1] ioremap()-ed by munich_probe(),         */
-    /* this is a 256-byte range, the start of the LBI on the board  */
-    munich_ccb_t *ccb;		/* virtual address of CCB                                       */
-    munich_intq_t *tiq;		/* Tx Interrupt Queue                                           */
-    munich_intq_t *riq;		/* Rx Interrupt Queue                                           */
-    munich_intq_t *piq;		/* Peripheral Interrupt Queue (FALC interrupts arrive here)     */
-    int tiq_ptr,		/* A 'current' helyek a tiq/riq/piq -ban.                       */
-      riq_ptr,			/* amikor feldolgoztam az interruptokat, a legelso ures         */
-      piq_ptr;			/* interrupt_information szora mutatnak.                        */
-    struct net_device *twins[32];	/* MUNICH channel -> network interface assignment       */
-
-    unsigned long lastcheck;	/* When were the Rx rings last checked. Time in jiffies         */
-
-    struct timer_list modemline_timer;
-    char isx21;
-    char lineup;
-    char framing;		/* a beallitasok tarolasa                               */
-    char linecode;
-    char clock_source;
-    char loopback;
-
-    char devname[30];		/* what to show in /proc/interrupts                     */
-    unsigned histogram[MAX_WORK];	/* number of processed events in the interrupt loop     */
-    unsigned stat_pri_races;	/* number of special events, we try to handle them      */
-    unsigned stat_pti_races;
-    unsigned stat_pri_races_missed;	/* when it can not be handled, because of MAX_WORK      */
-    unsigned stat_pti_races_missed;
-
-#define SLICECOM_BOARD_INTERVALS_SIZE	97
-    e1_stats_t intervals[SLICECOM_BOARD_INTERVALS_SIZE];	/* E1 line statistics           */
-    unsigned current_interval;	/* pointer to the current interval                      */
-    unsigned elapsed_seconds;	/* elapsed seconds from the start of the current interval */
-    unsigned ses_seconds;	/* counter of contiguous Severely Errored Seconds       */
-    unsigned is_unavailable;	/* set to 1 after 10 contiguous Severely Errored Seconds */
-    unsigned no_ses_seconds;	/* contiguous Severely Error -free seconds in unavail state */
-
-    unsigned deg_elapsed_seconds;	/* for counting the 'Degraded Mins'                     */
-    unsigned deg_cumulated_errors;
-
-    struct module *owner;	/* pointer to our module to avoid module load races */
-} munich_board_t;
-
-struct slicecom_privdata
-{
-    int busy;			/* transmitter busy - number of packets in the Tx ring  */
-    int channel;		/* Munich logical channel ('channel-group' in Cisco)    */
-    unsigned boardnum;
-    u32 timeslots;		/* i-th bit means i-th timeslot is our                  */
-
-    int tx_ring_hist[TX_DESC_MAX];	/* histogram: number of packets in Tx ring when _send_packet is called  */
-
-    tx_desc_t tx_desc[TX_DESC_MAX];	/* the ring of Tx descriptors                           */
-    u8 tx_data[TX_DESC_MAX][TXBUFFER_SIZE];	/* buffers for data to transmit                 */
-    int tx_desc_ptr;		/* hanyadik descriptornal tartunk a beirassal   */
-    /* ahol ez all, oda irtunk utoljara                     */
-
-    rx_desc_t rx_desc[RX_DESC_MAX];	/* the ring of Rx descriptors                           */
-    u8 rx_data[RX_DESC_MAX][RXBUFFER_SIZE];	/* buffers for received data                            */
-    int rx_desc_ptr;		/* hanyadik descriptornal tartunk az olvasassal */
-
-    int rafutott;
-};
-
-static u32 reg, reg_ertek;	/* why static: don't write stack trash into regs if strtoul() fails */
-static u32 lbireg;
-static u8 lbireg_ertek;		/* why static: don't write stack trash into regs if strtoul() fails */
-
-static munich_board_t slicecom_boards[MAX_BOARDS];
-static munich_board_t pcicom_boards[MAX_BOARDS];
-
-/*
- * Reprogram Idle Channel Registers in the FALC - send special code in not used channels
- * Should be called from the open and close, when the timeslot assignment changes
- */
-
-void rework_idle_channels(struct net_device *dev)
-{
-    struct comx_channel *ch = netdev_priv(dev);
-    struct slicecom_privdata *hw = ch->HW_privdata;
-    munich_board_t *board = slicecom_boards + hw->boardnum;
-    munich_ccb_t *ccb = board->ccb;
-
-    u8 *lbi = board->lbi;
-    int i, j, tmp;
-
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    for (i = 0; i < 4; i++)
-    {
-	tmp = 0xFF;
-	for (j = 0; j < 8; j++)
-	    if (ccb->timeslot_spec[8 * i + j].tti == 0) tmp ^= (0x80 >> j);
-	writeb(tmp, lbi + 0x30 + i);
-    }
-
-    spin_unlock_irqrestore(&mister_lock, flags);
-}
-
-/*
- * Set PCM framing - /proc/comx/comx0/framing
- */
-
-void slicecom_set_framing(int boardnum, int value)
-{
-    u8 *lbi = slicecom_boards[boardnum].lbi;
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    slicecom_boards[boardnum].framing = value;
-    switch (value)
-    {
-	case SLICECOM_FRAMING_CRC4:
-	    writeb(readb(lbi + FMR1) | 8, lbi + FMR1);
-	    writeb((readb(lbi + FMR2) & 0x3f) | 0x80, lbi + FMR2);
-	    break;
-	case SLICECOM_FRAMING_NO_CRC4:
-	    writeb(readb(lbi + FMR1) & 0xf7, lbi + FMR1);
-	    writeb(readb(lbi + FMR2) & 0x3f, lbi + FMR2);
-	    break;
-	default:
-	    printk("slicecom: board %d: unhandled " FILENAME_FRAMING
-		   " value %d\n", boardnum, value);
-    }
-
-    spin_unlock_irqrestore(&mister_lock, flags);
-}
-
-/*
- * Set PCM linecode - /proc/comx/comx0/linecode
- */
-
-void slicecom_set_linecode(int boardnum, int value)
-{
-    u8 *lbi = slicecom_boards[boardnum].lbi;
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    slicecom_boards[boardnum].linecode = value;
-    switch (value)
-    {
-	case SLICECOM_LINECODE_HDB3:
-	    writeb(readb(lbi + FMR0) | 0xf0, lbi + FMR0);
-	    break;
-	case SLICECOM_LINECODE_AMI:
-	    writeb((readb(lbi + FMR0) & 0x0f) | 0xa0, lbi + FMR0);
-	    break;
-	default:
-	    printk("slicecom: board %d: unhandled " FILENAME_LINECODE
-		   " value %d\n", boardnum, value);
-    }
-    spin_unlock_irqrestore(&mister_lock, flags);
-}
-
-/*
- * Set PCM clock source - /proc/comx/comx0/clock_source
- */
-
-void slicecom_set_clock_source(int boardnum, int value)
-{
-    u8 *lbi = slicecom_boards[boardnum].lbi;
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    slicecom_boards[boardnum].clock_source = value;
-    switch (value)
-    {
-	case SLICECOM_CLOCK_SOURCE_LINE:
-	    writeb(readb(lbi + LIM0) & ~1, lbi + LIM0);
-	    break;
-	case SLICECOM_CLOCK_SOURCE_INTERNAL:
-	    writeb(readb(lbi + LIM0) | 1, lbi + LIM0);
-	    break;
-	default:
-	    printk("slicecom: board %d: unhandled " FILENAME_CLOCK_SOURCE
-		   " value %d\n", boardnum, value);
-    }
-    spin_unlock_irqrestore(&mister_lock, flags);
-}
-
-/*
- * Set loopbacks - /proc/comx/comx0/loopback
- */
-
-void slicecom_set_loopback(int boardnum, int value)
-{
-    u8 *lbi = slicecom_boards[boardnum].lbi;
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    slicecom_boards[boardnum].loopback = value;
-    switch (value)
-    {
-	case SLICECOM_LOOPBACK_NONE:
-	    writeb(readb(lbi + LIM0) & ~2, lbi + LIM0);	/* Local Loop OFF  */
-	    writeb(readb(lbi + LIM1) & ~2, lbi + LIM1);	/* Remote Loop OFF */
-	    break;
-	case SLICECOM_LOOPBACK_LOCAL:
-	    writeb(readb(lbi + LIM1) & ~2, lbi + LIM1);	/* Remote Loop OFF */
-	    writeb(readb(lbi + LIM0) | 2, lbi + LIM0);	/* Local Loop ON   */
-	    break;
-	case SLICECOM_LOOPBACK_REMOTE:
-	    writeb(readb(lbi + LIM0) & ~2, lbi + LIM0);	/* Local Loop OFF  */
-	    writeb(readb(lbi + LIM1) | 2, lbi + LIM1);	/* Remote Loop ON  */
-	    break;
-	default:
-	    printk("slicecom: board %d: unhandled " FILENAME_LOOPBACK
-		   " value %d\n", boardnum, value);
-    }
-    spin_unlock_irqrestore(&mister_lock, flags);
-}
-
-/*
- * Update E1 line status LEDs on the adapter
- */
-
-void slicecom_update_leds(munich_board_t * board)
-{
-    u32 *bar1 = board->bar1;
-    u8 *lbi = board->lbi;
-    u8 frs0;
-    u32 leds;
-    int i;
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    leds = 0;
-    frs0 = readb(lbi + FRS0);	/* FRS0 bits described on page 137 */
-
-    if (!(frs0 & 0xa0))
-    {
-	leds |= 0x2000;		/* Green LED: Input signal seems to be OK, no LOS, no LFA       */
-	if (frs0 & 0x10)
-	    leds |= 0x8000;	/* Red LED: Receiving Remote Alarm                                      */
-    }
-    writel(leds, MUNICH_VIRT(GPDATA));
-
-    if (leds == 0x2000 && !board->lineup)
-    {				/* line up */
-	board->lineup = 1;
-	for (i = 0; i < 32; i++)
-	{
-	    if (board->twins[i] && (board->twins[i]->flags & IFF_RUNNING))
-	    {
-		struct comx_channel *ch = board->twins[i]->priv;
-
-		if (!test_and_set_bit(0, &ch->lineup_pending))
-		{
-		    ch->lineup_timer.function = comx_lineup_func;
-		    ch->lineup_timer.data = (unsigned long)board->twins[i];
-		    ch->lineup_timer.expires = jiffies + HZ * ch->lineup_delay;
-		    add_timer(&ch->lineup_timer);
-		}
-	    }
-	}
-    }
-    else if (leds != 0x2000 && board->lineup)
-    {				/* line down */
-	board->lineup = 0;
-	for (i = 0; i < 32; i++)
-	    if (board->twins[i] && (board->twins[i]->flags & IFF_RUNNING))
-	    {
-		struct comx_channel *ch = board->twins[i]->priv;
-
-		if (test_and_clear_bit(0, &ch->lineup_pending))
-		    del_timer(&ch->lineup_timer);
-		else if (ch->line_status & LINE_UP)
-		{
-		    ch->line_status &= ~LINE_UP;
-		    if (ch->LINE_status)
-			ch->LINE_status(board->twins[i], ch->line_status);
-		}
-	    }
-    }
-    spin_unlock_irqrestore(&mister_lock, flags);
-}
-
-/*
- * This function gets called every second when the FALC issues the interrupt.
- * Hardware counters contain error counts for last 1-second time interval.
- * We add them to the global counters here.
- * Read rfc2495 to understand this.
- */
-
-void slicecom_update_line_counters(munich_board_t * board)
-{
-    e1_stats_t *curr_int = &board->intervals[board->current_interval];
-
-    u8 *lbi = board->lbi;
-
-    unsigned framing_errors, code_violations, path_code_violations, crc4_errors,
-	e_bit_errors;
-    unsigned slip_detected,	/* this one has logical value, not the number of slips! */
-      out_of_frame_defect,	/* logical value        */
-      ais_defect,		/* logical value        */
-      errored_sec, bursty_err_sec, severely_err_sec = 0, failure_sec;
-    u8 isr2, isr3, isr5, frs0;
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    isr2 = readb(lbi + ISR2);	/* ISR0-5 described on page 156     */
-    isr3 = readb(lbi + ISR3);
-    isr5 = readb(lbi + ISR5);
-    frs0 = readb(lbi + FRS0);	/* FRS0 described on page 137       */
-
-    /* Error Events: */
-
-    code_violations = readb(lbi + CVCL) + (readb(lbi + CVCH) << 8);
-    framing_errors = readb(lbi + FECL) + (readb(lbi + FECH) << 8);
-    crc4_errors = readb(lbi + CEC1L) + (readb(lbi + CEC1H) << 8);
-    e_bit_errors = readb(lbi + EBCL) + (readb(lbi + EBCH) << 8);
-    slip_detected = isr3 & (ISR3_RSN | ISR3_RSP);
-
-    path_code_violations = framing_errors + crc4_errors;
-
-    curr_int->line_code_violations += code_violations;
-    curr_int->path_code_violations += path_code_violations;
-    curr_int->e_bit_errors += e_bit_errors;
-
-    /* Performance Defects: */
-
-    /* there was an LFA in the last second, but maybe disappeared: */
-    out_of_frame_defect = (isr2 & ISR2_LFA) || (frs0 & FRS0_LFA);
-
-    /* there was an AIS in the last second, but maybe disappeared: */
-    ais_defect = (isr2 & ISR2_AIS) || (frs0 & FRS0_AIS);
-
-    /* Performance Parameters: */
-
-    if (out_of_frame_defect)
-	curr_int->fr_loss_secs++;
-    if (code_violations)
-	curr_int->line_err_secs++;
-
-    errored_sec = ((board->framing == SLICECOM_FRAMING_NO_CRC4) &&
-		   (code_violations)) || path_code_violations ||
-	out_of_frame_defect || slip_detected || ais_defect;
-
-    bursty_err_sec = !out_of_frame_defect && !ais_defect &&
-	(path_code_violations > 1) && (path_code_violations < 320);
-
-    switch (board->framing)
-    {
-	case SLICECOM_FRAMING_CRC4:
-	    severely_err_sec = out_of_frame_defect ||
-		(path_code_violations >= 832);
-	    break;
-	case SLICECOM_FRAMING_NO_CRC4:
-	    severely_err_sec = (code_violations >= 2048);
-	    break;
-    }
-
-    /*
-     * failure_sec: true if there was a condition leading to a failure
-     * (and leading to unavailable state) in this second:
-     */
-
-    failure_sec = (isr2 & ISR2_RA) || (frs0 & FRS0_RRA)	/* Remote/Far End/Distant Alarm Failure */
-	|| ais_defect || out_of_frame_defect	/* AIS or LOF Failure                           */
-	|| (isr2 & ISR2_LOS) || (frs0 & FRS0_LOS)	/* Loss Of Signal Failure                       */
-	|| (board->loopback != SLICECOM_LOOPBACK_NONE);	/* Loopback has been set                        */
-
-    if (board->is_unavailable)
-    {
-	if (severely_err_sec)
-	    board->no_ses_seconds = 0;
-	else
-	    board->no_ses_seconds++;
-
-	if ((board->no_ses_seconds >= 10) && !failure_sec)
-	{
-	    board->is_unavailable = 0;
-	    board->ses_seconds = 0;
-	    board->no_ses_seconds = 0;
-	}
-    }
-    else
-    {
-	if (severely_err_sec)
-	    board->ses_seconds++;
-	else
-	    board->ses_seconds = 0;
-
-	if ((board->ses_seconds >= 10) || failure_sec)
-	{
-	    board->is_unavailable = 1;
-	    board->ses_seconds = 0;
-	    board->no_ses_seconds = 0;
-	}
-    }
-
-    if (board->is_unavailable)
-	curr_int->unavail_secs++;
-    else
-    {
-	if (slip_detected)
-	    curr_int->slip_secs++;
-	curr_int->errored_secs += errored_sec;
-	curr_int->bursty_err_secs += bursty_err_sec;
-	curr_int->severely_err_secs += severely_err_sec;
-    }
-
-    /* the RFC does not say clearly which errors to count here, we try to count bit errors */
-
-    if (!board->is_unavailable && !severely_err_sec)
-    {
-	board->deg_cumulated_errors += code_violations;
-	board->deg_elapsed_seconds++;
-	if (board->deg_elapsed_seconds >= 60)
-	{
-	    if (board->deg_cumulated_errors >= 123)
-		curr_int->degraded_mins++;
-	    board->deg_cumulated_errors = 0;
-	    board->deg_elapsed_seconds = 0;
-	}
-
-    }
-
-    board->elapsed_seconds++;
-    if (board->elapsed_seconds >= 900)
-    {
-	board->current_interval =
-	    (board->current_interval + 1) % SLICECOM_BOARD_INTERVALS_SIZE;
-	memset((void *)&board->intervals[board->current_interval], 0,
-	       sizeof(e1_stats_t));
-	board->elapsed_seconds = 0;
-    }
-
-    spin_unlock_irqrestore(&mister_lock, flags);
-}
-
-static void pcicom_modemline(unsigned long b)
-{
-    munich_board_t *board = (munich_board_t *) b;
-    struct net_device *dev = board->twins[0];
-    struct comx_channel *ch = netdev_priv(dev);
-    unsigned long regs;
-
-    regs = readl((void *)(&board->bar1[GPDATA]));
-    if ((ch->line_status & LINE_UP) && (regs & 0x0800))
-    {
-	ch->line_status &= ~LINE_UP;
-	board->lineup = 0;
-	if (ch->LINE_status)
-	{
-	    ch->LINE_status(dev, ch->line_status);
-	}
-    }
-
-    if (!(ch->line_status & LINE_UP) && !(regs & 0x0800))
-    {
-	ch->line_status |= LINE_UP;
-	board->lineup = 1;
-	if (ch->LINE_status)
-	{
-	    ch->LINE_status(dev, ch->line_status);
-	}
-    }
-
-    mod_timer((struct timer_list *)&board->modemline_timer, jiffies + HZ);
-}
-
-/* 
- * Is it possible to transmit ?
- * Called (may be called) by the protocol layer 
- */
-
-static int MUNICH_txe(struct net_device *dev)
-{
-    struct comx_channel *ch = netdev_priv(dev);
-    struct slicecom_privdata *hw = ch->HW_privdata;
-
-    return (hw->busy < TX_DESC_MAX - 1);
-}
-
-/* 
- * Hw probe function. Detects all the boards in the system,
- * and fills up slicecom_boards[] and pcicom_boards[]
- * Returns 0 on success.
- * We do not disable interrupts!
- */
-static int munich_probe(void)
-{
-    struct pci_dev *pci;
-    int boardnum;
-    int slicecom_boardnum;
-    int pcicom_boardnum;
-    u32 *bar1;
-    u8 *lbi;
-    munich_board_t *board;
-
-    for (boardnum = 0; boardnum < MAX_BOARDS; boardnum++)
-    {
-	pcicom_boards[boardnum].pci = 0;
-	pcicom_boards[boardnum].bar1 = 0;
-	pcicom_boards[boardnum].lbi = 0;
-	slicecom_boards[boardnum].pci = 0;
-	slicecom_boards[boardnum].bar1 = 0;
-	slicecom_boards[boardnum].lbi = 0;
-    }
-
-    pci = NULL;
-    board = NULL;
-    slicecom_boardnum = 0;
-    pcicom_boardnum = 0;
-
-    for (boardnum = 0;
-	boardnum < MAX_BOARDS && (pci = pci_find_device(PCI_VENDOR_ID_SIEMENS,
-	PCI_DEVICE_ID_SIEMENS_MUNICH32X, pci)); boardnum++)
-    {
-	if (pci_enable_device(pci))
-	    continue;
-
-	printk("munich_probe: munich chip found, IRQ %d\n", pci->irq);
-
-	bar1 = ioremap_nocache(pci->resource[0].start, 0x100);
-	lbi = ioremap_nocache(pci->resource[1].start, 0x100);
-
-	if (bar1 && lbi)
-	{
-	    pci_write_config_dword(pci, MUNICH_PCI_PCIRES, 0xe0000);
-	    set_current_state(TASK_UNINTERRUPTIBLE);
-	    schedule_timeout(1);
-	    pci_write_config_dword(pci, MUNICH_PCI_PCIRES, 0);
-	    set_current_state(TASK_UNINTERRUPTIBLE);
-	    schedule_timeout(1);
-	    /* check the type of the card */
-	    writel(LREG0_MAGIC, MUNICH_VIRT(LREG0));
-	    writel(LREG1_MAGIC, MUNICH_VIRT(LREG1));
-	    writel(LREG2_MAGIC, MUNICH_VIRT(LREG2));
-	    writel(LREG3_MAGIC, MUNICH_VIRT(LREG3));
-	    writel(LREG4_MAGIC, MUNICH_VIRT(LREG4));
-	    writel(LREG5_MAGIC, MUNICH_VIRT(LREG5));
-	    writel(LCONF_MAGIC2,MUNICH_VIRT(LCONF));	/* enable the DMSM */
-
-	    if ((readb(lbi + VSTR) == 0x13) || (readb(lbi + VSTR) == 0x10))
-	    {
-		board = slicecom_boards + slicecom_boardnum;
-		sprintf((char *)board->devname, "slicecom%d",
-			slicecom_boardnum);
-		board->isx21 = 0;
-		slicecom_boardnum++;
-	    }
-	    else if ((readb(lbi + VSTR) == 0x6) || (readb(lbi + GIS) == 0x6))
-	    {
-		board = pcicom_boards + pcicom_boardnum;
-		sprintf((char *)board->devname, "pcicom%d", pcicom_boardnum);
-		board->isx21 = 1;
-		pcicom_boardnum++;
-	    }
-	    if (board)
-	    {
-		printk("munich_probe: %s board found\n", board->devname);
-		writel(LCONF_MAGIC1, MUNICH_VIRT(LCONF));	/* reset the DMSM */
-		board->pci = pci;
-		board->bar1 = bar1;
-		board->lbi = lbi;
-		board->framing = SLICECOM_FRAMING_DEFAULT;
-		board->linecode = SLICECOM_LINECODE_DEFAULT;
-		board->clock_source = SLICECOM_CLOCK_SOURCE_DEFAULT;
-		board->loopback = SLICECOM_LOOPBACK_DEFAULT;
-		board->owner = THIS_MODULE;
-	    }
-	    else
-	    {
-		printk("munich_probe: Board error, VSTR: %02X\n",
-		       readb(lbi + VSTR));
-		iounmap((void *)bar1);
-		iounmap((void *)lbi);
-	    }
-	}
-	else
-	{
-	    printk("munich_probe: ioremap() failed, not enabling this board!\n");
-	    /* .pci = NULL, so the MUNICH_open will not try to open it            */
-	    if (bar1) iounmap((void *)bar1);
-	    if (lbi) iounmap((void *)lbi);
-	}
-    }
-
-    if (!pci && !boardnum)
-    {
-	printk("munich_probe: no PCI present!\n");
-	return -ENODEV;
-    }
-
-    if (pcicom_boardnum + slicecom_boardnum == 0)
-    {
-	printk
-	    ("munich_probe: Couldn't find any munich board: vendor:device %x:%x not found\n",
-	     PCI_VENDOR_ID_SIEMENS, PCI_DEVICE_ID_SIEMENS_MUNICH32X);
-	return -ENODEV;
-    }
-
-    /* Found some */
-    if (pcicom_boardnum)
-	printk("%d pcicom board(s) found.\n", pcicom_boardnum);
-    if (slicecom_boardnum)
-	printk("%d slicecom board(s) found.\n", slicecom_boardnum);
-
-    return 0;
-}
-
-/* 
- * Reset the hardware. Get called only from within this module if needed.
- */
-#if 0
-static int slicecom_reset(struct net_device *dev)
-{
-    struct comx_channel *ch = netdev_priv(dev);
-
-    printk("slicecom_reset: resetting the hardware\n");
-
-    /* Begin to reset the hardware */
-
-    if (ch->HW_set_clock)
-	ch->HW_set_clock(dev);
-
-    /* And finish it */
-
-    return 0;
-}
-#endif
-
-/* 
- * Transmit a packet. 
- * Called by the protocol layer
- * Return values:	
- *	FRAME_ACCEPTED:	frame is being transmited, transmitter is busy
- *	FRAME_QUEUED:	frame is being transmitted, there's more room in
- *				the transmitter for additional packet(s)
- *	FRAME_ERROR:
- *	FRAME_DROPPED:	there was some error
- */
-
-static int MUNICH_send_packet(struct net_device *dev, struct sk_buff *skb)
-{
-    struct comx_channel *ch = netdev_priv(dev);
-    struct slicecom_privdata *hw = ch->HW_privdata;
-
-    /* Send it to the debug facility too if needed: */
-
-    if (ch->debug_flags & DEBUG_HW_TX)
-	comx_debug_bytes(dev, skb->data, skb->len, "MUNICH_send_packet");
-
-    /* If the line is inactive, don't accept: */
-
-    /* TODO: atgondolni hogy mi is legyen itt */
-    /* if (!(ch->line_status & LINE_UP)) return FRAME_DROPPED; */
-
-    /* More check, to be sure: */
-
-    if (skb->len > TXBUFFER_SIZE)
-    {
-	ch->stats.tx_errors++;
-	kfree_skb(skb);
-	return FRAME_ERROR;
-    }
-
-    /* Maybe you have to disable irq's while programming the hw: */
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    /* And more check: */
-
-    if (hw->busy >= TX_DESC_MAX - 1)
-    {
-	printk(KERN_ERR
-	       "%s: Transmitter called while busy... dropping frame, busy = %d\n",
-	       dev->name, hw->busy);
-	spin_unlock_irqrestore(&mister_lock, flags);
-	kfree_skb(skb);
-	return FRAME_DROPPED;
-    }
-
-    if (hw->busy >= 0)
-	hw->tx_ring_hist[hw->busy]++;
-    /* DELL: */
-    else
-	printk("slicecom: %s: FATAL: busy = %d\n", dev->name, hw->busy);
-
-//              /* DEL: */
-//      printk("slicecom: %s: _send_packet called, busy = %d\n", dev->name, hw->busy );
-
-    /* Packet can go, update stats: */
-
-    ch->stats.tx_packets++;
-    ch->stats.tx_bytes += skb->len;
-
-    /* Pass the packet to the HW:                   */
-    /* Step forward with the transmit descriptors:  */
-
-    hw->tx_desc_ptr = (hw->tx_desc_ptr + 1) % TX_DESC_MAX;
-
-    memcpy(&(hw->tx_data[hw->tx_desc_ptr][0]), skb->data, skb->len);
-    hw->tx_desc[hw->tx_desc_ptr].no = skb->len;
-
-    /* We don't issue any command, just step with the HOLD bit      */
-
-    hw->tx_desc[hw->tx_desc_ptr].hold = 1;
-    hw->tx_desc[(hw->tx_desc_ptr + TX_DESC_MAX - 1) % TX_DESC_MAX].hold = 0;
-
-#ifdef COMX_NEW
-    dev_kfree_skb(skb);
-#endif
-    /* csomag kerult a Tx ringbe: */
-
-    hw->busy++;
-
-    /* Report it: */
-
-    if (ch->debug_flags & DEBUG_HW_TX)
-	comx_debug(dev, "%s: MUNICH_send_packet was successful\n\n", dev->name);
-
-    if (hw->busy >= TX_DESC_MAX - 1)
-    {
-	spin_unlock_irqrestore(&mister_lock, flags);
-	return FRAME_ACCEPTED;
-    }
-
-    spin_unlock_irqrestore(&mister_lock, flags);
-
-    /* All done */
-
-    return FRAME_QUEUED;
-}
-
-/*
- * Interrupt handler routine.
- * Called by the Linux kernel.
- * BEWARE! The interrupts are enabled on the call!
- */
-static irqreturn_t MUNICH_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-    struct sk_buff *skb;
-    int length;
-    int rx_status;
-    int work;			/* hany esemenyt kezeltem mar le                                */
-    u32 *bar1;
-    u8 *lbi;
-    u32 stat,			/* az esemenyek, amiket a ebben a loop korben le kell meg kezelni       */
-      race_stat = 0,		/* race eseten ebben uzenek magamnak hogy mit kell meg lekezelni        */
-      ack;			/* ezt fogom a vegen a STAT-ba irni, kiveszek belole 1-1 bitet ha       */
-
-    /* az adott dolgot nem kell ack-olni mert volt vele munkam, es  */
-    /* legjobb ha visszaterek ide megegyszer                        */
-    munich_intq_t int_info;
-
-    struct net_device *dev;
-    struct comx_channel *ch;
-    struct slicecom_privdata *hw;
-    munich_board_t *board = (munich_board_t *) dev_id;
-    int channel;
-
-    //      , boardnum = (int)dev_id;
-
-    // board = munich_boards + boardnum;
-    bar1 = board->bar1;
-    lbi = board->lbi;
-
-    //      Do not uncomment this under heavy load! :->
-    //      printk("MUNICH_interrupt: masked STAT=0x%08x, tiq=0x%08x, riq=0x%08x, piq=0x%08x\n", stat, board->tiq[0].all, board->riq[0].all, board->piq[0].all );
-
-    for (work = 0; (stat = (race_stat | (readl(MUNICH_VIRT(STAT)) & ~STAT_NOT_HANDLED_BY_INTERRUPT))) && (work < MAX_WORK - 1); work++)
-    {
-	ack = stat & (STAT_PRI | STAT_PTI | STAT_LBII);
-
-	/* Handle the interrupt information in the Rx queue. We don't really trust      */
-	/* info from this queue, because it can be overflowed, so later check           */
-	/* every Rx ring for received packets. But there are some errors which can't    */
-	/* be counted from the Rx rings, so we parse it.                                        */
-
-	int_info = board->riq[board->riq_ptr];
-	if (int_info.all & 0xF0000000)	/* ha ez nem 0, akkor itt interrupt_info van                    */
-	{
-	    ack &= ~STAT_PRI;	/* don't ack the interrupt, we had some work to do              */
-
-	    channel = PCM_INT_CHANNEL(int_info.all);
-	    dev = board->twins[channel];
-
-	    if (dev == NULL)
-	    {
-		printk
-		    ("MUNICH_interrupt: got an Rx interrupt info for NULL device "
-		     "%s.twins[%d], int_info = 0x%08x\n", board->devname,
-		     channel, int_info.all);
-		goto go_for_next_interrupt;
-	    }
-
-	    ch = netdev_priv(dev);
-	    hw = (struct slicecom_privdata *)ch->HW_privdata;
-
-	    //      printk("Rx STAT=0x%08x int_info=0x%08x rx_desc_ptr=%d rx_desc.status=0x%01x\n",
-	    //              stat, int_info.all, hw->rx_desc_ptr, hw->rx_desc[ hw->rx_desc_ptr ].status );
-
-	    if (int_info.all & PCM_INT_HI)
-		printk("SliceCOM: %s: Host Initiated interrupt\n", dev->name);
-	    if (int_info.all & PCM_INT_IFC)
-		printk("SliceCOM: %s: Idle/Flag Change\n", dev->name);
-	    /* TOD: jo ez az Idle/Flag Change valamire? - azonnal latszik belole hogy mikor ad a masik oldal */
-	    /* TOD: ilyen IT most nem is jon, mert ki van maszkolva az interrupt, biztosan kell ez? */
-
-	    if (int_info.all & PCM_INT_FO)
-		/* Internal buffer (RB) overrun */
-		ch->stats.rx_over_errors++;	/* TOD: Ez azt jelenti hogy a belso RB nem volt hozzaferheto, es ezert kihagyott valamit. De nem csak csomag lehetett, hanem esemeny, stb. is. lasd page 247. Ezzel a 'cat status'-hoz igazodok, de a netdevice.h szerint nem egyertelmu hogy ide ez kellene. Nem lehet hogy rx_missed ? */
-		/* DE: nem gotozok sehova, elvileg jo igy */
-		/* kesobb meg visszaterek az FO-ra, ha packet-FO volt. Keresd a "packet-FO"-t. */
-	    if (int_info.all & PCM_INT_FI)	/* frame received, but we do not trust the int_info queue       */
-		if (int_info.all & PCM_INT_SF)
-		{		/* Short Frame: rovidebb mint a CRC */
-		    /* "rovidebb mint CRC+2byte" vizsgalat a "CRC+2"-nel */
-		    ch->stats.rx_length_errors++;	/* TOD: noveljem? ne noveljem? */
-		    goto go_for_next_interrupt;
-		}
-
-	    go_for_next_interrupt:	/* One step in the interrupt queue */
-	    board->riq[board->riq_ptr].all = 0;	/* megjelolom hogy itt meg nem jart a hw */
-	    board->riq_ptr = (board->riq_ptr + 1) % MUNICH_INTQMAX;
-
-	}
-
-	/* Check every Rx ring for incomed packets: */
-
-	for (channel = 0; channel < 32; channel++)
-	{
-	    dev = board->twins[channel];
-
-	    if (dev != NULL)
-	    {
-		ch = netdev_priv(dev);
-		hw = (struct slicecom_privdata *)ch->HW_privdata;
-
-		rx_status = hw->rx_desc[hw->rx_desc_ptr].status;
-
-		if (!(rx_status & 0x80))	/* mar jart itt a hardver */
-		{
-		    ack &= ~STAT_PRI;	/* Don't ack, we had some work          */
-
-		    /* Ez most egy kicsit zuros, mert itt mar nem latom az int_infot        */
-		    if (rx_status & RX_STATUS_ROF)
-			ch->stats.rx_over_errors++;	/* TOD: 'cat status'-hoz igazodok */
-
-		    if (rx_status & RX_STATUS_RA)
-			/* Abort received or issued on channel  */
-			ch->stats.rx_frame_errors++;	/* or HOLD bit in the descriptor                */
-			/* TOD: 'cat status'-hoz igazodok */
-
-		    if (rx_status & RX_STATUS_LFD)
-		    {		/* Long Frame (longer then MFL in the MODE1) */
-			ch->stats.rx_length_errors++;
-			goto go_for_next_frame;
-		    }
-
-		    if (rx_status & RX_STATUS_NOB)
-		    {		/* Not n*8 bits long frame - frame alignment */
-			ch->stats.rx_frame_errors++;	/* ez viszont nem igazodik a 'cat status'-hoz */
-			goto go_for_next_frame;
-		    }
-
-		    if (rx_status & RX_STATUS_CRCO)
-		    {		/* CRC error */
-			ch->stats.rx_crc_errors++;
-			goto go_for_next_frame;
-		    }
-
-		    if (rx_status & RX_STATUS_SF)
-		    {		/* Short Frame: rovidebb mint CRC+2byte */
-			ch->stats.rx_errors++;	/* The HW does not set PCI_INT_ERR bit for this one, see page 246 */
-			ch->stats.rx_length_errors++;
-			goto go_for_next_frame;
-		    }
-
-		    if (rx_status != 0)
-		    {
-			printk("SliceCOM: %s: unhandled rx_status: 0x%02x\n",
-			       dev->name, rx_status);
-			goto go_for_next_frame;
-		    }
-
-		    /* frame received without errors: */
-
-		    length = hw->rx_desc[hw->rx_desc_ptr].bno;
-		    ch->stats.rx_packets++;	/* Count only 'good' packets */
-		    ch->stats.rx_bytes += length;
-
-		    /* Allocate a larger skb and reserve the heading for efficiency: */
-
-		    if ((skb = dev_alloc_skb(length + 16)) == NULL)
-		    {
-			ch->stats.rx_dropped++;
-			goto go_for_next_frame;
-		    }
-
-		    /* Do bookkeeping: */
-
-		    skb_reserve(skb, 16);
-		    skb_put(skb, length);
-		    skb->dev = dev;
-
-		    /* Now copy the data into the buffer: */
-
-		    memcpy(skb->data, &(hw->rx_data[hw->rx_desc_ptr][0]), length);
-
-		    /* DEL: UGLY HACK!!!! */
-		    if (*((int *)skb->data) == 0x02000000 &&
-			*(((int *)skb->data) + 1) == 0x3580008f)
-		    {
-			printk("%s: swapping hack\n", dev->name);
-			*((int *)skb->data) = 0x3580008f;
-			*(((int *)skb->data) + 1) = 0x02000000;
-		    }
-
-		    if (ch->debug_flags & DEBUG_HW_RX)
-			comx_debug_skb(dev, skb, "MUNICH_interrupt receiving");
-
-		    /* Pass it to the protocol entity: */
-
-		    ch->LINE_rx(dev, skb);
-
-		    go_for_next_frame:
-		    /* DEL: rafutott-e a HOLD bitre -detektalas */
-		    {
-			if( ((rx_desc_t*)phys_to_virt(board->ccb->current_rx_desc[channel]))->hold
-			    && ((rx_desc_t*)phys_to_virt(board->ccb->current_rx_desc[channel]))->status != 0xff)
-			    hw->rafutott++;	/* rafutott: hanyszor volt olyan hogy a current descriptoron HOLD bit volt, es a hw mar befejezte az irast (azaz a hw rafutott a HOLD bitre) */
-		    }
-
-		    //      if( jiffies % 2 )               /* DELL: okozzunk egy kis Rx ring slipet :) */
-		    //      {
-		    /* Step forward with the receive descriptors: */
-		    /* if you change this, change the copy of it below too! Search for: "RxSlip" */
-		    hw->rx_desc[(hw->rx_desc_ptr + RX_DESC_MAX - 1) % RX_DESC_MAX].hold = 1;
-		    hw->rx_desc[hw->rx_desc_ptr].status = 0xFF;	/* megjelolom hogy itt meg nem jart a hw */
-		    hw->rx_desc[(hw->rx_desc_ptr + RX_DESC_MAX - 2) % RX_DESC_MAX].hold = 0;
-		    hw->rx_desc_ptr = (hw->rx_desc_ptr + 1) % RX_DESC_MAX;
-		    //      }
-		}
-	    }
-	}
-
-	stat &= ~STAT_PRI;
-
-//      }
-
-//      if( stat & STAT_PTI )   /* TOD: primko megvalositas: mindig csak egy esemenyt dolgozok fel, */
-	/* es nem torlom a STAT-ot, ezert ujra visszajon ide a rendszer. Amikor */
-	/* jon interrupt, de nincs mit feldolgozni, akkor torlom a STAT-ot.     */
-	/* 'needs a rewrite', de elso megoldasnak jo lesz                       */
-//              {
-	int_info = board->tiq[board->tiq_ptr];
-	if (int_info.all & 0xF0000000)	/* ha ez nem 0, akkor itt interrupt_info van    */
-	{
-	    ack &= ~STAT_PTI;	/* don't ack the interrupt, we had some work to do      */
-
-	    channel = PCM_INT_CHANNEL(int_info.all);
-	    dev = board->twins[channel];
-
-	    if (dev == NULL)
-	    {
-		printk("MUNICH_interrupt: got a Tx interrupt for NULL device "
-		       "%s.twins[%d], int_info = 0x%08x\n",
-		       board->isx21 ? "pcicom" : "slicecom", channel, int_info.all);
-		goto go_for_next_tx_interrupt;
-	    }
-
-	    ch = netdev_priv(dev);
-	    hw = (struct slicecom_privdata *)ch->HW_privdata;
-
-	    //      printk("Tx STAT=0x%08x int_info=0x%08x tiq_ptr=%d\n", stat, int_info.all, board->tiq_ptr );
-
-	    if (int_info.all & PCM_INT_FE2)
-	    {			/* "Tx available"                               */
-		/* do nothing */
-	    }
-	    else if (int_info.all & PCM_INT_FO)
-	    {			/* Internal buffer (RB) overrun */
-		ch->stats.rx_over_errors++;
-	    }
-	    else
-	    {
-		printk("slicecom: %s: unhandled Tx int_info: 0x%08x\n",
-		       dev->name, int_info.all);
-	    }
-
-	    go_for_next_tx_interrupt:
-	    board->tiq[board->tiq_ptr].all = 0;
-	    board->tiq_ptr = (board->tiq_ptr + 1) % MUNICH_INTQMAX;
-	}
-
-	/* Check every Tx ring for incoming packets: */
-
-	for (channel = 0; channel < 32; channel++)
-	{
-	    dev = board->twins[channel];
-
-	    if (dev != NULL)
-	    {
-		int newbusy;
-
-		ch = netdev_priv(dev);
-		hw = (struct slicecom_privdata *)ch->HW_privdata;
-
-		/* We don't trust the "Tx available" info from the TIQ, but check        */
-		/* every ring if there is some free room                                        */
-
-		if (ch->init_status && netif_running(dev))
-		{
-		    newbusy = ( TX_DESC_MAX + (& hw->tx_desc[ hw->tx_desc_ptr ]) -
-			(tx_desc_t*)phys_to_virt(board->ccb->current_tx_desc[ hw->channel ]) ) % TX_DESC_MAX;
-
-		    if(newbusy < 0)
-		    {
-			printk("slicecom: %s: FATAL: fresly computed busy = %d, HW: 0x%p, SW: 0x%p\n",
-			dev->name, newbusy,
-			phys_to_virt(board->ccb->current_tx_desc[hw->channel]),
-			& hw->tx_desc[hw->tx_desc_ptr]);
-		    }
-
-		    /* Fogyott valami a Tx ringbol? */
-
-		    if (newbusy < hw->busy)
-		    {
-			// ack &= ~STAT_PTI;                            /* Don't ack, we had some work  */
-			hw->busy = newbusy;
-			if (ch->LINE_tx)
-			    ch->LINE_tx(dev);	/* Report it to protocol driver */
-		    }
-		    else if (newbusy > hw->busy)
-			printk("slicecom: %s: newbusy > hw->busy, this should not happen!\n", dev->name);
-		}
-	    }
-	}
-	stat &= ~STAT_PTI;
-
-	int_info = board->piq[board->piq_ptr];
-	if (int_info.all & 0xF0000000)	/* ha ez nem 0, akkor itt interrupt_info van            */
-	{
-	    ack &= ~STAT_LBII;	/* don't ack the interrupt, we had some work to do      */
-
-	    /* We do not really use (yet) the interrupt info from this queue, */
-
-	    // printk("slicecom: %s: LBI Interrupt event: %08x\n", board->devname, int_info.all);
-
-	    if (!board->isx21)
-	    {
-		slicecom_update_leds(board);
-		slicecom_update_line_counters(board);
-	    }
-
-	    goto go_for_next_lbi_interrupt;	/* To avoid warning about unused label  */
-
-	    go_for_next_lbi_interrupt:	/* One step in the interrupt queue */
-	    board->piq[board->piq_ptr].all = 0;	/* megjelolom hogy itt meg nem jart a hw        */
-	    board->piq_ptr = (board->piq_ptr + 1) % MUNICH_PIQMAX;
-	}
-	stat &= ~STAT_LBII;
-
-	writel(ack, MUNICH_VIRT(STAT));
-
-	if (stat & STAT_TSPA)
-	{
-	    //      printk("slicecom: %s: PCM TSP Asynchronous\n", board->devname);
-	    writel(STAT_TSPA, MUNICH_VIRT(STAT));
-	    stat &= ~STAT_TSPA;
-	}
-
-	if (stat & STAT_RSPA)
-	{
-	    //      printk("slicecom: %s: PCM RSP Asynchronous\n", board->devname);
-	    writel(STAT_RSPA, MUNICH_VIRT(STAT));
-	    stat &= ~STAT_RSPA;
-	}
-	if (stat)
-	{
-	    printk("MUNICH_interrupt: unhandled interrupt, STAT=0x%08x\n",
-		   stat);
-	    writel(stat, MUNICH_VIRT(STAT));	/* ha valamit megsem kezeltunk le, azert ack-ot kuldunk neki */
-	}
-
-    }
-    board->histogram[work]++;
-
-    /* We can miss these if we reach the MAX_WORK   */
-    /* Count it to see how often it happens         */
-
-    if (race_stat & STAT_PRI)
-	board->stat_pri_races_missed++;
-    if (race_stat & STAT_PTI)
-	board->stat_pti_races_missed++;
-    return IRQ_HANDLED;
-}
-
-/* 
- * Hardware open routine.
- * Called by comx (upper) layer when the user wants to bring up the interface
- * with ifconfig.
- * Initializes hardware, allocates resources etc.
- * Returns 0 on OK, or standard error value on error.
- */
-
-static int MUNICH_open(struct net_device *dev)
-{
-    struct comx_channel *ch = netdev_priv(dev);
-    struct slicecom_privdata *hw = ch->HW_privdata;
-    struct proc_dir_entry *procfile = ch->procdir->subdir;
-    munich_board_t *board;
-    munich_ccb_t *ccb;
-
-    u32 *bar1;
-    u8 *lbi;
-    u32 stat;
-    unsigned long flags, jiffs;
-
-    int i, channel;
-    u32 timeslots = hw->timeslots;
-
-    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
-
-    bar1 = board->bar1;
-    lbi = board->lbi;
-
-    /* TODO: a timeslotok ellenorzese kell majd ide .. hat, biztos? mar a write_proc-ban is
-       ellenorzom valamennyire.
-       if (!dev->io || !dev->irq) return -ENODEV;
-     */
-
-    if (!board->pci)
-    {
-	printk("MUNICH_open: no %s board with boardnum = %d\n",
-	       ch->hardware->name, hw->boardnum);
-	return -ENODEV;
-    }
-
-    spin_lock_irqsave(&mister_lock, flags);
-    /* lock the section to avoid race with multiple opens and make sure
-       that no interrupts get called while this lock is active */
-
-    if (board->use_count == 0)	/* bring up the board if it was unused                  */
-	/* if fails, frees allocated resources and returns.     */
-	/* TOD: is it safe? nem kellene resetelni a kartyat?    */
-    {
-	printk("MUNICH_open: %s: bringing up board\n", board->devname);
-
-	/* Clean up the board's static struct if messed: */
-
-	for (i = 0; i < 32; i++)
-	    board->twins[i] = NULL;
-	for (i = 0; i < MAX_WORK; i++)
-	    board->histogram[i] = 0;
-
-	board->lineup = 0;
-
-	/* Allocate CCB: */
-        board->ccb = kmalloc(sizeof(munich_ccb_t), GFP_KERNEL);
-	if (board->ccb == NULL)
-	{
-	    spin_unlock_irqrestore(&mister_lock, flags);
-	    return -ENOMEM;
-	}
-	memset((void *)board->ccb, 0, sizeof(munich_ccb_t));
-	board->ccb->csa = virt_to_phys(board->ccb);
-	ccb = board->ccb;
-	for (i = 0; i < 32; i++)
-	{
-	    ccb->timeslot_spec[i].tti = 1;
-	    ccb->timeslot_spec[i].rti = 1;
-	}
-
-	/* Interrupt queues: */
-
-	board->tiq = kmalloc(MUNICH_INTQSIZE, GFP_KERNEL);
-	if (board->tiq == NULL)
-	{
-	    spin_unlock_irqrestore(&mister_lock, flags);
-	    return -ENOMEM;
-	}
-	memset((void *)board->tiq, 0, MUNICH_INTQSIZE);
-
-	board->riq = kmalloc(MUNICH_INTQSIZE, GFP_KERNEL);
-	if (board->riq == NULL)
-	{
-	    spin_unlock_irqrestore(&mister_lock, flags);
-	    return -ENOMEM;
-	}
-	memset((void *)board->riq, 0, MUNICH_INTQSIZE);
-
-	board->piq = kmalloc(MUNICH_PIQSIZE, GFP_KERNEL);
-	if (board->piq == NULL)
-	{
-	    spin_unlock_irqrestore(&mister_lock, flags);
-	    return -ENOMEM;
-	}
-	memset((void *)board->piq, 0, MUNICH_PIQSIZE);
-
-	board->tiq_ptr = 0;
-	board->riq_ptr = 0;
-	board->piq_ptr = 0;
-
-	/* Request irq: */
-
-	board->irq = 0;
-
-	/* (char*) cast to avoid warning about discarding volatile:             */
-	if (request_irq(board->pci->irq, MUNICH_interrupt, 0,
-	    (char *)board->devname, (void *)board))
-	{
-	    printk("MUNICH_open: %s: unable to obtain irq %d\n", board->devname,
-		   board->pci->irq);
-	    /* TOD: free other resources (a sok malloc feljebb)                     */
-	    spin_unlock_irqrestore(&mister_lock, flags);
-	    return -EAGAIN;
-	}
-	board->irq = board->pci->irq;	/* csak akkor legyen != 0, ha tenyleg le van foglalva nekunk */
-
-	/* Programming device: */
-
-	/* Reset the board like a power-on: */
-	/* TOD:
-	   - It is not a real power-on: if a DMA transaction fails with master abort, the board
-	   stays in half-dead state.
-	   - It doesn't reset the FALC line driver */
-
-	pci_write_config_dword(board->pci, MUNICH_PCI_PCIRES, 0xe0000);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(1);
-	pci_write_config_dword(board->pci, MUNICH_PCI_PCIRES, 0);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(1);
-
-        writel(virt_to_phys(&ccb->csa), MUNICH_VIRT(CCBA));
-        writel(virt_to_phys( board->tiq ), MUNICH_VIRT(TIQBA));
-        writel(MUNICH_INTQLEN, MUNICH_VIRT(TIQL));
-        writel(virt_to_phys( board->riq ), MUNICH_VIRT(RIQBA));
-        writel(MUNICH_INTQLEN, MUNICH_VIRT(RIQL));
-        writel(virt_to_phys( board->piq ), MUNICH_VIRT(PIQBA));
-        writel(MUNICH_PIQLEN, MUNICH_VIRT(PIQL));
-        
-	/* Put the magic values into the registers: */
-
-	writel(MODE1_MAGIC, MUNICH_VIRT(MODE1));
-	writel(MODE2_MAGIC, MUNICH_VIRT(MODE2));
-
-	writel(LREG0_MAGIC, MUNICH_VIRT(LREG0));
-	writel(LREG1_MAGIC, MUNICH_VIRT(LREG1));
-	writel(LREG2_MAGIC, MUNICH_VIRT(LREG2));
-	writel(LREG3_MAGIC, MUNICH_VIRT(LREG3));
-	writel(LREG4_MAGIC, MUNICH_VIRT(LREG4));
-	writel(LREG5_MAGIC, MUNICH_VIRT(LREG5));
-
-	writel(LCONF_MAGIC1, MUNICH_VIRT(LCONF));	/* reset the DMSM */
-	writel(LCONF_MAGIC2, MUNICH_VIRT(LCONF));	/* enable the DMSM */
-
-	writel(~0, MUNICH_VIRT(TXPOLL));
-	writel(board->isx21 ? 0x1400 : 0xa000, MUNICH_VIRT(GPDIR));
-
-	if (readl(MUNICH_VIRT(STAT))) writel(readl(MUNICH_VIRT(STAT)), MUNICH_VIRT(STAT));
-
-	ccb->action_spec = CCB_ACTIONSPEC_RES | CCB_ACTIONSPEC_IA;
-	writel(CMD_ARPCM, MUNICH_VIRT(CMD));	/* Start the PCM core reset */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(1);
-
-	stat = 0;		/* Wait for the action to complete max. 1 second */
-	jiffs = jiffies;
-	while (!((stat = readl(MUNICH_VIRT(STAT))) & (STAT_PCMA | STAT_PCMF)) && time_before(jiffies, jiffs + HZ))
-	{
-	    set_current_state(TASK_UNINTERRUPTIBLE);
-	    schedule_timeout(1);
-	}
-
-	if (stat & STAT_PCMF)
-	{
-	    printk(KERN_ERR
-		   "MUNICH_open: %s: Initial ARPCM failed. STAT=0x%08x\n",
-		   board->devname, stat);
-	    writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMF, MUNICH_VIRT(STAT));
-	    free_irq(board->irq, (void *)board);	/* TOD: free other resources too *//* maybe shut down hw? */
-	    board->irq = 0;
-	    spin_unlock_irqrestore(&mister_lock, flags);
-	    return -EAGAIN;
-	}
-	else if (!(stat & STAT_PCMA))
-	{
-	    printk(KERN_ERR
-		   "MUNICH_open: %s: Initial ARPCM timeout. STAT=0x%08x\n",
-		   board->devname, stat);
-	    free_irq(board->irq, (void *)board);	/* TOD: free other resources too *//* maybe shut off the hw? */
-	    board->irq = 0;
-	    spin_unlock_irqrestore(&mister_lock, flags);
-	    return -EIO;
-	}
-
-	writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMA, MUNICH_VIRT(STAT));	/* Acknowledge */
-
-	if (board->isx21) writel(0, MUNICH_VIRT(GPDATA));
-
-	printk("MUNICH_open: %s: succesful HW-open took %ld jiffies\n",
-	       board->devname, jiffies - jiffs);
-
-	/* Set up the FALC hanging on the Local Bus: */
-
-	if (!board->isx21)
-	{
-	    writeb(0x0e, lbi + FMR1);
-	    writeb(0, lbi + LIM0);
-	    writeb(0xb0, lbi + LIM1);	/* TODO: input threshold */
-	    writeb(0xf7, lbi + XPM0);
-	    writeb(0x02, lbi + XPM1);
-	    writeb(0x00, lbi + XPM2);
-	    writeb(0xf0, lbi + FMR0);
-	    writeb(0x80, lbi + PCD);
-	    writeb(0x80, lbi + PCR);
-	    writeb(0x00, lbi + LIM2);
-	    writeb(0x07, lbi + XC0);
-	    writeb(0x3d, lbi + XC1);
-	    writeb(0x05, lbi + RC0);
-	    writeb(0x00, lbi + RC1);
-	    writeb(0x83, lbi + FMR2);
-	    writeb(0x9f, lbi + XSW);
-	    writeb(0x0f, lbi + XSP);
-	    writeb(0x00, lbi + TSWM);
-	    writeb(0xe0, lbi + MODE);
-	    writeb(0xff, lbi + IDLE);	/* Idle Code to send in unused timeslots        */
-	    writeb(0x83, lbi + IPC);	/* interrupt query line mode: Push/pull output, active high     */
-	    writeb(0xbf, lbi + IMR3);	/* send an interrupt every second               */
-
-	    slicecom_set_framing(hw->boardnum, board->framing);
-	    slicecom_set_linecode(hw->boardnum, board->linecode);
-	    slicecom_set_clock_source(hw->boardnum, board->clock_source);
-	    slicecom_set_loopback(hw->boardnum, board->loopback);
-
-	    memset((void *)board->intervals, 0, sizeof(board->intervals));
-	    board->current_interval = 0;
-	    board->elapsed_seconds = 0;
-	    board->ses_seconds = 0;
-	    board->is_unavailable = 0;
-	    board->no_ses_seconds = 0;
-	    board->deg_elapsed_seconds = 0;
-	    board->deg_cumulated_errors = 0;
-	}
-
-	/* Enable the interrupts last                                                   */
-	/* These interrupts will be enabled. We do not need the others. */
-
-	writel(readl(MUNICH_VIRT(IMASK)) & ~(STAT_PTI | STAT_PRI | STAT_LBII | STAT_TSPA | STAT_RSPA), MUNICH_VIRT(IMASK));
-    }
-
-    spin_unlock_irqrestore(&mister_lock, flags);
-
-    dev->irq = board->irq;	/* hogy szep legyen az ifconfig outputja */
-    ccb = board->ccb;		/* TODO: ez igy csunya egy kicsit hogy benn is meg kinn is beletoltom :( */
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    set_current_state(TASK_UNINTERRUPTIBLE);
-    schedule_timeout(1);
-
-    /* Check if the selected timeslots aren't used already */
-
-    for (i = 0; i < 32; i++)
-	if (((1 << i) & timeslots) && !ccb->timeslot_spec[i].tti)
-	{
-	    printk("MUNICH_open: %s: timeslot %d already used by %s\n",
-		   dev->name, i, board->twins[ccb->timeslot_spec[i].txchannel]->name);
-	    spin_unlock_irqrestore(&mister_lock, flags);
-	    return -EBUSY;	/* TODO: lehet hogy valami mas errno kellene? */
-	}
-
-    /* find a free channel: */
-    /* TODO: ugly, rewrite it  */
-
-    for (channel = 0; channel <= 32; channel++)
-    {
-	if (channel == 32)
-	{			/* not found a free one */
-	    printk
-		("MUNICH_open: %s: FATAL: can not find a free channel - this should not happen!\n",
-		 dev->name);
-	    spin_unlock_irqrestore(&mister_lock, flags);
-	    return -ENODEV;
-	}
-	if (board->twins[channel] == NULL)
-	    break;		/* found the first free one */
-    }
-
-    board->lastcheck = jiffies;	/* avoid checking uninitialized hardware channel */
-
-    /* Open the channel. If fails, calls MUNICH_close() to properly free resources and stop the HW */
-
-    hw->channel = channel;
-    board->twins[channel] = dev;
-
-    board->use_count++;		/* meg nem nyitottuk meg a csatornat, de a twins-ben
-				   mar elfoglaltunk egyet, es ha a _close-t akarjuk hivni, akkor ez kell. */
-    for (i = 0; i < 32; i++)
-	if ((1 << i) & timeslots)
-	{
-	    ccb->timeslot_spec[i].tti = 0;
-	    ccb->timeslot_spec[i].txchannel = channel;
-	    ccb->timeslot_spec[i].txfillmask = ~0;
-
-	    ccb->timeslot_spec[i].rti = 0;
-	    ccb->timeslot_spec[i].rxchannel = channel;
-	    ccb->timeslot_spec[i].rxfillmask = ~0;
-	}
-
-    if (!board->isx21) rework_idle_channels(dev);
-
-    memset((void *)&(hw->tx_desc), 0, TX_DESC_MAX * sizeof(tx_desc_t));
-    memset((void *)&(hw->rx_desc), 0, RX_DESC_MAX * sizeof(rx_desc_t));
-
-    for (i = 0; i < TX_DESC_MAX; i++)
-    {
-	hw->tx_desc[i].fe = 1;
-	hw->tx_desc[i].fnum = 2;
-                hw->tx_desc[i].data     = virt_to_phys( & (hw->tx_data[i][0]) );
-                hw->tx_desc[i].next     = virt_to_phys( & (hw->tx_desc[ (i+1) % TX_DESC_MAX ]) );
-
-    }
-    hw->tx_desc_ptr = 0;	/* we will send an initial packet so it is correct: "oda irtunk utoljara" */
-    hw->busy = 0;
-    hw->tx_desc[hw->tx_desc_ptr].hold = 1;
-    hw->tx_desc[hw->tx_desc_ptr].no = 1;	/* TOD: inkabb csak 0 hosszut kuldjunk ki az initkor? */
-
-    for (i = 0; i < RX_DESC_MAX; i++)
-    {
-	hw->rx_desc[i].no = RXBUFFER_SIZE;
-	hw->rx_desc[i].data = virt_to_phys(&(hw->rx_data[i][0]));
-	hw->rx_desc[i].next = virt_to_phys(&(hw->rx_desc[(i+1) % RX_DESC_MAX]));
-	hw->rx_desc[i].status = 0xFF;
-    }
-    hw->rx_desc_ptr = 0;
-
-    hw->rx_desc[(hw->rx_desc_ptr + RX_DESC_MAX - 2) % RX_DESC_MAX].hold = 1;
-
-    memset((void *)&ccb->channel_spec[channel], 0, sizeof(channel_spec_t));
-
-    ccb->channel_spec[channel].ti = 0;	/* Transmit off */
-    ccb->channel_spec[channel].to = 1;
-    ccb->channel_spec[channel].ta = 0;
-
-    ccb->channel_spec[channel].th = 1;	/* Transmit hold        */
-
-    ccb->channel_spec[channel].ri = 0;	/* Receive off  */
-    ccb->channel_spec[channel].ro = 1;
-    ccb->channel_spec[channel].ra = 0;
-
-    ccb->channel_spec[channel].mode = 3;	/* HDLC */
-
-    ccb->action_spec = CCB_ACTIONSPEC_IN | (channel << 8);
-    writel(CMD_ARPCM, MUNICH_VIRT(CMD));
-    set_current_state(TASK_UNINTERRUPTIBLE);
-    schedule_timeout(1);
-
-    spin_unlock_irqrestore(&mister_lock, flags);
-
-    stat = 0;
-    jiffs = jiffies;
-    while (!((stat = readl(MUNICH_VIRT(STAT))) & (STAT_PCMA | STAT_PCMF)) && time_before(jiffies, jiffs + HZ))
-    {
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(1);
-    }
-
-    if (stat & STAT_PCMF)
-    {
-	printk(KERN_ERR "MUNICH_open: %s: %s channel %d off failed\n",
-	       dev->name, board->devname, channel);
-	writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMF, MUNICH_VIRT(STAT));
-	MUNICH_close(dev);
-	return -EAGAIN;
-    }
-    else if (!(stat & STAT_PCMA))
-    {
-	printk(KERN_ERR "MUNICH_open: %s: %s channel %d off timeout\n",
-	       dev->name, board->devname, channel);
-	MUNICH_close(dev);
-	return -EIO;
-    }
-
-    writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMA, MUNICH_VIRT(STAT));
-    //      printk("MUNICH_open: %s: succesful channel off took %ld jiffies\n", board->devname, jiffies-jiffs);
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    set_current_state(TASK_UNINTERRUPTIBLE);
-    schedule_timeout(1);
-
-    ccb->channel_spec[channel].ifc = 1;	/* 1 .. 'Idle/Flag change' interrupt letiltva   */
-    ccb->channel_spec[channel].fit = 1;
-    ccb->channel_spec[channel].nitbs = 1;
-    ccb->channel_spec[channel].itbs = 2;
-
-    /* TODOO: lehet hogy jo lenne igy, de utana kellene nezni hogy nem okoz-e fragmentaciot */
-    //      ccb->channel_spec[channel].itbs = 2 * number_of_timeslots;
-    //      printk("open: %s: number_of_timeslots: %d\n", dev->name, number_of_timeslots);
-
-    ccb->channel_spec[channel].mode = 3;	/* HDLC */
-    ccb->channel_spec[channel].ftda = virt_to_phys(&(hw->tx_desc));
-    ccb->channel_spec[channel].frda = virt_to_phys(&(hw->rx_desc[0]));
-
-    ccb->channel_spec[channel].ti = 1;	/* Transmit init        */
-    ccb->channel_spec[channel].to = 0;
-    ccb->channel_spec[channel].ta = 1;
-
-    ccb->channel_spec[channel].th = 0;
-
-    ccb->channel_spec[channel].ri = 1;	/* Receive init */
-    ccb->channel_spec[channel].ro = 0;
-    ccb->channel_spec[channel].ra = 1;
-
-    ccb->action_spec = CCB_ACTIONSPEC_ICO | (channel << 8);
-    writel(CMD_ARPCM, MUNICH_VIRT(CMD));	/* Start the channel init */
-    set_current_state(TASK_UNINTERRUPTIBLE);
-    schedule_timeout(1);
-
-    spin_unlock_irqrestore(&mister_lock, flags);
-
-    stat = 0;			/* Wait for the action to complete max. 1 second */
-    jiffs = jiffies;
-    while (!((stat = readl(MUNICH_VIRT(STAT))) & (STAT_PCMA | STAT_PCMF)) && time_before(jiffies, jiffs + HZ))
-    {
-	set_current_state(TASK_UNINTERRUPTIBLE);
-        schedule_timeout(1);
-    }
-
-    if (stat & STAT_PCMF)
-    {
-	printk(KERN_ERR "MUNICH_open: %s: channel open ARPCM failed\n",
-	       board->devname);
-	writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMF, MUNICH_VIRT(STAT));
-	MUNICH_close(dev);
-	return -EAGAIN;
-    }
-    else if (!(stat & STAT_PCMA))
-    {
-	printk(KERN_ERR "MUNICH_open: %s: channel open ARPCM timeout\n",
-	       board->devname);
-	MUNICH_close(dev);
-	return -EIO;
-    }
-
-    writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMA, MUNICH_VIRT(STAT));
-    //      printk("MUNICH_open: %s: succesful channel open took %ld jiffies\n", board->devname, jiffies-jiffs);
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    ccb->channel_spec[channel].nitbs = 0;	/* once ITBS defined, these must be 0   */
-    ccb->channel_spec[channel].itbs = 0;
-
-    if (board->isx21)
-    {
-	init_timer(&board->modemline_timer);
-	board->modemline_timer.data = (unsigned long)board;
-	board->modemline_timer.function = pcicom_modemline;
-	board->modemline_timer.expires = jiffies + HZ;
-	add_timer((struct timer_list *)&board->modemline_timer);
-    }
-
-    /* It is done. Declare that we're open: */
-    hw->busy = 0;		/* It may be 1 if the frame at Tx init already ended, but it is not     */
-    /* a real problem: we compute hw->busy on every interrupt                       */
-    hw->rafutott = 0;
-    ch->init_status |= HW_OPEN;
-
-    /* Initialize line state: */
-    if (board->lineup)
-	ch->line_status |= LINE_UP;
-    else
-	ch->line_status &= ~LINE_UP;
-
-    /* Remove w attribute from /proc files associated to hw parameters:
-       no write when the device is open */
-
-    for (; procfile; procfile = procfile->next)
-	if (strcmp(procfile->name, FILENAME_BOARDNUM) == 0 ||
-	    strcmp(procfile->name, FILENAME_TIMESLOTS) == 0)
-	    procfile->mode = S_IFREG | 0444;
-
-    spin_unlock_irqrestore(&mister_lock, flags);
-
-    return 0;
-}
-
-/*
- * Hardware close routine.
- * Called by comx (upper) layer when the user wants to bring down the interface
- * with ifconfig.
- * We also call it from MUNICH_open, if the open fails.
- * Brings down hardware, frees resources, stops receiver
- * Returns 0 on OK, or standard error value on error.
- */
-
-static int MUNICH_close(struct net_device *dev)
-{
-    struct comx_channel *ch = netdev_priv(dev);
-    struct slicecom_privdata *hw = ch->HW_privdata;
-    struct proc_dir_entry *procfile = ch->procdir->subdir;
-    munich_board_t *board;
-    munich_ccb_t *ccb;
-
-    u32 *bar1;
-    u32 timeslots = hw->timeslots;
-    int stat, i, channel = hw->channel;
-    unsigned long jiffs;
-
-    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
-
-    ccb = board->ccb;
-    bar1 = board->bar1;
-
-    if (board->isx21)
-	del_timer((struct timer_list *)&board->modemline_timer);
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    set_current_state(TASK_UNINTERRUPTIBLE);
-    schedule_timeout(1);
-
-    /* Disable receiver for the channel: */
-
-    for (i = 0; i < 32; i++)
-	if ((1 << i) & timeslots)
-	{
-	    ccb->timeslot_spec[i].tti = 1;
-	    ccb->timeslot_spec[i].txfillmask = 0;	/* just to be double-sure :) */
-
-	    ccb->timeslot_spec[i].rti = 1;
-	    ccb->timeslot_spec[i].rxfillmask = 0;
-	}
-
-    if (!board->isx21) rework_idle_channels(dev);
-
-    ccb->channel_spec[channel].ti = 0;	/* Receive off, Transmit off */
-    ccb->channel_spec[channel].to = 1;
-    ccb->channel_spec[channel].ta = 0;
-    ccb->channel_spec[channel].th = 1;
-
-    ccb->channel_spec[channel].ri = 0;
-    ccb->channel_spec[channel].ro = 1;
-    ccb->channel_spec[channel].ra = 0;
-
-    board->twins[channel] = NULL;
-
-    ccb->action_spec = CCB_ACTIONSPEC_IN | (channel << 8);
-    writel(CMD_ARPCM, MUNICH_VIRT(CMD));
-    set_current_state(TASK_UNINTERRUPTIBLE);
-    schedule_timeout(1);
-
-    spin_unlock_irqrestore(&mister_lock, flags);
-
-    stat = 0;
-    jiffs = jiffies;
-    while (!((stat = readl(MUNICH_VIRT(STAT))) & (STAT_PCMA | STAT_PCMF)) && time_before(jiffies, jiffs + HZ))
-    {
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(1);
-    }
-
-    if (stat & STAT_PCMF)
-    {
-	printk(KERN_ERR
-	       "MUNICH_close: %s: FATAL: channel off ARPCM failed, not closing!\n",
-	       dev->name);
-	writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMF, MUNICH_VIRT(STAT));
-	/* If we return success, the privdata (and the descriptor list) will be freed */
-	return -EIO;
-    }
-    else if (!(stat & STAT_PCMA))
-	printk(KERN_ERR "MUNICH_close: %s: channel off ARPCM timeout\n",
-	       board->devname);
-
-    writel(readl(MUNICH_VIRT(STAT)) & STAT_PCMA, MUNICH_VIRT(STAT));
-    //      printk("MUNICH_close: %s: channel off took %ld jiffies\n", board->devname, jiffies-jiffs);
-
-    spin_lock_irqsave(&mister_lock, flags);
-
-    if (board->use_count) board->use_count--;
-
-    if (!board->use_count)	/* we were the last user of the board */
-    {
-	printk("MUNICH_close: bringing down board %s\n", board->devname);
-
-	/* program down the board: */
-
-	writel(0x0000FF7F, MUNICH_VIRT(IMASK));	/* do not send any interrupts */
-	writel(0, MUNICH_VIRT(CMD));	/* stop the timer if someone started it */
-	writel(~0U, MUNICH_VIRT(STAT));	/* if an interrupt came between the cli()-sti(), quiet it */
-	if (ch->hardware == &pcicomhw)
-	    writel(0x1400, MUNICH_VIRT(GPDATA));
-
-	/* Put the board into 'reset' state: */
-	pci_write_config_dword(board->pci, MUNICH_PCI_PCIRES, 0xe0000);
-
-	/* Free irq and other resources: */
-	if (board->irq)
-	    free_irq(board->irq, (void *)board);	/* Ha nem inicializalta magat, akkor meg nincs irq */
-	board->irq = 0;
-
-	/* Free CCB and the interrupt queues */
-	if (board->ccb) kfree((void *)board->ccb);
-	if (board->tiq) kfree((void *)board->tiq);
-	if (board->riq) kfree((void *)board->riq);
-	if (board->piq) kfree((void *)board->piq);
-	board->ccb = NULL;
-	board->tiq = board->riq = board->piq = NULL;
-    }
-
-    /* Enable setting of hw parameters */
-    for (; procfile; procfile = procfile->next)
-	if (strcmp(procfile->name, FILENAME_BOARDNUM) == 0 ||
-	    strcmp(procfile->name, FILENAME_TIMESLOTS) == 0)
-	    procfile->mode = S_IFREG | 0644;
-
-    /* We're not open anymore */
-    ch->init_status &= ~HW_OPEN;
-
-    spin_unlock_irqrestore(&mister_lock, flags);
-
-    return 0;
-}
-
-/* 
- * Give (textual) status information.
- * The text it returns will be a part of what appears when the user does a
- * cat /proc/comx/comx[n]/status 
- * Don't write more than PAGESIZE.
- * Return value: number of bytes written (length of the string, incl. 0)
- */
-
-static int MUNICH_minden(struct net_device *dev, char *page)
-{
-    struct comx_channel *ch = netdev_priv(dev);
-    struct slicecom_privdata *hw = ch->HW_privdata;
-    munich_board_t *board;
-    struct net_device *devp;
-
-    u8 *lbi;
-    e1_stats_t *curr_int, *prev_int;
-    e1_stats_t last4, last96;	/* sum of last 4, resp. last 96 intervals               */
-    unsigned *sump,		/* running pointer for the sum data                     */
-     *p;			/* running pointer for the interval data                */
-
-    int len = 0;
-    u8 frs0, frs1;
-    u8 fmr2;
-    int i, j;
-    u32 timeslots;
-
-    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
-
-    lbi = board->lbi;
-    curr_int = &board->intervals[board->current_interval];
-    prev_int =
-	&board->
-	intervals[(board->current_interval + SLICECOM_BOARD_INTERVALS_SIZE -
-		   1) % SLICECOM_BOARD_INTERVALS_SIZE];
-
-    if (!board->isx21)
-    {
-	frs0 = readb(lbi + FRS0);
-	fmr2 = readb(lbi + FMR2);
-	len += scnprintf(page + len, PAGE_SIZE - len, "Controller status:\n");
-	if (frs0 == 0)
-	    len += scnprintf(page + len, PAGE_SIZE - len, "\tNo alarms\n");
-	else
-	{
-	    if (frs0 & FRS0_LOS)
-	            len += scnprintf(page + len, PAGE_SIZE - len, "\tLoss Of Signal\n");
-	    else
-	    {
-		if (frs0 & FRS0_AIS)
-		    len += scnprintf(page + len, PAGE_SIZE - len,
-				 "\tAlarm Indication Signal\n");
-		else
-		{
-		    if (frs0 & FRS0_AUXP)
-			len += scnprintf(page + len, PAGE_SIZE - len,
-				     "\tAuxiliary Pattern Indication\n");
-		    if (frs0 & FRS0_LFA)
-			len += scnprintf(page + len, PAGE_SIZE - len,
-				     "\tLoss of Frame Alignment\n");
-		    else
-		    {
-			if (frs0 & FRS0_RRA)
-			    len += scnprintf(page + len, PAGE_SIZE - len,
-					 "\tReceive Remote Alarm\n");
-
-			/* You can't set this framing with the /proc interface, but it  */
-			/* may be good to have here this alarm if you set it by hand:   */
-
-			if ((board->framing == SLICECOM_FRAMING_CRC4) &&
-			    (frs0 & FRS0_LMFA))
-			    len += scnprintf(page + len, PAGE_SIZE - len,
-					 "\tLoss of CRC4 Multiframe Alignment\n");
-
-			if (((fmr2 & 0xc0) == 0xc0) && (frs0 & FRS0_NMF))
-			    len += scnprintf(page + len, PAGE_SIZE - len,
-				 "\tNo CRC4 Multiframe alignment Found after 400 msec\n");
-		    }
-		}
-	    }
-	}
-
-	frs1 = readb(lbi + FRS1);
-	if (FRS1_XLS & frs1)
-	    len += scnprintf(page + len, PAGE_SIZE - len,
-		 "\tTransmit Line Short\n");
-
-	/* debug Rx ring: DEL: - vagy meghagyni, de akkor legyen kicsit altalanosabb */
-    }
-
-    len += scnprintf(page + len, PAGE_SIZE - len, "Rx ring:\n");
-    len += scnprintf(page + len, PAGE_SIZE - len, "\trafutott: %d\n", hw->rafutott);
-    len += scnprintf(page + len, PAGE_SIZE - len,
-		 "\tlastcheck: %ld, jiffies: %ld\n", board->lastcheck, jiffies);
-    len += scnprintf(page + len, PAGE_SIZE - len, "\tbase: %08x\n",
-	(u32) virt_to_phys(&hw->rx_desc[0]));
-    len += scnprintf(page + len, PAGE_SIZE - len, "\trx_desc_ptr: %d\n",
-		 hw->rx_desc_ptr);
-    len += scnprintf(page + len, PAGE_SIZE - len, "\trx_desc_ptr: %08x\n",
-	(u32) virt_to_phys(&hw->rx_desc[hw->rx_desc_ptr]));
-    len += scnprintf(page + len, PAGE_SIZE - len, "\thw_curr_ptr: %08x\n",
-		 board->ccb->current_rx_desc[hw->channel]);
-
-    for (i = 0; i < RX_DESC_MAX; i++)
-	len += scnprintf(page + len, PAGE_SIZE - len, "\t%08x %08x %08x %08x\n",
-		     *((u32 *) & hw->rx_desc[i] + 0),
-		     *((u32 *) & hw->rx_desc[i] + 1),
-		     *((u32 *) & hw->rx_desc[i] + 2),
-		     *((u32 *) & hw->rx_desc[i] + 3));
-
-    if (!board->isx21)
-    {
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "Interfaces using this board: (channel-group, interface, timeslots)\n");
-	for (i = 0; i < 32; i++)
-	{
-	    devp = board->twins[i];
-	    if (devp != NULL)
-	    {
-		timeslots =
-		    ((struct slicecom_privdata *)((struct comx_channel *)devp->
-						  priv)->HW_privdata)->
-		    timeslots;
-		len += scnprintf(page + len, PAGE_SIZE - len, "\t%2d %s: ", i,
-			     devp->name);
-		for (j = 0; j < 32; j++)
-		    if ((1 << j) & timeslots)
-			len += scnprintf(page + len, PAGE_SIZE - len, "%d ", j);
-		len += scnprintf(page + len, PAGE_SIZE - len, "\n");
-	    }
-	}
-    }
-
-    len += scnprintf(page + len, PAGE_SIZE - len, "Interrupt work histogram:\n");
-    for (i = 0; i < MAX_WORK; i++)
-	len += scnprintf(page + len, PAGE_SIZE - len, "hist[%2d]: %8u%c", i,
-		     board->histogram[i], (i &&
-					   ((i + 1) % 4 == 0 ||
-					    i == MAX_WORK - 1)) ? '\n' : ' ');
-
-    len += scnprintf(page + len, PAGE_SIZE - len, "Tx ring histogram:\n");
-    for (i = 0; i < TX_DESC_MAX; i++)
-	len += scnprintf(page + len, PAGE_SIZE - len, "hist[%2d]: %8u%c", i,
-		     hw->tx_ring_hist[i], (i &&
-					   ((i + 1) % 4 == 0 ||
-					    i ==
-					    TX_DESC_MAX - 1)) ? '\n' : ' ');
-
-    if (!board->isx21)
-    {
-
-	memset((void *)&last4, 0, sizeof(last4));
-	memset((void *)&last96, 0, sizeof(last96));
-
-	/* Calculate the sum of last 4 intervals: */
-
-	for (i = 1; i <= 4; i++)
-	{
-	    p = (unsigned *)&board->intervals[(board->current_interval +
-			   SLICECOM_BOARD_INTERVALS_SIZE -
-			   i) % SLICECOM_BOARD_INTERVALS_SIZE];
-	    sump = (unsigned *)&last4;
-	    for (j = 0; j < (sizeof(e1_stats_t) / sizeof(unsigned)); j++)
-		sump[j] += p[j];
-	}
-
-	/* Calculate the sum of last 96 intervals: */
-
-	for (i = 1; i <= 96; i++)
-	{
-	    p = (unsigned *)&board->intervals[(board->current_interval +
-			   SLICECOM_BOARD_INTERVALS_SIZE -
-			   i) % SLICECOM_BOARD_INTERVALS_SIZE];
-	    sump = (unsigned *)&last96;
-	    for (j = 0; j < (sizeof(e1_stats_t) / sizeof(unsigned)); j++)
-		sump[j] += p[j];
-	}
-
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "Data in current interval (%d seconds elapsed):\n",
-		     board->elapsed_seconds);
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "   %d Line Code Violations, %d Path Code Violations, %d E-Bit Errors\n",
-		     curr_int->line_code_violations,
-		     curr_int->path_code_violations, curr_int->e_bit_errors);
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "   %d Slip Secs, %d Fr Loss Secs, %d Line Err Secs, %d Degraded Mins\n",
-		     curr_int->slip_secs, curr_int->fr_loss_secs,
-		     curr_int->line_err_secs, curr_int->degraded_mins);
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "   %d Errored Secs, %d Bursty Err Secs, %d Severely Err Secs, %d Unavail Secs\n",
-		     curr_int->errored_secs, curr_int->bursty_err_secs,
-		     curr_int->severely_err_secs, curr_int->unavail_secs);
-
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "Data in Interval 1 (15 minutes):\n");
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "   %d Line Code Violations, %d Path Code Violations, %d E-Bit Errors\n",
-		     prev_int->line_code_violations,
-		     prev_int->path_code_violations, prev_int->e_bit_errors);
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "   %d Slip Secs, %d Fr Loss Secs, %d Line Err Secs, %d Degraded Mins\n",
-		     prev_int->slip_secs, prev_int->fr_loss_secs,
-		     prev_int->line_err_secs, prev_int->degraded_mins);
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "   %d Errored Secs, %d Bursty Err Secs, %d Severely Err Secs, %d Unavail Secs\n",
-		     prev_int->errored_secs, prev_int->bursty_err_secs,
-		     prev_int->severely_err_secs, prev_int->unavail_secs);
-
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "Data in last 4 intervals (1 hour):\n");
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "   %d Line Code Violations, %d Path Code Violations, %d E-Bit Errors\n",
-		     last4.line_code_violations, last4.path_code_violations,
-		     last4.e_bit_errors);
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "   %d Slip Secs, %d Fr Loss Secs, %d Line Err Secs, %d Degraded Mins\n",
-		     last4.slip_secs, last4.fr_loss_secs, last4.line_err_secs,
-		     last4.degraded_mins);
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "   %d Errored Secs, %d Bursty Err Secs, %d Severely Err Secs, %d Unavail Secs\n",
-		     last4.errored_secs, last4.bursty_err_secs,
-		     last4.severely_err_secs, last4.unavail_secs);
-
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "Data in last 96 intervals (24 hours):\n");
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "   %d Line Code Violations, %d Path Code Violations, %d E-Bit Errors\n",
-		     last96.line_code_violations, last96.path_code_violations,
-		     last96.e_bit_errors);
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "   %d Slip Secs, %d Fr Loss Secs, %d Line Err Secs, %d Degraded Mins\n",
-		     last96.slip_secs, last96.fr_loss_secs,
-		     last96.line_err_secs, last96.degraded_mins);
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "   %d Errored Secs, %d Bursty Err Secs, %d Severely Err Secs, %d Unavail Secs\n",
-		     last96.errored_secs, last96.bursty_err_secs,
-		     last96.severely_err_secs, last96.unavail_secs);
-
-    }
-
-//      len +=scnprintf( page + len, PAGE_SIZE - len, "Special events:\n" );
-//      len +=scnprintf( page + len, PAGE_SIZE - len, "\tstat_pri/missed: %u / %u\n", board->stat_pri_races, board->stat_pri_races_missed );
-//      len +=scnprintf( page + len, PAGE_SIZE - len, "\tstat_pti/missed: %u / %u\n", board->stat_pti_races, board->stat_pti_races_missed );
-    return len;
-}
-
-/*
- * Memory dump function. Not used currently.
- */
-static int BOARD_dump(struct net_device *dev)
-{
-    printk
-	("BOARD_dump() requested. It is unimplemented, it should not be called\n");
-    return (-1);
-}
-
-/* 
- * /proc file read function for the files registered by this module.
- * This function is called by the procfs implementation when a user
- * wants to read from a file registered by this module.
- * page is the workspace, start should point to the real start of data,
- * off is the file offset, data points to the file's proc_dir_entry
- * structure.
- * Returns the number of bytes copied to the request buffer.
- */
-
-static int munich_read_proc(char *page, char **start, off_t off, int count,
-			    int *eof, void *data)
-{
-    struct proc_dir_entry *file = (struct proc_dir_entry *)data;
-    struct net_device *dev = file->parent->data;
-    struct comx_channel *ch = netdev_priv(dev);
-    struct slicecom_privdata *hw = ch->HW_privdata;
-    munich_board_t *board;
-
-    int len = 0, i;
-    u32 timeslots = hw->timeslots;
-
-    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
-
-    if (!strcmp(file->name, FILENAME_BOARDNUM))
-	len = sprintf(page, "%d\n", hw->boardnum);
-    else if (!strcmp(file->name, FILENAME_TIMESLOTS))
-    {
-	for (i = 0; i < 32; i++)
-	    if ((1 << i) & timeslots)
-		len += scnprintf(page + len, PAGE_SIZE - len, "%d ", i);
-	len += scnprintf(page + len, PAGE_SIZE - len, "\n");
-    }
-    else if (!strcmp(file->name, FILENAME_FRAMING))
-    {
-	i = 0;
-	while (slicecom_framings[i].value &&
-	       slicecom_framings[i].value != board->framing)
-	    i++;
-	len += scnprintf(page + len, PAGE_SIZE - len, "%s\n",
-		     slicecom_framings[i].name);
-    }
-    else if (!strcmp(file->name, FILENAME_LINECODE))
-    {
-	i = 0;
-	while (slicecom_linecodes[i].value &&
-	       slicecom_linecodes[i].value != board->linecode)
-	    i++;
-	len += scnprintf(page + len, PAGE_SIZE - len, "%s\n",
-		     slicecom_linecodes[i].name);
-    }
-    else if (!strcmp(file->name, FILENAME_CLOCK_SOURCE))
-    {
-	i = 0;
-	while (slicecom_clock_sources[i].value &&
-	       slicecom_clock_sources[i].value != board->clock_source)
-	    i++;
-	len +=
-	    scnprintf(page + len, PAGE_SIZE - len, "%s\n",
-		     slicecom_clock_sources[i].name);
-    }
-    else if (!strcmp(file->name, FILENAME_LOOPBACK))
-    {
-	i = 0;
-	while (slicecom_loopbacks[i].value &&
-	       slicecom_loopbacks[i].value != board->loopback)
-	    i++;
-	len += scnprintf(page + len, PAGE_SIZE - len, "%s\n",
-		     slicecom_loopbacks[i].name);
-    }
-    /* We set permissions to write-only for REG and LBIREG, but root can read them anyway: */
-    else if (!strcmp(file->name, FILENAME_REG))
-    {
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "%s: " FILENAME_REG ": write-only file\n", dev->name);
-    }
-    else if (!strcmp(file->name, FILENAME_LBIREG))
-    {
-	len += scnprintf(page + len, PAGE_SIZE - len,
-		     "%s: " FILENAME_LBIREG ": write-only file\n", dev->name);
-    }
-    else
-    {
-	printk("slicecom_read_proc: internal error, filename %s\n", file->name);
-	return -EBADF;
-    }
-    /* file handling administration: count eof status, offset, start address
-       and count: */
-
-    if (off >= len)
-    {
-	*eof = 1;
-	return 0;
-    }
-
-    *start = page + off;
-    if (count >= len - off)
-	*eof = 1;
-    return min((off_t) count, (off_t) len - off);
-}
-
-/* 
- * Write function for /proc files registered by us.
- * See the comment on read function above.
- * Beware! buffer is in userspace!!!
- * Returns the number of bytes written
- */
-
-static int munich_write_proc(struct file *file, const char *buffer,
-			     u_long count, void *data)
-{
-    struct proc_dir_entry *entry = (struct proc_dir_entry *)data;
-    struct net_device *dev = (struct net_device *)entry->parent->data;
-    struct comx_channel *ch = netdev_priv(dev);
-    struct slicecom_privdata *hw = ch->HW_privdata;
-    munich_board_t *board;
-
-    unsigned long ts, tmp_boardnum;
-
-    u32 tmp_timeslots = 0;
-    char *page, *p;
-    int i;
-
-    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
-
-    /* Paranoia checking: */
-
-    if (PDE(file->f_dentry->d_inode) != entry)
-    {
-	printk(KERN_ERR "munich_write_proc: file <-> data internal error\n");
-	return -EIO;
-    }
-
-    /* Request tmp buffer */
-    if (!(page = (char *)__get_free_page(GFP_KERNEL)))
-	return -ENOMEM;
-
-    /* Copy user data and cut trailing \n */
-    if (copy_from_user(page, buffer, count = min(count, PAGE_SIZE))) {
-	    free_page((unsigned long)page);
-	    return -EFAULT;
-    }
-    if (*(page + count - 1) == '\n')
-	*(page + count - 1) = 0;
-    *(page + PAGE_SIZE - 1) = 0;
-
-    if (!strcmp(entry->name, FILENAME_BOARDNUM))
-    {
-	tmp_boardnum = simple_strtoul(page, NULL, 0);
-	if (0 <= tmp_boardnum && tmp_boardnum < MAX_BOARDS)
-	    hw->boardnum = tmp_boardnum;
-	else
-	{
-	    printk("%s: " FILENAME_BOARDNUM " range is 0...%d\n", dev->name,
-		   MAX_BOARDS - 1);
-	    free_page((unsigned long)page);
-	    return -EINVAL;
-	}
-    }
-    else if (!strcmp(entry->name, FILENAME_TIMESLOTS))
-    {
-	p = page;
-	while (*p)
-	{
-	    if (isspace(*p))
-		p++;
-	    else
-	    {
-		ts = simple_strtoul(p, &p, 10);	/* base = 10: Don't read 09 as an octal number */
-		/* ts = 0 ha nem tudta beolvasni a stringet, erre egy kicsit epitek itt: */
-		if (0 <= ts && ts < 32)
-		{
-		    tmp_timeslots |= (1 << ts);
-		}
-		else
-		{
-		    printk("%s: " FILENAME_TIMESLOTS " range is 1...31\n",
-			   dev->name);
-		    free_page((unsigned long)page);
-		    return -EINVAL;
-		}
-	    }
-	}
-	hw->timeslots = tmp_timeslots;
-    }
-    else if (!strcmp(entry->name, FILENAME_FRAMING))
-    {
-	i = 0;
-	while (slicecom_framings[i].value &&
-	       strncmp(slicecom_framings[i].name, page,
-		       strlen(slicecom_framings[i].name)))
-	    i++;
-	if (!slicecom_framings[i].value)
-	{
-	    printk("slicecom: %s: Invalid " FILENAME_FRAMING " '%s'\n",
-		   dev->name, page);
-	    free_page((unsigned long)page);
-	    return -EINVAL;
-	}
-	else
-	{			/*
-				 * If somebody says:
-				 *      echo >boardnum  0
-				 *      echo >framing   no-crc4
-				 *      echo >boardnum  1
-				 * - when the framing was set, hw->boardnum was 0, so it would set the framing for board 0
-				 * Workaround: allow to set it only if interface is administrative UP
-				 */
-	    if (netif_running(dev))
-		slicecom_set_framing(hw->boardnum, slicecom_framings[i].value);
-	    else
-	    {
-		printk("%s: " FILENAME_FRAMING
-		       " can not be set while the interface is DOWN\n",
-		       dev->name);
-		free_page((unsigned long)page);
-		return -EINVAL;
-	    }
-	}
-    }
-    else if (!strcmp(entry->name, FILENAME_LINECODE))
-    {
-	i = 0;
-	while (slicecom_linecodes[i].value &&
-	       strncmp(slicecom_linecodes[i].name, page,
-		       strlen(slicecom_linecodes[i].name)))
-	    i++;
-	if (!slicecom_linecodes[i].value)
-	{
-	    printk("slicecom: %s: Invalid " FILENAME_LINECODE " '%s'\n",
-		   dev->name, page);
-	    free_page((unsigned long)page);
-	    return -EINVAL;
-	}
-	else
-	{			/*
-				 * Allow to set it only if interface is administrative UP,
-				 * for the same reason as FILENAME_FRAMING
-				 */
-	    if (netif_running(dev))
-		slicecom_set_linecode(hw->boardnum,
-				      slicecom_linecodes[i].value);
-	    else
-	    {
-		printk("%s: " FILENAME_LINECODE
-		       " can not be set while the interface is DOWN\n",
-		       dev->name);
-		free_page((unsigned long)page);
-		return -EINVAL;
-	    }
-	}
-    }
-    else if (!strcmp(entry->name, FILENAME_CLOCK_SOURCE))
-    {
-	i = 0;
-	while (slicecom_clock_sources[i].value &&
-	       strncmp(slicecom_clock_sources[i].name, page,
-		       strlen(slicecom_clock_sources[i].name)))
-	    i++;
-	if (!slicecom_clock_sources[i].value)
-	{
-	    printk("%s: Invalid " FILENAME_CLOCK_SOURCE " '%s'\n", dev->name,
-		   page);
-	    free_page((unsigned long)page);
-	    return -EINVAL;
-	}
-	else
-	{			/*
-				 * Allow to set it only if interface is administrative UP,
-				 * for the same reason as FILENAME_FRAMING
-				 */
-	    if (netif_running(dev))
-		slicecom_set_clock_source(hw->boardnum,
-					  slicecom_clock_sources[i].value);
-	    else
-	    {
-		printk("%s: " FILENAME_CLOCK_SOURCE
-		       " can not be set while the interface is DOWN\n",
-		       dev->name);
-		free_page((unsigned long)page);
-		return -EINVAL;
-	    }
-	}
-    }
-    else if (!strcmp(entry->name, FILENAME_LOOPBACK))
-    {
-	i = 0;
-	while (slicecom_loopbacks[i].value &&
-	       strncmp(slicecom_loopbacks[i].name, page,
-		       strlen(slicecom_loopbacks[i].name)))
-	    i++;
-	if (!slicecom_loopbacks[i].value)
-	{
-	    printk("%s: Invalid " FILENAME_LOOPBACK " '%s'\n", dev->name, page);
-	    free_page((unsigned long)page);
-	    return -EINVAL;
-	}
-	else
-	{			/*
-				 * Allow to set it only if interface is administrative UP,
-				 * for the same reason as FILENAME_FRAMING
-				 */
-	    if (netif_running(dev))
-		slicecom_set_loopback(hw->boardnum,
-				      slicecom_loopbacks[i].value);
-	    else
-	    {
-		printk("%s: " FILENAME_LOOPBACK
-		       " can not be set while the interface is DOWN\n",
-		       dev->name);
-		free_page((unsigned long)page);
-		return -EINVAL;
-	    }
-	}
-    }
-    else if (!strcmp(entry->name, FILENAME_REG))
-    {				/* DEL: 'reg' csak tmp */
-	char *p;
-	u32 *bar1 = board->bar1;
-
-	reg = simple_strtoul(page, &p, 0);
-	reg_ertek = simple_strtoul(p + 1, NULL, 0);
-
-	if (reg < 0x100)
-	{
-	    printk("reg(0x%02x) := 0x%08x  jiff: %lu\n", reg, reg_ertek, jiffies);
-	    writel(reg_ertek, MUNICH_VIRT(reg >> 2));
-	}
-	else
-	{
-	    printk("reg(0x%02x) is 0x%08x  jiff: %lu\n", reg - 0x100,
-		   readl(MUNICH_VIRT((reg - 0x100) >> 2)), jiffies);
-	}
-    }
-    else if (!strcmp(entry->name, FILENAME_LBIREG))
-    {				/* DEL: 'lbireg' csak tmp */
-	char *p;
-	u8 *lbi = board->lbi;
-
-	lbireg = simple_strtoul(page, &p, 0);
-	lbireg_ertek = simple_strtoul(p + 1, NULL, 0);
-
-	if (lbireg < 0x100)
-	{
-	    printk("lbireg(0x%02x) := 0x%02x  jiff: %lu\n", lbireg,
-		   lbireg_ertek, jiffies);
-	    writeb(lbireg_ertek, lbi + lbireg);
-	}
-	else
-	    printk("lbireg(0x%02x) is 0x%02x  jiff: %lu\n", lbireg - 0x100,
-		   readb(lbi + lbireg - 0x100), jiffies);
-    }
-    else
-    {
-	printk(KERN_ERR "munich_write_proc: internal error, filename %s\n",
-	       entry->name);
-	free_page((unsigned long)page);
-	return -EBADF;
-    }
-
-    /* Don't forget to free the workspace */
-    free_page((unsigned long)page);
-    return count;
-}
-
-/* 
- * Boardtype init function.
- * Called by the comx (upper) layer, when you set boardtype.
- * Allocates resources associated to using munich board for this device,
- * initializes ch_struct pointers etc.
- * Returns 0 on success and standard error codes on error.
- */
-
-static int init_escape(struct comx_channel *ch)
-{
-    kfree(ch->HW_privdata);
-    return -EIO;
-}
-
-static int BOARD_init(struct net_device *dev)
-{
-    struct comx_channel *ch = netdev_priv(dev);
-    struct slicecom_privdata *hw;
-    struct proc_dir_entry *new_file;
-
-    /* Alloc data for private structure */
-    if ((ch->HW_privdata =
-	kmalloc(sizeof(struct slicecom_privdata), GFP_KERNEL)) == NULL)
-        return -ENOMEM;
-        
-    memset(hw = ch->HW_privdata, 0, sizeof(struct slicecom_privdata));
-
-    /* Register /proc files */
-    if ((new_file = create_proc_entry(FILENAME_BOARDNUM, S_IFREG | 0644,
-			   ch->procdir)) == NULL)
-	return init_escape(ch);
-    new_file->data = (void *)new_file;
-    new_file->read_proc = &munich_read_proc;
-    new_file->write_proc = &munich_write_proc;
-//      new_file->proc_iops = &comx_normal_inode_ops;
-    new_file->nlink = 1;
-
-    if (ch->hardware == &slicecomhw)
-    {
-	if ((new_file = create_proc_entry(FILENAME_TIMESLOTS, S_IFREG | 0644,
-			       ch->procdir)) == NULL)
-	    return init_escape(ch);
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &munich_read_proc;
-	new_file->write_proc = &munich_write_proc;
-//              new_file->proc_iops = &comx_normal_inode_ops;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_FRAMING, S_IFREG | 0644,
-			       ch->procdir)) == NULL)
-	    return init_escape(ch);
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &munich_read_proc;
-	new_file->write_proc = &munich_write_proc;
-//              new_file->proc_iops = &comx_normal_inode_ops;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_LINECODE, S_IFREG | 0644,
-			       ch->procdir)) == NULL)
-	    return init_escape(ch);
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &munich_read_proc;
-	new_file->write_proc = &munich_write_proc;
-//              new_file->proc_iops = &comx_normal_inode_ops;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_CLOCK_SOURCE, S_IFREG | 0644,
-			       ch->procdir)) == NULL)
-	    return init_escape(ch);
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &munich_read_proc;
-	new_file->write_proc = &munich_write_proc;
-//              new_file->proc_iops = &comx_normal_inode_ops;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_LOOPBACK, S_IFREG | 0644,
-			       ch->procdir)) == NULL)
-	    return init_escape(ch);
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &munich_read_proc;
-	new_file->write_proc = &munich_write_proc;
-//              new_file->proc_iops = &comx_normal_inode_ops;
-	new_file->nlink = 1;
-    }
-
-    /* DEL: ez itt csak fejlesztesi celokra!! */
-    if ((new_file = create_proc_entry(FILENAME_REG, S_IFREG | 0200, ch->procdir)) == NULL)
-	return init_escape(ch);
-    new_file->data = (void *)new_file;
-    new_file->read_proc = &munich_read_proc;
-    new_file->write_proc = &munich_write_proc;
-//      new_file->proc_iops = &comx_normal_inode_ops;
-    new_file->nlink = 1;
-
-    /* DEL: ez itt csak fejlesztesi celokra!! */
-    if ((new_file = create_proc_entry(FILENAME_LBIREG, S_IFREG | 0200,
-			   ch->procdir)) == NULL)
-	return init_escape(ch);
-    new_file->data = (void *)new_file;
-    new_file->read_proc = &munich_read_proc;
-    new_file->write_proc = &munich_write_proc;
-//      new_file->proc_iops = &comx_normal_inode_ops;
-    new_file->nlink = 1;
-
-    /* Fill in ch_struct hw specific pointers: */
-
-    ch->HW_txe = MUNICH_txe;
-    ch->HW_open = MUNICH_open;
-    ch->HW_close = MUNICH_close;
-    ch->HW_send_packet = MUNICH_send_packet;
-#ifndef COMX_NEW
-    ch->HW_minden = MUNICH_minden;
-#else
-    ch->HW_statistics = MUNICH_minden;
-#endif
-
-    hw->boardnum = SLICECOM_BOARDNUM_DEFAULT;
-    hw->timeslots = ch->hardware == &pcicomhw ?  0xffffffff : 2;
-
-    /* O.K. Count one more user on this module */
-    MOD_INC_USE_COUNT;
-    return 0;
-}
-
-/* 
- * Boardtype exit function.
- * Called by the comx (upper) layer, when you clear boardtype from munich.
- * Frees resources associated to using munich board for this device,
- * resets ch_struct pointers etc.
- */
-static int BOARD_exit(struct net_device *dev)
-{
-    struct comx_channel *ch = netdev_priv(dev);
-
-    /* Free private data area */
-//    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
-
-    kfree(ch->HW_privdata);
-    /* Remove /proc files */
-    remove_proc_entry(FILENAME_BOARDNUM, ch->procdir);
-    if (ch->hardware == &slicecomhw)
-    {
-	remove_proc_entry(FILENAME_TIMESLOTS, ch->procdir);
-	remove_proc_entry(FILENAME_FRAMING, ch->procdir);
-	remove_proc_entry(FILENAME_LINECODE, ch->procdir);
-	remove_proc_entry(FILENAME_CLOCK_SOURCE, ch->procdir);
-	remove_proc_entry(FILENAME_LOOPBACK, ch->procdir);
-    }
-    remove_proc_entry(FILENAME_REG, ch->procdir);
-    remove_proc_entry(FILENAME_LBIREG, ch->procdir);
-
-    /* Minus one user for the module accounting */
-    MOD_DEC_USE_COUNT;
-    return 0;
-}
-
-static struct comx_hardware slicecomhw =
-{
-    "slicecom",
-#ifdef COMX_NEW
-    VERSION,
-#endif
-    BOARD_init,
-    BOARD_exit,
-    BOARD_dump,
-    NULL
-};
-
-static struct comx_hardware pcicomhw =
-{
-    "pcicom",
-#ifdef COMX_NEW
-    VERSION,
-#endif
-    BOARD_init,
-    BOARD_exit,
-    BOARD_dump,
-    NULL
-};
-
-/* Module management */
-
-static int __init init_mister(void)
-{
-    printk(VERSIONSTR);
-    comx_register_hardware(&slicecomhw);
-    comx_register_hardware(&pcicomhw);
-    return munich_probe();
-}
-
-static void __exit cleanup_mister(void)
-{
-    int i;
-
-    comx_unregister_hardware("slicecom");
-    comx_unregister_hardware("pcicom");
-
-    for (i = 0; i < MAX_BOARDS; i++)
-    {
-	if (slicecom_boards[i].bar1)
-	    iounmap((void *)slicecom_boards[i].bar1);
-	if (slicecom_boards[i].lbi)
-	    iounmap((void *)slicecom_boards[i].lbi);
-	if (pcicom_boards[i].bar1)
-	    iounmap((void *)pcicom_boards[i].bar1);
-	if (pcicom_boards[i].lbi)
-	    iounmap((void *)pcicom_boards[i].lbi);
-    }
-}
-
-module_init(init_mister);
-module_exit(cleanup_mister);
===== drivers/net/wan/comx-proto-fr.c 1.13 vs edited =====
--- 1.13/drivers/net/wan/comx-proto-fr.c	Thu Sep 11 19:40:53 2003
+++ edited/drivers/net/wan/comx-proto-fr.c	Fri May  7 13:05:52 2004
@@ -1,1014 +1 @@
-/*
- * Frame-relay protocol module for the COMX driver 
- * for Linux 2.2.X
- *
- * Original author: Tivadar Szemethy <tiv@itc.hu>
- * Maintainer: Gergely Madarasz <gorgo@itc.hu>
- *
- * Copyright (C) 1998-1999 ITConsult-Pro Co. <info@itc.hu>
- * 
- * Contributors:
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br> (0.73)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Version 0.70 (99/06/14):
- *		- cleaned up the source code a bit
- *		- ported back to kernel, now works as builtin code 
- *
- * Version 0.71 (99/06/25):
- *		- use skb priorities and queues for sending keepalive
- * 		- use device queues for slave->master data transmit
- *		- set IFF_RUNNING only line protocol up
- *		- fixes on slave device flags
- * 
- * Version 0.72 (99/07/09):
- *		- handle slave tbusy with master tbusy (should be fixed)
- *		- fix the keepalive timer addition/deletion
- *
- * Version 0.73 (00/08/15)
- * 		- resource release on failure at fr_master_init and
- *		  fr_slave_init 		  
- */
 
-#define VERSION "0.73"
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/jiffies.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/if_arp.h>
-#include <linux/inetdevice.h>
-#include <linux/pkt_sched.h>
-#include <linux/init.h>
-
-#include <asm/uaccess.h>
-
-#include "comx.h"
-#include "comxhw.h"
-
-MODULE_AUTHOR("Author: Tivadar Szemethy <tiv@itc.hu>");
-MODULE_DESCRIPTION("Frame Relay protocol implementation for the COMX drivers"
-	"for Linux kernel 2.4.X");
-MODULE_LICENSE("GPL");
-
-#define	FRAD_UI		0x03
-#define	NLPID_IP	0xcc
-#define	NLPID_Q933_LMI	0x08
-#define	NLPID_CISCO_LMI	0x09	
-#define Q933_ENQ	0x75
-#define	Q933_LINESTAT	0x51
-#define	Q933_COUNTERS	0x53
-
-#define	MAXALIVECNT	3		/* No. of failures */
-
-struct fr_data {
-	u16	dlci;
-	struct	net_device *master;
-	char	keepa_pend;
-	char	keepa_freq;
-	char	keepalivecnt, keeploopcnt;
-	struct	timer_list keepa_timer;
-	u8	local_cnt, remote_cnt;
-};
-
-static struct comx_protocol fr_master_protocol;
-static struct comx_protocol fr_slave_protocol;
-static struct comx_hardware fr_dlci;
-
-static void fr_keepalive_send(struct net_device *dev) 
-{
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = ch->LINE_privdata;
-	struct sk_buff *skb;
-	u8 *fr_packet;
-	
-	skb=alloc_skb(dev->hard_header_len + 13, GFP_ATOMIC);
-	
-	if(skb==NULL)
-		return;
-               
-        skb_reserve(skb, dev->hard_header_len);
-        
-        fr_packet=(u8*)skb_put(skb, 13);
-                 
-	fr_packet[0] = (fr->dlci & (1024 - 15)) >> 2;
-	fr_packet[1] = (fr->dlci & 15) << 4 | 1;	// EA bit 1
-	fr_packet[2] = FRAD_UI;
-	fr_packet[3] = NLPID_Q933_LMI;
-	fr_packet[4] = 0;
-	fr_packet[5] = Q933_ENQ;
-	fr_packet[6] = Q933_LINESTAT;
-	fr_packet[7] = 0x01;
-	fr_packet[8] = 0x01;
-	fr_packet[9] = Q933_COUNTERS;
-	fr_packet[10] = 0x02;
-	fr_packet[11] = ++fr->local_cnt;
-	fr_packet[12] = fr->remote_cnt;
-
-	skb->dev = dev;
-	skb->priority = TC_PRIO_CONTROL;
-	dev_queue_xmit(skb);
-}
-
-static void fr_keepalive_timerfun(unsigned long d) 
-{
-	struct net_device *dev = (struct net_device *)d;
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = ch->LINE_privdata;
-	struct proc_dir_entry *dir = ch->procdir->parent->subdir;
-	struct comx_channel *sch;
-	struct fr_data *sfr;
-	struct net_device *sdev;
-
-	if (ch->init_status & LINE_OPEN) {
-		if (fr->keepalivecnt == MAXALIVECNT) {
-			comx_status(dev, ch->line_status & ~PROTO_UP);
-			dev->flags &= ~IFF_RUNNING;
-			for (; dir ; dir = dir->next) {
-				if(!S_ISDIR(dir->mode)) {
-				    continue;
-				}
-	
-				if ((sdev = dir->data) && (sch = sdev->priv) && 
-				    (sdev->type == ARPHRD_DLCI) && 
-				    (sfr = sch->LINE_privdata) 
-				    && (sfr->master == dev) && 
-				    (sdev->flags & IFF_UP)) {
-					sdev->flags &= ~IFF_RUNNING;
-					comx_status(sdev, 
-						sch->line_status & ~PROTO_UP);
-				}
-			}
-		}
-		if (fr->keepalivecnt <= MAXALIVECNT) {
-			++fr->keepalivecnt;
-		}
-		fr_keepalive_send(dev);
-	}
-	mod_timer(&fr->keepa_timer, jiffies + HZ * fr->keepa_freq);
-}
-
-static void fr_rx_lmi(struct net_device *dev, struct sk_buff *skb, 
-	u16 dlci, u8 nlpid) 
-{
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = ch->LINE_privdata;
-	struct proc_dir_entry *dir = ch->procdir->parent->subdir;
-	struct comx_channel *sch;
-	struct fr_data *sfr;
-	struct net_device *sdev;
-
-	if (dlci != fr->dlci || nlpid != NLPID_Q933_LMI || !fr->keepa_freq) {
-		return;
-	}
-
-	fr->remote_cnt = skb->data[7];
-	if (skb->data[8] == fr->local_cnt) { // keepalive UP!
-		fr->keepalivecnt = 0;
-		if ((ch->line_status & LINE_UP) && 
-		    !(ch->line_status & PROTO_UP)) {
-			comx_status(dev, ch->line_status |= PROTO_UP);
-			dev->flags |= IFF_RUNNING;
-			for (; dir ; dir = dir->next) {
-				if(!S_ISDIR(dir->mode)) {
-				    continue;
-				}
-	
-				if ((sdev = dir->data) && (sch = sdev->priv) && 
-				    (sdev->type == ARPHRD_DLCI) && 
-				    (sfr = sch->LINE_privdata) 
-				    && (sfr->master == dev) && 
-				    (sdev->flags & IFF_UP)) {
-					sdev->flags |= IFF_RUNNING;
-					comx_status(sdev, 
-						sch->line_status | PROTO_UP);
-				}
-			}
-		}
-	}
-}
-
-static void fr_set_keepalive(struct net_device *dev, int keepa) 
-{
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = ch->LINE_privdata;
-
-	if (!keepa && fr->keepa_freq) { // switch off
-		fr->keepa_freq = 0;
-		if (ch->line_status & LINE_UP) {
-			comx_status(dev, ch->line_status | PROTO_UP);
-			dev->flags |= IFF_RUNNING;
-			del_timer(&fr->keepa_timer);
-		}
-		return;
-	}
-
-	if (keepa) { // bekapcs
-		if(fr->keepa_freq && (ch->line_status & LINE_UP)) {
-			del_timer(&fr->keepa_timer);
-		}
-		fr->keepa_freq = keepa;
-		fr->local_cnt = fr->remote_cnt = 0;
-		init_timer(&fr->keepa_timer);
-		fr->keepa_timer.expires = jiffies + HZ;
-		fr->keepa_timer.function = fr_keepalive_timerfun;
-		fr->keepa_timer.data = (unsigned long)dev;
-		ch->line_status &= ~(PROTO_UP | PROTO_LOOP);
-		dev->flags &= ~IFF_RUNNING;
-		comx_status(dev, ch->line_status);
-		if(ch->line_status & LINE_UP) {
-			add_timer(&fr->keepa_timer);
-		}
-	}
-}
-
-static void fr_rx(struct net_device *dev, struct sk_buff *skb) 
-{
-	struct comx_channel *ch = dev->priv;
-	struct proc_dir_entry *dir = ch->procdir->parent->subdir;
-	struct net_device *sdev = dev;
-	struct comx_channel *sch;
-	struct fr_data *sfr;
-	u16 dlci;
-	u8 nlpid;
-
-	if(skb->len <= 4 || skb->data[2] != FRAD_UI) {
-		kfree_skb(skb);
-		return;
-	}
-
-	/* Itt majd ki kell talalni, melyik slave kapja a csomagot */
-	dlci = ((skb->data[0] & 0xfc) << 2) | ((skb->data[1] & 0xf0) >> 4);
-	if ((nlpid = skb->data[3]) == 0) { // Optional padding 
-		nlpid = skb->data[4];
-		skb_pull(skb, 1);
-	}
-	skb_pull(skb, 4);	/* DLCI and header throw away */
-
-	if (ch->debug_flags & DEBUG_COMX_DLCI) {
-		comx_debug(dev, "Frame received, DLCI: %d, NLPID: 0x%02x\n", 
-			dlci, nlpid);
-		comx_debug_skb(dev, skb, "Contents");
-	}
-
-	/* Megkeressuk, kihez tartozik */
-	for (; dir ; dir = dir->next) {
-		if(!S_ISDIR(dir->mode)) {
-			continue;
-		}
-		if ((sdev = dir->data) && (sch = sdev->priv) && 
-		    (sdev->type == ARPHRD_DLCI) && (sfr = sch->LINE_privdata) &&
-		    (sfr->master == dev) && (sfr->dlci == dlci)) {
-			skb->dev = sdev;	
-			if (ch->debug_flags & DEBUG_COMX_DLCI) {
-				comx_debug(dev, "Passing it to %s\n",sdev->name);
-			}
-			if (dev != sdev) {
-				sch->stats.rx_packets++;
-				sch->stats.rx_bytes += skb->len;
-			}
-			break;
-		}
-	}
-	switch(nlpid) {
-		case NLPID_IP:
-			skb->protocol = htons(ETH_P_IP);
-			skb->mac.raw = skb->data;
-			comx_rx(sdev, skb);
-			break;
-		case NLPID_Q933_LMI:
-			fr_rx_lmi(dev, skb, dlci, nlpid);
-		default:
-			kfree_skb(skb);
-			break;
-	}
-}
-
-static int fr_tx(struct net_device *dev) 
-{
-	struct comx_channel *ch = dev->priv;
-	struct proc_dir_entry *dir = ch->procdir->parent->subdir;
-	struct net_device *sdev;
-	struct comx_channel *sch;
-	struct fr_data *sfr;
-	int cnt = 1;
-
-	/* Ha minden igaz, 2 helyen fog allni a tbusy: a masternel, 
-	   es annal a slave-nel aki eppen kuldott.
-	   Egy helyen akkor all, ha a master kuldott.
-	   Ez megint jo lesz majd, ha utemezni akarunk */
-	   
-	/* This should be fixed, the slave tbusy should be set when 
-	   the masters queue is full and reset when not */
-
-	for (; dir ; dir = dir->next) {
-		if(!S_ISDIR(dir->mode)) {
-		    continue;
-		}
-		if ((sdev = dir->data) && (sch = sdev->priv) && 
-		    (sdev->type == ARPHRD_DLCI) && (sfr = sch->LINE_privdata) &&
-		    (sfr->master == dev) && (netif_queue_stopped(sdev))) {
-		    	netif_wake_queue(sdev);
-			cnt++;
-		}
-	}
-
-	netif_wake_queue(dev);
-	return 0;
-}
-
-static void fr_status(struct net_device *dev, unsigned short status)
-{
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = ch->LINE_privdata;
-	struct proc_dir_entry *dir = ch->procdir->parent->subdir;
-	struct net_device *sdev;
-	struct comx_channel *sch;
-	struct fr_data *sfr;
-
-	if (status & LINE_UP) {
-		if (!fr->keepa_freq) {
-			status |= PROTO_UP;
-		}
-	} else {
-		status &= ~(PROTO_UP | PROTO_LOOP);
-	}
-
-	if (dev == fr->master && fr->keepa_freq) {
-		if (status & LINE_UP) {
-			fr->keepa_timer.expires = jiffies + HZ;
-			add_timer(&fr->keepa_timer);
-			fr->keepalivecnt = MAXALIVECNT + 1;
-			fr->keeploopcnt = 0;
-		} else {
-			del_timer(&fr->keepa_timer);
-		}
-	}
-		
-	/* Itt a status valtozast vegig kell vinni az osszes slave-n */
-	for (; dir ; dir = dir->next) {
-		if(!S_ISDIR(dir->mode)) {
-		    continue;
-		}
-	
-		if ((sdev = dir->data) && (sch = sdev->priv) && 
-		    (sdev->type == ARPHRD_FRAD || sdev->type == ARPHRD_DLCI) && 
-		    (sfr = sch->LINE_privdata) && (sfr->master == dev)) {
-			if(status & LINE_UP) {
-				netif_wake_queue(sdev);
-			}
-			comx_status(sdev, status);
-			if(status & (PROTO_UP | PROTO_LOOP)) {
-				dev->flags |= IFF_RUNNING;
-			} else {
-				dev->flags &= ~IFF_RUNNING;
-			}
-		}
-	}
-}
-
-static int fr_open(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = ch->LINE_privdata;
-	struct proc_dir_entry *comxdir = ch->procdir;
-	struct comx_channel *mch;
-
-	if (!(ch->init_status & HW_OPEN)) {
-		return -ENODEV;
-	}
-
-	if ((ch->hardware == &fr_dlci && ch->protocol != &fr_slave_protocol) ||
-	    (ch->protocol == &fr_slave_protocol && ch->hardware != &fr_dlci)) {
-		printk(KERN_ERR "Trying to open an improperly set FR interface, giving up\n");
-		return -EINVAL;
-	}
-
-	if (!fr->master) {
-		return -ENODEV;
-	}
-	mch = fr->master->priv;
-	if (fr->master != dev && (!(mch->init_status & LINE_OPEN) 
-	   || (mch->protocol != &fr_master_protocol))) {
-		printk(KERN_ERR "Master %s is inactive, or incorrectly set up, "
-			"unable to open %s\n", fr->master->name, dev->name);
-		return -ENODEV;
-	}
-
-	ch->init_status |= LINE_OPEN;
-	ch->line_status &= ~(PROTO_UP | PROTO_LOOP);
-	dev->flags &= ~IFF_RUNNING;
-
-	if (fr->master == dev) {
-		if (fr->keepa_freq) {
-			fr->keepa_timer.function = fr_keepalive_timerfun;
-			fr->keepa_timer.data = (unsigned long)dev;
-			add_timer(&fr->keepa_timer);
-		} else {
-			if (ch->line_status & LINE_UP) {
-				ch->line_status |= PROTO_UP;
-				dev->flags |= IFF_RUNNING;
-			}
-		}
-	} else {
-		ch->line_status = mch->line_status;
-		if(fr->master->flags & IFF_RUNNING) {
-			dev->flags |= IFF_RUNNING;
-		}
-	}
-
-	for (; comxdir ; comxdir = comxdir->next) {
-		if (strcmp(comxdir->name, FILENAME_DLCI) == 0 ||
-		   strcmp(comxdir->name, FILENAME_MASTER) == 0 ||
-		   strcmp(comxdir->name, FILENAME_KEEPALIVE) == 0) {
-			comxdir->mode = S_IFREG | 0444;
-		}
-	}
-//	comx_status(dev, ch->line_status);
-	return 0;
-}
-
-static int fr_close(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = ch->LINE_privdata;
-	struct proc_dir_entry *comxdir = ch->procdir;
-
-	if (fr->master == dev) { // Ha master 
-		struct proc_dir_entry *dir = ch->procdir->parent->subdir;
-		struct net_device *sdev = dev;
-		struct comx_channel *sch;
-		struct fr_data *sfr;
-
-		if (!(ch->init_status & HW_OPEN)) {
-			return -ENODEV;
-		}
-
-		if (fr->keepa_freq) {
-			del_timer(&fr->keepa_timer);
-		}
-		
-		for (; dir ; dir = dir->next) {
-			if(!S_ISDIR(dir->mode)) {
-				continue;
-			}
-			if ((sdev = dir->data) && (sch = sdev->priv) && 
-			    (sdev->type == ARPHRD_DLCI) && 
-			    (sfr = sch->LINE_privdata) &&
-			    (sfr->master == dev) && 
-			    (sch->init_status & LINE_OPEN)) {
-				dev_close(sdev);
-			}
-		}
-	}
-
-	ch->init_status &= ~LINE_OPEN;
-	ch->line_status &= ~(PROTO_UP | PROTO_LOOP);
-	dev->flags &= ~IFF_RUNNING;
-
-	for (; comxdir ; comxdir = comxdir->next) {
-		if (strcmp(comxdir->name, FILENAME_DLCI) == 0 ||
-		    strcmp(comxdir->name, FILENAME_MASTER) == 0 ||
-		    strcmp(comxdir->name, FILENAME_KEEPALIVE) == 0) {
-			comxdir->mode = S_IFREG | 0444;
-		}
-	}
-
-	return 0;
-}
-
-static int fr_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct comx_channel *sch, *mch;
-	struct fr_data *fr = ch->LINE_privdata;
-	struct fr_data *sfr;
-	struct net_device *sdev;
-	struct proc_dir_entry *dir = ch->procdir->parent->subdir;
-
-	if (!fr->master) {
-		printk(KERN_ERR "BUG: fr_xmit without a master!!! dev: %s\n", dev->name);
-		return 0;
-	}
-
-	mch = fr->master->priv;
-
-	/* Ennek majd a slave utemezeskor lesz igazan jelentosege */
-	if (ch->debug_flags & DEBUG_COMX_DLCI) {
-		comx_debug_skb(dev, skb, "Sending frame");
-	}
-
-	if (dev != fr->master) {
-		struct sk_buff *newskb=skb_clone(skb, GFP_ATOMIC);
-		if (!newskb)
-			return -ENOMEM;
-		newskb->dev=fr->master;
-		dev_queue_xmit(newskb);
-		ch->stats.tx_bytes += skb->len;
-		ch->stats.tx_packets++;
-		dev_kfree_skb(skb);
-	} else {
-		netif_stop_queue(dev);
-		for (; dir ; dir = dir->next) {
-			if(!S_ISDIR(dir->mode)) {
-			    continue;
-			}
-			if ((sdev = dir->data) && (sch = sdev->priv) && 
-			    (sdev->type == ARPHRD_DLCI) && (sfr = sch->LINE_privdata) &&
-			    (sfr->master == dev) && (netif_queue_stopped(sdev))) {
-				netif_stop_queue(sdev);
-			}
-		}
-		 	
-		switch(mch->HW_send_packet(dev, skb)) {
-			case FRAME_QUEUED:
-				netif_wake_queue(dev);
-				break;
-			case FRAME_ACCEPTED:
-			case FRAME_DROPPED:
-				break;
-			case FRAME_ERROR:
-				printk(KERN_ERR "%s: Transmit frame error (len %d)\n", 
-					dev->name, skb->len);
-				break;
-		}
-	}
-	return 0;
-}
-
-static int fr_header(struct sk_buff *skb, struct net_device *dev, 
-	unsigned short type, void *daddr, void *saddr, unsigned len) 
-{
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = ch->LINE_privdata;
-
-	skb_push(skb, dev->hard_header_len);	  
-	/* Put in DLCI */
-	skb->data[0] = (fr->dlci & (1024 - 15)) >> 2;
-	skb->data[1] = (fr->dlci & 15) << 4 | 1;	// EA bit 1
-	skb->data[2] = FRAD_UI;
-	skb->data[3] = NLPID_IP;
-
-	return dev->hard_header_len;  
-}
-
-static int fr_statistics(struct net_device *dev, char *page) 
-{
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = ch->LINE_privdata;
-	int len = 0;
-
-	if (fr->master == dev) {
-		struct proc_dir_entry *dir = ch->procdir->parent->subdir;
-		struct net_device *sdev;
-		struct comx_channel *sch;
-		struct fr_data *sfr;
-		int slaves = 0;
-
-		len += sprintf(page + len, 
-			"This is a Frame Relay master device\nSlaves: ");
-		for (; dir ; dir = dir->next) {
-			if(!S_ISDIR(dir->mode)) {
-				continue;
-			}
-			if ((sdev = dir->data) && (sch = sdev->priv) && 
-			    (sdev->type == ARPHRD_DLCI) &&
-			    (sfr = sch->LINE_privdata) && 
-			    (sfr->master == dev) && (sdev != dev)) {
-				slaves++;
-				len += sprintf(page + len, "%s ", sdev->name);
-			}
-		}
-		len += sprintf(page + len, "%s\n", slaves ? "" : "(none)");
-		if (fr->keepa_freq) {
-			len += sprintf(page + len, "Line keepalive (value %d) "
-				"status %s [%d]\n", fr->keepa_freq, 
-				ch->line_status & PROTO_LOOP ? "LOOP" :
-				ch->line_status & PROTO_UP ? "UP" : "DOWN", 
-				fr->keepalivecnt);
-		} else {
-			len += sprintf(page + len, "Line keepalive protocol "
-				"is not set\n");
-		}
-	} else {		// if slave
-		len += sprintf(page + len, 
-			"This is a Frame Relay slave device, master: %s\n",
-			fr->master ? fr->master->name : "(not set)");
-	}
-	return len;
-}
-
-static int fr_read_proc(char *page, char **start, off_t off, int count,
-	int *eof, void *data)
-{
-	struct proc_dir_entry *file = (struct proc_dir_entry *)data;
-	struct net_device *dev = file->parent->data;
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = NULL;
-	int len = 0;
-
-	if (ch) {
-		fr = ch->LINE_privdata;
-	}
-
-	if (strcmp(file->name, FILENAME_DLCI) == 0) {
-		len = sprintf(page, "%04d\n", fr->dlci);
-	} else if (strcmp(file->name, FILENAME_MASTER) == 0) {
-		len = sprintf(page, "%-9s\n", fr->master ? fr->master->name :
-			"(none)");
-	} else if (strcmp(file->name, FILENAME_KEEPALIVE) == 0) {
-		len = fr->keepa_freq ? sprintf(page, "% 3d\n", fr->keepa_freq) 
-			: sprintf(page, "off\n");
-	} else {
-		printk(KERN_ERR "comxfr: internal error, filename %s\n", file->name);
-		return -EBADF;
-	}
-
-	if (off >= len) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = page + off;
-	if (count >= len - off) *eof = 1;
-	return min_t(int, count, len - off);
-}
-
-static int fr_write_proc(struct file *file, const char *buffer, 
-	u_long count, void *data)
-{
-	struct proc_dir_entry *entry = (struct proc_dir_entry *)data;
-	struct net_device *dev = entry->parent->data;
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = NULL; 
-	char *page;
-
-	if (ch) {
-		fr = ch->LINE_privdata;
-	}
-
-	if (!(page = (char *)__get_free_page(GFP_KERNEL))) {
-		return -ENOMEM;
-	}
-
-	if (copy_from_user(page, buffer, count)) {
-		free_page((unsigned long)page);
-		return -EFAULT;
-	}
-	if (*(page + count - 1) == '\n') {
-		*(page + count - 1) = 0;
-	}
-
-	if (strcmp(entry->name, FILENAME_DLCI) == 0) {
-		u16 dlci_new = simple_strtoul(page, NULL, 10);
-
-		if (dlci_new > 1023) {
-			printk(KERN_ERR "Invalid DLCI value\n");
-		}
-		else fr->dlci = dlci_new;
-	} else if (strcmp(entry->name, FILENAME_MASTER) == 0) {
-		struct net_device *new_master = dev_get_by_name(page);
-
-		if (new_master && new_master->type == ARPHRD_FRAD) {
-			struct comx_channel *sch = new_master->priv;
-			struct fr_data *sfr = sch->LINE_privdata;
-
-			if (sfr && sfr->master == new_master) {
-				if(fr->master)
-					dev_put(fr->master);
-				fr->master = new_master;
-				/* Megorokli a master statuszat */
-				ch->line_status = sch->line_status;
-			}
-		}
-	} else if (strcmp(entry->name, FILENAME_KEEPALIVE) == 0) {
-		int keepa_new = -1;
-
-		if (strcmp(page, KEEPALIVE_OFF) == 0) {
-			keepa_new = 0;
-		} else {
-			keepa_new = simple_strtoul(page, NULL, 10);
-		}
-
-		if (keepa_new < 0 || keepa_new > 100) {
-			printk(KERN_ERR "invalid keepalive\n");
-		} else {
-			if (fr->keepa_freq && keepa_new != fr->keepa_freq) {
-				fr_set_keepalive(dev, 0);
-			}
-			if (keepa_new) {
-				fr_set_keepalive(dev, keepa_new);
-			}
-		}
-	} else {
-		printk(KERN_ERR "comxfr_write_proc: internal error, filename %s\n", 
-			entry->name);
-		count = -EBADF;
-	}
-
-	free_page((unsigned long)page);
-	return count;
-}
-
-static int fr_exit(struct net_device *dev) 
-{
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = ch->LINE_privdata;
-	struct net_device *sdev = dev;
-	struct comx_channel *sch;
-	struct fr_data *sfr;
-	struct proc_dir_entry *dir = ch->procdir->parent->subdir;
-
-	/* Ha lezarunk egy master-t, le kell kattintani a slave-eket is */
-	if (fr->master && fr->master == dev) {
-		for (; dir ; dir = dir->next) {
-			if(!S_ISDIR(dir->mode)) {
-				continue;
-			}
-			if ((sdev = dir->data) && (sch = sdev->priv) && 
-			    (sdev->type == ARPHRD_DLCI) && 
-			    (sfr = sch->LINE_privdata) && (sfr->master == dev)) {
-				dev_close(sdev);
-				sfr->master = NULL;
-			}
-		}
-	}
-	dev->flags		= 0;
-	dev->type		= 0;
-	dev->mtu		= 0;
-	dev->hard_header_len    = 0;
-
-	ch->LINE_rx	= NULL;
-	ch->LINE_tx	= NULL;
-	ch->LINE_status = NULL;
-	ch->LINE_open	= NULL;
-	ch->LINE_close	= NULL;
-	ch->LINE_xmit	= NULL;
-	ch->LINE_header	= NULL;
-	ch->LINE_rebuild_header	= NULL;
-	ch->LINE_statistics = NULL;
-
-	ch->LINE_status = 0;
-
-	if (fr->master != dev) { // if not master, remove dlci
-		if(fr->master)
-			dev_put(fr->master);
-		remove_proc_entry(FILENAME_DLCI, ch->procdir);
-		remove_proc_entry(FILENAME_MASTER, ch->procdir);
-	} else {
-		if (fr->keepa_freq) {
-			fr_set_keepalive(dev, 0);
-		}
-		remove_proc_entry(FILENAME_KEEPALIVE, ch->procdir);
-		remove_proc_entry(FILENAME_DLCI, ch->procdir);
-	}
-
-	kfree(fr);
-	ch->LINE_privdata = NULL;
-
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-static int fr_master_init(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr;
-	struct proc_dir_entry *new_file;
-
-	if ((fr = ch->LINE_privdata = kmalloc(sizeof(struct fr_data), 
-	    GFP_KERNEL)) == NULL) {
-		return -ENOMEM;
-	}
-	memset(fr, 0, sizeof(struct fr_data));
-	fr->master = dev;	// this means master
-	fr->dlci = 0;		// let's say default
-
-	dev->flags	= IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-	dev->type	= ARPHRD_FRAD;
-	dev->mtu	= 1500;
-	dev->hard_header_len    = 4;		
-	dev->addr_len	= 0;
-
-	ch->LINE_rx	= fr_rx;
-	ch->LINE_tx	= fr_tx;
-	ch->LINE_status = fr_status;
-	ch->LINE_open	= fr_open;
-	ch->LINE_close	= fr_close;
-	ch->LINE_xmit	= fr_xmit;
-	ch->LINE_header	= fr_header;
-	ch->LINE_rebuild_header	= NULL;
-	ch->LINE_statistics = fr_statistics;
-
-	if ((new_file = create_proc_entry(FILENAME_DLCI, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-		goto cleanup_LINE_privdata;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &fr_read_proc;
-	new_file->write_proc = &fr_write_proc;
-	new_file->size = 5;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_KEEPALIVE, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-		goto cleanup_filename_dlci;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &fr_read_proc;
-	new_file->write_proc = &fr_write_proc;
-	new_file->size = 4;
-	new_file->nlink = 1;
-
-	fr_set_keepalive(dev, 0);
-
-	MOD_INC_USE_COUNT;
-	return 0;
-cleanup_filename_dlci:
-	 remove_proc_entry(FILENAME_DLCI, ch->procdir);
-cleanup_LINE_privdata:
-	kfree(fr);
-	return -EIO;
-}
-
-static int fr_slave_init(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr;
-	struct proc_dir_entry *new_file;
-
-	if ((fr = ch->LINE_privdata = kmalloc(sizeof(struct fr_data), 
-	    GFP_KERNEL)) == NULL) {
-		return -ENOMEM;
-	}
-	memset(fr, 0, sizeof(struct fr_data));
-
-	dev->flags	= IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-	dev->type	= ARPHRD_DLCI;
-	dev->mtu	= 1500;
-	dev->hard_header_len    = 4;		
-	dev->addr_len	= 0;
-
-	ch->LINE_rx	= fr_rx;
-	ch->LINE_tx	= fr_tx;
-	ch->LINE_status = fr_status;
-	ch->LINE_open	= fr_open;
-	ch->LINE_close	= fr_close;
-	ch->LINE_xmit	= fr_xmit;
-	ch->LINE_header	= fr_header;
-	ch->LINE_rebuild_header	= NULL;
-	ch->LINE_statistics = fr_statistics;
-
-	if ((new_file = create_proc_entry(FILENAME_DLCI, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-		goto cleanup_LINE_privdata;
-	}
-	
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &fr_read_proc;
-	new_file->write_proc = &fr_write_proc;
-	new_file->size = 5;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_MASTER, S_IFREG | 0644, 
-	    ch->procdir)) == NULL) {
-		goto cleanup_filename_dlci;
-	}
-	new_file->data = (void *)new_file;
-	new_file->read_proc = &fr_read_proc;
-	new_file->write_proc = &fr_write_proc;
-	new_file->size = 10;
-	new_file->nlink = 1;
-	MOD_INC_USE_COUNT;
-	return 0;
-cleanup_filename_dlci:
-         remove_proc_entry(FILENAME_DLCI, ch->procdir);
-cleanup_LINE_privdata:
-	kfree(fr);
-	return -EIO;
-}
-
-static int dlci_open(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-
-	ch->init_status |= HW_OPEN;
-
-	MOD_INC_USE_COUNT;
-	return 0;
-}
-
-static int dlci_close(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-
-	ch->init_status &= ~HW_OPEN;
-
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-static int dlci_txe(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct fr_data *fr = ch->LINE_privdata;
-
-	if (!fr->master) {
-		return 0;
-	}
-
-	ch = fr->master->priv;
-	fr = ch->LINE_privdata;
-	return ch->HW_txe(fr->master);
-}
-
-static int dlci_statistics(struct net_device *dev, char *page) 
-{
-	return 0;
-}
-
-static int dlci_init(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-
-	ch->HW_open = dlci_open;
-	ch->HW_close = dlci_close;
-	ch->HW_txe = dlci_txe;
-	ch->HW_statistics = dlci_statistics;
-
-	/* Nincs egyeb hw info, mert ugyis a fr->master-bol fog minden kiderulni */
-
-	MOD_INC_USE_COUNT;
-	return 0;
-}
-
-static int dlci_exit(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-
-	ch->HW_open = NULL;
-	ch->HW_close = NULL;
-	ch->HW_txe = NULL;
-	ch->HW_statistics = NULL;
-
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-static int dlci_dump(struct net_device *dev)
-{
-	printk(KERN_INFO "dlci_dump %s, HOGY MI ???\n", dev->name);
-	return -1;
-}
-
-static struct comx_protocol fr_master_protocol = {
-	.name		= "frad", 
-	.version	= VERSION,
-	.encap_type	= ARPHRD_FRAD, 
-	.line_init	= fr_master_init, 
-	.line_exit	= fr_exit, 
-};
-
-static struct comx_protocol fr_slave_protocol = {
-	.name		= "ietf-ip", 
-	.version	= VERSION,
-	.encap_type	= ARPHRD_DLCI, 
-	.line_init	= fr_slave_init, 
-	.line_exit	= fr_exit, 
-};
-
-static struct comx_hardware fr_dlci = { 
-	.name		= "dlci", 
-	.version	= VERSION,
-	.hw_init	= dlci_init, 
-	.hw_exit	= dlci_exit, 
-	.hw_dump	= dlci_dump, 
-};
-
-static int __init comx_proto_fr_init(void)
-{
-	int ret; 
-
-	if ((ret = comx_register_hardware(&fr_dlci))) {
-		return ret;
-	}
-	if ((ret = comx_register_protocol(&fr_master_protocol))) {
-		return ret;
-	}
-	return comx_register_protocol(&fr_slave_protocol);
-}
-
-static void __exit comx_proto_fr_exit(void)
-{
-	comx_unregister_hardware(fr_dlci.name);
-	comx_unregister_protocol(fr_master_protocol.name);
-	comx_unregister_protocol(fr_slave_protocol.name);
-}
-
-module_init(comx_proto_fr_init);
-module_exit(comx_proto_fr_exit);
===== drivers/net/wan/comx-proto-lapb.c 1.12 vs edited =====
--- 1.12/drivers/net/wan/comx-proto-lapb.c	Sun Jan 11 00:39:04 2004
+++ edited/drivers/net/wan/comx-proto-lapb.c	Fri May  7 13:05:52 2004
@@ -1,551 +1 @@
-/*
- * LAPB protocol module for the COMX driver 
- * for Linux kernel 2.2.X
- *
- * Original author: Tivadar Szemethy <tiv@itc.hu>
- * Maintainer: Gergely Madarasz <gorgo@itc.hu>
- *
- * Copyright (C) 1997-1999 (C) ITConsult-Pro Co. <info@itc.hu>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Version 0.80 (99/06/14):
- *		- cleaned up the source code a bit
- *		- ported back to kernel, now works as non-module
- *
- * Changed      (00/10/29, Henner Eisen):
- * 		- comx_rx() / comxlapb_data_indication() return status.
- * 
- */
 
-#define VERSION "0.80"
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/if_arp.h>
-#include <linux/inetdevice.h>
-#include <asm/uaccess.h>
-#include <linux/lapb.h>
-#include <linux/init.h>
-
-#include	"comx.h"
-#include	"comxhw.h"
-
-static struct proc_dir_entry *create_comxlapb_proc_entry(char *name, int mode,
-	int size, struct proc_dir_entry *dir);
-
-static void comxlapb_rx(struct net_device *dev, struct sk_buff *skb) 
-{
-	if (!dev || !dev->priv) {
-		dev_kfree_skb(skb);
-	} else {
-		lapb_data_received(dev, skb);
-	}
-}
-
-static int comxlapb_tx(struct net_device *dev) 
-{
-	netif_wake_queue(dev);
-	return 0;
-}
-
-static int comxlapb_header(struct sk_buff *skb, struct net_device *dev, 
-	unsigned short type, void *daddr, void *saddr, unsigned len) 
-{
-	return dev->hard_header_len;  
-}
-
-static void comxlapb_status(struct net_device *dev, unsigned short status)
-{
-	struct comx_channel *ch;
-
-	if (!dev || !(ch = dev->priv)) {
-		return;
-	}
-	if (status & LINE_UP) {
-		netif_wake_queue(dev);
-	}
-	comx_status(dev, status);
-}
-
-static int comxlapb_open(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	int err = 0;
-
-	if (!(ch->init_status & HW_OPEN)) {
-		return -ENODEV;
-	}
-
-	err = lapb_connect_request(dev);
-
-	if (ch->debug_flags & DEBUG_COMX_LAPB) {
-		comx_debug(dev, "%s: lapb opened, error code: %d\n", 
-			dev->name, err);
-	}
-
-	if (!err) {
-		ch->init_status |= LINE_OPEN;
-		MOD_INC_USE_COUNT;
-	}
-	return err;
-}
-
-static int comxlapb_close(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-
-	if (!(ch->init_status & HW_OPEN)) {
-		return -ENODEV;
-	}
-
-	if (ch->debug_flags & DEBUG_COMX_LAPB) {
-		comx_debug(dev, "%s: lapb closed\n", dev->name);
-	}
-
-	lapb_disconnect_request(dev);
-
-	ch->init_status &= ~LINE_OPEN;
-	ch->line_status &= ~PROTO_UP;
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-static int comxlapb_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct sk_buff *skb2;
-
-	if (!dev || !(ch = dev->priv) || !(dev->flags & (IFF_UP | IFF_RUNNING))) {
-		return -ENODEV;
-	}
-
-	if (dev->type == ARPHRD_X25) { // first byte tells what to do 
-		switch(skb->data[0]) {
-			case 0x00:	
-				break;	// transmit
-			case 0x01:	
-				lapb_connect_request(dev);
-				kfree_skb(skb);
-				return 0;
-			case 0x02:	
-				lapb_disconnect_request(dev);
-			default:
-				kfree_skb(skb);
-				return 0;
-		}
-		skb_pull(skb,1);
-	}
-
-	netif_stop_queue(dev);
-	
-	if ((skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
-		lapb_data_request(dev, skb2);
-	}
-
-	return FRAME_ACCEPTED;
-}
-
-static int comxlapb_statistics(struct net_device *dev, char *page) 
-{
-	struct lapb_parms_struct parms;
-	int len = 0;
-
-	len += sprintf(page + len, "Line status: ");
-	if (lapb_getparms(dev, &parms) != LAPB_OK) {
-		len += sprintf(page + len, "not initialized\n");
-		return len;
-	}
-	len += sprintf(page + len, "%s (%s), T1: %d/%d, T2: %d/%d, N2: %d/%d, "
-		"window: %d\n", parms.mode & LAPB_DCE ? "DCE" : "DTE", 
-		parms.mode & LAPB_EXTENDED ? "EXTENDED" : "STANDARD",
-		parms.t1timer, parms.t1, parms.t2timer, parms.t2, 
-		parms.n2count, parms.n2, parms.window);
-
-	return len;
-}
-
-static int comxlapb_read_proc(char *page, char **start, off_t off, int count,
-	int *eof, void *data)
-{
-	struct proc_dir_entry *file = (struct proc_dir_entry *)data;
-	struct net_device *dev = file->parent->data;
-	struct lapb_parms_struct parms;
-	int len = 0;
-
-	if (lapb_getparms(dev, &parms)) {
-		return -ENODEV;
-	}
-
-	if (strcmp(file->name, FILENAME_T1) == 0) {
-		len += sprintf(page + len, "%02u / %02u\n", 
-			parms.t1timer, parms.t1);
-	} else if (strcmp(file->name, FILENAME_T2) == 0) {
-		len += sprintf(page + len, "%02u / %02u\n", 
-			parms.t2timer, parms.t2);
-	} else if (strcmp(file->name, FILENAME_N2) == 0) {
-		len += sprintf(page + len, "%02u / %02u\n", 
-			parms.n2count, parms.n2);
-	} else if (strcmp(file->name, FILENAME_WINDOW) == 0) {
-		len += sprintf(page + len, "%u\n", parms.window);
-	} else if (strcmp(file->name, FILENAME_MODE) == 0) {
-		len += sprintf(page + len, "%s, %s\n", 
-			parms.mode & LAPB_DCE ? "DCE" : "DTE",
-			parms.mode & LAPB_EXTENDED ? "EXTENDED" : "STANDARD");
-	} else {
-		printk(KERN_ERR "comxlapb: internal error, filename %s\n", file->name);
-		return -EBADF;
-	}
-
-	if (off >= len) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = page + off;
-	if (count >= len - off) {
-		*eof = 1;
-	}
-	return min_t(int, count, len - off);
-}
-
-static int comxlapb_write_proc(struct file *file, const char *buffer, 
-	u_long count, void *data)
-{
-	struct proc_dir_entry *entry = (struct proc_dir_entry *)data;
-	struct net_device *dev = entry->parent->data;
-	struct lapb_parms_struct parms;
-	unsigned long parm;
-	char *page;
-
-	if (lapb_getparms(dev, &parms)) {
-		return -ENODEV;
-	}
-
-	if (!(page = (char *)__get_free_page(GFP_KERNEL))) {
-		return -ENOMEM;
-	}
-
-	if (copy_from_user(page, buffer, count)) {
-		free_page((unsigned long)page);
-		return -EFAULT;
-	}
-	if (*(page + count - 1) == '\n') {
-		*(page + count - 1) = 0;
-	}
-
-	if (strcmp(entry->name, FILENAME_T1) == 0) {
-		parm=simple_strtoul(page,NULL,10);
-		if (parm > 0 && parm < 100) {
-			parms.t1=parm;
-			lapb_setparms(dev, &parms);
-		}
-	} else if (strcmp(entry->name, FILENAME_T2) == 0) {
-		parm=simple_strtoul(page, NULL, 10);
-		if (parm > 0 && parm < 100) {
-			parms.t2=parm;
-			lapb_setparms(dev, &parms);
-		}
-	} else if (strcmp(entry->name, FILENAME_N2) == 0) {
-		parm=simple_strtoul(page, NULL, 10);
-		if (parm > 0 && parm < 100) {
-			parms.n2=parm;
-			lapb_setparms(dev, &parms);
-		}
-	} else if (strcmp(entry->name, FILENAME_WINDOW) == 0) {
-		parms.window = simple_strtoul(page, NULL, 10);
-		lapb_setparms(dev, &parms);
-	} else if (strcmp(entry->name, FILENAME_MODE) == 0) {
-		if (comx_strcasecmp(page, "dte") == 0) {
-			parms.mode &= ~(LAPB_DCE | LAPB_DTE); 
-			parms.mode |= LAPB_DTE;
-		} else if (comx_strcasecmp(page, "dce") == 0) {
-			parms.mode &= ~(LAPB_DTE | LAPB_DCE); 
-			parms.mode |= LAPB_DCE;
-		} else if (comx_strcasecmp(page, "std") == 0 || 
-		    comx_strcasecmp(page, "standard") == 0) {
-			parms.mode &= ~LAPB_EXTENDED; 
-			parms.mode |= LAPB_STANDARD;
-		} else if (comx_strcasecmp(page, "ext") == 0 || 
-		    comx_strcasecmp(page, "extended") == 0) {
-			parms.mode &= ~LAPB_STANDARD; 
-			parms.mode |= LAPB_EXTENDED;
-		}
-		lapb_setparms(dev, &parms);
-	} else {
-		printk(KERN_ERR "comxlapb_write_proc: internal error, filename %s\n", 
-			entry->name);
-		return -EBADF;
-	}
-
-	free_page((unsigned long)page);
-	return count;
-}
-
-static void comxlapb_connected(struct net_device *dev, int reason)
-{
-	struct comx_channel *ch = dev->priv; 
-	struct proc_dir_entry *comxdir = ch->procdir->subdir;
-
-	if (ch->debug_flags & DEBUG_COMX_LAPB) {
-		comx_debug(ch->dev, "%s: lapb connected, reason: %d\n", 
-			ch->dev->name, reason);
-	}
-
-	if (ch->dev->type == ARPHRD_X25) {
-		unsigned char *p;
-		struct sk_buff *skb;
-
-		if ((skb = dev_alloc_skb(1)) == NULL) {
-			printk(KERN_ERR "comxlapb: out of memory!\n");
-			return;
-		}
-		p = skb_put(skb,1);
-		*p = 0x01;		// link established
-		skb->dev = ch->dev;
-		skb->protocol = htons(ETH_P_X25);
-		skb->mac.raw = skb->data;
-		skb->pkt_type = PACKET_HOST;
-
-		netif_rx(skb);
-		ch->dev->last_rx = jiffies;
-	}
-
-	for (; comxdir; comxdir = comxdir->next) {
-		if (strcmp(comxdir->name, FILENAME_MODE) == 0) {
-			comxdir->mode = S_IFREG | 0444;
-		}
-	}
-
-
-	ch->line_status |= PROTO_UP;
-	comx_status(ch->dev, ch->line_status);
-}
-
-static void comxlapb_disconnected(struct net_device *dev, int reason)
-{
-	struct comx_channel *ch = dev->priv; 
-	struct proc_dir_entry *comxdir = ch->procdir->subdir;
-
-	if (ch->debug_flags & DEBUG_COMX_LAPB) {
-		comx_debug(ch->dev, "%s: lapb disconnected, reason: %d\n", 
-			ch->dev->name, reason);
-	}
-
-	if (ch->dev->type == ARPHRD_X25) {
-		unsigned char *p;
-		struct sk_buff *skb;
-
-		if ((skb = dev_alloc_skb(1)) == NULL) {
-			printk(KERN_ERR "comxlapb: out of memory!\n");
-			return;
-		}
-		p = skb_put(skb,1);
-		*p = 0x02;		// link disconnected
-		skb->dev = ch->dev;
-		skb->protocol = htons(ETH_P_X25);
-		skb->mac.raw = skb->data;
-		skb->pkt_type = PACKET_HOST;
-
-		netif_rx(skb);
-		ch->dev->last_rx = jiffies;
-	}
-
-	for (; comxdir; comxdir = comxdir->next) {
-		if (strcmp(comxdir->name, FILENAME_MODE) == 0) {
-			comxdir->mode = S_IFREG | 0644;
-		}
-	}
-	
-	ch->line_status &= ~PROTO_UP;
-	comx_status(ch->dev, ch->line_status);
-}
-
-static int comxlapb_data_indication(struct net_device *dev, struct sk_buff *skb)
-{
-	struct comx_channel *ch = dev->priv; 
-
-	if (ch->dev->type == ARPHRD_X25) {
-		skb_push(skb, 1);
-
-		if (skb_cow(skb, 1))
-			return NET_RX_DROP;
-
-		skb->data[0] = 0;	// indicate data for X25
-		skb->protocol = htons(ETH_P_X25);
-	} else {
-		skb->protocol = htons(ETH_P_IP);
-	}
-
-	skb->dev = ch->dev;
-	skb->mac.raw = skb->data;
-	return comx_rx(ch->dev, skb);
-}
-
-static void comxlapb_data_transmit(struct net_device *dev, struct sk_buff *skb)
-{
-	struct comx_channel *ch = dev->priv; 
-
-	if (ch->HW_send_packet) {
-		ch->HW_send_packet(ch->dev, skb);
-	}
-}
-
-static int comxlapb_exit(struct net_device *dev) 
-{
-	struct comx_channel *ch = dev->priv;
-
-	dev->flags		= 0;
-	dev->type		= 0;
-	dev->mtu		= 0;
-	dev->hard_header_len    = 0;
-
-	ch->LINE_rx	= NULL;
-	ch->LINE_tx	= NULL;
-	ch->LINE_status = NULL;
-	ch->LINE_open	= NULL;
-	ch->LINE_close	= NULL;
-	ch->LINE_xmit	= NULL;
-	ch->LINE_header	= NULL;
-	ch->LINE_statistics = NULL;
-
-	if (ch->debug_flags & DEBUG_COMX_LAPB) {
-		comx_debug(dev, "%s: unregistering lapb\n", dev->name);
-	}
-	lapb_unregister(dev);
-
-	remove_proc_entry(FILENAME_T1, ch->procdir);
-	remove_proc_entry(FILENAME_T2, ch->procdir);
-	remove_proc_entry(FILENAME_N2, ch->procdir);
-	remove_proc_entry(FILENAME_MODE, ch->procdir);
-	remove_proc_entry(FILENAME_WINDOW, ch->procdir);
-
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-static int comxlapb_init(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct lapb_register_struct lapbreg;
-
-	dev->mtu		= 1500;
-	dev->hard_header_len    = 4;
-	dev->addr_len		= 0;
-
-	ch->LINE_rx	= comxlapb_rx;
-	ch->LINE_tx	= comxlapb_tx;
-	ch->LINE_status = comxlapb_status;
-	ch->LINE_open	= comxlapb_open;
-	ch->LINE_close	= comxlapb_close;
-	ch->LINE_xmit	= comxlapb_xmit;
-	ch->LINE_header	= comxlapb_header;
-	ch->LINE_statistics = comxlapb_statistics;
-
-	lapbreg.connect_confirmation = comxlapb_connected;
-	lapbreg.connect_indication = comxlapb_connected;
-	lapbreg.disconnect_confirmation = comxlapb_disconnected;
-	lapbreg.disconnect_indication = comxlapb_disconnected;
-	lapbreg.data_indication = comxlapb_data_indication;
-	lapbreg.data_transmit = comxlapb_data_transmit;
-	if (lapb_register(dev, &lapbreg)) {
-		return -ENOMEM;
-	}
-	if (ch->debug_flags & DEBUG_COMX_LAPB) {
-		comx_debug(dev, "%s: lapb registered\n", dev->name);
-	}
-
-	if (!create_comxlapb_proc_entry(FILENAME_T1, 0644, 8, ch->procdir)) {
-		return -ENOMEM;
-	}
-	if (!create_comxlapb_proc_entry(FILENAME_T2, 0644, 8, ch->procdir)) {
-		return -ENOMEM;
-	}
-	if (!create_comxlapb_proc_entry(FILENAME_N2, 0644, 8, ch->procdir)) {
-		return -ENOMEM;
-	}
-	if (!create_comxlapb_proc_entry(FILENAME_MODE, 0644, 14, ch->procdir)) {
-		return -ENOMEM;
-	}
-	if (!create_comxlapb_proc_entry(FILENAME_WINDOW, 0644, 0, ch->procdir)) {
-		return -ENOMEM;
-	}
-
-	MOD_INC_USE_COUNT;
-	return 0;
-}
-
-static int comxlapb_init_lapb(struct net_device *dev) 
-{
-	dev->flags	= IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-	dev->type	= ARPHRD_LAPB;
-
-	return(comxlapb_init(dev));
-}
-
-static int comxlapb_init_x25(struct net_device *dev)
-{
-	dev->flags		= IFF_NOARP;
-	dev->type		= ARPHRD_X25;
-
-	return(comxlapb_init(dev));
-}
-
-static struct proc_dir_entry *create_comxlapb_proc_entry(char *name, int mode,
-	int size, struct proc_dir_entry *dir)
-{
-	struct proc_dir_entry *new_file;
-
-	if ((new_file = create_proc_entry(name, S_IFREG | mode, dir)) != NULL) {
-		new_file->data = (void *)new_file;
-		new_file->read_proc = &comxlapb_read_proc;
-		new_file->write_proc = &comxlapb_write_proc;
-		new_file->size = size;
-		new_file->nlink = 1;
-	}
-	return(new_file);
-}
-
-static struct comx_protocol comxlapb_protocol = {
-	"lapb", 
-	VERSION,
-	ARPHRD_LAPB, 
-	comxlapb_init_lapb, 
-	comxlapb_exit, 
-	NULL 
-};
-
-static struct comx_protocol comx25_protocol = {
-	"x25", 
-	VERSION,
-	ARPHRD_X25, 
-	comxlapb_init_x25, 
-	comxlapb_exit, 
-	NULL 
-};
-
-static int __init comx_proto_lapb_init(void)
-{
-	int ret;
-
-	if ((ret = comx_register_protocol(&comxlapb_protocol)) != 0) {
-		return ret;
-	}
-	return comx_register_protocol(&comx25_protocol);
-}
-
-static void __exit comx_proto_lapb_exit(void)
-{
-	comx_unregister_protocol(comxlapb_protocol.name);
-	comx_unregister_protocol(comx25_protocol.name);
-}
-
-module_init(comx_proto_lapb_init);
-module_exit(comx_proto_lapb_exit);
-
-MODULE_LICENSE("GPL");
===== drivers/net/wan/comx-proto-ppp.c 1.6 vs edited =====
--- 1.6/drivers/net/wan/comx-proto-ppp.c	Thu Sep 11 19:40:53 2003
+++ edited/drivers/net/wan/comx-proto-ppp.c	Fri May  7 13:05:52 2004
@@ -1,269 +1 @@
-/*
- * Synchronous PPP / Cisco-HDLC driver for the COMX boards
- *
- * Author: Gergely Madarasz <gorgo@itc.hu>
- *
- * based on skeleton code by Tivadar Szemethy <tiv@itc.hu>
- *
- * Copyright (C) 1999 ITConsult-Pro Co. <info@itc.hu>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- *
- * Version 0.10 (99/06/10):
- *		- written the first code :)
- *
- * Version 0.20 (99/06/16):
- *		- added hdlc protocol 
- *		- protocol up is IFF_RUNNING
- *
- * Version 0.21 (99/07/15):
- *		- some small fixes with the line status
- *
- * Version 0.22 (99/08/05):
- *		- don't test IFF_RUNNING but the pp_link_state of the sppp
- * 
- * Version 0.23 (99/12/02):
- *		- tbusy fixes
- *
- */
 
-#define VERSION "0.23"
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/jiffies.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/if_arp.h>
-#include <linux/inetdevice.h>
-#include <asm/uaccess.h>
-#include <linux/init.h>
-
-#include <net/syncppp.h>
-#include	"comx.h"
-
-MODULE_AUTHOR("Author: Gergely Madarasz <gorgo@itc.hu>");
-MODULE_DESCRIPTION("Cisco-HDLC / Synchronous PPP driver for the COMX sync serial boards");
-MODULE_LICENSE("GPL");
-
-static struct comx_protocol syncppp_protocol;
-static struct comx_protocol hdlc_protocol;
-
-struct syncppp_data {
-	struct timer_list status_timer;
-};
-
-static void syncppp_status_timerfun(unsigned long d) {
-	struct net_device *dev=(struct net_device *)d;
-	struct comx_channel *ch=dev->priv;
-	struct syncppp_data *spch=ch->LINE_privdata;
-	struct sppp *sp = (struct sppp *)sppp_of(dev);
-        
-	if(!(ch->line_status & PROTO_UP) && 
-	    (sp->pp_link_state==SPPP_LINK_UP)) {
-    		comx_status(dev, ch->line_status | PROTO_UP);
-	}
-	if((ch->line_status & PROTO_UP) &&
-	    (sp->pp_link_state==SPPP_LINK_DOWN)) {
-	    	comx_status(dev, ch->line_status & ~PROTO_UP);
-	}
-	mod_timer(&spch->status_timer,jiffies + HZ*3);
-}
-
-static int syncppp_tx(struct net_device *dev) 
-{
-	struct comx_channel *ch=dev->priv;
-	
-	if(ch->line_status & LINE_UP) {
-		netif_wake_queue(dev);
-	}
-	return 0;
-}
-
-static void syncppp_status(struct net_device *dev, unsigned short status)
-{
-	status &= ~(PROTO_UP | PROTO_LOOP);
-	if(status & LINE_UP) {
-		netif_wake_queue(dev);
-		sppp_open(dev);
-	} else 	{
-		/* Line went down */
-		netif_stop_queue(dev);
-		sppp_close(dev);
-	}
-	comx_status(dev, status);
-}
-
-static int syncppp_open(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct syncppp_data *spch = ch->LINE_privdata;
-
-	if (!(ch->init_status & HW_OPEN)) return -ENODEV;
-
-	ch->init_status |= LINE_OPEN;
-	ch->line_status &= ~(PROTO_UP | PROTO_LOOP);
-
-	if(ch->line_status & LINE_UP) {
-		sppp_open(dev);
-	}
-
-	init_timer(&spch->status_timer);
-	spch->status_timer.function=syncppp_status_timerfun;
-	spch->status_timer.data=(unsigned long)dev;
-	spch->status_timer.expires=jiffies + HZ*3;
-	add_timer(&spch->status_timer);
-	
-	return 0;
-}
-
-static int syncppp_close(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct syncppp_data *spch = ch->LINE_privdata;
-
-	if (!(ch->init_status & HW_OPEN)) return -ENODEV;
-	del_timer(&spch->status_timer);
-	
-	sppp_close(dev);
-
-	ch->init_status &= ~LINE_OPEN;
-	ch->line_status &= ~(PROTO_UP | PROTO_LOOP);
-
-	return 0;
-}
-
-static int syncppp_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-
-	netif_stop_queue(dev);
-	switch(ch->HW_send_packet(dev, skb)) {
-		case FRAME_QUEUED:
-			netif_wake_queue(dev);
-			break;
-		case FRAME_ACCEPTED:
-		case FRAME_DROPPED:
-			break;
-		case FRAME_ERROR:
-			printk(KERN_ERR "%s: Transmit frame error (len %d)\n", 
-				dev->name, skb->len);
-		break;
-	}
-	return 0;
-}
-
-
-static int syncppp_statistics(struct net_device *dev, char *page) 
-{
-	int len = 0;
-
-	len += sprintf(page + len, " ");
-	return len;
-}
-
-
-static int syncppp_exit(struct net_device *dev) 
-{
-	struct comx_channel *ch = dev->priv;
-
-	sppp_detach(dev);
-
-	dev->flags = 0;
-	dev->type = 0;
-	dev->mtu = 0;
-
-	ch->LINE_rx = NULL;
-	ch->LINE_tx = NULL;
-	ch->LINE_status = NULL;
-	ch->LINE_open = NULL;
-	ch->LINE_close = NULL;
-	ch->LINE_xmit = NULL;
-	ch->LINE_header	= NULL;
-	ch->LINE_rebuild_header	= NULL;
-	ch->LINE_statistics = NULL;
-
-	kfree(ch->LINE_privdata);
-	ch->LINE_privdata = NULL;
-
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-static int syncppp_init(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct ppp_device *pppdev = (struct ppp_device *)ch->if_ptr;
-
-	ch->LINE_privdata = kmalloc(sizeof(struct syncppp_data), GFP_KERNEL);
-	if (!ch->LINE_privdata)
-		return -ENOMEM;
-
-	pppdev->dev = dev;
-	sppp_attach(pppdev);
-
-	if(ch->protocol == &hdlc_protocol) {
-		pppdev->sppp.pp_flags |= PP_CISCO;
-		dev->type = ARPHRD_HDLC;
-	} else {
-		pppdev->sppp.pp_flags &= ~PP_CISCO;
-		dev->type = ARPHRD_PPP;
-	}
-
-	ch->LINE_rx = sppp_input;
-	ch->LINE_tx = syncppp_tx;
-	ch->LINE_status = syncppp_status;
-	ch->LINE_open = syncppp_open;
-	ch->LINE_close = syncppp_close;
-	ch->LINE_xmit = syncppp_xmit;
-	ch->LINE_header	= NULL;
-	ch->LINE_statistics = syncppp_statistics;
-
-
-	MOD_INC_USE_COUNT;
-	return 0;
-}
-
-static struct comx_protocol syncppp_protocol = {
-	"ppp", 
-	VERSION,
-	ARPHRD_PPP, 
-	syncppp_init, 
-	syncppp_exit, 
-	NULL 
-};
-
-static struct comx_protocol hdlc_protocol = {
-	"hdlc", 
-	VERSION,
-	ARPHRD_PPP, 
-	syncppp_init, 
-	syncppp_exit, 
-	NULL 
-};
-
-static int __init comx_proto_ppp_init(void)
-{
-	int ret;
-
-	ret = comx_register_protocol(&hdlc_protocol);
-	if (!ret) {
-		ret = comx_register_protocol(&syncppp_protocol);
-		if (ret)
-			comx_unregister_protocol(hdlc_protocol.name);
-	}
-	return ret;
-}
-
-static void __exit comx_proto_ppp_exit(void)
-{
-	comx_unregister_protocol(syncppp_protocol.name);
-	comx_unregister_protocol(hdlc_protocol.name);
-}
-
-module_init(comx_proto_ppp_init);
-module_exit(comx_proto_ppp_exit);
===== drivers/net/wan/comx.c 1.23 vs edited =====
--- 1.23/drivers/net/wan/comx.c	Thu Mar 18 22:27:11 2004
+++ edited/drivers/net/wan/comx.c	Fri May  7 13:05:52 2004
@@ -1,1128 +1 @@
-/*
- * Device driver framework for the COMX line of synchronous serial boards
- * 
- * for Linux kernel 2.2.X / 2.4.X
- *
- * Original authors:  Arpad Bakay <bakay.arpad@synergon.hu>,
- *                    Peter Bajan <bajan.peter@synergon.hu>,
- * Previous maintainer: Tivadar Szemethy <tiv@itc.hu>
- * Current maintainer: Gergely Madarasz <gorgo@itc.hu>
- *
- * Copyright (C) 1995-1999 ITConsult-Pro Co.
- *
- * Contributors:
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br> (0.85)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Version 0.80 (99/06/11):
- *		- clean up source code (playing a bit of indent)
- *		- port back to kernel, add support for non-module versions
- *		- add support for board resets when channel protocol is down
- *		- reset the device structure after protocol exit
- *		  the syncppp driver needs it
- *		- add support for /proc/comx/protocols and 
- *		  /proc/comx/boardtypes
- *
- * Version 0.81 (99/06/21):
- *		- comment out the board reset support code, the locomx
- *		  driver seems not buggy now
- *		- printk() levels fixed
- *
- * Version 0.82 (99/07/08):
- *		- Handle stats correctly if the lowlevel driver is
- *		  is not a comx one (locomx - z85230)
- *
- * Version 0.83 (99/07/15):
- *		- reset line_status when interface is down
- *
- * Version 0.84 (99/12/01):
- *		- comx_status should not check for IFF_UP (to report
- *		  line status from dev->open())
- *
- * Version 0.85 (00/08/15):
- * 		- resource release on failure in comx_mkdir
- * 		- fix return value on failure at comx_write_proc
- *
- * Changed      (00/10/29, Henner Eisen):
- * 		- comx_rx() / comxlapb_data_indication() return status.
- */
 
-#define VERSION "0.85"
-
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/types.h>
-#include <linux/jiffies.h>
-#include <linux/netdevice.h>
-#include <linux/proc_fs.h>
-#include <asm/uaccess.h>
-#include <linux/ctype.h>
-#include <linux/init.h>
-#include <linux/smp_lock.h>
-
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
-#ifndef CONFIG_PROC_FS
-#error For now, COMX really needs the /proc filesystem
-#endif
-
-#include <net/syncppp.h>
-#include "comx.h"
-
-MODULE_AUTHOR("Gergely Madarasz <gorgo@itc.hu>");
-MODULE_DESCRIPTION("Common code for the COMX synchronous serial adapters");
-MODULE_LICENSE("GPL");
-
-static struct comx_hardware *comx_channels = NULL;
-static struct comx_protocol *comx_lines = NULL;
-
-static int comx_mkdir(struct inode *, struct dentry *, int);
-static int comx_rmdir(struct inode *, struct dentry *);
-static struct dentry *comx_lookup(struct inode *, struct dentry *, struct nameidata *);
-
-static struct inode_operations comx_root_inode_ops = {
-	.lookup = comx_lookup,
-	.mkdir = comx_mkdir,
-	.rmdir = comx_rmdir,
-};
-
-static int comx_delete_dentry(struct dentry *dentry);
-static struct proc_dir_entry *create_comx_proc_entry(char *name, int mode,
-	int size, struct proc_dir_entry *dir);
-
-static struct dentry_operations comx_dentry_operations = {
-	.d_delete	= comx_delete_dentry,
-};
-
-
-static struct proc_dir_entry * comx_root_dir;
-
-struct comx_debugflags_struct	comx_debugflags[] = {
-	{ "comx_rx",		DEBUG_COMX_RX		},
-	{ "comx_tx", 		DEBUG_COMX_TX		},
-	{ "hw_tx",		DEBUG_HW_TX		},
-	{ "hw_rx", 		DEBUG_HW_RX		},
-	{ "hdlc_keepalive",	DEBUG_HDLC_KEEPALIVE	},
-	{ "comxppp",		DEBUG_COMX_PPP		},
-	{ "comxlapb",		DEBUG_COMX_LAPB		},
-	{ "dlci",		DEBUG_COMX_DLCI		},
-	{ NULL,			0			} 
-};
-
-
-int comx_debug(struct net_device *dev, char *fmt, ...)
-{
-	struct comx_channel *ch = dev->priv;
-	char *page,*str;
-	va_list args;
-	int len;
-
-	if (!ch->debug_area) return 0;
-
-	if (!(page = (char *)__get_free_page(GFP_ATOMIC))) return -ENOMEM;
-
-	va_start(args, fmt);
-	len = vsprintf(str = page, fmt, args);
-	va_end(args);
-
-	if (len >= PAGE_SIZE) {
-		printk(KERN_ERR "comx_debug: PANIC! len = %d !!!\n", len);
-		free_page((unsigned long)page);
-		return -EINVAL;
-	}
-
-	while (len) {
-		int to_copy;
-		int free = (ch->debug_start - ch->debug_end + ch->debug_size) 
-			% ch->debug_size;
-
-		to_copy = min_t(int, free ? free : ch->debug_size, 
-			      min_t(int, ch->debug_size - ch->debug_end, len));
-		memcpy(ch->debug_area + ch->debug_end, str, to_copy);
-		str += to_copy;
-		len -= to_copy;
-		ch->debug_end = (ch->debug_end + to_copy) % ch->debug_size;
-		if (ch->debug_start == ch->debug_end) // Full ? push start away
-			ch->debug_start = (ch->debug_start + len + 1) % 
-					ch->debug_size;
-		ch->debug_file->size = (ch->debug_end - ch->debug_start +
-					ch->debug_size) % ch->debug_size;
-	} 
-
-	free_page((unsigned long)page);
-	return 0;
-}
-
-int comx_debug_skb(struct net_device *dev, struct sk_buff *skb, char *msg)
-{
-	struct comx_channel *ch = dev->priv;
-
-	if (!ch->debug_area) return 0;
-	if (!skb) comx_debug(dev, "%s: %s NULL skb\n\n", dev->name, msg);
-	if (!skb->len) comx_debug(dev, "%s: %s empty skb\n\n", dev->name, msg);
-
-	return comx_debug_bytes(dev, skb->data, skb->len, msg);
-}
-
-int comx_debug_bytes(struct net_device *dev, unsigned char *bytes, int len, 
-		char *msg)
-{
-	int pos = 0;
-	struct comx_channel *ch = dev->priv;
-
-	if (!ch->debug_area) return 0;
-
-	comx_debug(dev, "%s: %s len %d\n", dev->name, msg, len);
-
-	while (pos != len) {
-		char line[80];
-		int i = 0;
-
-		memset(line, 0, 80);
-		sprintf(line,"%04d ", pos);
-		do {
-			sprintf(line + 5 + (pos % 16) * 3, "%02x", bytes[pos]);
-			sprintf(line + 60 + (pos % 16), "%c", 
-				isprint(bytes[pos]) ? bytes[pos] : '.');
-			pos++;
-		} while (pos != len && pos % 16);
-
-		while ( i++ != 78 ) if (line[i] == 0) line[i] = ' ';
-		line[77] = '\n';
-		line[78] = 0;
-	
-		comx_debug(dev, "%s", line);
-	}
-	comx_debug(dev, "\n");
-	return 0;
-}
-
-static void comx_loadavg_timerfun(unsigned long d)
-{
-	struct net_device *dev = (struct net_device *)d;
-	struct comx_channel *ch = dev->priv;
-
-	ch->avg_bytes[ch->loadavg_counter] = ch->current_stats->rx_bytes;
-	ch->avg_bytes[ch->loadavg_counter + ch->loadavg_size] = 
-		ch->current_stats->tx_bytes;
-
-	ch->loadavg_counter = (ch->loadavg_counter + 1) % ch->loadavg_size;
-
-	mod_timer(&ch->loadavg_timer,jiffies + HZ * ch->loadavg[0]);
-}
-
-#if 0
-static void comx_reset_timerfun(unsigned long d)
-{ 
-	struct net_device *dev = (struct net_device *)d;
-	struct comx_channel *ch = dev->priv;
-
-	if(!(ch->line_status & (PROTO_LOOP | PROTO_UP))) {
-		if(test_and_set_bit(0,&ch->reset_pending) && ch->HW_reset) {
-			ch->HW_reset(dev);
-		}
-	}
-
-	mod_timer(&ch->reset_timer, jiffies + HZ * ch->reset_timeout);
-}
-#endif                                            
-
-static int comx_open(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct proc_dir_entry *comxdir = ch->procdir->subdir;
-	int ret=0;
-
-	if (!ch->protocol || !ch->hardware) return -ENODEV;
-
-	if ((ret = ch->HW_open(dev))) return ret;
-	if ((ret = ch->LINE_open(dev))) { 
-		ch->HW_close(dev); 
-		return ret; 
-	};
-
-	for (; comxdir ; comxdir = comxdir->next) {
-		if (strcmp(comxdir->name, FILENAME_HARDWARE) == 0 ||
-		   strcmp(comxdir->name, FILENAME_PROTOCOL) == 0)
-			comxdir->mode = S_IFREG | 0444;
-	}
-
-#if 0
-	ch->reset_pending = 1;
-	ch->reset_timeout = 30;
-	ch->reset_timer.function = comx_reset_timerfun;
-	ch->reset_timer.data = (unsigned long)dev;
-	ch->reset_timer.expires = jiffies + HZ * ch->reset_timeout;
-	add_timer(&ch->reset_timer);
-#endif
-
-	return 0;
-}
-
-static int comx_close(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	struct proc_dir_entry *comxdir = ch->procdir->subdir;
-	int ret = -ENODEV;
-
-	if (test_and_clear_bit(0, &ch->lineup_pending)) {
-		del_timer(&ch->lineup_timer);
-	}
-
-#if 0	
-	del_timer(&ch->reset_timer);
-#endif
-
-	if (ch->init_status & LINE_OPEN && ch->protocol && ch->LINE_close) {
-		ret = ch->LINE_close(dev);
-	}
-
-	if (ret) return ret;
-
-	if (ch->init_status & HW_OPEN && ch->hardware && ch->HW_close) {
-		ret = ch->HW_close(dev);
-	}
-	
-	ch->line_status=0;
-
-	for (; comxdir ; comxdir = comxdir->next) {
-		if (strcmp(comxdir->name, FILENAME_HARDWARE) == 0 ||
-		    strcmp(comxdir->name, FILENAME_PROTOCOL) == 0)
-			comxdir->mode = S_IFREG | 0644;
-	}
-
-	return ret;
-}
-
-void comx_status(struct net_device *dev, int status)
-{
-	struct comx_channel *ch = dev->priv;
-
-#if 0
-	if(status & (PROTO_UP | PROTO_LOOP)) {
-		clear_bit(0,&ch->reset_pending);
-	}
-#endif
-
-	printk(KERN_NOTICE "Interface %s: modem status %s, line protocol %s\n",
-		    dev->name, status & LINE_UP ? "UP" : "DOWN", 
-		    status & PROTO_LOOP ? "LOOP" : status & PROTO_UP ? 
-		    "UP" : "DOWN");
-	
-	ch->line_status = status;
-}
-
-static int comx_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-	int rc;
-
-	if (skb->len > dev->mtu + dev->hard_header_len) {
-		printk(KERN_ERR "comx_xmit: %s: skb->len %d > dev->mtu %d\n", dev->name,
-		(int)skb->len, dev->mtu);
-	}
-	
-	if (ch->debug_flags & DEBUG_COMX_TX) {
-		comx_debug_skb(dev, skb, "comx_xmit skb");
-	}
-	
-	rc=ch->LINE_xmit(skb, dev);
-//	if (!rc) dev_kfree_skb(skb);
-
-	return rc;
-}
-
-static int comx_header(struct sk_buff *skb, struct net_device *dev, 
-	unsigned short type, void *daddr, void *saddr, unsigned len) 
-{
-	struct comx_channel *ch = dev->priv;
-
-	if (ch->LINE_header) {
-		return (ch->LINE_header(skb, dev, type, daddr, saddr, len));
-	} else {
-		return 0;
-	}
-}
-
-static int comx_rebuild_header(struct sk_buff *skb) 
-{
-	struct net_device *dev = skb->dev;
-	struct comx_channel *ch = dev->priv;
-
-	if (ch->LINE_rebuild_header) {
-		return(ch->LINE_rebuild_header(skb));
-	} else {
-		return 0;
-	}
-}
-
-int comx_rx(struct net_device *dev, struct sk_buff *skb)
-{
-	struct comx_channel *ch = dev->priv;
-
-	if (ch->debug_flags & DEBUG_COMX_RX) {
-		comx_debug_skb(dev, skb, "comx_rx skb");
-	}
-	if (skb) {
-		netif_rx(skb);
-		dev->last_rx = jiffies;
-	}
-	return 0;
-}
-
-static struct net_device_stats *comx_stats(struct net_device *dev)
-{
-	struct comx_channel *ch = dev->priv;
-
-	return ch->current_stats;
-}
-
-void comx_lineup_func(unsigned long d)
-{
-	struct net_device *dev = (struct net_device *)d;
-	struct comx_channel *ch = dev->priv;
-
-	del_timer(&ch->lineup_timer);
-	clear_bit(0, &ch->lineup_pending);
-
-	if (ch->LINE_status) {
-		ch->LINE_status(dev, ch->line_status |= LINE_UP);
-	}
-}
-
-#define LOADAVG(avg, off) (int) \
-	((ch->avg_bytes[(ch->loadavg_counter - 1 + ch->loadavg_size * 2) \
-	% ch->loadavg_size + off] -  ch->avg_bytes[(ch->loadavg_counter - 1 \
-		- ch->loadavg[avg] / ch->loadavg[0] + ch->loadavg_size * 2) \
-		% ch->loadavg_size + off]) / ch->loadavg[avg] * 8)
-
-static int comx_statistics(struct net_device *dev, char *page)
-{
-	struct comx_channel *ch = dev->priv;
-	int len = 0;
-	int tmp;
-	int i = 0;
-	char tmpstr[20];
-	int tmpstrlen = 0;
-
-	len += sprintf(page + len, "Interface administrative status is %s, "
-		"modem status is %s, protocol is %s\n", 
-		dev->flags & IFF_UP ? "UP" : "DOWN",
-		ch->line_status & LINE_UP ? "UP" : "DOWN",
-		ch->line_status & PROTO_LOOP ? "LOOP" : 
-		ch->line_status & PROTO_UP ? "UP" : "DOWN");
-	len += sprintf(page + len, "Modem status changes: %lu, Transmitter status "
-		"is %s, tbusy: %d\n", ch->current_stats->tx_carrier_errors, ch->HW_txe ? 
-		ch->HW_txe(dev) ? "IDLE" : "BUSY" : "NOT READY", netif_running(dev));
-	len += sprintf(page + len, "Interface load (input): %d / %d / %d bits/s (",
-		LOADAVG(0,0), LOADAVG(1, 0), LOADAVG(2, 0));
-	tmpstr[0] = 0;
-	for (i=0; i != 3; i++) {
-		char tf;
-
-		tf = ch->loadavg[i] % 60 == 0 && 
-			ch->loadavg[i] / 60 > 0 ? 'm' : 's';
-		tmpstrlen += sprintf(tmpstr + tmpstrlen, "%d%c%s", 
-			ch->loadavg[i] / (tf == 'm' ? 60 : 1), tf, 
-			i == 2 ? ")\n" : "/");
-	}
-	len += sprintf(page + len, 
-		"%s              (output): %d / %d / %d bits/s (%s", tmpstr, 
-		LOADAVG(0,ch->loadavg_size), LOADAVG(1, ch->loadavg_size), 
-		LOADAVG(2, ch->loadavg_size), tmpstr);
-
-	len += sprintf(page + len, "Debug flags: ");
-	tmp = len; i = 0;
-	while (comx_debugflags[i].name) {
-		if (ch->debug_flags & comx_debugflags[i].value) 
-			len += sprintf(page + len, "%s ", 
-				comx_debugflags[i].name);
-		i++;
-	}
-	len += sprintf(page + len, "%s\n", tmp == len ? "none" : "");
-
-	len += sprintf(page + len, "RX errors: len: %lu, overrun: %lu, crc: %lu, "
-		"aborts: %lu\n           buffer overrun: %lu, pbuffer overrun: %lu\n"
-		"TX errors: underrun: %lu\n",
-		ch->current_stats->rx_length_errors, ch->current_stats->rx_over_errors, 
-		ch->current_stats->rx_crc_errors, ch->current_stats->rx_frame_errors, 
-		ch->current_stats->rx_missed_errors, ch->current_stats->rx_fifo_errors,
-		ch->current_stats->tx_fifo_errors);
-
-	if (ch->LINE_statistics && (ch->init_status & LINE_OPEN)) {
-		len += ch->LINE_statistics(dev, page + len);
-	} else {
-		len += sprintf(page+len, "Line status: driver not initialized\n");
-	}
-	if (ch->HW_statistics && (ch->init_status & HW_OPEN)) {
-		len += ch->HW_statistics(dev, page + len);
-	} else {
-		len += sprintf(page+len, "Board status: driver not initialized\n");
-	}
-
-	return len;
-}
-
-static int comx_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
-	struct comx_channel *ch = dev->priv;
-
-	if (ch->LINE_ioctl) {
-		return(ch->LINE_ioctl(dev, ifr, cmd));
-	}
-	return -EINVAL;
-}
-
-static void comx_reset_dev(struct net_device *dev)
-{
-	dev->open = comx_open;
-	dev->stop = comx_close;
-	dev->hard_start_xmit = comx_xmit;
-	dev->hard_header = comx_header;
-	dev->rebuild_header = comx_rebuild_header;
-	dev->get_stats = comx_stats;
-	dev->do_ioctl = comx_ioctl;
-	dev->change_mtu = NULL;
-	dev->tx_queue_len = 20;
-	dev->flags = IFF_NOARP;
-}
-
-static int comx_init_dev(struct net_device *dev)
-{
-	struct comx_channel *ch;
-
-	if ((ch = kmalloc(sizeof(struct comx_channel), GFP_KERNEL)) == NULL) {
-		return -ENOMEM;
-	}
-	memset(ch, 0, sizeof(struct comx_channel));
-
-	ch->loadavg[0] = 5;
-	ch->loadavg[1] = 300;
-	ch->loadavg[2] = 900;
-	ch->loadavg_size = ch->loadavg[2] / ch->loadavg[0] + 1; 
-	if ((ch->avg_bytes = kmalloc(ch->loadavg_size * 
-		sizeof(unsigned long) * 2, GFP_KERNEL)) == NULL) {
-		kfree(ch);
-		return -ENOMEM;
-	}
-
-	memset(ch->avg_bytes, 0, ch->loadavg_size * sizeof(unsigned long) * 2);
-	ch->loadavg_counter = 0;
-	ch->loadavg_timer.function = comx_loadavg_timerfun;
-	ch->loadavg_timer.data = (unsigned long)dev;
-	ch->loadavg_timer.expires = jiffies + HZ * ch->loadavg[0];
-	add_timer(&ch->loadavg_timer);
-
-	dev->priv = (void *)ch;
-	ch->dev = dev;
-	ch->line_status &= ~LINE_UP;
-
-	ch->current_stats = &ch->stats;
-
-	comx_reset_dev(dev);
-	return 0;
-}
-
-static int comx_read_proc(char *page, char **start, off_t off, int count, 
-	int *eof, void *data)
-{
-	struct proc_dir_entry *file = (struct proc_dir_entry *)data;
-	struct net_device *dev = file->parent->data;
-	struct comx_channel *ch = dev->priv;
-	int len = 0;
-
-	if (strcmp(file->name, FILENAME_STATUS) == 0) {
-		len = comx_statistics(dev, page);
-	} else if (strcmp(file->name, FILENAME_HARDWARE) == 0) {
-		len = sprintf(page, "%s\n", ch->hardware ? 
-			ch->hardware->name : HWNAME_NONE);
-	} else if (strcmp(file->name, FILENAME_PROTOCOL) == 0) {
-		len = sprintf(page, "%s\n", ch->protocol ? 
-			ch->protocol->name : PROTONAME_NONE);
-	} else if (strcmp(file->name, FILENAME_LINEUPDELAY) == 0) {
-		len = sprintf(page, "%01d\n", ch->lineup_delay);
-	}
-
-	if (off >= len) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = page + off;
-	if (count >= len - off) {
-		*eof = 1;
-	}
-	return min_t(int, count, len - off);
-}
-
-
-static int comx_root_read_proc(char *page, char **start, off_t off, int count, 
-	int *eof, void *data)
-{
-	struct proc_dir_entry *file = (struct proc_dir_entry *)data;
-	struct comx_hardware *hw;
-	struct comx_protocol *line;
-
-	int len = 0;
-
-	if (strcmp(file->name, FILENAME_HARDWARELIST) == 0) {
-		for(hw=comx_channels;hw;hw=hw->next) 
-			len+=sprintf(page+len, "%s\n", hw->name);
-	} else if (strcmp(file->name, FILENAME_PROTOCOLLIST) == 0) {
-		for(line=comx_lines;line;line=line->next)
-			len+=sprintf(page+len, "%s\n", line->name);
-	}
-
-	if (off >= len) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = page + off;
-	if (count >= len - off) {
-		*eof = 1;
-	}
-	return min_t(int, count, len - off);
-}
-
-
-
-static int comx_write_proc(struct file *file, const char *buffer, u_long count,
-	void *data)
-{
-	struct proc_dir_entry *entry = (struct proc_dir_entry *)data;
-	struct net_device *dev = (struct net_device *)entry->parent->data;
-	struct comx_channel *ch = dev->priv;
-	char *page;
-	struct comx_hardware *hw = comx_channels;
-	struct comx_protocol *line = comx_lines;
-	int ret=0;
-
-	if (count > PAGE_SIZE) {
-		printk(KERN_ERR "count is %lu > %d!!!\n", count, (int)PAGE_SIZE);
-		return -ENOSPC;
-	}
-
-	if (!(page = (char *)__get_free_page(GFP_KERNEL))) return -ENOMEM;
-
-	if(copy_from_user(page, buffer, count))
-	{
-		count = -EFAULT;
-		goto out;
-	}
-
-	if (page[count-1] == '\n')
-		page[count-1] = '\0';
-	else if (count < PAGE_SIZE)
-		page[count] = '\0';
-	else if (page[count]) {
-		count = -EINVAL;
-		goto out;
-	}
-
-	if (strcmp(entry->name, FILENAME_DEBUG) == 0) {
-		int i;
-		int ret = 0;
-
-		if ((i = simple_strtoul(page, NULL, 10)) != 0) {
-			unsigned long flags;
-
-			save_flags(flags); cli();
-			if (ch->debug_area) kfree(ch->debug_area);
-			if ((ch->debug_area = kmalloc(ch->debug_size = i, 
-				GFP_KERNEL)) == NULL) {
-				ret = -ENOMEM;
-			}
-			ch->debug_start = ch->debug_end = 0;
-			restore_flags(flags);
-			free_page((unsigned long)page);
-			return ret ? ret : count;
-		}
-		
-		if (*page != '+' && *page != '-') {
-			free_page((unsigned long)page);
-			return -EINVAL;
-		}
-		while (comx_debugflags[i].value && 
-			strncmp(comx_debugflags[i].name, page + 1, 
-			strlen(comx_debugflags[i].name))) {
-			i++;
-		}
-	
-		if (comx_debugflags[i].value == 0) {
-			printk(KERN_ERR "Invalid debug option\n");
-			free_page((unsigned long)page);
-			return -EINVAL;
-		}
-		if (*page == '+') {
-			ch->debug_flags |= comx_debugflags[i].value;
-		} else {
-			ch->debug_flags &= ~comx_debugflags[i].value;
-		}
-	} else if (strcmp(entry->name, FILENAME_HARDWARE) == 0) {
-		if(strlen(page)>10) {
-			free_page((unsigned long)page);
-			return -EINVAL;
-		}
-		while (hw) { 
-			if (strcmp(hw->name, page) == 0) {
-				break;
-			} else {
-				hw = hw->next;
-			}
-		}
-#ifdef CONFIG_KMOD
-		if(!hw && comx_strcasecmp(HWNAME_NONE,page) != 0){
-			request_module("comx-hw-%s",page);
-		}		
-		hw=comx_channels;
-		while (hw) {
-			if (comx_strcasecmp(hw->name, page) == 0) {
-				break;
-			} else {
-				hw = hw->next;
-			}
-		}
-#endif
-
-		if (comx_strcasecmp(HWNAME_NONE, page) != 0 && !hw)  {
-			free_page((unsigned long)page);
-			return -ENODEV;
-		}
-		if (ch->init_status & HW_OPEN) {
-			free_page((unsigned long)page);
-			return -EBUSY;
-		}
-		if (ch->hardware && ch->hardware->hw_exit && 
-		   (ret=ch->hardware->hw_exit(dev))) {
-			free_page((unsigned long)page);
-			return ret;
-		}
-		ch->hardware = hw;
-		entry->size = strlen(page) + 1;
-		if (hw && hw->hw_init) hw->hw_init(dev);
-	} else if (strcmp(entry->name, FILENAME_PROTOCOL) == 0) {
-		if(strlen(page)>10) {
-			free_page((unsigned long)page);
-			return -EINVAL;
-		}
-		while (line) {
-			if (comx_strcasecmp(line->name, page) == 0) {
-				break;
-			} else {
-				line = line->next;
-			}
-		}
-#ifdef CONFIG_KMOD
-		if(!line && comx_strcasecmp(PROTONAME_NONE, page) != 0) {
-			request_module("comx-proto-%s",page);
-		}		
-		line=comx_lines;
-		while (line) {
-			if (comx_strcasecmp(line->name, page) == 0) {
-				break;
-			} else {
-				line = line->next;
-			}
-		}
-#endif
-		
-		if (comx_strcasecmp(PROTONAME_NONE, page) != 0 && !line) {
-			free_page((unsigned long)page);
-			return -ENODEV;
-		}
-		
-		if (ch->init_status & LINE_OPEN) {
-			free_page((unsigned long)page);
-			return -EBUSY;
-		}
-		
-		if (ch->protocol && ch->protocol->line_exit && 
-		    (ret=ch->protocol->line_exit(dev))) {
-			free_page((unsigned long)page);
-			return ret;
-		}
-		ch->protocol = line;
-		entry->size = strlen(page) + 1;
-		comx_reset_dev(dev);
-		if (line && line->line_init) line->line_init(dev);
-	} else if (strcmp(entry->name, FILENAME_LINEUPDELAY) == 0) {
-		int i;
-
-		if ((i = simple_strtoul(page, NULL, 10)) != 0) {
-			if (i >=0 && i < 10) { 
-				ch->lineup_delay = i; 
-			} else {
-				printk(KERN_ERR "comx: invalid lineup_delay value\n");
-			}
-		}
-	}
-out:
-	free_page((unsigned long)page);
-	return count;
-}
-
-static int comx_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-{
-	struct proc_dir_entry *new_dir, *debug_file;
-	struct net_device *dev;
-	struct comx_channel *ch;
-	int ret = -EIO;
-
-	if ((dev = kmalloc(sizeof(struct net_device), GFP_KERNEL)) == NULL) {
-		return -ENOMEM;
-	}
-	memset(dev, 0, sizeof(struct net_device));
-
-	lock_kernel();
-	if ((new_dir = create_proc_entry(dentry->d_name.name, mode | S_IFDIR, 
-		comx_root_dir)) == NULL) {
-		goto cleanup_dev;
-	}
-
-	new_dir->nlink = 2;
-	new_dir->data = NULL; // ide jon majd a struct dev
-
-	/* Ezek kellenek */
-	if (!create_comx_proc_entry(FILENAME_HARDWARE, 0644, 
-	    strlen(HWNAME_NONE) + 1, new_dir)) {
-		goto cleanup_new_dir;
-	}
-	if (!create_comx_proc_entry(FILENAME_PROTOCOL, 0644, 
-	    strlen(PROTONAME_NONE) + 1, new_dir)) {
-		goto cleanup_filename_hardware;
-	}
-	if (!create_comx_proc_entry(FILENAME_STATUS, 0444, 0, new_dir)) {
-		goto cleanup_filename_protocol;
-	}
-	if (!create_comx_proc_entry(FILENAME_LINEUPDELAY, 0644, 2, new_dir)) {
-		goto cleanup_filename_status;
-	}
-
-	if ((debug_file = create_proc_entry(FILENAME_DEBUG, 
-	    S_IFREG | 0644, new_dir)) == NULL) {
-		goto cleanup_filename_lineupdelay;
-	}
-	debug_file->data = (void *)debug_file; 
-	debug_file->read_proc = NULL; // see below
-	debug_file->write_proc = &comx_write_proc;
-	debug_file->nlink = 1;
-
-	strcpy(dev->name, (char *)new_dir->name);
-	dev->init = comx_init_dev;
-
-	if (register_netdevice(dev)) {
-		goto cleanup_filename_debug;
-	}
-	ch = dev->priv;
-	if((ch->if_ptr = (void *)kmalloc(sizeof(struct ppp_device), 
-				 GFP_KERNEL)) == NULL) {
-		goto cleanup_register;
-	}
-	memset(ch->if_ptr, 0, sizeof(struct ppp_device));
-	ch->debug_file = debug_file; 
-	ch->procdir = new_dir;
-	new_dir->data = dev;
-
-	ch->debug_start = ch->debug_end = 0;
-	if ((ch->debug_area = kmalloc(ch->debug_size = DEFAULT_DEBUG_SIZE, 
-	    GFP_KERNEL)) == NULL) {
-		ret = -ENOMEM;
-		goto cleanup_if_ptr;
-	}
-
-	ch->lineup_delay = DEFAULT_LINEUP_DELAY;
-
-	MOD_INC_USE_COUNT;
-	unlock_kernel();
-	return 0;
-cleanup_if_ptr:
-	kfree(ch->if_ptr);
-cleanup_register:
-	unregister_netdevice(dev);
-cleanup_filename_debug:
-	remove_proc_entry(FILENAME_DEBUG, new_dir);
-cleanup_filename_lineupdelay:
-	remove_proc_entry(FILENAME_LINEUPDELAY, new_dir);
-cleanup_filename_status:
-	remove_proc_entry(FILENAME_STATUS, new_dir);
-cleanup_filename_protocol:
-	remove_proc_entry(FILENAME_PROTOCOL, new_dir);
-cleanup_filename_hardware:
-	remove_proc_entry(FILENAME_HARDWARE, new_dir);
-cleanup_new_dir:
-	remove_proc_entry(dentry->d_name.name, comx_root_dir);
-cleanup_dev:
-	kfree(dev);
-	unlock_kernel();
-	return ret;
-}
-
-static int comx_rmdir(struct inode *dir, struct dentry *dentry)
-{
-	struct proc_dir_entry *entry = PDE(dentry->d_inode);
-	struct net_device *dev;
-	struct comx_channel *ch;
-	int ret;
-
-	lock_kernel();
-	dev = entry->data;
-	ch = dev->priv;
-	if (dev->flags & IFF_UP) {
-		printk(KERN_ERR "%s: down interface before removing it\n", dev->name);
-		unlock_kernel();
-		return -EBUSY;
-	}
-
-	if (ch->protocol && ch->protocol->line_exit && 
-	    (ret=ch->protocol->line_exit(dev))) {
-		unlock_kernel();
-		return ret;
-	}
-	if (ch->hardware && ch->hardware->hw_exit && 
-	   (ret=ch->hardware->hw_exit(dev))) { 
-		if(ch->protocol && ch->protocol->line_init) {
-			ch->protocol->line_init(dev);
-		}
-		unlock_kernel();
-		return ret;
-	}
-	ch->protocol = NULL;
-	ch->hardware = NULL;
-
-	del_timer(&ch->loadavg_timer);
-	kfree(ch->avg_bytes);
-
-	unregister_netdev(dev);
-	if (ch->debug_area) {
-		kfree(ch->debug_area);
-	}
-	if (dev->priv) {
-		kfree(dev->priv);
-	}
-	free_netdev(dev);
-
-	remove_proc_entry(FILENAME_DEBUG, entry);
-	remove_proc_entry(FILENAME_LINEUPDELAY, entry);
-	remove_proc_entry(FILENAME_STATUS, entry);
-	remove_proc_entry(FILENAME_HARDWARE, entry);
-	remove_proc_entry(FILENAME_PROTOCOL, entry);
-	remove_proc_entry(dentry->d_name.name, comx_root_dir);
-
-	MOD_DEC_USE_COUNT;
-	unlock_kernel();
-	return 0;
-}
-
-static struct dentry *comx_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
-{
-	struct proc_dir_entry *de;
-	struct inode *inode = NULL;
-
-	lock_kernel();
-	if ((de = PDE(dir)) != NULL) {
-		for (de = de->subdir ; de ; de = de->next) {
-			if ((de->namelen == dentry->d_name.len) &&
-			    (memcmp(dentry->d_name.name, de->name, 
-			    de->namelen) == 0))	{
-			 	if ((inode = proc_get_inode(dir->i_sb, 
-			 	    de->low_ino, de)) == NULL) { 
-			 		printk(KERN_ERR "COMX: lookup error\n"); 
-					unlock_kernel();
-			 		return ERR_PTR(-EINVAL); 
-			 	}
-				break;
-			}
-		}
-	}
-	unlock_kernel();
-	dentry->d_op = &comx_dentry_operations;
-	d_add(dentry, inode);
-	return NULL;
-}
-
-int comx_strcasecmp(const char *cs, const char *ct)
-{
-	register signed char __res;
-
-	while (1) {
-		if ((__res = toupper(*cs) - toupper(*ct++)) != 0 || !*cs++) {
-			break;
-		}
-	}
-	return __res;
-}
-
-static int comx_delete_dentry(struct dentry *dentry)
-{
-	return 1;
-}
-
-static struct proc_dir_entry *create_comx_proc_entry(char *name, int mode,
-	int size, struct proc_dir_entry *dir)
-{
-	struct proc_dir_entry *new_file;
-
-	if ((new_file = create_proc_entry(name, S_IFREG | mode, dir)) != NULL) {
-		new_file->data = (void *)new_file;
-		new_file->read_proc = &comx_read_proc;
-		new_file->write_proc = &comx_write_proc;
-		new_file->size = size;
-		new_file->nlink = 1;
-	}
-	return(new_file);
-}
-
-int comx_register_hardware(struct comx_hardware *comx_hw)
-{
-	struct comx_hardware *hw = comx_channels;
-
-	if (!hw) {
-		comx_channels = comx_hw;
-	} else {
-		while (hw->next != NULL && strcmp(comx_hw->name, hw->name) != 0) {
-			hw = hw->next;
-		}
-		if (strcmp(comx_hw->name, hw->name) == 0) {
-			return -1;
-		}
-		hw->next = comx_hw;
-	}
-
-	printk(KERN_INFO "COMX: driver for hardware type %s, version %s\n", comx_hw->name, comx_hw->version);
-	return 0;
-}
-
-int comx_unregister_hardware(char *name)
-{
-	struct comx_hardware *hw = comx_channels;
-
-	if (!hw) {
-		return -1;
-	}
-
-	if (strcmp(hw->name, name) == 0) {
-		comx_channels = comx_channels->next;
-		return 0;
-	}
-
-	while (hw->next != NULL && strcmp(hw->next->name,name) != 0) {
-		hw = hw->next;
-	}
-
-	if (hw->next != NULL && strcmp(hw->next->name, name) == 0) {
-		hw->next = hw->next->next;
-		return 0;
-	}
-	return -1;
-}
-
-int comx_register_protocol(struct comx_protocol *comx_line)
-{
-	struct comx_protocol *pr = comx_lines;
-
-	if (!pr) {
-		comx_lines = comx_line;
-	} else {
-		while (pr->next != NULL && strcmp(comx_line->name, pr->name) !=0) {
-			pr = pr->next;
-		}
-		if (strcmp(comx_line->name, pr->name) == 0) {
-			return -1;
-		}
-		pr->next = comx_line;
-	}
-
-	printk(KERN_INFO "COMX: driver for protocol type %s, version %s\n", comx_line->name, comx_line->version);
-	return 0;
-}
-
-int comx_unregister_protocol(char *name)
-{
-	struct comx_protocol *pr = comx_lines;
-
-	if (!pr) {
-		return -1;
-	}
-
-	if (strcmp(pr->name, name) == 0) {
-		comx_lines = comx_lines->next;
-		return 0;
-	}
-
-	while (pr->next != NULL && strcmp(pr->next->name,name) != 0) {
-		pr = pr->next;
-	}
-
-	if (pr->next != NULL && strcmp(pr->next->name, name) == 0) {
-		pr->next = pr->next->next;
-		return 0;
-	}
-	return -1;
-}
-
-static int __init comx_init(void)
-{
-	struct proc_dir_entry *new_file;
-
-	comx_root_dir = create_proc_entry("comx", 
-		S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, &proc_root);
-	if (!comx_root_dir)
-		return -ENOMEM;
-	comx_root_dir->proc_iops = &comx_root_inode_ops;
-
-	if ((new_file = create_proc_entry(FILENAME_HARDWARELIST, 
-	   S_IFREG | 0444, comx_root_dir)) == NULL) {
-		return -ENOMEM;
-	}
-	
-	new_file->data = new_file;
-	new_file->read_proc = &comx_root_read_proc;
-	new_file->write_proc = NULL;
-	new_file->nlink = 1;
-
-	if ((new_file = create_proc_entry(FILENAME_PROTOCOLLIST, 
-	   S_IFREG | 0444, comx_root_dir)) == NULL) {
-		return -ENOMEM;
-	}
-	
-	new_file->data = new_file;
-	new_file->read_proc = &comx_root_read_proc;
-	new_file->write_proc = NULL;
-	new_file->nlink = 1;
-
-
-	printk(KERN_INFO "COMX: driver version %s (C) 1995-1999 ITConsult-Pro Co. <info@itc.hu>\n", 
-		VERSION);
-	return 0;
-}
-
-static void __exit comx_exit(void)
-{
-	remove_proc_entry(FILENAME_HARDWARELIST, comx_root_dir);
-	remove_proc_entry(FILENAME_PROTOCOLLIST, comx_root_dir);
-	remove_proc_entry(comx_root_dir->name, &proc_root);
-}
-
-module_init(comx_init);
-module_exit(comx_exit);
-
-EXPORT_SYMBOL(comx_register_hardware);
-EXPORT_SYMBOL(comx_unregister_hardware);
-EXPORT_SYMBOL(comx_register_protocol);
-EXPORT_SYMBOL(comx_unregister_protocol);
-EXPORT_SYMBOL(comx_debug_skb);
-EXPORT_SYMBOL(comx_debug_bytes);
-EXPORT_SYMBOL(comx_debug);
-EXPORT_SYMBOL(comx_lineup_func);
-EXPORT_SYMBOL(comx_status);
-EXPORT_SYMBOL(comx_rx);
-EXPORT_SYMBOL(comx_strcasecmp);
-EXPORT_SYMBOL(comx_root_dir);
===== drivers/net/wan/comx.h 1.2 vs edited =====
--- 1.2/drivers/net/wan/comx.h	Tue Feb  5 08:44:27 2002
+++ edited/drivers/net/wan/comx.h	Fri May  7 13:05:54 2004
@@ -1,232 +1 @@
-/*
- * General definitions for the COMX driver 
- * 
- * Original authors:  Arpad Bakay <bakay.arpad@synergon.hu>,
- *                    Peter Bajan <bajan.peter@synergon.hu>,
- * Previous maintainer: Tivadar Szemethy <tiv@itc.hu>
- * Currently maintained by: Gergely Madarasz <gorgo@itc.hu>
- *
- * Copyright (C) 1995-1999 ITConsult-Pro Co. <info@itc.hu>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- *
- * net_device_stats:
- *	rx_length_errors	rec_len < 4 || rec_len > 2000
- *	rx_over_errors		receive overrun (OVR)
- *	rx_crc_errors		rx crc error
- *	rx_frame_errors		aborts rec'd (ABO)
- *	rx_fifo_errors		status fifo overrun (PBUFOVR)
- *	rx_missed_errors	receive buffer overrun (BUFOVR)
- *	tx_aborted_errors	?
- *	tx_carrier_errors	modem line status changes
- *	tx_fifo_errors		tx underrun (locomx)
- */
-#include <linux/config.h>
 
-struct comx_protocol {
-	char	*name;
-	char	*version;
-	unsigned short encap_type;
-	int	(*line_init)(struct net_device *dev);
-	int	(*line_exit)(struct net_device *dev);
-	struct comx_protocol *next;
-	};
-
-struct comx_hardware {
-	char *name; 
-	char *version;
-	int	(*hw_init)(struct net_device *dev);
-	int	(*hw_exit)(struct net_device *dev);
-	int	(*hw_dump)(struct net_device *dev);
-	struct comx_hardware *next;
-	};
-
-struct comx_channel {
-	void		*if_ptr;	// General purpose pointer
-	struct net_device 	*dev;		// Where we belong to
-	struct net_device	*twin;		// On dual-port cards
-	struct proc_dir_entry *procdir;	// the directory
-
-	unsigned char	init_status;
-	unsigned char	line_status;
-
-	struct timer_list lineup_timer;	// against line jitter
-	long int	lineup_pending;
-	unsigned char	lineup_delay;
-
-#if 0
-	struct timer_list reset_timer; // for board resetting
-	long		reset_pending;
-	int		reset_timeout;
-#endif
-
-	struct net_device_stats	stats;	
-	struct net_device_stats *current_stats;
-#if 0
-	unsigned long	board_resets;
-#endif
-	unsigned long 	*avg_bytes;
-	int		loadavg_counter, loadavg_size;
-	int		loadavg[3];
-	struct timer_list loadavg_timer;
-	int		debug_flags;
-	char 		*debug_area;
-	int		debug_start, debug_end, debug_size;
-	struct proc_dir_entry *debug_file;
-#ifdef	CONFIG_COMX_DEBUG_RAW
-	char		*raw;
-	int		raw_len;
-#endif
-	// LINE specific	
-	struct comx_protocol *protocol;
-	void		(*LINE_rx)(struct net_device *dev, struct sk_buff *skb);
-	int		(*LINE_tx)(struct net_device *dev);
-	void		(*LINE_status)(struct net_device *dev, u_short status);
-	int		(*LINE_open)(struct net_device *dev);
-	int		(*LINE_close)(struct net_device *dev);
-	int		(*LINE_xmit)(struct sk_buff *skb, struct net_device *dev);
-	int		(*LINE_header)(struct sk_buff *skb, struct net_device *dev,
-				u_short type,void *daddr, void *saddr, 
-				unsigned len);
-	int		(*LINE_rebuild_header)(struct sk_buff *skb);
-	int		(*LINE_statistics)(struct net_device *dev, char *page);
-	int		(*LINE_parameter_check)(struct net_device *dev);
-	int		(*LINE_ioctl)(struct net_device *dev, struct ifreq *ifr,
-				int cmd);
-	void		(*LINE_mod_use)(int);
-	void *		LINE_privdata;
-
-	// HW specific
-
-	struct comx_hardware *hardware;
-	void	(*HW_board_on)(struct net_device *dev);
-	void	(*HW_board_off)(struct net_device *dev);
-	struct net_device *(*HW_access_board)(struct net_device *dev);
-	void	(*HW_release_board)(struct net_device *dev, struct net_device *savep);
-	int	(*HW_txe)(struct net_device *dev);
-	int	(*HW_open)(struct net_device *dev);
-	int	(*HW_close)(struct net_device *dev);
-	int	(*HW_send_packet)(struct net_device *dev,struct sk_buff *skb);
-	int	(*HW_statistics)(struct net_device *dev, char *page);
-#if 0
-	int	(*HW_reset)(struct net_device *dev, char *page);
-#endif
-	int	(*HW_load_board)(struct net_device *dev);
-	void	(*HW_set_clock)(struct net_device *dev);
-	void	*HW_privdata;
-	};
-
-struct comx_debugflags_struct {
-	char *name;
-	int  value;
-	};
-
-#define	COMX_ROOT_DIR_NAME	"comx"
-
-#define	FILENAME_HARDWARE	"boardtype"
-#define FILENAME_HARDWARELIST	"boardtypes"
-#define FILENAME_PROTOCOL	"protocol"
-#define FILENAME_PROTOCOLLIST	"protocols"
-#define FILENAME_DEBUG		"debug"
-#define FILENAME_CLOCK		"clock"
-#define	FILENAME_STATUS		"status"
-#define	FILENAME_IO		"io"
-#define FILENAME_IRQ		"irq"
-#define	FILENAME_KEEPALIVE	"keepalive"
-#define FILENAME_LINEUPDELAY	"lineup_delay"
-#define FILENAME_CHANNEL	"channel"
-#define FILENAME_FIRMWARE	"firmware"
-#define FILENAME_MEMADDR	"memaddr"
-#define	FILENAME_TWIN		"twin"
-#define FILENAME_T1		"t1"
-#define FILENAME_T2		"t2"
-#define FILENAME_N2		"n2"
-#define FILENAME_WINDOW		"window"
-#define FILENAME_MODE		"mode"
-#define	FILENAME_DLCI		"dlci"
-#define	FILENAME_MASTER		"master"
-#ifdef	CONFIG_COMX_DEBUG_RAW
-#define	FILENAME_RAW		"raw"
-#endif
-
-#define PROTONAME_NONE		"none"
-#define HWNAME_NONE		"none"
-#define KEEPALIVE_OFF		"off"
-
-#define FRAME_ACCEPTED		0		/* sending and xmitter busy */
-#define FRAME_DROPPED		1
-#define FRAME_ERROR		2		/* xmitter error */
-#define	FRAME_QUEUED		3		/* sending but more can come */
-
-#define	LINE_UP			1		/* Modem UP */
-#define PROTO_UP		2
-#define PROTO_LOOP		4
-
-#define	HW_OPEN			1
-#define	LINE_OPEN		2
-#define FW_LOADED		4
-#define IRQ_ALLOCATED		8
-
-#define DEBUG_COMX_RX		2
-#define	DEBUG_COMX_TX		4
-#define	DEBUG_HW_TX		16
-#define	DEBUG_HW_RX		32
-#define	DEBUG_HDLC_KEEPALIVE	64
-#define	DEBUG_COMX_PPP		128
-#define DEBUG_COMX_LAPB		256
-#define	DEBUG_COMX_DLCI		512
-
-#define	DEBUG_PAGESIZE		3072
-#define DEFAULT_DEBUG_SIZE	4096
-#define	DEFAULT_LINEUP_DELAY	1
-#define	FILE_PAGESIZE		3072
-
-#ifndef	COMX_PPP_MAJOR
-#define	COMX_PPP_MAJOR		88
-#endif
-
-
-#define COMX_CHANNEL(dev) ((struct comx_channel*)dev->priv)
-
-#define TWIN(dev) (COMX_CHANNEL(dev)->twin)
-
-
-#ifndef byte
-typedef u8	byte;
-#endif
-#ifndef word
-typedef u16	word;
-#endif
-
-#ifndef	SEEK_SET
-#define	SEEK_SET	0
-#endif
-#ifndef	SEEK_CUR
-#define	SEEK_CUR	1
-#endif
-#ifndef	SEEK_END
-#define	SEEK_END	2
-#endif
-
-extern struct proc_dir_entry * comx_root_dir;
-
-extern int	comx_register_hardware(struct comx_hardware *comx_hw);
-extern int	comx_unregister_hardware(char *name);
-extern int	comx_register_protocol(struct comx_protocol *comx_line);
-extern int	comx_unregister_protocol(char *name);
-
-extern int	comx_rx(struct net_device *dev, struct sk_buff *skb);
-extern void	comx_status(struct net_device *dev, int status);
-extern void	comx_lineup_func(unsigned long d);
-
-extern int	comx_debug(struct net_device *dev, char *fmt, ...);
-extern int	comx_debug_skb(struct net_device *dev, struct sk_buff *skb, char *msg);
-extern int	comx_debug_bytes(struct net_device *dev, unsigned char *bytes, int len,
-		char *msg);
-extern int	comx_strcasecmp(const char *cs, const char *ct);
-
-extern struct inode_operations comx_normal_inode_ops;
===== drivers/net/wan/comxhw.h 1.1 vs edited =====
--- 1.1/drivers/net/wan/comxhw.h	Tue Feb  5 18:40:01 2002
+++ edited/drivers/net/wan/comxhw.h	Fri May  7 13:05:54 2004
@@ -1,113 +1 @@
-/*
- * Defines for comxhw.c
- *
- * Original authors:  Arpad Bakay <bakay.arpad@synergon.hu>,
- *                    Peter Bajan <bajan.peter@synergon.hu>,
- * Previous maintainer: Tivadar Szemethy <tiv@itc.hu>
- * Current maintainer: Gergely Madarasz <gorgo@itc.hu>
- *
- * Copyright (C) 1995-1999 ITConsult-Pro Co. <info@itc.hu>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#define	LOCOMX_IO_EXTENT	8
-#define COMX_IO_EXTENT		4
-#define	HICOMX_IO_EXTENT	16
-
-#define COMX_MAX_TX_SIZE	1600
-#define COMX_MAX_RX_SIZE	2048
-
-#define COMX_JAIL_OFFSET	0xffff
-#define COMX_JAIL_VALUE		0xfe
-#define	COMX_MEMORY_SIZE	65536
-#define HICOMX_MEMORY_SIZE	16384
-#define COMX_MEM_MIN		0xa0000
-#define COMX_MEM_MAX		0xf0000
-
-#define	COMX_DEFAULT_IO		0x360
-#define	COMX_DEFAULT_IRQ	10
-#define	COMX_DEFAULT_MEMADDR	0xd0000
-#define	HICOMX_DEFAULT_IO	0x320
-#define	HICOMX_DEFAULT_IRQ	10
-#define	HICOMX_DEFAULT_MEMADDR	0xd0000
-#define	LOCOMX_DEFAULT_IO	0x368
-#define	LOCOMX_DEFAULT_IRQ	7
-
-#define MAX_CHANNELNO		2
-
-#define	COMX_CHANNEL_OFFSET	0x2000
-
-#define COMX_ENABLE_BOARD_IT    0x40
-#define COMX_BOARD_RESET       	0x20
-#define COMX_ENABLE_BOARD_MEM   0x10
-#define COMX_DISABLE_BOARD_MEM  0
-#define COMX_DISABLE_ALL	0x00
-
-#define HICOMX_DISABLE_ALL	0x00
-#define HICOMX_ENABLE_BOARD_MEM	0x02
-#define HICOMX_DISABLE_BOARD_MEM 0x0
-#define HICOMX_BOARD_RESET	0x01
-#define HICOMX_PRG_MEM		4
-#define HICOMX_DATA_MEM		0
-#define HICOMX_ID_BYTE		0x55
-
-#define CMX_ID_BYTE		0x31
-#define COMX_CLOCK_CONST	8000
-
-#define	LINKUP_READY		3
-
-#define	OFF_FW_L1_ID	0x01e	 /* ID bytes */
-#define OFF_FW_L2_ID	0x1006
-#define	FW_L1_ID_1	0xab
-#define FW_L1_ID_2_COMX		0xc0
-#define FW_L1_ID_2_HICOMX	0xc1
-#define	FW_L2_ID_1	0xab
-
-#define OFF_A_L2_CMD     0x130   /* command register for L2 */
-#define OFF_A_L2_CMDPAR  0x131   /* command parameter byte */
-#define OFF_A_L1_STATB   0x122   /* stat. block for L1 */
-#define OFF_A_L1_ABOREC  0x122   /* receive ABORT counter */
-#define OFF_A_L1_OVERRUN 0x123   /* receive overrun counter */
-#define OFF_A_L1_CRCREC  0x124   /* CRC error counter */
-#define OFF_A_L1_BUFFOVR 0x125   /* buffer overrun counter */
-#define OFF_A_L1_PBUFOVR 0x126   /* priority buffer overrun counter */
-#define OFF_A_L1_MODSTAT 0x127   /* current state of modem ctrl lines */
-#define OFF_A_L1_STATE   0x127   /* end of stat. block for L1 */
-#define OFF_A_L1_TXPC    0x128   /* Tx counter for the PC */
-#define OFF_A_L1_TXZ80   0x129   /* Tx counter for the Z80 */
-#define OFF_A_L1_RXPC    0x12a   /* Rx counter for the PC */
-#define OFF_A_L1_RXZ80   0x12b   /* Rx counter for the Z80 */
-#define OFF_A_L1_REPENA  0x12c   /* IT rep disable */
-#define OFF_A_L1_CHNR    0x12d   /* L1 channel logical number */
-#define OFF_A_L1_CLKINI  0x12e   /* Timer Const */
-#define OFF_A_L2_LINKUP	 0x132	 /* Linkup byte */
-#define OFF_A_L2_DAV	 0x134   /* Rx DAV */
-#define OFF_A_L2_RxBUFP  0x136	 /* Rx buff relative to membase */
-#define OFF_A_L2_TxEMPTY 0x138   /* Tx Empty */
-#define OFF_A_L2_TxBUFP  0x13a   /* Tx Buf */
-#define OFF_A_L2_NBUFFS	 0x144	 /* Number of buffers to fetch */
-
-#define OFF_A_L2_SABMREC 0x164	 /* LAPB no. of SABMs received */
-#define OFF_A_L2_SABMSENT 0x165	 /* LAPB no. of SABMs sent */
-#define OFF_A_L2_REJREC  0x166	 /* LAPB no. of REJs received */
-#define OFF_A_L2_REJSENT 0x167	 /* LAPB no. of REJs sent */
-#define OFF_A_L2_FRMRREC 0x168	 /* LAPB no. of FRMRs received */
-#define OFF_A_L2_FRMRSENT 0x169	 /* LAPB no. of FRMRs sent */
-#define OFF_A_L2_PROTERR 0x16A	 /* LAPB no. of protocol errors rec'd */
-#define OFF_A_L2_LONGREC 0x16B	 /* LAPB no. of long frames */
-#define OFF_A_L2_INVNR   0x16C	 /* LAPB no. of invalid N(R)s rec'd */
-#define OFF_A_L2_UNDEFFR 0x16D	 /* LAPB no. of invalid frames */
-
-#define	OFF_A_L2_T1	0x174	 /* T1 timer */
-#define	OFF_A_L2_ADDR	0x176	 /* DCE = 1, DTE = 3 */
-
-#define	COMX_CMD_INIT	1
-#define COMX_CMD_EXIT	2
-#define COMX_CMD_OPEN	16
-#define COMX_CMD_CLOSE	17
 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2004-05-16 21:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-07 11:17 [PATCH] remove comx drivers from tree Christoph Hellwig
2004-05-14 17:32 ` Jeff Garzik
2004-05-15 21:41   ` Krzysztof Halasa
2004-05-16 21:54     ` Jeff Garzik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).