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