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        char new_config2;
1102        char new_config3 = 0;
1103        char tmp_byte;
1104        int index;
1105        int rcv_buff, xmit_buff;
1106        unsigned long offset;
1107        unsigned long flags;
1108
1109        spin_lock_irqsave(&port->lock, flags);
1110        trace(ICOM_PORT, "CHANGE_SPEED", 0);
1111
1112        cflag = termios->c_cflag;
1113        iflag = termios->c_iflag;
1114
1115        new_config2 = ICOM_ACFG_DRIVE1;
1116
1117        /* byte size and parity */
1118        switch (cflag & CSIZE) {
1119        case CS5:               /* 5 bits/char */
1120                new_config2 |= ICOM_ACFG_5BPC;
1121                break;
1122        case CS6:               /* 6 bits/char */
1123                new_config2 |= ICOM_ACFG_6BPC;
1124                break;
1125        case CS7:               /* 7 bits/char */
1126                new_config2 |= ICOM_ACFG_7BPC;
1127                break;
1128        case CS8:               /* 8 bits/char */
1129                new_config2 |= ICOM_ACFG_8BPC;
1130                break;
1131        default:
1132                break;
1133        }
1134        if (cflag & CSTOPB) {
1135                /* 2 stop bits */
1136                new_config2 |= ICOM_ACFG_2STOP_BIT;
1137        }
1138        if (cflag & PARENB) {
1139                /* parity bit enabled */
1140                new_config2 |= ICOM_ACFG_PARITY_ENAB;
1141                trace(ICOM_PORT, "PARENB", 0);
1142        }
1143        if (cflag & PARODD) {
1144                /* odd parity */
1145                new_config2 |= ICOM_ACFG_PARITY_ODD;
1146                trace(ICOM_PORT, "PARODD", 0);
1147        }
1148
1149        /* Determine divisor based on baud rate */
1150        baud = uart_get_baud_rate(port, termios, old_termios,
1151                                  icom_acfg_baud[0],
1152                                  icom_acfg_baud[BAUD_TABLE_LIMIT]);
1153        if (!baud)
1154                baud = 9600;    /* B0 transition handled in rs_set_termios */
1155
1156        for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1157                if (icom_acfg_baud[index] == baud) {
1158                        new_config3 = index;
1159                        break;
1160                }
1161        }
1162
1163        uart_update_timeout(port, cflag, baud);
1164
1165        /* CTS flow control flag and modem status interrupts */
1166        tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1167        if (cflag & CRTSCTS)
1168                tmp_byte |= HDLC_HDW_FLOW;
1169        else
1170                tmp_byte &= ~HDLC_HDW_FLOW;
1171        writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1172
1173        /*
1174         * Set up parity check flag
1175         */
1176        ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1177        if (iflag & INPCK)
1178                ICOM_PORT->read_status_mask |=
1179                    SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1180
1181        if ((iflag & BRKINT) || (iflag & PARMRK))
1182                ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1183
1184        /*
1185         * Characters to ignore
1186         */
1187        ICOM_PORT->ignore_status_mask = 0;
1188        if (iflag & IGNPAR)
1189                ICOM_PORT->ignore_status_mask |=
1190                    SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1191        if (iflag & IGNBRK) {
1192                ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1193                /*
1194                 * If we're ignore parity and break indicators, ignore
1195                 * overruns too.  (For real raw support).
1196                 */
1197                if (iflag & IGNPAR)
1198                        ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1199        }
1200
1201        /*
1202         * !!! ignore all characters if CREAD is not set
1203         */
1204        if ((cflag & CREAD) == 0)
1205                ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1206
1207        /* Turn off Receiver to prepare for reset */
1208        writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1209
1210        for (index = 0; index < 10; index++) {
1211                if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1212                        break;
1213                }
1214        }
1215
1216        /* clear all current buffers of data */
1217        for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1218                ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1219                ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1220                ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1221                    (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1222        }
1223
1224        for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1225                ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1226        }
1227
1228        /* activate changes and start xmit and receiver here */
1229        /* Enable the receiver */
1230        writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1231        writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1232        tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1233        tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1234        writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1235        writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer));    /* 0.5 seconds */
1236        writeb(0xFF, &(ICOM_PORT->dram->ier));  /* enable modem signal interrupts */
1237
1238        /* reset processor */
1239        writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1240
1241        for (index = 0; index < 10; index++) {
1242                if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1243                        break;
1244                }
1245        }
1246
1247        /* Enable Transmitter and Reciever */
1248        offset =
1249            (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1250            (unsigned long) ICOM_PORT->statStg;
1251        writel(ICOM_PORT->statStg_pci + offset,
1252               &ICOM_PORT->dram->RcvStatusAddr);
1253        ICOM_PORT->next_rcv = 0;
1254        ICOM_PORT->put_length = 0;
1255        *ICOM_PORT->xmitRestart = 0;
1256        writel(ICOM_PORT->xmitRestart_pci,
1257               &ICOM_PORT->dram->XmitStatusAddr);
1258        trace(ICOM_PORT, "XR_ENAB", 0);
1259        writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1260
1261        spin_unlock_irqrestore(&port->lock, flags);
1262}
1263
1264static const char *icom_type(struct uart_port *port)
1265{
1266        return "icom";
1267}
1268
1269static void icom_release_port(struct uart_port *port)
1270{
1271}
1272
1273static int icom_request_port(struct uart_port *port)
1274{
1275        return 0;
1276}
1277
1278static void icom_config_port(struct uart_port *port, int flags)
1279{
1280        port->type = PORT_ICOM;
1281}
1282
1283static struct uart_ops icom_ops = {
1284        .tx_empty = icom_tx_empty,
1285        .set_mctrl = icom_set_mctrl,
1286        .get_mctrl = icom_get_mctrl,
1287        .stop_tx = icom_stop_tx,
1288        .start_tx = icom_start_tx,
1289        .send_xchar = icom_send_xchar,
1290        .stop_rx = icom_stop_rx,
1291        .enable_ms = icom_enable_ms,
1292        .break_ctl = icom_break,
1293        .startup = icom_open,
1294        .shutdown = icom_close,
1295        .set_termios = icom_set_termios,
1296        .type = icom_type,
1297        .release_port = icom_release_port,
1298        .request_port = icom_request_port,
1299        .config_port = icom_config_port,
1300};
1301
1302#define ICOM_CONSOLE NULL
1303
1304static struct uart_driver icom_uart_driver = {
1305        .owner = THIS_MODULE,
1306        .driver_name = ICOM_DRIVER_NAME,
1307        .dev_name = "ttyA",
1308        .major = ICOM_MAJOR,
1309        .minor = ICOM_MINOR_START,
1310        .nr = NR_PORTS,
1311        .cons = ICOM_CONSOLE,
1312};
1313
1314static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1315{
1316        u32 subsystem_id = icom_adapter->subsystem_id;
1317        int i;
1318        struct icom_port *icom_port;
1319
1320        if (icom_adapter->version == ADAPTER_V1) {
1321                icom_adapter->numb_ports = 2;
1322
1323                for (i = 0; i < 2; i++) {
1324                        icom_port = &icom_adapter->port_info[i];
1325                        icom_port->port = i;
1326                        icom_port->status = ICOM_PORT_ACTIVE;
1327                        icom_port->imbed_modem = ICOM_UNKNOWN;
1328                }
1329        } else {
1330                if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1331                        icom_adapter->numb_ports = 4;
1332
1333                        for (i = 0; i < 4; i++) {
1334                                icom_port = &icom_adapter->port_info[i];
1335
1336                                icom_port->port = i;
1337                                icom_port->status = ICOM_PORT_ACTIVE;
1338                                icom_port->imbed_modem = ICOM_IMBED_MODEM;
1339                        }
1340                } else {
1341                        icom_adapter->numb_ports = 4;
1342
1343                        icom_adapter->port_info[0].port = 0;
1344                        icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1345
1346                        if (subsystem_id ==
1347                            PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1348                                icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1349                        } else {
1350                                icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1351                        }
1352
1353                        icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1354
1355                        icom_adapter->port_info[2].port = 2;
1356                        icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1357                        icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1358                        icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1359                }
1360        }
1361
1362        return 0;
1363}
1364
1365static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1366{
1367        if (icom_adapter->version == ADAPTER_V1) {
1368                icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1369                icom_port->int_reg = icom_adapter->base_addr +
1370                    0x4004 + 2 - 2 * port_num;
1371        } else {
1372                icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1373                if (icom_port->port < 2)
1374                        icom_port->int_reg = icom_adapter->base_addr +
1375                            0x8004 + 2 - 2 * icom_port->port;
1376                else
1377                        icom_port->int_reg = icom_adapter->base_addr +
1378                            0x8024 + 2 - 2 * (icom_port->port - 2);
1379        }
1380}
1381static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
1382{
1383        struct icom_port *icom_port;
1384        int port_num;
1385
1386        for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1387
1388                icom_port = &icom_adapter->port_info[port_num];
1389
1390                if (icom_port->status == ICOM_PORT_ACTIVE) {
1391                        icom_port_active(icom_port, icom_adapter, port_num);
1392                        icom_port->dram = icom_adapter->base_addr +
1393                                        0x2000 * icom_port->port;
1394
1395                        icom_port->adapter = icom_adapter;
1396
1397                        /* get port memory */
1398                        if (get_port_memory(icom_port) != 0) {
1399                                dev_err(&icom_port->adapter->pci_dev->dev,
1400                                        "Memory allocation for port FAILED\n");
1401                        }
1402                }
1403        }
1404        return 0;
1405}
1406
1407static int __devinit icom_alloc_adapter(struct icom_adapter
1408                                        **icom_adapter_ref)
1409{
1410        int adapter_count = 0;
1411        struct icom_adapter *icom_adapter;
1412        struct icom_adapter *cur_adapter_entry;
1413        struct list_head *tmp;
1414
1415        icom_adapter = (struct icom_adapter *)
1416            kzalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1417
1418        if (!icom_adapter) {
1419                return -ENOMEM;
1420        }
1421
1422        list_for_each(tmp, &icom_adapter_head) {
1423                cur_adapter_entry =
1424                    list_entry(tmp, struct icom_adapter,
1425                               icom_adapter_entry);
1426                if (cur_adapter_entry->index != adapter_count) {
1427                        break;
1428                }
1429                adapter_count++;
1430        }
1431
1432        icom_adapter->index = adapter_count;
1433        list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1434
1435        *icom_adapter_ref = icom_adapter;
1436        return 0;
1437}
1438
1439static void icom_free_adapter(struct icom_adapter *icom_adapter)
1440{
1441        list_del(&icom_adapter->icom_adapter_entry);
1442        kfree(icom_adapter);
1443}
1444
1445static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1446{
1447        struct icom_port *icom_port;
1448        int index;
1449
1450        for (index = 0; index < icom_adapter->numb_ports; index++) {
1451                icom_port = &icom_adapter->port_info[index];
1452
1453                if (icom_port->status == ICOM_PORT_ACTIVE) {
1454                        dev_info(&icom_adapter->pci_dev->dev,
1455                                 "Device removed\n");
1456
1457                        uart_remove_one_port(&icom_uart_driver,
1458                                             &icom_port->uart_port);
1459
1460                        /* be sure that DTR and RTS are dropped */
1461                        writeb(0x00, &icom_port->dram->osr);
1462
1463                        /* Wait 0.1 Sec for simple Init to complete */
1464                        msleep(100);
1465
1466                        /* Stop proccessor */
1467                        stop_processor(icom_port);
1468
1469                        free_port_memory(icom_port);
1470                }
1471        }
1472
1473        free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter);
1474        iounmap(icom_adapter->base_addr);
1475        pci_release_regions(icom_adapter->pci_dev);
1476        icom_free_adapter(icom_adapter);
1477}
1478
1479static void icom_kref_release(struct kref *kref)
1480{
1481        struct icom_adapter *icom_adapter;
1482
1483        icom_adapter = to_icom_adapter(kref);
1484        icom_remove_adapter(icom_adapter);
1485}
1486
1487static int __devinit icom_probe(struct pci_dev *dev,
1488                                const struct pci_device_id *ent)
1489{
1490        int index;
1491        unsigned int command_reg;
1492        int retval;
1493        struct icom_adapter *icom_adapter;
1494        struct icom_port *icom_port;
1495
1496        retval = pci_enable_device(dev);
1497        if (retval) {
1498                dev_err(&dev->dev, "Device enable FAILED\n");
1499                return retval;
1500        }
1501
1502        if ( (retval = pci_request_regions(dev, "icom"))) {
1503                 dev_err(&dev->dev, "pci_request_regions FAILED\n");
1504                 pci_disable_device(dev);
1505                 return retval;
1506         }
1507
1508        pci_set_master(dev);
1509
1510        if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1511                dev_err(&dev->dev, "PCI Config read FAILED\n");
1512                return retval;
1513        }
1514
1515        pci_write_config_dword(dev, PCI_COMMAND,
1516                command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1517                | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1518
1519        if (ent->driver_data == ADAPTER_V1) {
1520                pci_write_config_dword(dev, 0x44, 0x8300830A);
1521         } else {
1522                pci_write_config_dword(dev, 0x44, 0x42004200);
1523                pci_write_config_dword(dev, 0x48, 0x42004200);
1524         }
1525
1526
1527        retval = icom_alloc_adapter(&icom_adapter);
1528        if (retval) {
1529                 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1530                 retval = -EIO;
1531                 goto probe_exit0;
1532        }
1533
1534         icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1535         icom_adapter->pci_dev = dev;
1536         icom_adapter->version = ent->driver_data;
1537         icom_adapter->subsystem_id = ent->subdevice;
1538
1539
1540        retval = icom_init_ports(icom_adapter);
1541        if (retval) {
1542                dev_err(&dev->dev, "Port configuration failed\n");
1543                goto probe_exit1;
1544        }
1545
1546         icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1547                                                pci_resource_len(dev, 0));
1548
1549        if (!icom_adapter->base_addr)
1550                goto probe_exit1;
1551
1552         /* save off irq and request irq line */
1553         if ( (retval = request_irq(dev->irq, icom_interrupt,
1554                                   IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME,
1555                                   (void *) icom_adapter))) {
1556                  goto probe_exit2;
1557         }
1558
1559        retval = icom_load_ports(icom_adapter);
1560
1561        for (index = 0; index < icom_adapter->numb_ports; index++) {
1562                icom_port = &icom_adapter->port_info[index];
1563
1564                if (icom_port->status == ICOM_PORT_ACTIVE) {
1565                        icom_port->uart_port.irq = icom_port->adapter->pci_dev->irq;
1566                        icom_port->uart_port.type = PORT_ICOM;
1567                        icom_port->uart_port.iotype = UPIO_MEM;
1568                        icom_port->uart_port.membase =
1569                                               (char *) icom_adapter->base_addr_pci;
1570                        icom_port->uart_port.fifosize = 16;
1571                        icom_port->uart_port.ops = &icom_ops;
1572                        icom_port->uart_port.line =
1573                        icom_port->port + icom_adapter->index * 4;
1574                        if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1575                                icom_port->status = ICOM_PORT_OFF;
1576                                dev_err(&dev->dev, "Device add failed\n");
1577                         } else
1578                                dev_info(&dev->dev, "Device added\n");
1579                }
1580        }
1581
1582        kref_init(&icom_adapter->kref);
1583        return 0;
1584
1585probe_exit2:
1586        iounmap(icom_adapter->base_addr);
1587probe_exit1:
1588        icom_free_adapter(icom_adapter);
1589
1590probe_exit0:
1591        pci_release_regions(dev);
1592        pci_disable_device(dev);
1593
1594        return retval;
1595
1596
1597}
1598
1599static void __devexit icom_remove(struct pci_dev *dev)
1600{
1601        struct icom_adapter *icom_adapter;
1602        struct list_head *tmp;
1603
1604        list_for_each(tmp, &icom_adapter_head) {
1605                icom_adapter = list_entry(tmp, struct icom_adapter,
1606                                          icom_adapter_entry);
1607                if (icom_adapter->pci_dev == dev) {
1608                        kref_put(&icom_adapter->kref, icom_kref_release);
1609                        return;
1610                }
1611        }
1612
1613        dev_err(&dev->dev, "Unable to find device to remove\n");
1614}
1615
1616static struct pci_driver icom_pci_driver = {
1617        .name = ICOM_DRIVER_NAME,
1618        .id_table = icom_pci_table,
1619        .probe = icom_probe,
1620        .remove = __devexit_p(icom_remove),
1621};
1622
1623static int __init icom_init(void)
1624{
1625        int ret;
1626
1627        spin_lock_init(&icom_lock);
1628
1629        ret = uart_register_driver(&icom_uart_driver);
1630        if (ret)
1631                return ret;
1632
1633        ret = pci_register_driver(&icom_pci_driver);
1634
1635        if (ret < 0)
1636                uart_unregister_driver(&icom_uart_driver);
1637
1638        return ret;
1639}
1640
1641static void __exit icom_exit(void)
1642{
1643        pci_unregister_driver(&icom_pci_driver);
1644        uart_unregister_driver(&icom_uart_driver);
1645}
1646
1647module_init(icom_init);
1648module_exit(icom_exit);
1649
1650#ifdef ICOM_TRACE
1651static inline void trace(struct icom_port *icom_port, char *trace_pt,
1652                  unsigned long trace_data)
1653{
1654        dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1655                 icom_port->port, trace_pt, trace_data);
1656}
1657#endif
1658
1659MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1660MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1661MODULE_SUPPORTED_DEVICE
1662    ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1663MODULE_LICENSE("GPL");
1664
1665