/*
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 *	NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
 *
 *	This is shared code between Digi's CVS archive and the
 *	Linux Kernel sources.
 *	Changing the source just for reformatting needlessly breaks
 *	our CVS diff history.
 *
 *	Send any bug fixes/changes to:  Eng.Linux at digi dot com.
 *	Thank you.
 *
 */


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include "dgnc_driver.h"
#include "dgnc_pci.h"
#include "dpacompat.h"
#include "dgnc_mgmt.h"
#include "dgnc_tty.h"
#include "dgnc_trace.h"
#include "dgnc_cls.h"
#include "dgnc_neo.h"
#include "dgnc_sysfs.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Digi International, http://www.digi.com");
MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line");
MODULE_SUPPORTED_DEVICE("dgnc");

/*
 * insmod command line overrideable parameters
 *
 * NOTE: we use a set of macros to create the variables, which allows
 * us to specify the variable type, name, initial value, and description.
 */
PARM_INT(debug,		0x00,		0644,	"Driver debugging level");
PARM_INT(rawreadok,	1,		0644,	"Bypass flip buffers on input");
PARM_INT(trcbuf_size,	0x100000,	0644, 	"Debugging trace buffer size.");

/**************************************************************************
 *
 * protos for this file
 *
 */
static int		dgnc_start(void);
static int		dgnc_finalize_board_init(struct dgnc_board *brd);
static void		dgnc_init_globals(void);
static int		dgnc_found_board(struct pci_dev *pdev, int id);
static void		dgnc_cleanup_board(struct dgnc_board *brd);
static void		dgnc_poll_handler(ulong dummy);
static int		dgnc_init_pci(void);
static int		dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static void		dgnc_remove_one(struct pci_dev *dev);
static int		dgnc_probe1(struct pci_dev *pdev, int card_type);
static void		dgnc_do_remap(struct dgnc_board *brd);

/* Driver load/unload functions */
int		dgnc_init_module(void);
void		dgnc_cleanup_module(void);

module_init(dgnc_init_module);
module_exit(dgnc_cleanup_module);


/*
 * File operations permitted on Control/Management major.
 */
static const struct file_operations dgnc_BoardFops =
{
	.owner		=	THIS_MODULE,
	.unlocked_ioctl =  	dgnc_mgmt_ioctl,
	.open		=	dgnc_mgmt_open,
	.release	=	dgnc_mgmt_close
};


/*
 * Globals
 */
uint			dgnc_NumBoards;
struct dgnc_board		*dgnc_Board[MAXBOARDS];
DEFINE_SPINLOCK(dgnc_global_lock);
int			dgnc_driver_state = DRIVER_INITIALIZED;
ulong			dgnc_poll_counter;
uint			dgnc_Major;
int			dgnc_poll_tick = 20;	/* Poll interval - 20 ms */

/*
 * Static vars.
 */
static uint		dgnc_Major_Control_Registered = FALSE;
static uint		dgnc_driver_start = FALSE;

static struct class *dgnc_class;

/*
 * Poller stuff
 */
static 			DEFINE_SPINLOCK(dgnc_poll_lock);	/* Poll scheduling lock */
static ulong		dgnc_poll_time;				/* Time of next poll */
static uint		dgnc_poll_stop;				/* Used to tell poller to stop */
static struct timer_list dgnc_poll_timer;


