linux/drivers/s390/char/raw3270.h
<<
>>
Prefs
   1/*
   2 *  drivers/s390/char/raw3270.h
   3 *    IBM/3270 Driver
   4 *
   5 *  Author(s):
   6 *    Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
   7 *    Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
   8 *      -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
   9 */
  10
  11#include <asm/idals.h>
  12#include <asm/ioctl.h>
  13
  14/* ioctls for fullscreen 3270 */
  15#define TUBICMD         _IO('3', 3)     /* set ccw command for fs reads. */
  16#define TUBOCMD         _IO('3', 4)     /* set ccw command for fs writes. */
  17#define TUBGETI         _IO('3', 7)     /* get ccw command for fs reads. */
  18#define TUBGETO         _IO('3', 8)     /* get ccw command for fs writes. */
  19#define TUBSETMOD       _IO('3',12)     /* FIXME: what does it do ?*/
  20#define TUBGETMOD       _IO('3',13)     /* FIXME: what does it do ?*/
  21
  22/* Local Channel Commands */
  23#define TC_WRITE        0x01            /* Write */
  24#define TC_RDBUF        0x02            /* Read Buffer */
  25#define TC_EWRITE       0x05            /* Erase write */
  26#define TC_READMOD      0x06            /* Read modified */
  27#define TC_EWRITEA      0x0d            /* Erase write alternate */
  28#define TC_WRITESF      0x11            /* Write structured field */
  29
  30/* Buffer Control Orders */
  31#define TO_SF           0x1d            /* Start field */
  32#define TO_SBA          0x11            /* Set buffer address */
  33#define TO_IC           0x13            /* Insert cursor */
  34#define TO_PT           0x05            /* Program tab */
  35#define TO_RA           0x3c            /* Repeat to address */
  36#define TO_SFE          0x29            /* Start field extended */
  37#define TO_EUA          0x12            /* Erase unprotected to address */
  38#define TO_MF           0x2c            /* Modify field */
  39#define TO_SA           0x28            /* Set attribute */
  40
  41/* Field Attribute Bytes */
  42#define TF_INPUT        0x40            /* Visible input */
  43#define TF_INPUTN       0x4c            /* Invisible input */
  44#define TF_INMDT        0xc1            /* Visible, Set-MDT */
  45#define TF_LOG          0x60
  46
  47/* Character Attribute Bytes */
  48#define TAT_RESET       0x00
  49#define TAT_FIELD       0xc0
  50#define TAT_EXTHI       0x41
  51#define TAT_COLOR       0x42
  52#define TAT_CHARS       0x43
  53#define TAT_TRANS       0x46
  54
  55/* Extended-Highlighting Bytes */
  56#define TAX_RESET       0x00
  57#define TAX_BLINK       0xf1
  58#define TAX_REVER       0xf2
  59#define TAX_UNDER       0xf4
  60
  61/* Reset value */
  62#define TAR_RESET       0x00
  63
  64/* Color values */
  65#define TAC_RESET       0x00
  66#define TAC_BLUE        0xf1
  67#define TAC_RED         0xf2
  68#define TAC_PINK        0xf3
  69#define TAC_GREEN       0xf4
  70#define TAC_TURQ        0xf5
  71#define TAC_YELLOW      0xf6
  72#define TAC_WHITE       0xf7
  73#define TAC_DEFAULT     0x00
  74
  75/* Write Control Characters */
  76#define TW_NONE         0x40            /* No particular action */
  77#define TW_KR           0xc2            /* Keyboard restore */
  78#define TW_PLUSALARM    0x04            /* Add this bit for alarm */
  79
  80#define RAW3270_FIRSTMINOR      1       /* First minor number */
  81#define RAW3270_MAXDEVS         255     /* Max number of 3270 devices */
  82
  83/* For TUBGETMOD and TUBSETMOD. Should include. */
  84struct raw3270_iocb {
  85        short model;
  86        short line_cnt;
  87        short col_cnt;
  88        short pf_cnt;
  89        short re_cnt;
  90        short map;
  91};
  92
  93struct raw3270;
  94struct raw3270_view;
  95
  96/* 3270 CCW request */
  97struct raw3270_request {
  98        struct list_head list;          /* list head for request queueing. */
  99        struct raw3270_view *view;      /* view of this request */
 100        struct ccw1 ccw;                /* single ccw. */
 101        void *buffer;                   /* output buffer. */
 102        size_t size;                    /* size of output buffer. */
 103        int rescnt;                     /* residual count from devstat. */
 104        int rc;                         /* return code for this request. */
 105
 106        /* Callback for delivering final status. */
 107        void (*callback)(struct raw3270_request *, void *);
 108        void *callback_data;
 109};
 110
 111struct raw3270_request *raw3270_request_alloc(size_t size);
 112struct raw3270_request *raw3270_request_alloc_bootmem(size_t size);
 113void raw3270_request_free(struct raw3270_request *);
 114void raw3270_request_reset(struct raw3270_request *);
 115void raw3270_request_set_cmd(struct raw3270_request *, u8 cmd);
 116int  raw3270_request_add_data(struct raw3270_request *, void *, size_t);
 117void raw3270_request_set_data(struct raw3270_request *, void *, size_t);
 118void raw3270_request_set_idal(struct raw3270_request *, struct idal_buffer *);
 119
 120static inline int
 121raw3270_request_final(struct raw3270_request *rq)
 122{
 123        return list_empty(&rq->list);
 124}
 125
 126void raw3270_buffer_address(struct raw3270 *, char *, unsigned short);
 127
 128/* Return value of *intv (see raw3270_fn below) can be one of the following: */
 129#define RAW3270_IO_DONE         0       /* request finished */
 130#define RAW3270_IO_BUSY         1       /* request still active */
 131#define RAW3270_IO_RETRY        2       /* retry current request */
 132#define RAW3270_IO_STOP         3       /* kill current request */
 133
 134/*
 135 * Functions of a 3270 view.
 136 */
 137struct raw3270_fn {
 138        int  (*activate)(struct raw3270_view *);
 139        void (*deactivate)(struct raw3270_view *);
 140        int  (*intv)(struct raw3270_view *,
 141                     struct raw3270_request *, struct irb *);
 142        void (*release)(struct raw3270_view *);
 143        void (*free)(struct raw3270_view *);
 144};
 145
 146/*
 147 * View structure chaining. The raw3270_view structure is meant to
 148 * be embedded at the start of the real view data structure, e.g.:
 149 *   struct example {
 150 *     struct raw3270_view view;
 151 *     ...
 152 *   };
 153 */
 154struct raw3270_view {
 155        struct list_head list;
 156        spinlock_t lock;
 157        atomic_t ref_count;
 158        struct raw3270 *dev;
 159        struct raw3270_fn *fn;
 160        unsigned int model;
 161        unsigned int rows, cols;        /* # of rows & colums of the view */
 162        unsigned char *ascebc;          /* ascii -> ebcdic table */
 163};
 164
 165int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int);
 166int raw3270_activate_view(struct raw3270_view *);
 167void raw3270_del_view(struct raw3270_view *);
 168void raw3270_deactivate_view(struct raw3270_view *);
 169struct raw3270_view *raw3270_find_view(struct raw3270_fn *, int);
 170int raw3270_start(struct raw3270_view *, struct raw3270_request *);
 171int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *);
 172int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *);
 173int raw3270_reset(struct raw3270_view *);
 174struct raw3270_view *raw3270_view(struct raw3270_view *);
 175
 176/* Reference count inliner for view structures. */
 177static inline void
 178raw3270_get_view(struct raw3270_view *view)
 179{
 180        atomic_inc(&view->ref_count);
 181}
 182
 183extern wait_queue_head_t raw3270_wait_queue;
 184
 185static inline void
 186raw3270_put_view(struct raw3270_view *view)
 187{
 188        if (atomic_dec_return(&view->ref_count) == 0)
 189                wake_up(&raw3270_wait_queue);
 190}
 191
 192struct raw3270 *raw3270_setup_console(struct ccw_device *cdev);
 193void raw3270_wait_cons_dev(struct raw3270 *);
 194
 195/* Notifier for device addition/removal */
 196int raw3270_register_notifier(void (*notifier)(int, int));
 197void raw3270_unregister_notifier(void (*notifier)(int, int));
 198
 199/*
 200 * Little memory allocator for string objects. 
 201 */
 202struct string
 203{
 204        struct list_head list;
 205        struct list_head update;
 206        unsigned long size;
 207        unsigned long len;
 208        char string[0];
 209} __attribute__ ((aligned(8)));
 210
 211static inline struct string *
 212alloc_string(struct list_head *free_list, unsigned long len)
 213{
 214        struct string *cs, *tmp;
 215        unsigned long size;
 216
 217        size = (len + 7L) & -8L;
 218        list_for_each_entry(cs, free_list, list) {
 219                if (cs->size < size)
 220                        continue;
 221                if (cs->size > size + sizeof(struct string)) {
 222                        char *endaddr = (char *) (cs + 1) + cs->size;
 223                        tmp = (struct string *) (endaddr - size) - 1;
 224                        tmp->size = size;
 225                        cs->size -= size + sizeof(struct string);
 226                        cs = tmp;
 227                } else
 228                        list_del(&cs->list);
 229                cs->len = len;
 230                INIT_LIST_HEAD(&cs->list);
 231                INIT_LIST_HEAD(&cs->update);
 232                return cs;
 233        }
 234        return NULL;
 235}
 236
 237static inline unsigned long
 238free_string(struct list_head *free_list, struct string *cs)
 239{
 240        struct string *tmp;
 241        struct list_head *p, *left;
 242
 243        /* Find out the left neighbour in free memory list. */
 244        left = free_list;
 245        list_for_each(p, free_list) {
 246                if (list_entry(p, struct string, list) > cs)
 247                        break;
 248                left = p;
 249        }
 250        /* Try to merge with right neighbour = next element from left. */
 251        if (left->next != free_list) {
 252                tmp = list_entry(left->next, struct string, list);
 253                if ((char *) (cs + 1) + cs->size == (char *) tmp) {
 254                        list_del(&tmp->list);
 255                        cs->size += tmp->size + sizeof(struct string);
 256                }
 257        }
 258        /* Try to merge with left neighbour. */
 259        if (left != free_list) {
 260                tmp = list_entry(left, struct string, list);
 261                if ((char *) (tmp + 1) + tmp->size == (char *) cs) {
 262                        tmp->size += cs->size + sizeof(struct string);
 263                        return tmp->size;
 264                }
 265        }
 266        __list_add(&cs->list, left, left->next);
 267        return cs->size;
 268}
 269
 270static inline void
 271add_string_memory(struct list_head *free_list, void *mem, unsigned long size)
 272{
 273        struct string *cs;
 274
 275        cs = (struct string *) mem;
 276        cs->size = size - sizeof(struct string);
 277        free_string(free_list, cs);
 278}
 279
 280