/*
  Madge Horizon ATM Adapter driver.
  Copyright (C) 1995-1999  Madge Networks Ltd.
  
  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.
  
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  
  The GNU GPL is contained in /usr/doc/copyright/GPL on a Debian
  system and in the file COPYING in the Linux kernel source.
*/

/*
  IMPORTANT NOTE: Madge Networks no longer makes the adapters
  supported by this driver and makes no commitment to maintain it.
*/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched/signal.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/errno.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <linux/sonet.h>
#include <linux/skbuff.h>
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/uio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/wait.h>
#include <linux/slab.h>

#include <asm/io.h>
#include <linux/atomic.h>
#include <linux/uaccess.h>
#include <asm/string.h>
#include <asm/byteorder.h>

#include "horizon.h"

#define maintainer_string "Giuliano Procida at Madge Networks <gprocida@madge.com>"
#define description_string "Madge ATM Horizon [Ultra] driver"
#define version_string "1.2.1"

static inline void __init show_version (void) {
  printk ("%s version %s\n", description_string, version_string);
}

/*
  
  CREDITS
  
  Driver and documentation by:
  
  Chris Aston        Madge Networks
  Giuliano Procida   Madge Networks
  Simon Benham       Madge Networks
  Simon Johnson      Madge Networks
  Various Others     Madge Networks
  
  Some inspiration taken from other drivers by:
  
  Alexandru Cucos    UTBv
  Kari Mettinen      University of Helsinki
  Werner Almesberger EPFL LRC
  
  Theory of Operation
  
  I Hardware, detection, initialisation and shutdown.
  
  1. Supported Hardware
  
  This driver should handle all variants of the PCI Madge ATM adapters
  with the Horizon chipset. These are all PCI cards supporting PIO, BM
  DMA and a form of MMIO (registers only, not internal RAM).
  
  The driver is only known to work with SONET and UTP Horizon Ultra
  cards at 155Mb/s. However, code is in place to deal with both the
  original Horizon and 25Mb/s operation.
  
  There are two revisions of the Horizon ASIC: the original and the
  Ultra. Details of hardware bugs are in section III.
  
  The ASIC version can be distinguished by chip markings but is NOT
  indicated by the PCI revision (all adapters seem to have PCI rev 1).
  
  I believe that:
  
  Horizon       => Collage  25 PCI Adapter (UTP and STP)
  Horizon Ultra => Collage 155 PCI Client (UTP or SONET)
  Ambassador x  => Collage 155 PCI Server (completely different)
  
  Horizon (25Mb/s) is fitted with UTP and STP connectors. It seems to
  have a Madge B154 plus glue logic serializer. I have also found a
  really ancient version of this with slightly different glue. It
  comes with the revision 0 (140-025-01) ASIC.
  
  Horizon Ultra (155Mb/s) is fitted with either a Pulse Medialink
  output (UTP) or an HP HFBR 5205 output (SONET). It has either
  Madge's SAMBA framer or a SUNI-lite device (early versions). It
  comes with the revision 1 (140-027-01) ASIC.
  
  2. Detection
  
  All Horizon-based cards present with the same PCI Vendor and Device
  IDs. The standard Linux 2.2 PCI API is used to locate any cards and
  to enable bus-mastering (with appropriate latency).
  
  ATM_LAYER_STATUS in the control register distinguishes between the
  two possible physical layers (25 and 155). It is not clear whether
  the 155 cards can also operate at 25Mbps. We rely on the fact that a
  card operates at 155 if and only if it has the newer Horizon Ultra
  ASIC.
  
  For 155 cards the two possible framers are probed for and then set
  up for loop-timing.
  
  3. Initialisation
  
  The card is reset and then put into a known state. The physical
  layer is configured for normal operation at the appropriate speed;
  in the case of the 155 cards, the framer is initialised with
  line-based timing; the internal RAM is zeroed and the allocation of
  buffers for RX and TX is made; the Burnt In Address is read and
  copied to the ATM ESI; various policy settings for RX (VPI bits,
  unknown VCs, oam cells) are made. Ideally all policy items should be
  configurable at module load (if not actually on-demand), however,
  only the vpi vs vci bit allocation can be specified at insmod.
  
  4. Shutdown
  
  This is in response to module_cleaup. No VCs are in use and the card
  should be idle; it is reset.
  
  II Driver software (as it should be)
  
  0. Traffic Parameters
  
  The traffic classes (not an enumeration) are currently: ATM_NONE (no
  traffic), ATM_UBR, ATM_CBR, ATM_VBR and ATM_ABR, ATM_ANYCLASS
  (compatible with everything). Together with (perhaps only some of)
  the following items they make up the traffic specification.
  
  struct atm_trafprm {
    unsigned char traffic_class; traffic class (ATM_UBR, ...)
    int           max_pcr;       maximum PCR in cells per second
    int           pcr;           desired PCR in cells per second
    int           min_pcr;       minimum PCR in cells per second
    int           max_cdv;       maximum CDV in microseconds
    int           max_sdu;       maximum SDU in bytes
  };
  
  Note that these denote bandwidth available not bandwidth used; the
  possibilities according to ATMF are:
  
  Real Time (cdv and max CDT given)
  
  CBR(pcr)             pcr bandwidth always available
  rtVBR(pcr,scr,mbs)   scr bandwidth always available, up to pcr at mbs too
  
  Non Real Time
  
  nrtVBR(pcr,scr,mbs)  scr bandwidth always available, up to pcr at mbs too
  UBR()
  ABR(mcr,pcr)         mcr bandwidth always available, up to pcr (depending) too
  
  mbs is max burst size (bucket)
  pcr and scr have associated cdvt values
  mcr is like scr but has no cdtv
  cdtv may differ at each hop
  
  Some of the above items are qos items (as opposed to traffic
  parameters). We have nothing to do with qos. All except ABR can have
  their traffic parameters converted to GCRA parameters. The GCRA may
  be implemented as a (real-number) leaky bucket. The GCRA can be used
  in complicated ways by switches and in simpler ways by end-stations.
  It can be used both to filter incoming cells and shape out-going
  cells.
  
  ATM Linux actually supports:
  
  ATM_NONE() (no traffic in this direction)
  ATM_UBR(max_frame_size)
  ATM_CBR(max/min_pcr, max_cdv, max_frame_size)
  
  0 or ATM_MAX_PCR are used to indicate maximum available PCR
  
  A traffic specification consists of the AAL type and separate
  traffic specifications for either direction. In ATM Linux it is:
  
  struct atm_qos {
  struct atm_trafprm txtp;
  struct atm_trafprm rxtp;
  unsigned char aal;
  };
  
  AAL types are:
  
  ATM_NO_AAL    AAL not specified
  ATM_AAL0      "raw" ATM cells
  ATM_AAL1      AAL1 (CBR)
  ATM_AAL2      AAL2 (VBR)
  ATM_AAL34     AAL3/4 (data)
  ATM_AAL5      AAL5 (data)
  ATM_SAAL      signaling AAL
  
  The Horizon has support for AAL frame types: 0, 3/4 and 5. However,
  it does not implement AAL 3/4 SAR and it has a different notion of
  "raw cell" to ATM Linux's (48 bytes vs. 52 bytes) so neither are
  supported by this driver.
  
  The Horizon has limited support for ABR (including UBR), VBR and
  CBR. Each TX channel has a bucket (containing up to 31 cell units)
  and two timers (PCR and SCR) associated with it that can be used to
  govern cell emissions and host notification (in the case of ABR this
  is presumably so that RM cells may be emitted at appropriate times).
  The timers may either be disabled or may be set to any of 240 values
  (determined by the clock crystal, a fixed (?) per-device divider, a
  configurable divider and a configurable timer preload value).
  
  At the moment only UBR and CBR are supported by the driver. VBR will
  be supported as soon as ATM for Linux supports it. ABR support is
  very unlikely as RM cell handling is completely up to the driver.
  
  1. TX (TX channel setup and TX transfer)
  
  The TX half of the driver owns the TX Horizon registers. The TX
  component in the IRQ handler is the BM completion handler. This can
  only be entered when tx_busy is true (enforced by hardware). The
  other TX component can only be entered when tx_busy is false
  (enforced by driver). So TX is single-threaded.
  
  Apart from a minor optimisation to not re-select the last channel,
  the TX send component works as follows:
  
  Atomic test and set tx_busy until we succeed; we should implement
  some sort of timeout so that tx_busy will never be stuck at true.
  
  If no TX channel is set up for this VC we wait for an idle one (if
  necessary) and set it up.
  
  At this point we have a TX channel ready for use. We wait for enough
  buffers to become available then start a TX transmit (set the TX
  descriptor, schedule transfer, exit).
  
  The IRQ component handles TX completion (stats, free buffer, tx_busy
  unset, exit). We also re-schedule further transfers for the same
  frame if needed.
  
  TX setup in more detail:
  
  TX open is a nop, the relevant information is held in the hrz_vcc
  (vcc->dev_data) structure and is "cached" on the card.
  
  TX close gets the TX lock and clears the channel from the "cache".
  
  2. RX (Data Available and RX transfer)
  
  The RX half of the driver owns the RX registers. There are two RX
  components in the IRQ handler: the data available handler deals with
  fresh data that has arrived on the card, the BM completion handler
  is very similar to the TX completion handler. The data available
  handler grabs the rx_lock and it is only released once the data has
  been discarded or completely transferred to the host. The BM
  completion handler only runs when the lock is held; the data
  available handler is locked out over the same period.
  
  Data available on the card triggers an interrupt. If the data is not
  suitable for our existing RX channels or we cannot allocate a buffer
  it is flushed. Otherwise an RX receive is scheduled. Multiple RX
  transfers may be scheduled for the same frame.
  
  RX setup in more detail:
  
  RX open...
  RX close...
  
  III Hardware Bugs
  
  0. Byte vs Word addressing of adapter RAM.
  
  A design feature; see the .h file (especially the memory map).
  
  1. Bus Master Data Transfers (original Horizon only, fixed in Ultra)
  
  The host must not start a transmit direction transfer at a
  non-four-byte boundary in host memory. Instead the host should
  perform a byte, or a two byte, or one byte followed by two byte
  transfer in order to start the rest of the transfer on a four byte
  boundary. RX is OK.
  
  Simultaneous transmit and receive direction bus master transfers are
  not allowed.
  
  The simplest solution to these two is to always do PIO (never DMA)
  in the TX direction on the original Horizon. More complicated
  solutions are likely to hurt my brain.
  
  2. Loss of buffer on close VC
  
  When a VC is being closed, the buffer associated with it is not
  returned to the pool. The host must store the reference to this
  buffer and when opening a new VC then give it to that new VC.
  
  The host intervention currently consists of stacking such a buffer
  pointer at VC close and checking the stack at VC open.
  
  3. Failure to close a VC
  
  If a VC is currently receiving a frame then closing the VC may fail
  and the frame continues to be received.
  
  The solution is to make sure any received frames are flushed when
  ready. This is currently done just before the solution to 2.
  
  4. PCI bus (original Horizon only, fixed in Ultra)
  
  Reading from the data port prior to initialisation will hang the PCI
  bus. Just don't do that then! We don't.
  
  IV To Do List
  
  . Timer code may be broken.
  
  . Allow users to specify buffer allocation split for TX and RX.
  
  . Deal once and for all with buggy VC close.
  
  . Handle interrupted and/or non-blocking operations.
  
  . Change some macros to functions and move from .h to .c.
  
  . Try to limit the number of TX frames each VC may have queued, in
    order to reduce the chances of TX buffer exhaustion.
  
  . Implement VBR (bucket and timers not understood) and ABR (need to
    do RM cells manually); also no Linux support for either.
  
  . Implement QoS changes on open VCs (involves extracting parts of VC open
    and close into separate functions and using them to make changes).
  
*/

/********** globals **********/

static void do_housekeeping (unsigned long arg);

static unsigned short debug = 0;
static unsigned short vpi_bits = 0;
static int max_tx_size = 9000;
static int max_rx_size = 9000;
static unsigned char pci_lat = 0;

/********** access functions **********/

/* Read / Write Horizon registers */
static inline void wr_regl (const hrz_dev * dev, unsigned char reg, u32 data) {
  outl (cpu_to_le32 (data), dev->iobase + reg);
}

static inline u32 rd_regl (const hrz_dev * dev, unsigned char reg) {
  return le32_to_cpu (inl (dev->iobase + reg));
}

static inline void wr_regw (const hrz_dev * dev, unsigned char reg, u16 data) {
  outw (cpu_to_le16 (data), dev->iobase + reg);
}

static inline u16 rd_regw (const hrz_dev * dev, unsigned char reg) {
  return le16_to_cpu (inw (dev->iobase + reg));
}

static inline void wrs_regb (const hrz_dev * dev, unsigned char reg, void * addr, u32 len) {
  outsb (dev->iobase + reg, addr, len);
}

static inline void rds_regb (const hrz_dev * dev, unsigned char reg, void * addr, u32 len) {
  insb (dev->iobase + reg, addr, len);
}

/* Read / Write to a given address in Horizon buffer memory.
   Interrupts must be disabled between the address register and data
   port accesses as these must form an atomic operation. */
