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