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