static inline void wr_mem (const hrz_dev * dev, HDW * addr, u32 data) {
  // wr_regl (dev, MEM_WR_ADDR_REG_OFF, (u32) addr);
  wr_regl (dev, MEM_WR_ADDR_REG_OFF, (addr - (HDW *) 0) * sizeof(HDW));
  wr_regl (dev, MEMORY_PORT_OFF, data);
}

static inline u32 rd_mem (const hrz_dev * dev, HDW * addr) {
  // wr_regl (dev, MEM_RD_ADDR_REG_OFF, (u32) addr);
  wr_regl (dev, MEM_RD_ADDR_REG_OFF, (addr - (HDW *) 0) * sizeof(HDW));
  return rd_regl (dev, MEMORY_PORT_OFF);
}

static inline void wr_framer (const hrz_dev * dev, u32 addr, u32 data) {
  wr_regl (dev, MEM_WR_ADDR_REG_OFF, (u32) addr | 0x80000000);
  wr_regl (dev, MEMORY_PORT_OFF, data);
}

static inline u32 rd_framer (const hrz_dev * dev, u32 addr) {
  wr_regl (dev, MEM_RD_ADDR_REG_OFF, (u32) addr | 0x80000000);
  return rd_regl (dev, MEMORY_PORT_OFF);
}

/********** specialised access functions **********/

/* RX */

static inline void FLUSH_RX_CHANNEL (hrz_dev * dev, u16 channel) {
  wr_regw (dev, RX_CHANNEL_PORT_OFF, FLUSH_CHANNEL | channel);
  return;
}

static void WAIT_FLUSH_RX_COMPLETE (hrz_dev * dev) {
  while (rd_regw (dev, RX_CHANNEL_PORT_OFF) & FLUSH_CHANNEL)
    ;
  return;
}

static inline void SELECT_RX_CHANNEL (hrz_dev * dev, u16 channel) {
  wr_regw (dev, RX_CHANNEL_PORT_OFF, channel);
  return;
}

static void WAIT_UPDATE_COMPLETE (hrz_dev * dev) {
  while (rd_regw (dev, RX_CHANNEL_PORT_OFF) & RX_CHANNEL_UPDATE_IN_PROGRESS)
    ;
  return;
}

/* TX */

static inline void SELECT_TX_CHANNEL (hrz_dev * dev, u16 tx_channel) {
  wr_regl (dev, TX_CHANNEL_PORT_OFF, tx_channel);
  return;
}

/* Update or query one configuration parameter of a particular channel. */

static inline void update_tx_channel_config (hrz_dev * dev, short chan, u8 mode, u16 value) {
  wr_regw (dev, TX_CHANNEL_CONFIG_COMMAND_OFF,
	   chan * TX_CHANNEL_CONFIG_MULT | mode);
    wr_regw (dev, TX_CHANNEL_CONFIG_DATA_OFF, value);
    return;
}

/********** dump functions **********/

static inline void dump_skb (char * prefix, unsigned int vc, struct sk_buff * skb) {
#ifdef DEBUG_HORIZON
  unsigned int i;
  unsigned char * data = skb->data;
  PRINTDB (DBG_DATA, "%s(%u) ", prefix, vc);
  for (i=0; i<skb->len && i < 256;i++)
    PRINTDM (DBG_DATA, "%02x ", data[i]);
  PRINTDE (DBG_DATA,"");
#else
  (void) prefix;
  (void) vc;
  (void) skb;
#endif
  return;
}

static inline void dump_regs (hrz_dev * dev) {
#ifdef DEBUG_HORIZON
  PRINTD (DBG_REGS, "CONTROL 0: %#x", rd_regl (dev, CONTROL_0_REG));
  PRINTD (DBG_REGS, "RX CONFIG: %#x", rd_regw (dev, RX_CONFIG_OFF));
  PRINTD (DBG_REGS, "TX CONFIG: %#x", rd_regw (dev, TX_CONFIG_OFF));
  PRINTD (DBG_REGS, "TX STATUS: %#x", rd_regw (dev, TX_STATUS_OFF));
  PRINTD (DBG_REGS, "IRQ ENBLE: %#x", rd_regl (dev, INT_ENABLE_REG_OFF));
  PRINTD (DBG_REGS, "IRQ SORCE: %#x", rd_regl (dev, INT_SOURCE_REG_OFF));
#else
  (void) dev;
#endif
  return;
}

static inline void dump_framer (hrz_dev * dev) {
#ifdef DEBUG_HORIZON
  unsigned int i;
  PRINTDB (DBG_REGS, "framer registers:");
  for (i = 0; i < 0x10; ++i)
    PRINTDM (DBG_REGS, " %02x", rd_framer (dev, i));
  PRINTDE (DBG_REGS,"");
#else
  (void) dev;
#endif
  return;
}

/********** VPI/VCI <-> (RX) channel conversions **********/

/* RX channels are 10 bit integers, these fns are quite paranoid */

static inline int vpivci_to_channel (u16 * channel, const short vpi, const int vci) {
  unsigned short vci_bits = 10 - vpi_bits;
  if (0 <= vpi && vpi < 1<<vpi_bits && 0 <= vci && vci < 1<<vci_bits) {
    *channel = vpi<<vci_bits | vci;
    return *channel ? 0 : -EINVAL;
  }
  return -EINVAL;
}

/********** decode RX queue entries **********/

static inline u16 rx_q_entry_to_length (u32 x) {
  return x & RX_Q_ENTRY_LENGTH_MASK;
}

static inline u16 rx_q_entry_to_rx_channel (u32 x) {
  return (x>>RX_Q_ENTRY_CHANNEL_SHIFT) & RX_CHANNEL_MASK;
}

/* Cell Transmit Rate Values
 *
 * the cell transmit rate (cells per sec) can be set to a variety of
 * different values by specifying two parameters: a timer preload from
 * 1 to 16 (stored as 0 to 15) and a clock divider (2 to the power of
 * an exponent from 0 to 14; the special value 15 disables the timer).
 *
 * cellrate = baserate / (preload * 2^divider)
 *
 * The maximum cell rate that can be specified is therefore just the
 * base rate. Halving the preload is equivalent to adding 1 to the
 * divider and so values 1 to 8 of the preload are redundant except
 * in the case of a maximal divider (14).
 *
 * Given a desired cell rate, an algorithm to determine the preload
 * and divider is:
 * 
 * a) x = baserate / cellrate, want p * 2^d = x (as far as possible)
 * b) if x > 16 * 2^14 then set p = 16, d = 14 (min rate), done
 *    if x <= 16 then set p = x, d = 0 (high rates), done
 * c) now have 16 < x <= 2^18, or 1 < x/16 <= 2^14 and we want to
 *    know n such that 2^(n-1) < x/16 <= 2^n, so slide a bit until
 *    we find the range (n will be between 1 and 14), set d = n
 * d) Also have 8 < x/2^n <= 16, so set p nearest x/2^n
 *
 * The algorithm used below is a minor variant of the above.
 *
 * The base rate is derived from the oscillator frequency (Hz) using a
 * fixed divider:
 *
 * baserate = freq / 32 in the case of some Unknown Card
 * baserate = freq / 8  in the case of the Horizon        25
 * baserate = freq / 8  in the case of the Horizon Ultra 155
 *
 * The Horizon cards have oscillators and base rates as follows:
 *
 * Card               Oscillator  Base Rate
 * Unknown Card       33 MHz      1.03125 MHz (33 MHz = PCI freq)
 * Horizon        25  32 MHz      4       MHz
 * Horizon Ultra 155  40 MHz      5       MHz
 *
 * The following defines give the base rates in Hz. These were
 * previously a factor of 100 larger, no doubt someone was using
 * cps*100.
 */

#define BR_UKN 1031250l
#define BR_HRZ 4000000l
#define BR_ULT 5000000l

// d is an exponent
#define CR_MIND 0
#define CR_MAXD 14

// p ranges from 1 to a power of 2
#define CR_MAXPEXP 4
 
static int make_rate (const hrz_dev * dev, u32 c, rounding r,
		      u16 * bits, unsigned int * actual)
{
	// note: rounding the rate down means rounding 'p' up
	const unsigned long br = test_bit(ultra, &dev->flags) ? BR_ULT : BR_HRZ;
  
	u32 div = CR_MIND;
	u32 pre;
  
	// br_exp and br_man are used to avoid overflowing (c*maxp*2^d) in
	// the tests below. We could think harder about exact possibilities
	// of failure...
  
	unsigned long br_man = br;
	unsigned int br_exp = 0;
  
	PRINTD (DBG_QOS|DBG_FLOW, "make_rate b=%lu, c=%u, %s", br, c,
		r == round_up ? "up" : r == round_down ? "down" : "nearest");
  
	// avoid div by zero
	if (!c) {
		PRINTD (DBG_QOS|DBG_ERR, "zero rate is not allowed!");
		return -EINVAL;
	}
  
	while (br_exp < CR_MAXPEXP + CR_MIND && (br_man % 2 == 0)) {
		br_man = br_man >> 1;
		++br_exp;
	}
	// (br >>br_exp) <<br_exp == br and
	// br_exp <= CR_MAXPEXP+CR_MIND
  
	if (br_man <= (c << (CR_MAXPEXP+CR_MIND-br_exp))) {
		// Equivalent to: B <= (c << (MAXPEXP+MIND))
		// take care of rounding
		switch (r) {
			case round_down:
				pre = DIV_ROUND_UP(br, c<<div);
				// but p must be non-zero
				if (!pre)
					pre = 1;
				break;
			case round_nearest:
				pre = DIV_ROUND_CLOSEST(br, c<<div);
				// but p must be non-zero
				if (!pre)
					pre = 1;
				break;
			default:	/* round_up */
				pre = br/(c<<div);
				// but p must be non-zero
				if (!pre)
					return -EINVAL;
		}
		PRINTD (DBG_QOS, "A: p=%u, d=%u", pre, div);
		goto got_it;
	}
  
	// at this point we have
	// d == MIND and (c << (MAXPEXP+MIND)) < B
	while (div < CR_MAXD) {
		div++;
		if (br_man <= (c << (CR_MAXPEXP+div-br_exp))) {
			// Equivalent to: B <= (c << (MAXPEXP+d))
			// c << (MAXPEXP+d-1) < B <= c << (MAXPEXP+d)
			// 1 << (MAXPEXP-1) < B/2^d/c <= 1 << MAXPEXP
			// MAXP/2 < B/c2^d <= MAXP
			// take care of rounding
			switch (r) {
				case round_down:
					pre = DIV_ROUND_UP(br, c<<div);
					break;
				case round_nearest:
					pre = DIV_ROUND_CLOSEST(br, c<<div);
					break;
				default: /* round_up */
					pre = br/(c<<div);
			}
			PRINTD (DBG_QOS, "B: p=%u, d=%u", pre, div);
			goto got_it;
		}
	}
	// at this point we have
	// d == MAXD and (c << (MAXPEXP+MAXD)) < B
	// but we cannot go any higher
	// take care of rounding
	if (r == round_down)
		return -EINVAL;
	pre = 1 << CR_MAXPEXP;
	PRINTD (DBG_QOS, "C: p=%u, d=%u", pre, div);
got_it:
	// paranoia
	if (div > CR_MAXD || (!pre) || pre > 1<<CR_MAXPEXP) {
		PRINTD (DBG_QOS, "set_cr internal failure: d=%u p=%u",
			div, pre);
		return -EINVAL;
	} else {
		if (bits)
			*bits = (div<<CLOCK_SELECT_SHIFT) | (pre-1);
		if (actual) {
			*actual = DIV_ROUND_UP(br, pre<<div);
			PRINTD (DBG_QOS, "actual rate: %u", *actual);
		}
		return 0;
	}
}

static int make_rate_with_tolerance (const hrz_dev * dev, u32 c, rounding r, unsigned int tol,
				     u16 * bit_pattern, unsigned int * actual) {
  unsigned int my_actual;
  
  PRINTD (DBG_QOS|DBG_FLOW, "make_rate_with_tolerance c=%u, %s, tol=%u",
	  c, (r == round_up) ? "up" : (r == round_down) ? "down" : "nearest", tol);
  
  if (!actual)
    // actual rate is not returned
    actual = &my_actual;
  
  if (make_rate (dev, c, round_nearest, bit_pattern, actual))
    // should never happen as round_nearest always succeeds
    return -1;
  
  if (c - tol <= *actual && *actual <= c + tol)
    // within tolerance
    return 0;
  else
    // intolerant, try rounding instead
    return make_rate (dev, c, r, bit_pattern, actual);
}

/********** Listen on a VC **********/

