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