/*
  * icom.c
  *
  * Copyright (C) 2001 IBM Corporation. All rights reserved.
  *
  * Serial device driver.
  *
  * Based on code from serial.c
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  *
  */
#define SERIAL_DO_RESTART
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/termios.h>
#include <linux/fs.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/serial_reg.h>
#include <linux/major.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/smp.h>
#include <linux/spinlock.h>
#include <linux/kref.h>
#include <linux/firmware.h>
#include <linux/bitops.h>

#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>

#include "icom.h"

/*#define ICOM_TRACE		 enable port trace capabilities */

#define ICOM_DRIVER_NAME "icom"
#define ICOM_VERSION_STR "1.3.1"
#define NR_PORTS	       128
#define ICOM_PORT ((struct icom_port *)port)
#define to_icom_adapter(d) container_of(d, struct icom_adapter, kref)

static const struct pci_device_id icom_pci_table[] = {
	{
		.vendor = PCI_VENDOR_ID_IBM,
		.device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1,
		.subvendor = PCI_ANY_ID,
		.subdevice = PCI_ANY_ID,
		.driver_data = ADAPTER_V1,
	},
	{
		.vendor = PCI_VENDOR_ID_IBM,
		.device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
		.subvendor = PCI_VENDOR_ID_IBM,
		.subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX,
		.driver_data = ADAPTER_V2,
	},
	{
		.vendor = PCI_VENDOR_ID_IBM,
		.device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
		.subvendor = PCI_VENDOR_ID_IBM,
		.subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM,
		.driver_data = ADAPTER_V2,
	},
	{
		.vendor = PCI_VENDOR_ID_IBM,
		.device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
		.subvendor = PCI_VENDOR_ID_IBM,
		.subdevice = PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL,
		.driver_data = ADAPTER_V2,
	},
	{
		.vendor = PCI_VENDOR_ID_IBM,
		.device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
		.subvendor = PCI_VENDOR_ID_IBM,
		.subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM_PCIE,
		.driver_data = ADAPTER_V2,
	},
	{}
};

struct lookup_proc_table start_proc[4] = {
	{NULL, ICOM_CONTROL_START_A},
	{NULL, ICOM_CONTROL_START_B},
	{NULL, ICOM_CONTROL_START_C},
	{NULL, ICOM_CONTROL_START_D}
};


struct lookup_proc_table stop_proc[4] = {
	{NULL, ICOM_CONTROL_STOP_A},
	{NULL, ICOM_CONTROL_STOP_B},
	{NULL, ICOM_CONTROL_STOP_C},
	{NULL, ICOM_CONTROL_STOP_D}
};

struct lookup_int_table int_mask_tbl[4] = {
	{NULL, ICOM_INT_MASK_PRC_A},
	{NULL, ICOM_INT_MASK_PRC_B},
	{NULL, ICOM_INT_MASK_PRC_C},
	{NULL, ICOM_INT_MASK_PRC_D},
};


MODULE_DEVICE_TABLE(pci, icom_pci_table);

static LIST_HEAD(icom_adapter_head);

/* spinlock for adapter initialization and changing adapter operations */
static spinlock_t icom_lock;

#ifdef ICOM_TRACE
static inline void trace(struct icom_port *, char *, unsigned long) {};
#else
static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
#endif
static void icom_kref_release(struct kref *kref);

static void free_port_memory(struct icom_port *icom_port)
{
	struct pci_dev *dev = icom_port->adapter->pci_dev;

	trace(icom_port, "RET_PORT_MEM", 0);
	if (icom_port->recv_buf) {
		pci_free_consistent(dev, 4096, icom_port->recv_buf,
				    icom_port->recv_buf_pci);
		icom_port->recv_buf = NULL;
	}
	if (icom_port->xmit_buf) {
		pci_free_consistent(dev, 4096, icom_port->xmit_buf,
				    icom_port->xmit_buf_pci);
		icom_port->xmit_buf = NULL;
	}
	if (icom_port->statStg) {
		pci_free_consistent(dev, 4096, icom_port->statStg,
				    icom_port->statStg_pci);
		icom_port->statStg = NULL;
	}

	if (icom_port->xmitRestart) {
		pci_free_consistent(dev, 4096, icom_port->xmitRestart,
				    icom_port->xmitRestart_pci);
		icom_port->xmitRestart = NULL;
	}
}

