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