linux/drivers/s390/char/raw3270.h
<<
>>
Prefs
   1/*
   2 * IBM/3270 Driver
   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 <asm/idals.h>
  11#include <asm/ioctl.h>
  12
  13/* ioctls for fullscreen 3270 */
  14#define TUBICMD         _IO('3', 3)     /* set ccw command for fs reads. */
  15#define TUBOCMD         _IO('3', 4)     /* set ccw command for fs writes. */
  16#define TUBGETI         _IO('3', 7)     /* get ccw command for fs reads. */
  17#define TUBGETO         _IO('3', 8)     /* get ccw command for fs writes. */
  18#define TUBSETMOD       _IO('3',12)     /* FIXME: what does it do ?*/
  19#define TUBGETMOD       _IO('3',13)     /* FIXME: what does it do ?*/
  20
  21/* Local Channel Commands */
  22#define TC_WRITE        0x01            /* Write */
  23#define TC_RDBUF        0x02            /* Read Buffer */
  24#define TC_EWRITE       0x05            /* Erase write */
  25#define TC_READMOD      0x06            /* Read modified */
  26#define TC_EWRITEA      0x0d            /* Erase write alternate */
  27#define TC_WRITESF      0x11            /* Write structured field */
  28
  29/* Buffer Control Orders */
  30#define TO_SF           0x1d            /* Start field */
  31#define TO_SBA          0x11            /* Set buffer address */
  32#define TO_IC           0x13            /* Insert cursor */
  33#define TO_PT           0x05            /* Program tab */
  34#define TO_RA           0x3c            /* Repeat to address */
  35#define TO_SFE          0x29            /* Start field extended */
  36#define TO_EUA          0x12            /* Erase unprotected to address */
  37#define TO_MF           0x2c            /* Modify field */
  38#define TO_SA           0x28            /* Set attribute */
  39
  40/* Field Attribute Bytes */
  41#define TF_INPUT        0x40            /* Visible input */
  42#define TF_INPUTN       0x4c            /* Invisible input */
  43#define TF_INMDT        0xc1            /* Visible, Set-MDT */
  44#define TF_LOG          0x60
  45
  46/* Character Attribute Bytes */
  47#define TAT_RESET       0x00
  48#define TAT_FIELD       0xc0
  49#define TAT_EXTHI       0x41
  50#define TAT_COLOR       0x42
  51#define TAT_CHARS       0x43
  52#define TAT_TRANS       0x46
  53
  54/* Extended-Highlighting Bytes */
  55#define TAX_RESET       0x00
  56#define TAX_BLINK       0xf1
  57#define TAX_REVER       0xf2
  58#define TAX_UNDER       0xf4
  59
  60/* Reset value */
  61#define TAR_RESET       0x00
  62
  63/* Color values */
  64#define TAC_RESET       0x00
  65#define TAC_BLUE        0xf1
  66#define TAC_RED         0xf2
  67#define TAC_PINK        0xf3
  68#define TAC_GREEN       0xf4
  69#define TAC_TURQ        0xf5
  70#define TAC_YELLOW      0xf6
  71#define TAC_WHITE       0xf7
  72#define TAC_DEFAULT     0x00
  73
  74/* Write Control Characters */
  75#define TW_NONE         0x40            /* No particular action */
  76#define TW_KR           0xc2            /* Keyboard restore */
  77#define TW_PLUSALARM    0x04            /* Add this bit for alarm */
  78
  79#define RAW3270_FIRSTMINOR      1       /* First minor number */
  80#define RAW3270_MAXDEVS         255     /* Max number of 3270 devices */
  81
  82/* For TUBGETMOD and TUBSETMOD. Should include. */
  83struct raw3270_iocb {
  84        short model;
  85        short line_cnt;
  86        short col_cnt;
  87        short pf_cnt;
  88        short re_cnt;
  89        short map;
  90};
  91
  92struct raw3270;
  93struct raw3270_view;
  94extern struct class *class3270;
  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        void (*resize)(struct raw3270_view *, int, int, int);
 145};
 146
 147/*
 148 * View structure chaining. The raw3270_view structure is meant to
 149 * be embedded at the start of the real view data structure, e.g.:
 150 *   struct example {
 151 *     struct raw3270_view view;
 152 *     ...
 153 *   };
 154 */
 155struct raw3270_view {
 156        struct list_head list;
 157        spinlock_t lock;
 158        atomic_t ref_count;
 159        struct raw3270 *dev;
 160        struct raw3270_fn *fn;
 161        unsigned int model;
 162        unsigned int rows, cols;        /* # of rows & colums of the view */
 163        unsigned char *ascebc;          /* ascii -> ebcdic table */
 164};
 165
 166int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int);
 167int raw3270_activate_view(struct raw3270_view *);
 168void raw3270_del_view(struct raw3270_view *);
 169void raw3270_deactivate_view(struct raw3270_view *);
 170struct raw3270_view *raw3270_find_view(struct raw3270_fn *, int);
 171int raw3270_start(struct raw3270_view *, struct raw3270_request *);
 172int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *);
 173int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *);
 174int raw3270_reset(struct raw3270_view *);
 175struct raw3270_view *raw3270_view(struct raw3270_view *);
 176
 177/* Reference count inliner for view structures. */
 178static inline void
 179raw3270_get_view(struct raw3270_view *view)
 180{
 181        atomic_inc(&view->ref_count);
 182}
 183
 184extern wait_queue_head_t raw3270_wait_queue;
 185
 186static inline void
 187raw3270_put_view(struct raw3270_view *view)
 188{
 189        if (atomic_dec_return(&view->ref_count) == 0)
 190                wake_up(&raw3270_wait_queue);
 191}
 192
 193struct raw3270 *raw3270_setup_console(struct ccw_device *cdev);
 194void raw3270_wait_cons_dev(struct raw3270 *);
 195
 196/* Notifier for device addition/removal */
 197struct raw3270_notifier {
 198        struct list_head list;
 199        void (*create)(int minor);
 200        void (*destroy)(int minor);
 201};
 202
 203int raw3270_register_notifier(struct raw3270_notifier *);
 204void raw3270_unregister_notifier(struct raw3270_notifier *);
 205void raw3270_pm_unfreeze(struct raw3270_view *);
 206
 207/*
 208 * Little memory allocator for string objects. 
 209 */
 210struct string
 211{
 212        struct list_head list;
 213        struct list_head update;
 214        unsigned long size;
 215        unsigned long len;
 216        char string[0];
 217} __attribute__ ((aligned(8)));
 218
 219static inline struct string *
 220alloc_string(struct list_head *free_list, unsigned long len)
 221{
 222        struct string *cs, *tmp;
 223        unsigned long size;
 224
 225        size = (len + 7L) & -8L;
 226        list_for_each_entry(cs, free_list, list) {
 227                if (cs->size < size)
 228                        continue;
 229                if (cs->size > size + sizeof(struct string)) {
 230                        char *endaddr = (char *) (cs + 1) + cs->size;
 231                        tmp = (struct string *) (endaddr - size) - 1;
 232                        tmp->size = size;
 233                        cs->size -= size + sizeof(struct string);
 234                        cs = tmp;
 235                } else
 236                        list_del(&cs->list);
 237                cs->len = len;
 238                INIT_LIST_HEAD(&cs->list);
 239                INIT_LIST_HEAD(&cs->update);
 240                return cs;
 241        }
 242        return NULL;
 243}
 244
 245static inline unsigned long
 246free_string(struct list_head *free_list, struct string *cs)
 247{
 248        struct string *tmp;
 249        struct list_head *p, *left;
 250
 251        /* Find out the left neighbour in free memory list. */
 252        left = free_list;
 253        list_for_each(p, free_list) {
 254                if (list_entry(p, struct string, list) > cs)
 255                        break;
 256                left = p;
 257        }
 258        /* Try to merge with right neighbour = next element from left. */
 259        if (left->next != free_list) {
 260                tmp = list_entry(left->next, struct string, list);
 261                if ((char *) (cs + 1) + cs->size == (char *) tmp) {
 262                        list_del(&tmp->list);
 263                        cs->size += tmp->size + sizeof(struct string);
 264                }
 265        }
 266        /* Try to merge with left neighbour. */
 267        if (left != free_list) {
 268                tmp = list_entry(left, struct string, list);
 269                if ((char *) (tmp + 1) + tmp->size == (char *) cs) {
 270                        tmp->size += cs->size + sizeof(struct string);
 271                        return tmp->size;
 272                }
 273        }
 274        __list_add(&cs->list, left, left->next);
 275        return cs->size;
 276}
 277
 278static inline void
 279add_string_memory(struct list_head *free_list, void *mem, unsigned long size)
 280{
 281        struct string *cs;
 282
 283        cs = (struct string *) mem;
 284        cs->size = size - sizeof(struct string);
 285        free_string(free_list, cs);
 286}
 287
 288