/*
 * Copyright 2003 Digi International (www.digi.com)
 *	Scott H Kilau <Scott_Kilau at digi dot com>
 *
 * 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, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 */

/*
 *      In the original out of kernel Digi dgap driver, firmware
 *      loading was done via user land to driver handshaking.
 *
 *      For cards that support a concentrator (port expander),
 *      I believe the concentrator its self told the card which
 *      concentrator is actually attached and then that info
 *      was used to tell user land which concentrator firmware
 *      image was to be downloaded. I think even the BIOS or
 *      FEP images required could change with the connection
 *      of a particular concentrator.
 *
 *      Since I have no access to any of these cards or
 *      concentrators, I cannot put the correct concentrator
 *      firmware file names into the firmware_info structure
 *      as is now done for the BIOS and FEP images.
 *
 *      I think, but am not certain, that the cards supporting
 *      concentrators will function without them. So support
 *      of these cards has been left in this driver.
 *
 *      In order to fully support those cards, they would
 *      either have to be acquired for dissection or maybe
 *      Digi International could provide some assistance.
 */
#undef DIGI_CONCENTRATORS_SUPPORTED

#define pr_fmt(fmt) "dgap: " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>	/* For udelay */
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/sched.h>

#include <linux/interrupt.h>	/* For tasklet and interrupt structs/defines */
#include <linux/ctype.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_reg.h>
#include <linux/io.h>		/* For read[bwl]/write[bwl] */

#include <linux/string.h>
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/firmware.h>

#include "dgap.h"

/*
 * File operations permitted on Control/Management major.
 */
static const struct file_operations dgap_board_fops = {
	.owner	= THIS_MODULE,
};

static uint dgap_numboards;
static struct board_t *dgap_board[MAXBOARDS];
static ulong dgap_poll_counter;
static int dgap_driver_state = DRIVER_INITIALIZED;
static int dgap_poll_tick = 20;	/* Poll interval - 20 ms */

static struct class *dgap_class;

static uint dgap_count = 500;

/*
 * Poller stuff
 */
static DEFINE_SPINLOCK(dgap_poll_lock);	/* Poll scheduling lock */
static ulong dgap_poll_time;		/* Time of next poll */
static uint dgap_poll_stop;		/* Used to tell poller to stop */
static struct timer_list dgap_poll_timer;

/*
     SUPPORTED PRODUCTS

     Card Model               Number of Ports      Interface
     ----------------------------------------------------------------
     Acceleport Xem           4 - 64              (EIA232 & EIA422)
     Acceleport Xr            4 & 8               (EIA232)
     Acceleport Xr 920        4 & 8               (EIA232)
     Acceleport C/X           8 - 128             (EIA232)
     Acceleport EPC/X         8 - 224             (EIA232)
     Acceleport Xr/422        4 & 8               (EIA422)
     Acceleport 2r/920        2                   (EIA232)
     Acceleport 4r/920        4                   (EIA232)
     Acceleport 8r/920        8                   (EIA232)

     IBM 8-Port Asynchronous PCI Adapter          (EIA232)
     IBM 128-Port Asynchronous PCI Adapter        (EIA232 & EIA422)
*/

static struct pci_device_id dgap_pci_tbl[] = {
	{ DIGI_VID, PCI_DEV_XEM_DID,      PCI_ANY_ID, PCI_ANY_ID, 0, 0,  0 },
	{ DIGI_VID, PCI_DEV_CX_DID,       PCI_ANY_ID, PCI_ANY_ID, 0, 0,  1 },
	{ DIGI_VID, PCI_DEV_CX_IBM_DID,   PCI_ANY_ID, PCI_ANY_ID, 0, 0,  2 },
	{ DIGI_VID, PCI_DEV_EPCJ_DID,     PCI_ANY_ID, PCI_ANY_ID, 0, 0,  3 },
	{ DIGI_VID, PCI_DEV_920_2_DID,    PCI_ANY_ID, PCI_ANY_ID, 0, 0,  4 },
	{ DIGI_VID, PCI_DEV_920_4_DID,    PCI_ANY_ID, PCI_ANY_ID, 0, 0,  5 },
	{ DIGI_VID, PCI_DEV_920_8_DID,    PCI_ANY_ID, PCI_ANY_ID, 0, 0,  6 },
	{ DIGI_VID, PCI_DEV_XR_DID,       PCI_ANY_ID, PCI_ANY_ID, 0, 0,  7 },
	{ DIGI_VID, PCI_DEV_XRJ_DID,      PCI_ANY_ID, PCI_ANY_ID, 0, 0,  8 },
	{ DIGI_VID, PCI_DEV_XR_422_DID,   PCI_ANY_ID, PCI_ANY_ID, 0, 0,  9 },
	{ DIGI_VID, PCI_DEV_XR_IBM_DID,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
	{ DIGI_VID, PCI_DEV_XR_SAIP_DID,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
	{ DIGI_VID, PCI_DEV_XR_BULL_DID,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
	{ DIGI_VID, PCI_DEV_920_8_HP_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 },
	{ DIGI_VID, PCI_DEV_XEM_HP_DID,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
	{0,}					/* 0 terminated list. */
};
MODULE_DEVICE_TABLE(pci, dgap_pci_tbl);

/*
 * A generic list of Product names, PCI Vendor ID, and PCI Device ID.
 */
struct board_id {
	uint config_type;
	u8 *name;
	uint maxports;
	uint dpatype;
};

static struct board_id dgap_ids[] = {
	{PPCM,        PCI_DEV_XEM_NAME,     64, (T_PCXM | T_PCLITE | T_PCIBUS)},
	{PCX,         PCI_DEV_CX_NAME,     128, (T_CX | T_PCIBUS)            },
	{PCX,         PCI_DEV_CX_IBM_NAME, 128, (T_CX | T_PCIBUS)            },
	{PEPC,        PCI_DEV_EPCJ_NAME,   224, (T_EPC | T_PCIBUS)           },
	{APORT2_920P, PCI_DEV_920_2_NAME,    2, (T_PCXR | T_PCLITE | T_PCIBUS)},
	{APORT4_920P, PCI_DEV_920_4_NAME,    4, (T_PCXR | T_PCLITE | T_PCIBUS)},
	{APORT8_920P, PCI_DEV_920_8_NAME,    8, (T_PCXR | T_PCLITE | T_PCIBUS)},
	{PAPORT8,     PCI_DEV_XR_NAME,       8, (T_PCXR | T_PCLITE | T_PCIBUS)},
	{PAPORT8,     PCI_DEV_XRJ_NAME,      8, (T_PCXR | T_PCLITE | T_PCIBUS)},
	{PAPORT8,     PCI_DEV_XR_422_NAME,   8, (T_PCXR | T_PCLITE | T_PCIBUS)},
	{PAPORT8,     PCI_DEV_XR_IBM_NAME,   8, (T_PCXR | T_PCLITE | T_PCIBUS)},
	{PAPORT8,     PCI_DEV_XR_SAIP_NAME,  8, (T_PCXR | T_PCLITE | T_PCIBUS)},
	{PAPORT8,     PCI_DEV_XR_BULL_NAME,  8, (T_PCXR | T_PCLITE | T_PCIBUS)},
	{APORT8_920P, PCI_DEV_920_8_HP_NAME, 8, (T_PCXR | T_PCLITE | T_PCIBUS)},
	{PPCM,        PCI_DEV_XEM_HP_NAME,  64, (T_PCXM | T_PCLITE | T_PCIBUS)},
	{0,}						/* 0 terminated list. */
};

struct firmware_info {
	u8 *conf_name;  /* dgap.conf */
	u8 *bios_name;	/* BIOS filename */
	u8 *fep_name;	/* FEP  filename */
	u8 *con_name;	/* Concentrator filename  FIXME*/
	int num;        /* sequence number */
};

/*
 * Firmware - BIOS, FEP, and CONC filenames
 */
static struct firmware_info fw_info[] = {
	{ "dgap/dgap.conf", "dgap/sxbios.bin",  "dgap/sxfep.bin",  NULL, 0 },
	{ "dgap/dgap.conf", "dgap/cxpbios.bin", "dgap/cxpfep.bin", NULL, 1 },
	{ "dgap/dgap.conf", "dgap/cxpbios.bin", "dgap/cxpfep.bin", NULL, 2 },
	{ "dgap/dgap.conf", "dgap/pcibios.bin", "dgap/pcifep.bin", NULL, 3 },
	{ "dgap/dgap.conf", "dgap/xrbios.bin",  "dgap/xrfep.bin",  NULL, 4 },
	{ "dgap/dgap.conf", "dgap/xrbios.bin",  "dgap/xrfep.bin",  NULL, 5 },
	{ "dgap/dgap.conf", "dgap/xrbios.bin",  "dgap/xrfep.bin",  NULL, 6 },
	{ "dgap/dgap.conf", "dgap/xrbios.bin",  "dgap/xrfep.bin",  NULL, 7 },
	{ "dgap/dgap.conf", "dgap/xrbios.bin",  "dgap/xrfep.bin",  NULL, 8 },
	{ "dgap/dgap.conf", "dgap/xrbios.bin",  "dgap/xrfep.bin",  NULL, 9 },
	{ "dgap/dgap.conf", "dgap/xrbios.bin",  "dgap/xrfep.bin",  NULL, 10 },
	{ "dgap/dgap.conf", "dgap/xrbios.bin",  "dgap/xrfep.bin",  NULL, 11 },
	{ "dgap/dgap.conf", "dgap/xrbios.bin",  "dgap/xrfep.bin",  NULL, 12 },
	{ "dgap/dgap.conf", "dgap/xrbios.bin",  "dgap/xrfep.bin",  NULL, 13 },
	{ "dgap/dgap.conf", "dgap/sxbios.bin",  "dgap/sxfep.bin",  NULL, 14 },
	{NULL,}
};

/*
 * Default transparent print information.
 */
static struct digi_t dgap_digi_init = {
	.digi_flags =	DIGI_COOK,	/* Flags			*/
	.digi_maxcps =	100,		/* Max CPS			*/
	.digi_maxchar =	50,		/* Max chars in print queue	*/
	.digi_bufsize =	100,		/* Printer buffer size		*/
	.digi_onlen =	4,		/* size of printer on string	*/
	.digi_offlen =	4,		/* size of printer off string	*/
	.digi_onstr =	"\033[5i",	/* ANSI printer on string ]	*/
	.digi_offstr =	"\033[4i",	/* ANSI printer off string ]	*/
	.digi_term =	"ansi"		/* default terminal type	*/
};

/*
 * Define a local default termios struct. All ports will be created
 * with this termios initially.
 *
 * This defines a raw port at 9600 baud, 8 data bits, no parity,
 * 1 stop bit.
 */

static struct ktermios dgap_default_termios = {
	.c_iflag =	(DEFAULT_IFLAGS),	/* iflags */
	.c_oflag =	(DEFAULT_OFLAGS),	/* oflags */
	.c_cflag =	(DEFAULT_CFLAGS),	/* cflags */
	.c_lflag =	(DEFAULT_LFLAGS),	/* lflags */
	.c_cc =		INIT_C_CC,
	.c_line =	0,
};

/*
 * Our needed internal static variables from dgap_parse.c
 */
static struct cnode dgap_head;
#define MAXCWORD 200
static char dgap_cword[MAXCWORD];

struct toklist {
	int token;
	char *string;
};

static struct toklist dgap_brdtype[] = {
	{ PCX,		"Digi_AccelePort_C/X_PCI" },
	{ PEPC,		"Digi_AccelePort_EPC/X_PCI" },
	{ PPCM,		"Digi_AccelePort_Xem_PCI" },
	{ APORT2_920P,	"Digi_AccelePort_2r_920_PCI" },
	{ APORT4_920P,	"Digi_AccelePort_4r_920_PCI" },
	{ APORT8_920P,	"Digi_AccelePort_8r_920_PCI" },
	{ PAPORT4,	"Digi_AccelePort_4r_PCI(EIA-232/RS-422)" },
	{ PAPORT8,	"Digi_AccelePort_8r_PCI(EIA-232/RS-422)" },
	{ 0, NULL }
};

static struct toklist dgap_tlist[] = {
	{ BEGIN,	"config_begin" },
	{ END,		"config_end" },
	{ BOARD,	"board"	},
	{ PCIINFO,	"pciinfo" },
	{ LINE,		"line" },
	{ CONC,		"conc" },
	{ CONC,		"concentrator" },
	{ CX,		"cx" },
	{ CX,		"ccon" },
	{ EPC,		"epccon" },
	{ EPC,		"epc" },
	{ MOD,		"module" },
	{ ID,		"id" },
	{ STARTO,	"start" },
	{ SPEED,	"speed"	},
	{ CABLE,	"cable"	},
	{ CONNECT,	"connect" },
	{ METHOD,	"method" },
	{ STATUS,	"status" },
	{ CUSTOM,	"Custom" },
	{ BASIC,	"Basic"	},
	{ MEM,		"mem" },
	{ MEM,		"memory" },
	{ PORTS,	"ports"	},
	{ MODEM,	"modem"	},
	{ NPORTS,	"nports" },
	{ TTYN,		"ttyname" },
	{ CU,		"cuname" },
	{ PRINT,	"prname" },
	{ CMAJOR,	"major"	 },
	{ ALTPIN,	"altpin" },
	{ USEINTR,	"useintr" },
	{ TTSIZ,	"ttysize" },
	{ CHSIZ,	"chsize" },
	{ BSSIZ,	"boardsize" },
	{ UNTSIZ,	"schedsize" },
	{ F2SIZ,	"f2200size" },
	{ VPSIZ,	"vpixsize" },
	{ 0,		NULL }
};

/*
 * get a word from the input stream, also keep track of current line number.
 * words are separated by whitespace.
 */
static char *dgap_getword(char **in)
{
	char *ret_ptr = *in;

	char *ptr = strpbrk(*in, " \t\n");

	/* If no word found, return null */
	if (!ptr)
		return NULL;

	/* Mark new location for our buffer */
	*ptr = '\0';
	*in = ptr + 1;

	/* Eat any extra spaces/tabs/newlines that might be present */
	while (*in && **in && ((**in == ' ') ||
			       (**in == '\t') ||
			       (**in == '\n'))) {
		**in = '\0';
		*in = *in + 1;
	}

	return ret_ptr;
}


/*
 * Get a token from the input file; return 0 if end of file is reached
 */
static int dgap_gettok(char **in)
{
	char *w;
	struct toklist *t;

	if (strstr(dgap_cword, "board")) {
		w = dgap_getword(in);
		if (!w)
			return 0;
		snprintf(dgap_cword, MAXCWORD, "%s", w);
		for (t = dgap_brdtype; t->token != 0; t++) {
			if (!strcmp(w, t->string))
				return t->token;
		}
	} else {
		while ((w = dgap_getword(in))) {
			snprintf(dgap_cword, MAXCWORD, "%s", w);
			for (t = dgap_tlist; t->token != 0; t++) {
				if (!strcmp(w, t->string))
					return t->token;
			}
		}
	}

	return 0;
}

/*
 * dgap_checknode: see if all the necessary info has been supplied for a node
 * before creating the next node.
 */
static int dgap_checknode(struct cnode *p)
{
	switch (p->type) {
	case LNODE:
		if (p->u.line.v_speed == 0) {
			pr_err("line speed not specified");
			return 1;
		}
		return 0;

	case CNODE:
		if (p->u.conc.v_speed == 0) {
			pr_err("concentrator line speed not specified");
			return 1;
		}
		if (p->u.conc.v_nport == 0) {
			pr_err("number of ports on concentrator not specified");
			return 1;
		}
		if (p->u.conc.v_id == 0) {
			pr_err("concentrator id letter not specified");
			return 1;
		}
		return 0;

	case MNODE:
		if (p->u.module.v_nport == 0) {
			pr_err("number of ports on EBI module not specified");
			return 1;
		}
		if (p->u.module.v_id == 0) {
			pr_err("EBI module id letter not specified");
			return 1;
		}
		return 0;
	}
	return 0;
}

/*
 * Given a board pointer, returns whether we should use interrupts or not.
 */
static uint dgap_config_get_useintr(struct board_t *bd)
{
	struct cnode *p;

	if (!bd)
		return 0;

	for (p = bd->bd_config; p; p = p->next) {
		if (p->type == INTRNODE) {
			/*
			 * check for pcxr types.
			 */
			return p->u.useintr;
		}
	}

	/* If not found, then don't turn on interrupts. */
	return 0;
}

/*
 * Given a board pointer, returns whether we turn on altpin or not.
 */
static uint dgap_config_get_altpin(struct board_t *bd)
{
	struct cnode *p;

	if (!bd)
		return 0;

	for (p = bd->bd_config; p; p = p->next) {
		if (p->type == ANODE) {
			/*
			 * check for pcxr types.
			 */
			return p->u.altpin;
		}
	}

	/* If not found, then don't turn on interrupts. */
	return 0;
}

/*
 * Given a specific type of board, if found, detached link and
 * returns the first occurrence in the list.
 */
static struct cnode *dgap_find_config(int type, int bus, int slot)
{
	struct cnode *p, *prev, *prev2, *found;

	p = &dgap_head;

	while (p->next) {
		prev = p;
		p = p->next;

		if (p->type != BNODE)
			continue;

		if (p->u.board.type != type)
			continue;

		if (p->u.board.v_pcibus &&
		    p->u.board.pcibus != bus)
			continue;

		if (p->u.board.v_pcislot &&
		    p->u.board.pcislot != slot)
			continue;

		found = p;
		/*
		 * Keep walking thru the list till we
		 * find the next board.
		 */
		while (p->next) {
			prev2 = p;
			p = p->next;

			if (p->type != BNODE)
				continue;

			/*
			 * Mark the end of our 1 board
			 * chain of configs.
			 */
			prev2->next = NULL;

			/*
			 * Link the "next" board to the
			 * previous board, effectively
			 * "unlinking" our board from
			 * the main config.
			 */
			prev->next = p;

			return found;
		}
		/*
		 * It must be the last board in the list.
		 */
		prev->next = NULL;
		return found;
	}
	return NULL;
}

/*
 * Given a board pointer, walks the config link, counting up
 * all ports user specified should be on the board.
 * (This does NOT mean they are all actually present right now tho)
 */
static uint dgap_config_get_num_prts(struct board_t *bd)
{
	int count = 0;
	struct cnode *p;

	if (!bd)
		return 0;

	for (p = bd->bd_config; p; p = p->next) {
		switch (p->type) {
		case BNODE:
			/*
			 * check for pcxr types.
			 */
			if (p->u.board.type > EPCFE)
				count += p->u.board.nport;
			break;
		case CNODE:
			count += p->u.conc.nport;
			break;
		case MNODE:
			count += p->u.module.nport;
			break;
		}
	}
	return count;
}

static char *dgap_create_config_string(struct board_t *bd, char *string)
{
	char *ptr = string;
	struct cnode *p;
	struct cnode *q;
	int speed;

	if (!bd) {
		*ptr = 0xff;
		return string;
	}

	for (p = bd->bd_config; p; p = p->next) {
		switch (p->type) {
		case LNODE:
			*ptr = '\0';
			ptr++;
			*ptr = p->u.line.speed;
			ptr++;
			break;
		case CNODE:
			/*
			 * Because the EPC/con concentrators can have EM modules
			 * hanging off of them, we have to walk ahead in the
			 * list and keep adding the number of ports on each EM
			 * to the config. UGH!
			 */
			speed = p->u.conc.speed;
			q = p->next;
			if (q && (q->type == MNODE)) {
				*ptr = (p->u.conc.nport + 0x80);
				ptr++;
				p = q;
				while (q->next && (q->next->type) == MNODE) {
					*ptr = (q->u.module.nport + 0x80);
					ptr++;
					p = q;
					q = q->next;
				}
				*ptr = q->u.module.nport;
				ptr++;
			} else {
				*ptr = p->u.conc.nport;
				ptr++;
			}

			*ptr = speed;
			ptr++;
			break;
		}
	}

	*ptr = 0xff;
	return string;
}

/*
 * Parse a configuration file read into memory as a string.
 */
static int dgap_parsefile(char **in)
{
	struct cnode *p, *brd, *line, *conc;
	int rc;
	char *s;
	int linecnt = 0;

	p = &dgap_head;
	brd = line = conc = NULL;

	/* perhaps we are adding to an existing list? */
	while (p->next)
		p = p->next;

	/* file must start with a BEGIN */
	while ((rc = dgap_gettok(in)) != BEGIN) {
		if (rc == 0) {
			pr_err("unexpected EOF");
			return -1;
		}
	}

	for (; ;) {
		int board_type = 0;
		int conc_type = 0;
		int module_type = 0;

		rc = dgap_gettok(in);
		if (rc == 0) {
			pr_err("unexpected EOF");
			return -1;
		}

		switch (rc) {
		case BEGIN:	/* should only be 1 begin */
			pr_err("unexpected config_begin\n");
			return -1;

		case END:
			return 0;

		case BOARD:	/* board info */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;

			p->type = BNODE;
			p->u.board.status = kstrdup("No", GFP_KERNEL);
			line = conc = NULL;
			brd = p;
			linecnt = -1;

			board_type = dgap_gettok(in);
			if (board_type == 0) {
				pr_err("board !!type not specified");
				return -1;
			}

			p->u.board.type = board_type;

			break;

		case MEM:	/* memory address */
			if (p->type != BNODE) {
				pr_err("memory address only valid for boards");
				return -1;
			}
			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			kfree(p->u.board.addrstr);
			p->u.board.addrstr = kstrdup(s, GFP_KERNEL);
			if (kstrtoul(s, 0, &p->u.board.addr)) {
				pr_err("bad number for memory address");
				return -1;
			}
			p->u.board.v_addr = 1;
			break;

		case PCIINFO:	/* pci information */
			if (p->type != BNODE) {
				pr_err("memory address only valid for boards");
				return -1;
			}
			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			kfree(p->u.board.pcibusstr);
			p->u.board.pcibusstr = kstrdup(s, GFP_KERNEL);
			if (kstrtoul(s, 0, &p->u.board.pcibus)) {
				pr_err("bad number for pci bus");
				return -1;
			}
			p->u.board.v_pcibus = 1;
			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			kfree(p->u.board.pcislotstr);
			p->u.board.pcislotstr = kstrdup(s, GFP_KERNEL);
			if (kstrtoul(s, 0, &p->u.board.pcislot)) {
				pr_err("bad number for pci slot");
				return -1;
			}
			p->u.board.v_pcislot = 1;
			break;

		case METHOD:
			if (p->type != BNODE) {
				pr_err("install method only valid for boards");
				return -1;
			}
			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			kfree(p->u.board.method);
			p->u.board.method = kstrdup(s, GFP_KERNEL);
			p->u.board.v_method = 1;
			break;

		case STATUS:
			if (p->type != BNODE) {
				pr_err("config status only valid for boards");
				return -1;
			}
			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			kfree(p->u.board.status);
			p->u.board.status = kstrdup(s, GFP_KERNEL);
			break;

		case NPORTS:	/* number of ports */
			if (p->type == BNODE) {
				s = dgap_getword(in);
				if (!s) {
					pr_err("unexpected end of file");
					return -1;
				}
				if (kstrtol(s, 0, &p->u.board.nport)) {
					pr_err("bad number for number of ports");
					return -1;
				}
				p->u.board.v_nport = 1;
			} else if (p->type == CNODE) {
				s = dgap_getword(in);
				if (!s) {
					pr_err("unexpected end of file");
					return -1;
				}
				if (kstrtol(s, 0, &p->u.conc.nport)) {
					pr_err("bad number for number of ports");
					return -1;
				}
				p->u.conc.v_nport = 1;
			} else if (p->type == MNODE) {
				s = dgap_getword(in);
				if (!s) {
					pr_err("unexpected end of file");
					return -1;
				}
				if (kstrtol(s, 0, &p->u.module.nport)) {
					pr_err("bad number for number of ports");
					return -1;
				}
				p->u.module.v_nport = 1;
			} else {
				pr_err("nports only valid for concentrators or modules");
				return -1;
			}
			break;

		case ID:	/* letter ID used in tty name */
			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			kfree(p->u.board.status);
			p->u.board.status = kstrdup(s, GFP_KERNEL);

			if (p->type == CNODE) {
				kfree(p->u.conc.id);
				p->u.conc.id = kstrdup(s, GFP_KERNEL);
				p->u.conc.v_id = 1;
			} else if (p->type == MNODE) {
				kfree(p->u.module.id);
				p->u.module.id = kstrdup(s, GFP_KERNEL);
				p->u.module.v_id = 1;
			} else {
				pr_err("id only valid for concentrators or modules");
				return -1;
			}
			break;

		case STARTO:	/* start offset of ID */
			if (p->type == BNODE) {
				s = dgap_getword(in);
				if (!s) {
					pr_err("unexpected end of file");
					return -1;
				}
				if (kstrtol(s, 0, &p->u.board.start)) {
					pr_err("bad number for start of tty count");
					return -1;
				}
				p->u.board.v_start = 1;
			} else if (p->type == CNODE) {
				s = dgap_getword(in);
				if (!s) {
					pr_err("unexpected end of file");
					return -1;
				}
				if (kstrtol(s, 0, &p->u.conc.start)) {
					pr_err("bad number for start of tty count");
					return -1;
				}
				p->u.conc.v_start = 1;
			} else if (p->type == MNODE) {
				s = dgap_getword(in);
				if (!s) {
					pr_err("unexpected end of file");
					return -1;
				}
				if (kstrtol(s, 0, &p->u.module.start)) {
					pr_err("bad number for start of tty count");
					return -1;
				}
				p->u.module.v_start = 1;
			} else {
				pr_err("start only valid for concentrators or modules");
				return -1;
			}
			break;

		case TTYN:	/* tty name prefix */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = TNODE;

			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpeced end of file");
				return -1;
			}
			p->u.ttyname = kstrdup(s, GFP_KERNEL);
			if (!p->u.ttyname)
				return -1;

			break;

		case CU:	/* cu name prefix */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = CUNODE;

			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpeced end of file");
				return -1;
			}
			p->u.cuname = kstrdup(s, GFP_KERNEL);
			if (!p->u.cuname)
				return -1;

			break;

		case LINE:	/* line information */
			if (dgap_checknode(p))
				return -1;
			if (!brd) {
				pr_err("must specify board before line info");
				return -1;
			}
			switch (brd->u.board.type) {
			case PPCM:
				pr_err("line not valid for PC/em");
				return -1;
			}

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = LNODE;
			conc = NULL;
			line = p;
			linecnt++;
			break;

		case CONC:	/* concentrator information */
			if (dgap_checknode(p))
				return -1;
			if (!line) {
				pr_err("must specify line info before concentrator");
				return -1;
			}

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = CNODE;
			conc = p;

			if (linecnt)
				brd->u.board.conc2++;
			else
				brd->u.board.conc1++;

			conc_type = dgap_gettok(in);
			if (conc_type == 0 ||
			    (conc_type != CX && conc_type != EPC)) {
				pr_err("failed to set a type of concentratros");
				return -1;
			}

			p->u.conc.type = conc_type;

			break;

		case MOD:	/* EBI module */
			if (dgap_checknode(p))
				return -1;
			if (!brd) {
				pr_err("must specify board info before EBI modules");
				return -1;
			}
			switch (brd->u.board.type) {
			case PPCM:
				linecnt = 0;
				break;
			default:
				if (!conc) {
					pr_err("must specify concentrator info before EBI module");
					return -1;
				}
			}

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = MNODE;

			if (linecnt)
				brd->u.board.module2++;
			else
				brd->u.board.module1++;

			module_type = dgap_gettok(in);
			if (module_type == 0 ||
			    (module_type != PORTS && module_type != MODEM)) {
				pr_err("failed to set a type of module");
				return -1;
			}

			p->u.module.type = module_type;

			break;

		case CABLE:
			if (p->type == LNODE) {
				s = dgap_getword(in);
				if (!s) {
					pr_err("unexpected end of file");
					return -1;
				}
				kfree(p->u.line.cable);
				p->u.line.cable = kstrdup(s, GFP_KERNEL);
				p->u.line.v_cable = 1;
			}
			break;

		case SPEED:	/* sync line speed indication */
			if (p->type == LNODE) {
				s = dgap_getword(in);
				if (!s) {
					pr_err("unexpected end of file");
					return -1;
				}
				if (kstrtol(s, 0, &p->u.line.speed)) {
					pr_err("bad number for line speed");
					return -1;
				}
				p->u.line.v_speed = 1;
			} else if (p->type == CNODE) {
				s = dgap_getword(in);
				if (!s) {
					pr_err("unexpected end of file");
					return -1;
				}
				if (kstrtol(s, 0, &p->u.conc.speed)) {
					pr_err("bad number for line speed");
					return -1;
				}
				p->u.conc.v_speed = 1;
			} else {
				pr_err("speed valid only for lines or concentrators.");
				return -1;
			}
			break;

		case CONNECT:
			if (p->type == CNODE) {
				s = dgap_getword(in);
				if (!s) {
					pr_err("unexpected end of file");
					return -1;
				}
				kfree(p->u.conc.connect);
				p->u.conc.connect = kstrdup(s, GFP_KERNEL);
				p->u.conc.v_connect = 1;
			}
			break;
		case PRINT:	/* transparent print name prefix */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = PNODE;

			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpeced end of file");
				return -1;
			}
			p->u.printname = kstrdup(s, GFP_KERNEL);
			if (!p->u.printname)
				return -1;

			break;

		case CMAJOR:	/* major number */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = JNODE;

			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			if (kstrtol(s, 0, &p->u.majornumber)) {
				pr_err("bad number for major number");
				return -1;
			}
			break;

		case ALTPIN:	/* altpin setting */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = ANODE;

			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			if (kstrtol(s, 0, &p->u.altpin)) {
				pr_err("bad number for altpin");
				return -1;
			}
			break;

		case USEINTR:		/* enable interrupt setting */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = INTRNODE;
			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			if (kstrtol(s, 0, &p->u.useintr)) {
				pr_err("bad number for useintr");
				return -1;
			}
			break;

		case TTSIZ:	/* size of tty structure */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = TSNODE;

			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			if (kstrtol(s, 0, &p->u.ttysize)) {
				pr_err("bad number for ttysize");
				return -1;
			}
			break;

		case CHSIZ:	/* channel structure size */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = CSNODE;

			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			if (kstrtol(s, 0, &p->u.chsize)) {
				pr_err("bad number for chsize");
				return -1;
			}
			break;

		case BSSIZ:	/* board structure size */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = BSNODE;

			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			if (kstrtol(s, 0, &p->u.bssize)) {
				pr_err("bad number for bssize");
				return -1;
			}
			break;

		case UNTSIZ:	/* sched structure size */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = USNODE;

			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			if (kstrtol(s, 0, &p->u.unsize)) {
				pr_err("bad number for schedsize");
				return -1;
			}
			break;

		case F2SIZ:	/* f2200 structure size */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = FSNODE;

			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			if (kstrtol(s, 0, &p->u.f2size)) {
				pr_err("bad number for f2200size");
				return -1;
			}
			break;

		case VPSIZ:	/* vpix structure size */
			if (dgap_checknode(p))
				return -1;

			p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
			if (!p->next)
				return -ENOMEM;

			p = p->next;
			p->type = VSNODE;

			s = dgap_getword(in);
			if (!s) {
				pr_err("unexpected end of file");
				return -1;
			}
			if (kstrtol(s, 0, &p->u.vpixsize)) {
				pr_err("bad number for vpixsize");
				return -1;
			}
			break;
		}
	}
}

static void dgap_cleanup_nodes(void)
{
	struct cnode *p;

	p = &dgap_head;

	while (p) {
		struct cnode *tmp = p->next;

		if (p->type == NULLNODE) {
			p = tmp;
			continue;
		}

		switch (p->type) {
		case BNODE:
			kfree(p->u.board.addrstr);
			kfree(p->u.board.pcibusstr);
			kfree(p->u.board.pcislotstr);
			kfree(p->u.board.method);
			break;
		case CNODE:
			kfree(p->u.conc.id);
			kfree(p->u.conc.connect);
			break;
		case MNODE:
			kfree(p->u.module.id);
			break;
		case TNODE:
			kfree(p->u.ttyname);
			break;
		case CUNODE:
			kfree(p->u.cuname);
			break;
		case LNODE:
			kfree(p->u.line.cable);
			break;
		case PNODE:
			kfree(p->u.printname);
			break;
		}

		kfree(p->u.board.status);
		kfree(p);
		p = tmp;
	}
}

/*
 * Retrives the current custom baud rate from FEP memory,
 * and returns it back to the user.
 * Returns 0 on error.
 */
static uint dgap_get_custom_baud(struct channel_t *ch)
{
	u8 __iomem *vaddr;
	ulong offset;

	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;

	if (!ch->ch_bd || ch->ch_bd->magic != DGAP_BOARD_MAGIC)
		return 0;

	if (!(ch->ch_bd->bd_flags & BD_FEP5PLUS))
		return 0;

	vaddr = ch->ch_bd->re_map_membase;

	if (!vaddr)
		return 0;

	/*
	 * Go get from fep mem, what the fep
	 * believes the custom baud rate is.
	 */
	offset = (ioread16(vaddr + ECS_SEG) << 4) + (ch->ch_portnum * 0x28)
	       + LINE_SPEED;

	return readw(vaddr + offset);
}

/*
 * Remap PCI memory.
 */
static int dgap_remap(struct board_t *brd)
{
	if (!brd || brd->magic != DGAP_BOARD_MAGIC)
		return -EIO;

	if (!request_mem_region(brd->membase, 0x200000, "dgap"))
		return -ENOMEM;

	if (!request_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000, "dgap"))
		goto err_req_mem;