static int __devinit get_port_memory(struct icom_port *icom_port)
{
	int index;
	unsigned long stgAddr;
	unsigned long startStgAddr;
	unsigned long offset;
	struct pci_dev *dev = icom_port->adapter->pci_dev;

	icom_port->xmit_buf =
	    pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci);
	if (!icom_port->xmit_buf) {
		dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
		return -ENOMEM;
	}

	trace(icom_port, "GET_PORT_MEM",
	      (unsigned long) icom_port->xmit_buf);

	icom_port->recv_buf =
	    pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci);
	if (!icom_port->recv_buf) {
		dev_err(&dev->dev, "Can not allocate Receive buffer\n");
		free_port_memory(icom_port);
		return -ENOMEM;
	}
	trace(icom_port, "GET_PORT_MEM",
	      (unsigned long) icom_port->recv_buf);

	icom_port->statStg =
	    pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci);
	if (!icom_port->statStg) {
		dev_err(&dev->dev, "Can not allocate Status buffer\n");
		free_port_memory(icom_port);
		return -ENOMEM;
	}
	trace(icom_port, "GET_PORT_MEM",
	      (unsigned long) icom_port->statStg);

	icom_port->xmitRestart =
	    pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci);
	if (!icom_port->xmitRestart) {
		dev_err(&dev->dev,
			"Can not allocate xmit Restart buffer\n");
		free_port_memory(icom_port);
		return -ENOMEM;
	}

	memset(icom_port->statStg, 0, 4096);

	/* FODs: Frame Out Descriptor Queue, this is a FIFO queue that
           indicates that frames are to be transmitted
	*/

	stgAddr = (unsigned long) icom_port->statStg;
	for (index = 0; index < NUM_XBUFFS; index++) {
		trace(icom_port, "FOD_ADDR", stgAddr);
		stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
		if (index < (NUM_XBUFFS - 1)) {
			memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
			icom_port->statStg->xmit[index].leLengthASD =
			    (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
			trace(icom_port, "FOD_ADDR", stgAddr);
			trace(icom_port, "FOD_XBUFF",
			      (unsigned long) icom_port->xmit_buf);
			icom_port->statStg->xmit[index].leBuffer =
			    cpu_to_le32(icom_port->xmit_buf_pci);
		} else if (index == (NUM_XBUFFS - 1)) {
			memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
			icom_port->statStg->xmit[index].leLengthASD =
			    (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
			trace(icom_port, "FOD_XBUFF",
			      (unsigned long) icom_port->xmit_buf);
			icom_port->statStg->xmit[index].leBuffer =
			    cpu_to_le32(icom_port->xmit_buf_pci);
		} else {
			memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
		}
	}
	/* FIDs */
	startStgAddr = stgAddr;

	/* fill in every entry, even if no buffer */
	for (index = 0; index <  NUM_RBUFFS; index++) {
		trace(icom_port, "FID_ADDR", stgAddr);
		stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
		icom_port->statStg->rcv[index].leLength = 0;
		icom_port->statStg->rcv[index].WorkingLength =
		    (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
		if (index < (NUM_RBUFFS - 1) ) {
			offset = stgAddr - (unsigned long) icom_port->statStg;
			icom_port->statStg->rcv[index].leNext =
			      cpu_to_le32(icom_port-> statStg_pci + offset);
			trace(icom_port, "FID_RBUFF",
			      (unsigned long) icom_port->recv_buf);
			icom_port->statStg->rcv[index].leBuffer =
			    cpu_to_le32(icom_port->recv_buf_pci);
		} else if (index == (NUM_RBUFFS -1) ) {
			offset = startStgAddr - (unsigned long) icom_port->statStg;
			icom_port->statStg->rcv[index].leNext =
			    cpu_to_le32(icom_port-> statStg_pci + offset);
			trace(icom_port, "FID_RBUFF",
			      (unsigned long) icom_port->recv_buf + 2048);
			icom_port->statStg->rcv[index].leBuffer =
			    cpu_to_le32(icom_port->recv_buf_pci + 2048);
		} else {
			icom_port->statStg->rcv[index].leNext = 0;
			icom_port->statStg->rcv[index].leBuffer = 0;
		}
	}

	return 0;
}

static void stop_processor(struct icom_port *icom_port)
{
	unsigned long temp;
	unsigned long flags;
	int port;

	spin_lock_irqsave(&icom_lock, flags);

	port = icom_port->port;
	if (port == 0 || port == 1)
		stop_proc[port].global_control_reg = &icom_port->global_reg->control;
	else
		stop_proc[port].global_control_reg = &icom_port->global_reg->control_2;


	if (port < 4) {
		temp = readl(stop_proc[port].global_control_reg);
		temp =
	    		(temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
		writel(temp, stop_proc[port].global_control_reg);

		/* write flush */
		readl(stop_proc[port].global_control_reg);
	} else {
		dev_err(&icom_port->adapter->pci_dev->dev,
                        "Invalid port assignment\n");
	}

	spin_unlock_irqrestore(&icom_lock, flags);
}

static void start_processor(struct icom_port *icom_port)
{
	unsigned long temp;
	unsigned long flags;
	int port;

	spin_lock_irqsave(&icom_lock, flags);

	port = icom_port->port;
	if (port == 0 || port == 1)
		start_proc[port].global_control_reg = &icom_port->global_reg->control;
	else
		start_proc[port].global_control_reg = &icom_port->global_reg->control_2;
	if (port < 4) {
		temp = readl(start_proc[port].global_control_reg);
		temp =
	    		(temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
		writel(temp, start_proc[port].global_control_reg);

		/* write flush */
		readl(start_proc[port].global_control_reg);
	} else {
		dev_err(&icom_port->adapter->pci_dev->dev,
                        "Invalid port assignment\n");
	}

	spin_unlock_irqrestore(&icom_lock, flags);
}

static void load_code(struct icom_port *icom_port)
{
	const struct firmware *fw;
	char __iomem *iram_ptr;
	int index;
	int status = 0;
	void __iomem *dram_ptr = icom_port->dram;
	dma_addr_t temp_pci;
	unsigned char *new_page = NULL;
	unsigned char cable_id = NO_CABLE;
	struct pci_dev *dev = icom_port->adapter->pci_dev;

	/* Clear out any pending interrupts */
	writew(0x3FFF, icom_port->int_reg);

	trace(icom_port, "CLEAR_INTERRUPTS", 0);

	/* Stop processor */
	stop_processor(icom_port);

	/* Zero out DRAM */
	memset_io(dram_ptr, 0, 512);

	/* Load Call Setup into Adapter */
	if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
		dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
		status = -1;
		goto load_code_exit;
	}

	if (fw->size > ICOM_DCE_IRAM_OFFSET) {
		dev_err(&dev->dev, "Invalid firmware image for icom_call_setup.bin found.\n");
		release_firmware(fw);
		status = -1;
		goto load_code_exit;
	}

	iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
	for (index = 0; index < fw->size; index++)
		writeb(fw->data[index], &iram_ptr[index]);

	release_firmware(fw);

	/* Load Resident DCE portion of Adapter */
	if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
		dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
		status = -1;
		goto load_code_exit;
	}

	if (fw->size > ICOM_IRAM_SIZE) {
		dev_err(&dev->dev, "Invalid firmware image for icom_res_dce.bin found.\n");
		release_firmware(fw);
		status = -1;
		goto load_code_exit;
	}

	iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
	for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
		writeb(fw->data[index], &iram_ptr[index]);

	release_firmware(fw);

	/* Set Hardware level */
	if ((icom_port->adapter->version | ADAPTER_V2) == ADAPTER_V2)
		writeb(V2_HARDWARE, &(icom_port->dram->misc_flags));

	/* Start the processor in Adapter */
	start_processor(icom_port);

	writeb((HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL),
	       &(icom_port->dram->HDLCConfigReg));
	writeb(0x04, &(icom_port->dram->FlagFillIdleTimer));	/* 0.5 seconds */
	writeb(0x00, &(icom_port->dram->CmdReg));
	writeb(0x10, &(icom_port->dram->async_config3));
	writeb((ICOM_ACFG_DRIVE1 | ICOM_ACFG_NO_PARITY | ICOM_ACFG_8BPC |
		ICOM_ACFG_1STOP_BIT), &(icom_port->dram->async_config2));

	/*Set up data in icom DRAM to indicate where personality
	 *code is located and its length.
	 */
	new_page = pci_alloc_consistent(dev, 4096, &temp_pci);

	if (!new_page) {
		dev_err(&dev->dev, "Can not allocate DMA buffer\n");
		status = -1;
		goto load_code_exit;
	}

	if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
		dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
		status = -1;
		goto load_code_exit;
	}

	if (fw->size > ICOM_DCE_IRAM_OFFSET) {
		dev_err(&dev->dev, "Invalid firmware image for icom_asc.bin found.\n");
		release_firmware(fw);
		status = -1;
		goto load_code_exit;
	}

	for (index = 0; index < fw->size; index++)
		new_page[index] = fw->data[index];

	release_firmware(fw);

	writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
	writel(temp_pci, &icom_port->dram->mac_load_addr);

	/*Setting the syncReg to 0x80 causes adapter to start downloading
	   the personality code into adapter instruction RAM.
	   Once code is loaded, it will begin executing and, based on
	   information provided above, will start DMAing data from
	   shared memory to adapter DRAM.
	 */
	/* the wait loop below verifies this write operation has been done
	   and processed
	*/
	writeb(START_DOWNLOAD, &icom_port->dram->sync);

	/* Wait max 1 Sec for data download and processor to start */
	for (index = 0; index < 10; index++) {
		msleep(100);
		if (readb(&icom_port->dram->misc_flags) & ICOM_HDW_ACTIVE)
			break;
	}

	if (index == 10)
		status = -1;

	/*
	 * check Cable ID
	 */
	cable_id = readb(&icom_port->dram->cable_id);

	if (cable_id & ICOM_CABLE_ID_VALID) {
		/* Get cable ID into the lower 4 bits (standard form) */
		cable_id = (cable_id & ICOM_CABLE_ID_MASK) >> 4;
		icom_port->cable_id = cable_id;
	} else {
		dev_err(&dev->dev,"Invalid or no cable attached\n");
		icom_port->cable_id = NO_CABLE;
	}

      load_code_exit:

	if (status != 0) {
		/* Clear out any pending interrupts */
		writew(0x3FFF, icom_port->int_reg);

		/* Turn off port */
		writeb(ICOM_DISABLE, &(icom_port->dram->disable));

		/* Stop processor */
		stop_processor(icom_port);

		dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
	}

      if (new_page != NULL)
	      pci_free_consistent(dev, 4096, new_page, temp_pci);
}

static int startup(struct icom_port *icom_port)
{
	unsigned long temp;
	unsigned char cable_id, raw_cable_id;
	unsigned long flags;
	int port;

	trace(icom_port, "STARTUP", 0);

	if (!icom_port->dram) {
		/* should NEVER be NULL */
		dev_err(&icom_port->adapter->pci_dev->dev,
			"Unusable Port, port configuration missing\n");
		return -ENODEV;
	}

	/*
	 * check Cable ID
	 */
	raw_cable_id = readb(&icom_port->dram->cable_id);
	trace(icom_port, "CABLE_ID", raw_cable_id);

	/* Get cable ID into the lower 4 bits (standard form) */
	cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;

	/* Check for valid Cable ID */
	if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
	    (cable_id != icom_port->cable_id)) {

		/* reload adapter code, pick up any potential changes in cable id */
		load_code(icom_port);

		/* still no sign of cable, error out */
		raw_cable_id = readb(&icom_port->dram->cable_id);
		cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
		if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
		    (icom_port->cable_id == NO_CABLE))
			return -EIO;
	}

	/*
	 * Finally, clear and  enable interrupts
	 */
	spin_lock_irqsave(&icom_lock, flags);
	port = icom_port->port;
	if (port == 0 || port == 1)
		int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
	else
		int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;

	if (port == 0 || port == 2)
		writew(0x00FF, icom_port->int_reg);
	else
		writew(0x3F00, icom_port->int_reg);
	if (port < 4) {
		temp = readl(int_mask_tbl[port].global_int_mask);
		writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);

		/* write flush */
		readl(int_mask_tbl[port].global_int_mask);
	} else {
		dev_err(&icom_port->adapter->pci_dev->dev,
                        "Invalid port assignment\n");
	}

	spin_unlock_irqrestore(&icom_lock, flags);
	return 0;
}

