linux/drivers/s390/char/raw3270.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   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 IBM Corp. 2003, 2009
   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;
  95extern struct class *class3270;
  96
  97/* 3270 CCW request */
  98struct raw3270_request {
  99        struct list_head list;          /* list head for request queueing. */
 100        struct raw3270_view *view;      /* view of this request */
 101        struct ccw1 ccw;                /* single ccw. */
 102        void *buffer;                   /* output buffer. */
 103        size_t size;                    /* size of output buffer. */
 104        int rescnt;                     /* residual count from devstat. */
 105        int rc;                         /* return code for this request. */
 106
 107        /* Callback for delivering final status. */
 108        void (*callback)(struct raw3270_request *, void *);
 109        void *callback_data;
 110};
 111
 112struct raw3270_request *raw3270_request_alloc(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/*
 129 * Functions of a 3270 view.
 130 */
 131struct raw3270_fn {
 132        int  (*activate)(struct raw3270_view *);
 133        void (*deactivate)(struct raw3270_view *);
 134        void (*intv)(struct raw3270_view *,
 135                     struct raw3270_request *, struct irb *);
 136        void (*release)(struct raw3270_view *);
 137        void (*free)(struct raw3270_view *);
 138        void (*resize)(struct raw3270_view *, int, int, int);
 139};
 140
 141/*
 142 * View structure chaining. The raw3270_view structure is meant to
 143 * be embedded at the start of the real view data structure, e.g.:
 144 *   struct example {
 145 *     struct raw3270_view view;
 146 *     ...
 147 *   };
 148 */
 149struct raw3270_view {
 150        struct list_head list;
 151        spinlock_t lock;
 152#define RAW3270_VIEW_LOCK_IRQ   0
 153#define RAW3270_VIEW_LOCK_BH    1
 154        atomic_t ref_count;
 155        struct raw3270 *dev;
 156        struct raw3270_fn *fn;
 157        unsigned int model;
 158        unsigned int rows, cols;        /* # of rows & colums of the view */
 159        unsigned char *ascebc;          /* ascii -> ebcdic table */
 160};
 161
 162int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int, int);
 163int raw3270_activate_view(struct raw3270_view *);
 164void raw3270_del_view(struct raw3270_view *);
 165void raw3270_deactivate_view(struct raw3270_view *);
 166struct raw3270_view *raw3270_find_view(struct raw3270_fn *, int);
 167int raw3270_start(struct raw3270_view *, struct raw3270_request *);
 168int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *);
 169int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *);
 170int raw3270_reset(struct raw3270_view *);
 171struct raw3270_view *raw3270_view(struct raw3270_view *);
 172int raw3270_view_active(struct raw3270_view *);
 173
 174/* Reference count inliner for view structures. */
 175static inline void
 176raw3270_get_view(struct raw3270_view *view)
 177{
 178        atomic_inc(&view->ref_count);
 179}
 180
 181extern wait_queue_head_t raw3270_wait_queue;
 182
 183static inline void
 184raw3270_put_view(struct raw3270_view *view)
 185{
 186        if (atomic_dec_return(&view->ref_count) == 0)
 187                wake_up(&raw3270_wait_queue);
 188}
 189
 190struct raw3270 *raw3270_setup_console(void);
 191void raw3270_wait_cons_dev(struct raw3270 *);
 192
 193/* Notifier for device addition/removal */
 194struct raw3270_notifier {
 195        struct list_head list;
 196        void (*create)(int minor);
 197        void (*destroy)(int minor);
 198};
 199
 200int raw3270_register_notifier(struct raw3270_notifier *);
 201void raw3270_unregister_notifier(struct raw3270_notifier *);
 202
 203/*
 204 * Little memory allocator for string objects. 
 205 */
 206struct string
 207{
 208        struct list_head list;
 209        struct list_head update;
 210        unsigned long size;
 211        unsigned long len;
 212        char string[];
 213} __attribute__ ((aligned(8)));
 214
 215static inline struct string *
 216alloc_string(struct list_head *free_list, unsigned long len)
 217{
 218        struct string *cs, *tmp;
 219        unsigned long size;
 220
 221        size = (len + 7L) & -8L;
 222        list_for_each_entry(cs, free_list, list) {
 223                if (cs->size < size)
 224                        continue;
 225                if (cs->size > size + sizeof(struct string)) {
 226                        char *endaddr = (char *) (cs + 1) + cs->size;
 227                        tmp = (struct string *) (endaddr - size) - 1;
 228                        tmp->size = size;
 229                        cs->size -= size + sizeof(struct string);
 230                        cs = tmp;
 231                } else
 232                        list_del(&cs->list);
 233                cs->len = len;
 234                INIT_LIST_HEAD(&cs->list);
 235                INIT_LIST_HEAD(&cs->update);
 236                return cs;
 237        }
 238        return NULL;
 239}
 240
 241static inline unsigned long
 242free_string(struct list_head *free_list, struct string *cs)
 243{
 244        struct string *tmp;
 245        struct list_head *p, *left;
 246
 247        /* Find out the left neighbour in free memory list. */
 248        left = free_list;
 249        list_for_each(p, free_list) {
 250                if (list_entry(p, struct string, list) > cs)
 251                        break;
 252                left = p;
 253        }
 254        /* Try to merge with right neighbour = next element from left. */
 255        if (left->next != free_list) {
 256                tmp = list_entry(left->next, struct string, list);
 257                if ((char *) (cs + 1) + cs->size == (char *) tmp) {
 258                        list_del(&tmp->list);
 259                        cs->size += tmp->size + sizeof(struct string);
 260                }
 261        }
 262        /* Try to merge with left neighbour. */
 263        if (left != free_list) {
 264                tmp = list_entry(left, struct string, list);
 265                if ((char *) (tmp + 1) + tmp->size == (char *) cs) {
 266                        tmp->size += cs->size + sizeof(struct string);
 267                        return tmp->size;
 268                }
 269        }
 270        __list_add(&cs->list, left, left->next);
 271        return cs->size;
 272}
 273
 274static inline void
 275add_string_memory(struct list_head *free_list, void *mem, unsigned long size)
 276{
 277        struct string *cs;
 278
 279        cs = (struct string *) mem;
 280        cs->size = size - sizeof(struct string);
 281        free_string(free_list, cs);
 282}
 283
 284