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