static struct pci_device_id dgnc_pci_tbl[] = {
	{	DIGI_VID, PCI_DEVICE_CLASSIC_4_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	0 },
	{	DIGI_VID, PCI_DEVICE_CLASSIC_4_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	1 },
	{	DIGI_VID, PCI_DEVICE_CLASSIC_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	2 },
	{	DIGI_VID, PCI_DEVICE_CLASSIC_8_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	3 },
	{	DIGI_VID, PCI_DEVICE_NEO_4_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,		4 },
	{	DIGI_VID, PCI_DEVICE_NEO_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,		5 },
	{	DIGI_VID, PCI_DEVICE_NEO_2DB9_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	6 },
	{	DIGI_VID, PCI_DEVICE_NEO_2DB9PRI_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	7 },
	{	DIGI_VID, PCI_DEVICE_NEO_2RJ45_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	8 },
	{	DIGI_VID, PCI_DEVICE_NEO_2RJ45PRI_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	9 },
	{	DIGI_VID, PCI_DEVICE_NEO_1_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	10 },
	{	DIGI_VID, PCI_DEVICE_NEO_1_422_485_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	11 },
	{	DIGI_VID, PCI_DEVICE_NEO_2_422_485_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	12 },
	{	DIGI_VID, PCI_DEVICE_NEO_EXPRESS_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	 13 },
	{	DIGI_VID, PCI_DEVICE_NEO_EXPRESS_4_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	14 },
	{	DIGI_VID, PCI_DEVICE_NEO_EXPRESS_4RJ45_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	15 },
	{	DIGI_VID, PCI_DEVICE_NEO_EXPRESS_8RJ45_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	16 },
	{0,}						/* 0 terminated list. */
};
MODULE_DEVICE_TABLE(pci, dgnc_pci_tbl);

struct board_id {
	uchar *name;
	uint maxports;
	unsigned int is_pci_express;
};

static struct board_id dgnc_Ids[] =
{
	{	PCI_DEVICE_CLASSIC_4_PCI_NAME,		4,	0	},
	{	PCI_DEVICE_CLASSIC_4_422_PCI_NAME,	4,	0	},
	{	PCI_DEVICE_CLASSIC_8_PCI_NAME,		8,	0	},
	{	PCI_DEVICE_CLASSIC_8_422_PCI_NAME,	8,	0	},
	{	PCI_DEVICE_NEO_4_PCI_NAME,		4,	0	},
	{	PCI_DEVICE_NEO_8_PCI_NAME,		8,	0	},
	{	PCI_DEVICE_NEO_2DB9_PCI_NAME,		2,	0	},
	{	PCI_DEVICE_NEO_2DB9PRI_PCI_NAME,	2,	0	},
	{	PCI_DEVICE_NEO_2RJ45_PCI_NAME,		2,	0	},
	{	PCI_DEVICE_NEO_2RJ45PRI_PCI_NAME,	2,	0	},
	{	PCI_DEVICE_NEO_1_422_PCI_NAME,		1,	0	},
	{	PCI_DEVICE_NEO_1_422_485_PCI_NAME,	1,	0	},
	{	PCI_DEVICE_NEO_2_422_485_PCI_NAME,	2,	0	},
	{	PCI_DEVICE_NEO_EXPRESS_8_PCI_NAME,	8,	1	},
	{	PCI_DEVICE_NEO_EXPRESS_4_PCI_NAME,	4,	1	},
	{	PCI_DEVICE_NEO_EXPRESS_4RJ45_PCI_NAME,	4,	1	},
	{	PCI_DEVICE_NEO_EXPRESS_8RJ45_PCI_NAME,	8,	1	},
	{	NULL,					0,	0	}
};

static struct pci_driver dgnc_driver = {
	.name		= "dgnc",
	.probe		= dgnc_init_one,
	.id_table       = dgnc_pci_tbl,
	.remove		= dgnc_remove_one,
};


char *dgnc_state_text[] = {
	"Board Failed",
	"Board Found",
	"Board READY",
};

char *dgnc_driver_state_text[] = {
	"Driver Initialized",
	"Driver Ready."
};



/************************************************************************
 *
 * Driver load/unload functions
 *
 ************************************************************************/


/*
 * init_module()
 *
 * Module load.  This is where it all starts.
 */
int dgnc_init_module(void)
{
	int rc = 0;

	APR(("%s, Digi International Part Number %s\n", DG_NAME, DG_PART));

	/*
	 * Initialize global stuff
	 */
	rc = dgnc_start();

	if (rc < 0) {
		return rc;
	}

	/*
	 * Find and configure all the cards
	 */
	rc = dgnc_init_pci();

	/*
	 * If something went wrong in the scan, bail out of driver.
	 */
	if (rc < 0) {
		/* Only unregister the pci driver if it was actually registered. */
		if (dgnc_NumBoards)
			pci_unregister_driver(&dgnc_driver);
		else
			pr_warn("WARNING: dgnc driver load failed.  No Digi Neo or Classic boards found.\n");

		dgnc_cleanup_module();
	}
	else {
		dgnc_create_driver_sysfiles(&dgnc_driver);
	}

	DPR_INIT(("Finished init_module. Returning %d\n", rc));
	return rc;
}