static void shutdown(struct icom_port *icom_port)
{
	unsigned long temp;
	unsigned char cmdReg;
	unsigned long flags;
	int port;

	spin_lock_irqsave(&icom_lock, flags);
	trace(icom_port, "SHUTDOWN", 0);

	/*
	 * disable all interrupts
	 */
	port = icom_port->port;
	if (port == 0 || port == 1)
		int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
	else
		int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;

	if (port < 4) {
		temp = readl(int_mask_tbl[port].global_int_mask);
		writel(temp | int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);

		/* write flush */
		readl(int_mask_tbl[port].global_int_mask);
	} else {
		dev_err(&icom_port->adapter->pci_dev->dev,
                        "Invalid port assignment\n");
	}
	spin_unlock_irqrestore(&icom_lock, flags);

	/*
	 * disable break condition
	 */
	cmdReg = readb(&icom_port->dram->CmdReg);
	if ((cmdReg | CMD_SND_BREAK) == CMD_SND_BREAK) {
		writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
	}
}

static int icom_write(struct uart_port *port)
{
	unsigned long data_count;
	unsigned char cmdReg;
	unsigned long offset;
	int temp_tail = port->info->xmit.tail;

	trace(ICOM_PORT, "WRITE", 0);

	if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
	    SA_FLAGS_READY_TO_XMIT) {
		trace(ICOM_PORT, "WRITE_FULL", 0);
		return 0;
	}

	data_count = 0;
	while ((port->info->xmit.head != temp_tail) &&
	       (data_count <= XMIT_BUFF_SZ)) {

		ICOM_PORT->xmit_buf[data_count++] =
		    port->info->xmit.buf[temp_tail];

		temp_tail++;
		temp_tail &= (UART_XMIT_SIZE - 1);
	}

	if (data_count) {
		ICOM_PORT->statStg->xmit[0].flags =
		    cpu_to_le16(SA_FLAGS_READY_TO_XMIT);
		ICOM_PORT->statStg->xmit[0].leLength =
		    cpu_to_le16(data_count);
		offset =
		    (unsigned long) &ICOM_PORT->statStg->xmit[0] -
		    (unsigned long) ICOM_PORT->statStg;
		*ICOM_PORT->xmitRestart =
		    cpu_to_le32(ICOM_PORT->statStg_pci + offset);
		cmdReg = readb(&ICOM_PORT->dram->CmdReg);
		writeb(cmdReg | CMD_XMIT_RCV_ENABLE,
		       &ICOM_PORT->dram->CmdReg);
		writeb(START_XMIT, &ICOM_PORT->dram->StartXmitCmd);
		trace(ICOM_PORT, "WRITE_START", data_count);
		/* write flush */
		readb(&ICOM_PORT->dram->StartXmitCmd);
	}

	return data_count;
}

