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 DEFINE_SPINLOCK(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                dma_free_coherent(&dev->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                dma_free_coherent(&dev->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                dma_free_coherent(&dev->dev, 4096, icom_port->statStg,
 152                                  icom_port->statStg_pci);
 153                icom_port->statStg = NULL;
 154        }
 155
 156        if (icom_port->xmitRestart) {
 157                dma_free_coherent(&dev->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            dma_alloc_coherent(&dev->dev, 4096, &icom_port->xmit_buf_pci,
 173                               GFP_KERNEL);
 174        if (!icom_port->xmit_buf) {
 175                dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
 176                return -ENOMEM;
 177        }
 178
 179        trace(icom_port, "GET_PORT_MEM",
 180              (unsigned long) icom_port->xmit_buf);
 181
 182        icom_port->recv_buf =
 183            dma_alloc_coherent(&dev->dev, 4096, &icom_port->recv_buf_pci,
 184                               GFP_KERNEL);
 185        if (!icom_port->recv_buf) {
 186                dev_err(&dev->dev, "Can not allocate Receive buffer\n");
 187                free_port_memory(icom_port);
 188                return -ENOMEM;
 189        }
 190        trace(icom_port, "GET_PORT_MEM",
 191              (unsigned long) icom_port->recv_buf);
 192
 193        icom_port->statStg =
 194            dma_alloc_coherent(&dev->dev, 4096, &icom_port->statStg_pci,
 195                               GFP_KERNEL);
 196        if (!icom_port->statStg) {
 197                dev_err(&dev->dev, "Can not allocate Status buffer\n");
 198                free_port_memory(icom_port);
 199                return -ENOMEM;
 200        }
 201        trace(icom_port, "GET_PORT_MEM",
 202              (unsigned long) icom_port->statStg);
 203
 204        icom_port->xmitRestart =
 205            dma_alloc_coherent(&dev->dev, 4096, &icom_port->xmitRestart_pci,
 206                               GFP_KERNEL);
 207        if (!icom_port->xmitRestart) {
 208                dev_err(&dev->dev,
 209                        "Can not allocate xmit Restart buffer\n");
 210                free_port_memory(icom_port);
 211                return -ENOMEM;
 212        }
 213
 214        /* FODs: Frame Out Descriptor Queue, this is a FIFO queue that
 215           indicates that frames are to be transmitted
 216        */
 217
 218        stgAddr = (unsigned long) icom_port->statStg;
 219        for (index = 0; index < NUM_XBUFFS; index++) {
 220                trace(icom_port, "FOD_ADDR", stgAddr);
 221                stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
 222                if (index < (NUM_XBUFFS - 1)) {
 223                        memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
 224                        icom_port->statStg->xmit[index].leLengthASD =
 225                            (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
 226                        trace(icom_port, "FOD_ADDR", stgAddr);
 227                        trace(icom_port, "FOD_XBUFF",
 228                              (unsigned long) icom_port->xmit_buf);
 229                        icom_port->statStg->xmit[index].leBuffer =
 230                            cpu_to_le32(icom_port->xmit_buf_pci);
 231                } else if (index == (NUM_XBUFFS - 1)) {
 232                        memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
 233                        icom_port->statStg->xmit[index].leLengthASD =
 234                            (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
 235                        trace(icom_port, "FOD_XBUFF",
 236                              (unsigned long) icom_port->xmit_buf);
 237                        icom_port->statStg->xmit[index].leBuffer =
 238                            cpu_to_le32(icom_port->xmit_buf_pci);
 239                } else {
 240                        memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
 241                }
 242        }
 243        /* FIDs */
 244        startStgAddr = stgAddr;
 245
 246        /* fill in every entry, even if no buffer */
 247        for (index = 0; index <  NUM_RBUFFS; index++) {
 248                trace(icom_port, "FID_ADDR", stgAddr);
 249                stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
 250                icom_port->statStg->rcv[index].leLength = 0;
 251                icom_port->statStg->rcv[index].WorkingLength =
 252                    (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
 253                if (index < (NUM_RBUFFS - 1) ) {
 254                        offset = stgAddr - (unsigned long) icom_port->statStg;
 255                        icom_port->statStg->rcv[index].leNext =
 256                              cpu_to_le32(icom_port-> statStg_pci + offset);
 257                        trace(icom_port, "FID_RBUFF",
 258                              (unsigned long) icom_port->recv_buf);
 259                        icom_port->statStg->rcv[index].leBuffer =
 260                            cpu_to_le32(icom_port->recv_buf_pci);
 261                } else if (index == (NUM_RBUFFS -1) ) {
 262                        offset = startStgAddr - (unsigned long) icom_port->statStg;
 263                        icom_port->statStg->rcv[index].leNext =
 264                            cpu_to_le32(icom_port-> statStg_pci + offset);
 265                        trace(icom_port, "FID_RBUFF",
 266                              (unsigned long) icom_port->recv_buf + 2048);
 267                        icom_port->statStg->rcv[index].leBuffer =
 268                            cpu_to_le32(icom_port->recv_buf_pci + 2048);
 269                } else {
 270                        icom_port->statStg->rcv[index].leNext = 0;
 271                        icom_port->statStg->rcv[index].leBuffer = 0;
 272                }
 273        }
 274
 275        return 0;
 276}
 277
 278static void stop_processor(struct icom_port *icom_port)
 279{
 280        unsigned long temp;
 281        unsigned long flags;
 282        int port;
 283
 284        spin_lock_irqsave(&icom_lock, flags);
 285
 286        port = icom_port->port;
 287        if (port >= ARRAY_SIZE(stop_proc)) {
 288                dev_err(&icom_port->adapter->pci_dev->dev,
 289                        "Invalid port assignment\n");
 290                goto unlock;
 291        }
 292
 293        if (port == 0 || port == 1)
 294                stop_proc[port].global_control_reg = &icom_port->global_reg->control;
 295        else
 296                stop_proc[port].global_control_reg = &icom_port->global_reg->control_2;
 297
 298        temp = readl(stop_proc[port].global_control_reg);
 299        temp = (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
 300        writel(temp, stop_proc[port].global_control_reg);
 301
 302        /* write flush */
 303        readl(stop_proc[port].global_control_reg);
 304
 305unlock:
 306        spin_unlock_irqrestore(&icom_lock, flags);
 307}
 308
 309static void start_processor(struct icom_port *icom_port)
 310{
 311        unsigned long temp;
 312        unsigned long flags;
 313        int port;
 314
 315        spin_lock_irqsave(&icom_lock, flags);
 316
 317        port = icom_port->port;
 318        if (port >= ARRAY_SIZE(start_proc)) {
 319                dev_err(&icom_port->adapter->pci_dev->dev,
 320                        "Invalid port assignment\n");
 321                goto unlock;
 322        }
 323
 324        if (port == 0 || port == 1)
 325                start_proc[port].global_control_reg = &icom_port->global_reg->control;
 326        else
 327                start_proc[port].global_control_reg = &icom_port->global_reg->control_2;
 328
 329        temp = readl(start_proc[port].global_control_reg);
 330        temp = (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
 331        writel(temp, start_proc[port].global_control_reg);
 332
 333        /* write flush */
 334        readl(start_proc[port].global_control_reg);
 335
 336unlock:
 337        spin_unlock_irqrestore(&icom_lock, flags);
 338}
 339
 340static void load_code(struct icom_port *icom_port)
 341{
 342        const struct firmware *fw;
 343        char __iomem *iram_ptr;
 344        int index;
 345        int status = 0;
 346        void __iomem *dram_ptr = icom_port->dram;
 347        dma_addr_t temp_pci;
 348        unsigned char *new_page = NULL;
 349        unsigned char cable_id = NO_CABLE;
 350        struct pci_dev *dev = icom_port->adapter->pci_dev;
 351
 352        /* Clear out any pending interrupts */
 353        writew(0x3FFF, icom_port->int_reg);
 354
 355        trace(icom_port, "CLEAR_INTERRUPTS", 0);
 356
 357        /* Stop processor */
 358        stop_processor(icom_port);
 359
 360        /* Zero out DRAM */
 361        memset_io(dram_ptr, 0, 512);
 362
 363        /* Load Call Setup into Adapter */
 364        if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
 365                dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
 366                status = -1;
 367                goto load_code_exit;
 368        }
 369
 370        if (fw->size > ICOM_DCE_IRAM_OFFSET) {
 371                dev_err(&dev->dev, "Invalid firmware image for icom_call_setup.bin found.\n");
 372                release_firmware(fw);
 373                status = -1;
 374                goto load_code_exit;
 375        }
 376
 377        iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
 378        for (index = 0; index < fw->size; index++)
 379                writeb(fw->data[index], &iram_ptr[index]);
 380
 381        release_firmware(fw);
 382
 383        /* Load Resident DCE portion of Adapter */
 384        if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
 385                dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
 386                status = -1;
 387                goto load_code_exit;
 388        }
 389
 390        if (fw->size > ICOM_IRAM_SIZE) {
 391                dev_err(&dev->dev, "Invalid firmware image for icom_res_dce.bin found.\n");
 392                release_firmware(fw);
 393                status = -1;
 394                goto load_code_exit;
 395        }
 396
 397        iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
 398        for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
 399                writeb(fw->data[index], &iram_ptr[index]);
 400
 401        release_firmware(fw);
 402
 403        /* Set Hardware level */
 404        if (icom_port->adapter->version == ADAPTER_V2)
 405                writeb(V2_HARDWARE, &(icom_port->dram->misc_flags));
 406
 407        /* Start the processor in Adapter */
 408        start_processor(icom_port);
 409
 410        writeb((HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL),
 411               &(icom_port->dram->HDLCConfigReg));
 412        writeb(0x04, &(icom_port->dram->FlagFillIdleTimer));    /* 0.5 seconds */
 413        writeb(0x00, &(icom_port->dram->CmdReg));
 414        writeb(0x10, &(icom_port->dram->async_config3));
 415        writeb((ICOM_ACFG_DRIVE1 | ICOM_ACFG_NO_PARITY | ICOM_ACFG_8BPC |
 416                ICOM_ACFG_1STOP_BIT), &(icom_port->dram->async_config2));
 417
 418        /*Set up data in icom DRAM to indicate where personality
 419         *code is located and its length.
 420         */
 421        new_page = dma_alloc_coherent(&dev->dev, 4096, &temp_pci, GFP_KERNEL);
 422
 423        if (!new_page) {
 424                dev_err(&dev->dev, "Can not allocate DMA buffer\n");
 425                status = -1;
 426                goto load_code_exit;
 427        }
 428
 429        if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
 430                dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
 431                status = -1;
 432                goto load_code_exit;
 433        }
 434
 435        if (fw->size > ICOM_DCE_IRAM_OFFSET) {
 436                dev_err(&dev->dev, "Invalid firmware image for icom_asc.bin found.\n");
 437                release_firmware(fw);
 438                status = -1;
 439                goto load_code_exit;
 440        }
 441
 442        for (index = 0; index < fw->size; index++)
 443                new_page[index] = fw->data[index];
 444
 445        writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
 446        writel(temp_pci, &icom_port->dram->mac_load_addr);
 447
 448        release_firmware(fw);
 449
 450        /*Setting the syncReg to 0x80 causes adapter to start downloading
 451           the personality code into adapter instruction RAM.
 452           Once code is loaded, it will begin executing and, based on
 453           information provided above, will start DMAing data from
 454           shared memory to adapter DRAM.
 455         */
 456        /* the wait loop below verifies this write operation has been done
 457           and processed
 458        */
 459        writeb(START_DOWNLOAD, &icom_port->dram->sync);
 460
 461        /* Wait max 1 Sec for data download and processor to start */
 462        for (index = 0; index < 10; index++) {
 463                msleep(100);
 464                if (readb(&icom_port->dram->misc_flags) & ICOM_HDW_ACTIVE)
 465                        break;
 466        }
 467
 468        if (index == 10)
 469                status = -1;
 470
 471        /*
 472         * check Cable ID
 473         */
 474        cable_id = readb(&icom_port->dram->cable_id);
 475
 476        if (cable_id & ICOM_CABLE_ID_VALID) {
 477                /* Get cable ID into the lower 4 bits (standard form) */
 478                cable_id = (cable_id & ICOM_CABLE_ID_MASK) >> 4;
 479                icom_port->cable_id = cable_id;
 480        } else {
 481                dev_err(&dev->dev,"Invalid or no cable attached\n");
 482                icom_port->cable_id = NO_CABLE;
 483        }
 484
 485      load_code_exit:
 486
 487        if (status != 0) {
 488                /* Clear out any pending interrupts */
 489                writew(0x3FFF, icom_port->int_reg);
 490
 491                /* Turn off port */
 492                writeb(ICOM_DISABLE, &(icom_port->dram->disable));
 493
 494                /* Stop processor */
 495                stop_processor(icom_port);
 496
 497                dev_err(&icom_port->adapter->pci_dev->dev,"Port not operational\n");
 498        }
 499
 500        if (new_page != NULL)
 501                dma_free_coherent(&dev->dev, 4096, new_page, temp_pci);
 502}
 503
 504static int startup(struct icom_port *icom_port)
 505{
 506        unsigned long temp;
 507        unsigned char cable_id, raw_cable_id;
 508        unsigned long flags;
 509        int port;
 510
 511        trace(icom_port, "STARTUP", 0);
 512
 513        if (!icom_port->dram) {
 514                /* should NEVER be NULL */
 515                dev_err(&icom_port->adapter->pci_dev->dev,
 516                        "Unusable Port, port configuration missing\n");
 517                return -ENODEV;
 518        }
 519
 520        /*
 521         * check Cable ID
 522         */
 523        raw_cable_id = readb(&icom_port->dram->cable_id);
 524        trace(icom_port, "CABLE_ID", raw_cable_id);
 525
 526        /* Get cable ID into the lower 4 bits (standard form) */
 527        cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
 528
 529        /* Check for valid Cable ID */
 530        if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
 531            (cable_id != icom_port->cable_id)) {
 532
 533                /* reload adapter code, pick up any potential changes in cable id */
 534                load_code(icom_port);
 535
 536                /* still no sign of cable, error out */
 537                raw_cable_id = readb(&icom_port->dram->cable_id);
 538                cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
 539                if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
 540                    (icom_port->cable_id == NO_CABLE))
 541                        return -EIO;
 542        }
 543
 544        /*
 545         * Finally, clear and  enable interrupts
 546         */
 547        spin_lock_irqsave(&icom_lock, flags);
 548        port = icom_port->port;
 549        if (port >= ARRAY_SIZE(int_mask_tbl)) {
 550                dev_err(&icom_port->adapter->pci_dev->dev,
 551                        "Invalid port assignment\n");
 552                goto unlock;
 553        }
 554
 555        if (port == 0 || port == 1)
 556                int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
 557        else
 558                int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
 559
 560        if (port == 0 || port == 2)
 561                writew(0x00FF, icom_port->int_reg);
 562        else
 563                writew(0x3F00, icom_port->int_reg);
 564
 565        temp = readl(int_mask_tbl[port].global_int_mask);
 566        writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
 567
 568        /* write flush */
 569        readl(int_mask_tbl[port].global_int_mask);
 570
 571unlock:
 572        spin_unlock_irqrestore(&icom_lock, flags);
 573        return 0;
 574}
 575
 576static void shutdown(struct icom_port *icom_port)
 577{
 578        unsigned long temp;
 579        unsigned char cmdReg;
 580        unsigned long flags;
 581        int port;
 582
 583        spin_lock_irqsave(&icom_lock, flags);
 584        trace(icom_port, "SHUTDOWN", 0);
 585
 586        /*
 587         * disable all interrupts
 588         */
 589        port = icom_port->port;
 590        if (port >= ARRAY_SIZE(int_mask_tbl)) {
 591                dev_err(&icom_port->adapter->pci_dev->dev,
 592                        "Invalid port assignment\n");
 593                goto unlock;
 594        }
 595        if (port == 0 || port == 1)
 596                int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
 597        else
 598                int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
 599
 600        temp = readl(int_mask_tbl[port].global_int_mask);
 601        writel(temp | int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
 602
 603        /* write flush */
 604        readl(int_mask_tbl[port].global_int_mask);
 605
 606unlock:
 607        spin_unlock_irqrestore(&icom_lock, flags);
 608
 609        /*
 610         * disable break condition
 611         */
 612        cmdReg = readb(&icom_port->dram->CmdReg);
 613        if (cmdReg & CMD_SND_BREAK) {
 614                writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
 615        }
 616}
 617
 618static int icom_write(struct uart_port *port)
 619{
 620        unsigned long data_count;
 621        unsigned char cmdReg;
 622        unsigned long offset;
 623        int temp_tail = port->state->xmit.tail;
 624
 625        trace(ICOM_PORT, "WRITE", 0);
 626
 627        if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
 628            SA_FLAGS_READY_TO_XMIT) {
 629                trace(ICOM_PORT, "WRITE_FULL", 0);
 630                return 0;
 631        }
 632
 633        data_count = 0;
 634        while ((port->state->xmit.head != temp_tail) &&
 635               (data_count <= XMIT_BUFF_SZ)) {
 636
 637                ICOM_PORT->xmit_buf[data_count++] =
 638                    port->state->xmit.buf[temp_tail];
 639
 640                temp_tail++;
 641                temp_tail &= (UART_XMIT_SIZE - 1);
 642        }
 643
 644        if (data_count) {
 645                ICOM_PORT->statStg->xmit[0].flags =
 646                    cpu_to_le16(SA_FLAGS_READY_TO_XMIT);
 647                ICOM_PORT->statStg->xmit[0].leLength =
 648                    cpu_to_le16(data_count);
 649                offset =
 650                    (unsigned long) &ICOM_PORT->statStg->xmit[0] -
 651                    (unsigned long) ICOM_PORT->statStg;
 652                *ICOM_PORT->xmitRestart =
 653                    cpu_to_le32(ICOM_PORT->statStg_pci + offset);
 654                cmdReg = readb(&ICOM_PORT->dram->CmdReg);
 655                writeb(cmdReg | CMD_XMIT_RCV_ENABLE,
 656                       &ICOM_PORT->dram->CmdReg);
 657                writeb(START_XMIT, &ICOM_PORT->dram->StartXmitCmd);
 658                trace(ICOM_PORT, "WRITE_START", data_count);
 659                /* write flush */
 660                readb(&ICOM_PORT->dram->StartXmitCmd);
 661        }
 662
 663        return data_count;
 664}
 665
 666static inline void check_modem_status(struct icom_port *icom_port)
 667{
 668        static char old_status = 0;
 669        char delta_status;
 670        unsigned char status;
 671
 672        spin_lock(&icom_port->uart_port.lock);
 673
 674        /*modem input register */
 675        status = readb(&icom_port->dram->isr);
 676        trace(icom_port, "CHECK_MODEM", status);
 677        delta_status = status ^ old_status;
 678        if (delta_status) {
 679                if (delta_status & ICOM_RI)
 680                        icom_port->uart_port.icount.rng++;
 681                if (delta_status & ICOM_DSR)
 682                        icom_port->uart_port.icount.dsr++;
 683                if (delta_status & ICOM_DCD)
 684                        uart_handle_dcd_change(&icom_port->uart_port,
 685                                               delta_status & ICOM_DCD);
 686                if (delta_status & ICOM_CTS)
 687                        uart_handle_cts_change(&icom_port->uart_port,
 688                                               delta_status & ICOM_CTS);
 689
 690                wake_up_interruptible(&icom_port->uart_port.state->
 691                                      port.delta_msr_wait);
 692                old_status = status;
 693        }
 694        spin_unlock(&icom_port->uart_port.lock);
 695}
 696
 697static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
 698{
 699        unsigned short int count;
 700        int i;
 701
 702        if (port_int_reg & (INT_XMIT_COMPLETED)) {
 703                trace(icom_port, "XMIT_COMPLETE", 0);
 704
 705                /* clear buffer in use bit */
 706                icom_port->statStg->xmit[0].flags &=
 707                        cpu_to_le16(~SA_FLAGS_READY_TO_XMIT);
 708
 709                count = (unsigned short int)
 710                        cpu_to_le16(icom_port->statStg->xmit[0].leLength);
 711                icom_port->uart_port.icount.tx += count;
 712
 713                for (i=0; i<count &&
 714                        !uart_circ_empty(&icom_port->uart_port.state->xmit); i++) {
 715
 716                        icom_port->uart_port.state->xmit.tail++;
 717                        icom_port->uart_port.state->xmit.tail &=
 718                                (UART_XMIT_SIZE - 1);
 719                }
 720
 721                if (!icom_write(&icom_port->uart_port))
 722                        /* activate write queue */
 723                        uart_write_wakeup(&icom_port->uart_port);
 724        } else
 725                trace(icom_port, "XMIT_DISABLED", 0);
 726}
 727
 728static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
 729{
 730        short int count, rcv_buff;
 731        struct tty_port *port = &icom_port->uart_port.state->port;
 732        unsigned short int status;
 733        struct uart_icount *icount;
 734        unsigned long offset;
 735        unsigned char flag;
 736
 737        trace(icom_port, "RCV_COMPLETE", 0);
 738        rcv_buff = icom_port->next_rcv;
 739
 740        status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
 741        while (status & SA_FL_RCV_DONE) {
 742                int first = -1;
 743
 744                trace(icom_port, "FID_STATUS", status);
 745                count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
 746
 747                trace(icom_port, "RCV_COUNT", count);
 748
 749                trace(icom_port, "REAL_COUNT", count);
 750
 751                offset =
 752                        cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
 753                        icom_port->recv_buf_pci;
 754
 755                /* Block copy all but the last byte as this may have status */
 756                if (count > 0) {
 757                        first = icom_port->recv_buf[offset];
 758                        tty_insert_flip_string(port, icom_port->recv_buf + offset, count - 1);
 759                }
 760
 761                icount = &icom_port->uart_port.icount;
 762                icount->rx += count;
 763
 764                /* Break detect logic */
 765                if ((status & SA_FLAGS_FRAME_ERROR)
 766                    && first == 0) {
 767                        status &= ~SA_FLAGS_FRAME_ERROR;
 768                        status |= SA_FLAGS_BREAK_DET;
 769                        trace(icom_port, "BREAK_DET", 0);
 770                }
 771
 772                flag = TTY_NORMAL;
 773
 774                if (status &
 775                    (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
 776                     SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
 777
 778                        if (status & SA_FLAGS_BREAK_DET)
 779                                icount->brk++;
 780                        if (status & SA_FLAGS_PARITY_ERROR)
 781                                icount->parity++;
 782                        if (status & SA_FLAGS_FRAME_ERROR)
 783                                icount->frame++;
 784                        if (status & SA_FLAGS_OVERRUN)
 785                                icount->overrun++;
 786
 787                        /*
 788                         * Now check to see if character should be
 789                         * ignored, and mask off conditions which
 790                         * should be ignored.
 791                         */
 792                        if (status & icom_port->ignore_status_mask) {
 793                                trace(icom_port, "IGNORE_CHAR", 0);
 794                                goto ignore_char;
 795                        }
 796
 797                        status &= icom_port->read_status_mask;
 798
 799                        if (status & SA_FLAGS_BREAK_DET) {
 800                                flag = TTY_BREAK;
 801                        } else if (status & SA_FLAGS_PARITY_ERROR) {
 802                                trace(icom_port, "PARITY_ERROR", 0);
 803                                flag = TTY_PARITY;
 804                        } else if (status & SA_FLAGS_FRAME_ERROR)
 805                                flag = TTY_FRAME;
 806
 807                }
 808
 809                tty_insert_flip_char(port, *(icom_port->recv_buf + offset + count - 1), flag);
 810
 811                if (status & SA_FLAGS_OVERRUN)
 812                        /*
 813                         * Overrun is special, since it's
 814                         * reported immediately, and doesn't
 815                         * affect the current character
 816                         */
 817                        tty_insert_flip_char(port, 0, TTY_OVERRUN);
 818ignore_char:
 819                icom_port->statStg->rcv[rcv_buff].flags = 0;
 820                icom_port->statStg->rcv[rcv_buff].leLength = 0;
 821                icom_port->statStg->rcv[rcv_buff].WorkingLength =
 822                        (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
 823
 824                rcv_buff++;
 825                if (rcv_buff == NUM_RBUFFS)
 826                        rcv_buff = 0;
 827
 828                status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
 829        }
 830        icom_port->next_rcv = rcv_buff;
 831
 832        tty_flip_buffer_push(port);
 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        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_LICENSE("GPL");
1641MODULE_FIRMWARE("icom_call_setup.bin");
1642MODULE_FIRMWARE("icom_res_dce.bin");
1643MODULE_FIRMWARE("icom_asc.bin");
1644