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