static inline void check_modem_status(struct icom_port *icom_port)
{
	static char old_status = 0;
	char delta_status;
	unsigned char status;

	spin_lock(&icom_port->uart_port.lock);

	/*modem input register */
	status = readb(&icom_port->dram->isr);
	trace(icom_port, "CHECK_MODEM", status);
	delta_status = status ^ old_status;
	if (delta_status) {
		if (delta_status & ICOM_RI)
			icom_port->uart_port.icount.rng++;
		if (delta_status & ICOM_DSR)
			icom_port->uart_port.icount.dsr++;
		if (delta_status & ICOM_DCD)
			uart_handle_dcd_change(&icom_port->uart_port,
					       delta_status & ICOM_DCD);
		if (delta_status & ICOM_CTS)
			uart_handle_cts_change(&icom_port->uart_port,
					       delta_status & ICOM_CTS);

		wake_up_interruptible(&icom_port->uart_port.info->
				      delta_msr_wait);
		old_status = status;
	}
	spin_unlock(&icom_port->uart_port.lock);
}

static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
{
	unsigned short int count;
	int i;

	if (port_int_reg & (INT_XMIT_COMPLETED)) {
		trace(icom_port, "XMIT_COMPLETE", 0);

		/* clear buffer in use bit */
		icom_port->statStg->xmit[0].flags &=
			cpu_to_le16(~SA_FLAGS_READY_TO_XMIT);

		count = (unsigned short int)
			cpu_to_le16(icom_port->statStg->xmit[0].leLength);
		icom_port->uart_port.icount.tx += count;

		for (i=0; i<count &&
			!uart_circ_empty(&icom_port->uart_port.info->xmit); i++) {

			icom_port->uart_port.info->xmit.tail++;
			icom_port->uart_port.info->xmit.tail &=
				(UART_XMIT_SIZE - 1);
		}

		if (!icom_write(&icom_port->uart_port))
			/* activate write queue */
			uart_write_wakeup(&icom_port->uart_port);
	} else
		trace(icom_port, "XMIT_DISABLED", 0);
}

static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
{
	short int count, rcv_buff;
	struct tty_struct *tty = icom_port->uart_port.info->port.tty;
	unsigned short int status;
	struct uart_icount *icount;
	unsigned long offset;
	unsigned char flag;

	trace(icom_port, "RCV_COMPLETE", 0);
	rcv_buff = icom_port->next_rcv;

	status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
	while (status & SA_FL_RCV_DONE) {
		int first = -1;

		trace(icom_port, "FID_STATUS", status);
		count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);

                count = tty_buffer_request_room(tty, count);
		trace(icom_port, "RCV_COUNT", count);

		trace(icom_port, "REAL_COUNT", count);

		offset =
			cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
			icom_port->recv_buf_pci;

		/* Block copy all but the last byte as this may have status */
		if (count > 0) {
			first = icom_port->recv_buf[offset];
			tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1);
		}

		icount = &icom_port->uart_port.icount;
		icount->rx += count;

		/* Break detect logic */
		if ((status & SA_FLAGS_FRAME_ERROR)
		    && first == 0) {
			status &= ~SA_FLAGS_FRAME_ERROR;
			status |= SA_FLAGS_BREAK_DET;
			trace(icom_port, "BREAK_DET", 0);
		}

		flag = TTY_NORMAL;

		if (status &
		    (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
		     SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {

			if (status & SA_FLAGS_BREAK_DET)
				icount->brk++;
			if (status & SA_FLAGS_PARITY_ERROR)
				icount->parity++;
			if (status & SA_FLAGS_FRAME_ERROR)
				icount->frame++;
			if (status & SA_FLAGS_OVERRUN)
				icount->overrun++;

			/*
			 * Now check to see if character should be
			 * ignored, and mask off conditions which
			 * should be ignored.
			 */
			if (status & icom_port->ignore_status_mask) {
				trace(icom_port, "IGNORE_CHAR", 0);
				goto ignore_char;
			}

			status &= icom_port->read_status_mask;

			if (status & SA_FLAGS_BREAK_DET) {
				flag = TTY_BREAK;
			} else if (status & SA_FLAGS_PARITY_ERROR) {
				trace(icom_port, "PARITY_ERROR", 0);
				flag = TTY_PARITY;
			} else if (status & SA_FLAGS_FRAME_ERROR)
				flag = TTY_FRAME;

		}

		tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag);

		if (status & SA_FLAGS_OVERRUN)
			/*
			 * Overrun is special, since it's
			 * reported immediately, and doesn't
			 * affect the current character
			 */
			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
ignore_char:
		icom_port->statStg->rcv[rcv_buff].flags = 0;
		icom_port->statStg->rcv[rcv_buff].leLength = 0;
		icom_port->statStg->rcv[rcv_buff].WorkingLength =
			(unsigned short int) cpu_to_le16(RCV_BUFF_SZ);

		rcv_buff++;
		if (rcv_buff == NUM_RBUFFS)
			rcv_buff = 0;

		status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
	}
	icom_port->next_rcv = rcv_buff;
	tty_flip_buffer_push(tty);
}