/*
 * Start of driver.
 */
static int dgnc_start(void)
{
	int rc = 0;
	unsigned long flags;

	if (dgnc_driver_start == FALSE) {

		dgnc_driver_start = TRUE;

		/* make sure that the globals are init'd before we do anything else */
		dgnc_init_globals();

		dgnc_NumBoards = 0;

		APR(("For the tools package or updated drivers please visit http://www.digi.com\n"));

		/*
		 * Register our base character device into the kernel.
		 * This allows the download daemon to connect to the downld device
		 * before any of the boards are init'ed.
		 */
		if (!dgnc_Major_Control_Registered) {
			/*
			 * Register management/dpa devices
			 */
			rc = register_chrdev(0, "dgnc", &dgnc_BoardFops);
			if (rc <= 0) {
				APR(("Can't register dgnc driver device (%d)\n", rc));
				rc = -ENXIO;
				return rc;
			}
			dgnc_Major = rc;

			dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt");
			device_create(dgnc_class, NULL,
				MKDEV(dgnc_Major, 0),
				NULL, "dgnc_mgmt");
			dgnc_Major_Control_Registered = TRUE;
		}

		/*
		 * Init any global tty stuff.
		 */
		rc = dgnc_tty_preinit();

		if (rc < 0) {
			APR(("tty preinit - not enough memory (%d)\n", rc));
			return rc;
		}

		/* Start the poller */
		DGNC_LOCK(dgnc_poll_lock, flags);
		init_timer(&dgnc_poll_timer);
		dgnc_poll_timer.function = dgnc_poll_handler;
		dgnc_poll_timer.data = 0;
		dgnc_poll_time = jiffies + dgnc_jiffies_from_ms(dgnc_poll_tick);
		dgnc_poll_timer.expires = dgnc_poll_time;
		DGNC_UNLOCK(dgnc_poll_lock, flags);

		add_timer(&dgnc_poll_timer);

		dgnc_driver_state = DRIVER_READY;
	}

	return rc;
}

/*
 * Register pci driver, and return how many boards we have.
 */
static int dgnc_init_pci(void)
{
	return pci_register_driver(&dgnc_driver);
}


/* returns count (>= 0), or negative on error */
static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	int rc;

	/* wake up and enable device */
	rc = pci_enable_device(pdev);

	if (rc < 0) {
		rc = -EIO;
	} else {
		rc = dgnc_probe1(pdev, ent->driver_data);
		if (rc == 0) {
			dgnc_NumBoards++;
			DPR_INIT(("Incrementing numboards to %d\n", dgnc_NumBoards));
		}
	}
	return rc;
}

static int dgnc_probe1(struct pci_dev *pdev, int card_type)
{
	return dgnc_found_board(pdev, card_type);
}


static void dgnc_remove_one(struct pci_dev *dev)
{
	/* Do Nothing */
}

/*
 * dgnc_cleanup_module()
 *
 * Module unload.  This is where it all ends.
 */
void dgnc_cleanup_module(void)
{
	int i;
	ulong lock_flags;

	DGNC_LOCK(dgnc_poll_lock, lock_flags);
	dgnc_poll_stop = 1;
	DGNC_UNLOCK(dgnc_poll_lock, lock_flags);

	/* Turn off poller right away. */
	del_timer_sync(&dgnc_poll_timer);

	dgnc_remove_driver_sysfiles(&dgnc_driver);

	if (dgnc_Major_Control_Registered) {
		device_destroy(dgnc_class, MKDEV(dgnc_Major, 0));
		class_destroy(dgnc_class);
		unregister_chrdev(dgnc_Major, "dgnc");
	}

	for (i = 0; i < dgnc_NumBoards; ++i) {
		dgnc_remove_ports_sysfiles(dgnc_Board[i]);
		dgnc_tty_uninit(dgnc_Board[i]);
		dgnc_cleanup_board(dgnc_Board[i]);
	}

	dgnc_tty_post_uninit();

#if defined(DGNC_TRACER)
	/* last thing, make sure we release the tracebuffer */
	dgnc_tracer_free();
#endif
	if (dgnc_NumBoards)
		pci_unregister_driver(&dgnc_driver);
}


