Merge branch 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[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 {
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             kmalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1421
1422         if (!icom_adapter) {
1423                 return -ENOMEM;
1424         }
1425
1426         memset(icom_adapter, 0, sizeof(struct icom_adapter));
1427
1428         list_for_each(tmp, &icom_adapter_head) {
1429                 cur_adapter_entry =
1430                     list_entry(tmp, struct icom_adapter,
1431                                icom_adapter_entry);
1432                 if (cur_adapter_entry->index != adapter_count) {
1433                         break;
1434                 }
1435                 adapter_count++;
1436         }
1437
1438         icom_adapter->index = adapter_count;
1439         list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1440
1441         *icom_adapter_ref = icom_adapter;
1442         return 0;
1443 }
1444
1445 static void icom_free_adapter(struct icom_adapter *icom_adapter)
1446 {
1447         list_del(&icom_adapter->icom_adapter_entry);
1448         kfree(icom_adapter);
1449 }
1450
1451 static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1452 {
1453         struct icom_port *icom_port;
1454         int index;
1455
1456         for (index = 0; index < icom_adapter->numb_ports; index++) {
1457                 icom_port = &icom_adapter->port_info[index];
1458
1459                 if (icom_port->status == ICOM_PORT_ACTIVE) {
1460                         dev_info(&icom_adapter->pci_dev->dev,
1461                                  "Device removed\n");
1462
1463                         uart_remove_one_port(&icom_uart_driver,
1464                                              &icom_port->uart_port);
1465
1466                         /* be sure that DTR and RTS are dropped */
1467                         writeb(0x00, &icom_port->dram->osr);
1468
1469                         /* Wait 0.1 Sec for simple Init to complete */
1470                         msleep(100);
1471
1472                         /* Stop proccessor */
1473                         stop_processor(icom_port);
1474
1475                         free_port_memory(icom_port);
1476                 }
1477         }
1478
1479         free_irq(icom_adapter->irq_number, (void *) icom_adapter);
1480         iounmap(icom_adapter->base_addr);
1481         icom_free_adapter(icom_adapter);
1482         pci_release_regions(icom_adapter->pci_dev);
1483 }
1484
1485 static void icom_kobj_release(struct kobject *kobj)
1486 {
1487         struct icom_adapter *icom_adapter;
1488
1489         icom_adapter = to_icom_adapter(kobj);
1490         icom_remove_adapter(icom_adapter);
1491 }
1492
1493 static struct kobj_type icom_kobj_type = {
1494         .release = icom_kobj_release,
1495 };
1496
1497 static int __devinit icom_probe(struct pci_dev *dev,
1498                                 const struct pci_device_id *ent)
1499 {
1500         int index;
1501         unsigned int command_reg;
1502         int retval;
1503         struct icom_adapter *icom_adapter;
1504         struct icom_port *icom_port;
1505
1506         retval = pci_enable_device(dev);
1507         if (retval) {
1508                 dev_err(&dev->dev, "Device enable FAILED\n");
1509                 return retval;
1510         }
1511
1512         if ( (retval = pci_request_regions(dev, "icom"))) {
1513                  dev_err(&dev->dev, "pci_request_region FAILED\n");
1514                  pci_disable_device(dev);
1515                  return retval;
1516          }
1517
1518         pci_set_master(dev);
1519
1520         if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1521                 dev_err(&dev->dev, "PCI Config read FAILED\n");
1522                 return retval;
1523         }
1524
1525         pci_write_config_dword(dev, PCI_COMMAND,
1526                 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1527                 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1528
1529         if (ent->driver_data == ADAPTER_V1) {
1530                 pci_write_config_dword(dev, 0x44, 0x8300830A);
1531          } else {
1532                 pci_write_config_dword(dev, 0x44, 0x42004200);
1533                 pci_write_config_dword(dev, 0x48, 0x42004200);
1534          }
1535
1536
1537         retval = icom_alloc_adapter(&icom_adapter);
1538         if (retval) {
1539                  dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1540                  retval = -EIO;
1541                  goto probe_exit0;
1542         }
1543
1544          icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1545          icom_adapter->irq_number = dev->irq;
1546          icom_adapter->pci_dev = dev;
1547          icom_adapter->version = ent->driver_data;
1548          icom_adapter->subsystem_id = ent->subdevice;
1549
1550
1551         retval = icom_init_ports(icom_adapter);
1552         if (retval) {
1553                 dev_err(&dev->dev, "Port configuration failed\n");
1554                 goto probe_exit1;
1555         }
1556
1557          icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1558                                                 pci_resource_len(dev, 0));
1559
1560         if (!icom_adapter->base_addr)
1561                 goto probe_exit1;
1562
1563          /* save off irq and request irq line */
1564          if ( (retval = request_irq(dev->irq, icom_interrupt,
1565                                    IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME,
1566                                    (void *) icom_adapter))) {
1567                   goto probe_exit2;
1568          }
1569
1570         retval = icom_load_ports(icom_adapter);
1571
1572         for (index = 0; index < icom_adapter->numb_ports; index++) {
1573                 icom_port = &icom_adapter->port_info[index];
1574
1575                 if (icom_port->status == ICOM_PORT_ACTIVE) {
1576                         icom_port->uart_port.irq = icom_port->adapter->irq_number;
1577                         icom_port->uart_port.type = PORT_ICOM;
1578                         icom_port->uart_port.iotype = UPIO_MEM;
1579                         icom_port->uart_port.membase =
1580                                                (char *) icom_adapter->base_addr_pci;
1581                         icom_port->uart_port.fifosize = 16;
1582                         icom_port->uart_port.ops = &icom_ops;
1583                         icom_port->uart_port.line =
1584                         icom_port->port + icom_adapter->index * 4;
1585                         if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1586                                 icom_port->status = ICOM_PORT_OFF;
1587                                 dev_err(&dev->dev, "Device add failed\n");
1588                          } else
1589                                 dev_info(&dev->dev, "Device added\n");
1590                 }
1591         }
1592
1593         kobject_init(&icom_adapter->kobj);
1594         icom_adapter->kobj.ktype = &icom_kobj_type;
1595         return 0;
1596
1597 probe_exit2:
1598         iounmap(icom_adapter->base_addr);
1599 probe_exit1:
1600         icom_free_adapter(icom_adapter);
1601
1602 probe_exit0:
1603         pci_release_regions(dev);
1604         pci_disable_device(dev);
1605
1606         return retval;
1607
1608
1609 }
1610
1611 static void __devexit icom_remove(struct pci_dev *dev)
1612 {
1613         struct icom_adapter *icom_adapter;
1614         struct list_head *tmp;
1615
1616         list_for_each(tmp, &icom_adapter_head) {
1617                 icom_adapter = list_entry(tmp, struct icom_adapter,
1618                                           icom_adapter_entry);
1619                 if (icom_adapter->pci_dev == dev) {
1620                         kobject_put(&icom_adapter->kobj);
1621                         return;
1622                 }
1623         }
1624
1625         dev_err(&dev->dev, "Unable to find device to remove\n");
1626 }
1627
1628 static struct pci_driver icom_pci_driver = {
1629         .name = ICOM_DRIVER_NAME,
1630         .id_table = icom_pci_table,
1631         .probe = icom_probe,
1632         .remove = __devexit_p(icom_remove),
1633 };
1634
1635 static int __init icom_init(void)
1636 {
1637         int ret;
1638
1639         spin_lock_init(&icom_lock);
1640
1641         ret = uart_register_driver(&icom_uart_driver);
1642         if (ret)
1643                 return ret;
1644
1645         ret = pci_register_driver(&icom_pci_driver);
1646
1647         if (ret < 0)
1648                 uart_unregister_driver(&icom_uart_driver);
1649
1650         return ret;
1651 }
1652
1653 static void __exit icom_exit(void)
1654 {
1655         pci_unregister_driver(&icom_pci_driver);
1656         uart_unregister_driver(&icom_uart_driver);
1657 }
1658
1659 module_init(icom_init);
1660 module_exit(icom_exit);
1661
1662 #ifdef ICOM_TRACE
1663 static inline void trace(struct icom_port *icom_port, char *trace_pt,
1664                   unsigned long trace_data)
1665 {
1666         dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1667                  icom_port->port, trace_pt, trace_data);
1668 }
1669 #endif
1670
1671 MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1672 MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1673 MODULE_SUPPORTED_DEVICE
1674     ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1675 MODULE_LICENSE("GPL");
1676