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