static int hrz_open_rx (hrz_dev * dev, u16 channel) {
  // is there any guarantee that we don't get two simulataneous
  // identical calls of this function from different processes? yes
  // rate_lock
  unsigned long flags;
  u32 channel_type; // u16?
  
  u16 buf_ptr = RX_CHANNEL_IDLE;
  
  rx_ch_desc * rx_desc = &memmap->rx_descs[channel];
  
  PRINTD (DBG_FLOW, "hrz_open_rx %x", channel);
  
  spin_lock_irqsave (&dev->mem_lock, flags);
  channel_type = rd_mem (dev, &rx_desc->wr_buf_type) & BUFFER_PTR_MASK;
  spin_unlock_irqrestore (&dev->mem_lock, flags);
  
  // very serious error, should never occur
  if (channel_type != RX_CHANNEL_DISABLED) {
    PRINTD (DBG_ERR|DBG_VCC, "RX channel for VC already open");
    return -EBUSY; // clean up?
  }
  
  // Give back spare buffer
  if (dev->noof_spare_buffers) {
    buf_ptr = dev->spare_buffers[--dev->noof_spare_buffers];
    PRINTD (DBG_VCC, "using a spare buffer: %u", buf_ptr);
    // should never occur
    if (buf_ptr == RX_CHANNEL_DISABLED || buf_ptr == RX_CHANNEL_IDLE) {
      // but easy to recover from
      PRINTD (DBG_ERR|DBG_VCC, "bad spare buffer pointer, using IDLE");
      buf_ptr = RX_CHANNEL_IDLE;
    }
  } else {
    PRINTD (DBG_VCC, "using IDLE buffer pointer");
  }
  
  // Channel is currently disabled so change its status to idle
  
  // do we really need to save the flags again?
  spin_lock_irqsave (&dev->mem_lock, flags);
  
  wr_mem (dev, &rx_desc->wr_buf_type,
	  buf_ptr | CHANNEL_TYPE_AAL5 | FIRST_CELL_OF_AAL5_FRAME);
  if (buf_ptr != RX_CHANNEL_IDLE)
    wr_mem (dev, &rx_desc->rd_buf_type, buf_ptr);
  
  spin_unlock_irqrestore (&dev->mem_lock, flags);
  
  // rxer->rate = make_rate (qos->peak_cells);
  
  PRINTD (DBG_FLOW, "hrz_open_rx ok");
  
  return 0;
}

#if 0
/********** change vc rate for a given vc **********/

static void hrz_change_vc_qos (ATM_RXER * rxer, MAAL_QOS * qos) {
  rxer->rate = make_rate (qos->peak_cells);
}
#endif

/********** free an skb (as per ATM device driver documentation) **********/

static void hrz_kfree_skb (struct sk_buff * skb) {
  if (ATM_SKB(skb)->vcc->pop) {
    ATM_SKB(skb)->vcc->pop (ATM_SKB(skb)->vcc, skb);
  } else {
    dev_kfree_skb_any (skb);
  }
}

/********** cancel listen on a VC **********/

static void hrz_close_rx (hrz_dev * dev, u16 vc) {
  unsigned long flags;
  
  u32 value;
  
  u32 r1, r2;
  
  rx_ch_desc * rx_desc = &memmap->rx_descs[vc];
  
  int was_idle = 0;
  
  spin_lock_irqsave (&dev->mem_lock, flags);
  value = rd_mem (dev, &rx_desc->wr_buf_type) & BUFFER_PTR_MASK;
  spin_unlock_irqrestore (&dev->mem_lock, flags);
  
  if (value == RX_CHANNEL_DISABLED) {
    // I suppose this could happen once we deal with _NONE traffic properly
    PRINTD (DBG_VCC, "closing VC: RX channel %u already disabled", vc);
    return;
  }
  if (value == RX_CHANNEL_IDLE)
    was_idle = 1;
  
  spin_lock_irqsave (&dev->mem_lock, flags);
  
  for (;;) {
    wr_mem (dev, &rx_desc->wr_buf_type, RX_CHANNEL_DISABLED);
    
    if ((rd_mem (dev, &rx_desc->wr_buf_type) & BUFFER_PTR_MASK) == RX_CHANNEL_DISABLED)
      break;
    
    was_idle = 0;
  }
  
  if (was_idle) {
    spin_unlock_irqrestore (&dev->mem_lock, flags);
    return;
  }
  
  WAIT_FLUSH_RX_COMPLETE(dev);
  
  // XXX Is this all really necessary? We can rely on the rx_data_av
  // handler to discard frames that remain queued for delivery. If the
  // worry is that immediately reopening the channel (perhaps by a
  // different process) may cause some data to be mis-delivered then
  // there may still be a simpler solution (such as busy-waiting on
  // rx_busy once the channel is disabled or before a new one is
  // opened - does this leave any holes?). Arguably setting up and
  // tearing down the TX and RX halves of each virtual circuit could
  // most safely be done within ?x_busy protected regions.
  
  // OK, current changes are that Simon's marker is disabled and we DO
  // look for NULL rxer elsewhere. The code here seems flush frames
  // and then remember the last dead cell belonging to the channel
  // just disabled - the cell gets relinked at the next vc_open.
  // However, when all VCs are closed or only a few opened there are a
  // handful of buffers that are unusable.
  
  // Does anyone feel like documenting spare_buffers properly?
  // Does anyone feel like fixing this in a nicer way?
  
  // Flush any data which is left in the channel
  for (;;) {
    // Change the rx channel port to something different to the RX
    // channel we are trying to close to force Horizon to flush the rx
    // channel read and write pointers.
    
    u16 other = vc^(RX_CHANS/2);
    
    SELECT_RX_CHANNEL (dev, other);
    WAIT_UPDATE_COMPLETE (dev);
    
    r1 = rd_mem (dev, &rx_desc->rd_buf_type);
    
    // Select this RX channel. Flush doesn't seem to work unless we
    // select an RX channel before hand
    
    SELECT_RX_CHANNEL (dev, vc);
    WAIT_UPDATE_COMPLETE (dev);
    
    // Attempt to flush a frame on this RX channel
    
    FLUSH_RX_CHANNEL (dev, vc);
    WAIT_FLUSH_RX_COMPLETE (dev);
    
    // Force Horizon to flush rx channel read and write pointers as before
    
    SELECT_RX_CHANNEL (dev, other);
    WAIT_UPDATE_COMPLETE (dev);
    
    r2 = rd_mem (dev, &rx_desc->rd_buf_type);
    
    PRINTD (DBG_VCC|DBG_RX, "r1 = %u, r2 = %u", r1, r2);
    
    if (r1 == r2) {
      dev->spare_buffers[dev->noof_spare_buffers++] = (u16)r1;
      break;
    }
  }
  
#if 0
  {
    rx_q_entry * wr_ptr = &memmap->rx_q_entries[rd_regw (dev, RX_QUEUE_WR_PTR_OFF)];
    rx_q_entry * rd_ptr = dev->rx_q_entry;
    
    PRINTD (DBG_VCC|DBG_RX, "rd_ptr = %u, wr_ptr = %u", rd_ptr, wr_ptr);
    
    while (rd_ptr != wr_ptr) {
      u32 x = rd_mem (dev, (HDW *) rd_ptr);
      
      if (vc == rx_q_entry_to_rx_channel (x)) {
	x |= SIMONS_DODGEY_MARKER;
	
	PRINTD (DBG_RX|DBG_VCC|DBG_WARN, "marking a frame as dodgey");
	
	wr_mem (dev, (HDW *) rd_ptr, x);
      }
      
      if (rd_ptr == dev->rx_q_wrap)
	rd_ptr = dev->rx_q_reset;
      else
	rd_ptr++;
    }
  }
#endif
  
  spin_unlock_irqrestore (&dev->mem_lock, flags);
  
  return;
}

/********** schedule RX transfers **********/

// Note on tail recursion: a GCC developer said that it is not likely
// to be fixed soon, so do not define TAILRECUSRIONWORKS unless you
// are sure it does as you may otherwise overflow the kernel stack.

// giving this fn a return value would help GCC, allegedly

static void rx_schedule (hrz_dev * dev, int irq) {
  unsigned int rx_bytes;
  
  int pio_instead = 0;
#ifndef TAILRECURSIONWORKS
  pio_instead = 1;
  while (pio_instead) {
#endif
    // bytes waiting for RX transfer
    rx_bytes = dev->rx_bytes;
    
#if 0
    spin_count = 0;
    while (rd_regl (dev, MASTER_RX_COUNT_REG_OFF)) {
      PRINTD (DBG_RX|DBG_WARN, "RX error: other PCI Bus Master RX still in progress!");
      if (++spin_count > 10) {
	PRINTD (DBG_RX|DBG_ERR, "spun out waiting PCI Bus Master RX completion");
	wr_regl (dev, MASTER_RX_COUNT_REG_OFF, 0);
	clear_bit (rx_busy, &dev->flags);
	hrz_kfree_skb (dev->rx_skb);
	return;
      }
    }
#endif
    
    // this code follows the TX code but (at the moment) there is only
    // one region - the skb itself. I don't know if this will change,
    // but it doesn't hurt to have the code here, disabled.
    
    if (rx_bytes) {
      // start next transfer within same region
      if (rx_bytes <= MAX_PIO_COUNT) {
	PRINTD (DBG_RX|DBG_BUS, "(pio)");
	pio_instead = 1;
      }
      if (rx_bytes <= MAX_TRANSFER_COUNT) {
	PRINTD (DBG_RX|DBG_BUS, "(simple or last multi)");
	dev->rx_bytes = 0;
      } else {
	PRINTD (DBG_RX|DBG_BUS, "(continuing multi)");
	dev->rx_bytes = rx_bytes - MAX_TRANSFER_COUNT;
	rx_bytes = MAX_TRANSFER_COUNT;
      }
    } else {
      // rx_bytes == 0 -- we're between regions
      // regions remaining to transfer
#if 0
      unsigned int rx_regions = dev->rx_regions;
#else
      unsigned int rx_regions = 0;
#endif
      
      if (rx_regions) {
#if 0
	// start a new region
	dev->rx_addr = dev->rx_iovec->iov_base;
	rx_bytes = dev->rx_iovec->iov_len;
	++dev->rx_iovec;
	dev->rx_regions = rx_regions - 1;
	
	if (rx_bytes <= MAX_PIO_COUNT) {
	  PRINTD (DBG_RX|DBG_BUS, "(pio)");
	  pio_instead = 1;
	}
	if (rx_bytes <= MAX_TRANSFER_COUNT) {
	  PRINTD (DBG_RX|DBG_BUS, "(full region)");
	  dev->rx_bytes = 0;
	} else {
	  PRINTD (DBG_RX|DBG_BUS, "(start multi region)");
	  dev->rx_bytes = rx_bytes - MAX_TRANSFER_COUNT;
	  rx_bytes = MAX_TRANSFER_COUNT;
	}
#endif
      } else {
	// rx_regions == 0
	// that's all folks - end of frame
	struct sk_buff * skb = dev->rx_skb;
	// dev->rx_iovec = 0;
	
	FLUSH_RX_CHANNEL (dev, dev->rx_channel);
	
	dump_skb ("<<<", dev->rx_channel, skb);
	
	PRINTD (DBG_RX|DBG_SKB, "push %p %u", skb->data, skb->len);
	
	{
	  struct atm_vcc * vcc = ATM_SKB(skb)->vcc;
	  // VC layer stats
	  atomic_inc(&vcc->stats->rx);
	  __net_timestamp(skb);
	  // end of our responsibility
	  vcc->push (vcc, skb);
	}
      }
    }
    
    // note: writing RX_COUNT clears any interrupt condition
    if (rx_bytes) {
      if (pio_instead) {
	if (irq)
	  wr_regl (dev, MASTER_RX_COUNT_REG_OFF, 0);
	rds_regb (dev, DATA_PORT_OFF, dev->rx_addr, rx_bytes);
      } else {
	wr_regl (dev, MASTER_RX_ADDR_REG_OFF, virt_to_bus (dev->rx_addr));
	wr_regl (dev, MASTER_RX_COUNT_REG_OFF, rx_bytes);
      }
      dev->rx_addr += rx_bytes;
    } else {
      if (irq)
	wr_regl (dev, MASTER_RX_COUNT_REG_OFF, 0);
      // allow another RX thread to start
      YELLOW_LED_ON(dev);
      clear_bit (rx_busy, &dev->flags);
      PRINTD (DBG_RX, "cleared rx_busy for dev %p", dev);
    }
    
#ifdef TAILRECURSIONWORKS
    // and we all bless optimised tail calls
    if (pio_instead)
      return rx_schedule (dev, 0);
    return;
#else
    // grrrrrrr!
    irq = 0;
  }
  return;
#endif
}

/********** handle RX bus master complete events **********/

static void rx_bus_master_complete_handler (hrz_dev * dev) {
  if (test_bit (rx_busy, &dev->flags)) {
    rx_schedule (dev, 1);
  } else {
    PRINTD (DBG_RX|DBG_ERR, "unexpected RX bus master completion");
    // clear interrupt condition on adapter
    wr_regl (dev, MASTER_RX_COUNT_REG_OFF, 0);
  }
  return;
}

/********** (queue to) become the next TX thread **********/

static int tx_hold (hrz_dev * dev) {
  PRINTD (DBG_TX, "sleeping at tx lock %p %lu", dev, dev->flags);
  wait_event_interruptible(dev->tx_queue, (!test_and_set_bit(tx_busy, &dev->flags)));
  PRINTD (DBG_TX, "woken at tx lock %p %lu", dev, dev->flags);
  if (signal_pending (current))
    return -1;
  PRINTD (DBG_TX, "set tx_busy for dev %p", dev);
  return 0;
}