	brd->re_map_membase = ioremap(brd->membase, 0x200000);
	if (!brd->re_map_membase)
		goto err_remap_mem;

	brd->re_map_port = ioremap((brd->membase + PCI_IO_OFFSET), 0x200000);
	if (!brd->re_map_port)
		goto err_remap_port;

	return 0;

err_remap_port:
	iounmap(brd->re_map_membase);
err_remap_mem:
	release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000);
err_req_mem:
	release_mem_region(brd->membase, 0x200000);

	return -ENOMEM;
}

static void dgap_unmap(struct board_t *brd)
{
	iounmap(brd->re_map_port);
	iounmap(brd->re_map_membase);
	release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000);
	release_mem_region(brd->membase, 0x200000);
}

/*
 * dgap_parity_scan()
 *
 * Convert the FEP5 way of reporting parity errors and breaks into
 * the Linux line discipline way.
 */
static void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf,
			     unsigned char *fbuf, int *len)
{
	int l = *len;
	int count = 0;
	unsigned char *in, *cout, *fout;
	unsigned char c;

	in = cbuf;
	cout = cbuf;
	fout = fbuf;

	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	while (l--) {
		c = *in++;
		switch (ch->pscan_state) {
		default:
			/* reset to sanity and fall through */
			ch->pscan_state = 0;

		case 0:
			/* No FF seen yet */
			if (c == (unsigned char)'\377')
				/* delete this character from stream */
				ch->pscan_state = 1;
			else {
				*cout++ = c;
				*fout++ = TTY_NORMAL;
				count += 1;
			}
			break;

		case 1:
			/* first FF seen */
			if (c == (unsigned char)'\377') {
				/* doubled ff, transform to single ff */
				*cout++ = c;
				*fout++ = TTY_NORMAL;
				count += 1;
				ch->pscan_state = 0;
			} else {
				/* save value examination in next state */
				ch->pscan_savechar = c;
				ch->pscan_state = 2;
			}
			break;

		case 2:
			/* third character of ff sequence */

			*cout++ = c;

			if (ch->pscan_savechar == 0x0) {
				if (c == 0x0) {
					ch->ch_err_break++;
					*fout++ = TTY_BREAK;
				} else {
					ch->ch_err_parity++;
					*fout++ = TTY_PARITY;
				}
			}

			count += 1;
			ch->pscan_state = 0;
		}
	}
	*len = count;
}

/*=======================================================================
 *
 *      dgap_input - Process received data.
 *
 *              ch      - Pointer to channel structure.
 *
 *=======================================================================*/

static void dgap_input(struct channel_t *ch)
{
	struct board_t *bd;
	struct bs_t __iomem *bs;
	struct tty_struct *tp;
	struct tty_ldisc *ld;
	uint rmask;
	uint head;
	uint tail;
	int data_len;
	ulong lock_flags;
	ulong lock_flags2;
	int flip_len;
	int len;
	int n;
	u8 *buf;
	u8 tmpchar;
	int s;

	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	tp = ch->ch_tun.un_tty;

	bs  = ch->ch_bs;
	if (!bs)
		return;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	/*
	 *      Figure the number of characters in the buffer.
	 *      Exit immediately if none.
	 */

	rmask = ch->ch_rsize - 1;

	head = readw(&bs->rx_head);
	head &= rmask;
	tail = readw(&bs->rx_tail);
	tail &= rmask;

	data_len = (head - tail) & rmask;

	if (data_len == 0) {
		writeb(1, &bs->idata);
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return;
	}

	/*
	 * If the device is not open, or CREAD is off, flush
	 * input data and return immediately.
	 */
	if ((bd->state != BOARD_READY) || !tp  ||
	    (tp->magic != TTY_MAGIC) ||
	    !(ch->ch_tun.un_flags & UN_ISOPEN) ||
	    !(tp->termios.c_cflag & CREAD) ||
	    (ch->ch_tun.un_flags & UN_CLOSING)) {
		writew(head, &bs->rx_tail);
		writeb(1, &bs->idata);
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return;
	}

	/*
	 * If we are throttled, simply don't read any data.
	 */
	if (ch->ch_flags & CH_RXBLOCK) {
		writeb(1, &bs->idata);
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return;
	}

	/*
	 *      Ignore oruns.
	 */
	tmpchar = readb(&bs->orun);
	if (tmpchar) {
		ch->ch_err_overrun++;
		writeb(0, &bs->orun);
	}

	/* Decide how much data we can send into the tty layer */
	flip_len = TTY_FLIPBUF_SIZE;

	/* Chop down the length, if needed */
	len = min(data_len, flip_len);
	len = min(len, (N_TTY_BUF_SIZE - 1));

	ld = tty_ldisc_ref(tp);

#ifdef TTY_DONT_FLIP
	/*
	 * If the DONT_FLIP flag is on, don't flush our buffer, and act
	 * like the ld doesn't have any space to put the data right now.
	 */
	if (test_bit(TTY_DONT_FLIP, &tp->flags))
		len = 0;
#endif

	/*
	 * If we were unable to get a reference to the ld,
	 * don't flush our buffer, and act like the ld doesn't
	 * have any space to put the data right now.
	 */
	if (!ld) {
		len = 0;
	} else {
		/*
		 * If ld doesn't have a pointer to a receive_buf function,
		 * flush the data, then act like the ld doesn't have any
		 * space to put the data right now.
		 */
		if (!ld->ops->receive_buf) {
			writew(head, &bs->rx_tail);
			len = 0;
		}
	}

	if (len <= 0) {
		writeb(1, &bs->idata);
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		if (ld)
			tty_ldisc_deref(ld);
		return;
	}

	buf = ch->ch_bd->flipbuf;
	n = len;

	/*
	 * n now contains the most amount of data we can copy,
	 * bounded either by our buffer size or the amount
	 * of data the card actually has pending...
	 */
	while (n) {
		s = ((head >= tail) ? head : ch->ch_rsize) - tail;
		s = min(s, n);

		if (s <= 0)
			break;

		memcpy_fromio(buf, ch->ch_raddr + tail, s);

		tail += s;
		buf += s;

		n -= s;
		/* Flip queue if needed */
		tail &= rmask;
	}

	writew(tail, &bs->rx_tail);
	writeb(1, &bs->idata);
	ch->ch_rxcount += len;

	/*
	 * If we are completely raw, we don't need to go through a lot
	 * of the tty layers that exist.
	 * In this case, we take the shortest and fastest route we
	 * can to relay the data to the user.
	 *
	 * On the other hand, if we are not raw, we need to go through
	 * the tty layer, which has its API more well defined.
	 */
	if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) {
		dgap_parity_scan(ch, ch->ch_bd->flipbuf,
				 ch->ch_bd->flipflagbuf, &len);

		len = tty_buffer_request_room(tp->port, len);
		tty_insert_flip_string_flags(tp->port, ch->ch_bd->flipbuf,
					     ch->ch_bd->flipflagbuf, len);
	} else {
		len = tty_buffer_request_room(tp->port, len);
		tty_insert_flip_string(tp->port, ch->ch_bd->flipbuf, len);
	}

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

	/* Tell the tty layer its okay to "eat" the data now */
	tty_flip_buffer_push(tp->port);

	if (ld)
		tty_ldisc_deref(ld);
}

static void dgap_write_wakeup(struct board_t *bd, struct channel_t *ch,
			      struct un_t *un, u32 mask,
			      unsigned long *irq_flags1,
			      unsigned long *irq_flags2)
{
	if (!(un->un_flags & mask))
		return;

	un->un_flags &= ~mask;

	if (!(un->un_flags & UN_ISOPEN))
		return;

	if ((un->un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
	    un->un_tty->ldisc->ops->write_wakeup) {
		spin_unlock_irqrestore(&ch->ch_lock, *irq_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, *irq_flags1);

		(un->un_tty->ldisc->ops->write_wakeup)(un->un_tty);

		spin_lock_irqsave(&bd->bd_lock, *irq_flags1);
		spin_lock_irqsave(&ch->ch_lock, *irq_flags2);
	}
	wake_up_interruptible(&un->un_tty->write_wait);
	wake_up_interruptible(&un->un_flags_wait);
}

/************************************************************************
 * Determines when CARRIER changes state and takes appropriate
 * action.
 ************************************************************************/
static void dgap_carrier(struct channel_t *ch)
{
	struct board_t *bd;

	int virt_carrier = 0;
	int phys_carrier = 0;

	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	bd = ch->ch_bd;

	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return;

	/* Make sure altpin is always set correctly */
	if (ch->ch_digi.digi_flags & DIGI_ALTPIN) {
		ch->ch_dsr      = DM_CD;
		ch->ch_cd       = DM_DSR;
	} else {
		ch->ch_dsr      = DM_DSR;
		ch->ch_cd       = DM_CD;
	}

	if (ch->ch_mistat & D_CD(ch))
		phys_carrier = 1;

	if (ch->ch_digi.digi_flags & DIGI_FORCEDCD)
		virt_carrier = 1;

	if (ch->ch_c_cflag & CLOCAL)
		virt_carrier = 1;

	/*
	 * Test for a VIRTUAL carrier transition to HIGH.
	 */
	if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) {
		/*
		 * When carrier rises, wake any threads waiting
		 * for carrier in the open routine.
		 */

		if (waitqueue_active(&(ch->ch_flags_wait)))
			wake_up_interruptible(&ch->ch_flags_wait);
	}

	/*
	 * Test for a PHYSICAL carrier transition to HIGH.
	 */
	if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) {
		/*
		 * When carrier rises, wake any threads waiting
		 * for carrier in the open routine.
		 */

		if (waitqueue_active(&(ch->ch_flags_wait)))
			wake_up_interruptible(&ch->ch_flags_wait);
	}

	/*
	 *  Test for a PHYSICAL transition to low, so long as we aren't
	 *  currently ignoring physical transitions (which is what "virtual
	 *  carrier" indicates).
	 *
	 *  The transition of the virtual carrier to low really doesn't
	 *  matter... it really only means "ignore carrier state", not
	 *  "make pretend that carrier is there".
	 */
	if ((virt_carrier == 0) &&
	    ((ch->ch_flags & CH_CD) != 0) &&
	    (phys_carrier == 0)) {
		/*
		 *   When carrier drops:
		 *
		 *   Drop carrier on all open units.
		 *
		 *   Flush queues, waking up any task waiting in the
		 *   line discipline.
		 *
		 *   Send a hangup to the control terminal.
		 *
		 *   Enable all select calls.
		 */
		if (waitqueue_active(&(ch->ch_flags_wait)))
			wake_up_interruptible(&ch->ch_flags_wait);

		if (ch->ch_tun.un_open_count > 0)
			tty_hangup(ch->ch_tun.un_tty);

		if (ch->ch_pun.un_open_count > 0)
			tty_hangup(ch->ch_pun.un_tty);
	}

	/*
	 *  Make sure that our cached values reflect the current reality.
	 */
	if (virt_carrier == 1)
		ch->ch_flags |= CH_FCAR;
	else
		ch->ch_flags &= ~CH_FCAR;

	if (phys_carrier == 1)
		ch->ch_flags |= CH_CD;
	else
		ch->ch_flags &= ~CH_CD;
}

