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;
  94
  95/* 3270 CCW request */
  96struct raw3270_request {
  97        struct list_head list;          /* list head for request queueing. */
  98        struct raw3270_view *view;      /* view of this request */
  99        struct ccw1 ccw;                /* single ccw. */
 100        void *buffer;                   /* output buffer. */
 101        size_t size;                    /* size of output buffer. */
 102        int rescnt;                     /* residual count from devstat. */
 103        int rc;                         /* return code for this request. */
 104
 105        /* Callback for delivering final status. */
 106        void (*callback)(struct raw3270_request *, void *);
 107        void *callback_data;
 108};
 109
 110struct raw3270_request *raw3270_request_alloc(size_t size);
 111struct raw3270_request *raw3270_request_alloc_bootmem(size_t size);
 112void raw3270_request_free(struct raw3270_request *);
 113void raw3270_request_reset(struct raw3270_request *);
 114void raw3270_request_set_cmd(struct raw3270_request *, u8 cmd);
 115int  raw3270_request_add_data(struct raw3270_request *, void *, size_t);
 116void raw3270_request_set_data(struct raw3270_request *, void *, size_t);
 117void raw3270_request_set_idal(struct raw3270_request *, struct idal_buffer *);
 118
 119static inline int
 120raw3270_request_final(struct raw3270_request *rq)
 121{
 122        return list_empty(&rq->list);
 123}
 124
 125void raw3270_buffer_address(struct raw3270 *, char *, unsigned short);
 126
 127/* Return value of *intv (see raw3270_fn below) can be one of the following: */
 128#define RAW3270_IO_DONE         0       /* request finished */
 129#define RAW3270_IO_BUSY         1       /* request still active */
 130#define RAW3270_IO_RETRY        2       /* retry current request */
 131#define RAW3270_IO_STOP         3       /* kill current request */
 132
 133/*
 134 * Functions of a 3270 view.
 135 */
 136struct raw3270_fn {
 137        int  (*activate)(struct raw3270_view *);
 138        void (*deactivate)(struct raw3270_view *);
 139        int  (*intv)(struct raw3270_view *,
 140                     struct raw3270_request *, struct irb *);
 141        void (*release)(struct raw3270_view *);
 142        void (*free)(struct raw3270_view *);
 143};
 144
 145/*
 146 * View structure chaining. The raw3270_view structure is meant to
 147 * be embedded at the start of the real view data structure, e.g.:
 148 *   struct example {
 149 *     struct raw3270_view view;
 150 *     ...
 151 *   };
 152 */
 153struct raw3270_view {
 154        struct list_head list;
 155        spinlock_t lock;
 156        atomic_t ref_count;
 157        struct raw3270 *dev;
 158        struct raw3270_fn *fn;
 159        unsigned int model;
 160        unsigned int rows, cols;        /* # of rows & colums of the view */
 161        unsigned char *ascebc;          /* ascii -> ebcdic table */
 162};
 163
 164int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int);
 165int raw3270_activate_view(struct raw3270_view *);
 166void raw3270_del_view(struct raw3270_view *);
 167void raw3270_deactivate_view(struct raw3270_view *);
 168struct raw3270_view *raw3270_find_view(struct raw3270_fn *, int);
 169int raw3270_start(struct raw3270_view *, struct raw3270_request *);
 170int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *);
 171int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *);
 172int raw3270_reset(struct raw3270_view *);
 173struct raw3270_view *raw3270_view(struct raw3270_view *);
 174
 175/* Reference count inliner for view structures. */
 176static inline void
 177raw3270_get_view(struct raw3270_view *view)
 178{
 179        atomic_inc(&view->ref_count);
 180}
 181
 182extern wait_queue_head_t raw3270_wait_queue;
 183
 184static inline void
 185raw3270_put_view(struct raw3270_view *view)
 186{
 187        if (atomic_dec_return(&view->ref_count) == 0)
 188                wake_up(&raw3270_wait_queue);
 189}
 190
 191struct raw3270 *raw3270_setup_console(struct ccw_device *cdev);
 192void raw3270_wait_cons_dev(struct raw3270 *);
 193
 194/* Notifier for device addition/removal */
 195int raw3270_register_notifier(void (*notifier)(int, int));
 196void raw3270_unregister_notifier(void (*notifier)(int, int));
 197void raw3270_pm_unfreeze(struct raw3270_view *);
 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