/*
 * dgnc_cleanup_board()
 *
 * Free all the memory associated with a board
 */
static void dgnc_cleanup_board(struct dgnc_board *brd)
{
	int i = 0;

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

	switch (brd->device) {
	case PCI_DEVICE_CLASSIC_4_DID:
	case PCI_DEVICE_CLASSIC_8_DID:
	case PCI_DEVICE_CLASSIC_4_422_DID:
	case PCI_DEVICE_CLASSIC_8_422_DID:

		/* Tell card not to interrupt anymore. */
		outb(0, brd->iobase + 0x4c);
		break;

	default:
		break;
	}

	if (brd->irq)
		free_irq(brd->irq, brd);

	tasklet_kill(&brd->helper_tasklet);

	if (brd->re_map_membase) {
		iounmap(brd->re_map_membase);
		brd->re_map_membase = NULL;
	}

	if (brd->msgbuf_head) {
		unsigned long flags;

		DGNC_LOCK(dgnc_global_lock, flags);
		brd->msgbuf = NULL;
		printk("%s", brd->msgbuf_head);
		kfree(brd->msgbuf_head);
		brd->msgbuf_head = NULL;
		DGNC_UNLOCK(dgnc_global_lock, flags);
	}

	/* Free all allocated channels structs */
	for (i = 0; i < MAXPORTS ; i++) {
		if (brd->channels[i]) {
			if (brd->channels[i]->ch_rqueue)
				kfree(brd->channels[i]->ch_rqueue);
			if (brd->channels[i]->ch_equeue)
				kfree(brd->channels[i]->ch_equeue);
			if (brd->channels[i]->ch_wqueue)
				kfree(brd->channels[i]->ch_wqueue);

			kfree(brd->channels[i]);
			brd->channels[i] = NULL;
		}
	}

	if (brd->flipbuf)
		kfree(brd->flipbuf);

	dgnc_Board[brd->boardnum] = NULL;

	kfree(brd);
}


/*
 * dgnc_found_board()
 *
 * A board has been found, init it.
 */