/********** allow another TX thread to start **********/

static inline void tx_release (hrz_dev * dev) {
  clear_bit (tx_busy, &dev->flags);
  PRINTD (DBG_TX, "cleared tx_busy for dev %p", dev);
  wake_up_interruptible (&dev->tx_queue);
}

/********** schedule TX transfers **********/

static void tx_schedule (hrz_dev * const dev, int irq) {
  unsigned int tx_bytes;
  
  int append_desc = 0;
  
  int pio_instead = 0;
#ifndef TAILRECURSIONWORKS
  pio_instead = 1;
  while (pio_instead) {
#endif
    // bytes in current region waiting for TX transfer
    tx_bytes = dev->tx_bytes;
    
#if 0
    spin_count = 0;
    while (rd_regl (dev, MASTER_TX_COUNT_REG_OFF)) {
      PRINTD (DBG_TX|DBG_WARN, "TX error: other PCI Bus Master TX still in progress!");
      if (++spin_count > 10) {
	PRINTD (DBG_TX|DBG_ERR, "spun out waiting PCI Bus Master TX completion");
	wr_regl (dev, MASTER_TX_COUNT_REG_OFF, 0);
	tx_release (dev);
	hrz_kfree_skb (dev->tx_skb);
	return;
      }
    }
#endif
    
    if (tx_bytes) {
      // start next transfer within same region
      if (!test_bit (ultra, &dev->flags) || tx_bytes <= MAX_PIO_COUNT) {
	PRINTD (DBG_TX|DBG_BUS, "(pio)");
	pio_instead = 1;
      }
      if (tx_bytes <= MAX_TRANSFER_COUNT) {
	PRINTD (DBG_TX|DBG_BUS, "(simple or last multi)");
	if (!dev->tx_iovec) {
	  // end of last region
	  append_desc = 1;
	}
	dev->tx_bytes = 0;
      } else {
	PRINTD (DBG_TX|DBG_BUS, "(continuing multi)");
	dev->tx_bytes = tx_bytes - MAX_TRANSFER_COUNT;
	tx_bytes = MAX_TRANSFER_COUNT;
      }
    } else {
      // tx_bytes == 0 -- we're between regions
      // regions remaining to transfer
      unsigned int tx_regions = dev->tx_regions;
      
      if (tx_regions) {
	// start a new region
	dev->tx_addr = dev->tx_iovec->iov_base;
	tx_bytes = dev->tx_iovec->iov_len;
	++dev->tx_iovec;
	dev->tx_regions = tx_regions - 1;
	
	if (!test_bit (ultra, &dev->flags) || tx_bytes <= MAX_PIO_COUNT) {
	  PRINTD (DBG_TX|DBG_BUS, "(pio)");
	  pio_instead = 1;
	}
	if (tx_bytes <= MAX_TRANSFER_COUNT) {
	  PRINTD (DBG_TX|DBG_BUS, "(full region)");
	  dev->tx_bytes = 0;
	} else {
	  PRINTD (DBG_TX|DBG_BUS, "(start multi region)");
	  dev->tx_bytes = tx_bytes - MAX_TRANSFER_COUNT;
	  tx_bytes = MAX_TRANSFER_COUNT;
	}
      } else {
	// tx_regions == 0
	// that's all folks - end of frame
	struct sk_buff * skb = dev->tx_skb;
	dev->tx_iovec = NULL;
	
	// VC layer stats
	atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
	
	// free the skb
	hrz_kfree_skb (skb);
      }
    }
    
    // note: writing TX_COUNT clears any interrupt condition
    if (tx_bytes) {
      if (pio_instead) {
	if (irq)
	  wr_regl (dev, MASTER_TX_COUNT_REG_OFF, 0);
	wrs_regb (dev, DATA_PORT_OFF, dev->tx_addr, tx_bytes);
	if (append_desc)
	  wr_regl (dev, TX_DESCRIPTOR_PORT_OFF, cpu_to_be32 (dev->tx_skb->len));
      } else {
	wr_regl (dev, MASTER_TX_ADDR_REG_OFF, virt_to_bus (dev->tx_addr));
	if (append_desc)
	  wr_regl (dev, TX_DESCRIPTOR_REG_OFF, cpu_to_be32 (dev->tx_skb->len));
	wr_regl (dev, MASTER_TX_COUNT_REG_OFF,
		 append_desc
		 ? tx_bytes | MASTER_TX_AUTO_APPEND_DESC
		 : tx_bytes);
      }
      dev->tx_addr += tx_bytes;
    } else {
      if (irq)
	wr_regl (dev, MASTER_TX_COUNT_REG_OFF, 0);
      YELLOW_LED_ON(dev);
      tx_release (dev);
    }
    
#ifdef TAILRECURSIONWORKS
    // and we all bless optimised tail calls
    if (pio_instead)
      return tx_schedule (dev, 0);
    return;
#else
    // grrrrrrr!
    irq = 0;
  }
  return;
#endif
}

/********** handle TX bus master complete events **********/

static void tx_bus_master_complete_handler (hrz_dev * dev) {
  if (test_bit (tx_busy, &dev->flags)) {
    tx_schedule (dev, 1);
  } else {
    PRINTD (DBG_TX|DBG_ERR, "unexpected TX bus master completion");
    // clear interrupt condition on adapter
    wr_regl (dev, MASTER_TX_COUNT_REG_OFF, 0);
  }
  return;
}

/********** move RX Q pointer to next item in circular buffer **********/

// called only from IRQ sub-handler
static u32 rx_queue_entry_next (hrz_dev * dev) {
  u32 rx_queue_entry;
  spin_lock (&dev->mem_lock);
  rx_queue_entry = rd_mem (dev, &dev->rx_q_entry->entry);
  if (dev->rx_q_entry == dev->rx_q_wrap)
    dev->rx_q_entry = dev->rx_q_reset;
  else
    dev->rx_q_entry++;
  wr_regw (dev, RX_QUEUE_RD_PTR_OFF, dev->rx_q_entry - dev->rx_q_reset);
  spin_unlock (&dev->mem_lock);
  return rx_queue_entry;
}

/********** handle RX data received by device **********/

// called from IRQ handler
static void rx_data_av_handler (hrz_dev * dev) {
  u32 rx_queue_entry;
  u32 rx_queue_entry_flags;
  u16 rx_len;
  u16 rx_channel;
  
  PRINTD (DBG_FLOW, "hrz_data_av_handler");
  
  // try to grab rx lock (not possible during RX bus mastering)
  if (test_and_set_bit (rx_busy, &dev->flags)) {
    PRINTD (DBG_RX, "locked out of rx lock");
    return;
  }
  PRINTD (DBG_RX, "set rx_busy for dev %p", dev);
  // lock is cleared if we fail now, o/w after bus master completion
  
  YELLOW_LED_OFF(dev);
  
  rx_queue_entry = rx_queue_entry_next (dev);
  
  rx_len = rx_q_entry_to_length (rx_queue_entry);
  rx_channel = rx_q_entry_to_rx_channel (rx_queue_entry);
  
  WAIT_FLUSH_RX_COMPLETE (dev);
  
  SELECT_RX_CHANNEL (dev, rx_channel);
  
  PRINTD (DBG_RX, "rx_queue_entry is: %#x", rx_queue_entry);
  rx_queue_entry_flags = rx_queue_entry & (RX_CRC_32_OK|RX_COMPLETE_FRAME|SIMONS_DODGEY_MARKER);
  
  if (!rx_len) {
    // (at least) bus-mastering breaks if we try to handle a
    // zero-length frame, besides AAL5 does not support them
    PRINTK (KERN_ERR, "zero-length frame!");
    rx_queue_entry_flags &= ~RX_COMPLETE_FRAME;
  }
  
  if (rx_queue_entry_flags & SIMONS_DODGEY_MARKER) {
    PRINTD (DBG_RX|DBG_ERR, "Simon's marker detected!");
  }
  if (rx_queue_entry_flags == (RX_CRC_32_OK | RX_COMPLETE_FRAME)) {
    struct atm_vcc * atm_vcc;
    
    PRINTD (DBG_RX, "got a frame on rx_channel %x len %u", rx_channel, rx_len);
    
    atm_vcc = dev->rxer[rx_channel];
    // if no vcc is assigned to this channel, we should drop the frame
    // (is this what SIMONS etc. was trying to achieve?)
    
    if (atm_vcc) {
      
      if (atm_vcc->qos.rxtp.traffic_class != ATM_NONE) {
	
	if (rx_len <= atm_vcc->qos.rxtp.max_sdu) {
	    
	  struct sk_buff * skb = atm_alloc_charge (atm_vcc, rx_len, GFP_ATOMIC);
	  if (skb) {
	    // remember this so we can push it later
	    dev->rx_skb = skb;
	    // remember this so we can flush it later
	    dev->rx_channel = rx_channel;
	    
	    // prepare socket buffer
	    skb_put (skb, rx_len);
	    ATM_SKB(skb)->vcc = atm_vcc;
	    
	    // simple transfer
	    // dev->rx_regions = 0;
	    // dev->rx_iovec = 0;
	    dev->rx_bytes = rx_len;
	    dev->rx_addr = skb->data;
	    PRINTD (DBG_RX, "RX start simple transfer (addr %p, len %d)",
		    skb->data, rx_len);
	    
	    // do the business
	    rx_schedule (dev, 0);
	    return;
	    
	  } else {
	    PRINTD (DBG_SKB|DBG_WARN, "failed to get skb");
	  }
	  
	} else {
	  PRINTK (KERN_INFO, "frame received on TX-only VC %x", rx_channel);
	  // do we count this?
	}
	
      } else {
	PRINTK (KERN_WARNING, "dropped over-size frame");
	// do we count this?
      }
      
    } else {
      PRINTD (DBG_WARN|DBG_VCC|DBG_RX, "no VCC for this frame (VC closed)");
      // do we count this?
    }
    
  } else {
    // Wait update complete ? SPONG
  }
  
  // RX was aborted
  YELLOW_LED_ON(dev);
  
  FLUSH_RX_CHANNEL (dev,rx_channel);
  clear_bit (rx_busy, &dev->flags);
  
  return;
}

/********** interrupt handler **********/

static irqreturn_t interrupt_handler(int irq, void *dev_id)
{
  hrz_dev *dev = dev_id;
  u32 int_source;
  unsigned int irq_ok;
  
  PRINTD (DBG_FLOW, "interrupt_handler: %p", dev_id);
  
  // definitely for us
  irq_ok = 0;
  while ((int_source = rd_regl (dev, INT_SOURCE_REG_OFF)
	  & INTERESTING_INTERRUPTS)) {
    // In the interests of fairness, the handlers below are
    // called in sequence and without immediate return to the head of
    // the while loop. This is only of issue for slow hosts (or when
    // debugging messages are on). Really slow hosts may find a fast
    // sender keeps them permanently in the IRQ handler. :(
    
    // (only an issue for slow hosts) RX completion goes before
    // rx_data_av as the former implies rx_busy and so the latter
    // would just abort. If it reschedules another transfer
    // (continuing the same frame) then it will not clear rx_busy.
    
    // (only an issue for slow hosts) TX completion goes before RX
    // data available as it is a much shorter routine - there is the
    // chance that any further transfers it schedules will be complete
    // by the time of the return to the head of the while loop
    
    if (int_source & RX_BUS_MASTER_COMPLETE) {
      ++irq_ok;
      PRINTD (DBG_IRQ|DBG_BUS|DBG_RX, "rx_bus_master_complete asserted");
      rx_bus_master_complete_handler (dev);
    }
    if (int_source & TX_BUS_MASTER_COMPLETE) {
      ++irq_ok;
      PRINTD (DBG_IRQ|DBG_BUS|DBG_TX, "tx_bus_master_complete asserted");
      tx_bus_master_complete_handler (dev);
    }
    if (int_source & RX_DATA_AV) {
      ++irq_ok;
      PRINTD (DBG_IRQ|DBG_RX, "rx_data_av asserted");
      rx_data_av_handler (dev);
    }
  }
  if (irq_ok) {
    PRINTD (DBG_IRQ, "work done: %u", irq_ok);
  } else {
    PRINTD (DBG_IRQ|DBG_WARN, "spurious interrupt source: %#x", int_source);
  }
  
  PRINTD (DBG_IRQ|DBG_FLOW, "interrupt_handler done: %p", dev_id);
  if (irq_ok)
	return IRQ_HANDLED;
  return IRQ_NONE;
}

/********** housekeeping **********/

static void do_housekeeping (unsigned long arg) {
  // just stats at the moment
  hrz_dev * dev = (hrz_dev *) arg;

  // collect device-specific (not driver/atm-linux) stats here
  dev->tx_cell_count += rd_regw (dev, TX_CELL_COUNT_OFF);
  dev->rx_cell_count += rd_regw (dev, RX_CELL_COUNT_OFF);
  dev->hec_error_count += rd_regw (dev, HEC_ERROR_COUNT_OFF);
  dev->unassigned_cell_count += rd_regw (dev, UNASSIGNED_CELL_COUNT_OFF);

  mod_timer (&dev->housekeeping, jiffies + HZ/10);

  return;
}

/********** find an idle channel for TX and set it up **********/