/*=======================================================================
 *
 *      dgap_event - FEP to host event processing routine.
 *
 *              bd     - Board of current event.
 *
 *=======================================================================*/
static int dgap_event(struct board_t *bd)
{
	struct channel_t *ch;
	ulong lock_flags;
	ulong lock_flags2;
	struct bs_t __iomem *bs;
	u8 __iomem *event;
	u8 __iomem *vaddr;
	struct ev_t __iomem *eaddr;
	uint head;
	uint tail;
	int port;
	int reason;
	int modem;

	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return -EIO;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);

	vaddr = bd->re_map_membase;

	if (!vaddr) {
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return -EIO;
	}

	eaddr = (struct ev_t __iomem *)(vaddr + EVBUF);

	/* Get our head and tail */
	head = readw(&eaddr->ev_head);
	tail = readw(&eaddr->ev_tail);

	/*
	 * Forget it if pointers out of range.
	 */

	if (head >= EVMAX - EVSTART || tail >= EVMAX - EVSTART ||
	    (head | tail) & 03) {
		/* Let go of board lock */
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return -EIO;
	}

	/*
	 * Loop to process all the events in the buffer.
	 */
	while (tail != head) {
		/*
		 * Get interrupt information.
		 */

		event = bd->re_map_membase + tail + EVSTART;

		port   = ioread8(event);
		reason = ioread8(event + 1);
		modem  = ioread8(event + 2);
		ioread8(event + 3);

		/*
		 * Make sure the interrupt is valid.
		 */
		if (port >= bd->nasync)
			goto next;

		if (!(reason & (IFMODEM | IFBREAK | IFTLW | IFTEM | IFDATA)))
			goto next;

		ch = bd->channels[port];

		if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
			goto next;

		/*
		 * If we have made it here, the event was valid.
		 * Lock down the channel.
		 */
		spin_lock_irqsave(&ch->ch_lock, lock_flags2);

		bs = ch->ch_bs;

		if (!bs) {
			spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
			goto next;
		}

		/*
		 * Process received data.
		 */
		if (reason & IFDATA) {
			/*
			 * ALL LOCKS *MUST* BE DROPPED BEFORE CALLING INPUT!
			 * input could send some data to ld, which in turn
			 * could do a callback to one of our other functions.
			 */
			spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

			dgap_input(ch);

			spin_lock_irqsave(&bd->bd_lock, lock_flags);
			spin_lock_irqsave(&ch->ch_lock, lock_flags2);

			if (ch->ch_flags & CH_RACTIVE)
				ch->ch_flags |= CH_RENABLE;
			else
				writeb(1, &bs->idata);

			if (ch->ch_flags & CH_RWAIT) {
				ch->ch_flags &= ~CH_RWAIT;

				wake_up_interruptible
					(&ch->ch_tun.un_flags_wait);
			}
		}

		/*
		 * Process Modem change signals.
		 */
		if (reason & IFMODEM) {
			ch->ch_mistat = modem;
			dgap_carrier(ch);
		}

		/*
		 * Process break.
		 */
		if (reason & IFBREAK) {
			if (ch->ch_tun.un_tty) {
				/* A break has been indicated */
				ch->ch_err_break++;
				tty_buffer_request_room
					(ch->ch_tun.un_tty->port, 1);
				tty_insert_flip_char(ch->ch_tun.un_tty->port,
						     0, TTY_BREAK);
				tty_flip_buffer_push(ch->ch_tun.un_tty->port);
			}
		}

		/*
		 * Process Transmit low.
		 */
		if (reason & IFTLW) {
			dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_LOW,
					  &lock_flags, &lock_flags2);
			dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_LOW,
					  &lock_flags, &lock_flags2);
			if (ch->ch_flags & CH_WLOW) {
				ch->ch_flags &= ~CH_WLOW;
				wake_up_interruptible(&ch->ch_flags_wait);
			}
		}

		/*
		 * Process Transmit empty.
		 */
		if (reason & IFTEM) {
			dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_EMPTY,
					  &lock_flags, &lock_flags2);
			dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_EMPTY,
					  &lock_flags, &lock_flags2);
			if (ch->ch_flags & CH_WEMPTY) {
				ch->ch_flags &= ~CH_WEMPTY;
				wake_up_interruptible(&ch->ch_flags_wait);
			}
		}

		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);

next:
		tail = (tail + 4) & (EVMAX - EVSTART - 4);
	}

	writew(tail, &eaddr->ev_tail);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

	return 0;
}

/*
 * Our board poller function.
 */
static void dgap_poll_tasklet(unsigned long data)
{
	struct board_t *bd = (struct board_t *)data;
	ulong lock_flags;
	char __iomem *vaddr;
	u16 head, tail;

	if (!bd || (bd->magic != DGAP_BOARD_MAGIC))
		return;

	if (bd->inhibit_poller)
		return;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);

	vaddr = bd->re_map_membase;

	/*
	 * If board is ready, parse deeper to see if there is anything to do.
	 */
	if (bd->state == BOARD_READY) {
		struct ev_t __iomem *eaddr;

		if (!bd->re_map_membase) {
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
			return;
		}
		if (!bd->re_map_port) {
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
			return;
		}

		if (!bd->nasync)
			goto out;

		eaddr = (struct ev_t __iomem *)(vaddr + EVBUF);

		/* Get our head and tail */
		head = readw(&eaddr->ev_head);
		tail = readw(&eaddr->ev_tail);

		/*
		 * If there is an event pending. Go service it.
		 */
		if (head != tail) {
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
			dgap_event(bd);
			spin_lock_irqsave(&bd->bd_lock, lock_flags);
		}

out:
		/*
		 * If board is doing interrupts, ACK the interrupt.
		 */
		if (bd->intr_running)
			readb(bd->re_map_port + 2);

		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return;
	}

	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
}

/*
 * dgap_found_board()
 *
 * A board has been found, init it.
 */
static struct board_t *dgap_found_board(struct pci_dev *pdev, int id,
					int boardnum)
{
	struct board_t *brd;
	unsigned int pci_irq;
	int i;
	int ret;

	/* get the board structure and prep it */
	brd = kzalloc(sizeof(struct board_t), GFP_KERNEL);
	if (!brd)
		return ERR_PTR(-ENOMEM);

	/* store the info for the board we've found */
	brd->magic = DGAP_BOARD_MAGIC;
	brd->boardnum = boardnum;
	brd->vendor = dgap_pci_tbl[id].vendor;
	brd->device = dgap_pci_tbl[id].device;
	brd->pdev = pdev;
	brd->pci_bus = pdev->bus->number;
	brd->pci_slot = PCI_SLOT(pdev->devfn);
	brd->name = dgap_ids[id].name;
	brd->maxports = dgap_ids[id].maxports;
	brd->type = dgap_ids[id].config_type;
	brd->dpatype = dgap_ids[id].dpatype;
	brd->dpastatus = BD_NOFEP;
	init_waitqueue_head(&brd->state_wait);

	spin_lock_init(&brd->bd_lock);

	brd->inhibit_poller	= FALSE;
	brd->wait_for_bios	= 0;
	brd->wait_for_fep	= 0;

	for (i = 0; i < MAXPORTS; i++)
		brd->channels[i] = NULL;

	/* store which card & revision we have */
	pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &brd->subvendor);
	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &brd->subdevice);
	pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev);

	pci_irq = pdev->irq;
	brd->irq = pci_irq;

	/* get the PCI Base Address Registers */

	/* Xr Jupiter and EPC use BAR 2 */
	if (brd->device == PCI_DEV_XRJ_DID || brd->device == PCI_DEV_EPCJ_DID) {
		brd->membase     = pci_resource_start(pdev, 2);
		brd->membase_end = pci_resource_end(pdev, 2);
	}
	/* Everyone else uses BAR 0 */
	else {
		brd->membase     = pci_resource_start(pdev, 0);
		brd->membase_end = pci_resource_end(pdev, 0);
	}

	if (!brd->membase) {
		ret = -ENODEV;
		goto free_brd;
	}

	if (brd->membase & 1)
		brd->membase &= ~3;
	else
		brd->membase &= ~15;

	/*
	 * On the PCI boards, there is no IO space allocated
	 * The I/O registers will be in the first 3 bytes of the
	 * upper 2MB of the 4MB memory space.  The board memory
	 * will be mapped into the low 2MB of the 4MB memory space
	 */
	brd->port = brd->membase + PCI_IO_OFFSET;
	brd->port_end = brd->port + PCI_IO_SIZE_DGAP;

	/*
	 * Special initialization for non-PLX boards
	 */
	if (brd->device != PCI_DEV_XRJ_DID && brd->device != PCI_DEV_EPCJ_DID) {
		unsigned short cmd;

		pci_write_config_byte(pdev, 0x40, 0);
		pci_write_config_byte(pdev, 0x46, 0);

		/* Limit burst length to 2 doubleword transactions */
		pci_write_config_byte(pdev, 0x42, 1);

		/*
		 * Enable IO and mem if not already done.
		 * This was needed for support on Itanium.
		 */
		pci_read_config_word(pdev, PCI_COMMAND, &cmd);
		cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
		pci_write_config_word(pdev, PCI_COMMAND, cmd);
	}

	/* init our poll helper tasklet */
	tasklet_init(&brd->helper_tasklet, dgap_poll_tasklet,
		     (unsigned long)brd);

	ret = dgap_remap(brd);
	if (ret)
		goto free_brd;

	pr_info("dgap: board %d: %s (rev %d), irq %ld\n",
		boardnum, brd->name, brd->rev, brd->irq);

	return brd;

free_brd:
	kfree(brd);

	return ERR_PTR(ret);
}

/*
 * dgap_intr()
 *
 * Driver interrupt handler.
 */
static irqreturn_t dgap_intr(int irq, void *voidbrd)
{
	struct board_t *brd = voidbrd;

	if (!brd)
		return IRQ_NONE;

	/*
	 * Check to make sure its for us.
	 */
	if (brd->magic != DGAP_BOARD_MAGIC)
		return IRQ_NONE;

	brd->intr_count++;

	/*
	 * Schedule tasklet to run at a better time.
	 */
	tasklet_schedule(&brd->helper_tasklet);
	return IRQ_HANDLED;
}

/*****************************************************************************
*
* Function:
*
*    dgap_poll_handler
*
* Author:
*
*    Scott H Kilau
*
* Parameters:
*
*    dummy -- ignored
*
* Return Values:
*
*    none
*
* Description:
*
*    As each timer expires, it determines (a) whether the "transmit"
*    waiter needs to be woken up, and (b) whether the poller needs to
*    be rescheduled.
*
******************************************************************************/

static void dgap_poll_handler(ulong dummy)
{
	unsigned int i;
	struct board_t *brd;
	unsigned long lock_flags;
	ulong new_time;

	dgap_poll_counter++;

	/*
	 * Do not start the board state machine until
	 * driver tells us its up and running, and has
	 * everything it needs.
	 */
	if (dgap_driver_state != DRIVER_READY)
		goto schedule_poller;

	/*
	 * If we have just 1 board, or the system is not SMP,
	 * then use the typical old style poller.
	 * Otherwise, use our new tasklet based poller, which should
	 * speed things up for multiple boards.
	 */
	if ((dgap_numboards == 1) || (num_online_cpus() <= 1)) {
		for (i = 0; i < dgap_numboards; i++) {
			brd = dgap_board[i];

			if (brd->state == BOARD_FAILED)
				continue;
			if (!brd->intr_running)
				/* Call the real board poller directly */
				dgap_poll_tasklet((unsigned long)brd);
		}
	} else {
		/*
		 * Go thru each board, kicking off a
		 * tasklet for each if needed
		 */
		for (i = 0; i < dgap_numboards; i++) {
			brd = dgap_board[i];

			/*
			 * Attempt to grab the board lock.
			 *
			 * If we can't get it, no big deal, the next poll
			 * will get it. Basically, I just really don't want
			 * to spin in here, because I want to kick off my
			 * tasklets as fast as I can, and then get out the
			 * poller.
			 */
			if (!spin_trylock(&brd->bd_lock))
				continue;

			/*
			 * If board is in a failed state, don't bother
			 *  scheduling a tasklet
			 */
			if (brd->state == BOARD_FAILED) {
				spin_unlock(&brd->bd_lock);
				continue;
			}

			/* Schedule a poll helper task */
			if (!brd->intr_running)
				tasklet_schedule(&brd->helper_tasklet);

			/*
			 * Can't do DGAP_UNLOCK here, as we don't have
			 * lock_flags because we did a trylock above.
			 */
			spin_unlock(&brd->bd_lock);
		}
	}

schedule_poller:

	/*
	 * Schedule ourself back at the nominal wakeup interval.
	 */
	spin_lock_irqsave(&dgap_poll_lock, lock_flags);
	dgap_poll_time +=  dgap_jiffies_from_ms(dgap_poll_tick);

	new_time = dgap_poll_time - jiffies;

	if ((ulong)new_time >= 2 * dgap_poll_tick) {
		dgap_poll_time =
			jiffies +  dgap_jiffies_from_ms(dgap_poll_tick);
	}

	dgap_poll_timer.function = dgap_poll_handler;
	dgap_poll_timer.data = 0;
	dgap_poll_timer.expires = dgap_poll_time;
	spin_unlock_irqrestore(&dgap_poll_lock, lock_flags);

	if (!dgap_poll_stop)
		add_timer(&dgap_poll_timer);
}

/*=======================================================================
 *
 *      dgap_cmdb - Sends a 2 byte command to the FEP.
 *
 *              ch      - Pointer to channel structure.
 *              cmd     - Command to be sent.
 *              byte1   - Integer containing first byte to be sent.
 *              byte2   - Integer containing second byte to be sent.
 *              ncmds   - Wait until ncmds or fewer cmds are left
 *                        in the cmd buffer before returning.
 *
 *=======================================================================*/
static void dgap_cmdb(struct channel_t *ch, u8 cmd, u8 byte1,
		      u8 byte2, uint ncmds)
{
	char __iomem *vaddr;
	struct __iomem cm_t *cm_addr;
	uint count;
	uint n;
	u16 head;
	u16 tail;

	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	/*
	 * Check if board is still alive.
	 */
	if (ch->ch_bd->state == BOARD_FAILED)
		return;

	/*
	 * Make sure the pointers are in range before
	 * writing to the FEP memory.
	 */
	vaddr = ch->ch_bd->re_map_membase;

	if (!vaddr)
		return;

	cm_addr = (struct cm_t __iomem *)(vaddr + CMDBUF);
	head = readw(&cm_addr->cm_head);

	/*
	 * Forget it if pointers out of range.
	 */
	if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
		ch->ch_bd->state = BOARD_FAILED;
		return;
	}

	/*
	 * Put the data in the circular command buffer.
	 */
	writeb(cmd, (vaddr + head + CMDSTART + 0));
	writeb((u8)ch->ch_portnum, (vaddr + head + CMDSTART + 1));
	writeb(byte1, (vaddr + head + CMDSTART + 2));
	writeb(byte2, (vaddr + head + CMDSTART + 3));

	head = (head + 4) & (CMDMAX - CMDSTART - 4);

	writew(head, &cm_addr->cm_head);

	/*
	 * Wait if necessary before updating the head
	 * pointer to limit the number of outstanding
	 * commands to the FEP.   If the time spent waiting
	 * is outlandish, declare the FEP dead.
	 */
	for (count = dgap_count ;;) {
		head = readw(&cm_addr->cm_head);
		tail = readw(&cm_addr->cm_tail);

		n = (head - tail) & (CMDMAX - CMDSTART - 4);

		if (n <= ncmds * sizeof(struct cm_t))
			break;

		if (--count == 0) {
			ch->ch_bd->state = BOARD_FAILED;
			return;
		}
		udelay(10);
	}
}

/*=======================================================================
 *
 *      dgap_cmdw - Sends a 1 word command to the FEP.
 *
 *              ch      - Pointer to channel structure.
 *              cmd     - Command to be sent.
 *              word    - Integer containing word to be sent.
 *              ncmds   - Wait until ncmds or fewer cmds are left
 *                        in the cmd buffer before returning.
 *
 *=======================================================================*/
static void dgap_cmdw(struct channel_t *ch, u8 cmd, u16 word, uint ncmds)
{
	char __iomem *vaddr;
	struct __iomem cm_t *cm_addr;
	uint count;
	uint n;
	u16 head;
	u16 tail;

	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	/*
	 * Check if board is still alive.
	 */
	if (ch->ch_bd->state == BOARD_FAILED)
		return;

	/*
	 * Make sure the pointers are in range before
	 * writing to the FEP memory.
	 */
	vaddr = ch->ch_bd->re_map_membase;
	if (!vaddr)
		return;

	cm_addr = (struct cm_t __iomem *)(vaddr + CMDBUF);
	head = readw(&cm_addr->cm_head);

	/*
	 * Forget it if pointers out of range.
	 */
	if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
		ch->ch_bd->state = BOARD_FAILED;
		return;
	}

	/*
	 * Put the data in the circular command buffer.
	 */
	writeb(cmd, (vaddr + head + CMDSTART + 0));
	writeb((u8)ch->ch_portnum, (vaddr + head + CMDSTART + 1));
	writew((u16)word, (vaddr + head + CMDSTART + 2));

	head = (head + 4) & (CMDMAX - CMDSTART - 4);

	writew(head, &cm_addr->cm_head);

	/*
	 * Wait if necessary before updating the head
	 * pointer to limit the number of outstanding
	 * commands to the FEP.   If the time spent waiting
	 * is outlandish, declare the FEP dead.
	 */
	for (count = dgap_count ;;) {
		head = readw(&cm_addr->cm_head);
		tail = readw(&cm_addr->cm_tail);

		n = (head - tail) & (CMDMAX - CMDSTART - 4);

		if (n <= ncmds * sizeof(struct cm_t))
			break;

		if (--count == 0) {
			ch->ch_bd->state = BOARD_FAILED;
			return;
		}
		udelay(10);
	}
}

/*=======================================================================
 *
 *      dgap_cmdw_ext - Sends a extended word command to the FEP.
 *
 *              ch      - Pointer to channel structure.
 *              cmd     - Command to be sent.
 *              word    - Integer containing word to be sent.
 *              ncmds   - Wait until ncmds or fewer cmds are left
 *                        in the cmd buffer before returning.
 *
 *=======================================================================*/
static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds)
{
	char __iomem *vaddr;
	struct __iomem cm_t *cm_addr;
	uint count;
	uint n;
	u16 head;
	u16 tail;

	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	/*
	 * Check if board is still alive.
	 */
	if (ch->ch_bd->state == BOARD_FAILED)
		return;

	/*
	 * Make sure the pointers are in range before
	 * writing to the FEP memory.
	 */
	vaddr = ch->ch_bd->re_map_membase;
	if (!vaddr)
		return;

	cm_addr = (struct cm_t __iomem *)(vaddr + CMDBUF);
	head = readw(&cm_addr->cm_head);

	/*
	 * Forget it if pointers out of range.
	 */
	if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
		ch->ch_bd->state = BOARD_FAILED;
		return;
	}

	/*
	 * Put the data in the circular command buffer.
	 */

	/* Write an FF to tell the FEP that we want an extended command */
	writeb((u8)0xff, (vaddr + head + CMDSTART + 0));

	writeb((u8)ch->ch_portnum, (vaddr + head + CMDSTART + 1));
	writew((u16)cmd, (vaddr + head + CMDSTART + 2));

	/*
	 * If the second part of the command won't fit,
	 * put it at the beginning of the circular buffer.
	 */
	if (((head + 4) >= ((CMDMAX - CMDSTART)) || (head & 03)))
		writew((u16)word, (vaddr + CMDSTART));
	else
		writew((u16)word, (vaddr + head + CMDSTART + 4));

	head = (head + 8) & (CMDMAX - CMDSTART - 4);

	writew(head, &cm_addr->cm_head);

	/*
	 * Wait if necessary before updating the head
	 * pointer to limit the number of outstanding
	 * commands to the FEP.   If the time spent waiting
	 * is outlandish, declare the FEP dead.
	 */
	for (count = dgap_count ;;) {
		head = readw(&cm_addr->cm_head);
		tail = readw(&cm_addr->cm_tail);

		n = (head - tail) & (CMDMAX - CMDSTART - 4);

		if (n <= ncmds * sizeof(struct cm_t))
			break;

		if (--count == 0) {
			ch->ch_bd->state = BOARD_FAILED;
			return;
		}
		udelay(10);
	}
}

/*=======================================================================
 *
 *      dgap_wmove - Write data to FEP buffer.
 *
 *              ch      - Pointer to channel structure.
 *              buf     - Pointer to characters to be moved.
 *              cnt     - Number of characters to move.
 *
 *=======================================================================*/
static void dgap_wmove(struct channel_t *ch, char *buf, uint cnt)
{
	int n;
	char __iomem *taddr;
	struct bs_t __iomem *bs;
	u16 head;

	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	/*
	 * Check parameters.
	 */
	bs   = ch->ch_bs;
	head = readw(&bs->tx_head);

	/*
	 * If pointers are out of range, just return.
	 */
	if ((cnt > ch->ch_tsize) ||
	    (unsigned)(head - ch->ch_tstart) >= ch->ch_tsize)
		return;

	/*
	 * If the write wraps over the top of the circular buffer,
	 * move the portion up to the wrap point, and reset the
	 * pointers to the bottom.
	 */
	n = ch->ch_tstart + ch->ch_tsize - head;

	if (cnt >= n) {
		cnt -= n;
		taddr = ch->ch_taddr + head;
		memcpy_toio(taddr, buf, n);
		head = ch->ch_tstart;
		buf += n;
	}

	/*
	 * Move rest of data.
	 */
	taddr = ch->ch_taddr + head;
	n = cnt;
	memcpy_toio(taddr, buf, n);
	head += cnt;

	writew(head, &bs->tx_head);
}

/*
 * Calls the firmware to reset this channel.
 */