static int dgnc_found_board(struct pci_dev *pdev, int id)
{
	struct dgnc_board *brd;
	unsigned int pci_irq;
	int i = 0;
	int rc = 0;
	unsigned long flags;

	/* get the board structure and prep it */
	brd = dgnc_Board[dgnc_NumBoards] =
		kzalloc(sizeof(*brd), GFP_KERNEL);
	if (!brd) 
		return -ENOMEM;

	/* make a temporary message buffer for the boot messages */
	brd->msgbuf = brd->msgbuf_head =
		kzalloc(sizeof(u8) * 8192, GFP_KERNEL);
	if (!brd->msgbuf) {
		kfree(brd);
		return -ENOMEM;
	}

	/* store the info for the board we've found */
	brd->magic = DGNC_BOARD_MAGIC;
	brd->boardnum = dgnc_NumBoards;
	brd->vendor = dgnc_pci_tbl[id].vendor;
	brd->device = dgnc_pci_tbl[id].device;
	brd->pdev = pdev;
	brd->pci_bus = pdev->bus->number;
	brd->pci_slot = PCI_SLOT(pdev->devfn);
	brd->name = dgnc_Ids[id].name;
	brd->maxports = dgnc_Ids[id].maxports;
	if (dgnc_Ids[i].is_pci_express)
		brd->bd_flags |= BD_IS_PCI_EXPRESS;
	brd->dpastatus = BD_NOFEP;
	init_waitqueue_head(&brd->state_wait);

	DGNC_SPINLOCK_INIT(brd->bd_lock);
	DGNC_SPINLOCK_INIT(brd->bd_intr_lock);

	brd->state		= BOARD_FOUND;

	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;


	switch(brd->device) {

	case PCI_DEVICE_CLASSIC_4_DID:
	case PCI_DEVICE_CLASSIC_8_DID:
	case PCI_DEVICE_CLASSIC_4_422_DID:
	case PCI_DEVICE_CLASSIC_8_422_DID:

		brd->dpatype = T_CLASSIC | T_PCIBUS;

		DPR_INIT(("dgnc_found_board - Classic.\n"));

		/*
		 * For PCI ClassicBoards
		 * PCI Local Address (i.e. "resource" number) space
		 * 0	PLX Memory Mapped Config
		 * 1	PLX I/O Mapped Config
		 * 2	I/O Mapped UARTs and Status
		 * 3	Memory Mapped VPD
		 * 4	Memory Mapped UARTs and Status
		 */


		/* get the PCI Base Address Registers */
		brd->membase = pci_resource_start(pdev, 4);

		if (!brd->membase) {
			APR(("card has no PCI IO resources, failing board.\n"));
			return -ENODEV;
		}

		brd->membase_end = pci_resource_end(pdev, 4);

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

		brd->iobase	= pci_resource_start(pdev, 1);
		brd->iobase_end = pci_resource_end(pdev, 1);
		brd->iobase	= ((unsigned int) (brd->iobase)) & 0xFFFE;

		/* Assign the board_ops struct */
		brd->bd_ops = &dgnc_cls_ops;

		brd->bd_uart_offset = 0x8;
		brd->bd_dividend = 921600;

		dgnc_do_remap(brd);

		/* Get and store the board VPD, if it exists */
		brd->bd_ops->vpd(brd);

		/*
		 * Enable Local Interrupt 1		  (0x1),
		 * Local Interrupt 1 Polarity Active high (0x2),
		 * Enable PCI interrupt			  (0x40)
		 */
		outb(0x43, brd->iobase + 0x4c);

		break;


	case PCI_DEVICE_NEO_4_DID:
	case PCI_DEVICE_NEO_8_DID:
	case PCI_DEVICE_NEO_2DB9_DID:
	case PCI_DEVICE_NEO_2DB9PRI_DID:
	case PCI_DEVICE_NEO_2RJ45_DID:
	case PCI_DEVICE_NEO_2RJ45PRI_DID:
	case PCI_DEVICE_NEO_1_422_DID:
	case PCI_DEVICE_NEO_1_422_485_DID:
	case PCI_DEVICE_NEO_2_422_485_DID:
	case PCI_DEVICE_NEO_EXPRESS_8_DID:
	case PCI_DEVICE_NEO_EXPRESS_4_DID:
	case PCI_DEVICE_NEO_EXPRESS_4RJ45_DID:
	case PCI_DEVICE_NEO_EXPRESS_8RJ45_DID:

		/*
		 * This chip is set up 100% when we get to it.
		 * No need to enable global interrupts or anything.
		 */
		if (brd->bd_flags & BD_IS_PCI_EXPRESS)
			brd->dpatype = T_NEO_EXPRESS | T_PCIBUS;
		else
			brd->dpatype = T_NEO | T_PCIBUS;

		DPR_INIT(("dgnc_found_board - NEO.\n"));

		/* get the PCI Base Address Registers */
		brd->membase     = pci_resource_start(pdev, 0);
		brd->membase_end = pci_resource_end(pdev, 0);

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

		/* Assign the board_ops struct */
		brd->bd_ops = &dgnc_neo_ops;

		brd->bd_uart_offset = 0x200;
		brd->bd_dividend = 921600;

		dgnc_do_remap(brd);

		if (brd->re_map_membase) {

			/* After remap is complete, we need to read and store the dvid */
			brd->dvid = readb(brd->re_map_membase + 0x8D);

			/* Get and store the board VPD, if it exists */
			brd->bd_ops->vpd(brd);
		}
		break;

	default:
		APR(("Did not find any compatible Neo or Classic PCI boards in system.\n"));
		return -ENXIO;

	}

	/*
	 * Do tty device initialization.
	 */

	rc = dgnc_tty_register(brd);
	if (rc < 0) {
		dgnc_tty_uninit(brd);
		APR(("Can't register tty devices (%d)\n", rc));
		brd->state = BOARD_FAILED;
		brd->dpastatus = BD_NOFEP;
		goto failed;
	}

	rc = dgnc_finalize_board_init(brd);
	if (rc < 0) {
		APR(("Can't finalize board init (%d)\n", rc));
		brd->state = BOARD_FAILED;
		brd->dpastatus = BD_NOFEP;

		goto failed;
	}

	rc = dgnc_tty_init(brd);
	if (rc < 0) {
		dgnc_tty_uninit(brd);
		APR(("Can't init tty devices (%d)\n", rc));
		brd->state = BOARD_FAILED;
		brd->dpastatus = BD_NOFEP;

		goto failed;
	}

	brd->state = BOARD_READY;
	brd->dpastatus = BD_RUNNING;

	dgnc_create_ports_sysfiles(brd);

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

	DPR_INIT(("dgnc_scan(%d) - printing out the msgbuf\n", i));
	DGNC_LOCK(dgnc_global_lock, flags);
	brd->msgbuf = NULL;
	printk("%s", brd->msgbuf_head);
	kfree(brd->msgbuf_head);
	brd->msgbuf_head = NULL;
	DGNC_UNLOCK(dgnc_global_lock, flags);

	/*
	 * allocate flip buffer for board.
	 *
	 * Okay to malloc with GFP_KERNEL, we are not at interrupt
	 * context, and there are no locks held.
	 */
	brd->flipbuf = kzalloc(MYFLIPLEN, GFP_KERNEL);

	wake_up_interruptible(&brd->state_wait);

	return 0;

failed:

	return -ENXIO;

}


