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