// called with tx_busy set
static short setup_idle_tx_channel (hrz_dev * dev, hrz_vcc * vcc) {
  unsigned short idle_channels;
  short tx_channel = -1;
  unsigned int spin_count;
  PRINTD (DBG_FLOW|DBG_TX, "setup_idle_tx_channel %p", dev);
  
  // better would be to fail immediately, the caller can then decide whether
  // to wait or drop (depending on whether this is UBR etc.)
  spin_count = 0;
  while (!(idle_channels = rd_regw (dev, TX_STATUS_OFF) & IDLE_CHANNELS_MASK)) {
    PRINTD (DBG_TX|DBG_WARN, "waiting for idle TX channel");
    // delay a bit here
    if (++spin_count > 100) {
      PRINTD (DBG_TX|DBG_ERR, "spun out waiting for idle TX channel");
      return -EBUSY;
    }
  }
  
  // got an idle channel
  {
    // tx_idle ensures we look for idle channels in RR order
    int chan = dev->tx_idle;
    
    int keep_going = 1;
    while (keep_going) {
      if (idle_channels & (1<<chan)) {
	tx_channel = chan;
	keep_going = 0;
      }
      ++chan;
      if (chan == TX_CHANS)
	chan = 0;
    }
    
    dev->tx_idle = chan;
  }
  
  // set up the channel we found
  {
    // Initialise the cell header in the transmit channel descriptor
    // a.k.a. prepare the channel and remember that we have done so.
    
    tx_ch_desc * tx_desc = &memmap->tx_descs[tx_channel];
    u32 rd_ptr;
    u32 wr_ptr;
    u16 channel = vcc->channel;
    
    unsigned long flags;
    spin_lock_irqsave (&dev->mem_lock, flags);
    
    // Update the transmit channel record.
    dev->tx_channel_record[tx_channel] = channel;
    
    // xBR channel
    update_tx_channel_config (dev, tx_channel, RATE_TYPE_ACCESS,
			      vcc->tx_xbr_bits);
    
    // Update the PCR counter preload value etc.
    update_tx_channel_config (dev, tx_channel, PCR_TIMER_ACCESS,
			      vcc->tx_pcr_bits);

#if 0
    if (vcc->tx_xbr_bits == VBR_RATE_TYPE) {
      // SCR timer
      update_tx_channel_config (dev, tx_channel, SCR_TIMER_ACCESS,
				vcc->tx_scr_bits);
      
      // Bucket size...
      update_tx_channel_config (dev, tx_channel, BUCKET_CAPACITY_ACCESS,
				vcc->tx_bucket_bits);
      
      // ... and fullness
      update_tx_channel_config (dev, tx_channel, BUCKET_FULLNESS_ACCESS,
				vcc->tx_bucket_bits);
    }
#endif

    // Initialise the read and write buffer pointers
    rd_ptr = rd_mem (dev, &tx_desc->rd_buf_type) & BUFFER_PTR_MASK;
    wr_ptr = rd_mem (dev, &tx_desc->wr_buf_type) & BUFFER_PTR_MASK;
    
    // idle TX channels should have identical pointers
    if (rd_ptr != wr_ptr) {
      PRINTD (DBG_TX|DBG_ERR, "TX buffer pointers are broken!");
      // spin_unlock... return -E...
      // I wonder if gcc would get rid of one of the pointer aliases
    }
    PRINTD (DBG_TX, "TX buffer pointers are: rd %x, wr %x.",
	    rd_ptr, wr_ptr);
    
    switch (vcc->aal) {
      case aal0:
	PRINTD (DBG_QOS|DBG_TX, "tx_channel: aal0");
	rd_ptr |= CHANNEL_TYPE_RAW_CELLS;
	wr_ptr |= CHANNEL_TYPE_RAW_CELLS;
	break;
      case aal34:
	PRINTD (DBG_QOS|DBG_TX, "tx_channel: aal34");
	rd_ptr |= CHANNEL_TYPE_AAL3_4;
	wr_ptr |= CHANNEL_TYPE_AAL3_4;
	break;
      case aal5:
	rd_ptr |= CHANNEL_TYPE_AAL5;
	wr_ptr |= CHANNEL_TYPE_AAL5;
	// Initialise the CRC
	wr_mem (dev, &tx_desc->partial_crc, INITIAL_CRC);
	break;
    }
    
    wr_mem (dev, &tx_desc->rd_buf_type, rd_ptr);
    wr_mem (dev, &tx_desc->wr_buf_type, wr_ptr);
    
    // Write the Cell Header
    // Payload Type, CLP and GFC would go here if non-zero
    wr_mem (dev, &tx_desc->cell_header, channel);
    
    spin_unlock_irqrestore (&dev->mem_lock, flags);
  }
  
  return tx_channel;
}

/********** send a frame **********/

static int hrz_send (struct atm_vcc * atm_vcc, struct sk_buff * skb) {
  unsigned int spin_count;
  int free_buffers;
  hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
  hrz_vcc * vcc = HRZ_VCC(atm_vcc);
  u16 channel = vcc->channel;
  
  u32 buffers_required;
  
  /* signed for error return */
  short tx_channel;
  
  PRINTD (DBG_FLOW|DBG_TX, "hrz_send vc %x data %p len %u",
	  channel, skb->data, skb->len);
  
  dump_skb (">>>", channel, skb);
  
  if (atm_vcc->qos.txtp.traffic_class == ATM_NONE) {
    PRINTK (KERN_ERR, "attempt to send on RX-only VC %x", channel);
    hrz_kfree_skb (skb);
    return -EIO;
  }
  
  // don't understand this
  ATM_SKB(skb)->vcc = atm_vcc;
  
  if (skb->len > atm_vcc->qos.txtp.max_sdu) {
    PRINTK (KERN_ERR, "sk_buff length greater than agreed max_sdu, dropping...");
    hrz_kfree_skb (skb);
    return -EIO;
  }
  
  if (!channel) {
    PRINTD (DBG_ERR|DBG_TX, "attempt to transmit on zero (rx_)channel");
    hrz_kfree_skb (skb);
    return -EIO;
  }
  
#if 0
  {
    // where would be a better place for this? housekeeping?
    u16 status;
    pci_read_config_word (dev->pci_dev, PCI_STATUS, &status);
    if (status & PCI_STATUS_REC_MASTER_ABORT) {
      PRINTD (DBG_BUS|DBG_ERR, "Clearing PCI Master Abort (and cleaning up)");
      status &= ~PCI_STATUS_REC_MASTER_ABORT;
      pci_write_config_word (dev->pci_dev, PCI_STATUS, status);
      if (test_bit (tx_busy, &dev->flags)) {
	hrz_kfree_skb (dev->tx_skb);
	tx_release (dev);
      }
    }
  }
#endif
  
#ifdef DEBUG_HORIZON
  /* wey-hey! */
  if (channel == 1023) {
    unsigned int i;
    unsigned short d = 0;
    char * s = skb->data;
    if (*s++ == 'D') {
	for (i = 0; i < 4; ++i)
		d = (d << 4) | hex_to_bin(*s++);
      PRINTK (KERN_INFO, "debug bitmap is now %hx", debug = d);
    }
  }
#endif
  
  // wait until TX is free and grab lock
  if (tx_hold (dev)) {
    hrz_kfree_skb (skb);
    return -ERESTARTSYS;
  }
 
  // Wait for enough space to be available in transmit buffer memory.
  
  // should be number of cells needed + 2 (according to hardware docs)
  // = ((framelen+8)+47) / 48 + 2
  // = (framelen+7) / 48 + 3, hmm... faster to put addition inside XXX
  buffers_required = (skb->len+(ATM_AAL5_TRAILER-1)) / ATM_CELL_PAYLOAD + 3;
  
  // replace with timer and sleep, add dev->tx_buffers_queue (max 1 entry)
  spin_count = 0;
  while ((free_buffers = rd_regw (dev, TX_FREE_BUFFER_COUNT_OFF)) < buffers_required) {
    PRINTD (DBG_TX, "waiting for free TX buffers, got %d of %d",
	    free_buffers, buffers_required);
    // what is the appropriate delay? implement a timeout? (depending on line speed?)
    // mdelay (1);
    // what happens if we kill (current_pid, SIGKILL) ?
    schedule();
    if (++spin_count > 1000) {
      PRINTD (DBG_TX|DBG_ERR, "spun out waiting for tx buffers, got %d of %d",
	      free_buffers, buffers_required);
      tx_release (dev);
      hrz_kfree_skb (skb);
      return -ERESTARTSYS;
    }
  }
  
  // Select a channel to transmit the frame on.
  if (channel == dev->last_vc) {
    PRINTD (DBG_TX, "last vc hack: hit");
    tx_channel = dev->tx_last;
  } else {
    PRINTD (DBG_TX, "last vc hack: miss");
    // Are we currently transmitting this VC on one of the channels?
    for (tx_channel = 0; tx_channel < TX_CHANS; ++tx_channel)
      if (dev->tx_channel_record[tx_channel] == channel) {
	PRINTD (DBG_TX, "vc already on channel: hit");
	break;
      }
    if (tx_channel == TX_CHANS) { 
      PRINTD (DBG_TX, "vc already on channel: miss");
      // Find and set up an idle channel.
      tx_channel = setup_idle_tx_channel (dev, vcc);
      if (tx_channel < 0) {
	PRINTD (DBG_TX|DBG_ERR, "failed to get channel");
	tx_release (dev);
	return tx_channel;
      }
    }
    
    PRINTD (DBG_TX, "got channel");
    SELECT_TX_CHANNEL(dev, tx_channel);
    
    dev->last_vc = channel;
    dev->tx_last = tx_channel;
  }
  
  PRINTD (DBG_TX, "using channel %u", tx_channel);
  
  YELLOW_LED_OFF(dev);
  
  // TX start transfer
  
  {
    unsigned int tx_len = skb->len;
    unsigned int tx_iovcnt = skb_shinfo(skb)->nr_frags;
    // remember this so we can free it later
    dev->tx_skb = skb;
    
    if (tx_iovcnt) {
      // scatter gather transfer
      dev->tx_regions = tx_iovcnt;
      dev->tx_iovec = NULL;		/* @@@ needs rewritten */
      dev->tx_bytes = 0;
      PRINTD (DBG_TX|DBG_BUS, "TX start scatter-gather transfer (iovec %p, len %d)",
	      skb->data, tx_len);
      tx_release (dev);
      hrz_kfree_skb (skb);
      return -EIO;
    } else {
      // simple transfer
      dev->tx_regions = 0;
      dev->tx_iovec = NULL;
      dev->tx_bytes = tx_len;
      dev->tx_addr = skb->data;
      PRINTD (DBG_TX|DBG_BUS, "TX start simple transfer (addr %p, len %d)",
	      skb->data, tx_len);
    }
    
    // and do the business
    tx_schedule (dev, 0);
    
  }
  
  return 0;
}

/********** reset a card **********/

static void hrz_reset (const hrz_dev * dev) {
  u32 control_0_reg = rd_regl (dev, CONTROL_0_REG);
  
  // why not set RESET_HORIZON to one and wait for the card to
  // reassert that bit as zero? Like so:
  control_0_reg = control_0_reg & RESET_HORIZON;
  wr_regl (dev, CONTROL_0_REG, control_0_reg);
  while (control_0_reg & RESET_HORIZON)
    control_0_reg = rd_regl (dev, CONTROL_0_REG);
  
  // old reset code retained:
  wr_regl (dev, CONTROL_0_REG, control_0_reg |
	   RESET_ATM | RESET_RX | RESET_TX | RESET_HOST);
  // just guessing here
  udelay (1000);
  
  wr_regl (dev, CONTROL_0_REG, control_0_reg);
}

/********** read the burnt in address **********/

static void WRITE_IT_WAIT (const hrz_dev *dev, u32 ctrl)
{
	wr_regl (dev, CONTROL_0_REG, ctrl);
	udelay (5);
}
  
static void CLOCK_IT (const hrz_dev *dev, u32 ctrl)
{
	// DI must be valid around rising SK edge
	WRITE_IT_WAIT(dev, ctrl & ~SEEPROM_SK);
	WRITE_IT_WAIT(dev, ctrl | SEEPROM_SK);
}

static u16 read_bia(const hrz_dev *dev, u16 addr)
{
  u32 ctrl = rd_regl (dev, CONTROL_0_REG);
  
  const unsigned int addr_bits = 6;
  const unsigned int data_bits = 16;
  
  unsigned int i;
  
  u16 res;
  
  ctrl &= ~(SEEPROM_CS | SEEPROM_SK | SEEPROM_DI);
  WRITE_IT_WAIT(dev, ctrl);
  
  // wake Serial EEPROM and send 110 (READ) command
  ctrl |=  (SEEPROM_CS | SEEPROM_DI);
  CLOCK_IT(dev, ctrl);
  
  ctrl |= SEEPROM_DI;
  CLOCK_IT(dev, ctrl);
  
  ctrl &= ~SEEPROM_DI;
  CLOCK_IT(dev, ctrl);
  
  for (i=0; i<addr_bits; i++) {
    if (addr & (1 << (addr_bits-1)))
      ctrl |= SEEPROM_DI;
    else
      ctrl &= ~SEEPROM_DI;
    
    CLOCK_IT(dev, ctrl);
    
    addr = addr << 1;
  }
  
  // we could check that we have DO = 0 here
  ctrl &= ~SEEPROM_DI;
  
  res = 0;
  for (i=0;i<data_bits;i++) {
    res = res >> 1;
    
    CLOCK_IT(dev, ctrl);
    
    if (rd_regl (dev, CONTROL_0_REG) & SEEPROM_DO)
      res |= (1 << (data_bits-1));
  }
  
  ctrl &= ~(SEEPROM_SK | SEEPROM_CS);
  WRITE_IT_WAIT(dev, ctrl);
  
  return res;
}

