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