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