/********** initialise a card **********/

static int hrz_init(hrz_dev *dev)
{
  int onefivefive;
  
  u16 chan;
  
  int buff_count;
  
  HDW * mem;
  
  cell_buf * tx_desc;
  cell_buf * rx_desc;
  
  u32 ctrl;
  
  ctrl = rd_regl (dev, CONTROL_0_REG);
  PRINTD (DBG_INFO, "ctrl0reg is %#x", ctrl);
  onefivefive = ctrl & ATM_LAYER_STATUS;
  
  if (onefivefive)
    printk (DEV_LABEL ": Horizon Ultra (at 155.52 MBps)");
  else
    printk (DEV_LABEL ": Horizon (at 25 MBps)");
  
  printk (":");
  // Reset the card to get everything in a known state
  
  printk (" reset");
  hrz_reset (dev);
  
  // Clear all the buffer memory
  
  printk (" clearing memory");
  
  for (mem = (HDW *) memmap; mem < (HDW *) (memmap + 1); ++mem)
    wr_mem (dev, mem, 0);
  
  printk (" tx channels");
  
  // All transmit eight channels are set up as AAL5 ABR channels with
  // a 16us cell spacing. Why?
  
  // Channel 0 gets the free buffer at 100h, channel 1 gets the free
  // buffer at 110h etc.
  
  for (chan = 0; chan < TX_CHANS; ++chan) {
    tx_ch_desc * tx_desc = &memmap->tx_descs[chan];
    cell_buf * buf = &memmap->inittxbufs[chan];
    
    // initialise the read and write buffer pointers
    wr_mem (dev, &tx_desc->rd_buf_type, BUF_PTR(buf));
    wr_mem (dev, &tx_desc->wr_buf_type, BUF_PTR(buf));
    
    // set the status of the initial buffers to empty
    wr_mem (dev, &buf->next, BUFF_STATUS_EMPTY);
  }
  
  // Use space bufn3 at the moment for tx buffers
  
  printk (" tx buffers");
  
  tx_desc = memmap->bufn3;
  
  wr_mem (dev, &memmap->txfreebufstart.next, BUF_PTR(tx_desc) | BUFF_STATUS_EMPTY);
  
  for (buff_count = 0; buff_count < BUFN3_SIZE-1; buff_count++) {
    wr_mem (dev, &tx_desc->next, BUF_PTR(tx_desc+1) | BUFF_STATUS_EMPTY);
    tx_desc++;
  }
  
  wr_mem (dev, &tx_desc->next, BUF_PTR(&memmap->txfreebufend) | BUFF_STATUS_EMPTY);
  
  // Initialise the transmit free buffer count
  wr_regw (dev, TX_FREE_BUFFER_COUNT_OFF, BUFN3_SIZE);
  
  printk (" rx channels");
  
  // Initialise all of the receive channels to be AAL5 disabled with
  // an interrupt threshold of 0
  
  for (chan = 0; chan < RX_CHANS; ++chan) {
    rx_ch_desc * rx_desc = &memmap->rx_descs[chan];
    
    wr_mem (dev, &rx_desc->wr_buf_type, CHANNEL_TYPE_AAL5 | RX_CHANNEL_DISABLED);
  }
  
  printk (" rx buffers");
  
  // Use space bufn4 at the moment for rx buffers
  
  rx_desc = memmap->bufn4;
  
  wr_mem (dev, &memmap->rxfreebufstart.next, BUF_PTR(rx_desc) | BUFF_STATUS_EMPTY);
  
  for (buff_count = 0; buff_count < BUFN4_SIZE-1; buff_count++) {
    wr_mem (dev, &rx_desc->next, BUF_PTR(rx_desc+1) | BUFF_STATUS_EMPTY);
    
    rx_desc++;
  }
  
  wr_mem (dev, &rx_desc->next, BUF_PTR(&memmap->rxfreebufend) | BUFF_STATUS_EMPTY);
  
  // Initialise the receive free buffer count
  wr_regw (dev, RX_FREE_BUFFER_COUNT_OFF, BUFN4_SIZE);
  
  // Initialize Horizons registers
  
  // TX config
  wr_regw (dev, TX_CONFIG_OFF,
	   ABR_ROUND_ROBIN | TX_NORMAL_OPERATION | DRVR_DRVRBAR_ENABLE);
  
  // RX config. Use 10-x VC bits, x VP bits, non user cells in channel 0.
  wr_regw (dev, RX_CONFIG_OFF,
	   DISCARD_UNUSED_VPI_VCI_BITS_SET | NON_USER_CELLS_IN_ONE_CHANNEL | vpi_bits);
  
  // RX line config
  wr_regw (dev, RX_LINE_CONFIG_OFF,
	   LOCK_DETECT_ENABLE | FREQUENCY_DETECT_ENABLE | GXTALOUT_SELECT_DIV4);
  
  // Set the max AAL5 cell count to be just enough to contain the
  // largest AAL5 frame that the user wants to receive
  wr_regw (dev, MAX_AAL5_CELL_COUNT_OFF,
	   DIV_ROUND_UP(max_rx_size + ATM_AAL5_TRAILER, ATM_CELL_PAYLOAD));
  
  // Enable receive
  wr_regw (dev, RX_CONFIG_OFF, rd_regw (dev, RX_CONFIG_OFF) | RX_ENABLE);
  
  printk (" control");
  
  // Drive the OE of the LEDs then turn the green LED on
  ctrl |= GREEN_LED_OE | YELLOW_LED_OE | GREEN_LED | YELLOW_LED;
  wr_regl (dev, CONTROL_0_REG, ctrl);
  
  // Test for a 155-capable card
  
  if (onefivefive) {
    // Select 155 mode... make this a choice (or: how do we detect
    // external line speed and switch?)
    ctrl |= ATM_LAYER_SELECT;
    wr_regl (dev, CONTROL_0_REG, ctrl);
    
    // test SUNI-lite vs SAMBA
    
    // Register 0x00 in the SUNI will have some of bits 3-7 set, and
    // they will always be zero for the SAMBA.  Ha!  Bloody hardware
    // engineers.  It'll never work.
    
    if (rd_framer (dev, 0) & 0x00f0) {
      // SUNI
      printk (" SUNI");
      
      // Reset, just in case
      wr_framer (dev, 0x00, 0x0080);
      wr_framer (dev, 0x00, 0x0000);
      
      // Configure transmit FIFO
      wr_framer (dev, 0x63, rd_framer (dev, 0x63) | 0x0002);
      
      // Set line timed mode
      wr_framer (dev, 0x05, rd_framer (dev, 0x05) | 0x0001);
    } else {
      // SAMBA
      printk (" SAMBA");
      
      // Reset, just in case
      wr_framer (dev, 0, rd_framer (dev, 0) | 0x0001);
      wr_framer (dev, 0, rd_framer (dev, 0) &~ 0x0001);
      
      // Turn off diagnostic loopback and enable line-timed mode
      wr_framer (dev, 0, 0x0002);
      
      // Turn on transmit outputs
      wr_framer (dev, 2, 0x0B80);
    }
  } else {
    // Select 25 mode
    ctrl &= ~ATM_LAYER_SELECT;
    
    // Madge B154 setup
    // none required?
  }
  
  printk (" LEDs");
  
  GREEN_LED_ON(dev);
  YELLOW_LED_ON(dev);
  
  printk (" ESI=");
  
  {
    u16 b = 0;
    int i;
    u8 * esi = dev->atm_dev->esi;
    
    // in the card I have, EEPROM
    // addresses 0, 1, 2 contain 0
    // addresess 5, 6 etc. contain ffff
    // NB: Madge prefix is 00 00 f6 (which is 00 00 6f in Ethernet bit order)
    // the read_bia routine gets the BIA in Ethernet bit order
    
    for (i=0; i < ESI_LEN; ++i) {
      if (i % 2 == 0)
	b = read_bia (dev, i/2 + 2);
      else
	b = b >> 8;
      esi[i] = b & 0xFF;
      printk ("%02x", esi[i]);
    }
  }
  
  // Enable RX_Q and ?X_COMPLETE interrupts only
  wr_regl (dev, INT_ENABLE_REG_OFF, INTERESTING_INTERRUPTS);
  printk (" IRQ on");
  
  printk (".\n");
  
  return onefivefive;
}

/********** check max_sdu **********/

static int check_max_sdu (hrz_aal aal, struct atm_trafprm * tp, unsigned int max_frame_size) {
  PRINTD (DBG_FLOW|DBG_QOS, "check_max_sdu");
  
  switch (aal) {
    case aal0:
      if (!(tp->max_sdu)) {
	PRINTD (DBG_QOS, "defaulting max_sdu");
	tp->max_sdu = ATM_AAL0_SDU;
      } else if (tp->max_sdu != ATM_AAL0_SDU) {
	PRINTD (DBG_QOS|DBG_ERR, "rejecting max_sdu");
	return -EINVAL;
      }
      break;
    case aal34:
      if (tp->max_sdu == 0 || tp->max_sdu > ATM_MAX_AAL34_PDU) {
	PRINTD (DBG_QOS, "%sing max_sdu", tp->max_sdu ? "capp" : "default");
	tp->max_sdu = ATM_MAX_AAL34_PDU;
      }
      break;
    case aal5:
      if (tp->max_sdu == 0 || tp->max_sdu > max_frame_size) {
	PRINTD (DBG_QOS, "%sing max_sdu", tp->max_sdu ? "capp" : "default");
	tp->max_sdu = max_frame_size;
      }
      break;
  }
  return 0;
}

/********** check pcr **********/

// something like this should be part of ATM Linux
static int atm_pcr_check (struct atm_trafprm * tp, unsigned int pcr) {
  // we are assuming non-UBR, and non-special values of pcr
  if (tp->min_pcr == ATM_MAX_PCR)
    PRINTD (DBG_QOS, "luser gave min_pcr = ATM_MAX_PCR");
  else if (tp->min_pcr < 0)
    PRINTD (DBG_QOS, "luser gave negative min_pcr");
  else if (tp->min_pcr && tp->min_pcr > pcr)
    PRINTD (DBG_QOS, "pcr less than min_pcr");
  else
    // !! max_pcr = UNSPEC (0) is equivalent to max_pcr = MAX (-1)
    // easier to #define ATM_MAX_PCR 0 and have all rates unsigned?
    // [this would get rid of next two conditionals]
    if ((0) && tp->max_pcr == ATM_MAX_PCR)
      PRINTD (DBG_QOS, "luser gave max_pcr = ATM_MAX_PCR");
    else if ((tp->max_pcr != ATM_MAX_PCR) && tp->max_pcr < 0)
      PRINTD (DBG_QOS, "luser gave negative max_pcr");
    else if (tp->max_pcr && tp->max_pcr != ATM_MAX_PCR && tp->max_pcr < pcr)
      PRINTD (DBG_QOS, "pcr greater than max_pcr");
    else {
      // each limit unspecified or not violated
      PRINTD (DBG_QOS, "xBR(pcr) OK");
      return 0;
    }
  PRINTD (DBG_QOS, "pcr=%u, tp: min_pcr=%d, pcr=%d, max_pcr=%d",
	  pcr, tp->min_pcr, tp->pcr, tp->max_pcr);
  return -EINVAL;
}

/********** open VC **********/

static int hrz_open (struct atm_vcc *atm_vcc)
{
  int error;
  u16 channel;
  
  struct atm_qos * qos;
  struct atm_trafprm * txtp;
  struct atm_trafprm * rxtp;
  
  hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
  hrz_vcc vcc;
  hrz_vcc * vccp; // allocated late
  short vpi = atm_vcc->vpi;
  int vci = atm_vcc->vci;
  PRINTD (DBG_FLOW|DBG_VCC, "hrz_open %x %x", vpi, vci);
  
#ifdef ATM_VPI_UNSPEC
  // UNSPEC is deprecated, remove this code eventually
  if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) {
    PRINTK (KERN_WARNING, "rejecting open with unspecified VPI/VCI (deprecated)");
    return -EINVAL;
  }