static int dgnc_finalize_board_init(struct dgnc_board *brd) {
	int rc = 0;

	DPR_INIT(("dgnc_finalize_board_init() - start\n"));

	if (!brd || brd->magic != DGNC_BOARD_MAGIC)
		return -ENODEV;

	DPR_INIT(("dgnc_finalize_board_init() - start #2\n"));

	if (brd->irq) {
		rc = request_irq(brd->irq, brd->bd_ops->intr, IRQF_SHARED, "DGNC", brd);

		if (rc) {
			printk("Failed to hook IRQ %d\n",brd->irq);
			brd->state = BOARD_FAILED;
			brd->dpastatus = BD_NOFEP;
			rc = -ENODEV;
		} else {
			DPR_INIT(("Requested and received usage of IRQ %d\n", brd->irq));
		}
	}
	return rc;
}

/*
 * Remap PCI memory.
 */
static void dgnc_do_remap(struct dgnc_board *brd)
{

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

	brd->re_map_membase = ioremap(brd->membase, 0x1000);

	DPR_INIT(("remapped mem: 0x%p\n", brd->re_map_membase));
}


/*****************************************************************************
*
* Function:
*
*    dgnc_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 dgnc_poll_handler(ulong dummy)
{
	struct dgnc_board *brd;
	unsigned long lock_flags;
	int i;
	unsigned long new_time;

	dgnc_poll_counter++;

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

	/* Go thru each board, kicking off a tasklet for each if needed */
	for (i = 0; i < dgnc_NumBoards; i++) {
		brd = dgnc_Board[i];

		DGNC_LOCK(brd->bd_lock, lock_flags);

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

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

		DGNC_UNLOCK(brd->bd_lock, lock_flags);
	}

