linux/drivers/s390/char/raw3270.c
<<
>>
Prefs
   1/*
   2 * IBM/3270 Driver - core functions.
   3 *
   4 * Author(s):
   5 *   Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
   6 *   Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
   7 *     Copyright IBM Corp. 2003, 2009
   8 */
   9
  10#include <linux/module.h>
  11#include <linux/err.h>
  12#include <linux/init.h>
  13#include <linux/interrupt.h>
  14#include <linux/list.h>
  15#include <linux/slab.h>
  16#include <linux/types.h>
  17#include <linux/wait.h>
  18
  19#include <asm/ccwdev.h>
  20#include <asm/cio.h>
  21#include <asm/ebcdic.h>
  22#include <asm/diag.h>
  23
  24#include "raw3270.h"
  25
  26#include <linux/major.h>
  27#include <linux/kdev_t.h>
  28#include <linux/device.h>
  29#include <linux/mutex.h>
  30
  31struct class *class3270;
  32
  33/* The main 3270 data structure. */
  34struct raw3270 {
  35        struct list_head list;
  36        struct ccw_device *cdev;
  37        int minor;
  38
  39        short model, rows, cols;
  40        unsigned int state;
  41        unsigned long flags;
  42
  43        struct list_head req_queue;     /* Request queue. */
  44        struct list_head view_list;     /* List of available views. */
  45        struct raw3270_view *view;      /* Active view. */
  46
  47        struct timer_list timer;        /* Device timer. */
  48
  49        unsigned char *ascebc;          /* ascii -> ebcdic table */
  50
  51        struct raw3270_view init_view;
  52        struct raw3270_request init_reset;
  53        struct raw3270_request init_readpart;
  54        struct raw3270_request init_readmod;
  55        unsigned char init_data[256];
  56};
  57
  58/* raw3270->state */
  59#define RAW3270_STATE_INIT      0       /* Initial state */
  60#define RAW3270_STATE_RESET     1       /* Reset command is pending */
  61#define RAW3270_STATE_W4ATTN    2       /* Wait for attention interrupt */
  62#define RAW3270_STATE_READMOD   3       /* Read partition is pending */
  63#define RAW3270_STATE_READY     4       /* Device is usable by views */
  64
  65/* raw3270->flags */
  66#define RAW3270_FLAGS_14BITADDR 0       /* 14-bit buffer addresses */
  67#define RAW3270_FLAGS_BUSY      1       /* Device busy, leave it alone */
  68#define RAW3270_FLAGS_CONSOLE   2       /* Device is the console. */
  69#define RAW3270_FLAGS_FROZEN    3       /* set if 3270 is frozen for suspend */
  70
  71/* Semaphore to protect global data of raw3270 (devices, views, etc). */
  72static DEFINE_MUTEX(raw3270_mutex);
  73
  74/* List of 3270 devices. */
  75static LIST_HEAD(raw3270_devices);
  76
  77/*
  78 * Flag to indicate if the driver has been registered. Some operations
  79 * like waiting for the end of i/o need to be done differently as long
  80 * as the kernel is still starting up (console support).
  81 */
  82static int raw3270_registered;
  83
  84/* Module parameters */
  85static bool tubxcorrect = 0;
  86module_param(tubxcorrect, bool, 0);
  87
  88/*
  89 * Wait queue for device init/delete, view delete.
  90 */
  91DECLARE_WAIT_QUEUE_HEAD(raw3270_wait_queue);
  92
  93/*
  94 * Encode array for 12 bit 3270 addresses.
  95 */
  96static unsigned char raw3270_ebcgraf[64] =      {
  97        0x40, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
  98        0xc8, 0xc9, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
  99        0x50, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
 100        0xd8, 0xd9, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
 101        0x60, 0x61, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
 102        0xe8, 0xe9, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
 103        0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
 104        0xf8, 0xf9, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
 105};
 106
 107static inline int raw3270_state_ready(struct raw3270 *rp)
 108{
 109        return rp->state == RAW3270_STATE_READY;
 110}
 111
 112static inline int raw3270_state_final(struct raw3270 *rp)
 113{
 114        return rp->state == RAW3270_STATE_INIT ||
 115                rp->state == RAW3270_STATE_READY;
 116}
 117
 118void
 119raw3270_buffer_address(struct raw3270 *rp, char *cp, unsigned short addr)
 120{
 121        if (test_bit(RAW3270_FLAGS_14BITADDR, &rp->flags)) {
 122                cp[0] = (addr >> 8) & 0x3f;
 123                cp[1] = addr & 0xff;
 124        } else {
 125                cp[0] = raw3270_ebcgraf[(addr >> 6) & 0x3f];
 126                cp[1] = raw3270_ebcgraf[addr & 0x3f];
 127        }
 128}
 129
 130/*
 131 * Allocate a new 3270 ccw request
 132 */
 133struct raw3270_request *
 134raw3270_request_alloc(size_t size)
 135{
 136        struct raw3270_request *rq;
 137
 138        /* Allocate request structure */
 139        rq = kzalloc(sizeof(struct raw3270_request), GFP_KERNEL | GFP_DMA);
 140        if (!rq)
 141                return ERR_PTR(-ENOMEM);
 142
 143        /* alloc output buffer. */
 144        if (size > 0) {
 145                rq->buffer = kmalloc(size, GFP_KERNEL | GFP_DMA);
 146                if (!rq->buffer) {
 147                        kfree(rq);
 148                        return ERR_PTR(-ENOMEM);
 149                }
 150        }
 151        rq->size = size;
 152        INIT_LIST_HEAD(&rq->list);
 153
 154        /*
 155         * Setup ccw.
 156         */
 157        rq->ccw.cda = __pa(rq->buffer);
 158        rq->ccw.flags = CCW_FLAG_SLI;
 159
 160        return rq;
 161}
 162
 163/*
 164 * Free 3270 ccw request
 165 */
 166void
 167raw3270_request_free (struct raw3270_request *rq)
 168{
 169        kfree(rq->buffer);
 170        kfree(rq);
 171}
 172
 173/*
 174 * Reset request to initial state.
 175 */
 176void
 177raw3270_request_reset(struct raw3270_request *rq)
 178{
 179        BUG_ON(!list_empty(&rq->list));
 180        rq->ccw.cmd_code = 0;
 181        rq->ccw.count = 0;
 182        rq->ccw.cda = __pa(rq->buffer);
 183        rq->ccw.flags = CCW_FLAG_SLI;
 184        rq->rescnt = 0;
 185        rq->rc = 0;
 186}
 187
 188/*
 189 * Set command code to ccw of a request.
 190 */
 191void
 192raw3270_request_set_cmd(struct raw3270_request *rq, u8 cmd)
 193{
 194        rq->ccw.cmd_code = cmd;
 195}
 196
 197/*
 198 * Add data fragment to output buffer.
 199 */
 200int
 201raw3270_request_add_data(struct raw3270_request *rq, void *data, size_t size)
 202{
 203        if (size + rq->ccw.count > rq->size)
 204                return -E2BIG;
 205        memcpy(rq->buffer + rq->ccw.count, data, size);
 206        rq->ccw.count += size;
 207        return 0;
 208}
 209
 210/*
 211 * Set address/length pair to ccw of a request.
 212 */
 213void
 214raw3270_request_set_data(struct raw3270_request *rq, void *data, size_t size)
 215{
 216        rq->ccw.cda = __pa(data);
 217        rq->ccw.count = size;
 218}
 219
 220/*
 221 * Set idal buffer to ccw of a request.
 222 */
 223void
 224raw3270_request_set_idal(struct raw3270_request *rq, struct idal_buffer *ib)
 225{
 226        rq->ccw.cda = __pa(ib->data);
 227        rq->ccw.count = ib->size;
 228        rq->ccw.flags |= CCW_FLAG_IDA;
 229}
 230
 231/*
 232 * Stop running ccw.
 233 */
 234static int
 235__raw3270_halt_io(struct raw3270 *rp, struct raw3270_request *rq)
 236{
 237        int retries;
 238        int rc;
 239
 240        if (raw3270_request_final(rq))
 241                return 0;
 242        /* Check if interrupt has already been processed */
 243        for (retries = 0; retries < 5; retries++) {
 244                if (retries < 2)
 245                        rc = ccw_device_halt(rp->cdev, (long) rq);
 246                else
 247                        rc = ccw_device_clear(rp->cdev, (long) rq);
 248                if (rc == 0)
 249                        break;          /* termination successful */
 250        }
 251        return rc;
 252}
 253
 254/*
 255 * Add the request to the request queue, try to start it if the
 256 * 3270 device is idle. Return without waiting for end of i/o.
 257 */
 258static int
 259__raw3270_start(struct raw3270 *rp, struct raw3270_view *view,
 260                struct raw3270_request *rq)
 261{
 262        rq->view = view;
 263        raw3270_get_view(view);
 264        if (list_empty(&rp->req_queue) &&
 265            !test_bit(RAW3270_FLAGS_BUSY, &rp->flags)) {
 266                /* No other requests are on the queue. Start this one. */
 267                rq->rc = ccw_device_start(rp->cdev, &rq->ccw,
 268                                               (unsigned long) rq, 0, 0);
 269                if (rq->rc) {
 270                        raw3270_put_view(view);
 271                        return rq->rc;
 272                }
 273        }
 274        list_add_tail(&rq->list, &rp->req_queue);
 275        return 0;
 276}
 277
 278int
 279raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)
 280{
 281        unsigned long flags;
 282        struct raw3270 *rp;
 283        int rc;
 284
 285        spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags);
 286        rp = view->dev;
 287        if (!rp || rp->view != view ||
 288            test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
 289                rc = -EACCES;
 290        else if (!raw3270_state_ready(rp))
 291                rc = -EBUSY;
 292        else
 293                rc =  __raw3270_start(rp, view, rq);
 294        spin_unlock_irqrestore(get_ccwdev_lock(view->dev->cdev), flags);
 295        return rc;
 296}
 297
 298int
 299raw3270_start_locked(struct raw3270_view *view, struct raw3270_request *rq)
 300{
 301        struct raw3270 *rp;
 302        int rc;
 303
 304        rp = view->dev;
 305        if (!rp || rp->view != view ||
 306            test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
 307                rc = -EACCES;
 308        else if (!raw3270_state_ready(rp))
 309                rc = -EBUSY;
 310        else
 311                rc =  __raw3270_start(rp, view, rq);
 312        return rc;
 313}
 314
 315int
 316raw3270_start_irq(struct raw3270_view *view, struct raw3270_request *rq)
 317{
 318        struct raw3270 *rp;
 319
 320        rp = view->dev;
 321        rq->view = view;
 322        raw3270_get_view(view);
 323        list_add_tail(&rq->list, &rp->req_queue);
 324        return 0;
 325}
 326
 327/*
 328 * 3270 interrupt routine, called from the ccw_device layer
 329 */
 330static void
 331raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
 332{
 333        struct raw3270 *rp;
 334        struct raw3270_view *view;
 335        struct raw3270_request *rq;
 336        int rc;
 337
 338        rp = dev_get_drvdata(&cdev->dev);
 339        if (!rp)
 340                return;
 341        rq = (struct raw3270_request *) intparm;
 342        view = rq ? rq->view : rp->view;
 343
 344        if (IS_ERR(irb))
 345                rc = RAW3270_IO_RETRY;
 346        else if (irb->scsw.cmd.fctl & SCSW_FCTL_HALT_FUNC) {
 347                rq->rc = -EIO;
 348                rc = RAW3270_IO_DONE;
 349        } else if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END |
 350                                           DEV_STAT_UNIT_EXCEP)) {
 351                /* Handle CE-DE-UE and subsequent UDE */
 352                set_bit(RAW3270_FLAGS_BUSY, &rp->flags);
 353                rc = RAW3270_IO_BUSY;
 354        } else if (test_bit(RAW3270_FLAGS_BUSY, &rp->flags)) {
 355                /* Wait for UDE if busy flag is set. */
 356                if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) {
 357                        clear_bit(RAW3270_FLAGS_BUSY, &rp->flags);
 358                        /* Got it, now retry. */
 359                        rc = RAW3270_IO_RETRY;
 360                } else
 361                        rc = RAW3270_IO_BUSY;
 362        } else if (view)
 363                rc = view->fn->intv(view, rq, irb);
 364        else
 365                rc = RAW3270_IO_DONE;
 366
 367        switch (rc) {
 368        case RAW3270_IO_DONE:
 369                break;
 370        case RAW3270_IO_BUSY:
 371                /* 
 372                 * Intervention required by the operator. We have to wait
 373                 * for unsolicited device end.
 374                 */
 375                return;
 376        case RAW3270_IO_RETRY:
 377                if (!rq)
 378                        break;
 379                rq->rc = ccw_device_start(rp->cdev, &rq->ccw,
 380                                          (unsigned long) rq, 0, 0);
 381                if (rq->rc == 0)
 382                        return; /* Successfully restarted. */
 383                break;
 384        case RAW3270_IO_STOP:
 385                if (!rq)
 386                        break;
 387                __raw3270_halt_io(rp, rq);
 388                rq->rc = -EIO;
 389                break;
 390        default:
 391                BUG();
 392        }
 393        if (rq) {
 394                BUG_ON(list_empty(&rq->list));
 395                /* The request completed, remove from queue and do callback. */
 396                list_del_init(&rq->list);
 397                if (rq->callback)
 398                        rq->callback(rq, rq->callback_data);
 399                /* Do put_device for get_device in raw3270_start. */
 400                raw3270_put_view(view);
 401        }
 402        /*
 403         * Try to start each request on request queue until one is
 404         * started successful.
 405         */
 406        while (!list_empty(&rp->req_queue)) {
 407                rq = list_entry(rp->req_queue.next,struct raw3270_request,list);
 408                rq->rc = ccw_device_start(rp->cdev, &rq->ccw,
 409                                          (unsigned long) rq, 0, 0);
 410                if (rq->rc == 0)
 411                        break;
 412                /* Start failed. Remove request and do callback. */
 413                list_del_init(&rq->list);
 414                if (rq->callback)
 415                        rq->callback(rq, rq->callback_data);
 416                /* Do put_device for get_device in raw3270_start. */
 417                raw3270_put_view(view);
 418        }
 419}
 420
 421/*
 422 * To determine the size of the 3270 device we need to do:
 423 * 1) send a 'read partition' data stream to the device
 424 * 2) wait for the attn interrupt that precedes the query reply
 425 * 3) do a read modified to get the query reply
 426 * To make things worse we have to cope with intervention
 427 * required (3270 device switched to 'stand-by') and command
 428 * rejects (old devices that can't do 'read partition').
 429 */
 430struct raw3270_ua {     /* Query Reply structure for Usable Area */
 431        struct {        /* Usable Area Query Reply Base */
 432                short l;        /* Length of this structured field */
 433                char  sfid;     /* 0x81 if Query Reply */
 434                char  qcode;    /* 0x81 if Usable Area */
 435                char  flags0;
 436                char  flags1;
 437                short w;        /* Width of usable area */
 438                short h;        /* Heigth of usavle area */
 439                char  units;    /* 0x00:in; 0x01:mm */
 440                int   xr;
 441                int   yr;
 442                char  aw;
 443                char  ah;
 444                short buffsz;   /* Character buffer size, bytes */
 445                char  xmin;
 446                char  ymin;
 447                char  xmax;
 448                char  ymax;
 449        } __attribute__ ((packed)) uab;
 450        struct {        /* Alternate Usable Area Self-Defining Parameter */
 451                char  l;        /* Length of this Self-Defining Parm */
 452                char  sdpid;    /* 0x02 if Alternate Usable Area */
 453                char  res;
 454                char  auaid;    /* 0x01 is Id for the A U A */
 455                short wauai;    /* Width of AUAi */
 456                short hauai;    /* Height of AUAi */
 457                char  auaunits; /* 0x00:in, 0x01:mm */
 458                int   auaxr;
 459                int   auayr;
 460                char  awauai;
 461                char  ahauai;
 462        } __attribute__ ((packed)) aua;
 463} __attribute__ ((packed));
 464
 465static void
 466raw3270_size_device_vm(struct raw3270 *rp)
 467{
 468        int rc, model;
 469        struct ccw_dev_id dev_id;
 470        struct diag210 diag_data;
 471
 472        ccw_device_get_id(rp->cdev, &dev_id);
 473        diag_data.vrdcdvno = dev_id.devno;
 474        diag_data.vrdclen = sizeof(struct diag210);
 475        rc = diag210(&diag_data);
 476        model = diag_data.vrdccrmd;
 477        /* Use default model 2 if the size could not be detected */
 478        if (rc || model < 2 || model > 5)
 479                model = 2;
 480        switch (model) {
 481        case 2:
 482                rp->model = model;
 483                rp->rows = 24;
 484                rp->cols = 80;
 485                break;
 486        case 3:
 487                rp->model = model;
 488                rp->rows = 32;
 489                rp->cols = 80;
 490                break;
 491        case 4:
 492                rp->model = model;
 493                rp->rows = 43;
 494                rp->cols = 80;
 495                break;
 496        case 5:
 497                rp->model = model;
 498                rp->rows = 27;
 499                rp->cols = 132;
 500                break;
 501        }
 502}
 503
 504static void
 505raw3270_size_device(struct raw3270 *rp)
 506{
 507        struct raw3270_ua *uap;
 508
 509        /* Got a Query Reply */
 510        uap = (struct raw3270_ua *) (rp->init_data + 1);
 511        /* Paranoia check. */
 512        if (rp->init_readmod.rc || rp->init_data[0] != 0x88 ||
 513            uap->uab.qcode != 0x81) {
 514                /* Couldn't detect size. Use default model 2. */
 515                rp->model = 2;
 516                rp->rows = 24;
 517                rp->cols = 80;
 518                return;
 519        }
 520        /* Copy rows/columns of default Usable Area */
 521        rp->rows = uap->uab.h;
 522        rp->cols = uap->uab.w;
 523        /* Check for 14 bit addressing */
 524        if ((uap->uab.flags0 & 0x0d) == 0x01)
 525                set_bit(RAW3270_FLAGS_14BITADDR, &rp->flags);
 526        /* Check for Alternate Usable Area */
 527        if (uap->uab.l == sizeof(struct raw3270_ua) &&
 528            uap->aua.sdpid == 0x02) {
 529                rp->rows = uap->aua.hauai;
 530                rp->cols = uap->aua.wauai;
 531        }
 532        /* Try to find a model. */
 533        rp->model = 0;
 534        if (rp->rows == 24 && rp->cols == 80)
 535                rp->model = 2;
 536        if (rp->rows == 32 && rp->cols == 80)
 537                rp->model = 3;
 538        if (rp->rows == 43 && rp->cols == 80)
 539                rp->model = 4;
 540        if (rp->rows == 27 && rp->cols == 132)
 541                rp->model = 5;
 542}
 543
 544static void
 545raw3270_size_device_done(struct raw3270 *rp)
 546{
 547        struct raw3270_view *view;
 548
 549        rp->view = NULL;
 550        rp->state = RAW3270_STATE_READY;
 551        /* Notify views about new size */
 552        list_for_each_entry(view, &rp->view_list, list)
 553                if (view->fn->resize)
 554                        view->fn->resize(view, rp->model, rp->rows, rp->cols);
 555        /* Setup processing done, now activate a view */
 556        list_for_each_entry(view, &rp->view_list, list) {
 557                rp->view = view;
 558                if (view->fn->activate(view) == 0)
 559                        break;
 560                rp->view = NULL;
 561        }
 562}
 563
 564static void
 565raw3270_read_modified_cb(struct raw3270_request *rq, void *data)
 566{
 567        struct raw3270 *rp = rq->view->dev;
 568
 569        raw3270_size_device(rp);
 570        raw3270_size_device_done(rp);
 571}
 572
 573static void
 574raw3270_read_modified(struct raw3270 *rp)
 575{
 576        if (rp->state != RAW3270_STATE_W4ATTN)
 577                return;
 578        /* Use 'read modified' to get the result of a read partition. */
 579        memset(&rp->init_readmod, 0, sizeof(rp->init_readmod));
 580        memset(&rp->init_data, 0, sizeof(rp->init_data));
 581        rp->init_readmod.ccw.cmd_code = TC_READMOD;
 582        rp->init_readmod.ccw.flags = CCW_FLAG_SLI;
 583        rp->init_readmod.ccw.count = sizeof(rp->init_data);
 584        rp->init_readmod.ccw.cda = (__u32) __pa(rp->init_data);
 585        rp->init_readmod.callback = raw3270_read_modified_cb;
 586        rp->state = RAW3270_STATE_READMOD;
 587        raw3270_start_irq(&rp->init_view, &rp->init_readmod);
 588}
 589
 590static void
 591raw3270_writesf_readpart(struct raw3270 *rp)
 592{
 593        static const unsigned char wbuf[] =
 594                { 0x00, 0x07, 0x01, 0xff, 0x03, 0x00, 0x81 };
 595
 596        /* Store 'read partition' data stream to init_data */
 597        memset(&rp->init_readpart, 0, sizeof(rp->init_readpart));
 598        memset(&rp->init_data, 0, sizeof(rp->init_data));
 599        memcpy(&rp->init_data, wbuf, sizeof(wbuf));
 600        rp->init_readpart.ccw.cmd_code = TC_WRITESF;
 601        rp->init_readpart.ccw.flags = CCW_FLAG_SLI;
 602        rp->init_readpart.ccw.count = sizeof(wbuf);
 603        rp->init_readpart.ccw.cda = (__u32) __pa(&rp->init_data);
 604        rp->state = RAW3270_STATE_W4ATTN;
 605        raw3270_start_irq(&rp->init_view, &rp->init_readpart);
 606}
 607
 608/*
 609 * Device reset
 610 */
 611static void
 612raw3270_reset_device_cb(struct raw3270_request *rq, void *data)
 613{
 614        struct raw3270 *rp = rq->view->dev;
 615
 616        if (rp->state != RAW3270_STATE_RESET)
 617                return;
 618        if (rq && rq->rc) {
 619                /* Reset command failed. */
 620                rp->state = RAW3270_STATE_INIT;
 621        } else if (0 && MACHINE_IS_VM) {
 622                raw3270_size_device_vm(rp);
 623                raw3270_size_device_done(rp);
 624        } else
 625                raw3270_writesf_readpart(rp);
 626}
 627
 628static int
 629__raw3270_reset_device(struct raw3270 *rp)
 630{
 631        int rc;
 632
 633        /* Store reset data stream to init_data/init_reset */
 634        memset(&rp->init_reset, 0, sizeof(rp->init_reset));
 635        memset(&rp->init_data, 0, sizeof(rp->init_data));
 636        rp->init_data[0] = TW_KR;
 637        rp->init_reset.ccw.cmd_code = TC_EWRITEA;
 638        rp->init_reset.ccw.flags = CCW_FLAG_SLI;
 639        rp->init_reset.ccw.count = 1;
 640        rp->init_reset.ccw.cda = (__u32) __pa(rp->init_data);
 641        rp->init_reset.callback = raw3270_reset_device_cb;
 642        rc = __raw3270_start(rp, &rp->init_view, &rp->init_reset);
 643        if (rc == 0 && rp->state == RAW3270_STATE_INIT)
 644                rp->state = RAW3270_STATE_RESET;
 645        return rc;
 646}
 647
 648static int
 649raw3270_reset_device(struct raw3270 *rp)
 650{
 651        unsigned long flags;
 652        int rc;
 653
 654        spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
 655        rc = __raw3270_reset_device(rp);
 656        spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 657        return rc;
 658}
 659
 660int
 661raw3270_reset(struct raw3270_view *view)
 662{
 663        struct raw3270 *rp;
 664        int rc;
 665
 666        rp = view->dev;
 667        if (!rp || rp->view != view ||
 668            test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
 669                rc = -EACCES;
 670        else if (!raw3270_state_ready(rp))
 671                rc = -EBUSY;
 672        else
 673                rc = raw3270_reset_device(view->dev);
 674        return rc;
 675}
 676
 677static int
 678raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq,
 679                 struct irb *irb)
 680{
 681        struct raw3270 *rp;
 682
 683        /*
 684         * Unit-Check Processing:
 685         * Expect Command Reject or Intervention Required.
 686         */
 687        if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
 688                /* Request finished abnormally. */
 689                if (irb->ecw[0] & SNS0_INTERVENTION_REQ) {
 690                        set_bit(RAW3270_FLAGS_BUSY, &view->dev->flags);
 691                        return RAW3270_IO_BUSY;
 692                }
 693        }
 694        if (rq) {
 695                if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
 696                        if (irb->ecw[0] & SNS0_CMD_REJECT)
 697                                rq->rc = -EOPNOTSUPP;
 698                        else
 699                                rq->rc = -EIO;
 700                }
 701        }
 702        if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
 703                /* Queue read modified after attention interrupt */
 704                rp = view->dev;
 705                raw3270_read_modified(rp);
 706        }
 707        return RAW3270_IO_DONE;
 708}
 709
 710static struct raw3270_fn raw3270_init_fn = {
 711        .intv = raw3270_init_irq
 712};
 713
 714/*
 715 * Setup new 3270 device.
 716 */
 717static int
 718raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
 719{
 720        struct list_head *l;
 721        struct raw3270 *tmp;
 722        int minor;
 723
 724        memset(rp, 0, sizeof(struct raw3270));
 725        /* Copy ebcdic -> ascii translation table. */
 726        memcpy(ascebc, _ascebc, 256);
 727        if (tubxcorrect) {
 728                /* correct brackets and circumflex */
 729                ascebc['['] = 0xad;
 730                ascebc[']'] = 0xbd;
 731                ascebc['^'] = 0xb0;
 732        }
 733        rp->ascebc = ascebc;
 734
 735        /* Set defaults. */
 736        rp->rows = 24;
 737        rp->cols = 80;
 738
 739        INIT_LIST_HEAD(&rp->req_queue);
 740        INIT_LIST_HEAD(&rp->view_list);
 741
 742        rp->init_view.dev = rp;
 743        rp->init_view.fn = &raw3270_init_fn;
 744        rp->view = &rp->init_view;
 745
 746        /*
 747         * Add device to list and find the smallest unused minor
 748         * number for it. Note: there is no device with minor 0,
 749         * see special case for fs3270.c:fs3270_open().
 750         */
 751        mutex_lock(&raw3270_mutex);
 752        /* Keep the list sorted. */
 753        minor = RAW3270_FIRSTMINOR;
 754        rp->minor = -1;
 755        list_for_each(l, &raw3270_devices) {
 756                tmp = list_entry(l, struct raw3270, list);
 757                if (tmp->minor > minor) {
 758                        rp->minor = minor;
 759                        __list_add(&rp->list, l->prev, l);
 760                        break;
 761                }
 762                minor++;
 763        }
 764        if (rp->minor == -1 && minor < RAW3270_MAXDEVS + RAW3270_FIRSTMINOR) {
 765                rp->minor = minor;
 766                list_add_tail(&rp->list, &raw3270_devices);
 767        }
 768        mutex_unlock(&raw3270_mutex);
 769        /* No free minor number? Then give up. */
 770        if (rp->minor == -1)
 771                return -EUSERS;
 772        rp->cdev = cdev;
 773        dev_set_drvdata(&cdev->dev, rp);
 774        cdev->handler = raw3270_irq;
 775        return 0;
 776}
 777
 778#ifdef CONFIG_TN3270_CONSOLE
 779/*
 780 * Setup 3270 device configured as console.
 781 */
 782struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev)
 783{
 784        unsigned long flags;
 785        struct raw3270 *rp;
 786        char *ascebc;
 787        int rc;
 788
 789        rp = kzalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA);
 790        ascebc = kzalloc(256, GFP_KERNEL);
 791        rc = raw3270_setup_device(cdev, rp, ascebc);
 792        if (rc)
 793                return ERR_PTR(rc);
 794        set_bit(RAW3270_FLAGS_CONSOLE, &rp->flags);
 795        spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
 796        do {
 797                __raw3270_reset_device(rp);
 798                while (!raw3270_state_final(rp)) {
 799                        ccw_device_wait_idle(rp->cdev);
 800                        barrier();
 801                }
 802        } while (rp->state != RAW3270_STATE_READY);
 803        spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 804        return rp;
 805}
 806
 807void
 808raw3270_wait_cons_dev(struct raw3270 *rp)
 809{
 810        unsigned long flags;
 811
 812        spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
 813        ccw_device_wait_idle(rp->cdev);
 814        spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 815}
 816
 817#endif
 818
 819/*
 820 * Create a 3270 device structure.
 821 */
 822static struct raw3270 *
 823raw3270_create_device(struct ccw_device *cdev)
 824{
 825        struct raw3270 *rp;
 826        char *ascebc;
 827        int rc;
 828
 829        rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA);
 830        if (!rp)
 831                return ERR_PTR(-ENOMEM);
 832        ascebc = kmalloc(256, GFP_KERNEL);
 833        if (!ascebc) {
 834                kfree(rp);
 835                return ERR_PTR(-ENOMEM);
 836        }
 837        rc = raw3270_setup_device(cdev, rp, ascebc);
 838        if (rc) {
 839                kfree(rp->ascebc);
 840                kfree(rp);
 841                rp = ERR_PTR(rc);
 842        }
 843        /* Get reference to ccw_device structure. */
 844        get_device(&cdev->dev);
 845        return rp;
 846}
 847
 848/*
 849 * Activate a view.
 850 */
 851int
 852raw3270_activate_view(struct raw3270_view *view)
 853{
 854        struct raw3270 *rp;
 855        struct raw3270_view *oldview, *nv;
 856        unsigned long flags;
 857        int rc;
 858
 859        rp = view->dev;
 860        if (!rp)
 861                return -ENODEV;
 862        spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
 863        if (rp->view == view)
 864                rc = 0;
 865        else if (!raw3270_state_ready(rp))
 866                rc = -EBUSY;
 867        else if (test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
 868                rc = -EACCES;
 869        else {
 870                oldview = NULL;
 871                if (rp->view && rp->view->fn->deactivate) {
 872                        oldview = rp->view;
 873                        oldview->fn->deactivate(oldview);
 874                }
 875                rp->view = view;
 876                rc = view->fn->activate(view);
 877                if (rc) {
 878                        /* Didn't work. Try to reactivate the old view. */
 879                        rp->view = oldview;
 880                        if (!oldview || oldview->fn->activate(oldview) != 0) {
 881                                /* Didn't work as well. Try any other view. */
 882                                list_for_each_entry(nv, &rp->view_list, list)
 883                                        if (nv != view && nv != oldview) {
 884                                                rp->view = nv;
 885                                                if (nv->fn->activate(nv) == 0)
 886                                                        break;
 887                                                rp->view = NULL;
 888                                        }
 889                        }
 890                }
 891        }
 892        spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 893        return rc;
 894}
 895
 896/*
 897 * Deactivate current view.
 898 */
 899void
 900raw3270_deactivate_view(struct raw3270_view *view)
 901{
 902        unsigned long flags;
 903        struct raw3270 *rp;
 904
 905        rp = view->dev;
 906        if (!rp)
 907                return;
 908        spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
 909        if (rp->view == view) {
 910                view->fn->deactivate(view);
 911                rp->view = NULL;
 912                /* Move deactivated view to end of list. */
 913                list_del_init(&view->list);
 914                list_add_tail(&view->list, &rp->view_list);
 915                /* Try to activate another view. */
 916                if (raw3270_state_ready(rp) &&
 917                    !test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) {
 918                        list_for_each_entry(view, &rp->view_list, list) {
 919                                rp->view = view;
 920                                if (view->fn->activate(view) == 0)
 921                                        break;
 922                                rp->view = NULL;
 923                        }
 924                }
 925        }
 926        spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 927}
 928
 929/*
 930 * Add view to device with minor "minor".
 931 */
 932int
 933raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
 934{
 935        unsigned long flags;
 936        struct raw3270 *rp;
 937        int rc;
 938
 939        if (minor <= 0)
 940                return -ENODEV;
 941        mutex_lock(&raw3270_mutex);
 942        rc = -ENODEV;
 943        list_for_each_entry(rp, &raw3270_devices, list) {
 944                if (rp->minor != minor)
 945                        continue;
 946                spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
 947                atomic_set(&view->ref_count, 2);
 948                view->dev = rp;
 949                view->fn = fn;
 950                view->model = rp->model;
 951                view->rows = rp->rows;
 952                view->cols = rp->cols;
 953                view->ascebc = rp->ascebc;
 954                spin_lock_init(&view->lock);
 955                list_add(&view->list, &rp->view_list);
 956                rc = 0;
 957                spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 958                break;
 959        }
 960        mutex_unlock(&raw3270_mutex);
 961        return rc;
 962}
 963
 964/*
 965 * Find specific view of device with minor "minor".
 966 */
 967struct raw3270_view *
 968raw3270_find_view(struct raw3270_fn *fn, int minor)
 969{
 970        struct raw3270 *rp;
 971        struct raw3270_view *view, *tmp;
 972        unsigned long flags;
 973
 974        mutex_lock(&raw3270_mutex);
 975        view = ERR_PTR(-ENODEV);
 976        list_for_each_entry(rp, &raw3270_devices, list) {
 977                if (rp->minor != minor)
 978                        continue;
 979                spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
 980                list_for_each_entry(tmp, &rp->view_list, list) {
 981                        if (tmp->fn == fn) {
 982                                raw3270_get_view(tmp);
 983                                view = tmp;
 984                                break;
 985                        }
 986                }
 987                spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 988                break;
 989        }
 990        mutex_unlock(&raw3270_mutex);
 991        return view;
 992}
 993
 994/*
 995 * Remove view from device and free view structure via call to view->fn->free.
 996 */
 997void
 998raw3270_del_view(struct raw3270_view *view)
 999{
1000        unsigned long flags;
1001        struct raw3270 *rp;
1002        struct raw3270_view *nv;
1003
1004        rp = view->dev;
1005        spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1006        if (rp->view == view) {
1007                view->fn->deactivate(view);
1008                rp->view = NULL;
1009        }
1010        list_del_init(&view->list);
1011        if (!rp->view && raw3270_state_ready(rp) &&
1012            !test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) {
1013                /* Try to activate another view. */
1014                list_for_each_entry(nv, &rp->view_list, list) {
1015                        if (nv->fn->activate(nv) == 0) {
1016                                rp->view = nv;
1017                                break;
1018                        }
1019                }
1020        }
1021        spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1022        /* Wait for reference counter to drop to zero. */
1023        atomic_dec(&view->ref_count);
1024        wait_event(raw3270_wait_queue, atomic_read(&view->ref_count) == 0);
1025        if (view->fn->free)
1026                view->fn->free(view);
1027}
1028
1029/*
1030 * Remove a 3270 device structure.
1031 */
1032static void
1033raw3270_delete_device(struct raw3270 *rp)
1034{
1035        struct ccw_device *cdev;
1036
1037        /* Remove from device chain. */
1038        mutex_lock(&raw3270_mutex);
1039        list_del_init(&rp->list);
1040        mutex_unlock(&raw3270_mutex);
1041
1042        /* Disconnect from ccw_device. */
1043        cdev = rp->cdev;
1044        rp->cdev = NULL;
1045        dev_set_drvdata(&cdev->dev, NULL);
1046        cdev->handler = NULL;
1047
1048        /* Put ccw_device structure. */
1049        put_device(&cdev->dev);
1050
1051        /* Now free raw3270 structure. */
1052        kfree(rp->ascebc);
1053        kfree(rp);
1054}
1055
1056static int
1057raw3270_probe (struct ccw_device *cdev)
1058{
1059        return 0;
1060}
1061
1062/*
1063 * Additional attributes for a 3270 device
1064 */
1065static ssize_t
1066raw3270_model_show(struct device *dev, struct device_attribute *attr, char *buf)
1067{
1068        return snprintf(buf, PAGE_SIZE, "%i\n",
1069                        ((struct raw3270 *) dev_get_drvdata(dev))->model);
1070}
1071static DEVICE_ATTR(model, 0444, raw3270_model_show, NULL);
1072
1073static ssize_t
1074raw3270_rows_show(struct device *dev, struct device_attribute *attr, char *buf)
1075{
1076        return snprintf(buf, PAGE_SIZE, "%i\n",
1077                        ((struct raw3270 *) dev_get_drvdata(dev))->rows);
1078}
1079static DEVICE_ATTR(rows, 0444, raw3270_rows_show, NULL);
1080
1081static ssize_t
1082raw3270_columns_show(struct device *dev, struct device_attribute *attr, char *buf)
1083{
1084        return snprintf(buf, PAGE_SIZE, "%i\n",
1085                        ((struct raw3270 *) dev_get_drvdata(dev))->cols);
1086}
1087static DEVICE_ATTR(columns, 0444, raw3270_columns_show, NULL);
1088
1089static struct attribute * raw3270_attrs[] = {
1090        &dev_attr_model.attr,
1091        &dev_attr_rows.attr,
1092        &dev_attr_columns.attr,
1093        NULL,
1094};
1095
1096static struct attribute_group raw3270_attr_group = {
1097        .attrs = raw3270_attrs,
1098};
1099
1100static int raw3270_create_attributes(struct raw3270 *rp)
1101{
1102        return sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
1103}
1104
1105/*
1106 * Notifier for device addition/removal
1107 */
1108static LIST_HEAD(raw3270_notifier);
1109
1110int raw3270_register_notifier(struct raw3270_notifier *notifier)
1111{
1112        struct raw3270 *rp;
1113
1114        mutex_lock(&raw3270_mutex);
1115        list_add_tail(&notifier->list, &raw3270_notifier);
1116        list_for_each_entry(rp, &raw3270_devices, list)
1117                notifier->create(rp->minor);
1118        mutex_unlock(&raw3270_mutex);
1119        return 0;
1120}
1121
1122void raw3270_unregister_notifier(struct raw3270_notifier *notifier)
1123{
1124        struct raw3270 *rp;
1125
1126        mutex_lock(&raw3270_mutex);
1127        list_for_each_entry(rp, &raw3270_devices, list)
1128                notifier->destroy(rp->minor);
1129        list_del(&notifier->list);
1130        mutex_unlock(&raw3270_mutex);
1131}
1132
1133/*
1134 * Set 3270 device online.
1135 */
1136static int
1137raw3270_set_online (struct ccw_device *cdev)
1138{
1139        struct raw3270_notifier *np;
1140        struct raw3270 *rp;
1141        int rc;
1142
1143        rp = raw3270_create_device(cdev);
1144        if (IS_ERR(rp))
1145                return PTR_ERR(rp);
1146        rc = raw3270_create_attributes(rp);
1147        if (rc)
1148                goto failure;
1149        raw3270_reset_device(rp);
1150        mutex_lock(&raw3270_mutex);
1151        list_for_each_entry(np, &raw3270_notifier, list)
1152                np->create(rp->minor);
1153        mutex_unlock(&raw3270_mutex);
1154        return 0;
1155
1156failure:
1157        raw3270_delete_device(rp);
1158        return rc;
1159}
1160
1161/*
1162 * Remove 3270 device structure.
1163 */
1164static void
1165raw3270_remove (struct ccw_device *cdev)
1166{
1167        unsigned long flags;
1168        struct raw3270 *rp;
1169        struct raw3270_view *v;
1170        struct raw3270_notifier *np;
1171
1172        rp = dev_get_drvdata(&cdev->dev);
1173        /*
1174         * _remove is the opposite of _probe; it's probe that
1175         * should set up rp.  raw3270_remove gets entered for
1176         * devices even if they haven't been varied online.
1177         * Thus, rp may validly be NULL here.
1178         */
1179        if (rp == NULL)
1180                return;
1181
1182        sysfs_remove_group(&cdev->dev.kobj, &raw3270_attr_group);
1183
1184        /* Deactivate current view and remove all views. */
1185        spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
1186        if (rp->view) {
1187                if (rp->view->fn->deactivate)
1188                        rp->view->fn->deactivate(rp->view);
1189                rp->view = NULL;
1190        }
1191        while (!list_empty(&rp->view_list)) {
1192                v = list_entry(rp->view_list.next, struct raw3270_view, list);
1193                if (v->fn->release)
1194                        v->fn->release(v);
1195                spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
1196                raw3270_del_view(v);
1197                spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
1198        }
1199        spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
1200
1201        mutex_lock(&raw3270_mutex);
1202        list_for_each_entry(np, &raw3270_notifier, list)
1203                np->destroy(rp->minor);
1204        mutex_unlock(&raw3270_mutex);
1205
1206        /* Reset 3270 device. */
1207        raw3270_reset_device(rp);
1208        /* And finally remove it. */
1209        raw3270_delete_device(rp);
1210}
1211
1212/*
1213 * Set 3270 device offline.
1214 */
1215static int
1216raw3270_set_offline (struct ccw_device *cdev)
1217{
1218        struct raw3270 *rp;
1219
1220        rp = dev_get_drvdata(&cdev->dev);
1221        if (test_bit(RAW3270_FLAGS_CONSOLE, &rp->flags))
1222                return -EBUSY;
1223        raw3270_remove(cdev);
1224        return 0;
1225}
1226
1227static int raw3270_pm_stop(struct ccw_device *cdev)
1228{
1229        struct raw3270 *rp;
1230        struct raw3270_view *view;
1231        unsigned long flags;
1232
1233        rp = dev_get_drvdata(&cdev->dev);
1234        if (!rp)
1235                return 0;
1236        spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1237        if (rp->view && rp->view->fn->deactivate)
1238                rp->view->fn->deactivate(rp->view);
1239        if (!test_bit(RAW3270_FLAGS_CONSOLE, &rp->flags)) {
1240                /*
1241                 * Release tty and fullscreen for all non-console
1242                 * devices.
1243                 */
1244                list_for_each_entry(view, &rp->view_list, list) {
1245                        if (view->fn->release)
1246                                view->fn->release(view);
1247                }
1248        }
1249        set_bit(RAW3270_FLAGS_FROZEN, &rp->flags);
1250        spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1251        return 0;
1252}
1253
1254static int raw3270_pm_start(struct ccw_device *cdev)
1255{
1256        struct raw3270 *rp;
1257        unsigned long flags;
1258
1259        rp = dev_get_drvdata(&cdev->dev);
1260        if (!rp)
1261                return 0;
1262        spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1263        clear_bit(RAW3270_FLAGS_FROZEN, &rp->flags);
1264        if (rp->view && rp->view->fn->activate)
1265                rp->view->fn->activate(rp->view);
1266        spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1267        return 0;
1268}
1269
1270void raw3270_pm_unfreeze(struct raw3270_view *view)
1271{
1272#ifdef CONFIG_TN3270_CONSOLE
1273        struct raw3270 *rp;
1274
1275        rp = view->dev;
1276        if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
1277                ccw_device_force_console(rp->cdev);
1278#endif
1279}
1280
1281static struct ccw_device_id raw3270_id[] = {
1282        { CCW_DEVICE(0x3270, 0) },
1283        { CCW_DEVICE(0x3271, 0) },
1284        { CCW_DEVICE(0x3272, 0) },
1285        { CCW_DEVICE(0x3273, 0) },
1286        { CCW_DEVICE(0x3274, 0) },
1287        { CCW_DEVICE(0x3275, 0) },
1288        { CCW_DEVICE(0x3276, 0) },
1289        { CCW_DEVICE(0x3277, 0) },
1290        { CCW_DEVICE(0x3278, 0) },
1291        { CCW_DEVICE(0x3279, 0) },
1292        { CCW_DEVICE(0x3174, 0) },
1293        { /* end of list */ },
1294};
1295
1296static struct ccw_driver raw3270_ccw_driver = {
1297        .driver = {
1298                .name   = "3270",
1299                .owner  = THIS_MODULE,
1300        },
1301        .ids            = raw3270_id,
1302        .probe          = &raw3270_probe,
1303        .remove         = &raw3270_remove,
1304        .set_online     = &raw3270_set_online,
1305        .set_offline    = &raw3270_set_offline,
1306        .freeze         = &raw3270_pm_stop,
1307        .thaw           = &raw3270_pm_start,
1308        .restore        = &raw3270_pm_start,
1309        .int_class      = IRQIO_C70,
1310};
1311
1312static int
1313raw3270_init(void)
1314{
1315        struct raw3270 *rp;
1316        int rc;
1317
1318        if (raw3270_registered)
1319                return 0;
1320        raw3270_registered = 1;
1321        rc = ccw_driver_register(&raw3270_ccw_driver);
1322        if (rc == 0) {
1323                /* Create attributes for early (= console) device. */
1324                mutex_lock(&raw3270_mutex);
1325                class3270 = class_create(THIS_MODULE, "3270");
1326                list_for_each_entry(rp, &raw3270_devices, list) {
1327                        get_device(&rp->cdev->dev);
1328                        raw3270_create_attributes(rp);
1329                }
1330                mutex_unlock(&raw3270_mutex);
1331        }
1332        return rc;
1333}
1334
1335static void
1336raw3270_exit(void)
1337{
1338        ccw_driver_unregister(&raw3270_ccw_driver);
1339        class_destroy(class3270);
1340}
1341
1342MODULE_LICENSE("GPL");
1343
1344module_init(raw3270_init);
1345module_exit(raw3270_exit);
1346
1347EXPORT_SYMBOL(class3270);
1348EXPORT_SYMBOL(raw3270_request_alloc);
1349EXPORT_SYMBOL(raw3270_request_free);
1350EXPORT_SYMBOL(raw3270_request_reset);
1351EXPORT_SYMBOL(raw3270_request_set_cmd);
1352EXPORT_SYMBOL(raw3270_request_add_data);
1353EXPORT_SYMBOL(raw3270_request_set_data);
1354EXPORT_SYMBOL(raw3270_request_set_idal);
1355EXPORT_SYMBOL(raw3270_buffer_address);
1356EXPORT_SYMBOL(raw3270_add_view);
1357EXPORT_SYMBOL(raw3270_del_view);
1358EXPORT_SYMBOL(raw3270_find_view);
1359EXPORT_SYMBOL(raw3270_activate_view);
1360EXPORT_SYMBOL(raw3270_deactivate_view);
1361EXPORT_SYMBOL(raw3270_start);
1362EXPORT_SYMBOL(raw3270_start_locked);
1363EXPORT_SYMBOL(raw3270_start_irq);
1364EXPORT_SYMBOL(raw3270_reset);
1365EXPORT_SYMBOL(raw3270_register_notifier);
1366EXPORT_SYMBOL(raw3270_unregister_notifier);
1367EXPORT_SYMBOL(raw3270_wait_queue);
1368