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