static void process_interrupt(u16 port_int_reg,
			      struct icom_port *icom_port)
{

	spin_lock(&icom_port->uart_port.lock);
	trace(icom_port, "INTERRUPT", port_int_reg);

	if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
		xmit_interrupt(port_int_reg, icom_port);

	if (port_int_reg & INT_RCV_COMPLETED)
		recv_interrupt(port_int_reg, icom_port);

	spin_unlock(&icom_port->uart_port.lock);
}

static irqreturn_t icom_interrupt(int irq, void *dev_id)
{
	void __iomem * int_reg;
	u32 adapter_interrupts;
	u16 port_int_reg;
	struct icom_adapter *icom_adapter;
	struct icom_port *icom_port;

	/* find icom_port for this interrupt */
	icom_adapter = (struct icom_adapter *) dev_id;

	if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
		int_reg = icom_adapter->base_addr + 0x8024;

		adapter_interrupts = readl(int_reg);

		if (adapter_interrupts & 0x00003FFF) {
			/* port 2 interrupt,  NOTE:  for all ADAPTER_V2, port 2 will be active */
			icom_port = &icom_adapter->port_info[2];
			port_int_reg = (u16) adapter_interrupts;
			process_interrupt(port_int_reg, icom_port);
			check_modem_status(icom_port);
		}
		if (adapter_interrupts & 0x3FFF0000) {
			/* port 3 interrupt */
			icom_port = &icom_adapter->port_info[3];
			if (icom_port->status == ICOM_PORT_ACTIVE) {
				port_int_reg =
				    (u16) (adapter_interrupts >> 16);
				process_interrupt(port_int_reg, icom_port);
				check_modem_status(icom_port);
			}
		}

		/* Clear out any pending interrupts */
		writel(adapter_interrupts, int_reg);

		int_reg = icom_adapter->base_addr + 0x8004;
	} else {
		int_reg = icom_adapter->base_addr + 0x4004;
	}

	adapter_interrupts = readl(int_reg);

	if (adapter_interrupts & 0x00003FFF) {
		/* port 0 interrupt, NOTE:  for all adapters, port 0 will be active */
		icom_port = &icom_adapter->port_info[0];
		port_int_reg = (u16) adapter_interrupts;
		process_interrupt(port_int_reg, icom_port);
		check_modem_status(icom_port);
	}
	if (adapter_interrupts & 0x3FFF0000) {
		/* port 1 interrupt */
		icom_port = &icom_adapter->port_info[1];
		if (icom_port->status == ICOM_PORT_ACTIVE) {
			port_int_reg = (u16) (adapter_interrupts >> 16);
			process_interrupt(port_int_reg, icom_port);
			check_modem_status(icom_port);
		}
	}

	/* Clear out any pending interrupts */
	writel(adapter_interrupts, int_reg);

	/* flush the write */
	adapter_interrupts = readl(int_reg);

	return IRQ_HANDLED;
}

/*
 * ------------------------------------------------------------------
 * Begin serial-core API
 * ------------------------------------------------------------------
 */
static unsigned int icom_tx_empty(struct uart_port *port)
{
	int ret;
	unsigned long flags;

	spin_lock_irqsave(&port->lock, flags);
	if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
	    SA_FLAGS_READY_TO_XMIT)
		ret = TIOCSER_TEMT;
	else
		ret = 0;

	spin_unlock_irqrestore(&port->lock, flags);
	return ret;
}

static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	unsigned char local_osr;

	trace(ICOM_PORT, "SET_MODEM", 0);
	local_osr = readb(&ICOM_PORT->dram->osr);

	if (mctrl & TIOCM_RTS) {
		trace(ICOM_PORT, "RAISE_RTS", 0);
		local_osr |= ICOM_RTS;
	} else {
		trace(ICOM_PORT, "LOWER_RTS", 0);
		local_osr &= ~ICOM_RTS;
	}

	if (mctrl & TIOCM_DTR) {
		trace(ICOM_PORT, "RAISE_DTR", 0);
		local_osr |= ICOM_DTR;
	} else {
		trace(ICOM_PORT, "LOWER_DTR", 0);
		local_osr &= ~ICOM_DTR;
	}

	writeb(local_osr, &ICOM_PORT->dram->osr);
}

static unsigned int icom_get_mctrl(struct uart_port *port)
{
	unsigned char status;
	unsigned int result;

	trace(ICOM_PORT, "GET_MODEM", 0);

	status = readb(&ICOM_PORT->dram->isr);

	result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
	    | ((status & ICOM_RI) ? TIOCM_RNG : 0)
	    | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
	    | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
	return result;
}

static void icom_stop_tx(struct uart_port *port)
{
	unsigned char cmdReg;

	trace(ICOM_PORT, "STOP", 0);
	cmdReg = readb(&ICOM_PORT->dram->CmdReg);
	writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
}

static void icom_start_tx(struct uart_port *port)
{
	unsigned char cmdReg;

	trace(ICOM_PORT, "START", 0);
	cmdReg = readb(&ICOM_PORT->dram->CmdReg);
	if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
		writeb(cmdReg & ~CMD_HOLD_XMIT,
		       &ICOM_PORT->dram->CmdReg);

	icom_write(port);
}

