root/drivers/tty/serial/icom.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. trace
  2. trace
  3. free_port_memory
  4. get_port_memory
  5. stop_processor
  6. start_processor
  7. load_code
  8. startup
  9. shutdown
  10. icom_write
  11. check_modem_status
  12. xmit_interrupt
  13. recv_interrupt
  14. process_interrupt
  15. icom_interrupt
  16. icom_tx_empty
  17. icom_set_mctrl
  18. icom_get_mctrl
  19. icom_stop_tx
  20. icom_start_tx
  21. icom_send_xchar
  22. icom_stop_rx
  23. icom_break
  24. icom_open
  25. icom_close
  26. icom_set_termios
  27. icom_type
  28. icom_release_port
  29. icom_request_port
  30. icom_config_port
  31. icom_init_ports
  32. icom_port_active
  33. icom_load_ports
  34. icom_alloc_adapter
  35. icom_free_adapter
  36. icom_remove_adapter
  37. icom_kref_release
  38. icom_probe
  39. icom_remove
  40. icom_init
  41. icom_exit

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

/* [<][>][^][v][top][bottom][index][help] */