static void dgap_firmware_reset_port(struct channel_t *ch)
{
	dgap_cmdb(ch, CHRESET, 0, 0, 0);

	/*
	 * Now that the channel is reset, we need to make sure
	 * all the current settings get reapplied to the port
	 * in the firmware.
	 *
	 * So we will set the driver's cache of firmware
	 * settings all to 0, and then call param.
	 */
	ch->ch_fepiflag = 0;
	ch->ch_fepcflag = 0;
	ch->ch_fepoflag = 0;
	ch->ch_fepstartc = 0;
	ch->ch_fepstopc = 0;
	ch->ch_fepastartc = 0;
	ch->ch_fepastopc = 0;
	ch->ch_mostat = 0;
	ch->ch_hflow = 0;
}

/*=======================================================================
 *
 *      dgap_param - Set Digi parameters.
 *
 *              struct tty_struct *     - TTY for port.
 *
 *=======================================================================*/
static int dgap_param(struct channel_t *ch, struct board_t *bd, u32 un_type)
{
	u16 head;
	u16 cflag;
	u16 iflag;
	u8 mval;
	u8 hflow;

	/*
	 * If baud rate is zero, flush queues, and set mval to drop DTR.
	 */
	if ((ch->ch_c_cflag & (CBAUD)) == 0) {
		/* flush rx */
		head = readw(&ch->ch_bs->rx_head);
		writew(head, &ch->ch_bs->rx_tail);

		/* flush tx */
		head = readw(&ch->ch_bs->tx_head);
		writew(head, &ch->ch_bs->tx_tail);

		ch->ch_flags |= (CH_BAUD0);

		/* Drop RTS and DTR */
		ch->ch_mval &= ~(D_RTS(ch) | D_DTR(ch));
		mval = D_DTR(ch) | D_RTS(ch);
		ch->ch_baud_info = 0;

	} else if (ch->ch_custom_speed && (bd->bd_flags & BD_FEP5PLUS)) {
		/*
		 * Tell the fep to do the command
		 */

		dgap_cmdw_ext(ch, 0xff01, ch->ch_custom_speed, 0);

		/*
		 * Now go get from fep mem, what the fep
		 * believes the custom baud rate is.
		 */
		ch->ch_custom_speed = dgap_get_custom_baud(ch);
		ch->ch_baud_info = ch->ch_custom_speed;

		/* Handle transition from B0 */
		if (ch->ch_flags & CH_BAUD0) {
			ch->ch_flags &= ~(CH_BAUD0);
			ch->ch_mval |= (D_RTS(ch) | D_DTR(ch));
		}
		mval = D_DTR(ch) | D_RTS(ch);

	} else {
		/*
		 * Set baud rate, character size, and parity.
		 */


		int iindex = 0;
		int jindex = 0;
		int baud = 0;

		ulong bauds[4][16] = {
			{ /* slowbaud */
				0,	50,	75,	110,
				134,	150,	200,	300,
				600,	1200,	1800,	2400,
				4800,	9600,	19200,	38400 },
			{ /* slowbaud & CBAUDEX */
				0,	57600,	115200,	230400,
				460800,	150,	200,	921600,
				600,	1200,	1800,	2400,
				4800,	9600,	19200,	38400 },
			{ /* fastbaud */
				0,	57600,	76800,	115200,
				14400,	57600,	230400,	76800,
				115200,	230400,	28800,	460800,
				921600,	9600,	19200,	38400 },
			{ /* fastbaud & CBAUDEX */
				0,	57600,	115200,	230400,
				460800,	150,	200,	921600,
				600,	1200,	1800,	2400,
				4800,	9600,	19200,	38400 }
		};

		/*
		 * Only use the TXPrint baud rate if the
		 * terminal unit is NOT open
		 */
		if (!(ch->ch_tun.un_flags & UN_ISOPEN) &&
		    un_type == DGAP_PRINT)
			baud = C_BAUD(ch->ch_pun.un_tty) & 0xff;
		else
			baud = C_BAUD(ch->ch_tun.un_tty) & 0xff;

		if (ch->ch_c_cflag & CBAUDEX)
			iindex = 1;

		if (ch->ch_digi.digi_flags & DIGI_FAST)
			iindex += 2;

		jindex = baud;

		if ((iindex >= 0) && (iindex < 4) &&
		    (jindex >= 0) && (jindex < 16))
			baud = bauds[iindex][jindex];
		else
			baud = 0;

		if (baud == 0)
			baud = 9600;

		ch->ch_baud_info = baud;

		/*
		 * CBAUD has bit position 0x1000 set these days to
		 * indicate Linux baud rate remap.
		 * We use a different bit assignment for high speed.
		 * Clear this bit out while grabbing the parts of
		 * "cflag" we want.
		 */
		cflag = ch->ch_c_cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB |
						   CSTOPB | CSIZE);

		/*
		 * HUPCL bit is used by FEP to indicate fast baud
		 * table is to be used.
		 */
		if ((ch->ch_digi.digi_flags & DIGI_FAST) ||
		    (ch->ch_c_cflag & CBAUDEX))
			cflag |= HUPCL;

		if ((ch->ch_c_cflag & CBAUDEX) &&
		    !(ch->ch_digi.digi_flags & DIGI_FAST)) {
			/*
			 * The below code is trying to guarantee that only
			 * baud rates 115200, 230400, 460800, 921600 are
			 * remapped. We use exclusive or  because the various
			 * baud rates share common bit positions and therefore
			 * can't be tested for easily.
			 */
			tcflag_t tcflag = (ch->ch_c_cflag & CBAUD) | CBAUDEX;
			int baudpart = 0;

			/*
			 * Map high speed requests to index
			 * into FEP's baud table
			 */
			switch (tcflag) {
			case B57600:
				baudpart = 1;
				break;
#ifdef B76800
			case B76800:
				baudpart = 2;
				break;
#endif
			case B115200:
				baudpart = 3;
				break;
			case B230400:
				baudpart = 9;
				break;
			case B460800:
				baudpart = 11;
				break;
#ifdef B921600
			case B921600:
				baudpart = 12;
				break;
#endif
			default:
				baudpart = 0;
			}

			if (baudpart)
				cflag = (cflag & ~(CBAUD | CBAUDEX)) | baudpart;
		}

		cflag &= 0xffff;

		if (cflag != ch->ch_fepcflag) {
			ch->ch_fepcflag = (u16)(cflag & 0xffff);

			/*
			 * Okay to have channel and board
			 * locks held calling this
			 */
			dgap_cmdw(ch, SCFLAG, (u16)cflag, 0);
		}

		/* Handle transition from B0 */
		if (ch->ch_flags & CH_BAUD0) {
			ch->ch_flags &= ~(CH_BAUD0);
			ch->ch_mval |= (D_RTS(ch) | D_DTR(ch));
		}
		mval = D_DTR(ch) | D_RTS(ch);
	}

	/*
	 * Get input flags.
	 */
	iflag = ch->ch_c_iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK |
				  INPCK | ISTRIP | IXON | IXANY | IXOFF);

	if ((ch->ch_startc == _POSIX_VDISABLE) ||
	    (ch->ch_stopc == _POSIX_VDISABLE)) {
		iflag &= ~(IXON | IXOFF);
		ch->ch_c_iflag &= ~(IXON | IXOFF);
	}

	/*
	 * Only the IBM Xr card can switch between
	 * 232 and 422 modes on the fly
	 */
	if (bd->device == PCI_DEV_XR_IBM_DID) {
		if (ch->ch_digi.digi_flags & DIGI_422)
			dgap_cmdb(ch, SCOMMODE, MODE_422, 0, 0);
		else
			dgap_cmdb(ch, SCOMMODE, MODE_232, 0, 0);
	}

	if (ch->ch_digi.digi_flags & DIGI_ALTPIN)
		iflag |= IALTPIN;

	if (iflag != ch->ch_fepiflag) {
		ch->ch_fepiflag = iflag;

		/* Okay to have channel and board locks held calling this */
		dgap_cmdw(ch, SIFLAG, (u16)ch->ch_fepiflag, 0);
	}

	/*
	 * Select hardware handshaking.
	 */
	hflow = 0;

	if (ch->ch_c_cflag & CRTSCTS)
		hflow |= (D_RTS(ch) | D_CTS(ch));
	if (ch->ch_digi.digi_flags & RTSPACE)
		hflow |= D_RTS(ch);
	if (ch->ch_digi.digi_flags & DTRPACE)
		hflow |= D_DTR(ch);
	if (ch->ch_digi.digi_flags & CTSPACE)
		hflow |= D_CTS(ch);
	if (ch->ch_digi.digi_flags & DSRPACE)
		hflow |= D_DSR(ch);
	if (ch->ch_digi.digi_flags & DCDPACE)
		hflow |= D_CD(ch);

	if (hflow != ch->ch_hflow) {
		ch->ch_hflow = hflow;

		/* Okay to have channel and board locks held calling this */
		dgap_cmdb(ch, SHFLOW, (u8)hflow, 0xff, 0);
	}

	/*
	 * Set RTS and/or DTR Toggle if needed,
	 * but only if product is FEP5+ based.
	 */
	if (bd->bd_flags & BD_FEP5PLUS) {
		u16 hflow2 = 0;

		if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)
			hflow2 |= (D_RTS(ch));
		if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE)
			hflow2 |= (D_DTR(ch));

		dgap_cmdw_ext(ch, 0xff03, hflow2, 0);
	}

	/*
	 * Set modem control lines.
	 */

	mval ^= ch->ch_mforce & (mval ^ ch->ch_mval);

	if (ch->ch_mostat ^ mval) {
		ch->ch_mostat = mval;

		/* Okay to have channel and board locks held calling this */
		dgap_cmdb(ch, SMODEM, (u8)mval, D_RTS(ch) | D_DTR(ch), 0);
	}

	/*
	 * Read modem signals, and then call carrier function.
	 */
	ch->ch_mistat = readb(&ch->ch_bs->m_stat);
	dgap_carrier(ch);

	/*
	 * Set the start and stop characters.
	 */
	if (ch->ch_startc != ch->ch_fepstartc ||
	    ch->ch_stopc != ch->ch_fepstopc) {
		ch->ch_fepstartc = ch->ch_startc;
		ch->ch_fepstopc =  ch->ch_stopc;

		/* Okay to have channel and board locks held calling this */
		dgap_cmdb(ch, SFLOWC, ch->ch_fepstartc, ch->ch_fepstopc, 0);
	}

	/*
	 * Set the Auxiliary start and stop characters.
	 */
	if (ch->ch_astartc != ch->ch_fepastartc ||
	    ch->ch_astopc != ch->ch_fepastopc) {
		ch->ch_fepastartc = ch->ch_astartc;
		ch->ch_fepastopc = ch->ch_astopc;

		/* Okay to have channel and board locks held calling this */
		dgap_cmdb(ch, SAFLOWC, ch->ch_fepastartc, ch->ch_fepastopc, 0);
	}

	return 0;
}

/*
 * dgap_block_til_ready()
 *
 * Wait for DCD, if needed.
 */
static int dgap_block_til_ready(struct tty_struct *tty, struct file *file,
				struct channel_t *ch)
{
	int retval = 0;
	struct un_t *un;
	ulong lock_flags;
	uint old_flags;
	int sleep_on_un_flags;

	if (!tty || tty->magic != TTY_MAGIC || !file || !ch ||
	    ch->magic != DGAP_CHANNEL_MAGIC)
		return -EIO;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return -EIO;

	spin_lock_irqsave(&ch->ch_lock, lock_flags);

	ch->ch_wopen++;

	/* Loop forever */
	while (1) {
		sleep_on_un_flags = 0;

		/*
		 * If board has failed somehow during our sleep,
		 * bail with error.
		 */
		if (ch->ch_bd->state == BOARD_FAILED) {
			retval = -EIO;
			break;
		}

		/* If tty was hung up, break out of loop and set error. */
		if (tty_hung_up_p(file)) {
			retval = -EAGAIN;
			break;
		}

		/*
		 * If either unit is in the middle of the fragile part of close,
		 * we just cannot touch the channel safely.
		 * Go back to sleep, knowing that when the channel can be
		 * touched safely, the close routine will signal the
		 * ch_wait_flags to wake us back up.
		 */
		if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) &
		      UN_CLOSING)) {
			/*
			 * Our conditions to leave cleanly and happily:
			 * 1) NONBLOCKING on the tty is set.
			 * 2) CLOCAL is set.
			 * 3) DCD (fake or real) is active.
			 */

			if (file->f_flags & O_NONBLOCK)
				break;

			if (tty->flags & (1 << TTY_IO_ERROR))
				break;

			if (ch->ch_flags & CH_CD)
				break;

			if (ch->ch_flags & CH_FCAR)
				break;
		} else {
			sleep_on_un_flags = 1;
		}

		/*
		 * If there is a signal pending, the user probably
		 * interrupted (ctrl-c) us.
		 * Leave loop with error set.
		 */
		if (signal_pending(current)) {
			retval = -ERESTARTSYS;
			break;
		}

		/*
		 * Store the flags before we let go of channel lock
		 */
		if (sleep_on_un_flags)
			old_flags = ch->ch_tun.un_flags | ch->ch_pun.un_flags;
		else
			old_flags = ch->ch_flags;

		/*
		 * Let go of channel lock before calling schedule.
		 * Our poller will get any FEP events and wake us up when DCD
		 * eventually goes active.
		 */

		spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

		/*
		 * Wait for something in the flags to change
		 * from the current value.
		 */
		if (sleep_on_un_flags) {
			retval = wait_event_interruptible(un->un_flags_wait,
				(old_flags != (ch->ch_tun.un_flags |
					       ch->ch_pun.un_flags)));
		} else {
			retval = wait_event_interruptible(ch->ch_flags_wait,
				(old_flags != ch->ch_flags));
		}

		/*
		 * We got woken up for some reason.
		 * Before looping around, grab our channel lock.
		 */
		spin_lock_irqsave(&ch->ch_lock, lock_flags);
	}

	ch->ch_wopen--;

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

	return retval;
}

/*
 * dgap_tty_flush_buffer()
 *
 * Flush Tx buffer (make in == out)
 */
static void dgap_tty_flush_buffer(struct tty_struct *tty)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	ulong lock_flags;
	ulong lock_flags2;
	u16 head;

	if (!tty || tty->magic != TTY_MAGIC)
		return;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	ch->ch_flags &= ~CH_STOP;
	head = readw(&ch->ch_bs->tx_head);
	dgap_cmdw(ch, FLUSHTX, (u16)head, 0);
	dgap_cmdw(ch, RESUMETX, 0, 0);
	if (ch->ch_tun.un_flags & (UN_LOW | UN_EMPTY)) {
		ch->ch_tun.un_flags &= ~(UN_LOW | UN_EMPTY);
		wake_up_interruptible(&ch->ch_tun.un_flags_wait);
	}
	if (ch->ch_pun.un_flags & (UN_LOW | UN_EMPTY)) {
		ch->ch_pun.un_flags &= ~(UN_LOW | UN_EMPTY);
		wake_up_interruptible(&ch->ch_pun.un_flags_wait);
	}

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
	if (waitqueue_active(&tty->write_wait))
		wake_up_interruptible(&tty->write_wait);
	tty_wakeup(tty);
}

/*
 * dgap_tty_hangup()
 *
 * Hangup the port.  Like a close, but don't wait for output to drain.
 */
static void dgap_tty_hangup(struct tty_struct *tty)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;

	if (!tty || tty->magic != TTY_MAGIC)
		return;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return;

	/* flush the transmit queues */
	dgap_tty_flush_buffer(tty);
}

/*
 * dgap_tty_chars_in_buffer()
 *
 * Return number of characters that have not been transmitted yet.
 *
 * This routine is used by the line discipline to determine if there
 * is data waiting to be transmitted/drained/flushed or not.
 */
static int dgap_tty_chars_in_buffer(struct tty_struct *tty)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	struct bs_t __iomem *bs;
	u8 tbusy;
	uint chars;
	u16 thead, ttail, tmask, chead, ctail;
	ulong lock_flags = 0;
	ulong lock_flags2 = 0;

	if (!tty)
		return 0;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return 0;

	bs = ch->ch_bs;
	if (!bs)
		return 0;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	tmask = (ch->ch_tsize - 1);

	/* Get Transmit queue pointers */
	thead = readw(&bs->tx_head) & tmask;
	ttail = readw(&bs->tx_tail) & tmask;

	/* Get tbusy flag */
	tbusy = readb(&bs->tbusy);

	/* Get Command queue pointers */
	chead = readw(&ch->ch_cm->cm_head);
	ctail = readw(&ch->ch_cm->cm_tail);

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

	/*
	 * The only way we know for sure if there is no pending
	 * data left to be transferred, is if:
	 * 1) Transmit head and tail are equal (empty).
	 * 2) Command queue head and tail are equal (empty).
	 * 3) The "TBUSY" flag is 0. (Transmitter not busy).
	 */

	if ((ttail == thead) && (tbusy == 0) && (chead == ctail)) {
		chars = 0;
	} else {
		if (thead >= ttail)
			chars = thead - ttail;
		else
			chars = thead - ttail + ch->ch_tsize;
		/*
		 * Fudge factor here.
		 * If chars is zero, we know that the command queue had
		 * something in it or tbusy was set.  Because we cannot
		 * be sure if there is still some data to be transmitted,
		 * lets lie, and tell ld we have 1 byte left.
		 */
		if (chars == 0) {
			/*
			 * If TBUSY is still set, and our tx buffers are empty,
			 * force the firmware to send me another wakeup after
			 * TBUSY has been cleared.
			 */
			if (tbusy != 0) {
				spin_lock_irqsave(&ch->ch_lock, lock_flags);
				un->un_flags |= UN_EMPTY;
				writeb(1, &bs->iempty);
				spin_unlock_irqrestore(&ch->ch_lock,
						       lock_flags);
			}
			chars = 1;
		}
	}

	return chars;
}

static int dgap_wait_for_drain(struct tty_struct *tty)
{
	struct channel_t *ch;
	struct un_t *un;
	struct bs_t __iomem *bs;
	int ret = 0;
	uint count = 1;
	ulong lock_flags = 0;

	if (!tty || tty->magic != TTY_MAGIC)
		return -EIO;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return -EIO;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return -EIO;

	bs = ch->ch_bs;
	if (!bs)
		return -EIO;

	/* Loop until data is drained */
	while (count != 0) {
		count = dgap_tty_chars_in_buffer(tty);

		if (count == 0)
			break;

		/* Set flag waiting for drain */
		spin_lock_irqsave(&ch->ch_lock, lock_flags);
		un->un_flags |= UN_EMPTY;
		writeb(1, &bs->iempty);
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

		/* Go to sleep till we get woken up */
		ret = wait_event_interruptible(un->un_flags_wait,
					((un->un_flags & UN_EMPTY) == 0));
		/* If ret is non-zero, user ctrl-c'ed us */
		if (ret)
			break;
	}

	spin_lock_irqsave(&ch->ch_lock, lock_flags);
	un->un_flags &= ~(UN_EMPTY);
	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

	return ret;
}

/*
 * dgap_maxcps_room
 *
 * Reduces bytes_available to the max number of characters
 * that can be sent currently given the maxcps value, and
 * returns the new bytes_available.  This only affects printer
 * output.
 */
static int dgap_maxcps_room(struct channel_t *ch, struct un_t *un,
			    int bytes_available)
{
	/*
	 * If its not the Transparent print device, return
	 * the full data amount.
	 */
	if (un->un_type != DGAP_PRINT)
		return bytes_available;

	if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0) {
		int cps_limit = 0;
		unsigned long current_time = jiffies;
		unsigned long buffer_time = current_time +
			(HZ * ch->ch_digi.digi_bufsize) /
			ch->ch_digi.digi_maxcps;

		if (ch->ch_cpstime < current_time) {
			/* buffer is empty */
			ch->ch_cpstime = current_time;   /* reset ch_cpstime */
			cps_limit = ch->ch_digi.digi_bufsize;
		} else if (ch->ch_cpstime < buffer_time) {
			/* still room in the buffer */
			cps_limit = ((buffer_time - ch->ch_cpstime) *
				     ch->ch_digi.digi_maxcps) / HZ;
		} else {
			/* no room in the buffer */
			cps_limit = 0;
		}

		bytes_available = min(cps_limit, bytes_available);
	}

	return bytes_available;
}

static inline void dgap_set_firmware_event(struct un_t *un, unsigned int event)
{
	struct channel_t *ch;
	struct bs_t __iomem *bs;

	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return;
	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;
	bs = ch->ch_bs;
	if (!bs)
		return;

	if ((event & UN_LOW) != 0) {
		if ((un->un_flags & UN_LOW) == 0) {
			un->un_flags |= UN_LOW;
			writeb(1, &bs->ilow);
		}
	}
	if ((event & UN_LOW) != 0) {
		if ((un->un_flags & UN_EMPTY) == 0) {
			un->un_flags |= UN_EMPTY;
			writeb(1, &bs->iempty);
		}
	}
}

/*
 * dgap_tty_write_room()
 *
 * Return space available in Tx buffer
 */
static int dgap_tty_write_room(struct tty_struct *tty)
{
	struct channel_t *ch;
	struct un_t *un;
	struct bs_t __iomem *bs;
	u16 head, tail, tmask;
	int ret;
	ulong lock_flags = 0;

	if (!tty)
		return 0;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;

	bs = ch->ch_bs;
	if (!bs)
		return 0;

	spin_lock_irqsave(&ch->ch_lock, lock_flags);

	tmask = ch->ch_tsize - 1;
	head = readw(&bs->tx_head) & tmask;
	tail = readw(&bs->tx_tail) & tmask;

	ret = tail - head - 1;
	if (ret < 0)
		ret += ch->ch_tsize;

	/* Limit printer to maxcps */
	ret = dgap_maxcps_room(ch, un, ret);

	/*
	 * If we are printer device, leave space for
	 * possibly both the on and off strings.
	 */
	if (un->un_type == DGAP_PRINT) {
		if (!(ch->ch_flags & CH_PRON))
			ret -= ch->ch_digi.digi_onlen;
		ret -= ch->ch_digi.digi_offlen;
	} else {
		if (ch->ch_flags & CH_PRON)
			ret -= ch->ch_digi.digi_offlen;
	}

	if (ret < 0)
		ret = 0;

	/*
	 * Schedule FEP to wake us up if needed.
	 *
	 * TODO:  This might be overkill...
	 * Do we really need to schedule callbacks from the FEP
	 * in every case?  Can we get smarter based on ret?
	 */
	dgap_set_firmware_event(un, UN_LOW | UN_EMPTY);
	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

	return ret;
}