static void icom_send_xchar(struct uart_port *port, char ch)
{
	unsigned char xdata;
	int index;
	unsigned long flags;

	trace(ICOM_PORT, "SEND_XCHAR", ch);

	/* wait .1 sec to send char */
	for (index = 0; index < 10; index++) {
		spin_lock_irqsave(&port->lock, flags);
		xdata = readb(&ICOM_PORT->dram->xchar);
		if (xdata == 0x00) {
			trace(ICOM_PORT, "QUICK_WRITE", 0);
			writeb(ch, &ICOM_PORT->dram->xchar);

			/* flush write operation */
			xdata = readb(&ICOM_PORT->dram->xchar);
			spin_unlock_irqrestore(&port->lock, flags);
			break;
		}
		spin_unlock_irqrestore(&port->lock, flags);
		msleep(10);
	}
}

static void icom_stop_rx(struct uart_port *port)
{
	unsigned char cmdReg;

	cmdReg = readb(&ICOM_PORT->dram->CmdReg);
	writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
}

static void icom_enable_ms(struct uart_port *port)
{
	/* no-op */
}

static void icom_break(struct uart_port *port, int break_state)
{
	unsigned char cmdReg;
	unsigned long flags;

	spin_lock_irqsave(&port->lock, flags);
	trace(ICOM_PORT, "BREAK", 0);
	cmdReg = readb(&ICOM_PORT->dram->CmdReg);
	if (break_state == -1) {
		writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
	} else {
		writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
	}
	spin_unlock_irqrestore(&port->lock, flags);
}

static int icom_open(struct uart_port *port)
{
	int retval;

	kref_get(&ICOM_PORT->adapter->kref);
	retval = startup(ICOM_PORT);

	if (retval) {
		kref_put(&ICOM_PORT->adapter->kref, icom_kref_release);
		trace(ICOM_PORT, "STARTUP_ERROR", 0);
		return retval;
	}

	return 0;
}

static void icom_close(struct uart_port *port)
{
	unsigned char cmdReg;

	trace(ICOM_PORT, "CLOSE", 0);

	/* stop receiver */
	cmdReg = readb(&ICOM_PORT->dram->CmdReg);
	writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
	       &ICOM_PORT->dram->CmdReg);

	shutdown(ICOM_PORT);

	kref_put(&ICOM_PORT->adapter->kref, icom_kref_release);
}

static void icom_set_termios(struct uart_port *port,
			     struct ktermios *termios,
			     struct ktermios *old_termios)
{
	int baud;
	unsigned cflag, iflag;
	int bits;
	char new_config2;
	char new_config3 = 0;
	char tmp_byte;
	int index;
	int rcv_buff, xmit_buff;
	unsigned long offset;
	unsigned long flags;

	spin_lock_irqsave(&port->lock, flags);
	trace(ICOM_PORT, "CHANGE_SPEED", 0);

	cflag = termios->c_cflag;
	iflag = termios->c_iflag;

	new_config2 = ICOM_ACFG_DRIVE1;

	/* byte size and parity */
	switch (cflag & CSIZE) {
	case CS5:		/* 5 bits/char */
		new_config2 |= ICOM_ACFG_5BPC;
		bits = 7;
		break;
	case CS6:		/* 6 bits/char */
		new_config2 |= ICOM_ACFG_6BPC;
		bits = 8;
		break;
	case CS7:		/* 7 bits/char */
		new_config2 |= ICOM_ACFG_7BPC;
		bits = 9;
		break;
	case CS8:		/* 8 bits/char */
		new_config2 |= ICOM_ACFG_8BPC;
		bits = 10;
		break;
	default:
		bits = 10;
		break;
	}
	if (cflag & CSTOPB) {
		/* 2 stop bits */
		new_config2 |= ICOM_ACFG_2STOP_BIT;
		bits++;
	}
	if (cflag & PARENB) {
		/* parity bit enabled */
		new_config2 |= ICOM_ACFG_PARITY_ENAB;
		trace(ICOM_PORT, "PARENB", 0);
		bits++;
	}
	if (cflag & PARODD) {
		/* odd parity */
		new_config2 |= ICOM_ACFG_PARITY_ODD;
		trace(ICOM_PORT, "PARODD", 0);
	}

	/* Determine divisor based on baud rate */
	baud = uart_get_baud_rate(port, termios, old_termios,
				  icom_acfg_baud[0],
				  icom_acfg_baud[BAUD_TABLE_LIMIT]);
	if (!baud)
		baud = 9600;	/* B0 transition handled in rs_set_termios */

	for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
		if (icom_acfg_baud[index] == baud) {
			new_config3 = index;
			break;
		}
	}

	uart_update_timeout(port, cflag, baud);

	/* CTS flow control flag and modem status interrupts */
	tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
	if (cflag & CRTSCTS)
		tmp_byte |= HDLC_HDW_FLOW;
	else
		tmp_byte &= ~HDLC_HDW_FLOW;
	writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));

	/*
	 * Set up parity check flag
	 */
	ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
	if (iflag & INPCK)
		ICOM_PORT->read_status_mask |=
		    SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;

	if ((iflag & BRKINT) || (iflag & PARMRK))
		ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;

	/*
	 * Characters to ignore
	 */
	ICOM_PORT->ignore_status_mask = 0;
	if (iflag & IGNPAR)
		ICOM_PORT->ignore_status_mask |=
		    SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
	if (iflag & IGNBRK) {
		ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
		/*
		 * If we're ignore parity and break indicators, ignore
		 * overruns too.  (For real raw support).
		 */
		if (iflag & IGNPAR)
			ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
	}

	/*
	 * !!! ignore all characters if CREAD is not set
	 */
	if ((cflag & CREAD) == 0)
		ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;

	/* Turn off Receiver to prepare for reset */
	writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);

	for (index = 0; index < 10; index++) {
		if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
			break;
		}
	}

	/* clear all current buffers of data */
	for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
		ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
		ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
		ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
		    (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
	}

	for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
		ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
	}

	/* activate changes and start xmit and receiver here */
	/* Enable the receiver */
	writeb(new_config3, &(ICOM_PORT->dram->async_config3));
	writeb(new_config2, &(ICOM_PORT->dram->async_config2));
	tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
	tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
	writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
	writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer));	/* 0.5 seconds */
	writeb(0xFF, &(ICOM_PORT->dram->ier));	/* enable modem signal interrupts */

	/* reset processor */
	writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);

	for (index = 0; index < 10; index++) {
		if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
			break;
		}
	}

	/* Enable Transmitter and Reciever */
	offset =
	    (unsigned long) &ICOM_PORT->statStg->rcv[0] -
	    (unsigned long) ICOM_PORT->statStg;
	writel(ICOM_PORT->statStg_pci + offset,
	       &ICOM_PORT->dram->RcvStatusAddr);
	ICOM_PORT->next_rcv = 0;
	ICOM_PORT->put_length = 0;
	*ICOM_PORT->xmitRestart = 0;
	writel(ICOM_PORT->xmitRestart_pci,
	       &ICOM_PORT->dram->XmitStatusAddr);
	trace(ICOM_PORT, "XR_ENAB", 0);
	writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);

	spin_unlock_irqrestore(&port->lock, flags);
}

