linux/drivers/tty/serial/icom.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3  * icom.c
   4  *
   5  * Copyright (C) 2001 IBM Corporation. All rights reserved.
   6  *
   7  * Serial device driver.
   8  *
   9  * Based on code from serial.c
  10  */
  11#include <linux/module.h>
  12#include <linux/kernel.h>
  13#include <linux/errno.h>
  14#include <linux/signal.h>
  15#include <linux/timer.h>
  16#include <linux/interrupt.h>
  17#include <linux/tty.h>
  18#include <linux/termios.h>
  19#include <linux/fs.h>
  20#include <linux/tty_flip.h>
  21#include <linux/serial.h>
  22#include <linux/serial_reg.h>
  23#include <linux/major.h>
  24#include <linux/string.h>
  25#include <linux/fcntl.h>
  26#include <linux/ptrace.h>
  27#include <linux/ioport.h>
  28#include <linux/mm.h>
  29#include <linux/slab.h>
  30#include <linux/init.h>
  31#include <linux/delay.h>
  32#include <linux/pci.h>
  33#include <linux/vmalloc.h>
  34#include <linux/smp.h>
  35#include <linux/spinlock.h>
  36#include <linux/kref.h>
  37#include <linux/firmware.h>
  38#include <linux/bitops.h>
  39
  40#include <asm/io.h>
  41#include <asm/irq.h>
  42#include <linux/uaccess.h>
  43
  44#include "icom.h"
  45
  46/*#define ICOM_TRACE             enable port trace capabilities */
  47
  48#define ICOM_DRIVER_NAME "icom"
  49#define ICOM_VERSION_STR "1.3.1"
  50#define NR_PORTS               128
  51#define ICOM_PORT ((struct icom_port *)port)
  52#define to_icom_adapter(d) container_of(d, struct icom_adapter, kref)
  53
  54static const struct pci_device_id icom_pci_table[] = {
  55        {
  56                .vendor = PCI_VENDOR_ID_IBM,
  57                .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1,
  58                .subvendor = PCI_ANY_ID,
  59                .subdevice = PCI_ANY_ID,
  60                .driver_data = ADAPTER_V1,
  61        },
  62        {
  63                .vendor = PCI_VENDOR_ID_IBM,
  64                .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
  65                .subvendor = PCI_VENDOR_ID_IBM,
  66                .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX,
  67                .driver_data = ADAPTER_V2,
  68        },
  69        {
  70                .vendor = PCI_VENDOR_ID_IBM,
  71                .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
  72                .subvendor = PCI_VENDOR_ID_IBM,
  73                .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM,
  74                .driver_data = ADAPTER_V2,
  75        },
  76        {
  77                .vendor = PCI_VENDOR_ID_IBM,
  78                .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
  79                .subvendor = PCI_VENDOR_ID_IBM,
  80                .subdevice = PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL,
  81                .driver_data = ADAPTER_V2,
  82        },
  83        {
  84                .vendor = PCI_VENDOR_ID_IBM,
  85                .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
  86                .subvendor = PCI_VENDOR_ID_IBM,
  87                .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM_PCIE,
  88                .driver_data = ADAPTER_V2,
  89        },
  90        {}
  91};
  92
  93static struct lookup_proc_table start_proc[4] = {
  94        {NULL, ICOM_CONTROL_START_A},
  95        {NULL, ICOM_CONTROL_START_B},
  96        {NULL, ICOM_CONTROL_START_C},
  97        {NULL, ICOM_CONTROL_START_D}
  98};
  99
 100
 101static struct lookup_proc_table stop_proc[4] = {
 102        {NULL, ICOM_CONTROL_STOP_A},
 103        {NULL, ICOM_CONTROL_STOP_B},
 104        {NULL, ICOM_CONTROL_STOP_C},
 105        {NULL, ICOM_CONTROL_STOP_D}
 106};
 107
 108static struct lookup_int_table int_mask_tbl[4] = {
 109        {NULL, ICOM_INT_MASK_PRC_A},
 110        {NULL, ICOM_INT_MASK_PRC_B},
 111        {NULL, ICOM_INT_MASK_PRC_C},
 112        {NULL, ICOM_INT_MASK_PRC_D},
 113};
 114
 115
 116MODULE_DEVICE_TABLE(pci, icom_pci_table);
 117
 118static LIST_HEAD(icom_adapter_head);
 119
 120/* spinlock for adapter initialization and changing adapter operations */
 121static spinlock_t icom_lock;
 122
 123#ifdef ICOM_TRACE
 124static inline void trace(struct icom_port *icom_port, char *trace_pt,
 125                        unsigned long trace_data)
 126{
 127        dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
 128        icom_port->port, trace_pt, trace_data);
 129}
 130#else
 131static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
 132#endif
 133static void icom_kref_release(struct kref *kref);
 134
 135static void free_port_memory(struct icom_port *icom_port)
 136{
 137        struct pci_dev *dev = icom_port->adapter->pci_dev;
 138
 139        trace(icom_port, "RET_PORT_MEM", 0);
 140        if (icom_port->recv_buf) {
 141                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        spin_unlock(&icom_port->uart_port.lock);
 833        tty_flip_buffer_push(port);
 834        spin_lock(&icom_port->uart_port.lock);
 835}
 836
 837static void process_interrupt(u16 port_int_reg,
 838                              struct icom_port *icom_port)
 839{
 840
 841        spin_lock(&icom_port->uart_port.lock);
 842        trace(icom_port, "INTERRUPT", port_int_reg);
 843
 844        if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
 845                xmit_interrupt(port_int_reg, icom_port);
 846
 847        if (port_int_reg & INT_RCV_COMPLETED)
 848                recv_interrupt(port_int_reg, icom_port);
 849
 850        spin_unlock(&icom_port->uart_port.lock);
 851}
 852
 853static irqreturn_t icom_interrupt(int irq, void *dev_id)
 854{
 855        void __iomem * int_reg;
 856        u32 adapter_interrupts;
 857        u16 port_int_reg;
 858        struct icom_adapter *icom_adapter;
 859        struct icom_port *icom_port;
 860
 861        /* find icom_port for this interrupt */
 862        icom_adapter = (struct icom_adapter *) dev_id;
 863
 864        if (icom_adapter->version == ADAPTER_V2) {
 865                int_reg = icom_adapter->base_addr + 0x8024;
 866
 867                adapter_interrupts = readl(int_reg);
 868
 869                if (adapter_interrupts & 0x00003FFF) {
 870                        /* port 2 interrupt,  NOTE:  for all ADAPTER_V2, port 2 will be active */
 871                        icom_port = &icom_adapter->port_info[2];
 872                        port_int_reg = (u16) adapter_interrupts;
 873                        process_interrupt(port_int_reg, icom_port);
 874                        check_modem_status(icom_port);
 875                }
 876                if (adapter_interrupts & 0x3FFF0000) {
 877                        /* port 3 interrupt */
 878                        icom_port = &icom_adapter->port_info[3];
 879                        if (icom_port->status == ICOM_PORT_ACTIVE) {
 880                                port_int_reg =
 881                                    (u16) (adapter_interrupts >> 16);
 882                                process_interrupt(port_int_reg, icom_port);
 883                                check_modem_status(icom_port);
 884                        }
 885                }
 886
 887                /* Clear out any pending interrupts */
 888                writel(adapter_interrupts, int_reg);
 889
 890                int_reg = icom_adapter->base_addr + 0x8004;
 891        } else {
 892                int_reg = icom_adapter->base_addr + 0x4004;
 893        }
 894
 895        adapter_interrupts = readl(int_reg);
 896
 897        if (adapter_interrupts & 0x00003FFF) {
 898                /* port 0 interrupt, NOTE:  for all adapters, port 0 will be active */
 899                icom_port = &icom_adapter->port_info[0];
 900                port_int_reg = (u16) adapter_interrupts;
 901                process_interrupt(port_int_reg, icom_port);
 902                check_modem_status(icom_port);
 903        }
 904        if (adapter_interrupts & 0x3FFF0000) {
 905                /* port 1 interrupt */
 906                icom_port = &icom_adapter->port_info[1];
 907                if (icom_port->status == ICOM_PORT_ACTIVE) {
 908                        port_int_reg = (u16) (adapter_interrupts >> 16);
 909                        process_interrupt(port_int_reg, icom_port);
 910                        check_modem_status(icom_port);
 911                }
 912        }
 913
 914        /* Clear out any pending interrupts */
 915        writel(adapter_interrupts, int_reg);
 916
 917        /* flush the write */
 918        adapter_interrupts = readl(int_reg);
 919
 920        return IRQ_HANDLED;
 921}
 922
 923/*
 924 * ------------------------------------------------------------------
 925 * Begin serial-core API
 926 * ------------------------------------------------------------------
 927 */
 928static unsigned int icom_tx_empty(struct uart_port *port)
 929{
 930        int ret;
 931        unsigned long flags;
 932
 933        spin_lock_irqsave(&port->lock, flags);
 934        if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
 935            SA_FLAGS_READY_TO_XMIT)
 936                ret = TIOCSER_TEMT;
 937        else
 938                ret = 0;
 939
 940        spin_unlock_irqrestore(&port->lock, flags);
 941        return ret;
 942}
 943
 944static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
 945{
 946        unsigned char local_osr;
 947
 948        trace(ICOM_PORT, "SET_MODEM", 0);
 949        local_osr = readb(&ICOM_PORT->dram->osr);
 950
 951        if (mctrl & TIOCM_RTS) {
 952                trace(ICOM_PORT, "RAISE_RTS", 0);
 953                local_osr |= ICOM_RTS;
 954        } else {
 955                trace(ICOM_PORT, "LOWER_RTS", 0);
 956                local_osr &= ~ICOM_RTS;
 957        }
 958
 959        if (mctrl & TIOCM_DTR) {
 960                trace(ICOM_PORT, "RAISE_DTR", 0);
 961                local_osr |= ICOM_DTR;
 962        } else {
 963                trace(ICOM_PORT, "LOWER_DTR", 0);
 964                local_osr &= ~ICOM_DTR;
 965        }
 966
 967        writeb(local_osr, &ICOM_PORT->dram->osr);
 968}
 969
 970static unsigned int icom_get_mctrl(struct uart_port *port)
 971{
 972        unsigned char status;
 973        unsigned int result;
 974
 975        trace(ICOM_PORT, "GET_MODEM", 0);
 976
 977        status = readb(&ICOM_PORT->dram->isr);
 978
 979        result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
 980            | ((status & ICOM_RI) ? TIOCM_RNG : 0)
 981            | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
 982            | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
 983        return result;
 984}
 985
 986static void icom_stop_tx(struct uart_port *port)
 987{
 988        unsigned char cmdReg;
 989
 990        trace(ICOM_PORT, "STOP", 0);
 991        cmdReg = readb(&ICOM_PORT->dram->CmdReg);
 992        writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
 993}
 994
 995static void icom_start_tx(struct uart_port *port)
 996{
 997        unsigned char cmdReg;
 998
 999        trace(ICOM_PORT, "START", 0);
1000        cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1001        if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
1002                writeb(cmdReg & ~CMD_HOLD_XMIT,
1003                       &ICOM_PORT->dram->CmdReg);
1004
1005        icom_write(port);
1006}
1007
1008static void icom_send_xchar(struct uart_port *port, char ch)
1009{
1010        unsigned char xdata;
1011        int index;
1012        unsigned long flags;
1013
1014        trace(ICOM_PORT, "SEND_XCHAR", ch);
1015
1016        /* wait .1 sec to send char */
1017        for (index = 0; index < 10; index++) {
1018                spin_lock_irqsave(&port->lock, flags);
1019                xdata = readb(&ICOM_PORT->dram->xchar);
1020                if (xdata == 0x00) {
1021                        trace(ICOM_PORT, "QUICK_WRITE", 0);
1022                        writeb(ch, &ICOM_PORT->dram->xchar);
1023
1024                        /* flush write operation */
1025                        xdata = readb(&ICOM_PORT->dram->xchar);
1026                        spin_unlock_irqrestore(&port->lock, flags);
1027                        break;
1028                }
1029                spin_unlock_irqrestore(&port->lock, flags);
1030                msleep(10);
1031        }
1032}
1033
1034static void icom_stop_rx(struct uart_port *port)
1035{
1036        unsigned char cmdReg;
1037
1038        cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1039        writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1040}
1041
1042static void icom_break(struct uart_port *port, int break_state)
1043{
1044        unsigned char cmdReg;
1045        unsigned long flags;
1046
1047        spin_lock_irqsave(&port->lock, flags);
1048        trace(ICOM_PORT, "BREAK", 0);
1049        cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1050        if (break_state == -1) {
1051                writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1052        } else {
1053                writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1054        }
1055        spin_unlock_irqrestore(&port->lock, flags);
1056}
1057
1058static int icom_open(struct uart_port *port)
1059{
1060        int retval;
1061
1062        kref_get(&ICOM_PORT->adapter->kref);
1063        retval = startup(ICOM_PORT);
1064
1065        if (retval) {
1066                kref_put(&ICOM_PORT->adapter->kref, icom_kref_release);
1067                trace(ICOM_PORT, "STARTUP_ERROR", 0);
1068                return retval;
1069        }
1070
1071        return 0;
1072}
1073
1074static void icom_close(struct uart_port *port)
1075{
1076        unsigned char cmdReg;
1077
1078        trace(ICOM_PORT, "CLOSE", 0);
1079
1080        /* stop receiver */
1081        cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1082        writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1083
1084        shutdown(ICOM_PORT);
1085
1086        kref_put(&ICOM_PORT->adapter->kref, icom_kref_release);
1087}
1088
1089static void icom_set_termios(struct uart_port *port,
1090                             struct ktermios *termios,
1091                             struct ktermios *old_termios)
1092{
1093        int baud;
1094        unsigned cflag, iflag;
1095        char new_config2;
1096        char new_config3 = 0;
1097        char tmp_byte;
1098        int index;
1099        int rcv_buff, xmit_buff;
1100        unsigned long offset;
1101        unsigned long flags;
1102
1103        spin_lock_irqsave(&port->lock, flags);
1104        trace(ICOM_PORT, "CHANGE_SPEED", 0);
1105
1106        cflag = termios->c_cflag;
1107        iflag = termios->c_iflag;
1108
1109        new_config2 = ICOM_ACFG_DRIVE1;
1110
1111        /* byte size and parity */
1112        switch (cflag & CSIZE) {
1113        case CS5:               /* 5 bits/char */
1114                new_config2 |= ICOM_ACFG_5BPC;
1115                break;
1116        case CS6:               /* 6 bits/char */
1117                new_config2 |= ICOM_ACFG_6BPC;
1118                break;
1119        case CS7:               /* 7 bits/char */
1120                new_config2 |= ICOM_ACFG_7BPC;
1121                break;
1122        case CS8:               /* 8 bits/char */
1123                new_config2 |= ICOM_ACFG_8BPC;
1124                break;
1125        default:
1126                break;
1127        }
1128        if (cflag & CSTOPB) {
1129                /* 2 stop bits */
1130                new_config2 |= ICOM_ACFG_2STOP_BIT;
1131        }
1132        if (cflag & PARENB) {
1133                /* parity bit enabled */
1134                new_config2 |= ICOM_ACFG_PARITY_ENAB;
1135                trace(ICOM_PORT, "PARENB", 0);
1136        }
1137        if (cflag & PARODD) {
1138                /* odd parity */
1139                new_config2 |= ICOM_ACFG_PARITY_ODD;
1140                trace(ICOM_PORT, "PARODD", 0);
1141        }
1142
1143        /* Determine divisor based on baud rate */
1144        baud = uart_get_baud_rate(port, termios, old_termios,
1145                                  icom_acfg_baud[0],
1146                                  icom_acfg_baud[BAUD_TABLE_LIMIT]);
1147        if (!baud)
1148                baud = 9600;    /* B0 transition handled in rs_set_termios */
1149
1150        for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1151                if (icom_acfg_baud[index] == baud) {
1152                        new_config3 = index;
1153                        break;
1154                }
1155        }
1156
1157        uart_update_timeout(port, cflag, baud);
1158
1159        /* CTS flow control flag and modem status interrupts */
1160        tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1161        if (cflag & CRTSCTS)
1162                tmp_byte |= HDLC_HDW_FLOW;
1163        else
1164                tmp_byte &= ~HDLC_HDW_FLOW;
1165        writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1166
1167        /*
1168         * Set up parity check flag
1169         */
1170        ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1171        if (iflag & INPCK)
1172                ICOM_PORT->read_status_mask |=
1173                    SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1174
1175        if ((iflag & BRKINT) || (iflag & PARMRK))
1176                ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1177
1178        /*
1179         * Characters to ignore
1180         */
1181        ICOM_PORT->ignore_status_mask = 0;
1182        if (iflag & IGNPAR)
1183                ICOM_PORT->ignore_status_mask |=
1184                    SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1185        if (iflag & IGNBRK) {
1186                ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1187                /*
1188                 * If we're ignore parity and break indicators, ignore
1189                 * overruns too.  (For real raw support).
1190                 */
1191                if (iflag & IGNPAR)
1192                        ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1193        }
1194
1195        /*
1196         * !!! ignore all characters if CREAD is not set
1197         */
1198        if ((cflag & CREAD) == 0)
1199                ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1200
1201        /* Turn off Receiver to prepare for reset */
1202        writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1203
1204        for (index = 0; index < 10; index++) {
1205                if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1206                        break;
1207                }
1208        }
1209
1210        /* clear all current buffers of data */
1211        for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1212                ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1213                ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1214                ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1215                    (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1216        }
1217
1218        for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1219                ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1220        }
1221
1222        /* activate changes and start xmit and receiver here */
1223        /* Enable the receiver */
1224        writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1225        writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1226        tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1227        tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1228        writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1229        writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer));    /* 0.5 seconds */
1230        writeb(0xFF, &(ICOM_PORT->dram->ier));  /* enable modem signal interrupts */
1231
1232        /* reset processor */
1233        writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1234
1235        for (index = 0; index < 10; index++) {
1236                if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1237                        break;
1238                }
1239        }
1240
1241        /* Enable Transmitter and Receiver */
1242        offset =
1243            (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1244            (unsigned long) ICOM_PORT->statStg;
1245        writel(ICOM_PORT->statStg_pci + offset,
1246               &ICOM_PORT->dram->RcvStatusAddr);
1247        ICOM_PORT->next_rcv = 0;
1248        ICOM_PORT->put_length = 0;
1249        *ICOM_PORT->xmitRestart = 0;
1250        writel(ICOM_PORT->xmitRestart_pci,
1251               &ICOM_PORT->dram->XmitStatusAddr);
1252        trace(ICOM_PORT, "XR_ENAB", 0);
1253        writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1254
1255        spin_unlock_irqrestore(&port->lock, flags);
1256}
1257
1258static const char *icom_type(struct uart_port *port)
1259{
1260        return "icom";
1261}
1262
1263static void icom_release_port(struct uart_port *port)
1264{
1265}
1266
1267static int icom_request_port(struct uart_port *port)
1268{
1269        return 0;
1270}
1271
1272static void icom_config_port(struct uart_port *port, int flags)
1273{
1274        port->type = PORT_ICOM;
1275}
1276
1277static const struct uart_ops icom_ops = {
1278        .tx_empty = icom_tx_empty,
1279        .set_mctrl = icom_set_mctrl,
1280        .get_mctrl = icom_get_mctrl,
1281        .stop_tx = icom_stop_tx,
1282        .start_tx = icom_start_tx,
1283        .send_xchar = icom_send_xchar,
1284        .stop_rx = icom_stop_rx,
1285        .break_ctl = icom_break,
1286        .startup = icom_open,
1287        .shutdown = icom_close,
1288        .set_termios = icom_set_termios,
1289        .type = icom_type,
1290        .release_port = icom_release_port,
1291        .request_port = icom_request_port,
1292        .config_port = icom_config_port,
1293};
1294
1295#define ICOM_CONSOLE NULL
1296
1297static struct uart_driver icom_uart_driver = {
1298        .owner = THIS_MODULE,
1299        .driver_name = ICOM_DRIVER_NAME,
1300        .dev_name = "ttyA",
1301        .major = ICOM_MAJOR,
1302        .minor = ICOM_MINOR_START,
1303        .nr = NR_PORTS,
1304        .cons = ICOM_CONSOLE,
1305};
1306
1307static int icom_init_ports(struct icom_adapter *icom_adapter)
1308{
1309        u32 subsystem_id = icom_adapter->subsystem_id;
1310        int i;
1311        struct icom_port *icom_port;
1312
1313        if (icom_adapter->version == ADAPTER_V1) {
1314                icom_adapter->numb_ports = 2;
1315
1316                for (i = 0; i < 2; i++) {
1317                        icom_port = &icom_adapter->port_info[i];
1318                        icom_port->port = i;
1319                        icom_port->status = ICOM_PORT_ACTIVE;
1320                        icom_port->imbed_modem = ICOM_UNKNOWN;
1321                }
1322        } else {
1323                if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1324                        icom_adapter->numb_ports = 4;
1325
1326                        for (i = 0; i < 4; i++) {
1327                                icom_port = &icom_adapter->port_info[i];
1328
1329                                icom_port->port = i;
1330                                icom_port->status = ICOM_PORT_ACTIVE;
1331                                icom_port->imbed_modem = ICOM_IMBED_MODEM;
1332                        }
1333                } else {
1334                        icom_adapter->numb_ports = 4;
1335
1336                        icom_adapter->port_info[0].port = 0;
1337                        icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1338
1339                        if (subsystem_id ==
1340                            PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1341                                icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1342                        } else {
1343                                icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1344                        }
1345
1346                        icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1347
1348                        icom_adapter->port_info[2].port = 2;
1349                        icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1350                        icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1351                        icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1352                }
1353        }
1354
1355        return 0;
1356}
1357
1358static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1359{
1360        if (icom_adapter->version == ADAPTER_V1) {
1361                icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1362                icom_port->int_reg = icom_adapter->base_addr +
1363                    0x4004 + 2 - 2 * port_num;
1364        } else {
1365                icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1366                if (icom_port->port < 2)
1367                        icom_port->int_reg = icom_adapter->base_addr +
1368                            0x8004 + 2 - 2 * icom_port->port;
1369                else
1370                        icom_port->int_reg = icom_adapter->base_addr +
1371                            0x8024 + 2 - 2 * (icom_port->port - 2);
1372        }
1373}
1374static int icom_load_ports(struct icom_adapter *icom_adapter)
1375{
1376        struct icom_port *icom_port;
1377        int port_num;
1378
1379        for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1380
1381                icom_port = &icom_adapter->port_info[port_num];
1382
1383                if (icom_port->status == ICOM_PORT_ACTIVE) {
1384                        icom_port_active(icom_port, icom_adapter, port_num);
1385                        icom_port->dram = icom_adapter->base_addr +
1386                                        0x2000 * icom_port->port;
1387
1388                        icom_port->adapter = icom_adapter;
1389
1390                        /* get port memory */
1391                        if (get_port_memory(icom_port) != 0) {
1392                                dev_err(&icom_port->adapter->pci_dev->dev,
1393                                        "Memory allocation for port FAILED\n");
1394                        }
1395                }
1396        }
1397        return 0;
1398}
1399
1400static int icom_alloc_adapter(struct icom_adapter
1401                                        **icom_adapter_ref)
1402{
1403        int adapter_count = 0;
1404        struct icom_adapter *icom_adapter;
1405        struct icom_adapter *cur_adapter_entry;
1406        struct list_head *tmp;
1407
1408        icom_adapter = kzalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1409
1410        if (!icom_adapter) {
1411                return -ENOMEM;
1412        }
1413
1414        list_for_each(tmp, &icom_adapter_head) {
1415                cur_adapter_entry =
1416                    list_entry(tmp, struct icom_adapter,
1417                               icom_adapter_entry);
1418                if (cur_adapter_entry->index != adapter_count) {
1419                        break;
1420                }
1421                adapter_count++;
1422        }
1423
1424        icom_adapter->index = adapter_count;
1425        list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1426
1427        *icom_adapter_ref = icom_adapter;
1428        return 0;
1429}
1430
1431static void icom_free_adapter(struct icom_adapter *icom_adapter)
1432{
1433        list_del(&icom_adapter->icom_adapter_entry);
1434        kfree(icom_adapter);
1435}
1436
1437static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1438{
1439        struct icom_port *icom_port;
1440        int index;
1441
1442        for (index = 0; index < icom_adapter->numb_ports; index++) {
1443                icom_port = &icom_adapter->port_info[index];
1444
1445                if (icom_port->status == ICOM_PORT_ACTIVE) {
1446                        dev_info(&icom_adapter->pci_dev->dev,
1447                                 "Device removed\n");
1448
1449                        uart_remove_one_port(&icom_uart_driver,
1450                                             &icom_port->uart_port);
1451
1452                        /* be sure that DTR and RTS are dropped */
1453                        writeb(0x00, &icom_port->dram->osr);
1454
1455                        /* Wait 0.1 Sec for simple Init to complete */
1456                        msleep(100);
1457
1458                        /* Stop proccessor */
1459                        stop_processor(icom_port);
1460
1461                        free_port_memory(icom_port);
1462                }
1463        }
1464
1465        free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter);
1466        iounmap(icom_adapter->base_addr);
1467        pci_release_regions(icom_adapter->pci_dev);
1468        icom_free_adapter(icom_adapter);
1469}
1470
1471static void icom_kref_release(struct kref *kref)
1472{
1473        struct icom_adapter *icom_adapter;
1474
1475        icom_adapter = to_icom_adapter(kref);
1476        icom_remove_adapter(icom_adapter);
1477}
1478
1479static int icom_probe(struct pci_dev *dev,
1480                                const struct pci_device_id *ent)
1481{
1482        int index;
1483        unsigned int command_reg;
1484        int retval;
1485        struct icom_adapter *icom_adapter;
1486        struct icom_port *icom_port;
1487
1488        retval = pci_enable_device(dev);
1489        if (retval) {
1490                dev_err(&dev->dev, "Device enable FAILED\n");
1491                return retval;
1492        }
1493
1494        retval = pci_request_regions(dev, "icom");
1495        if (retval) {
1496                 dev_err(&dev->dev, "pci_request_regions FAILED\n");
1497                 pci_disable_device(dev);
1498                 return retval;
1499         }
1500
1501        pci_set_master(dev);
1502
1503        retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg);
1504        if (retval) {
1505                dev_err(&dev->dev, "PCI Config read FAILED\n");
1506                return retval;
1507        }
1508
1509        pci_write_config_dword(dev, PCI_COMMAND,
1510                command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1511                | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1512
1513        if (ent->driver_data == ADAPTER_V1) {
1514                pci_write_config_dword(dev, 0x44, 0x8300830A);
1515        } else {
1516                pci_write_config_dword(dev, 0x44, 0x42004200);
1517                pci_write_config_dword(dev, 0x48, 0x42004200);
1518        }
1519
1520
1521        retval = icom_alloc_adapter(&icom_adapter);
1522        if (retval) {
1523                 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1524                 retval = -EIO;
1525                 goto probe_exit0;
1526        }
1527
1528        icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1529        icom_adapter->pci_dev = dev;
1530        icom_adapter->version = ent->driver_data;
1531        icom_adapter->subsystem_id = ent->subdevice;
1532
1533
1534        retval = icom_init_ports(icom_adapter);
1535        if (retval) {
1536                dev_err(&dev->dev, "Port configuration failed\n");
1537                goto probe_exit1;
1538        }
1539
1540        icom_adapter->base_addr = pci_ioremap_bar(dev, 0);
1541
1542        if (!icom_adapter->base_addr) {
1543                retval = -ENOMEM;
1544                goto probe_exit1;
1545        }
1546
1547         /* save off irq and request irq line */
1548         retval = request_irq(dev->irq, icom_interrupt, IRQF_SHARED, ICOM_DRIVER_NAME, (void *)icom_adapter);
1549         if (retval) {
1550                  goto probe_exit2;
1551         }
1552
1553        retval = icom_load_ports(icom_adapter);
1554
1555        for (index = 0; index < icom_adapter->numb_ports; index++) {
1556                icom_port = &icom_adapter->port_info[index];
1557
1558                if (icom_port->status == ICOM_PORT_ACTIVE) {
1559                        icom_port->uart_port.irq = icom_port->adapter->pci_dev->irq;
1560                        icom_port->uart_port.type = PORT_ICOM;
1561                        icom_port->uart_port.iotype = UPIO_MEM;
1562                        icom_port->uart_port.membase =
1563                                (unsigned char __iomem *)icom_adapter->base_addr_pci;
1564                        icom_port->uart_port.fifosize = 16;
1565                        icom_port->uart_port.ops = &icom_ops;
1566                        icom_port->uart_port.line =
1567                        icom_port->port + icom_adapter->index * 4;
1568                        if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1569                                icom_port->status = ICOM_PORT_OFF;
1570                                dev_err(&dev->dev, "Device add failed\n");
1571                         } else
1572                                dev_info(&dev->dev, "Device added\n");
1573                }
1574        }
1575
1576        kref_init(&icom_adapter->kref);
1577        return 0;
1578
1579probe_exit2:
1580        iounmap(icom_adapter->base_addr);
1581probe_exit1:
1582        icom_free_adapter(icom_adapter);
1583
1584probe_exit0:
1585        pci_release_regions(dev);
1586        pci_disable_device(dev);
1587
1588        return retval;
1589}
1590
1591static void icom_remove(struct pci_dev *dev)
1592{
1593        struct icom_adapter *icom_adapter;
1594        struct list_head *tmp;
1595
1596        list_for_each(tmp, &icom_adapter_head) {
1597                icom_adapter = list_entry(tmp, struct icom_adapter,
1598                                          icom_adapter_entry);
1599                if (icom_adapter->pci_dev == dev) {
1600                        kref_put(&icom_adapter->kref, icom_kref_release);
1601                        return;
1602                }
1603        }
1604
1605        dev_err(&dev->dev, "Unable to find device to remove\n");
1606}
1607
1608static struct pci_driver icom_pci_driver = {
1609        .name = ICOM_DRIVER_NAME,
1610        .id_table = icom_pci_table,
1611        .probe = icom_probe,
1612        .remove = icom_remove,
1613};
1614
1615static int __init icom_init(void)
1616{
1617        int ret;
1618
1619        spin_lock_init(&icom_lock);
1620
1621        ret = uart_register_driver(&icom_uart_driver);
1622        if (ret)
1623                return ret;
1624
1625        ret = pci_register_driver(&icom_pci_driver);
1626
1627        if (ret < 0)
1628                uart_unregister_driver(&icom_uart_driver);
1629
1630        return ret;
1631}
1632
1633static void __exit icom_exit(void)
1634{
1635        pci_unregister_driver(&icom_pci_driver);
1636        uart_unregister_driver(&icom_uart_driver);
1637}
1638
1639module_init(icom_init);
1640module_exit(icom_exit);
1641
1642MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1643MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1644MODULE_SUPPORTED_DEVICE
1645    ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1646MODULE_LICENSE("GPL");
1647MODULE_FIRMWARE("icom_call_setup.bin");
1648MODULE_FIRMWARE("icom_res_dce.bin");
1649MODULE_FIRMWARE("icom_asc.bin");
1650