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