static const char *icom_type(struct uart_port *port)
{
	return "icom";
}

static void icom_release_port(struct uart_port *port)
{
}

static int icom_request_port(struct uart_port *port)
{
	return 0;
}

static void icom_config_port(struct uart_port *port, int flags)
{
	port->type = PORT_ICOM;
}

static struct uart_ops icom_ops = {
	.tx_empty = icom_tx_empty,
	.set_mctrl = icom_set_mctrl,
	.get_mctrl = icom_get_mctrl,
	.stop_tx = icom_stop_tx,
	.start_tx = icom_start_tx,
	.send_xchar = icom_send_xchar,
	.stop_rx = icom_stop_rx,
	.enable_ms = icom_enable_ms,
	.break_ctl = icom_break,
	.startup = icom_open,
	.shutdown = icom_close,
	.set_termios = icom_set_termios,
	.type = icom_type,
	.release_port = icom_release_port,
	.request_port = icom_request_port,
	.config_port = icom_config_port,
};

#define ICOM_CONSOLE NULL

static struct uart_driver icom_uart_driver = {
	.owner = THIS_MODULE,
	.driver_name = ICOM_DRIVER_NAME,
	.dev_name = "ttyA",
	.major = ICOM_MAJOR,
	.minor = ICOM_MINOR_START,
	.nr = NR_PORTS,
	.cons = ICOM_CONSOLE,
};

static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
{
	u32 subsystem_id = icom_adapter->subsystem_id;
	int retval = 0;
	int i;
	struct icom_port *icom_port;

	if (icom_adapter->version == ADAPTER_V1) {
		icom_adapter->numb_ports = 2;

		for (i = 0; i < 2; i++) {
			icom_port = &icom_adapter->port_info[i];
			icom_port->port = i;
			icom_port->status = ICOM_PORT_ACTIVE;
			icom_port->imbed_modem = ICOM_UNKNOWN;
		}
	} else {
		if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
			icom_adapter->numb_ports = 4;

			for (i = 0; i < 4; i++) {
				icom_port = &icom_adapter->port_info[i];

				icom_port->port = i;
				icom_port->status = ICOM_PORT_ACTIVE;
				icom_port->imbed_modem = ICOM_IMBED_MODEM;
			}
		} else {
			icom_adapter->numb_ports = 4;

			icom_adapter->port_info[0].port = 0;
			icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;

			if (subsystem_id ==
			    PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
				icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
			} else {
				icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
			}

			icom_adapter->port_info[1].status = ICOM_PORT_OFF;

			icom_adapter->port_info[2].port = 2;
			icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
			icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
			icom_adapter->port_info[3].status = ICOM_PORT_OFF;
		}
	}

	return retval;
}

static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
{
	if (icom_adapter->version == ADAPTER_V1) {
		icom_port->global_reg = icom_adapter->base_addr + 0x4000;
		icom_port->int_reg = icom_adapter->base_addr +
		    0x4004 + 2 - 2 * port_num;
	} else {
		icom_port->global_reg = icom_adapter->base_addr + 0x8000;
		if (icom_port->port < 2)
			icom_port->int_reg = icom_adapter->base_addr +
			    0x8004 + 2 - 2 * icom_port->port;
		else
			icom_port->int_reg = icom_adapter->base_addr +
			    0x8024 + 2 - 2 * (icom_port->port - 2);
	}
}
static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
{
	struct icom_port *icom_port;
	int port_num;
	int retval;

	for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {

		icom_port = &icom_adapter->port_info[port_num];

		if (icom_port->status == ICOM_PORT_ACTIVE) {
			icom_port_active(icom_port, icom_adapter, port_num);
			icom_port->dram = icom_adapter->base_addr +
					0x2000 * icom_port->port;

			icom_port->adapter = icom_adapter;

			/* get port memory */
			if ((retval = get_port_memory(icom_port)) != 0) {
				dev_err(&icom_port->adapter->pci_dev->dev,
					"Memory allocation for port FAILED\n");
			}
		}
	}
	return 0;
}

static int __devinit icom_alloc_adapter(struct icom_adapter
					**icom_adapter_ref)
{
	int adapter_count = 0;
	struct icom_adapter *icom_adapter;
	struct icom_adapter *cur_adapter_entry;
	struct list_head *tmp;

	icom_adapter = (struct icom_adapter *)
	    kzalloc(sizeof(struct icom_adapter), GFP_KERNEL);

	if (!icom_adapter) {
		return -ENOMEM;
	}

	list_for_each(tmp, &icom_adapter_head) {
		cur_adapter_entry =
		    list_entry(tmp, struct icom_adapter,
			       icom_adapter_entry);
		if (cur_adapter_entry->index != adapter_count) {
			break;
		}
		adapter_count++;
	}

	icom_adapter->index = adapter_count;
	list_add_tail(&icom_adapter->icom_adapter_entry, tmp);

	*icom_adapter_ref = icom_adapter;
	return 0;
}

static void icom_free_adapter(struct icom_adapter *icom_adapter)
{
	list_del(&icom_adapter->icom_adapter_entry);
	kfree(icom_adapter);
}

