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