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