static void icom_remove_adapter(struct icom_adapter *icom_adapter)
{
	struct icom_port *icom_port;
	int index;

	for (index = 0; index < icom_adapter->numb_ports; index++) {
		icom_port = &icom_adapter->port_info[index];

		if (icom_port->status == ICOM_PORT_ACTIVE) {
			dev_info(&icom_adapter->pci_dev->dev,
				 "Device removed\n");

			uart_remove_one_port(&icom_uart_driver,
					     &icom_port->uart_port);

			/* be sure that DTR and RTS are dropped */
			writeb(0x00, &icom_port->dram->osr);

			/* Wait 0.1 Sec for simple Init to complete */
			msleep(100);

			/* Stop proccessor */
			stop_processor(icom_port);

			free_port_memory(icom_port);
		}
	}

	free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter);
	iounmap(icom_adapter->base_addr);
	icom_free_adapter(icom_adapter);
	pci_release_regions(icom_adapter->pci_dev);
}

static void icom_kref_release(struct kref *kref)
{
	struct icom_adapter *icom_adapter;

	icom_adapter = to_icom_adapter(kref);
	icom_remove_adapter(icom_adapter);
}

static int __devinit icom_probe(struct pci_dev *dev,
				const struct pci_device_id *ent)
{
	int index;
        unsigned int command_reg;
        int retval;
        struct icom_adapter *icom_adapter;
        struct icom_port *icom_port;

        retval = pci_enable_device(dev);
        if (retval) {
		dev_err(&dev->dev, "Device enable FAILED\n");
                return retval;
	}

	if ( (retval = pci_request_regions(dev, "icom"))) {
		 dev_err(&dev->dev, "pci_request_regions FAILED\n");
		 pci_disable_device(dev);
		 return retval;
	 }

        pci_set_master(dev);

        if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
		dev_err(&dev->dev, "PCI Config read FAILED\n");
                return retval;
        }

	pci_write_config_dword(dev, PCI_COMMAND,
		command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
 		| PCI_COMMAND_PARITY | PCI_COMMAND_SERR);

        if (ent->driver_data == ADAPTER_V1) {
		pci_write_config_dword(dev, 0x44, 0x8300830A);
	 } else {
		pci_write_config_dword(dev, 0x44, 0x42004200);
		pci_write_config_dword(dev, 0x48, 0x42004200);
         }


	retval = icom_alloc_adapter(&icom_adapter);
	if (retval) {
		 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
		 retval = -EIO;
		 goto probe_exit0;
	}

	 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
	 icom_adapter->pci_dev = dev;
	 icom_adapter->version = ent->driver_data;
	 icom_adapter->subsystem_id = ent->subdevice;


	retval = icom_init_ports(icom_adapter);
	if (retval) {
		dev_err(&dev->dev, "Port configuration failed\n");
		goto probe_exit1;
	}

	 icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
						pci_resource_len(dev, 0));

	if (!icom_adapter->base_addr)
		goto probe_exit1;

	 /* save off irq and request irq line */
	 if ( (retval = request_irq(dev->irq, icom_interrupt,
				   IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME,
				   (void *) icom_adapter))) {
		  goto probe_exit2;
	 }

	retval = icom_load_ports(icom_adapter);

        for (index = 0; index < icom_adapter->numb_ports; index++) {
		icom_port = &icom_adapter->port_info[index];

		if (icom_port->status == ICOM_PORT_ACTIVE) {
			icom_port->uart_port.irq = icom_port->adapter->pci_dev->irq;
			icom_port->uart_port.type = PORT_ICOM;
			icom_port->uart_port.iotype = UPIO_MEM;
			icom_port->uart_port.membase =
					       (char *) icom_adapter->base_addr_pci;
			icom_port->uart_port.fifosize = 16;
			icom_port->uart_port.ops = &icom_ops;
			icom_port->uart_port.line =
		        icom_port->port + icom_adapter->index * 4;
			if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
				icom_port->status = ICOM_PORT_OFF;
				dev_err(&dev->dev, "Device add failed\n");
			 } else
			        dev_info(&dev->dev, "Device added\n");
		}
	}

	kref_init(&icom_adapter->kref);
	return 0;

probe_exit2:
	iounmap(icom_adapter->base_addr);
probe_exit1:
	icom_free_adapter(icom_adapter);

probe_exit0:
	pci_release_regions(dev);
	pci_disable_device(dev);

        return retval;


}

static void __devexit icom_remove(struct pci_dev *dev)
{
	struct icom_adapter *icom_adapter;
	struct list_head *tmp;

	list_for_each(tmp, &icom_adapter_head) {
		icom_adapter = list_entry(tmp, struct icom_adapter,
					  icom_adapter_entry);
		if (icom_adapter->pci_dev == dev) {
			kref_put(&icom_adapter->kref, icom_kref_release);
			return;
		}
	}

	dev_err(&dev->dev, "Unable to find device to remove\n");
}

static struct pci_driver icom_pci_driver = {
	.name = ICOM_DRIVER_NAME,
	.id_table = icom_pci_table,
	.probe = icom_probe,
	.remove = __devexit_p(icom_remove),
};

static int __init icom_init(void)
{
	int ret;

	spin_lock_init(&icom_lock);

	ret = uart_register_driver(&icom_uart_driver);
	if (ret)
		return ret;

	ret = pci_register_driver(&icom_pci_driver);

	if (ret < 0)
		uart_unregister_driver(&icom_uart_driver);

	return ret;
}

static void __exit icom_exit(void)
{
	pci_unregister_driver(&icom_pci_driver);
	uart_unregister_driver(&icom_uart_driver);
}

module_init(icom_init);
module_exit(icom_exit);

#ifdef ICOM_TRACE
static inline void trace(struct icom_port *icom_port, char *trace_pt,
		  unsigned long trace_data)
{
	dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
		 icom_port->port, trace_pt, trace_data);
}
#endif

MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
MODULE_SUPPORTED_DEVICE
    ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
MODULE_LICENSE("GPL");

