1/*
2  * icom.c
3  *
4  * Copyright (C) 2001 IBM Corporation. All rights reserved.
5  *
6  * Serial device driver.
7  *
8  * Based on code from serial.c
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  *
24  */
25#define SERIAL_DO_RESTART
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/errno.h>
29#include <linux/signal.h>
30#include <linux/timer.h>
31#include <linux/interrupt.h>
32#include <linux/tty.h>
33#include <linux/termios.h>
34#include <linux/fs.h>
35#include <linux/tty_flip.h>
36#include <linux/serial.h>
37#include <linux/serial_reg.h>
38#include <linux/major.h>
39#include <linux/string.h>
40#include <linux/fcntl.h>
41#include <linux/ptrace.h>
42#include <linux/ioport.h>
43#include <linux/mm.h>
44#include <linux/slab.h>
45#include <linux/init.h>
46#include <linux/delay.h>
47#include <linux/pci.h>
48#include <linux/vmalloc.h>
49#include <linux/smp.h>
50#include <linux/spinlock.h>
51#include <linux/kobject.h>
52#include <linux/firmware.h>
53#include <linux/bitops.h>
54
55#include <asm/system.h>
56#include <asm/io.h>
57#include <asm/irq.h>
58#include <asm/uaccess.h>
59
60#include "icom.h"
61
62/*#define ICOM_TRACE		 enable port trace capabilities */
63
64#define ICOM_DRIVER_NAME "icom"
65#define ICOM_VERSION_STR "1.3.1"
66#define NR_PORTS	       128
67#define ICOM_PORT ((struct icom_port *)port)
68#define to_icom_adapter(d) container_of(d, struct icom_adapter, kobj)
69
70static const struct pci_device_id icom_pci_table[] = {
71	{
72		.vendor = PCI_VENDOR_ID_IBM,
73		.device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1,
74		.subvendor = PCI_ANY_ID,
75		.subdevice = PCI_ANY_ID,
76		.driver_data = ADAPTER_V1,
77	},
78	{
79		.vendor = PCI_VENDOR_ID_IBM,
80		.device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
81		.subvendor = PCI_VENDOR_ID_IBM,
82		.subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX,
83		.driver_data = ADAPTER_V2,
84	},
85	{
86		.vendor = PCI_VENDOR_ID_IBM,
87		.device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
88		.subvendor = PCI_VENDOR_ID_IBM,
89		.subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM,
90		.driver_data = ADAPTER_V2,
91	},
92	{
93		.vendor = PCI_VENDOR_ID_IBM,
94		.device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
95		.subvendor = PCI_VENDOR_ID_IBM,
96		.subdevice = PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL,
97		.driver_data = ADAPTER_V2,
98	},
99	{
100		.vendor = PCI_VENDOR_ID_IBM,
101		.device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
102		.subvendor = PCI_VENDOR_ID_IBM,
103		.subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM_PCIE,
104		.driver_data = ADAPTER_V2,
105	},
106	{}
107};
108
109struct lookup_proc_table start_proc[4] = {
110	{NULL, ICOM_CONTROL_START_A},
111	{NULL, ICOM_CONTROL_START_B},
112	{NULL, ICOM_CONTROL_START_C},
113	{NULL, ICOM_CONTROL_START_D}
114};
115
116
117struct lookup_proc_table stop_proc[4] = {
118	{NULL, ICOM_CONTROL_STOP_A},
119	{NULL, ICOM_CONTROL_STOP_B},
120	{NULL, ICOM_CONTROL_STOP_C},
121	{NULL, ICOM_CONTROL_STOP_D}
122};
123
124struct lookup_int_table int_mask_tbl[4] = {
125	{NULL, ICOM_INT_MASK_PRC_A},
126	{NULL, ICOM_INT_MASK_PRC_B},
127	{NULL, ICOM_INT_MASK_PRC_C},
128	{NULL, ICOM_INT_MASK_PRC_D},
129};
130
131
132MODULE_DEVICE_TABLE(pci, icom_pci_table);
133
134static LIST_HEAD(icom_adapter_head);
135
136/* spinlock for adapter initialization and changing adapter operations */
137static spinlock_t icom_lock;
138
139#ifdef ICOM_TRACE
140static inline void trace(struct icom_port *, char *, unsigned long) {};
141#else
142static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
143#endif
144
145static void free_port_memory(struct icom_port *icom_port)
146{
147	struct pci_dev *dev = icom_port->adapter->pci_dev;
148
149	trace(icom_port, "RET_PORT_MEM", 0);
150	if (icom_port->recv_buf) {
151		pci_free_consistent(dev, 4096, icom_port->recv_buf,
152				    icom_port->recv_buf_pci);
153		icom_port->recv_buf = NULL;
154	}
155	if (icom_port->xmit_buf) {
156		pci_free_consistent(dev, 4096, icom_port->xmit_buf,
157				    icom_port->xmit_buf_pci);
158		icom_port->xmit_buf = NULL;
159	}
160	if (icom_port->statStg) {
161		pci_free_consistent(dev, 4096, icom_port->statStg,
162				    icom_port->statStg_pci);
163		icom_port->statStg = NULL;
164	}
165
166	if (icom_port->xmitRestart) {
167		pci_free_consistent(dev, 4096, icom_port->xmitRestart,
168				    icom_port->xmitRestart_pci);
169		icom_port->xmitRestart = NULL;
170	}
171}
172
173static int __devinit get_port_memory(struct icom_port *icom_port)
174{
175	int index;
176	unsigned long stgAddr;
177	unsigned long startStgAddr;
178	unsigned long offset;
179	struct pci_dev *dev = icom_port->adapter->pci_dev;
180
181	icom_port->xmit_buf =
182	    pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci);
183	if (!icom_port->xmit_buf) {
184		dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
185		return -ENOMEM;
186	}
187
188	trace(icom_port, "GET_PORT_MEM",
189	      (unsigned long) icom_port->xmit_buf);
190
191	icom_port->recv_buf =
192	    pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci);
193	if (!icom_port->recv_buf) {
194		dev_err(&dev->dev, "Can not allocate Receive buffer\n");
195		free_port_memory(icom_port);
196		return -ENOMEM;
197	}
198	trace(icom_port, "GET_PORT_MEM",
199	      (unsigned long) icom_port->recv_buf);
200
201	icom_port->statStg =
202	    pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci);
203	if (!icom_port->statStg) {
204		dev_err(&dev->dev, "Can not allocate Status buffer\n");
205		free_port_memory(icom_port);
206		return -ENOMEM;
207	}
208	trace(icom_port, "GET_PORT_MEM",
209	      (unsigned long) icom_port->statStg);
210
211	icom_port->xmitRestart =
212	    pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci);
213	if (!icom_port->xmitRestart) {
214		dev_err(&dev->dev,
215			"Can not allocate xmit Restart buffer\n");
216		free_port_memory(icom_port);
217		return -ENOMEM;
218	}
219
220	memset(icom_port->statStg, 0, 4096);
221
222	/* FODs: Frame Out Descriptor Queue, this is a FIFO queue that
223           indicates that frames are to be transmitted
224	*/
225
226	stgAddr = (unsigned long) icom_port->statStg;
227	for (index = 0; index < NUM_XBUFFS; index++) {
228		trace(icom_port, "FOD_ADDR", stgAddr);
229		stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
230		if (index < (NUM_XBUFFS - 1)) {
231			memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
232			icom_port->statStg->xmit[index].leLengthASD =
233			    (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
234			trace(icom_port, "FOD_ADDR", stgAddr);
235			trace(icom_port, "FOD_XBUFF",
236			      (unsigned long) icom_port->xmit_buf);
237			icom_port->statStg->xmit[index].leBuffer =
238			    cpu_to_le32(icom_port->xmit_buf_pci);
239		} else if (index == (NUM_XBUFFS - 1)) {
240			memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
241			icom_port->statStg->xmit[index].leLengthASD =
242			    (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
243			trace(icom_port, "FOD_XBUFF",
244			      (unsigned long) icom_port->xmit_buf);
245			icom_port->statStg->xmit[index].leBuffer =
246			    cpu_to_le32(icom_port->xmit_buf_pci);
247		} else {
248			memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
249		}
250	}
251	/* FIDs */
252	startStgAddr = stgAddr;
253
254	/* fill in every entry, even if no buffer */
255	for (index = 0; index <  NUM_RBUFFS; index++) {
256		trace(icom_port, "FID_ADDR", stgAddr);
257		stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
258		icom_port->statStg->rcv[index].leLength = 0;
259		icom_port->statStg->rcv[index].WorkingLength =
260		    (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
261		if (index < (NUM_RBUFFS - 1) ) {
262			offset = stgAddr - (unsigned long) icom_port->statStg;
263			icom_port->statStg->rcv[index].leNext =
264			      cpu_to_le32(icom_port-> statStg_pci + offset);
265			trace(icom_port, "FID_RBUFF",
266			      (unsigned long) icom_port->recv_buf);
267			icom_port->statStg->rcv[index].leBuffer =
268			    cpu_to_le32(icom_port->recv_buf_pci);
269		} else if (index == (NUM_RBUFFS -1) ) {
270			offset = startStgAddr - (unsigned long) icom_port->statStg;
271			icom_port->statStg->rcv[index].leNext =
272			    cpu_to_le32(icom_port-> statStg_pci + offset);
273			trace(icom_port, "FID_RBUFF",
274			      (unsigned long) icom_port->recv_buf + 2048);
275			icom_port->statStg->rcv[index].leBuffer =
276			    cpu_to_le32(icom_port->recv_buf_pci + 2048);
277		} else {
278			icom_port->statStg->rcv[index].leNext = 0;
279			icom_port->statStg->rcv[index].leBuffer = 0;
280		}
281	}
282
283	return 0;
284}
285
286static void stop_processor(struct icom_port *icom_port)
287{
288	unsigned long temp;
289	unsigned long flags;
290	int port;
291
292	spin_lock_irqsave(&icom_lock, flags);
293
294	port = icom_port->port;
295	if (port == 0 || port == 1)
296		stop_proc[port].global_control_reg = &icom_port->global_reg->control;
297	else
298		stop_proc[port].global_control_reg = &icom_port->global_reg->control_2;
299
300
301	if (port < 4) {
302		temp = readl(stop_proc[port].global_control_reg);
303		temp =
304	    		(temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
305		writel(temp, stop_proc[port].global_control_reg);
306
307		/* write flush */
308		readl(stop_proc[port].global_control_reg);
309	} else {
310		dev_err(&icom_port->adapter->pci_dev->dev,
311                        "Invalid port assignment\n");
312	}
313
314	spin_unlock_irqrestore(&icom_lock, flags);
315}
316
317static void start_processor(struct icom_port *icom_port)
318{
319	unsigned long temp;
320	unsigned long flags;
321	int port;
322
323	spin_lock_irqsave(&icom_lock, flags);
324
325	port = icom_port->port;
326	if (port == 0 || port == 1)
327		start_proc[port].global_control_reg = &icom_port->global_reg->control;
328	else
329		start_proc[port].global_control_reg = &icom_port->global_reg->control_2;
330	if (port < 4) {
331		temp = readl(start_proc[port].global_control_reg);
332		temp =
333	    		(temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
334		writel(temp, start_proc[port].global_control_reg);
335
336		/* write flush */
337		readl(start_proc[port].global_control_reg);
338	} else {
339		dev_err(&icom_port->adapter->pci_dev->dev,
340                        "Invalid port assignment\n");
341	}
342
343	spin_unlock_irqrestore(&icom_lock, flags);
344}
345
346static void load_code(struct icom_port *icom_port)
347{
348	const struct firmware *fw;
349	char __iomem *iram_ptr;
350	int index;
351	int status = 0;
352	void __iomem *dram_ptr = icom_port->dram;
353	dma_addr_t temp_pci;
354	unsigned char *new_page = NULL;
355	unsigned char cable_id = NO_CABLE;
356	struct pci_dev *dev = icom_port->adapter->pci_dev;
357
358	/* Clear out any pending interrupts */
359	writew(0x3FFF, icom_port->int_reg);
360
361	trace(icom_port, "CLEAR_INTERRUPTS", 0);
362
363	/* Stop processor */
364	stop_processor(icom_port);
365
366	/* Zero out DRAM */
367	memset_io(dram_ptr, 0, 512);
368
369	/* Load Call Setup into Adapter */
370	if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
371		dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
372		status = -1;
373		goto load_code_exit;
374	}
375
376	if (fw->size > ICOM_DCE_IRAM_OFFSET) {
377		dev_err(&dev->dev, "Invalid firmware image for icom_call_setup.bin found.\n");
378		release_firmware(fw);
379		status = -1;
380		goto load_code_exit;
381	}
382
383	iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
384	for (index = 0; index < fw->size; index++)
385		writeb(fw->data[index], &iram_ptr[index]);
386
387	release_firmware(fw);
388
389	/* Load Resident DCE portion of Adapter */
390	if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
391		dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
392		status = -1;
393		goto load_code_exit;
394	}
395
396	if (fw->size > ICOM_IRAM_SIZE) {
397		dev_err(&dev->dev, "Invalid firmware image for icom_res_dce.bin found.\n");
398		release_firmware(fw);
399		status = -1;
400		goto load_code_exit;
401	}
402
403	iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
404	for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
405		writeb(fw->data[index], &iram_ptr[index]);
406
407	release_firmware(fw);
408
409	/* Set Hardware level */
410	if ((icom_port->adapter->version | ADAPTER_V2) == ADAPTER_V2)
411		writeb(V2_HARDWARE, &(icom_port->dram->misc_flags));
412
413	/* Start the processor in Adapter */
414	start_processor(icom_port);
415
416	writeb((HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL),
417	       &(icom_port->dram->HDLCConfigReg));
418	writeb(0x04, &(icom_port->dram->FlagFillIdleTimer));	/* 0.5 seconds */
419	writeb(0x00, &(icom_port->dram->CmdReg));
420	writeb(0x10, &(icom_port->dram->async_config3));
421	writeb((ICOM_ACFG_DRIVE1 | ICOM_ACFG_NO_PARITY | ICOM_ACFG_8BPC |
422		ICOM_ACFG_1STOP_BIT), &(icom_port->dram->async_config2));
423
424	/*Set up data in icom DRAM to indicate where personality
425	 *code is located and its length.
426	 */
427	new_page = pci_alloc_consistent(dev, 4096, &temp_pci);
428
429	if (!new_page) {
430		dev_err(&dev->dev, "Can not allocate DMA buffer\n");
431		status = -1;
432		goto load_code_exit;
433	}
434
435	if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
436		dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
437		status = -1;
438		goto load_code_exit;
439	}
440
441	if (fw->size > ICOM_DCE_IRAM_OFFSET) {
442		dev_err(&dev->dev, "Invalid firmware image for icom_asc.bin found.\n");
443		release_firmware(fw);
444		status = -1;
445		goto load_code_exit;
446	}
447
448	for (index = 0; index < fw->size; index++)
449		new_page[index] = fw->data[index];
450
451	release_firmware(fw);
452
453	writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
454	writel(temp_pci, &icom_port->dram->mac_load_addr);
455
456	/*Setting the syncReg to 0x80 causes adapter to start downloading
457	   the personality code into adapter instruction RAM.
458	   Once code is loaded, it will begin executing and, based on
459	   information provided above, will start DMAing data from
460	   shared memory to adapter DRAM.
461	 */
462	/* the wait loop below verifies this write operation has been done
463	   and processed
464	*/
465	writeb(START_DOWNLOAD, &icom_port->dram->sync);
466
467	/* Wait max 1 Sec for data download and processor to start */
468	for (index = 0; index < 10; index++) {
469		msleep(100);
470		if (readb(&icom_port->dram->misc_flags) & ICOM_HDW_ACTIVE)
471			break;
472	}
473
474	if (index == 10)
475		status = -1;
476
477	/*
478	 * check Cable ID
479	 */
480	cable_id = readb(&icom_port->dram->cable_id);
481
482	if (cable_id & ICOM_CABLE_ID_VALID) {
483		/* Get cable ID into the lower 4 bits (standard form) */
484		cable_id = (cable_id & ICOM_CABLE_ID_MASK) >> 4;
485		icom_port->cable_id = cable_id;
486	} else {
487		dev_err(&dev->dev,"Invalid or no cable attached\n");
488		icom_port->cable_id = NO_CABLE;
489	}
490
491      load_code_exit:
492
493	if (status != 0) {
494		/* Clear out any pending interrupts */
495		writew(0x3FFF, icom_port->int_reg);
496
497		/* Turn off port */
498		writeb(ICOM_DISABLE, &(icom_port->dram->disable));
499
500		/* Stop processor */
501		stop_processor(icom_port);
502
503		dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
504	}
505
506      if (new_page != NULL)
507	      pci_free_consistent(dev, 4096, new_page, temp_pci);
508}
509
510static int startup(struct icom_port *icom_port)
511{
512	unsigned long temp;
513	unsigned char cable_id, raw_cable_id;
514	unsigned long flags;
515	int port;
516
517	trace(icom_port, "STARTUP", 0);
518
519	if (!icom_port->dram) {
520		/* should NEVER be NULL */
521		dev_err(&icom_port->adapter->pci_dev->dev,
522			"Unusable Port, port configuration missing\n");
523		return -ENODEV;
524	}
525
526	/*
527	 * check Cable ID
528	 */
529	raw_cable_id = readb(&icom_port->dram->cable_id);
530	trace(icom_port, "CABLE_ID", raw_cable_id);
531
532	/* Get cable ID into the lower 4 bits (standard form) */
533	cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
534
535	/* Check for valid Cable ID */
536	if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
537	    (cable_id != icom_port->cable_id)) {
538
539		/* reload adapter code, pick up any potential changes in cable id */
540		load_code(icom_port);
541
542		/* still no sign of cable, error out */
543		raw_cable_id = readb(&icom_port->dram->cable_id);
544		cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
545		if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
546		    (icom_port->cable_id == NO_CABLE))
547			return -EIO;
548	}
549
550	/*
551	 * Finally, clear and  enable interrupts
552	 */
553	spin_lock_irqsave(&icom_lock, flags);
554	port = icom_port->port;
555	if (port == 0 || port == 1)
556		int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
557	else
558		int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
559
560	if (port == 0 || port == 2)
561		writew(0x00FF, icom_port->int_reg);
562	else
563		writew(0x3F00, icom_port->int_reg);
564	if (port < 4) {
565		temp = readl(int_mask_tbl[port].global_int_mask);
566		writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
567
568		/* write flush */
569		readl(int_mask_tbl[port].global_int_mask);
570	} else {
571		dev_err(&icom_port->adapter->pci_dev->dev,
572                        "Invalid port assignment\n");
573	}
574
575	spin_unlock_irqrestore(&icom_lock, flags);
576	return 0;
577}
578
579static void shutdown(struct icom_port *icom_port)
580{
581	unsigned long temp;
582	unsigned char cmdReg;
583	unsigned long flags;
584	int port;
585
586	spin_lock_irqsave(&icom_lock, flags);
587	trace(icom_port, "SHUTDOWN", 0);
588
589	/*
590	 * disable all interrupts
591	 */
592	port = icom_port->port;
593	if (port == 0 || port == 1)
594		int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
595	else
596		int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
597
598	if (port < 4) {
599		temp = readl(int_mask_tbl[port].global_int_mask);
600		writel(temp | int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
601
602		/* write flush */
603		readl(int_mask_tbl[port].global_int_mask);
604	} else {
605		dev_err(&icom_port->adapter->pci_dev->dev,
606                        "Invalid port assignment\n");
607	}
608	spin_unlock_irqrestore(&icom_lock, flags);
609
610	/*
611	 * disable break condition
612	 */
613	cmdReg = readb(&icom_port->dram->CmdReg);
614	if ((cmdReg | CMD_SND_BREAK) == CMD_SND_BREAK) {
615		writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
616	}
617}
618
619static int icom_write(struct uart_port *port)
620{
621	unsigned long data_count;
622	unsigned char cmdReg;
623	unsigned long offset;
624	int temp_tail = port->info->xmit.tail;
625
626	trace(ICOM_PORT, "WRITE", 0);
627
628	if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
629	    SA_FLAGS_READY_TO_XMIT) {
630		trace(ICOM_PORT, "WRITE_FULL", 0);
631		return 0;
632	}
633
634	data_count = 0;
635	while ((port->info->xmit.head != temp_tail) &&
636	       (data_count <= XMIT_BUFF_SZ)) {
637
638		ICOM_PORT->xmit_buf[data_count++] =
639		    port->info->xmit.buf[temp_tail];
640
641		temp_tail++;
642		temp_tail &= (UART_XMIT_SIZE - 1);
643	}
644
645	if (data_count) {
646		ICOM_PORT->statStg->xmit[0].flags =
647		    cpu_to_le16(SA_FLAGS_READY_TO_XMIT);
648		ICOM_PORT->statStg->xmit[0].leLength =
649		    cpu_to_le16(data_count);
650		offset =
651		    (unsigned long) &ICOM_PORT->statStg->xmit[0] -
652		    (unsigned long) ICOM_PORT->statStg;
653		*ICOM_PORT->xmitRestart =
654		    cpu_to_le32(ICOM_PORT->statStg_pci + offset);
655		cmdReg = readb(&ICOM_PORT->dram->CmdReg);
656		writeb(cmdReg | CMD_XMIT_RCV_ENABLE,
657		       &ICOM_PORT->dram->CmdReg);
658		writeb(START_XMIT, &ICOM_PORT->dram->StartXmitCmd);
659		trace(ICOM_PORT, "WRITE_START", data_count);
660		/* write flush */
661		readb(&ICOM_PORT->dram->StartXmitCmd);
662	}
663
664	return data_count;
665}
666
667static inline void check_modem_status(struct icom_port *icom_port)
668{
669	static char old_status = 0;
670	char delta_status;
671	unsigned char status;
672
673	spin_lock(&icom_port->uart_port.lock);
674
675	/*modem input register */
676	status = readb(&icom_port->dram->isr);
677	trace(icom_port, "CHECK_MODEM", status);
678	delta_status = status ^ old_status;
679	if (delta_status) {
680		if (delta_status & ICOM_RI)
681			icom_port->uart_port.icount.rng++;
682		if (delta_status & ICOM_DSR)
683			icom_port->uart_port.icount.dsr++;
684		if (delta_status & ICOM_DCD)
685			uart_handle_dcd_change(&icom_port->uart_port,
686					       delta_status & ICOM_DCD);
687		if (delta_status & ICOM_CTS)
688			uart_handle_cts_change(&icom_port->uart_port,
689					       delta_status & ICOM_CTS);
690
691		wake_up_interruptible(&icom_port->uart_port.info->
692				      delta_msr_wait);
693		old_status = status;
694	}
695	spin_unlock(&icom_port->uart_port.lock);
696}
697
698static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
699{
700	unsigned short int count;
701	int i;
702
703	if (port_int_reg & (INT_XMIT_COMPLETED)) {
704		trace(icom_port, "XMIT_COMPLETE", 0);
705
706		/* clear buffer in use bit */
707		icom_port->statStg->xmit[0].flags &=
708			cpu_to_le16(~SA_FLAGS_READY_TO_XMIT);
709
710		count = (unsigned short int)
711			cpu_to_le16(icom_port->statStg->xmit[0].leLength);
712		icom_port->uart_port.icount.tx += count;
713
714		for (i=0; i<count &&
715			!uart_circ_empty(&icom_port->uart_port.info->xmit); i++) {
716
717			icom_port->uart_port.info->xmit.tail++;
718			icom_port->uart_port.info->xmit.tail &=
719				(UART_XMIT_SIZE - 1);
720		}
721
722		if (!icom_write(&icom_port->uart_port))
723			/* activate write queue */
724			uart_write_wakeup(&icom_port->uart_port);
725	} else
726		trace(icom_port, "XMIT_DISABLED", 0);
727}
728
729static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
730{
731	short int count, rcv_buff;
732	struct tty_struct *tty = icom_port->uart_port.info->tty;
733	unsigned short int status;
734	struct uart_icount *icount;
735	unsigned long offset;
736	unsigned char flag;
737
738	trace(icom_port, "RCV_COMPLETE", 0);
739	rcv_buff = icom_port->next_rcv;
740
741	status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
742	while (status & SA_FL_RCV_DONE) {
743		int first = -1;
744
745		trace(icom_port, "FID_STATUS", status);
746		count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
747
748                count = tty_buffer_request_room(tty, count);
749		trace(icom_port, "RCV_COUNT", count);
750
751		trace(icom_port, "REAL_COUNT", count);
752
753		offset =
754			cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
755			icom_port->recv_buf_pci;
756
757		/* Block copy all but the last byte as this may have status */
758		if (count > 0) {
759			first = icom_port->recv_buf[offset];
760			tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1);
761		}
762
763		icount = &icom_port->uart_port.icount;
764		icount->rx += count;
765
766		/* Break detect logic */
767		if ((status & SA_FLAGS_FRAME_ERROR)
768		    && first == 0) {
769			status &= ~SA_FLAGS_FRAME_ERROR;
770			status |= SA_FLAGS_BREAK_DET;
771			trace(icom_port, "BREAK_DET", 0);
772		}
773
774		flag = TTY_NORMAL;
775
776		if (status &
777		    (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
778		     SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
779
780			if (status & SA_FLAGS_BREAK_DET)
781				icount->brk++;
782			if (status & SA_FLAGS_PARITY_ERROR)
783				icount->parity++;
784			if (status & SA_FLAGS_FRAME_ERROR)
785				icount->frame++;
786			if (status & SA_FLAGS_OVERRUN)
787				icount->overrun++;
788
789			/*
790			 * Now check to see if character should be
791			 * ignored, and mask off conditions which
792			 * should be ignored.
793			 */
794			if (status & icom_port->ignore_status_mask) {
795				trace(icom_port, "IGNORE_CHAR", 0);
796				goto ignore_char;
797			}
798
799			status &= icom_port->read_status_mask;
800
801			if (status & SA_FLAGS_BREAK_DET) {
802				flag = TTY_BREAK;
803			} else if (status & SA_FLAGS_PARITY_ERROR) {
804				trace(icom_port, "PARITY_ERROR", 0);
805				flag = TTY_PARITY;
806			} else if (status & SA_FLAGS_FRAME_ERROR)
807				flag = TTY_FRAME;
808
809		}
810
811		tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag);
812
813		if (status & SA_FLAGS_OVERRUN)
814			/*
815			 * Overrun is special, since it's
816			 * reported immediately, and doesn't
817			 * affect the current character
818			 */
819			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
820ignore_char:
821		icom_port->statStg->rcv[rcv_buff].flags = 0;
822		icom_port->statStg->rcv[rcv_buff].leLength = 0;
823		icom_port->statStg->rcv[rcv_buff].WorkingLength =
824			(unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
825
826		rcv_buff++;
827		if (rcv_buff == NUM_RBUFFS)
828			rcv_buff = 0;
829
830		status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
831	}
832	icom_port->next_rcv = rcv_buff;
833	tty_flip_buffer_push(tty);
834}
835
836static void process_interrupt(u16 port_int_reg,
837			      struct icom_port *icom_port)
838{
839
840	spin_lock(&icom_port->uart_port.lock);
841	trace(icom_port, "INTERRUPT", port_int_reg);
842
843	if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
844		xmit_interrupt(port_int_reg, icom_port);
845
846	if (port_int_reg & INT_RCV_COMPLETED)
847		recv_interrupt(port_int_reg, icom_port);
848
849	spin_unlock(&icom_port->uart_port.lock);
850}
851
852static irqreturn_t icom_interrupt(int irq, void *dev_id)
853{
854	void __iomem * int_reg;
855	u32 adapter_interrupts;
856	u16 port_int_reg;
857	struct icom_adapter *icom_adapter;
858	struct icom_port *icom_port;
859
860	/* find icom_port for this interrupt */
861	icom_adapter = (struct icom_adapter *) dev_id;
862
863	if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
864		int_reg = icom_adapter->base_addr + 0x8024;
865
866		adapter_interrupts = readl(int_reg);
867
868		if (adapter_interrupts & 0x00003FFF) {
869			/* port 2 interrupt,  NOTE:  for all ADAPTER_V2, port 2 will be active */
870			icom_port = &icom_adapter->port_info[2];
871			port_int_reg = (u16) adapter_interrupts;
872			process_interrupt(port_int_reg, icom_port);
873			check_modem_status(icom_port);
874		}
875		if (adapter_interrupts & 0x3FFF0000) {
876			/* port 3 interrupt */
877			icom_port = &icom_adapter->port_info[3];
878			if (icom_port->status == ICOM_PORT_ACTIVE) {
879				port_int_reg =
880				    (u16) (adapter_interrupts >> 16);
881				process_interrupt(port_int_reg, icom_port);
882				check_modem_status(icom_port);
883			}
884		}
885
886		/* Clear out any pending interrupts */
887		writel(adapter_interrupts, int_reg);
888
889		int_reg = icom_adapter->base_addr + 0x8004;
890	} else {
891		int_reg = icom_adapter->base_addr + 0x4004;
892	}
893
894	adapter_interrupts = readl(int_reg);
895
896	if (adapter_interrupts & 0x00003FFF) {
897		/* port 0 interrupt, NOTE:  for all adapters, port 0 will be active */
898		icom_port = &icom_adapter->port_info[0];
899		port_int_reg = (u16) adapter_interrupts;
900		process_interrupt(port_int_reg, icom_port);
901		check_modem_status(icom_port);
902	}
903	if (adapter_interrupts & 0x3FFF0000) {
904		/* port 1 interrupt */
905		icom_port = &icom_adapter->port_info[1];
906		if (icom_port->status == ICOM_PORT_ACTIVE) {
907			port_int_reg = (u16) (adapter_interrupts >> 16);
908			process_interrupt(port_int_reg, icom_port);
909			check_modem_status(icom_port);
910		}
911	}
912
913	/* Clear out any pending interrupts */
914	writel(adapter_interrupts, int_reg);
915
916	/* flush the write */
917	adapter_interrupts = readl(int_reg);
918
919	return IRQ_HANDLED;
920}
921
922/*
923 * ------------------------------------------------------------------
924 * Begin serial-core API
925 * ------------------------------------------------------------------
926 */
927static unsigned int icom_tx_empty(struct uart_port *port)
928{
929	int ret;
930	unsigned long flags;
931
932	spin_lock_irqsave(&port->lock, flags);
933	if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
934	    SA_FLAGS_READY_TO_XMIT)
935		ret = TIOCSER_TEMT;
936	else
937		ret = 0;
938
939	spin_unlock_irqrestore(&port->lock, flags);
940	return ret;
941}
942
943static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
944{
945	unsigned char local_osr;
946
947	trace(ICOM_PORT, "SET_MODEM", 0);
948	local_osr = readb(&ICOM_PORT->dram->osr);
949
950	if (mctrl & TIOCM_RTS) {
951		trace(ICOM_PORT, "RAISE_RTS", 0);
952		local_osr |= ICOM_RTS;
953	} else {
954		trace(ICOM_PORT, "LOWER_RTS", 0);
955		local_osr &= ~ICOM_RTS;
956	}
957
958	if (mctrl & TIOCM_DTR) {
959		trace(ICOM_PORT, "RAISE_DTR", 0);
960		local_osr |= ICOM_DTR;
961	} else {
962		trace(ICOM_PORT, "LOWER_DTR", 0);
963		local_osr &= ~ICOM_DTR;
964	}
965
966	writeb(local_osr, &ICOM_PORT->dram->osr);
967}
968
969static unsigned int icom_get_mctrl(struct uart_port *port)
970{
971	unsigned char status;
972	unsigned int result;
973
974	trace(ICOM_PORT, "GET_MODEM", 0);
975
976	status = readb(&ICOM_PORT->dram->isr);
977
978	result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
979	    | ((status & ICOM_RI) ? TIOCM_RNG : 0)
980	    | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
981	    | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
982	return result;
983}
984
985static void icom_stop_tx(struct uart_port *port)
986{
987	unsigned char cmdReg;
988
989	trace(ICOM_PORT, "STOP", 0);
990	cmdReg = readb(&ICOM_PORT->dram->CmdReg);
991	writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
992}
993
994static void icom_start_tx(struct uart_port *port)
995{
996	unsigned char cmdReg;
997
998	trace(ICOM_PORT, "START", 0);
999	cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1000	if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
1001		writeb(cmdReg & ~CMD_HOLD_XMIT,
1002		       &ICOM_PORT->dram->CmdReg);
1003
1004	icom_write(port);
1005}
1006
1007static void icom_send_xchar(struct uart_port *port, char ch)
1008{
1009	unsigned char xdata;
1010	int index;
1011	unsigned long flags;
1012
1013	trace(ICOM_PORT, "SEND_XCHAR", ch);
1014
1015	/* wait .1 sec to send char */
1016	for (index = 0; index < 10; index++) {
1017		spin_lock_irqsave(&port->lock, flags);
1018		xdata = readb(&ICOM_PORT->dram->xchar);
1019		if (xdata == 0x00) {
1020			trace(ICOM_PORT, "QUICK_WRITE", 0);
1021			writeb(ch, &ICOM_PORT->dram->xchar);
1022
1023			/* flush write operation */
1024			xdata = readb(&ICOM_PORT->dram->xchar);
1025			spin_unlock_irqrestore(&port->lock, flags);
1026			break;
1027		}
1028		spin_unlock_irqrestore(&port->lock, flags);
1029		msleep(10);
1030	}
1031}
1032
1033static void icom_stop_rx(struct uart_port *port)
1034{
1035	unsigned char cmdReg;
1036
1037	cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1038	writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1039}
1040
1041static void icom_enable_ms(struct uart_port *port)
1042{
1043	/* no-op */
1044}
1045
1046static void icom_break(struct uart_port *port, int break_state)
1047{
1048	unsigned char cmdReg;
1049	unsigned long flags;
1050
1051	spin_lock_irqsave(&port->lock, flags);
1052	trace(ICOM_PORT, "BREAK", 0);
1053	cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1054	if (break_state == -1) {
1055		writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1056	} else {
1057		writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1058	}
1059	spin_unlock_irqrestore(&port->lock, flags);
1060}
1061
1062static int icom_open(struct uart_port *port)
1063{
1064	int retval;
1065
1066	kobject_get(&ICOM_PORT->adapter->kobj);
1067	retval = startup(ICOM_PORT);
1068
1069	if (retval) {
1070		kobject_put(&ICOM_PORT->adapter->kobj);
1071		trace(ICOM_PORT, "STARTUP_ERROR", 0);
1072		return retval;
1073	}
1074
1075	return 0;
1076}
1077
1078static void icom_close(struct uart_port *port)
1079{
1080	unsigned char cmdReg;
1081
1082	trace(ICOM_PORT, "CLOSE", 0);
1083
1084	/* stop receiver */
1085	cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1086	writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
1087	       &ICOM_PORT->dram->CmdReg);
1088
1089	shutdown(ICOM_PORT);
1090
1091	kobject_put(&ICOM_PORT->adapter->kobj);
1092}
1093
1094static void icom_set_termios(struct uart_port *port,
1095			     struct ktermios *termios,
1096			     struct ktermios *old_termios)
1097{
1098	int baud;
1099	unsigned cflag, iflag;
1100	int bits;
1101	char new_config2;
1102	char new_config3 = 0;
1103	char tmp_byte;
1104	int index;
1105	int rcv_buff, xmit_buff;
1106	unsigned long offset;
1107	unsigned long flags;
1108
1109	spin_lock_irqsave(&port->lock, flags);
1110	trace(ICOM_PORT, "CHANGE_SPEED", 0);
1111
1112	cflag = termios->c_cflag;
1113	iflag = termios->c_iflag;
1114
1115	new_config2 = ICOM_ACFG_DRIVE1;
1116
1117	/* byte size and parity */
1118	switch (cflag & CSIZE) {
1119	case CS5:		/* 5 bits/char */
1120		new_config2 |= ICOM_ACFG_5BPC;
1121		bits = 7;
1122		break;
1123	case CS6:		/* 6 bits/char */
1124		new_config2 |= ICOM_ACFG_6BPC;
1125		bits = 8;
1126		break;
1127	case CS7:		/* 7 bits/char */
1128		new_config2 |= ICOM_ACFG_7BPC;
1129		bits = 9;
1130		break;
1131	case CS8:		/* 8 bits/char */
1132		new_config2 |= ICOM_ACFG_8BPC;
1133		bits = 10;
1134		break;
1135	default:
1136		bits = 10;
1137		break;
1138	}
1139	if (cflag & CSTOPB) {
1140		/* 2 stop bits */
1141		new_config2 |= ICOM_ACFG_2STOP_BIT;
1142		bits++;
1143	}
1144	if (cflag & PARENB) {
1145		/* parity bit enabled */
1146		new_config2 |= ICOM_ACFG_PARITY_ENAB;
1147		trace(ICOM_PORT, "PARENB", 0);
1148		bits++;
1149	}
1150	if (cflag & PARODD) {
1151		/* odd parity */
1152		new_config2 |= ICOM_ACFG_PARITY_ODD;
1153		trace(ICOM_PORT, "PARODD", 0);
1154	}
1155
1156	/* Determine divisor based on baud rate */
1157	baud = uart_get_baud_rate(port, termios, old_termios,
1158				  icom_acfg_baud[0],
1159				  icom_acfg_baud[BAUD_TABLE_LIMIT]);
1160	if (!baud)
1161		baud = 9600;	/* B0 transition handled in rs_set_termios */
1162
1163	for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1164		if (icom_acfg_baud[index] == baud) {
1165			new_config3 = index;
1166			break;
1167		}
1168	}
1169
1170	uart_update_timeout(port, cflag, baud);
1171
1172	/* CTS flow control flag and modem status interrupts */
1173	tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1174	if (cflag & CRTSCTS)
1175		tmp_byte |= HDLC_HDW_FLOW;
1176	else
1177		tmp_byte &= ~HDLC_HDW_FLOW;
1178	writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1179
1180	/*
1181	 * Set up parity check flag
1182	 */
1183	ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1184	if (iflag & INPCK)
1185		ICOM_PORT->read_status_mask |=
1186		    SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1187
1188	if ((iflag & BRKINT) || (iflag & PARMRK))
1189		ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1190
1191	/*
1192	 * Characters to ignore
1193	 */
1194	ICOM_PORT->ignore_status_mask = 0;
1195	if (iflag & IGNPAR)
1196		ICOM_PORT->ignore_status_mask |=
1197		    SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1198	if (iflag & IGNBRK) {
1199		ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1200		/*
1201		 * If we're ignore parity and break indicators, ignore
1202		 * overruns too.  (For real raw support).
1203		 */
1204		if (iflag & IGNPAR)
1205			ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1206	}
1207
1208	/*
1209	 * !!! ignore all characters if CREAD is not set
1210	 */
1211	if ((cflag & CREAD) == 0)
1212		ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1213
1214	/* Turn off Receiver to prepare for reset */
1215	writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1216
1217	for (index = 0; index < 10; index++) {
1218		if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1219			break;
1220		}
1221	}
1222
1223	/* clear all current buffers of data */
1224	for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1225		ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1226		ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1227		ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1228		    (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1229	}
1230
1231	for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1232		ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1233	}
1234
1235	/* activate changes and start xmit and receiver here */
1236	/* Enable the receiver */
1237	writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1238	writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1239	tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1240	tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1241	writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1242	writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer));	/* 0.5 seconds */
1243	writeb(0xFF, &(ICOM_PORT->dram->ier));	/* enable modem signal interrupts */
1244
1245	/* reset processor */
1246	writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1247
1248	for (index = 0; index < 10; index++) {
1249		if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1250			break;
1251		}
1252	}
1253
1254	/* Enable Transmitter and Reciever */
1255	offset =
1256	    (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1257	    (unsigned long) ICOM_PORT->statStg;
1258	writel(ICOM_PORT->statStg_pci + offset,
1259	       &ICOM_PORT->dram->RcvStatusAddr);
1260	ICOM_PORT->next_rcv = 0;
1261	ICOM_PORT->put_length = 0;
1262	*ICOM_PORT->xmitRestart = 0;
1263	writel(ICOM_PORT->xmitRestart_pci,
1264	       &ICOM_PORT->dram->XmitStatusAddr);
1265	trace(ICOM_PORT, "XR_ENAB", 0);
1266	writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1267
1268	spin_unlock_irqrestore(&port->lock, flags);
1269}
1270
1271static const char *icom_type(struct uart_port *port)
1272{
1273	return "icom";
1274}
1275
1276static void icom_release_port(struct uart_port *port)
1277{
1278}
1279
1280static int icom_request_port(struct uart_port *port)
1281{
1282	return 0;
1283}
1284
1285static void icom_config_port(struct uart_port *port, int flags)
1286{
1287	port->type = PORT_ICOM;
1288}
1289
1290static struct uart_ops icom_ops = {
1291	.tx_empty = icom_tx_empty,
1292	.set_mctrl = icom_set_mctrl,
1293	.get_mctrl = icom_get_mctrl,
1294	.stop_tx = icom_stop_tx,
1295	.start_tx = icom_start_tx,
1296	.send_xchar = icom_send_xchar,
1297	.stop_rx = icom_stop_rx,
1298	.enable_ms = icom_enable_ms,
1299	.break_ctl = icom_break,
1300	.startup = icom_open,
1301	.shutdown = icom_close,
1302	.set_termios = icom_set_termios,
1303	.type = icom_type,
1304	.release_port = icom_release_port,
1305	.request_port = icom_request_port,
1306	.config_port = icom_config_port,
1307};
1308
1309#define ICOM_CONSOLE NULL
1310
1311static struct uart_driver icom_uart_driver = {
1312	.owner = THIS_MODULE,
1313	.driver_name = ICOM_DRIVER_NAME,
1314	.dev_name = "ttyA",
1315	.major = ICOM_MAJOR,
1316	.minor = ICOM_MINOR_START,
1317	.nr = NR_PORTS,
1318	.cons = ICOM_CONSOLE,
1319};
1320
1321static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1322{
1323	u32 subsystem_id = icom_adapter->subsystem_id;
1324	int retval = 0;
1325	int i;
1326	struct icom_port *icom_port;
1327
1328	if (icom_adapter->version == ADAPTER_V1) {
1329		icom_adapter->numb_ports = 2;
1330
1331		for (i = 0; i < 2; i++) {
1332			icom_port = &icom_adapter->port_info[i];
1333			icom_port->port = i;
1334			icom_port->status = ICOM_PORT_ACTIVE;
1335			icom_port->imbed_modem = ICOM_UNKNOWN;
1336		}
1337	} else {
1338		if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1339			icom_adapter->numb_ports = 4;
1340
1341			for (i = 0; i < 4; i++) {
1342				icom_port = &icom_adapter->port_info[i];
1343
1344				icom_port->port = i;
1345				icom_port->status = ICOM_PORT_ACTIVE;
1346				icom_port->imbed_modem = ICOM_IMBED_MODEM;
1347			}
1348		} else {
1349			icom_adapter->numb_ports = 4;
1350
1351			icom_adapter->port_info[0].port = 0;
1352			icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1353
1354			if (subsystem_id ==
1355			    PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1356				icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1357			} else {
1358				icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1359			}
1360
1361			icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1362
1363			icom_adapter->port_info[2].port = 2;
1364			icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1365			icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1366			icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1367		}
1368	}
1369
1370	return retval;
1371}
1372
1373static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1374{
1375	if (icom_adapter->version == ADAPTER_V1) {
1376		icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1377		icom_port->int_reg = icom_adapter->base_addr +
1378		    0x4004 + 2 - 2 * port_num;
1379	} else {
1380		icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1381		if (icom_port->port < 2)
1382			icom_port->int_reg = icom_adapter->base_addr +
1383			    0x8004 + 2 - 2 * icom_port->port;
1384		else
1385			icom_port->int_reg = icom_adapter->base_addr +
1386			    0x8024 + 2 - 2 * (icom_port->port - 2);
1387	}
1388}
1389static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
1390{
1391	struct icom_port *icom_port;
1392	int port_num;
1393	int retval;
1394
1395	for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1396
1397		icom_port = &icom_adapter->port_info[port_num];
1398
1399		if (icom_port->status == ICOM_PORT_ACTIVE) {
1400			icom_port_active(icom_port, icom_adapter, port_num);
1401			icom_port->dram = icom_adapter->base_addr +
1402					0x2000 * icom_port->port;
1403
1404			icom_port->adapter = icom_adapter;
1405
1406			/* get port memory */
1407			if ((retval = get_port_memory(icom_port)) != 0) {
1408				dev_err(&icom_port->adapter->pci_dev->dev,
1409					"Memory allocation for port FAILED\n");
1410			}
1411		}
1412	}
1413	return 0;
1414}
1415
1416static int __devinit icom_alloc_adapter(struct icom_adapter
1417					**icom_adapter_ref)
1418{
1419	int adapter_count = 0;
1420	struct icom_adapter *icom_adapter;
1421	struct icom_adapter *cur_adapter_entry;
1422	struct list_head *tmp;
1423
1424	icom_adapter = (struct icom_adapter *)
1425	    kzalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1426
1427	if (!icom_adapter) {
1428		return -ENOMEM;
1429	}
1430
1431	list_for_each(tmp, &icom_adapter_head) {
1432		cur_adapter_entry =
1433		    list_entry(tmp, struct icom_adapter,
1434			       icom_adapter_entry);
1435		if (cur_adapter_entry->index != adapter_count) {
1436			break;
1437		}
1438		adapter_count++;
1439	}
1440
1441	icom_adapter->index = adapter_count;
1442	list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1443
1444	*icom_adapter_ref = icom_adapter;
1445	return 0;
1446}
1447
1448static void icom_free_adapter(struct icom_adapter *icom_adapter)
1449{
1450	list_del(&icom_adapter->icom_adapter_entry);
1451	kfree(icom_adapter);
1452}
1453
1454static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1455{
1456	struct icom_port *icom_port;
1457	int index;
1458
1459	for (index = 0; index < icom_adapter->numb_ports; index++) {
1460		icom_port = &icom_adapter->port_info[index];
1461
1462		if (icom_port->status == ICOM_PORT_ACTIVE) {
1463			dev_info(&icom_adapter->pci_dev->dev,
1464				 "Device removed\n");
1465
1466			uart_remove_one_port(&icom_uart_driver,
1467					     &icom_port->uart_port);
1468
1469			/* be sure that DTR and RTS are dropped */
1470			writeb(0x00, &icom_port->dram->osr);
1471
1472			/* Wait 0.1 Sec for simple Init to complete */
1473			msleep(100);
1474
1475			/* Stop proccessor */
1476			stop_processor(icom_port);
1477
1478			free_port_memory(icom_port);
1479		}
1480	}
1481
1482	free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter);
1483	iounmap(icom_adapter->base_addr);
1484	icom_free_adapter(icom_adapter);
1485	pci_release_regions(icom_adapter->pci_dev);
1486}
1487
1488static void icom_kobj_release(struct kobject *kobj)
1489{
1490	struct icom_adapter *icom_adapter;
1491
1492	icom_adapter = to_icom_adapter(kobj);
1493	icom_remove_adapter(icom_adapter);
1494}
1495
1496static struct kobj_type icom_kobj_type = {
1497	.release = icom_kobj_release,
1498};
1499
1500static int __devinit icom_probe(struct pci_dev *dev,
1501				const struct pci_device_id *ent)
1502{
1503	int index;
1504        unsigned int command_reg;
1505        int retval;
1506        struct icom_adapter *icom_adapter;
1507        struct icom_port *icom_port;
1508
1509        retval = pci_enable_device(dev);
1510        if (retval) {
1511		dev_err(&dev->dev, "Device enable FAILED\n");
1512                return retval;
1513	}
1514
1515	if ( (retval = pci_request_regions(dev, "icom"))) {
1516		 dev_err(&dev->dev, "pci_request_regions FAILED\n");
1517		 pci_disable_device(dev);
1518		 return retval;
1519	 }
1520
1521        pci_set_master(dev);
1522
1523        if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1524		dev_err(&dev->dev, "PCI Config read FAILED\n");
1525                return retval;
1526        }
1527
1528	pci_write_config_dword(dev, PCI_COMMAND,
1529		command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1530 		| PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1531
1532        if (ent->driver_data == ADAPTER_V1) {
1533		pci_write_config_dword(dev, 0x44, 0x8300830A);
1534	 } else {
1535		pci_write_config_dword(dev, 0x44, 0x42004200);
1536		pci_write_config_dword(dev, 0x48, 0x42004200);
1537         }
1538
1539
1540	retval = icom_alloc_adapter(&icom_adapter);
1541	if (retval) {
1542		 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1543		 retval = -EIO;
1544		 goto probe_exit0;
1545	}
1546
1547	 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1548	 icom_adapter->pci_dev = dev;
1549	 icom_adapter->version = ent->driver_data;
1550	 icom_adapter->subsystem_id = ent->subdevice;
1551
1552
1553	retval = icom_init_ports(icom_adapter);
1554	if (retval) {
1555		dev_err(&dev->dev, "Port configuration failed\n");
1556		goto probe_exit1;
1557	}
1558
1559	 icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1560						pci_resource_len(dev, 0));
1561
1562	if (!icom_adapter->base_addr)
1563		goto probe_exit1;
1564
1565	 /* save off irq and request irq line */
1566	 if ( (retval = request_irq(dev->irq, icom_interrupt,
1567				   IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME,
1568				   (void *) icom_adapter))) {
1569		  goto probe_exit2;
1570	 }
1571
1572	retval = icom_load_ports(icom_adapter);
1573
1574        for (index = 0; index < icom_adapter->numb_ports; index++) {
1575		icom_port = &icom_adapter->port_info[index];
1576
1577		if (icom_port->status == ICOM_PORT_ACTIVE) {
1578			icom_port->uart_port.irq = icom_port->adapter->pci_dev->irq;
1579			icom_port->uart_port.type = PORT_ICOM;
1580			icom_port->uart_port.iotype = UPIO_MEM;
1581			icom_port->uart_port.membase =
1582					       (char *) icom_adapter->base_addr_pci;
1583			icom_port->uart_port.fifosize = 16;
1584			icom_port->uart_port.ops = &icom_ops;
1585			icom_port->uart_port.line =
1586		        icom_port->port + icom_adapter->index * 4;
1587			if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1588				icom_port->status = ICOM_PORT_OFF;
1589				dev_err(&dev->dev, "Device add failed\n");
1590			 } else
1591			        dev_info(&dev->dev, "Device added\n");
1592		}
1593	}
1594
1595	kobject_init(&icom_adapter->kobj);
1596	icom_adapter->kobj.ktype = &icom_kobj_type;
1597	return 0;
1598
1599probe_exit2:
1600	iounmap(icom_adapter->base_addr);
1601probe_exit1:
1602	icom_free_adapter(icom_adapter);
1603
1604probe_exit0:
1605	pci_release_regions(dev);
1606	pci_disable_device(dev);
1607
1608        return retval;
1609
1610
1611}
1612
1613static void __devexit icom_remove(struct pci_dev *dev)
1614{
1615	struct icom_adapter *icom_adapter;
1616	struct list_head *tmp;
1617
1618	list_for_each(tmp, &icom_adapter_head) {
1619		icom_adapter = list_entry(tmp, struct icom_adapter,
1620					  icom_adapter_entry);
1621		if (icom_adapter->pci_dev == dev) {
1622			kobject_put(&icom_adapter->kobj);
1623			return;
1624		}
1625	}
1626
1627	dev_err(&dev->dev, "Unable to find device to remove\n");
1628}
1629
1630static struct pci_driver icom_pci_driver = {
1631	.name = ICOM_DRIVER_NAME,
1632	.id_table = icom_pci_table,
1633	.probe = icom_probe,
1634	.remove = __devexit_p(icom_remove),
1635};
1636
1637static int __init icom_init(void)
1638{
1639	int ret;
1640
1641	spin_lock_init(&icom_lock);
1642
1643	ret = uart_register_driver(&icom_uart_driver);
1644	if (ret)
1645		return ret;
1646
1647	ret = pci_register_driver(&icom_pci_driver);
1648
1649	if (ret < 0)
1650		uart_unregister_driver(&icom_uart_driver);
1651
1652	return ret;
1653}
1654
1655static void __exit icom_exit(void)
1656{
1657	pci_unregister_driver(&icom_pci_driver);
1658	uart_unregister_driver(&icom_uart_driver);
1659}
1660
1661module_init(icom_init);
1662module_exit(icom_exit);
1663
1664#ifdef ICOM_TRACE
1665static inline void trace(struct icom_port *icom_port, char *trace_pt,
1666		  unsigned long trace_data)
1667{
1668	dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1669		 icom_port->port, trace_pt, trace_data);
1670}
1671#endif
1672
1673MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1674MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1675MODULE_SUPPORTED_DEVICE
1676    ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1677MODULE_LICENSE("GPL");
1678