[PATCH] serial: replace kmalloc+memset with kzalloc
[safe/jmp/linux-2.6] / 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 {
849         void __iomem * int_reg;
850         u32 adapter_interrupts;
851         u16 port_int_reg;
852         struct icom_adapter *icom_adapter;
853         struct icom_port *icom_port;
854
855         /* find icom_port for this interrupt */
856         icom_adapter = (struct icom_adapter *) dev_id;
857
858         if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
859                 int_reg = icom_adapter->base_addr + 0x8024;
860
861                 adapter_interrupts = readl(int_reg);
862
863                 if (adapter_interrupts & 0x00003FFF) {
864                         /* port 2 interrupt,  NOTE:  for all ADAPTER_V2, port 2 will be active */
865                         icom_port = &icom_adapter->port_info[2];
866                         port_int_reg = (u16) adapter_interrupts;
867                         process_interrupt(port_int_reg, icom_port);
868                         check_modem_status(icom_port);
869                 }
870                 if (adapter_interrupts & 0x3FFF0000) {
871                         /* port 3 interrupt */
872                         icom_port = &icom_adapter->port_info[3];
873                         if (icom_port->status == ICOM_PORT_ACTIVE) {
874                                 port_int_reg =
875                                     (u16) (adapter_interrupts >> 16);
876                                 process_interrupt(port_int_reg, icom_port);
877                                 check_modem_status(icom_port);
878                         }
879                 }
880
881                 /* Clear out any pending interrupts */
882                 writel(adapter_interrupts, int_reg);
883
884                 int_reg = icom_adapter->base_addr + 0x8004;
885         } else {
886                 int_reg = icom_adapter->base_addr + 0x4004;
887         }
888
889         adapter_interrupts = readl(int_reg);
890
891         if (adapter_interrupts & 0x00003FFF) {
892                 /* port 0 interrupt, NOTE:  for all adapters, port 0 will be active */
893                 icom_port = &icom_adapter->port_info[0];
894                 port_int_reg = (u16) adapter_interrupts;
895                 process_interrupt(port_int_reg, icom_port);
896                 check_modem_status(icom_port);
897         }
898         if (adapter_interrupts & 0x3FFF0000) {
899                 /* port 1 interrupt */
900                 icom_port = &icom_adapter->port_info[1];
901                 if (icom_port->status == ICOM_PORT_ACTIVE) {
902                         port_int_reg = (u16) (adapter_interrupts >> 16);
903                         process_interrupt(port_int_reg, icom_port);
904                         check_modem_status(icom_port);
905                 }
906         }
907
908         /* Clear out any pending interrupts */
909         writel(adapter_interrupts, int_reg);
910
911         /* flush the write */
912         adapter_interrupts = readl(int_reg);
913
914         return IRQ_HANDLED;
915 }
916
917 /*
918  * ------------------------------------------------------------------
919  * Begin serial-core API
920  * ------------------------------------------------------------------
921  */
922 static unsigned int icom_tx_empty(struct uart_port *port)
923 {
924         int ret;
925         unsigned long flags;
926
927         spin_lock_irqsave(&port->lock, flags);
928         if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
929             SA_FLAGS_READY_TO_XMIT)
930                 ret = TIOCSER_TEMT;
931         else
932                 ret = 0;
933
934         spin_unlock_irqrestore(&port->lock, flags);
935         return ret;
936 }
937
938 static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
939 {
940         unsigned char local_osr;
941
942         trace(ICOM_PORT, "SET_MODEM", 0);
943         local_osr = readb(&ICOM_PORT->dram->osr);
944
945         if (mctrl & TIOCM_RTS) {
946                 trace(ICOM_PORT, "RAISE_RTS", 0);
947                 local_osr |= ICOM_RTS;
948         } else {
949                 trace(ICOM_PORT, "LOWER_RTS", 0);
950                 local_osr &= ~ICOM_RTS;
951         }
952
953         if (mctrl & TIOCM_DTR) {
954                 trace(ICOM_PORT, "RAISE_DTR", 0);
955                 local_osr |= ICOM_DTR;
956         } else {
957                 trace(ICOM_PORT, "LOWER_DTR", 0);
958                 local_osr &= ~ICOM_DTR;
959         }
960
961         writeb(local_osr, &ICOM_PORT->dram->osr);
962 }
963
964 static unsigned int icom_get_mctrl(struct uart_port *port)
965 {
966         unsigned char status;
967         unsigned int result;
968
969         trace(ICOM_PORT, "GET_MODEM", 0);
970
971         status = readb(&ICOM_PORT->dram->isr);
972
973         result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
974             | ((status & ICOM_RI) ? TIOCM_RNG : 0)
975             | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
976             | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
977         return result;
978 }
979
980 static void icom_stop_tx(struct uart_port *port)
981 {
982         unsigned char cmdReg;
983
984         trace(ICOM_PORT, "STOP", 0);
985         cmdReg = readb(&ICOM_PORT->dram->CmdReg);
986         writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
987 }
988
989 static void icom_start_tx(struct uart_port *port)
990 {
991         unsigned char cmdReg;
992
993         trace(ICOM_PORT, "START", 0);
994         cmdReg = readb(&ICOM_PORT->dram->CmdReg);
995         if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
996                 writeb(cmdReg & ~CMD_HOLD_XMIT,
997                        &ICOM_PORT->dram->CmdReg);
998
999         icom_write(port);
1000 }
1001
1002 static void icom_send_xchar(struct uart_port *port, char ch)
1003 {
1004         unsigned char xdata;
1005         int index;
1006         unsigned long flags;
1007
1008         trace(ICOM_PORT, "SEND_XCHAR", ch);
1009
1010         /* wait .1 sec to send char */
1011         for (index = 0; index < 10; index++) {
1012                 spin_lock_irqsave(&port->lock, flags);
1013                 xdata = readb(&ICOM_PORT->dram->xchar);
1014                 if (xdata == 0x00) {
1015                         trace(ICOM_PORT, "QUICK_WRITE", 0);
1016                         writeb(ch, &ICOM_PORT->dram->xchar);
1017
1018                         /* flush write operation */
1019                         xdata = readb(&ICOM_PORT->dram->xchar);
1020                         spin_unlock_irqrestore(&port->lock, flags);
1021                         break;
1022                 }
1023                 spin_unlock_irqrestore(&port->lock, flags);
1024                 msleep(10);
1025         }
1026 }
1027
1028 static void icom_stop_rx(struct uart_port *port)
1029 {
1030         unsigned char cmdReg;
1031
1032         cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1033         writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1034 }
1035
1036 static void icom_enable_ms(struct uart_port *port)
1037 {
1038         /* no-op */
1039 }
1040
1041 static void icom_break(struct uart_port *port, int break_state)
1042 {
1043         unsigned char cmdReg;
1044         unsigned long flags;
1045
1046         spin_lock_irqsave(&port->lock, flags);
1047         trace(ICOM_PORT, "BREAK", 0);
1048         cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1049         if (break_state == -1) {
1050                 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1051         } else {
1052                 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1053         }
1054         spin_unlock_irqrestore(&port->lock, flags);
1055 }
1056
1057 static int icom_open(struct uart_port *port)
1058 {
1059         int retval;
1060
1061         kobject_get(&ICOM_PORT->adapter->kobj);
1062         retval = startup(ICOM_PORT);
1063
1064         if (retval) {
1065                 kobject_put(&ICOM_PORT->adapter->kobj);
1066                 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1067                 return retval;
1068         }
1069
1070         return 0;
1071 }
1072
1073 static void icom_close(struct uart_port *port)
1074 {
1075         unsigned char cmdReg;
1076
1077         trace(ICOM_PORT, "CLOSE", 0);
1078
1079         /* stop receiver */
1080         cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1081         writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
1082                &ICOM_PORT->dram->CmdReg);
1083
1084         shutdown(ICOM_PORT);
1085
1086         kobject_put(&ICOM_PORT->adapter->kobj);
1087 }
1088
1089 static void icom_set_termios(struct uart_port *port,
1090                              struct ktermios *termios,
1091                              struct ktermios *old_termios)
1092 {
1093         int baud;
1094         unsigned cflag, iflag;
1095         int bits;
1096         char new_config2;
1097         char new_config3 = 0;
1098         char tmp_byte;
1099         int index;
1100         int rcv_buff, xmit_buff;
1101         unsigned long offset;
1102         unsigned long flags;
1103
1104         spin_lock_irqsave(&port->lock, flags);
1105         trace(ICOM_PORT, "CHANGE_SPEED", 0);
1106
1107         cflag = termios->c_cflag;
1108         iflag = termios->c_iflag;
1109
1110         new_config2 = ICOM_ACFG_DRIVE1;
1111
1112         /* byte size and parity */
1113         switch (cflag & CSIZE) {
1114         case CS5:               /* 5 bits/char */
1115                 new_config2 |= ICOM_ACFG_5BPC;
1116                 bits = 7;
1117                 break;
1118         case CS6:               /* 6 bits/char */
1119                 new_config2 |= ICOM_ACFG_6BPC;
1120                 bits = 8;
1121                 break;
1122         case CS7:               /* 7 bits/char */
1123                 new_config2 |= ICOM_ACFG_7BPC;
1124                 bits = 9;
1125                 break;
1126         case CS8:               /* 8 bits/char */
1127                 new_config2 |= ICOM_ACFG_8BPC;
1128                 bits = 10;
1129                 break;
1130         default:
1131                 bits = 10;
1132                 break;
1133         }
1134         if (cflag & CSTOPB) {
1135                 /* 2 stop bits */
1136                 new_config2 |= ICOM_ACFG_2STOP_BIT;
1137                 bits++;
1138         }
1139         if (cflag & PARENB) {
1140                 /* parity bit enabled */
1141                 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1142                 trace(ICOM_PORT, "PARENB", 0);
1143                 bits++;
1144         }
1145         if (cflag & PARODD) {
1146                 /* odd parity */
1147                 new_config2 |= ICOM_ACFG_PARITY_ODD;
1148                 trace(ICOM_PORT, "PARODD", 0);
1149         }
1150
1151         /* Determine divisor based on baud rate */
1152         baud = uart_get_baud_rate(port, termios, old_termios,
1153                                   icom_acfg_baud[0],
1154                                   icom_acfg_baud[BAUD_TABLE_LIMIT]);
1155         if (!baud)
1156                 baud = 9600;    /* B0 transition handled in rs_set_termios */
1157
1158         for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1159                 if (icom_acfg_baud[index] == baud) {
1160                         new_config3 = index;
1161                         break;
1162                 }
1163         }
1164
1165         uart_update_timeout(port, cflag, baud);
1166
1167         /* CTS flow control flag and modem status interrupts */
1168         tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1169         if (cflag & CRTSCTS)
1170                 tmp_byte |= HDLC_HDW_FLOW;
1171         else
1172                 tmp_byte &= ~HDLC_HDW_FLOW;
1173         writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1174
1175         /*
1176          * Set up parity check flag
1177          */
1178         ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1179         if (iflag & INPCK)
1180                 ICOM_PORT->read_status_mask |=
1181                     SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1182
1183         if ((iflag & BRKINT) || (iflag & PARMRK))
1184                 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1185
1186         /*
1187          * Characters to ignore
1188          */
1189         ICOM_PORT->ignore_status_mask = 0;
1190         if (iflag & IGNPAR)
1191                 ICOM_PORT->ignore_status_mask |=
1192                     SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1193         if (iflag & IGNBRK) {
1194                 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1195                 /*
1196                  * If we're ignore parity and break indicators, ignore
1197                  * overruns too.  (For real raw support).
1198                  */
1199                 if (iflag & IGNPAR)
1200                         ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1201         }
1202
1203         /*
1204          * !!! ignore all characters if CREAD is not set
1205          */
1206         if ((cflag & CREAD) == 0)
1207                 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1208
1209         /* Turn off Receiver to prepare for reset */
1210         writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1211
1212         for (index = 0; index < 10; index++) {
1213                 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1214                         break;
1215                 }
1216         }
1217
1218         /* clear all current buffers of data */
1219         for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1220                 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1221                 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1222                 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1223                     (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1224         }
1225
1226         for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1227                 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1228         }
1229
1230         /* activate changes and start xmit and receiver here */
1231         /* Enable the receiver */
1232         writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1233         writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1234         tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1235         tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1236         writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1237         writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer));    /* 0.5 seconds */
1238         writeb(0xFF, &(ICOM_PORT->dram->ier));  /* enable modem signal interrupts */
1239
1240         /* reset processor */
1241         writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1242
1243         for (index = 0; index < 10; index++) {
1244                 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1245                         break;
1246                 }
1247         }
1248
1249         /* Enable Transmitter and Reciever */
1250         offset =
1251             (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1252             (unsigned long) ICOM_PORT->statStg;
1253         writel(ICOM_PORT->statStg_pci + offset,
1254                &ICOM_PORT->dram->RcvStatusAddr);
1255         ICOM_PORT->next_rcv = 0;
1256         ICOM_PORT->put_length = 0;
1257         *ICOM_PORT->xmitRestart = 0;
1258         writel(ICOM_PORT->xmitRestart_pci,
1259                &ICOM_PORT->dram->XmitStatusAddr);
1260         trace(ICOM_PORT, "XR_ENAB", 0);
1261         writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1262
1263         spin_unlock_irqrestore(&port->lock, flags);
1264 }
1265
1266 static const char *icom_type(struct uart_port *port)
1267 {
1268         return "icom";
1269 }
1270
1271 static void icom_release_port(struct uart_port *port)
1272 {
1273 }
1274
1275 static int icom_request_port(struct uart_port *port)
1276 {
1277         return 0;
1278 }
1279
1280 static void icom_config_port(struct uart_port *port, int flags)
1281 {
1282         port->type = PORT_ICOM;
1283 }
1284
1285 static struct uart_ops icom_ops = {
1286         .tx_empty = icom_tx_empty,
1287         .set_mctrl = icom_set_mctrl,
1288         .get_mctrl = icom_get_mctrl,
1289         .stop_tx = icom_stop_tx,
1290         .start_tx = icom_start_tx,
1291         .send_xchar = icom_send_xchar,
1292         .stop_rx = icom_stop_rx,
1293         .enable_ms = icom_enable_ms,
1294         .break_ctl = icom_break,
1295         .startup = icom_open,
1296         .shutdown = icom_close,
1297         .set_termios = icom_set_termios,
1298         .type = icom_type,
1299         .release_port = icom_release_port,
1300         .request_port = icom_request_port,
1301         .config_port = icom_config_port,
1302 };
1303
1304 #define ICOM_CONSOLE NULL
1305
1306 static struct uart_driver icom_uart_driver = {
1307         .owner = THIS_MODULE,
1308         .driver_name = ICOM_DRIVER_NAME,
1309         .dev_name = "ttyA",
1310         .major = ICOM_MAJOR,
1311         .minor = ICOM_MINOR_START,
1312         .nr = NR_PORTS,
1313         .cons = ICOM_CONSOLE,
1314 };
1315
1316 static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1317 {
1318         u32 subsystem_id = icom_adapter->subsystem_id;
1319         int retval = 0;
1320         int i;
1321         struct icom_port *icom_port;
1322
1323         if (icom_adapter->version == ADAPTER_V1) {
1324                 icom_adapter->numb_ports = 2;
1325
1326                 for (i = 0; i < 2; i++) {
1327                         icom_port = &icom_adapter->port_info[i];
1328                         icom_port->port = i;
1329                         icom_port->status = ICOM_PORT_ACTIVE;
1330                         icom_port->imbed_modem = ICOM_UNKNOWN;
1331                 }
1332         } else {
1333                 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1334                         icom_adapter->numb_ports = 4;
1335
1336                         for (i = 0; i < 4; i++) {
1337                                 icom_port = &icom_adapter->port_info[i];
1338
1339                                 icom_port->port = i;
1340                                 icom_port->status = ICOM_PORT_ACTIVE;
1341                                 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1342                         }
1343                 } else {
1344                         icom_adapter->numb_ports = 4;
1345
1346                         icom_adapter->port_info[0].port = 0;
1347                         icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1348
1349                         if (subsystem_id ==
1350                             PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1351                                 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1352                         } else {
1353                                 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1354                         }
1355
1356                         icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1357
1358                         icom_adapter->port_info[2].port = 2;
1359                         icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1360                         icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1361                         icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1362                 }
1363         }
1364
1365         return retval;
1366 }
1367
1368 static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1369 {
1370         if (icom_adapter->version == ADAPTER_V1) {
1371                 icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1372                 icom_port->int_reg = icom_adapter->base_addr +
1373                     0x4004 + 2 - 2 * port_num;
1374         } else {
1375                 icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1376                 if (icom_port->port < 2)
1377                         icom_port->int_reg = icom_adapter->base_addr +
1378                             0x8004 + 2 - 2 * icom_port->port;
1379                 else
1380                         icom_port->int_reg = icom_adapter->base_addr +
1381                             0x8024 + 2 - 2 * (icom_port->port - 2);
1382         }
1383 }
1384 static int __init icom_load_ports(struct icom_adapter *icom_adapter)
1385 {
1386         struct icom_port *icom_port;
1387         int port_num;
1388         int retval;
1389
1390         for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1391
1392                 icom_port = &icom_adapter->port_info[port_num];
1393
1394                 if (icom_port->status == ICOM_PORT_ACTIVE) {
1395                         icom_port_active(icom_port, icom_adapter, port_num);
1396                         icom_port->dram = icom_adapter->base_addr +
1397                                         0x2000 * icom_port->port;
1398
1399                         icom_port->adapter = icom_adapter;
1400
1401                         /* get port memory */
1402                         if ((retval = get_port_memory(icom_port)) != 0) {
1403                                 dev_err(&icom_port->adapter->pci_dev->dev,
1404                                         "Memory allocation for port FAILED\n");
1405                         }
1406                 }
1407         }
1408         return 0;
1409 }
1410
1411 static int __devinit icom_alloc_adapter(struct icom_adapter
1412                                         **icom_adapter_ref)
1413 {
1414         int adapter_count = 0;
1415         struct icom_adapter *icom_adapter;
1416         struct icom_adapter *cur_adapter_entry;
1417         struct list_head *tmp;
1418
1419         icom_adapter = (struct icom_adapter *)
1420             kzalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1421
1422         if (!icom_adapter) {
1423                 return -ENOMEM;
1424         }
1425
1426         list_for_each(tmp, &icom_adapter_head) {
1427                 cur_adapter_entry =
1428                     list_entry(tmp, struct icom_adapter,
1429                                icom_adapter_entry);
1430                 if (cur_adapter_entry->index != adapter_count) {
1431                         break;
1432                 }
1433                 adapter_count++;
1434         }
1435
1436         icom_adapter->index = adapter_count;
1437         list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1438
1439         *icom_adapter_ref = icom_adapter;
1440         return 0;
1441 }
1442
1443 static void icom_free_adapter(struct icom_adapter *icom_adapter)
1444 {
1445         list_del(&icom_adapter->icom_adapter_entry);
1446         kfree(icom_adapter);
1447 }
1448
1449 static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1450 {
1451         struct icom_port *icom_port;
1452         int index;
1453
1454         for (index = 0; index < icom_adapter->numb_ports; index++) {
1455                 icom_port = &icom_adapter->port_info[index];
1456
1457                 if (icom_port->status == ICOM_PORT_ACTIVE) {
1458                         dev_info(&icom_adapter->pci_dev->dev,
1459                                  "Device removed\n");
1460
1461                         uart_remove_one_port(&icom_uart_driver,
1462                                              &icom_port->uart_port);
1463
1464                         /* be sure that DTR and RTS are dropped */
1465                         writeb(0x00, &icom_port->dram->osr);
1466
1467                         /* Wait 0.1 Sec for simple Init to complete */
1468                         msleep(100);
1469
1470                         /* Stop proccessor */
1471                         stop_processor(icom_port);
1472
1473                         free_port_memory(icom_port);
1474                 }
1475         }
1476
1477         free_irq(icom_adapter->irq_number, (void *) icom_adapter);
1478         iounmap(icom_adapter->base_addr);
1479         icom_free_adapter(icom_adapter);
1480         pci_release_regions(icom_adapter->pci_dev);
1481 }
1482
1483 static void icom_kobj_release(struct kobject *kobj)
1484 {
1485         struct icom_adapter *icom_adapter;
1486
1487         icom_adapter = to_icom_adapter(kobj);
1488         icom_remove_adapter(icom_adapter);
1489 }
1490
1491 static struct kobj_type icom_kobj_type = {
1492         .release = icom_kobj_release,
1493 };
1494
1495 static int __devinit icom_probe(struct pci_dev *dev,
1496                                 const struct pci_device_id *ent)
1497 {
1498         int index;
1499         unsigned int command_reg;
1500         int retval;
1501         struct icom_adapter *icom_adapter;
1502         struct icom_port *icom_port;
1503
1504         retval = pci_enable_device(dev);
1505         if (retval) {
1506                 dev_err(&dev->dev, "Device enable FAILED\n");
1507                 return retval;
1508         }
1509
1510         if ( (retval = pci_request_regions(dev, "icom"))) {
1511                  dev_err(&dev->dev, "pci_request_regions FAILED\n");
1512                  pci_disable_device(dev);
1513                  return retval;
1514          }
1515
1516         pci_set_master(dev);
1517
1518         if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1519                 dev_err(&dev->dev, "PCI Config read FAILED\n");
1520                 return retval;
1521         }
1522
1523         pci_write_config_dword(dev, PCI_COMMAND,
1524                 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1525                 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1526
1527         if (ent->driver_data == ADAPTER_V1) {
1528                 pci_write_config_dword(dev, 0x44, 0x8300830A);
1529          } else {
1530                 pci_write_config_dword(dev, 0x44, 0x42004200);
1531                 pci_write_config_dword(dev, 0x48, 0x42004200);
1532          }
1533
1534
1535         retval = icom_alloc_adapter(&icom_adapter);
1536         if (retval) {
1537                  dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1538                  retval = -EIO;
1539                  goto probe_exit0;
1540         }
1541
1542          icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1543          icom_adapter->irq_number = dev->irq;
1544          icom_adapter->pci_dev = dev;
1545          icom_adapter->version = ent->driver_data;
1546          icom_adapter->subsystem_id = ent->subdevice;
1547
1548
1549         retval = icom_init_ports(icom_adapter);
1550         if (retval) {
1551                 dev_err(&dev->dev, "Port configuration failed\n");
1552                 goto probe_exit1;
1553         }
1554
1555          icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1556                                                 pci_resource_len(dev, 0));
1557
1558         if (!icom_adapter->base_addr)
1559                 goto probe_exit1;
1560
1561          /* save off irq and request irq line */
1562          if ( (retval = request_irq(dev->irq, icom_interrupt,
1563                                    IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME,
1564                                    (void *) icom_adapter))) {
1565                   goto probe_exit2;
1566          }
1567
1568         retval = icom_load_ports(icom_adapter);
1569
1570         for (index = 0; index < icom_adapter->numb_ports; index++) {
1571                 icom_port = &icom_adapter->port_info[index];
1572
1573                 if (icom_port->status == ICOM_PORT_ACTIVE) {
1574                         icom_port->uart_port.irq = icom_port->adapter->irq_number;
1575                         icom_port->uart_port.type = PORT_ICOM;
1576                         icom_port->uart_port.iotype = UPIO_MEM;
1577                         icom_port->uart_port.membase =
1578                                                (char *) icom_adapter->base_addr_pci;
1579                         icom_port->uart_port.fifosize = 16;
1580                         icom_port->uart_port.ops = &icom_ops;
1581                         icom_port->uart_port.line =
1582                         icom_port->port + icom_adapter->index * 4;
1583                         if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1584                                 icom_port->status = ICOM_PORT_OFF;
1585                                 dev_err(&dev->dev, "Device add failed\n");
1586                          } else
1587                                 dev_info(&dev->dev, "Device added\n");
1588                 }
1589         }
1590
1591         kobject_init(&icom_adapter->kobj);
1592         icom_adapter->kobj.ktype = &icom_kobj_type;
1593         return 0;
1594
1595 probe_exit2:
1596         iounmap(icom_adapter->base_addr);
1597 probe_exit1:
1598         icom_free_adapter(icom_adapter);
1599
1600 probe_exit0:
1601         pci_release_regions(dev);
1602         pci_disable_device(dev);
1603
1604         return retval;
1605
1606
1607 }
1608
1609 static void __devexit icom_remove(struct pci_dev *dev)
1610 {
1611         struct icom_adapter *icom_adapter;
1612         struct list_head *tmp;
1613
1614         list_for_each(tmp, &icom_adapter_head) {
1615                 icom_adapter = list_entry(tmp, struct icom_adapter,
1616                                           icom_adapter_entry);
1617                 if (icom_adapter->pci_dev == dev) {
1618                         kobject_put(&icom_adapter->kobj);
1619                         return;
1620                 }
1621         }
1622
1623         dev_err(&dev->dev, "Unable to find device to remove\n");
1624 }
1625
1626 static struct pci_driver icom_pci_driver = {
1627         .name = ICOM_DRIVER_NAME,
1628         .id_table = icom_pci_table,
1629         .probe = icom_probe,
1630         .remove = __devexit_p(icom_remove),
1631 };
1632
1633 static int __init icom_init(void)
1634 {
1635         int ret;
1636
1637         spin_lock_init(&icom_lock);
1638
1639         ret = uart_register_driver(&icom_uart_driver);
1640         if (ret)
1641                 return ret;
1642
1643         ret = pci_register_driver(&icom_pci_driver);
1644
1645         if (ret < 0)
1646                 uart_unregister_driver(&icom_uart_driver);
1647
1648         return ret;
1649 }
1650
1651 static void __exit icom_exit(void)
1652 {
1653         pci_unregister_driver(&icom_pci_driver);
1654         uart_unregister_driver(&icom_uart_driver);
1655 }
1656
1657 module_init(icom_init);
1658 module_exit(icom_exit);
1659
1660 #ifdef ICOM_TRACE
1661 static inline void trace(struct icom_port *icom_port, char *trace_pt,
1662                   unsigned long trace_data)
1663 {
1664         dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1665                  icom_port->port, trace_pt, trace_data);
1666 }
1667 #endif
1668
1669 MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1670 MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1671 MODULE_SUPPORTED_DEVICE
1672     ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1673 MODULE_LICENSE("GPL");
1674