/*
 * dgap_tty_write()
 *
 * Take data from the user or kernel and send it out to the FEP.
 * In here exists all the Transparent Print magic as well.
 */
static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf,
			  int count)
{
	struct channel_t *ch;
	struct un_t *un;
	struct bs_t __iomem *bs;
	char __iomem *vaddr;
	u16 head, tail, tmask, remain;
	int bufcount, n;
	ulong lock_flags;

	if (!tty)
		return 0;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;

	bs = ch->ch_bs;
	if (!bs)
		return 0;

	if (!count)
		return 0;

	spin_lock_irqsave(&ch->ch_lock, lock_flags);

	/* Get our space available for the channel from the board */
	tmask = ch->ch_tsize - 1;
	head = readw(&(bs->tx_head)) & tmask;
	tail = readw(&(bs->tx_tail)) & tmask;

	bufcount = tail - head - 1;
	if (bufcount < 0)
		bufcount += ch->ch_tsize;

	/*
	 * Limit printer output to maxcps overall, with bursts allowed
	 * up to bufsize characters.
	 */
	bufcount = dgap_maxcps_room(ch, un, bufcount);

	/*
	 * Take minimum of what the user wants to send, and the
	 * space available in the FEP buffer.
	 */
	count = min(count, bufcount);

	/*
	 * Bail if no space left.
	 */
	if (count <= 0) {
		dgap_set_firmware_event(un, UN_LOW | UN_EMPTY);
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
		return 0;
	}

	/*
	 * Output the printer ON string, if we are in terminal mode, but
	 * need to be in printer mode.
	 */
	if ((un->un_type == DGAP_PRINT) && !(ch->ch_flags & CH_PRON)) {
		dgap_wmove(ch, ch->ch_digi.digi_onstr,
			   (int)ch->ch_digi.digi_onlen);
		head = readw(&bs->tx_head) & tmask;
		ch->ch_flags |= CH_PRON;
	}

	/*
	 * On the other hand, output the printer OFF string, if we are
	 * currently in printer mode, but need to output to the terminal.
	 */
	if ((un->un_type != DGAP_PRINT) && (ch->ch_flags & CH_PRON)) {
		dgap_wmove(ch, ch->ch_digi.digi_offstr,
			   (int)ch->ch_digi.digi_offlen);
		head = readw(&bs->tx_head) & tmask;
		ch->ch_flags &= ~CH_PRON;
	}

	n = count;

	/*
	 * If the write wraps over the top of the circular buffer,
	 * move the portion up to the wrap point, and reset the
	 * pointers to the bottom.
	 */
	remain = ch->ch_tstart + ch->ch_tsize - head;

	if (n >= remain) {
		n -= remain;
		vaddr = ch->ch_taddr + head;

		memcpy_toio(vaddr, (u8 *)buf, remain);

		head = ch->ch_tstart;
		buf += remain;
	}

	if (n > 0) {
		/*
		 * Move rest of data.
		 */
		vaddr = ch->ch_taddr + head;
		remain = n;

		memcpy_toio(vaddr, (u8 *)buf, remain);
		head += remain;
	}

	if (count) {
		ch->ch_txcount += count;
		head &= tmask;
		writew(head, &bs->tx_head);
	}

	dgap_set_firmware_event(un, UN_LOW | UN_EMPTY);

	/*
	 * If this is the print device, and the
	 * printer is still on, we need to turn it
	 * off before going idle.  If the buffer is
	 * non-empty, wait until it goes empty.
	 * Otherwise turn it off right now.
	 */
	if ((un->un_type == DGAP_PRINT) && (ch->ch_flags & CH_PRON)) {
		tail = readw(&bs->tx_tail) & tmask;

		if (tail != head) {
			un->un_flags |= UN_EMPTY;
			writeb(1, &bs->iempty);
		} else {
			dgap_wmove(ch, ch->ch_digi.digi_offstr,
				   (int)ch->ch_digi.digi_offlen);
			head = readw(&bs->tx_head) & tmask;
			ch->ch_flags &= ~CH_PRON;
		}
	}

	/* Update printer buffer empty time. */
	if ((un->un_type == DGAP_PRINT) && (ch->ch_digi.digi_maxcps > 0)
	    && (ch->ch_digi.digi_bufsize > 0)) {
		ch->ch_cpstime += (HZ * count) / ch->ch_digi.digi_maxcps;
	}

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

	return count;
}

/*
 * dgap_tty_put_char()
 *
 * Put a character into ch->ch_buf
 *
 *      - used by the line discipline for OPOST processing
 */
static int dgap_tty_put_char(struct tty_struct *tty, unsigned char c)
{
	/*
	 * Simply call tty_write.
	 */
	dgap_tty_write(tty, &c, 1);
	return 1;
}

/*
 * Return modem signals to ld.
 */
static int dgap_tty_tiocmget(struct tty_struct *tty)
{
	struct channel_t *ch;
	struct un_t *un;
	int result;
	u8 mstat;
	ulong lock_flags;

	if (!tty || tty->magic != TTY_MAGIC)
		return -EIO;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return -EIO;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return -EIO;

	spin_lock_irqsave(&ch->ch_lock, lock_flags);

	mstat = readb(&ch->ch_bs->m_stat);
	/* Append any outbound signals that might be pending... */
	mstat |= ch->ch_mostat;

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

	result = 0;

	if (mstat & D_DTR(ch))
		result |= TIOCM_DTR;
	if (mstat & D_RTS(ch))
		result |= TIOCM_RTS;
	if (mstat & D_CTS(ch))
		result |= TIOCM_CTS;
	if (mstat & D_DSR(ch))
		result |= TIOCM_DSR;
	if (mstat & D_RI(ch))
		result |= TIOCM_RI;
	if (mstat & D_CD(ch))
		result |= TIOCM_CD;

	return result;
}

/*
 * dgap_tty_tiocmset()
 *
 * Set modem signals, called by ld.
 */
static int dgap_tty_tiocmset(struct tty_struct *tty,
			     unsigned int set, unsigned int clear)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	ulong lock_flags;
	ulong lock_flags2;

	if (!tty || tty->magic != TTY_MAGIC)
		return -EIO;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return -EIO;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return -EIO;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return -EIO;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	if (set & TIOCM_RTS) {
		ch->ch_mforce |= D_RTS(ch);
		ch->ch_mval   |= D_RTS(ch);
	}

	if (set & TIOCM_DTR) {
		ch->ch_mforce |= D_DTR(ch);
		ch->ch_mval   |= D_DTR(ch);
	}

	if (clear & TIOCM_RTS) {
		ch->ch_mforce |= D_RTS(ch);
		ch->ch_mval   &= ~(D_RTS(ch));
	}

	if (clear & TIOCM_DTR) {
		ch->ch_mforce |= D_DTR(ch);
		ch->ch_mval   &= ~(D_DTR(ch));
	}

	dgap_param(ch, bd, un->un_type);

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

	return 0;
}

/*
 * dgap_tty_send_break()
 *
 * Send a Break, called by ld.
 */
static int dgap_tty_send_break(struct tty_struct *tty, int msec)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	ulong lock_flags;
	ulong lock_flags2;

	if (!tty || tty->magic != TTY_MAGIC)
		return -EIO;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return -EIO;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return -EIO;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return -EIO;

	switch (msec) {
	case -1:
		msec = 0xFFFF;
		break;
	case 0:
		msec = 1;
		break;
	default:
		msec /= 10;
		break;
	}

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);
#if 0
	dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0);
#endif
	dgap_cmdw(ch, SBREAK, (u16)msec, 0);

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

	return 0;
}

/*
 * dgap_tty_wait_until_sent()
 *
 * wait until data has been transmitted, called by ld.
 */
static void dgap_tty_wait_until_sent(struct tty_struct *tty, int timeout)
{
	dgap_wait_for_drain(tty);
}

/*
 * dgap_send_xchar()
 *
 * send a high priority character, called by ld.
 */
static void dgap_tty_send_xchar(struct tty_struct *tty, char c)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	ulong lock_flags;
	ulong lock_flags2;

	if (!tty || tty->magic != TTY_MAGIC)
		return;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	/*
	 * This is technically what we should do.
	 * However, the NIST tests specifically want
	 * to see each XON or XOFF character that it
	 * sends, so lets just send each character
	 * by hand...
	 */
#if 0
	if (c == STOP_CHAR(tty))
		dgap_cmdw(ch, RPAUSE, 0, 0);
	else if (c == START_CHAR(tty))
		dgap_cmdw(ch, RRESUME, 0, 0);
	else
		dgap_wmove(ch, &c, 1);
#else
	dgap_wmove(ch, &c, 1);
#endif

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
}

/*
 * Return modem signals to ld.
 */
static int dgap_get_modem_info(struct channel_t *ch, unsigned int __user *value)
{
	int result;
	u8 mstat;
	ulong lock_flags;

	spin_lock_irqsave(&ch->ch_lock, lock_flags);

	mstat = readb(&ch->ch_bs->m_stat);
	/* Append any outbound signals that might be pending... */
	mstat |= ch->ch_mostat;

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

	result = 0;

	if (mstat & D_DTR(ch))
		result |= TIOCM_DTR;
	if (mstat & D_RTS(ch))
		result |= TIOCM_RTS;
	if (mstat & D_CTS(ch))
		result |= TIOCM_CTS;
	if (mstat & D_DSR(ch))
		result |= TIOCM_DSR;
	if (mstat & D_RI(ch))
		result |= TIOCM_RI;
	if (mstat & D_CD(ch))
		result |= TIOCM_CD;

	return put_user(result, value);
}

/*
 * dgap_set_modem_info()
 *
 * Set modem signals, called by ld.
 */
static int dgap_set_modem_info(struct channel_t *ch, struct board_t *bd,
			       struct un_t *un, unsigned int command,
			       unsigned int __user *value)
{
	int ret;
	unsigned int arg;
	ulong lock_flags;
	ulong lock_flags2;

	ret = get_user(arg, value);
	if (ret)
		return ret;

	switch (command) {
	case TIOCMBIS:
		if (arg & TIOCM_RTS) {
			ch->ch_mforce |= D_RTS(ch);
			ch->ch_mval   |= D_RTS(ch);
		}

		if (arg & TIOCM_DTR) {
			ch->ch_mforce |= D_DTR(ch);
			ch->ch_mval   |= D_DTR(ch);
		}

		break;

	case TIOCMBIC:
		if (arg & TIOCM_RTS) {
			ch->ch_mforce |= D_RTS(ch);
			ch->ch_mval   &= ~(D_RTS(ch));
		}

		if (arg & TIOCM_DTR) {
			ch->ch_mforce |= D_DTR(ch);
			ch->ch_mval   &= ~(D_DTR(ch));
		}

		break;

	case TIOCMSET:
		ch->ch_mforce = D_DTR(ch) | D_RTS(ch);

		if (arg & TIOCM_RTS)
			ch->ch_mval |= D_RTS(ch);
		else
			ch->ch_mval &= ~(D_RTS(ch));

		if (arg & TIOCM_DTR)
			ch->ch_mval |= (D_DTR(ch));
		else
			ch->ch_mval &= ~(D_DTR(ch));

		break;

	default:
		return -EINVAL;
	}

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	dgap_param(ch, bd, un->un_type);

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

	return 0;
}

/*
 * dgap_tty_digigeta()
 *
 * Ioctl to get the information for ditty.
 *
 *
 *
 */
static int dgap_tty_digigeta(struct channel_t *ch,
			     struct digi_t __user *retinfo)
{
	struct digi_t tmp;
	ulong lock_flags;

	if (!retinfo)
		return -EFAULT;

	memset(&tmp, 0, sizeof(tmp));

	spin_lock_irqsave(&ch->ch_lock, lock_flags);
	memcpy(&tmp, &ch->ch_digi, sizeof(tmp));
	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
		return -EFAULT;

	return 0;
}

/*
 * dgap_tty_digiseta()
 *
 * Ioctl to set the information for ditty.
 *
 *
 *
 */
static int dgap_tty_digiseta(struct channel_t *ch, struct board_t *bd,
			     struct un_t *un, struct digi_t __user *new_info)
{
	struct digi_t new_digi;
	ulong lock_flags = 0;
	unsigned long lock_flags2;

	if (copy_from_user(&new_digi, new_info, sizeof(struct digi_t)))
		return -EFAULT;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	memcpy(&ch->ch_digi, &new_digi, sizeof(struct digi_t));

	if (ch->ch_digi.digi_maxcps < 1)
		ch->ch_digi.digi_maxcps = 1;

	if (ch->ch_digi.digi_maxcps > 10000)
		ch->ch_digi.digi_maxcps = 10000;

	if (ch->ch_digi.digi_bufsize < 10)
		ch->ch_digi.digi_bufsize = 10;

	if (ch->ch_digi.digi_maxchar < 1)
		ch->ch_digi.digi_maxchar = 1;

	if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize)
		ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize;

	if (ch->ch_digi.digi_onlen > DIGI_PLEN)
		ch->ch_digi.digi_onlen = DIGI_PLEN;

	if (ch->ch_digi.digi_offlen > DIGI_PLEN)
		ch->ch_digi.digi_offlen = DIGI_PLEN;

	dgap_param(ch, bd, un->un_type);

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

	return 0;
}

/*
 * dgap_tty_digigetedelay()
 *
 * Ioctl to get the current edelay setting.
 *
 *
 *
 */
static int dgap_tty_digigetedelay(struct tty_struct *tty, int __user *retinfo)
{
	struct channel_t *ch;
	struct un_t *un;
	int tmp;
	ulong lock_flags;

	if (!retinfo)
		return -EFAULT;

	if (!tty || tty->magic != TTY_MAGIC)
		return -EFAULT;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return -EFAULT;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return -EFAULT;

	memset(&tmp, 0, sizeof(tmp));

	spin_lock_irqsave(&ch->ch_lock, lock_flags);
	tmp = readw(&ch->ch_bs->edelay);
	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
		return -EFAULT;

	return 0;
}

/*
 * dgap_tty_digisetedelay()
 *
 * Ioctl to set the EDELAY setting
 *
 */
static int dgap_tty_digisetedelay(struct channel_t *ch, struct board_t *bd,
				  struct un_t *un, int __user *new_info)
{
	int new_digi;
	ulong lock_flags;
	ulong lock_flags2;

	if (copy_from_user(&new_digi, new_info, sizeof(int)))
		return -EFAULT;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	writew((u16)new_digi, &ch->ch_bs->edelay);

	dgap_param(ch, bd, un->un_type);

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

	return 0;
}

/*
 * dgap_tty_digigetcustombaud()
 *
 * Ioctl to get the current custom baud rate setting.
 */
static int dgap_tty_digigetcustombaud(struct channel_t *ch, struct un_t *un,
				      int __user *retinfo)
{
	int tmp;
	ulong lock_flags;

	if (!retinfo)
		return -EFAULT;

	memset(&tmp, 0, sizeof(tmp));

	spin_lock_irqsave(&ch->ch_lock, lock_flags);
	tmp = dgap_get_custom_baud(ch);
	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
		return -EFAULT;

	return 0;
}

/*
 * dgap_tty_digisetcustombaud()
 *
 * Ioctl to set the custom baud rate setting
 */
static int dgap_tty_digisetcustombaud(struct channel_t *ch, struct board_t *bd,
				      struct un_t *un, int __user *new_info)
{
	uint new_rate;
	ulong lock_flags;
	ulong lock_flags2;

	if (copy_from_user(&new_rate, new_info, sizeof(unsigned int)))
		return -EFAULT;

	if (bd->bd_flags & BD_FEP5PLUS) {
		spin_lock_irqsave(&bd->bd_lock, lock_flags);
		spin_lock_irqsave(&ch->ch_lock, lock_flags2);

		ch->ch_custom_speed = new_rate;

		dgap_param(ch, bd, un->un_type);

		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
	}

	return 0;
}

/*
 * dgap_set_termios()
 */
static void dgap_tty_set_termios(struct tty_struct *tty,
				 struct ktermios *old_termios)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	unsigned long lock_flags;
	unsigned long lock_flags2;

	if (!tty || tty->magic != TTY_MAGIC)
		return;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	ch->ch_c_cflag   = tty->termios.c_cflag;
	ch->ch_c_iflag   = tty->termios.c_iflag;
	ch->ch_c_oflag   = tty->termios.c_oflag;
	ch->ch_c_lflag   = tty->termios.c_lflag;
	ch->ch_startc    = tty->termios.c_cc[VSTART];
	ch->ch_stopc     = tty->termios.c_cc[VSTOP];

	dgap_carrier(ch);
	dgap_param(ch, bd, un->un_type);

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
}

static void dgap_tty_throttle(struct tty_struct *tty)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	ulong lock_flags;
	ulong lock_flags2;

	if (!tty || tty->magic != TTY_MAGIC)
		return;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	ch->ch_flags |= (CH_RXBLOCK);
#if 1
	dgap_cmdw(ch, RPAUSE, 0, 0);
#endif

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
}

static void dgap_tty_unthrottle(struct tty_struct *tty)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	ulong lock_flags;
	ulong lock_flags2;

	if (!tty || tty->magic != TTY_MAGIC)
		return;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	ch->ch_flags &= ~(CH_RXBLOCK);

#if 1
	dgap_cmdw(ch, RRESUME, 0, 0);
#endif

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
}

static struct board_t *find_board_by_major(unsigned int major)
{
	unsigned int i;

	for (i = 0; i < MAXBOARDS; i++) {
		struct board_t *brd = dgap_board[i];

		if (!brd)
			return NULL;
		if (major == brd->serial_driver->major ||
		    major == brd->print_driver->major)
			return brd;
	}

	return NULL;
}

/************************************************************************
 *
 * TTY Entry points and helper functions
 *
 ************************************************************************/

/*
 * dgap_tty_open()
 *
 */
static int dgap_tty_open(struct tty_struct *tty, struct file *file)
{
	struct board_t *brd;
	struct channel_t *ch;
	struct un_t *un;
	struct bs_t __iomem *bs;
	uint major;
	uint minor;
	int rc;
	ulong lock_flags;
	ulong lock_flags2;
	u16 head;

	major = MAJOR(tty_devnum(tty));
	minor = MINOR(tty_devnum(tty));

	brd = find_board_by_major(major);
	if (!brd)
		return -EIO;

	/*
	 * If board is not yet up to a state of READY, go to
	 * sleep waiting for it to happen or they cancel the open.
	 */
	rc = wait_event_interruptible(brd->state_wait,
				      (brd->state & BOARD_READY));

	if (rc)
		return rc;

	spin_lock_irqsave(&brd->bd_lock, lock_flags);

	/* The wait above should guarantee this cannot happen */
	if (brd->state != BOARD_READY) {
		spin_unlock_irqrestore(&brd->bd_lock, lock_flags);
		return -EIO;
	}

	/* If opened device is greater than our number of ports, bail. */
	if (MINOR(tty_devnum(tty)) > brd->nasync) {
		spin_unlock_irqrestore(&brd->bd_lock, lock_flags);
		return -EIO;
	}

	ch = brd->channels[minor];
	if (!ch) {
		spin_unlock_irqrestore(&brd->bd_lock, lock_flags);
		return -EIO;
	}

	/* Grab channel lock */
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	/* Figure out our type */
	if (major == brd->serial_driver->major) {
		un = &brd->channels[minor]->ch_tun;
		un->un_type = DGAP_SERIAL;
	} else if (major == brd->print_driver->major) {
		un = &brd->channels[minor]->ch_pun;
		un->un_type = DGAP_PRINT;
	} else {
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&brd->bd_lock, lock_flags);
		return -EIO;
	}

	/* Store our unit into driver_data, so we always have it available. */
	tty->driver_data = un;

	/*
	 * Error if channel info pointer is NULL.
	 */
	bs = ch->ch_bs;
	if (!bs) {
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&brd->bd_lock, lock_flags);
		return -EIO;
	}

	/*
	 * Initialize tty's
	 */
	if (!(un->un_flags & UN_ISOPEN)) {
		/* Store important variables. */
		un->un_tty     = tty;

		/* Maybe do something here to the TTY struct as well? */
	}

	/*
	 * Initialize if neither terminal or printer is open.
	 */
	if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) {
		ch->ch_mforce = 0;
		ch->ch_mval = 0;

		/*
		 * Flush input queue.
		 */
		head = readw(&bs->rx_head);
		writew(head, &bs->rx_tail);

		ch->ch_flags = 0;
		ch->pscan_state = 0;
		ch->pscan_savechar = 0;

		ch->ch_c_cflag   = tty->termios.c_cflag;
		ch->ch_c_iflag   = tty->termios.c_iflag;
		ch->ch_c_oflag   = tty->termios.c_oflag;
		ch->ch_c_lflag   = tty->termios.c_lflag;
		ch->ch_startc = tty->termios.c_cc[VSTART];
		ch->ch_stopc  = tty->termios.c_cc[VSTOP];

		/* TODO: flush our TTY struct here? */
	}

	dgap_carrier(ch);
	/*
	 * Run param in case we changed anything
	 */
	dgap_param(ch, brd, un->un_type);

	/*
	 * follow protocol for opening port
	 */

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&brd->bd_lock, lock_flags);

	rc = dgap_block_til_ready(tty, file, ch);

	if (!un->un_tty)
		return -ENODEV;

	/* No going back now, increment our unit and channel counters */
	spin_lock_irqsave(&ch->ch_lock, lock_flags);
	ch->ch_open_count++;
	un->un_open_count++;
	un->un_flags |= (UN_ISOPEN);
	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

	return rc;
}

/*
 * dgap_tty_close()
 *
 */
