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 *);
 176int raw3270_view_active(struct raw3270_view *);
 177
 178/* Reference count inliner for view structures. */
 179static inline void
 180raw3270_get_view(struct raw3270_view *view)
 181{
 182        atomic_inc(&view->ref_count);
 183}
 184
 185extern wait_queue_head_t raw3270_wait_queue;
 186
 187static inline void
 188raw3270_put_view(struct raw3270_view *view)
 189{
 190        if (atomic_dec_return(&view->ref_count) == 0)
 191                wake_up(&raw3270_wait_queue);
 192}
 193
 194struct raw3270 *raw3270_setup_console(void);
 195void raw3270_wait_cons_dev(struct raw3270 *);
 196
 197/* Notifier for device addition/removal */
 198struct raw3270_notifier {
 199        struct list_head list;
 200        void (*create)(int minor);
 201        void (*destroy)(int minor);
 202};
 203
 204int raw3270_register_notifier(struct raw3270_notifier *);
 205void raw3270_unregister_notifier(struct raw3270_notifier *);
 206void raw3270_pm_unfreeze(struct raw3270_view *);
 207
 208/*
 209 * Little memory allocator for string objects. 
 210 */
 211struct string
 212{
 213        struct list_head list;
 214        struct list_head update;
 215        unsigned long size;
 216        unsigned long len;
 217        char string[0];
 218} __attribute__ ((aligned(8)));
 219
 220static inline struct string *
 221alloc_string(struct list_head *free_list, unsigned long len)
 222{
 223        struct string *cs, *tmp;
 224        unsigned long size;
 225
 226        size = (len + 7L) & -8L;
 227        list_for_each_entry(cs, free_list, list) {
 228                if (cs->size < size)
 229                        continue;
 230                if (cs->size > size + sizeof(struct string)) {
 231                        char *endaddr = (char *) (cs + 1) + cs->size;
 232                        tmp = (struct string *) (endaddr - size) - 1;
 233                        tmp->size = size;
 234                        cs->size -= size + sizeof(struct string);
 235                        cs = tmp;
 236                } else
 237                        list_del(&cs->list);
 238                cs->len = len;
 239                INIT_LIST_HEAD(&cs->list);
 240                INIT_LIST_HEAD(&cs->update);
 241                return cs;
 242        }
 243        return NULL;
 244}
 245
 246static inline unsigned long
 247free_string(struct list_head *free_list, struct string *cs)
 248{
 249        struct string *tmp;
 250        struct list_head *p, *left;
 251
 252        /* Find out the left neighbour in free memory list. */
 253        left = free_list;
 254        list_for_each(p, free_list) {
 255                if (list_entry(p, struct string, list) > cs)
 256                        break;
 257                left = p;
 258        }
 259        /* Try to merge with right neighbour = next element from left. */
 260        if (left->next != free_list) {
 261                tmp = list_entry(left->next, struct string, list);
 262                if ((char *) (cs + 1) + cs->size == (char *) tmp) {
 263                        list_del(&tmp->list);
 264                        cs->size += tmp->size + sizeof(struct string);
 265                }
 266        }
 267        /* Try to merge with left neighbour. */
 268        if (left != free_list) {
 269                tmp = list_entry(left, struct string, list);
 270                if ((char *) (tmp + 1) + tmp->size == (char *) cs) {
 271                        tmp->size += cs->size + sizeof(struct string);
 272                        return tmp->size;
 273                }
 274        }
 275        __list_add(&cs->list, left, left->next);
 276        return cs->size;
 277}
 278
 279static inline void
 280add_string_memory(struct list_head *free_list, void *mem, unsigned long size)
 281{
 282        struct string *cs;
 283
 284        cs = (struct string *) mem;
 285        cs->size = size - sizeof(struct string);
 286        free_string(free_list, cs);
 287}
 288
 289