#endif
  
  error = vpivci_to_channel (&channel, vpi, vci);
  if (error) {
    PRINTD (DBG_WARN|DBG_VCC, "VPI/VCI out of range: %hd/%d", vpi, vci);
    return error;
  }
  
  vcc.channel = channel;
  // max speed for the moment
  vcc.tx_rate = 0x0;
  
  qos = &atm_vcc->qos;
  
  // check AAL and remember it
  switch (qos->aal) {
    case ATM_AAL0:
      // we would if it were 48 bytes and not 52!
      PRINTD (DBG_QOS|DBG_VCC, "AAL0");
      vcc.aal = aal0;
      break;
    case ATM_AAL34:
      // we would if I knew how do the SAR!
      PRINTD (DBG_QOS|DBG_VCC, "AAL3/4");
      vcc.aal = aal34;
      break;
    case ATM_AAL5:
      PRINTD (DBG_QOS|DBG_VCC, "AAL5");
      vcc.aal = aal5;
      break;
    default:
      PRINTD (DBG_QOS|DBG_VCC, "Bad AAL!");
      return -EINVAL;
  }
  
  // TX traffic parameters
  
  // there are two, interrelated problems here: 1. the reservation of
  // PCR is not a binary choice, we are given bounds and/or a
  // desirable value; 2. the device is only capable of certain values,
  // most of which are not integers. It is almost certainly acceptable
  // to be off by a maximum of 1 to 10 cps.
  
  // Pragmatic choice: always store an integral PCR as that which has
  // been allocated, even if we allocate a little (or a lot) less,
  // after rounding. The actual allocation depends on what we can
  // manage with our rate selection algorithm. The rate selection
  // algorithm is given an integral PCR and a tolerance and told
  // whether it should round the value up or down if the tolerance is
  // exceeded; it returns: a) the actual rate selected (rounded up to
  // the nearest integer), b) a bit pattern to feed to the timer
  // register, and c) a failure value if no applicable rate exists.
  
  // Part of the job is done by atm_pcr_goal which gives us a PCR
  // specification which says: EITHER grab the maximum available PCR
  // (and perhaps a lower bound which we musn't pass), OR grab this
  // amount, rounding down if you have to (and perhaps a lower bound
  // which we musn't pass) OR grab this amount, rounding up if you
  // have to (and perhaps an upper bound which we musn't pass). If any
  // bounds ARE passed we fail. Note that rounding is only rounding to
  // match device limitations, we do not round down to satisfy
  // bandwidth availability even if this would not violate any given
  // lower bound.
  
  // Note: telephony = 64kb/s = 48 byte cell payload @ 500/3 cells/s
  // (say) so this is not even a binary fixpoint cell rate (but this
  // device can do it). To avoid this sort of hassle we use a
  // tolerance parameter (currently fixed at 10 cps).
  
  PRINTD (DBG_QOS, "TX:");
  
  txtp = &qos->txtp;
  
  // set up defaults for no traffic
  vcc.tx_rate = 0;
  // who knows what would actually happen if you try and send on this?
  vcc.tx_xbr_bits = IDLE_RATE_TYPE;
  vcc.tx_pcr_bits = CLOCK_DISABLE;
#if 0
  vcc.tx_scr_bits = CLOCK_DISABLE;
  vcc.tx_bucket_bits = 0;
#endif
  
  if (txtp->traffic_class != ATM_NONE) {
    error = check_max_sdu (vcc.aal, txtp, max_tx_size);
    if (error) {
      PRINTD (DBG_QOS, "TX max_sdu check failed");
      return error;
    }
    
    switch (txtp->traffic_class) {
      case ATM_UBR: {
	// we take "the PCR" as a rate-cap
	// not reserved
	vcc.tx_rate = 0;
	make_rate (dev, 1<<30, round_nearest, &vcc.tx_pcr_bits, NULL);
	vcc.tx_xbr_bits = ABR_RATE_TYPE;
	break;
      }
#if 0
      case ATM_ABR: {
	// reserve min, allow up to max
	vcc.tx_rate = 0; // ?
	make_rate (dev, 1<<30, round_nearest, &vcc.tx_pcr_bits, 0);
	vcc.tx_xbr_bits = ABR_RATE_TYPE;
	break;
      }
#endif
      case ATM_CBR: {
	int pcr = atm_pcr_goal (txtp);
	rounding r;
	if (!pcr) {
	  // down vs. up, remaining bandwidth vs. unlimited bandwidth!!
	  // should really have: once someone gets unlimited bandwidth
	  // that no more non-UBR channels can be opened until the
	  // unlimited one closes?? For the moment, round_down means
	  // greedy people actually get something and not nothing
	  r = round_down;
	  // slight race (no locking) here so we may get -EAGAIN
	  // later; the greedy bastards would deserve it :)
	  PRINTD (DBG_QOS, "snatching all remaining TX bandwidth");
	  pcr = dev->tx_avail;
	} else if (pcr < 0) {
	  r = round_down;
	  pcr = -pcr;
	} else {
	  r = round_up;
	}
	error = make_rate_with_tolerance (dev, pcr, r, 10,
					  &vcc.tx_pcr_bits, &vcc.tx_rate);
	if (error) {
	  PRINTD (DBG_QOS, "could not make rate from TX PCR");
	  return error;
	}
	// not really clear what further checking is needed
	error = atm_pcr_check (txtp, vcc.tx_rate);
	if (error) {
	  PRINTD (DBG_QOS, "TX PCR failed consistency check");
	  return error;
	}
	vcc.tx_xbr_bits = CBR_RATE_TYPE;
	break;
      }
#if 0
      case ATM_VBR: {
	int pcr = atm_pcr_goal (txtp);
	// int scr = atm_scr_goal (txtp);
	int scr = pcr/2; // just for fun
	unsigned int mbs = 60; // just for fun
	rounding pr;
	rounding sr;
	unsigned int bucket;
	if (!pcr) {
	  pr = round_nearest;
	  pcr = 1<<30;
	} else if (pcr < 0) {
	  pr = round_down;
	  pcr = -pcr;
	} else {
	  pr = round_up;
	}
	error = make_rate_with_tolerance (dev, pcr, pr, 10,
					  &vcc.tx_pcr_bits, 0);
	if (!scr) {
	  // see comments for PCR with CBR above
	  sr = round_down;
	  // slight race (no locking) here so we may get -EAGAIN
	  // later; the greedy bastards would deserve it :)
	  PRINTD (DBG_QOS, "snatching all remaining TX bandwidth");
	  scr = dev->tx_avail;
	} else if (scr < 0) {
	  sr = round_down;
	  scr = -scr;
	} else {
	  sr = round_up;
	}
	error = make_rate_with_tolerance (dev, scr, sr, 10,
					  &vcc.tx_scr_bits, &vcc.tx_rate);
	if (error) {
	  PRINTD (DBG_QOS, "could not make rate from TX SCR");
	  return error;
	}
	// not really clear what further checking is needed
	// error = atm_scr_check (txtp, vcc.tx_rate);
	if (error) {
	  PRINTD (DBG_QOS, "TX SCR failed consistency check");
	  return error;
	}
	// bucket calculations (from a piece of paper...) cell bucket
	// capacity must be largest integer smaller than m(p-s)/p + 1
	// where m = max burst size, p = pcr, s = scr
	bucket = mbs*(pcr-scr)/pcr;
	if (bucket*pcr != mbs*(pcr-scr))
	  bucket += 1;
	if (bucket > BUCKET_MAX_SIZE) {
	  PRINTD (DBG_QOS, "shrinking bucket from %u to %u",
		  bucket, BUCKET_MAX_SIZE);
	  bucket = BUCKET_MAX_SIZE;
	}
	vcc.tx_xbr_bits = VBR_RATE_TYPE;
	vcc.tx_bucket_bits = bucket;
	break;
      }
#endif
      default: {
	PRINTD (DBG_QOS, "unsupported TX traffic class");
	return -EINVAL;
      }
    }
  }
  
  // RX traffic parameters
  
  PRINTD (DBG_QOS, "RX:");
  
  rxtp = &qos->rxtp;
  
  // set up defaults for no traffic
  vcc.rx_rate = 0;
  
  if (rxtp->traffic_class != ATM_NONE) {
    error = check_max_sdu (vcc.aal, rxtp, max_rx_size);
    if (error) {
      PRINTD (DBG_QOS, "RX max_sdu check failed");
      return error;
    }
    switch (rxtp->traffic_class) {
      case ATM_UBR: {
	// not reserved
	break;
      }
#if 0
      case ATM_ABR: {
	// reserve min
	vcc.rx_rate = 0; // ?
	break;
      }
#endif
      case ATM_CBR: {
	int pcr = atm_pcr_goal (rxtp);
	if (!pcr) {
	  // slight race (no locking) here so we may get -EAGAIN
	  // later; the greedy bastards would deserve it :)
	  PRINTD (DBG_QOS, "snatching all remaining RX bandwidth");
	  pcr = dev->rx_avail;
	} else if (pcr < 0) {
	  pcr = -pcr;
	}
	vcc.rx_rate = pcr;
	// not really clear what further checking is needed
	error = atm_pcr_check (rxtp, vcc.rx_rate);
	if (error) {
	  PRINTD (DBG_QOS, "RX PCR failed consistency check");
	  return error;
	}
	break;
      }
#if 0
      case ATM_VBR: {
	// int scr = atm_scr_goal (rxtp);
	int scr = 1<<16; // just for fun
	if (!scr) {
	  // slight race (no locking) here so we may get -EAGAIN
	  // later; the greedy bastards would deserve it :)
	  PRINTD (DBG_QOS, "snatching all remaining RX bandwidth");
	  scr = dev->rx_avail;
	} else if (scr < 0) {
	  scr = -scr;
	}
	vcc.rx_rate = scr;
	// not really clear what further checking is needed
	// error = atm_scr_check (rxtp, vcc.rx_rate);
	if (error) {
	  PRINTD (DBG_QOS, "RX SCR failed consistency check");
	  return error;
	}
	break;
      }
#endif
      default: {
	PRINTD (DBG_QOS, "unsupported RX traffic class");
	return -EINVAL;
      }
    }
  }
  
  
  // late abort useful for diagnostics
  if (vcc.aal != aal5) {
    PRINTD (DBG_QOS, "AAL not supported");
    return -EINVAL;
  }
  
  // get space for our vcc stuff and copy parameters into it
  vccp = kmalloc (sizeof(hrz_vcc), GFP_KERNEL);
  if (!vccp) {
    PRINTK (KERN_ERR, "out of memory!");
    return -ENOMEM;
  }
  *vccp = vcc;
  
  // clear error and grab cell rate resource lock
  error = 0;
  spin_lock (&dev->rate_lock);
  
  if (vcc.tx_rate > dev->tx_avail) {
    PRINTD (DBG_QOS, "not enough TX PCR left");
    error = -EAGAIN;
  }
  
  if (vcc.rx_rate > dev->rx_avail) {
    PRINTD (DBG_QOS, "not enough RX PCR left");
    error = -EAGAIN;
  }
  
  if (!error) {
    // really consume cell rates
    dev->tx_avail -= vcc.tx_rate;
    dev->rx_avail -= vcc.rx_rate;
    PRINTD (DBG_QOS|DBG_VCC, "reserving %u TX PCR and %u RX PCR",
	    vcc.tx_rate, vcc.rx_rate);
  }
  
  // release lock and exit on error
  spin_unlock (&dev->rate_lock);
  if (error) {
    PRINTD (DBG_QOS|DBG_VCC, "insufficient cell rate resources");
    kfree (vccp);
    return error;
  }
  
  // this is "immediately before allocating the connection identifier
  // in hardware" - so long as the next call does not fail :)
  set_bit(ATM_VF_ADDR,&atm_vcc->flags);
  
  // any errors here are very serious and should never occur
  
  if (rxtp->traffic_class != ATM_NONE) {
    if (dev->rxer[channel]) {
      PRINTD (DBG_ERR|DBG_VCC, "VC already open for RX");
      error = -EBUSY;
    }
    if (!error)
      error = hrz_open_rx (dev, channel);
    if (error) {
      kfree (vccp);
      return error;
    }
    // this link allows RX frames through
    dev->rxer[channel] = atm_vcc;
  }
  
  // success, set elements of atm_vcc
  atm_vcc->dev_data = (void *) vccp;
  
  // indicate readiness
  set_bit(ATM_VF_READY,&atm_vcc->flags);
  
  return 0;
}

/********** close VC **********/

static void hrz_close (struct atm_vcc * atm_vcc) {
  hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
  hrz_vcc * vcc = HRZ_VCC(atm_vcc);
  u16 channel = vcc->channel;
  PRINTD (DBG_VCC|DBG_FLOW, "hrz_close");
  
  // indicate unreadiness
  clear_bit(ATM_VF_READY,&atm_vcc->flags);

  if (atm_vcc->qos.txtp.traffic_class != ATM_NONE) {
    unsigned int i;
    
    // let any TX on this channel that has started complete
    // no restart, just keep trying
    while (tx_hold (dev))
      ;
    // remove record of any tx_channel having been setup for this channel
    for (i = 0; i < TX_CHANS; ++i)
      if (dev->tx_channel_record[i] == channel) {
	dev->tx_channel_record[i] = -1;
	break;
      }
    if (dev->last_vc == channel)
      dev->tx_last = -1;
    tx_release (dev);
  }

  if (atm_vcc->qos.rxtp.traffic_class != ATM_NONE) {
    // disable RXing - it tries quite hard
    hrz_close_rx (dev, channel);
    // forget the vcc - no more skbs will be pushed
    if (atm_vcc != dev->rxer[channel])
      PRINTK (KERN_ERR, "%s atm_vcc=%p rxer[channel]=%p",
	      "arghhh! we're going to die!",
	      atm_vcc, dev->rxer[channel]);
    dev->rxer[channel] = NULL;
  }
  
  // atomically release our rate reservation
  spin_lock (&dev->rate_lock);
  PRINTD (DBG_QOS|DBG_VCC, "releasing %u TX PCR and %u RX PCR",
	  vcc->tx_rate, vcc->rx_rate);
  dev->tx_avail += vcc->tx_rate;
  dev->rx_avail += vcc->rx_rate;
  spin_unlock (&dev->rate_lock);
  
  // free our structure
  kfree (vcc);
  // say the VPI/VCI is free again
  clear_bit(ATM_VF_ADDR,&atm_vcc->flags);
}