static void dgap_tty_close(struct tty_struct *tty, struct file *file)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	ulong lock_flags;

	if (!tty || tty->magic != TTY_MAGIC)
		return;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return;

	spin_lock_irqsave(&ch->ch_lock, lock_flags);

	/*
	 * Determine if this is the last close or not - and if we agree about
	 * which type of close it is with the Line Discipline
	 */
	if ((tty->count == 1) && (un->un_open_count != 1)) {
		/*
		 * Uh, oh.  tty->count is 1, which means that the tty
		 * structure will be freed.  un_open_count should always
		 * be one in these conditions.  If it's greater than
		 * one, we've got real problems, since it means the
		 * serial port won't be shutdown.
		 */
		un->un_open_count = 1;
	}

	if (--un->un_open_count < 0)
		un->un_open_count = 0;

	ch->ch_open_count--;

	if (ch->ch_open_count && un->un_open_count) {
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
		return;
	}

	/* OK, its the last close on the unit */

	un->un_flags |= UN_CLOSING;

	tty->closing = 1;

	/*
	 * Only officially close channel if count is 0 and
	 * DIGI_PRINTER bit is not set.
	 */
	if ((ch->ch_open_count == 0) &&
	    !(ch->ch_digi.digi_flags & DIGI_PRINTER)) {
		ch->ch_flags &= ~(CH_RXBLOCK);

		spin_unlock_irqrestore(&ch->ch_lock, lock_flags);

		/* wait for output to drain */
		/* This will also return if we take an interrupt */

		dgap_wait_for_drain(tty);

		dgap_tty_flush_buffer(tty);
		tty_ldisc_flush(tty);

		spin_lock_irqsave(&ch->ch_lock, lock_flags);

		tty->closing = 0;

		/*
		 * If we have HUPCL set, lower DTR and RTS
		 */
		if (ch->ch_c_cflag & HUPCL) {
			ch->ch_mostat &= ~(D_RTS(ch) | D_DTR(ch));
			dgap_cmdb(ch, SMODEM, 0, D_DTR(ch) | D_RTS(ch), 0);

			/*
			 * Go to sleep to ensure RTS/DTR
			 * have been dropped for modems to see it.
			 */
			spin_unlock_irqrestore(&ch->ch_lock,
					       lock_flags);

			/* .25 second delay for dropping RTS/DTR */
			schedule_timeout_interruptible(msecs_to_jiffies(250));

			spin_lock_irqsave(&ch->ch_lock, lock_flags);
		}

		ch->pscan_state = 0;
		ch->pscan_savechar = 0;
		ch->ch_baud_info = 0;
	}

	/*
	 * turn off print device when closing print device.
	 */
	if ((un->un_type == DGAP_PRINT)  && (ch->ch_flags & CH_PRON)) {
		dgap_wmove(ch, ch->ch_digi.digi_offstr,
			   (int)ch->ch_digi.digi_offlen);
		ch->ch_flags &= ~CH_PRON;
	}

	un->un_tty = NULL;
	un->un_flags &= ~(UN_ISOPEN | UN_CLOSING);
	tty->driver_data = NULL;

	wake_up_interruptible(&ch->ch_flags_wait);
	wake_up_interruptible(&un->un_flags_wait);

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
}

static void dgap_tty_start(struct tty_struct *tty)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	ulong lock_flags;
	ulong lock_flags2;

	if (!tty || tty->magic != TTY_MAGIC)
		return;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	dgap_cmdw(ch, RESUMETX, 0, 0);

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
}

static void dgap_tty_stop(struct tty_struct *tty)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	ulong lock_flags;
	ulong lock_flags2;

	if (!tty || tty->magic != TTY_MAGIC)
		return;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	dgap_cmdw(ch, PAUSETX, 0, 0);

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
}

/*
 * dgap_tty_flush_chars()
 *
 * Flush the cook buffer
 *
 * Note to self, and any other poor souls who venture here:
 *
 * flush in this case DOES NOT mean dispose of the data.
 * instead, it means "stop buffering and send it if you
 * haven't already."  Just guess how I figured that out...   SRW 2-Jun-98
 *
 * It is also always called in interrupt context - JAR 8-Sept-99
 */
static void dgap_tty_flush_chars(struct tty_struct *tty)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	ulong lock_flags;
	ulong lock_flags2;

	if (!tty || tty->magic != TTY_MAGIC)
		return;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	/* TODO: Do something here */

	spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
	spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
}

/*****************************************************************************
 *
 * The IOCTL function and all of its helpers
 *
 *****************************************************************************/

/*
 * dgap_tty_ioctl()
 *
 * The usual assortment of ioctl's
 */
static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
			  unsigned long arg)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	int rc;
	u16 head;
	ulong lock_flags = 0;
	ulong lock_flags2 = 0;
	void __user *uarg = (void __user *)arg;

	if (!tty || tty->magic != TTY_MAGIC)
		return -ENODEV;

	un = tty->driver_data;
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return -ENODEV;

	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return -ENODEV;

	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return -ENODEV;

	spin_lock_irqsave(&bd->bd_lock, lock_flags);
	spin_lock_irqsave(&ch->ch_lock, lock_flags2);

	if (un->un_open_count <= 0) {
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return -EIO;
	}

	switch (cmd) {
	/* Here are all the standard ioctl's that we MUST implement */
	case TCSBRK:
		/*
		 * TCSBRK is SVID version: non-zero arg --> no break
		 * this behaviour is exploited by tcdrain().
		 *
		 * According to POSIX.1 spec (7.2.2.1.2) breaks should be
		 * between 0.25 and 0.5 seconds so we'll ask for something
		 * in the middle: 0.375 seconds.
		 */
		rc = tty_check_change(tty);
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		if (rc)
			return rc;

		rc = dgap_wait_for_drain(tty);

		if (rc)
			return -EINTR;

		spin_lock_irqsave(&bd->bd_lock, lock_flags);
		spin_lock_irqsave(&ch->ch_lock, lock_flags2);

		if (((cmd == TCSBRK) && (!arg)) || (cmd == TCSBRKP))
			dgap_cmdw(ch, SBREAK, (u16)SBREAK_TIME, 0);

		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

		return 0;

	case TCSBRKP:
		/* support for POSIX tcsendbreak()

		 * According to POSIX.1 spec (7.2.2.1.2) breaks should be
		 * between 0.25 and 0.5 seconds so we'll ask for something
		 * in the middle: 0.375 seconds.
		 */
		rc = tty_check_change(tty);
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		if (rc)
			return rc;

		rc = dgap_wait_for_drain(tty);
		if (rc)
			return -EINTR;

		spin_lock_irqsave(&bd->bd_lock, lock_flags);
		spin_lock_irqsave(&ch->ch_lock, lock_flags2);

		dgap_cmdw(ch, SBREAK, (u16)SBREAK_TIME, 0);

		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

		return 0;

	case TIOCSBRK:
		/*
		 * FEP5 doesn't support turning on a break unconditionally.
		 * The FEP5 device will stop sending a break automatically
		 * after the specified time value that was sent when turning on
		 * the break.
		 */
		rc = tty_check_change(tty);
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		if (rc)
			return rc;

		rc = dgap_wait_for_drain(tty);
		if (rc)
			return -EINTR;

		spin_lock_irqsave(&bd->bd_lock, lock_flags);
		spin_lock_irqsave(&ch->ch_lock, lock_flags2);

		dgap_cmdw(ch, SBREAK, (u16)SBREAK_TIME, 0);

		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

		return 0;

	case TIOCCBRK:
		/*
		 * FEP5 doesn't support turning off a break unconditionally.
		 * The FEP5 device will stop sending a break automatically
		 * after the specified time value that was sent when turning on
		 * the break.
		 */
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return 0;

	case TIOCGSOFTCAR:

		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

		return put_user(C_CLOCAL(tty) ? 1 : 0,
				(unsigned long __user *)arg);

	case TIOCSSOFTCAR:
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

		rc = get_user(arg, (unsigned long __user *)arg);
		if (rc)
			return rc;

		spin_lock_irqsave(&bd->bd_lock, lock_flags);
		spin_lock_irqsave(&ch->ch_lock, lock_flags2);
		tty->termios.c_cflag = ((tty->termios.c_cflag & ~CLOCAL) |
						(arg ? CLOCAL : 0));
		dgap_param(ch, bd, un->un_type);
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

		return 0;

	case TIOCMGET:
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return dgap_get_modem_info(ch, uarg);

	case TIOCMBIS:
	case TIOCMBIC:
	case TIOCMSET:
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return dgap_set_modem_info(ch, bd, un, cmd, uarg);

		/*
		 * Here are any additional ioctl's that we want to implement
		 */

	case TCFLSH:
		/*
		 * The linux tty driver doesn't have a flush
		 * input routine for the driver, assuming all backed
		 * up data is in the line disc. buffers.  However,
		 * we all know that's not the case.  Here, we
		 * act on the ioctl, but then lie and say we didn't
		 * so the line discipline will process the flush
		 * also.
		 */
		rc = tty_check_change(tty);
		if (rc) {
			spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
			return rc;
		}

		if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) {
			if (!(un->un_type == DGAP_PRINT)) {
				head = readw(&ch->ch_bs->rx_head);
				writew(head, &ch->ch_bs->rx_tail);
				writeb(0, &ch->ch_bs->orun);
			}
		}

		if ((arg != TCOFLUSH) && (arg != TCIOFLUSH)) {
			/* pretend we didn't recognize this IOCTL */
			spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

			return -ENOIOCTLCMD;
		}

		ch->ch_flags &= ~CH_STOP;
		head = readw(&ch->ch_bs->tx_head);
		dgap_cmdw(ch, FLUSHTX, (u16)head, 0);
		dgap_cmdw(ch, RESUMETX, 0, 0);
		if (ch->ch_tun.un_flags & (UN_LOW | UN_EMPTY)) {
			ch->ch_tun.un_flags &= ~(UN_LOW | UN_EMPTY);
			wake_up_interruptible(&ch->ch_tun.un_flags_wait);
		}
		if (ch->ch_pun.un_flags & (UN_LOW | UN_EMPTY)) {
			ch->ch_pun.un_flags &= ~(UN_LOW | UN_EMPTY);
			wake_up_interruptible(&ch->ch_pun.un_flags_wait);
		}
		if (waitqueue_active(&tty->write_wait))
			wake_up_interruptible(&tty->write_wait);

		/* Can't hold any locks when calling tty_wakeup! */
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		tty_wakeup(tty);

		/* pretend we didn't recognize this IOCTL */
		return -ENOIOCTLCMD;

	case TCSETSF:
	case TCSETSW:
		/*
		 * The linux tty driver doesn't have a flush
		 * input routine for the driver, assuming all backed
		 * up data is in the line disc. buffers.  However,
		 * we all know that's not the case.  Here, we
		 * act on the ioctl, but then lie and say we didn't
		 * so the line discipline will process the flush
		 * also.
		 */
		if (cmd == TCSETSF) {
			/* flush rx */
			ch->ch_flags &= ~CH_STOP;
			head = readw(&ch->ch_bs->rx_head);
			writew(head, &ch->ch_bs->rx_tail);
		}

		/* now wait for all the output to drain */
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		rc = dgap_wait_for_drain(tty);
		if (rc)
			return -EINTR;

		/* pretend we didn't recognize this */
		return -ENOIOCTLCMD;

	case TCSETAW:

		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		rc = dgap_wait_for_drain(tty);
		if (rc)
			return -EINTR;

		/* pretend we didn't recognize this */
		return -ENOIOCTLCMD;

	case TCXONC:
		/*
		 * The Linux Line Discipline (LD) would do this for us if we
		 * let it, but we have the special firmware options to do this
		 * the "right way" regardless of hardware or software flow
		 * control so we'll do it outselves instead of letting the LD
		 * do it.
		 */
		rc = tty_check_change(tty);
		if (rc) {
			spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
			return rc;
		}

		switch (arg) {
		case TCOON:
			spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
			dgap_tty_start(tty);
			return 0;
		case TCOOFF:
			spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
			dgap_tty_stop(tty);
			return 0;
		case TCION:
			spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
			/* Make the ld do it */
			return -ENOIOCTLCMD;
		case TCIOFF:
			spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
			/* Make the ld do it */
			return -ENOIOCTLCMD;
		default:
			spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
			return -EINVAL;
		}

	case DIGI_GETA:
		/* get information for ditty */
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return dgap_tty_digigeta(ch, uarg);

	case DIGI_SETAW:
	case DIGI_SETAF:

		/* set information for ditty */
		if (cmd == (DIGI_SETAW)) {
			spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
			spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
			rc = dgap_wait_for_drain(tty);
			if (rc)
				return -EINTR;
			spin_lock_irqsave(&bd->bd_lock, lock_flags);
			spin_lock_irqsave(&ch->ch_lock, lock_flags2);
		} else
			tty_ldisc_flush(tty);
		/* fall thru */

	case DIGI_SETA:
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return dgap_tty_digiseta(ch, bd, un, uarg);

	case DIGI_GEDELAY:
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return dgap_tty_digigetedelay(tty, uarg);

	case DIGI_SEDELAY:
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return dgap_tty_digisetedelay(ch, bd, un, uarg);

	case DIGI_GETCUSTOMBAUD:
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return dgap_tty_digigetcustombaud(ch, un, uarg);

	case DIGI_SETCUSTOMBAUD:
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return dgap_tty_digisetcustombaud(ch, bd, un, uarg);

	case DIGI_RESET_PORT:
		dgap_firmware_reset_port(ch);
		dgap_param(ch, bd, un->un_type);
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
		return 0;

	default:
		spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
		spin_unlock_irqrestore(&bd->bd_lock, lock_flags);

		return -ENOIOCTLCMD;
	}
}

static const struct tty_operations dgap_tty_ops = {
	.open = dgap_tty_open,
	.close = dgap_tty_close,
	.write = dgap_tty_write,
	.write_room = dgap_tty_write_room,
	.flush_buffer = dgap_tty_flush_buffer,
	.chars_in_buffer = dgap_tty_chars_in_buffer,
	.flush_chars = dgap_tty_flush_chars,
	.ioctl = dgap_tty_ioctl,
	.set_termios = dgap_tty_set_termios,
	.stop = dgap_tty_stop,
	.start = dgap_tty_start,
	.throttle = dgap_tty_throttle,
	.unthrottle = dgap_tty_unthrottle,
	.hangup = dgap_tty_hangup,
	.put_char = dgap_tty_put_char,
	.tiocmget = dgap_tty_tiocmget,
	.tiocmset = dgap_tty_tiocmset,
	.break_ctl = dgap_tty_send_break,
	.wait_until_sent = dgap_tty_wait_until_sent,
	.send_xchar = dgap_tty_send_xchar
};

/************************************************************************
 *
 * TTY Initialization/Cleanup Functions
 *
 ************************************************************************/

/*
 * dgap_tty_register()
 *
 * Init the tty subsystem for this board.
 */
static int dgap_tty_register(struct board_t *brd)
{
	int rc;

	brd->serial_driver = tty_alloc_driver(MAXPORTS,
					      TTY_DRIVER_REAL_RAW |
					      TTY_DRIVER_DYNAMIC_DEV |
					      TTY_DRIVER_HARDWARE_BREAK);
	if (IS_ERR(brd->serial_driver))
		return PTR_ERR(brd->serial_driver);

	snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgap_%d_",
		 brd->boardnum);
	brd->serial_driver->name = brd->serial_name;
	brd->serial_driver->name_base = 0;
	brd->serial_driver->major = 0;
	brd->serial_driver->minor_start = 0;
	brd->serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
	brd->serial_driver->subtype = SERIAL_TYPE_NORMAL;
	brd->serial_driver->init_termios = dgap_default_termios;
	brd->serial_driver->driver_name = DRVSTR;

	/*
	 * Entry points for driver.  Called by the kernel from
	 * tty_io.c and n_tty.c.
	 */
	tty_set_operations(brd->serial_driver, &dgap_tty_ops);

	/*
	 * If we're doing transparent print, we have to do all of the above
	 * again, separately so we don't get the LD confused about what major
	 * we are when we get into the dgap_tty_open() routine.
	 */
	brd->print_driver = tty_alloc_driver(MAXPORTS,
					     TTY_DRIVER_REAL_RAW |
					     TTY_DRIVER_DYNAMIC_DEV |
					     TTY_DRIVER_HARDWARE_BREAK);
	if (IS_ERR(brd->print_driver)) {
		rc = PTR_ERR(brd->print_driver);
		goto free_serial_drv;
	}

	snprintf(brd->print_name, MAXTTYNAMELEN, "pr_dgap_%d_",
		 brd->boardnum);
	brd->print_driver->name = brd->print_name;
	brd->print_driver->name_base = 0;
	brd->print_driver->major = 0;
	brd->print_driver->minor_start = 0;
	brd->print_driver->type = TTY_DRIVER_TYPE_SERIAL;
	brd->print_driver->subtype = SERIAL_TYPE_NORMAL;
	brd->print_driver->init_termios = dgap_default_termios;
	brd->print_driver->driver_name = DRVSTR;

	/*
	 * Entry points for driver.  Called by the kernel from
	 * tty_io.c and n_tty.c.
	 */
	tty_set_operations(brd->print_driver, &dgap_tty_ops);

	/* Register tty devices */
	rc = tty_register_driver(brd->serial_driver);
	if (rc < 0)
		goto free_print_drv;

	/* Register Transparent Print devices */
	rc = tty_register_driver(brd->print_driver);
	if (rc < 0)
		goto unregister_serial_drv;

	return 0;

unregister_serial_drv:
	tty_unregister_driver(brd->serial_driver);
free_print_drv:
	put_tty_driver(brd->print_driver);
free_serial_drv:
	put_tty_driver(brd->serial_driver);

	return rc;
}

static void dgap_tty_unregister(struct board_t *brd)
{
	tty_unregister_driver(brd->print_driver);
	tty_unregister_driver(brd->serial_driver);
	put_tty_driver(brd->print_driver);
	put_tty_driver(brd->serial_driver);
}

static int dgap_alloc_flipbuf(struct board_t *brd)
{
	/*
	 * allocate flip buffer for board.
	 */
	brd->flipbuf = kmalloc(MYFLIPLEN, GFP_KERNEL);
	if (!brd->flipbuf)
		return -ENOMEM;

	brd->flipflagbuf = kmalloc(MYFLIPLEN, GFP_KERNEL);
	if (!brd->flipflagbuf) {
		kfree(brd->flipbuf);
		return -ENOMEM;
	}

	return 0;
}

static void dgap_free_flipbuf(struct board_t *brd)
{
	kfree(brd->flipbuf);
	kfree(brd->flipflagbuf);
}

static struct board_t *dgap_verify_board(struct device *p)
{
	struct board_t *bd;

	if (!p)
		return NULL;

	bd = dev_get_drvdata(p);
	if (!bd || bd->magic != DGAP_BOARD_MAGIC || bd->state != BOARD_READY)
		return NULL;

	return bd;
}

static ssize_t dgap_ports_state_show(struct device *p,
				     struct device_attribute *attr,
				     char *buf)
{
	struct board_t *bd;
	int count = 0;
	unsigned int i;

	bd = dgap_verify_board(p);
	if (!bd)
		return 0;

	for (i = 0; i < bd->nasync; i++) {
		count += snprintf(buf + count, PAGE_SIZE - count,
			"%d %s\n", bd->channels[i]->ch_portnum,
			bd->channels[i]->ch_open_count ? "Open" : "Closed");
	}
	return count;
}
static DEVICE_ATTR(ports_state, S_IRUSR, dgap_ports_state_show, NULL);

static ssize_t dgap_ports_baud_show(struct device *p,
				    struct device_attribute *attr,
				    char *buf)
{
	struct board_t *bd;
	int count = 0;
	unsigned int i;

	bd = dgap_verify_board(p);
	if (!bd)
		return 0;

	for (i = 0; i < bd->nasync; i++) {
		count +=  snprintf(buf + count, PAGE_SIZE - count, "%d %d\n",
				   bd->channels[i]->ch_portnum,
				   bd->channels[i]->ch_baud_info);
	}
	return count;
}
static DEVICE_ATTR(ports_baud, S_IRUSR, dgap_ports_baud_show, NULL);

static ssize_t dgap_ports_msignals_show(struct device *p,
					struct device_attribute *attr,
					char *buf)
{
	struct board_t *bd;
	int count = 0;
	unsigned int i;

	bd = dgap_verify_board(p);
	if (!bd)
		return 0;

	for (i = 0; i < bd->nasync; i++) {
		if (bd->channels[i]->ch_open_count)
			count += snprintf(buf + count, PAGE_SIZE - count,
				"%d %s %s %s %s %s %s\n",
				bd->channels[i]->ch_portnum,
				(bd->channels[i]->ch_mostat &
				 UART_MCR_RTS) ? "RTS" : "",
				(bd->channels[i]->ch_mistat &
				 UART_MSR_CTS) ? "CTS" : "",
				(bd->channels[i]->ch_mostat &
				 UART_MCR_DTR) ? "DTR" : "",
				(bd->channels[i]->ch_mistat &
				 UART_MSR_DSR) ? "DSR" : "",
				(bd->channels[i]->ch_mistat &
				 UART_MSR_DCD) ? "DCD" : "",
				(bd->channels[i]->ch_mistat &
				 UART_MSR_RI)  ? "RI"  : "");
		else
			count += snprintf(buf + count, PAGE_SIZE - count,
				"%d\n", bd->channels[i]->ch_portnum);
	}
	return count;
}
static DEVICE_ATTR(ports_msignals, S_IRUSR, dgap_ports_msignals_show, NULL);

static ssize_t dgap_ports_iflag_show(struct device *p,
				     struct device_attribute *attr,
				     char *buf)
{
	struct board_t *bd;
	int count = 0;
	unsigned int i;

	bd = dgap_verify_board(p);
	if (!bd)
		return 0;

	for (i = 0; i < bd->nasync; i++)
		count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
				  bd->channels[i]->ch_portnum,
				  bd->channels[i]->ch_c_iflag);
	return count;
}
static DEVICE_ATTR(ports_iflag, S_IRUSR, dgap_ports_iflag_show, NULL);

static ssize_t dgap_ports_cflag_show(struct device *p,
				     struct device_attribute *attr,
				     char *buf)
{
	struct board_t *bd;
	int count = 0;
	unsigned int i;

	bd = dgap_verify_board(p);
	if (!bd)
		return 0;

	for (i = 0; i < bd->nasync; i++)
		count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
				  bd->channels[i]->ch_portnum,
				  bd->channels[i]->ch_c_cflag);
	return count;
}
static DEVICE_ATTR(ports_cflag, S_IRUSR, dgap_ports_cflag_show, NULL);

static ssize_t dgap_ports_oflag_show(struct device *p,
				     struct device_attribute *attr,
				     char *buf)
{
	struct board_t *bd;
	int count = 0;
	unsigned int i;

	bd = dgap_verify_board(p);
	if (!bd)
		return 0;

	for (i = 0; i < bd->nasync; i++)
		count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
				  bd->channels[i]->ch_portnum,
				  bd->channels[i]->ch_c_oflag);
	return count;
}
static DEVICE_ATTR(ports_oflag, S_IRUSR, dgap_ports_oflag_show, NULL);

