linux/drivers/tty/serial/icom.c
<<
>>
Prefs
   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
  54static 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
  93static 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
 101static 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
 108static 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
 116MODULE_DEVICE_TABLE(pci, icom_pci_table);
 117
 118static LIST_HEAD(icom_adapter_head);
 119
 120/* spinlock for adapter initialization and changing adapter operations */
 121static spinlock_t icom_lock;
 122
 123#ifdef ICOM_TRACE
 124static 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
 131static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
 132#endif
 133static void icom_kref_release(struct kref *kref);
 134
 135static 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
 163static 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
 274static 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
 301unlock:
 302        spin_unlock_irqrestore(&icom_lock, flags);
 303}
 304
 305static 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
 332unlock:
 333        spin_unlock_irqrestore(&icom_lock, flags);
 334}
 335
 336static 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
 500static 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
 567unlock:
 568        spin_unlock_irqrestore(&icom_lock, flags);
 569        return 0;
 570}
 571
 572static 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
 602unlock:
 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
 614static 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
 662static 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
 693static 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
 724static 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);
 814ignore_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
 833static 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
 849static 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 */
 924static 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
 940static 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
 966static 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
 982static 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
 991static 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
1004static 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
1030static 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
1038static 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
1054static 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
1070static 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
1085static 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
1254static const char *icom_type(struct uart_port *port)
1255{
1256        return "icom";
1257}
1258
1259static void icom_release_port(struct uart_port *port)
1260{
1261}
1262
1263static int icom_request_port(struct uart_port *port)
1264{
1265        return 0;
1266}
1267
1268static void icom_config_port(struct uart_port *port, int flags)
1269{
1270        port->type = PORT_ICOM;
1271}
1272
1273static 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
1293static 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
1303static 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
1354static 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}
1370static 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
1396static 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
1427static void icom_free_adapter(struct icom_adapter *icom_adapter)
1428{
1429        list_del(&icom_adapter->icom_adapter_entry);
1430        kfree(icom_adapter);
1431}
1432
1433static 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
1467static 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
1475static 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
1575probe_exit2:
1576        iounmap(icom_adapter->base_addr);
1577probe_exit1:
1578        icom_free_adapter(icom_adapter);
1579
1580probe_exit0:
1581        pci_release_regions(dev);
1582        pci_disable_device(dev);
1583
1584        return retval;
1585}
1586
1587static 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
1604static 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
1611static 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
1629static void __exit icom_exit(void)
1630{
1631        pci_unregister_driver(&icom_pci_driver);
1632        uart_unregister_driver(&icom_uart_driver);
1633}
1634
1635module_init(icom_init);
1636module_exit(icom_exit);
1637
1638MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1639MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1640MODULE_SUPPORTED_DEVICE
1641    ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1642MODULE_LICENSE("GPL");
1643MODULE_FIRMWARE("icom_call_setup.bin");
1644MODULE_FIRMWARE("icom_res_dce.bin");
1645MODULE_FIRMWARE("icom_asc.bin");
1646