schedule_poller:

	/*
	 * Schedule ourself back at the nominal wakeup interval.
	 */
	DGNC_LOCK(dgnc_poll_lock, lock_flags);
	dgnc_poll_time += dgnc_jiffies_from_ms(dgnc_poll_tick);

	new_time = dgnc_poll_time - jiffies;

	if ((ulong) new_time >= 2 * dgnc_poll_tick) {
		dgnc_poll_time = jiffies +  dgnc_jiffies_from_ms(dgnc_poll_tick);
	}

	init_timer(&dgnc_poll_timer);
	dgnc_poll_timer.function = dgnc_poll_handler;
	dgnc_poll_timer.data = 0;
	dgnc_poll_timer.expires = dgnc_poll_time;
	DGNC_UNLOCK(dgnc_poll_lock, lock_flags);

	if (!dgnc_poll_stop)
		add_timer(&dgnc_poll_timer);
}

/*
 * dgnc_init_globals()
 *
 * This is where we initialize the globals from the static insmod
 * configuration variables.  These are declared near the head of
 * this file.
 */
static void dgnc_init_globals(void)
{
	int i = 0;

	dgnc_rawreadok		= rawreadok;
	dgnc_trcbuf_size	= trcbuf_size;
	dgnc_debug		= debug;

	for (i = 0; i < MAXBOARDS; i++) {
		dgnc_Board[i] = NULL;
	}

	init_timer(&dgnc_poll_timer);
}


/************************************************************************
 *
 * Utility functions
 *
 ************************************************************************/

/*
 * dgnc_ms_sleep()
 *
 * Put the driver to sleep for x ms's
 *
 * Returns 0 if timed out, !0 (showing signal) if interrupted by a signal.
 */
int dgnc_ms_sleep(ulong ms)
{
	current->state = TASK_INTERRUPTIBLE;
	schedule_timeout((ms * HZ) / 1000);
	return signal_pending(current);
}



/*
 *      dgnc_ioctl_name() : Returns a text version of each ioctl value.
 */
char *dgnc_ioctl_name(int cmd)
{
	switch(cmd) {

	case TCGETA:		return "TCGETA";
	case TCGETS:		return "TCGETS";
	case TCSETA:		return "TCSETA";
	case TCSETS:		return "TCSETS";
	case TCSETAW:		return "TCSETAW";
	case TCSETSW:		return "TCSETSW";
	case TCSETAF:		return "TCSETAF";
	case TCSETSF:		return "TCSETSF";
	case TCSBRK:		return "TCSBRK";
	case TCXONC:		return "TCXONC";
	case TCFLSH:		return "TCFLSH";
	case TIOCGSID:		return "TIOCGSID";

	case TIOCGETD:		return "TIOCGETD";
	case TIOCSETD:		return "TIOCSETD";
	case TIOCGWINSZ:	return "TIOCGWINSZ";
	case TIOCSWINSZ:	return "TIOCSWINSZ";

	case TIOCMGET:		return "TIOCMGET";
	case TIOCMSET:		return "TIOCMSET";
	case TIOCMBIS:		return "TIOCMBIS";
	case TIOCMBIC:		return "TIOCMBIC";

	/* from digi.h */
	case DIGI_SETA:		return "DIGI_SETA";
	case DIGI_SETAW:	return "DIGI_SETAW";
	case DIGI_SETAF:	return "DIGI_SETAF";
	case DIGI_SETFLOW:	return "DIGI_SETFLOW";
	case DIGI_SETAFLOW:	return "DIGI_SETAFLOW";
	case DIGI_GETFLOW:	return "DIGI_GETFLOW";
	case DIGI_GETAFLOW:	return "DIGI_GETAFLOW";
	case DIGI_GETA:		return "DIGI_GETA";
	case DIGI_GEDELAY:	return "DIGI_GEDELAY";
	case DIGI_SEDELAY:	return "DIGI_SEDELAY";
	case DIGI_GETCUSTOMBAUD: return "DIGI_GETCUSTOMBAUD";
	case DIGI_SETCUSTOMBAUD: return "DIGI_SETCUSTOMBAUD";
	case TIOCMODG:		return "TIOCMODG";
	case TIOCMODS:		return "TIOCMODS";
	case TIOCSDTR:		return "TIOCSDTR";
	case TIOCCDTR:		return "TIOCCDTR";

	default:		return "unknown";
	}
}
