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