#if 0
static int hrz_getsockopt (struct atm_vcc * atm_vcc, int level, int optname,
			   void *optval, int optlen) {
  hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
  PRINTD (DBG_FLOW|DBG_VCC, "hrz_getsockopt");
  switch (level) {
    case SOL_SOCKET:
      switch (optname) {
//	case SO_BCTXOPT:
//	  break;
//	case SO_BCRXOPT:
//	  break;
	default:
	  return -ENOPROTOOPT;
      };
      break;
  }
  return -EINVAL;
}

static int hrz_setsockopt (struct atm_vcc * atm_vcc, int level, int optname,
			   void *optval, unsigned int optlen) {
  hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
  PRINTD (DBG_FLOW|DBG_VCC, "hrz_setsockopt");
  switch (level) {
    case SOL_SOCKET:
      switch (optname) {
//	case SO_BCTXOPT:
//	  break;
//	case SO_BCRXOPT:
//	  break;
	default:
	  return -ENOPROTOOPT;
      };
      break;
  }
  return -EINVAL;
}
#endif

#if 0
static int hrz_ioctl (struct atm_dev * atm_dev, unsigned int cmd, void *arg) {
  hrz_dev * dev = HRZ_DEV(atm_dev);
  PRINTD (DBG_FLOW, "hrz_ioctl");
  return -1;
}

unsigned char hrz_phy_get (struct atm_dev * atm_dev, unsigned long addr) {
  hrz_dev * dev = HRZ_DEV(atm_dev);
  PRINTD (DBG_FLOW, "hrz_phy_get");
  return 0;
}

static void hrz_phy_put (struct atm_dev * atm_dev, unsigned char value,
			 unsigned long addr) {
  hrz_dev * dev = HRZ_DEV(atm_dev);
  PRINTD (DBG_FLOW, "hrz_phy_put");
}

static int hrz_change_qos (struct atm_vcc * atm_vcc, struct atm_qos *qos, int flgs) {
  hrz_dev * dev = HRZ_DEV(vcc->dev);
  PRINTD (DBG_FLOW, "hrz_change_qos");
  return -1;
}
#endif

/********** proc file contents **********/

static int hrz_proc_read (struct atm_dev * atm_dev, loff_t * pos, char * page) {
  hrz_dev * dev = HRZ_DEV(atm_dev);
  int left = *pos;
  PRINTD (DBG_FLOW, "hrz_proc_read");
  
  /* more diagnostics here? */
  
#if 0
  if (!left--) {
    unsigned int count = sprintf (page, "vbr buckets:");
    unsigned int i;
    for (i = 0; i < TX_CHANS; ++i)
      count += sprintf (page, " %u/%u",
			query_tx_channel_config (dev, i, BUCKET_FULLNESS_ACCESS),
			query_tx_channel_config (dev, i, BUCKET_CAPACITY_ACCESS));
    count += sprintf (page+count, ".\n");
    return count;
  }
#endif
  
  if (!left--)
    return sprintf (page,
		    "cells: TX %lu, RX %lu, HEC errors %lu, unassigned %lu.\n",
		    dev->tx_cell_count, dev->rx_cell_count,
		    dev->hec_error_count, dev->unassigned_cell_count);
  
  if (!left--)
    return sprintf (page,
		    "free cell buffers: TX %hu, RX %hu+%hu.\n",
		    rd_regw (dev, TX_FREE_BUFFER_COUNT_OFF),
		    rd_regw (dev, RX_FREE_BUFFER_COUNT_OFF),
		    dev->noof_spare_buffers);
  
  if (!left--)
    return sprintf (page,
		    "cps remaining: TX %u, RX %u\n",
		    dev->tx_avail, dev->rx_avail);
  
  return 0;
}

static const struct atmdev_ops hrz_ops = {
  .open	= hrz_open,
  .close	= hrz_close,
  .send	= hrz_send,
  .proc_read	= hrz_proc_read,
  .owner	= THIS_MODULE,
};

static int hrz_probe(struct pci_dev *pci_dev,
		     const struct pci_device_id *pci_ent)
{
	hrz_dev * dev;
	int err = 0;

	// adapter slot free, read resources from PCI configuration space
	u32 iobase = pci_resource_start (pci_dev, 0);
	u32 * membase = bus_to_virt (pci_resource_start (pci_dev, 1));
	unsigned int irq;
	unsigned char lat;

	PRINTD (DBG_FLOW, "hrz_probe");

	if (pci_enable_device(pci_dev))
		return -EINVAL;

	/* XXX DEV_LABEL is a guess */
	if (!request_region(iobase, HRZ_IO_EXTENT, DEV_LABEL)) {
		err = -EINVAL;
		goto out_disable;
	}

	dev = kzalloc(sizeof(hrz_dev), GFP_KERNEL);
	if (!dev) {
		// perhaps we should be nice: deregister all adapters and abort?
		PRINTD(DBG_ERR, "out of memory");
		err = -ENOMEM;
		goto out_release;
	}

	pci_set_drvdata(pci_dev, dev);

	// grab IRQ and install handler - move this someplace more sensible
	irq = pci_dev->irq;
	if (request_irq(irq,
			interrupt_handler,
			IRQF_SHARED, /* irqflags guess */
			DEV_LABEL, /* name guess */
			dev)) {
		PRINTD(DBG_WARN, "request IRQ failed!");
		err = -EINVAL;
		goto out_free;
	}

	PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p",
	       iobase, irq, membase);

	dev->atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &hrz_ops, -1,
					NULL);
	if (!(dev->atm_dev)) {
		PRINTD(DBG_ERR, "failed to register Madge ATM adapter");
		err = -EINVAL;
		goto out_free_irq;
	}

	PRINTD(DBG_INFO, "registered Madge ATM adapter (no. %d) (%p) at %p",
	       dev->atm_dev->number, dev, dev->atm_dev);
	dev->atm_dev->dev_data = (void *) dev;
	dev->pci_dev = pci_dev; 

	// enable bus master accesses
	pci_set_master(pci_dev);

	// frobnicate latency (upwards, usually)
	pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &lat);
	if (pci_lat) {
		PRINTD(DBG_INFO, "%s PCI latency timer from %hu to %hu",
		       "changing", lat, pci_lat);
		pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, pci_lat);
	} else if (lat < MIN_PCI_LATENCY) {
		PRINTK(KERN_INFO, "%s PCI latency timer from %hu to %hu",
		       "increasing", lat, MIN_PCI_LATENCY);
		pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, MIN_PCI_LATENCY);
	}

	dev->iobase = iobase;
	dev->irq = irq; 
	dev->membase = membase; 

	dev->rx_q_entry = dev->rx_q_reset = &memmap->rx_q_entries[0];
	dev->rx_q_wrap  = &memmap->rx_q_entries[RX_CHANS-1];

	// these next three are performance hacks
	dev->last_vc = -1;
	dev->tx_last = -1;
	dev->tx_idle = 0;

	dev->tx_regions = 0;
	dev->tx_bytes = 0;
	dev->tx_skb = NULL;
	dev->tx_iovec = NULL;

	dev->tx_cell_count = 0;
	dev->rx_cell_count = 0;
	dev->hec_error_count = 0;
	dev->unassigned_cell_count = 0;

	dev->noof_spare_buffers = 0;

	{
		unsigned int i;
		for (i = 0; i < TX_CHANS; ++i)
			dev->tx_channel_record[i] = -1;
	}

	dev->flags = 0;

	// Allocate cell rates and remember ASIC version
	// Fibre: ATM_OC3_PCR = 1555200000/8/270*260/53 - 29/53
	// Copper: (WRONG) we want 6 into the above, close to 25Mb/s
	// Copper: (plagarise!) 25600000/8/270*260/53 - n/53

	if (hrz_init(dev)) {
		// to be really pedantic, this should be ATM_OC3c_PCR
		dev->tx_avail = ATM_OC3_PCR;
		dev->rx_avail = ATM_OC3_PCR;
		set_bit(ultra, &dev->flags); // NOT "|= ultra" !
	} else {
		dev->tx_avail = ((25600000/8)*26)/(27*53);
		dev->rx_avail = ((25600000/8)*26)/(27*53);
		PRINTD(DBG_WARN, "Buggy ASIC: no TX bus-mastering.");
	}

	// rate changes spinlock
	spin_lock_init(&dev->rate_lock);

	// on-board memory access spinlock; we want atomic reads and
	// writes to adapter memory (handles IRQ and SMP)
	spin_lock_init(&dev->mem_lock);

	init_waitqueue_head(&dev->tx_queue);

	// vpi in 0..4, vci in 6..10
	dev->atm_dev->ci_range.vpi_bits = vpi_bits;
	dev->atm_dev->ci_range.vci_bits = 10-vpi_bits;

	setup_timer(&dev->housekeeping, do_housekeeping, (unsigned long) dev);
	mod_timer(&dev->housekeeping, jiffies);

out:
	return err;

out_free_irq:
	free_irq(irq, dev);
out_free:
	kfree(dev);
out_release:
	release_region(iobase, HRZ_IO_EXTENT);
out_disable:
	pci_disable_device(pci_dev);
	goto out;
}

static void hrz_remove_one(struct pci_dev *pci_dev)
{
	hrz_dev *dev;

	dev = pci_get_drvdata(pci_dev);

	PRINTD(DBG_INFO, "closing %p (atm_dev = %p)", dev, dev->atm_dev);
	del_timer_sync(&dev->housekeeping);
	hrz_reset(dev);
	atm_dev_deregister(dev->atm_dev);
	free_irq(dev->irq, dev);
	release_region(dev->iobase, HRZ_IO_EXTENT);
	kfree(dev);

	pci_disable_device(pci_dev);
}

static void __init hrz_check_args (void) {
#ifdef DEBUG_HORIZON
  PRINTK (KERN_NOTICE, "debug bitmap is %hx", debug &= DBG_MASK);
#else
  if (debug)
    PRINTK (KERN_NOTICE, "no debug support in this image");
#endif
  
  if (vpi_bits > HRZ_MAX_VPI)
    PRINTK (KERN_ERR, "vpi_bits has been limited to %hu",
	    vpi_bits = HRZ_MAX_VPI);
  
  if (max_tx_size < 0 || max_tx_size > TX_AAL5_LIMIT)
    PRINTK (KERN_NOTICE, "max_tx_size has been limited to %hu",
	    max_tx_size = TX_AAL5_LIMIT);
  
  if (max_rx_size < 0 || max_rx_size > RX_AAL5_LIMIT)
    PRINTK (KERN_NOTICE, "max_rx_size has been limited to %hu",
	    max_rx_size = RX_AAL5_LIMIT);
  
  return;
}

MODULE_AUTHOR(maintainer_string);
MODULE_DESCRIPTION(description_string);
MODULE_LICENSE("GPL");
module_param(debug, ushort, 0644);
module_param(vpi_bits, ushort, 0);
module_param(max_tx_size, int, 0);
module_param(max_rx_size, int, 0);
module_param(pci_lat, byte, 0);
MODULE_PARM_DESC(debug, "debug bitmap, see .h file");
MODULE_PARM_DESC(vpi_bits, "number of bits (0..4) to allocate to VPIs");
MODULE_PARM_DESC(max_tx_size, "maximum size of TX AAL5 frames");
MODULE_PARM_DESC(max_rx_size, "maximum size of RX AAL5 frames");
MODULE_PARM_DESC(pci_lat, "PCI latency in bus cycles");

static const struct pci_device_id hrz_pci_tbl[] = {
	{ PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_HORIZON, PCI_ANY_ID, PCI_ANY_ID,
	  0, 0, 0 },
	{ 0, }
};

MODULE_DEVICE_TABLE(pci, hrz_pci_tbl);

static struct pci_driver hrz_driver = {
	.name =		"horizon",
	.probe =	hrz_probe,
	.remove =	hrz_remove_one,
	.id_table =	hrz_pci_tbl,
};

/********** module entry **********/

static int __init hrz_module_init (void) {
  BUILD_BUG_ON(sizeof(struct MEMMAP) != 128*1024/4);
  
  show_version();
  
  // check arguments
  hrz_check_args();
  
  // get the juice
  return pci_register_driver(&hrz_driver);
}

/********** module exit **********/

static void __exit hrz_module_exit (void) {
  PRINTD (DBG_FLOW, "cleanup_module");

  pci_unregister_driver(&hrz_driver);
}

module_init(hrz_module_init);
module_exit(hrz_module_exit);
