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