static ssize_t dgap_ports_lflag_show(struct device *p,
				     struct device_attribute *attr,
				     char *buf)
{
	struct board_t *bd;
	int count = 0;
	unsigned int i;

	bd = dgap_verify_board(p);
	if (!bd)
		return 0;

	for (i = 0; i < bd->nasync; i++)
		count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
				  bd->channels[i]->ch_portnum,
				  bd->channels[i]->ch_c_lflag);
	return count;
}
static DEVICE_ATTR(ports_lflag, S_IRUSR, dgap_ports_lflag_show, NULL);

static ssize_t dgap_ports_digi_flag_show(struct device *p,
					 struct device_attribute *attr,
					 char *buf)
{
	struct board_t *bd;
	int count = 0;
	unsigned int i;

	bd = dgap_verify_board(p);
	if (!bd)
		return 0;

	for (i = 0; i < bd->nasync; i++)
		count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
				  bd->channels[i]->ch_portnum,
				  bd->channels[i]->ch_digi.digi_flags);
	return count;
}
static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgap_ports_digi_flag_show, NULL);

static ssize_t dgap_ports_rxcount_show(struct device *p,
				       struct device_attribute *attr,
				       char *buf)
{
	struct board_t *bd;
	int count = 0;
	unsigned int i;

	bd = dgap_verify_board(p);
	if (!bd)
		return 0;

	for (i = 0; i < bd->nasync; i++)
		count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
				  bd->channels[i]->ch_portnum,
				  bd->channels[i]->ch_rxcount);
	return count;
}
static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgap_ports_rxcount_show, NULL);

static ssize_t dgap_ports_txcount_show(struct device *p,
				       struct device_attribute *attr,
				       char *buf)
{
	struct board_t *bd;
	int count = 0;
	unsigned int i;

	bd = dgap_verify_board(p);
	if (!bd)
		return 0;

	for (i = 0; i < bd->nasync; i++)
		count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
				  bd->channels[i]->ch_portnum,
				  bd->channels[i]->ch_txcount);
	return count;
}
static DEVICE_ATTR(ports_txcount, S_IRUSR, dgap_ports_txcount_show, NULL);

static ssize_t dgap_tty_state_show(struct device *d,
				   struct device_attribute *attr,
				   char *buf)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;

	if (!d)
		return 0;
	un = dev_get_drvdata(d);
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;
	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;
	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return 0;
	if (bd->state != BOARD_READY)
		return 0;

	return snprintf(buf, PAGE_SIZE, "%s", un->un_open_count ?
			"Open" : "Closed");
}
static DEVICE_ATTR(state, S_IRUSR, dgap_tty_state_show, NULL);

static ssize_t dgap_tty_baud_show(struct device *d,
				  struct device_attribute *attr,
				  char *buf)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;

	if (!d)
		return 0;
	un = dev_get_drvdata(d);
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;
	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;
	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return 0;
	if (bd->state != BOARD_READY)
		return 0;

	return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_baud_info);
}
static DEVICE_ATTR(baud, S_IRUSR, dgap_tty_baud_show, NULL);

static ssize_t dgap_tty_msignals_show(struct device *d,
				      struct device_attribute *attr,
				      char *buf)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;

	if (!d)
		return 0;
	un = dev_get_drvdata(d);
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;
	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;
	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return 0;
	if (bd->state != BOARD_READY)
		return 0;

	if (ch->ch_open_count) {
		return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
			(ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
			(ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
			(ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
			(ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
			(ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
			(ch->ch_mistat & UART_MSR_RI)  ? "RI"  : "");
	}
	return 0;
}
static DEVICE_ATTR(msignals, S_IRUSR, dgap_tty_msignals_show, NULL);

static ssize_t dgap_tty_iflag_show(struct device *d,
				   struct device_attribute *attr,
				   char *buf)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;

	if (!d)
		return 0;
	un = dev_get_drvdata(d);
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;
	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;
	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return 0;
	if (bd->state != BOARD_READY)
		return 0;

	return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
}
static DEVICE_ATTR(iflag, S_IRUSR, dgap_tty_iflag_show, NULL);

static ssize_t dgap_tty_cflag_show(struct device *d,
				   struct device_attribute *attr,
				   char *buf)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;

	if (!d)
		return 0;
	un = dev_get_drvdata(d);
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;
	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;
	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return 0;
	if (bd->state != BOARD_READY)
		return 0;

	return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
}
static DEVICE_ATTR(cflag, S_IRUSR, dgap_tty_cflag_show, NULL);

static ssize_t dgap_tty_oflag_show(struct device *d,
				   struct device_attribute *attr,
				   char *buf)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;

	if (!d)
		return 0;
	un = dev_get_drvdata(d);
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;
	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;
	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return 0;
	if (bd->state != BOARD_READY)
		return 0;

	return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
}
static DEVICE_ATTR(oflag, S_IRUSR, dgap_tty_oflag_show, NULL);

static ssize_t dgap_tty_lflag_show(struct device *d,
				   struct device_attribute *attr,
				   char *buf)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;

	if (!d)
		return 0;
	un = dev_get_drvdata(d);
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;
	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;
	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return 0;
	if (bd->state != BOARD_READY)
		return 0;

	return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
}
static DEVICE_ATTR(lflag, S_IRUSR, dgap_tty_lflag_show, NULL);

static ssize_t dgap_tty_digi_flag_show(struct device *d,
				       struct device_attribute *attr,
				       char *buf)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;

	if (!d)
		return 0;
	un = dev_get_drvdata(d);
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;
	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;
	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return 0;
	if (bd->state != BOARD_READY)
		return 0;

	return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
}
static DEVICE_ATTR(digi_flag, S_IRUSR, dgap_tty_digi_flag_show, NULL);

static ssize_t dgap_tty_rxcount_show(struct device *d,
				     struct device_attribute *attr,
				     char *buf)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;

	if (!d)
		return 0;
	un = dev_get_drvdata(d);
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;
	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;
	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return 0;
	if (bd->state != BOARD_READY)
		return 0;

	return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
}
static DEVICE_ATTR(rxcount, S_IRUSR, dgap_tty_rxcount_show, NULL);

static ssize_t dgap_tty_txcount_show(struct device *d,
				     struct device_attribute *attr,
				     char *buf)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;

	if (!d)
		return 0;
	un = dev_get_drvdata(d);
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;
	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;
	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return 0;
	if (bd->state != BOARD_READY)
		return 0;

	return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
}
static DEVICE_ATTR(txcount, S_IRUSR, dgap_tty_txcount_show, NULL);

static ssize_t dgap_tty_name_show(struct device *d,
				  struct device_attribute *attr,
				  char *buf)
{
	struct board_t *bd;
	struct channel_t *ch;
	struct un_t *un;
	int cn;
	int bn;
	struct cnode *cptr;
	int found = FALSE;
	int ncount = 0;
	int starto = 0;
	int i;

	if (!d)
		return 0;
	un = dev_get_drvdata(d);
	if (!un || un->magic != DGAP_UNIT_MAGIC)
		return 0;
	ch = un->un_ch;
	if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
		return 0;
	bd = ch->ch_bd;
	if (!bd || bd->magic != DGAP_BOARD_MAGIC)
		return 0;
	if (bd->state != BOARD_READY)
		return 0;

	bn = bd->boardnum;
	cn = ch->ch_portnum;

	for (cptr = bd->bd_config; cptr; cptr = cptr->next) {
		if ((cptr->type == BNODE) &&
		    ((cptr->u.board.type == APORT2_920P) ||
		     (cptr->u.board.type == APORT4_920P) ||
		     (cptr->u.board.type == APORT8_920P) ||
		     (cptr->u.board.type == PAPORT4) ||
		     (cptr->u.board.type == PAPORT8))) {
			found = TRUE;
			if (cptr->u.board.v_start)
				starto = cptr->u.board.start;
			else
				starto = 1;
		}

		if (cptr->type == TNODE && found == TRUE) {
			char *ptr1;

			if (strstr(cptr->u.ttyname, "tty")) {
				ptr1 = cptr->u.ttyname;
				ptr1 += 3;
			} else
				ptr1 = cptr->u.ttyname;

			for (i = 0; i < dgap_config_get_num_prts(bd); i++) {
				if (cn != i)
					continue;

				return snprintf(buf, PAGE_SIZE, "%s%s%02d\n",
						(un->un_type == DGAP_PRINT) ?
						 "pr" : "tty",
						ptr1, i + starto);
			}
		}

		if (cptr->type == CNODE) {
			for (i = 0; i < cptr->u.conc.nport; i++) {
				if (cn != (i + ncount))
					continue;

				return snprintf(buf, PAGE_SIZE, "%s%s%02ld\n",
						(un->un_type == DGAP_PRINT) ?
						 "pr" : "tty",
						cptr->u.conc.id,
						i + (cptr->u.conc.v_start ?
						     cptr->u.conc.start : 1));
			}

			ncount += cptr->u.conc.nport;
		}

		if (cptr->type == MNODE) {
			for (i = 0; i < cptr->u.module.nport; i++) {
				if (cn != (i + ncount))
					continue;

				return snprintf(buf, PAGE_SIZE, "%s%s%02ld\n",
						(un->un_type == DGAP_PRINT) ?
						 "pr" : "tty",
						cptr->u.module.id,
						i + (cptr->u.module.v_start ?
						     cptr->u.module.start : 1));
			}

			ncount += cptr->u.module.nport;
		}
	}

	return snprintf(buf, PAGE_SIZE, "%s_dgap_%d_%d\n",
		(un->un_type == DGAP_PRINT) ? "pr" : "tty", bn, cn);
}
static DEVICE_ATTR(custom_name, S_IRUSR, dgap_tty_name_show, NULL);

static struct attribute *dgap_sysfs_tty_entries[] = {
	&dev_attr_state.attr,
	&dev_attr_baud.attr,
	&dev_attr_msignals.attr,
	&dev_attr_iflag.attr,
	&dev_attr_cflag.attr,
	&dev_attr_oflag.attr,
	&dev_attr_lflag.attr,
	&dev_attr_digi_flag.attr,
	&dev_attr_rxcount.attr,
	&dev_attr_txcount.attr,
	&dev_attr_custom_name.attr,
	NULL
};


/* this function creates the sys files that will export each signal status
 * to sysfs each value will be put in a separate filename
 */
static void dgap_create_ports_sysfiles(struct board_t *bd)
{
	dev_set_drvdata(&bd->pdev->dev, bd);
	device_create_file(&bd->pdev->dev, &dev_attr_ports_state);
	device_create_file(&bd->pdev->dev, &dev_attr_ports_baud);
	device_create_file(&bd->pdev->dev, &dev_attr_ports_msignals);
	device_create_file(&bd->pdev->dev, &dev_attr_ports_iflag);
	device_create_file(&bd->pdev->dev, &dev_attr_ports_cflag);
	device_create_file(&bd->pdev->dev, &dev_attr_ports_oflag);
	device_create_file(&bd->pdev->dev, &dev_attr_ports_lflag);
	device_create_file(&bd->pdev->dev, &dev_attr_ports_digi_flag);
	device_create_file(&bd->pdev->dev, &dev_attr_ports_rxcount);
	device_create_file(&bd->pdev->dev, &dev_attr_ports_txcount);
}

/* removes all the sys files created for that port */
static void dgap_remove_ports_sysfiles(struct board_t *bd)
{
	device_remove_file(&bd->pdev->dev, &dev_attr_ports_state);
	device_remove_file(&bd->pdev->dev, &dev_attr_ports_baud);
	device_remove_file(&bd->pdev->dev, &dev_attr_ports_msignals);
	device_remove_file(&bd->pdev->dev, &dev_attr_ports_iflag);
	device_remove_file(&bd->pdev->dev, &dev_attr_ports_cflag);
	device_remove_file(&bd->pdev->dev, &dev_attr_ports_oflag);
	device_remove_file(&bd->pdev->dev, &dev_attr_ports_lflag);
	device_remove_file(&bd->pdev->dev, &dev_attr_ports_digi_flag);
	device_remove_file(&bd->pdev->dev, &dev_attr_ports_rxcount);
	device_remove_file(&bd->pdev->dev, &dev_attr_ports_txcount);
}

/*
 * Copies the BIOS code from the user to the board,
 * and starts the BIOS running.
 */
static void dgap_do_bios_load(struct board_t *brd, const u8 *ubios, int len)
{
	u8 __iomem *addr;
	uint offset;
	unsigned int i;

	if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
		return;

	addr = brd->re_map_membase;

	/*
	 * clear POST area
	 */
	for (i = 0; i < 16; i++)
		writeb(0, addr + POSTAREA + i);

	/*
	 * Download bios
	 */
	offset = 0x1000;
	memcpy_toio(addr + offset, ubios, len);

	writel(0x0bf00401, addr);
	writel(0, (addr + 4));

	/* Clear the reset, and change states. */
	writeb(FEPCLR, brd->re_map_port);
}

/*
 * Checks to see if the BIOS completed running on the card.
 */
static int dgap_test_bios(struct board_t *brd)
{
	u8 __iomem *addr;
	u16 word;
	u16 err1;
	u16 err2;

	if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
		return -EINVAL;

	addr = brd->re_map_membase;
	word = readw(addr + POSTAREA);

	/*
	 * It can take 5-6 seconds for a board to
	 * pass the bios self test and post results.
	 * Give it 10 seconds.
	 */
	brd->wait_for_bios = 0;
	while (brd->wait_for_bios < 1000) {
		/* Check to see if BIOS thinks board is good. (GD). */
		if (word == *(u16 *)"GD")
			return 0;
		msleep_interruptible(10);
		brd->wait_for_bios++;
		word = readw(addr + POSTAREA);
	}

	/* Gave up on board after too long of time taken */
	err1 = readw(addr + SEQUENCE);
	err2 = readw(addr + ERROR);
	dev_warn(&brd->pdev->dev, "%s failed diagnostics.  Error #(%x,%x).\n",
		 brd->name, err1, err2);
	brd->state = BOARD_FAILED;
	brd->dpastatus = BD_NOBIOS;

	return -EIO;
}

/*
 * Copies the FEP code from the user to the board,
 * and starts the FEP running.
 */
static void dgap_do_fep_load(struct board_t *brd, const u8 *ufep, int len)
{
	u8 __iomem *addr;
	uint offset;

	if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
		return;

	addr = brd->re_map_membase;

	/*
	 * Download FEP
	 */
	offset = 0x1000;
	memcpy_toio(addr + offset, ufep, len);

	/*
	 * If board is a concentrator product, we need to give
	 * it its config string describing how the concentrators look.
	 */
	if ((brd->type == PCX) || (brd->type == PEPC)) {
		u8 string[100];
		u8 __iomem *config;
		u8 *xconfig;
		unsigned int i = 0;

		xconfig = dgap_create_config_string(brd, string);

		/* Write string to board memory */
		config = addr + CONFIG;
		for (; i < CONFIGSIZE; i++, config++, xconfig++) {
			writeb(*xconfig, config);
			if ((*xconfig & 0xff) == 0xff)
				break;
		}
	}

	writel(0xbfc01004, (addr + 0xc34));
	writel(0x3, (addr + 0xc30));
}

/*
 * Waits for the FEP to report thats its ready for us to use.
 */
static int dgap_test_fep(struct board_t *brd)
{
	u8 __iomem *addr;
	u16 word;
	u16 err1;
	u16 err2;

	if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
		return -EINVAL;

	addr = brd->re_map_membase;
	word = readw(addr + FEPSTAT);

	/*
	 * It can take 2-3 seconds for the FEP to
	 * be up and running. Give it 5 secs.
	 */
	brd->wait_for_fep = 0;
	while (brd->wait_for_fep < 500) {
		/* Check to see if FEP is up and running now. */
		if (word == *(u16 *)"OS") {
			/*
			 * Check to see if the board can support FEP5+ commands.
			*/
			word = readw(addr + FEP5_PLUS);
			if (word == *(u16 *)"5A")
				brd->bd_flags |= BD_FEP5PLUS;

			return 0;
		}
		msleep_interruptible(10);
		brd->wait_for_fep++;
		word = readw(addr + FEPSTAT);
	}

	/* Gave up on board after too long of time taken */
	err1 = readw(addr + SEQUENCE);
	err2 = readw(addr + ERROR);
	dev_warn(&brd->pdev->dev,
		 "FEPOS for %s not functioning.  Error #(%x,%x).\n",
		 brd->name, err1, err2);
	brd->state = BOARD_FAILED;
	brd->dpastatus = BD_NOFEP;

	return -EIO;
}

/*
 * Physically forces the FEP5 card to reset itself.
 */
static void dgap_do_reset_board(struct board_t *brd)
{
	u8 check;
	u32 check1;
	u32 check2;
	unsigned int i;

	if (!brd || (brd->magic != DGAP_BOARD_MAGIC) ||
	    !brd->re_map_membase || !brd->re_map_port)
		return;

	/* FEPRST does not vary among supported boards */
	writeb(FEPRST, brd->re_map_port);

	for (i = 0; i <= 1000; i++) {
		check = readb(brd->re_map_port) & 0xe;
		if (check == FEPRST)
			break;
		udelay(10);
	}
	if (i > 1000) {
		dev_warn(&brd->pdev->dev,
			 "dgap: Board not resetting...  Failing board.\n");
		brd->state = BOARD_FAILED;
		brd->dpastatus = BD_NOFEP;
		return;
	}

	/*
	 * Make sure there really is memory out there.
	 */
	writel(0xa55a3cc3, (brd->re_map_membase + LOWMEM));
	writel(0x5aa5c33c, (brd->re_map_membase + HIGHMEM));
	check1 = readl(brd->re_map_membase + LOWMEM);
	check2 = readl(brd->re_map_membase + HIGHMEM);

	if ((check1 != 0xa55a3cc3) || (check2 != 0x5aa5c33c)) {
		dev_warn(&brd->pdev->dev,
			 "No memory at %p for board.\n",
			 brd->re_map_membase);
		brd->state = BOARD_FAILED;
		brd->dpastatus = BD_NOFEP;
		return;
	}
}

#ifdef DIGI_CONCENTRATORS_SUPPORTED
/*
 * Sends a concentrator image into the FEP5 board.
 */
static void dgap_do_conc_load(struct board_t *brd, u8 *uaddr, int len)
{
	char __iomem *vaddr;
	u16 offset;
	struct downld_t *to_dp;

	if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
		return;

	vaddr = brd->re_map_membase;

	offset = readw((u16 *)(vaddr + DOWNREQ));
	to_dp = (struct downld_t *)(vaddr + (int)offset);
	memcpy_toio(to_dp, uaddr, len);

	/* Tell card we have data for it */
	writew(0, vaddr + (DOWNREQ));

	brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS;
}
#endif

#define EXPANSION_ROM_SIZE	(64 * 1024)
#define FEP5_ROM_MAGIC		(0xFEFFFFFF)

static void dgap_get_vpd(struct board_t *brd)
{
	u32 magic;
	u32 base_offset;
	u16 rom_offset;
	u16 vpd_offset;
	u16 image_length;
	u16 i;
	u8 byte1;
	u8 byte2;

	/*
	 * Poke the magic number at the PCI Rom Address location.
	 * If VPD is supported, the value read from that address
	 * will be non-zero.
	 */
	magic = FEP5_ROM_MAGIC;
	pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic);
	pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic);

	/* VPD not supported, bail */
	if (!magic)
		return;

	/*
	 * To get to the OTPROM memory, we have to send the boards base
	 * address or'ed with 1 into the PCI Rom Address location.
	 */
	magic = brd->membase | 0x01;
	pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic);
	pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic);

	byte1 = readb(brd->re_map_membase);
	byte2 = readb(brd->re_map_membase + 1);

	/*
	 * If the board correctly swapped to the OTPROM memory,
	 * the first 2 bytes (header) should be 0x55, 0xAA
	 */
	if (byte1 == 0x55 && byte2 == 0xAA) {
		base_offset = 0;

		/*
		 * We have to run through all the OTPROM memory looking
		 * for the VPD offset.
		 */
		while (base_offset <= EXPANSION_ROM_SIZE) {
			/*
			 * Lots of magic numbers here.
			 *
			 * The VPD offset is located inside the ROM Data
			 * Structure.
			 *
			 * We also have to remember the length of each
			 * ROM Data Structure, so we can "hop" to the next
			 * entry if the VPD isn't in the current
			 * ROM Data Structure.
			 */
			rom_offset = readw(brd->re_map_membase +
						base_offset + 0x18);
			image_length = readw(brd->re_map_membase +
						rom_offset + 0x10) * 512;
			vpd_offset = readw(brd->re_map_membase +
						rom_offset + 0x08);

			/* Found the VPD entry */
			if (vpd_offset)
				break;

			/* We didn't find a VPD entry, go to next ROM entry. */
			base_offset += image_length;

			byte1 = readb(brd->re_map_membase + base_offset);
			byte2 = readb(brd->re_map_membase + base_offset + 1);

			/*
			 * If the new ROM offset doesn't have 0x55, 0xAA
			 * as its header, we have run out of ROM.
			 */
			if (byte1 != 0x55 || byte2 != 0xAA)
				break;
		}

		/*
		 * If we have a VPD offset, then mark the board
		 * as having a valid VPD, and copy VPDSIZE (512) bytes of
		 * that VPD to the buffer we have in our board structure.
		 */
		if (vpd_offset) {
			brd->bd_flags |= BD_HAS_VPD;
			for (i = 0; i < VPDSIZE; i++) {
				brd->vpd[i] = readb(brd->re_map_membase +
							vpd_offset + i);
			}
		}
	}

	/*
	 * We MUST poke the magic number at the PCI Rom Address location again.
	 * This makes the card report the regular board memory back to us,
	 * rather than the OTPROM memory.
	 */
	magic = FEP5_ROM_MAGIC;
	pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic);
}


static ssize_t dgap_driver_version_show(struct device_driver *ddp, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART);
}
static DRIVER_ATTR(version, S_IRUSR, dgap_driver_version_show, NULL);


static ssize_t dgap_driver_boards_show(struct device_driver *ddp, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", dgap_numboards);
}
static DRIVER_ATTR(boards, S_IRUSR, dgap_driver_boards_show, NULL);


static ssize_t dgap_driver_maxboards_show(struct device_driver *ddp, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS);
}
static DRIVER_ATTR(maxboards, S_IRUSR, dgap_driver_maxboards_show, NULL);


