Version:  2.0.40 2.2.26 2.4.37 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us