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