static ssize_t dgap_driver_pollcounter_show(struct device_driver *ddp,
					    char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%ld\n", dgap_poll_counter);
}
static DRIVER_ATTR(pollcounter, S_IRUSR, dgap_driver_pollcounter_show, NULL);

static ssize_t dgap_driver_pollrate_show(struct device_driver *ddp, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%dms\n", dgap_poll_tick);
}

static ssize_t dgap_driver_pollrate_store(struct device_driver *ddp,
					  const char *buf, size_t count)
{
	if (sscanf(buf, "%d\n", &dgap_poll_tick) != 1)
		return -EINVAL;
	return count;
}
static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgap_driver_pollrate_show,
		   dgap_driver_pollrate_store);


static int dgap_create_driver_sysfiles(struct pci_driver *dgap_driver)
{
	int rc = 0;
	struct device_driver *driverfs = &dgap_driver->driver;

	rc |= driver_create_file(driverfs, &driver_attr_version);
	rc |= driver_create_file(driverfs, &driver_attr_boards);
	rc |= driver_create_file(driverfs, &driver_attr_maxboards);
	rc |= driver_create_file(driverfs, &driver_attr_pollrate);
	rc |= driver_create_file(driverfs, &driver_attr_pollcounter);

	return rc;
}

static void dgap_remove_driver_sysfiles(struct pci_driver *dgap_driver)
{
	struct device_driver *driverfs = &dgap_driver->driver;

	driver_remove_file(driverfs, &driver_attr_version);
	driver_remove_file(driverfs, &driver_attr_boards);
	driver_remove_file(driverfs, &driver_attr_maxboards);
	driver_remove_file(driverfs, &driver_attr_pollrate);
	driver_remove_file(driverfs, &driver_attr_pollcounter);
}

static struct attribute_group dgap_tty_attribute_group = {
	.name = NULL,
	.attrs = dgap_sysfs_tty_entries,
};

static void dgap_create_tty_sysfs(struct un_t *un, struct device *c)
{
	int ret;

	ret = sysfs_create_group(&c->kobj, &dgap_tty_attribute_group);
	if (ret)
		return;

	dev_set_drvdata(c, un);
}

static void dgap_remove_tty_sysfs(struct device *c)
{
	sysfs_remove_group(&c->kobj, &dgap_tty_attribute_group);
}

/*
 * Create pr and tty device entries
 */
static int dgap_tty_register_ports(struct board_t *brd)
{
	struct channel_t *ch;
	int i;
	int ret;

	brd->serial_ports = kcalloc(brd->nasync, sizeof(*brd->serial_ports),
					GFP_KERNEL);
	if (!brd->serial_ports)
		return -ENOMEM;

	brd->printer_ports = kcalloc(brd->nasync, sizeof(*brd->printer_ports),
					GFP_KERNEL);
	if (!brd->printer_ports) {
		ret = -ENOMEM;
		goto free_serial_ports;
	}

	for (i = 0; i < brd->nasync; i++) {
		tty_port_init(&brd->serial_ports[i]);
		tty_port_init(&brd->printer_ports[i]);
	}

	ch = brd->channels[0];
	for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) {
		struct device *classp;

		classp = tty_port_register_device(&brd->serial_ports[i],
						  brd->serial_driver,
						  i, NULL);

		if (IS_ERR(classp)) {
			ret = PTR_ERR(classp);
			goto unregister_ttys;
		}

		dgap_create_tty_sysfs(&ch->ch_tun, classp);
		ch->ch_tun.un_sysfs = classp;

		classp = tty_port_register_device(&brd->printer_ports[i],
						  brd->print_driver,
						  i, NULL);

		if (IS_ERR(classp)) {
			ret = PTR_ERR(classp);
			goto unregister_ttys;
		}

		dgap_create_tty_sysfs(&ch->ch_pun, classp);
		ch->ch_pun.un_sysfs = classp;
	}
	dgap_create_ports_sysfiles(brd);

	return 0;

unregister_ttys:
	while (i >= 0) {
		ch = brd->channels[i];
		if (ch->ch_tun.un_sysfs) {
			dgap_remove_tty_sysfs(ch->ch_tun.un_sysfs);
			tty_unregister_device(brd->serial_driver, i);
		}

		if (ch->ch_pun.un_sysfs) {
			dgap_remove_tty_sysfs(ch->ch_pun.un_sysfs);
			tty_unregister_device(brd->print_driver, i);
		}
		i--;
	}

	for (i = 0; i < brd->nasync; i++) {
		tty_port_destroy(&brd->serial_ports[i]);
		tty_port_destroy(&brd->printer_ports[i]);
	}

	kfree(brd->printer_ports);
	brd->printer_ports = NULL;

free_serial_ports:
	kfree(brd->serial_ports);
	brd->serial_ports = NULL;

	return ret;
}

/*
 * dgap_cleanup_tty()
 *
 * Uninitialize the TTY portion of this driver.  Free all memory and
 * resources.
 */
static void dgap_cleanup_tty(struct board_t *brd)
{
	struct device *dev;
	unsigned int i;

	for (i = 0; i < brd->nasync; i++) {
		tty_port_destroy(&brd->serial_ports[i]);
		dev = brd->channels[i]->ch_tun.un_sysfs;
		dgap_remove_tty_sysfs(dev);
		tty_unregister_device(brd->serial_driver, i);
	}
	tty_unregister_driver(brd->serial_driver);
	put_tty_driver(brd->serial_driver);
	kfree(brd->serial_ports);

	for (i = 0; i < brd->nasync; i++) {
		tty_port_destroy(&brd->printer_ports[i]);
		dev = brd->channels[i]->ch_pun.un_sysfs;
		dgap_remove_tty_sysfs(dev);
		tty_unregister_device(brd->print_driver, i);
	}
	tty_unregister_driver(brd->print_driver);
	put_tty_driver(brd->print_driver);
	kfree(brd->printer_ports);
}

static int dgap_request_irq(struct board_t *brd)
{
	int rc;

	if (!brd || brd->magic != DGAP_BOARD_MAGIC)
		return -ENODEV;

	/*
	 * Set up our interrupt handler if we are set to do interrupts.
	 */
	if (dgap_config_get_useintr(brd) && brd->irq) {
		rc = request_irq(brd->irq, dgap_intr, IRQF_SHARED, "DGAP", brd);

		if (!rc)
			brd->intr_used = 1;
	}
	return 0;
}

static void dgap_free_irq(struct board_t *brd)
{
	if (brd->intr_used && brd->irq)
		free_irq(brd->irq, brd);
}

static int dgap_firmware_load(struct pci_dev *pdev, int card_type,
			      struct board_t *brd)
{
	const struct firmware *fw;
	char *tmp_ptr;
	int ret;
	char *dgap_config_buf;

	dgap_get_vpd(brd);
	dgap_do_reset_board(brd);

	if (fw_info[card_type].conf_name) {
		ret = request_firmware(&fw, fw_info[card_type].conf_name,
				       &pdev->dev);
		if (ret) {
			dev_err(&pdev->dev, "config file %s not found\n",
				fw_info[card_type].conf_name);
			return ret;
		}

		dgap_config_buf = kzalloc(fw->size + 1, GFP_KERNEL);
		if (!dgap_config_buf) {
			release_firmware(fw);
			return -ENOMEM;
		}

		memcpy(dgap_config_buf, fw->data, fw->size);
		release_firmware(fw);

		/*
		 * preserve dgap_config_buf
		 * as dgap_parsefile would
		 * otherwise alter it.
		 */
		tmp_ptr = dgap_config_buf;

		if (dgap_parsefile(&tmp_ptr) != 0) {
			kfree(dgap_config_buf);
			return -EINVAL;
		}
		kfree(dgap_config_buf);
	}

	/*
	 * Match this board to a config the user created for us.
	 */
	brd->bd_config =
		dgap_find_config(brd->type, brd->pci_bus, brd->pci_slot);

	/*
	 * Because the 4 port Xr products share the same PCI ID
	 * as the 8 port Xr products, if we receive a NULL config
	 * back, and this is a PAPORT8 board, retry with a
	 * PAPORT4 attempt as well.
	 */
	if (brd->type == PAPORT8 && !brd->bd_config)
		brd->bd_config =
			dgap_find_config(PAPORT4, brd->pci_bus, brd->pci_slot);

	if (!brd->bd_config) {
		dev_err(&pdev->dev, "No valid configuration found\n");
		return -EINVAL;
	}

	if (fw_info[card_type].bios_name) {
		ret = request_firmware(&fw, fw_info[card_type].bios_name,
				       &pdev->dev);
		if (ret) {
			dev_err(&pdev->dev, "bios file %s not found\n",
				fw_info[card_type].bios_name);
			return ret;
		}
		dgap_do_bios_load(brd, fw->data, fw->size);
		release_firmware(fw);

		/* Wait for BIOS to test board... */
		ret = dgap_test_bios(brd);
		if (ret)
			return ret;
	}

	if (fw_info[card_type].fep_name) {
		ret = request_firmware(&fw, fw_info[card_type].fep_name,
				       &pdev->dev);
		if (ret) {
			dev_err(&pdev->dev, "dgap: fep file %s not found\n",
				fw_info[card_type].fep_name);
			return ret;
		}
		dgap_do_fep_load(brd, fw->data, fw->size);
		release_firmware(fw);

		/* Wait for FEP to load on board... */
		ret = dgap_test_fep(brd);
		if (ret)
			return ret;
	}

#ifdef DIGI_CONCENTRATORS_SUPPORTED
	/*
	 * If this is a CX or EPCX, we need to see if the firmware
	 * is requesting a concentrator image from us.
	 */
	if ((bd->type == PCX) || (bd->type == PEPC)) {
		chk_addr = (u16 *)(vaddr + DOWNREQ);
		/* Nonzero if FEP is requesting concentrator image. */
		check = readw(chk_addr);
		vaddr = brd->re_map_membase;
	}

	if (fw_info[card_type].con_name && check && vaddr) {
		ret = request_firmware(&fw, fw_info[card_type].con_name,
				       &pdev->dev);
		if (ret) {
			dev_err(&pdev->dev, "conc file %s not found\n",
				fw_info[card_type].con_name);
			return ret;
		}
		/* Put concentrator firmware loading code here */
		offset = readw((u16 *)(vaddr + DOWNREQ));
		memcpy_toio(offset, fw->data, fw->size);

		dgap_do_conc_load(brd, (char *)fw->data, fw->size)
		release_firmware(fw);
	}
#endif

	return 0;
}

/*
 * dgap_tty_init()
 *
 * Init the tty subsystem.  Called once per board after board has been
 * downloaded and init'ed.
 */
static int dgap_tty_init(struct board_t *brd)
{
	int i;
	int tlw;
	uint true_count;
	u8 __iomem *vaddr;
	u8 modem;
	struct channel_t *ch;
	struct bs_t __iomem *bs;
	struct cm_t __iomem *cm;
	int ret;

	/*
	 * Initialize board structure elements.
	 */

	vaddr = brd->re_map_membase;
	true_count = readw((vaddr + NCHAN));

	brd->nasync = dgap_config_get_num_prts(brd);

	if (!brd->nasync)
		brd->nasync = brd->maxports;

	if (brd->nasync > brd->maxports)
		brd->nasync = brd->maxports;

	if (true_count != brd->nasync) {
		dev_warn(&brd->pdev->dev,
			 "%s configured for %d ports, has %d ports.\n",
			 brd->name, brd->nasync, true_count);

		if ((brd->type == PPCM) &&
		    (true_count == 64 || true_count == 0)) {
			dev_warn(&brd->pdev->dev,
				 "Please make SURE the EBI cable running from the card\n");
			dev_warn(&brd->pdev->dev,
				 "to each EM module is plugged into EBI IN!\n");
		}

		brd->nasync = true_count;

		/* If no ports, don't bother going any further */
		if (!brd->nasync) {
			brd->state = BOARD_FAILED;
			brd->dpastatus = BD_NOFEP;
			return -EIO;
		}
	}

	/*
	 * Allocate channel memory that might not have been allocated
	 * when the driver was first loaded.
	 */
	for (i = 0; i < brd->nasync; i++) {
		brd->channels[i] =
			kzalloc(sizeof(struct channel_t), GFP_KERNEL);
		if (!brd->channels[i]) {
			ret = -ENOMEM;
			goto free_chan;
		}
	}

	ch = brd->channels[0];
	vaddr = brd->re_map_membase;

	bs = (struct bs_t __iomem *)((ulong)vaddr + CHANBUF);
	cm = (struct cm_t __iomem *)((ulong)vaddr + CMDBUF);

	brd->bd_bs = bs;

	/* Set up channel variables */
	for (i = 0; i < brd->nasync; i++, ch = brd->channels[i], bs++) {
		spin_lock_init(&ch->ch_lock);

		/* Store all our magic numbers */
		ch->magic = DGAP_CHANNEL_MAGIC;
		ch->ch_tun.magic = DGAP_UNIT_MAGIC;
		ch->ch_tun.un_type = DGAP_SERIAL;
		ch->ch_tun.un_ch = ch;
		ch->ch_tun.un_dev = i;

		ch->ch_pun.magic = DGAP_UNIT_MAGIC;
		ch->ch_pun.un_type = DGAP_PRINT;
		ch->ch_pun.un_ch = ch;
		ch->ch_pun.un_dev = i;

		ch->ch_vaddr = vaddr;
		ch->ch_bs = bs;
		ch->ch_cm = cm;
		ch->ch_bd = brd;
		ch->ch_portnum = i;
		ch->ch_digi = dgap_digi_init;

		/*
		 * Set up digi dsr and dcd bits based on altpin flag.
		 */
		if (dgap_config_get_altpin(brd)) {
			ch->ch_dsr	= DM_CD;
			ch->ch_cd	= DM_DSR;
			ch->ch_digi.digi_flags |= DIGI_ALTPIN;
		} else {
			ch->ch_cd	= DM_CD;
			ch->ch_dsr	= DM_DSR;
		}

		ch->ch_taddr = vaddr + (ioread16(&ch->ch_bs->tx_seg) << 4);
		ch->ch_raddr = vaddr + (ioread16(&ch->ch_bs->rx_seg) << 4);
		ch->ch_tx_win = 0;
		ch->ch_rx_win = 0;
		ch->ch_tsize = readw(&ch->ch_bs->tx_max) + 1;
		ch->ch_rsize = readw(&ch->ch_bs->rx_max) + 1;
		ch->ch_tstart = 0;
		ch->ch_rstart = 0;

		/*
		 * Set queue water marks, interrupt mask,
		 * and general tty parameters.
		 */
		tlw = ch->ch_tsize >= 2000 ? ((ch->ch_tsize * 5) / 8) :
						ch->ch_tsize / 2;
		ch->ch_tlw = tlw;

		dgap_cmdw(ch, STLOW, tlw, 0);

		dgap_cmdw(ch, SRLOW, ch->ch_rsize / 2, 0);

		dgap_cmdw(ch, SRHIGH, 7 * ch->ch_rsize / 8, 0);

		ch->ch_mistat = readb(&ch->ch_bs->m_stat);

		init_waitqueue_head(&ch->ch_flags_wait);
		init_waitqueue_head(&ch->ch_tun.un_flags_wait);
		init_waitqueue_head(&ch->ch_pun.un_flags_wait);

		/* Turn on all modem interrupts for now */
		modem = (DM_CD | DM_DSR | DM_CTS | DM_RI);
		writeb(modem, &ch->ch_bs->m_int);

		/*
		 * Set edelay to 0 if interrupts are turned on,
		 * otherwise set edelay to the usual 100.
		 */
		if (brd->intr_used)
			writew(0, &ch->ch_bs->edelay);
		else
			writew(100, &ch->ch_bs->edelay);

		writeb(1, &ch->ch_bs->idata);
	}

	return 0;

free_chan:
	while (--i >= 0) {
		kfree(brd->channels[i]);
		brd->channels[i] = NULL;
	}
	return ret;
}

/*
 * dgap_tty_free()
 *
 * Free the channles which are allocated in dgap_tty_init().
 */
static void dgap_tty_free(struct board_t *brd)
{
	int i;

	for (i = 0; i < brd->nasync; i++)
		kfree(brd->channels[i]);
}

static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	int rc;
	struct board_t *brd;

	if (dgap_numboards >= MAXBOARDS)
		return -EPERM;

	rc = pci_enable_device(pdev);
	if (rc)
		return -EIO;

	brd = dgap_found_board(pdev, ent->driver_data, dgap_numboards);
	if (IS_ERR(brd))
		return PTR_ERR(brd);

	rc = dgap_firmware_load(pdev, ent->driver_data, brd);
	if (rc)
		goto cleanup_brd;

	rc = dgap_alloc_flipbuf(brd);
	if (rc)
		goto cleanup_brd;

	rc = dgap_tty_register(brd);
	if (rc)
		goto free_flipbuf;

	rc = dgap_request_irq(brd);
	if (rc)
		goto unregister_tty;

	/*
	 * Do tty device initialization.
	 */
	rc = dgap_tty_init(brd);
	if (rc < 0)
		goto free_irq;

	rc = dgap_tty_register_ports(brd);
	if (rc)
		goto tty_free;

	brd->state = BOARD_READY;
	brd->dpastatus = BD_RUNNING;

	dgap_board[dgap_numboards++] = brd;

	return 0;

tty_free:
	dgap_tty_free(brd);
free_irq:
	dgap_free_irq(brd);
unregister_tty:
	dgap_tty_unregister(brd);
free_flipbuf:
	dgap_free_flipbuf(brd);
cleanup_brd:
	dgap_cleanup_nodes();
	dgap_unmap(brd);
	kfree(brd);

	return rc;
}

/*
 * dgap_cleanup_board()
 *
 * Free all the memory associated with a board
 */
static void dgap_cleanup_board(struct board_t *brd)
{
	unsigned int i;

	if (!brd || brd->magic != DGAP_BOARD_MAGIC)
		return;

	dgap_free_irq(brd);

	tasklet_kill(&brd->helper_tasklet);

	dgap_unmap(brd);

	/* Free all allocated channels structs */
	for (i = 0; i < MAXPORTS ; i++)
		kfree(brd->channels[i]);

	kfree(brd->flipbuf);
	kfree(brd->flipflagbuf);

	dgap_board[brd->boardnum] = NULL;

	kfree(brd);
}

static void dgap_stop(bool removesys, struct pci_driver *drv)
{
	unsigned long lock_flags;

	spin_lock_irqsave(&dgap_poll_lock, lock_flags);
	dgap_poll_stop = 1;
	spin_unlock_irqrestore(&dgap_poll_lock, lock_flags);

	del_timer_sync(&dgap_poll_timer);
	if (removesys)
		dgap_remove_driver_sysfiles(drv);

	device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0));
	class_destroy(dgap_class);
	unregister_chrdev(DIGI_DGAP_MAJOR, "dgap");
}

static void dgap_remove_one(struct pci_dev *dev)
{
	unsigned int i;
	struct pci_driver *drv = to_pci_driver(dev->dev.driver);

	dgap_stop(true, drv);
	for (i = 0; i < dgap_numboards; ++i) {
		dgap_remove_ports_sysfiles(dgap_board[i]);
		dgap_cleanup_tty(dgap_board[i]);
		dgap_cleanup_board(dgap_board[i]);
	}

	dgap_cleanup_nodes();
}

static struct pci_driver dgap_driver = {
	.name		= "dgap",
	.probe		= dgap_init_one,
	.id_table	= dgap_pci_tbl,
	.remove		= dgap_remove_one,
};

/*
 * Start of driver.
 */
static int dgap_start(void)
{
	int rc;
	unsigned long flags;
	struct device *device;

	dgap_numboards = 0;

	pr_info("For the tools package please visit http://www.digi.com\n");

	/*
	 * Register our base character device into the kernel.
	 */

	/*
	 * Register management/dpa devices
	 */
	rc = register_chrdev(DIGI_DGAP_MAJOR, "dgap", &dgap_board_fops);
	if (rc < 0)
		return rc;

	dgap_class = class_create(THIS_MODULE, "dgap_mgmt");
	if (IS_ERR(dgap_class)) {
		rc = PTR_ERR(dgap_class);
		goto failed_class;
	}

	device = device_create(dgap_class, NULL,
			       MKDEV(DIGI_DGAP_MAJOR, 0),
			       NULL, "dgap_mgmt");
	if (IS_ERR(device)) {
		rc = PTR_ERR(device);
		goto failed_device;
	}

	/* Start the poller */
	spin_lock_irqsave(&dgap_poll_lock, flags);
	setup_timer(&dgap_poll_timer, dgap_poll_handler, 0);
	dgap_poll_timer.data = 0;
	dgap_poll_time = jiffies + dgap_jiffies_from_ms(dgap_poll_tick);
	dgap_poll_timer.expires = dgap_poll_time;
	spin_unlock_irqrestore(&dgap_poll_lock, flags);

	add_timer(&dgap_poll_timer);

	return rc;

failed_device:
	class_destroy(dgap_class);
failed_class:
	unregister_chrdev(DIGI_DGAP_MAJOR, "dgap");
	return rc;
}

/************************************************************************
 *
 * Driver load/unload functions
 *
 ************************************************************************/

/*
 * init_module()
 *
 * Module load.  This is where it all starts.
 */
static int dgap_init_module(void)
{
	int rc;

	pr_info("%s, Digi International Part Number %s\n", DG_NAME, DG_PART);

	rc = dgap_start();
	if (rc)
		return rc;

	rc = pci_register_driver(&dgap_driver);
	if (rc) {
		dgap_stop(false, NULL);
		return rc;
	}

	rc = dgap_create_driver_sysfiles(&dgap_driver);
	if (rc)
		goto err_unregister;

	dgap_driver_state = DRIVER_READY;

	return 0;

err_unregister:
	pci_unregister_driver(&dgap_driver);
	return rc;
}

/*
 * dgap_cleanup_module()
 *
 * Module unload.  This is where it all ends.
 */
static void dgap_cleanup_module(void)
{
	if (dgap_numboards)
		pci_unregister_driver(&dgap_driver);
}

module_init(dgap_init_module);
module_exit(dgap_cleanup_module);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Digi International, http://www.digi.com");
MODULE_DESCRIPTION("Driver for the Digi International EPCA PCI based product line");
MODULE_SUPPORTED_DEVICE("dgap");
