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