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