0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef __SCLP_H__
0010 #define __SCLP_H__
0011
0012 #include <linux/types.h>
0013 #include <linux/list.h>
0014 #include <asm/asm-extable.h>
0015 #include <asm/sclp.h>
0016 #include <asm/ebcdic.h>
0017
0018
0019 #define MAX_KMEM_PAGES (sizeof(unsigned long) << 3)
0020 #define SCLP_CONSOLE_PAGES 6
0021
0022 #define SCLP_EVTYP_MASK(T) (1UL << (sizeof(sccb_mask_t) * BITS_PER_BYTE - (T)))
0023
0024 #define EVTYP_OPCMD 0x01
0025 #define EVTYP_MSG 0x02
0026 #define EVTYP_CONFMGMDATA 0x04
0027 #define EVTYP_DIAG_TEST 0x07
0028 #define EVTYP_STATECHANGE 0x08
0029 #define EVTYP_PMSGCMD 0x09
0030 #define EVTYP_ASYNC 0x0A
0031 #define EVTYP_CTLPROGIDENT 0x0B
0032 #define EVTYP_STORE_DATA 0x0C
0033 #define EVTYP_ERRNOTIFY 0x18
0034 #define EVTYP_VT220MSG 0x1A
0035 #define EVTYP_SDIAS 0x1C
0036 #define EVTYP_SIGQUIESCE 0x1D
0037 #define EVTYP_OCF 0x1E
0038
0039 #define EVTYP_OPCMD_MASK SCLP_EVTYP_MASK(EVTYP_OPCMD)
0040 #define EVTYP_MSG_MASK SCLP_EVTYP_MASK(EVTYP_MSG)
0041 #define EVTYP_CONFMGMDATA_MASK SCLP_EVTYP_MASK(EVTYP_CONFMGMDATA)
0042 #define EVTYP_DIAG_TEST_MASK SCLP_EVTYP_MASK(EVTYP_DIAG_TEST)
0043 #define EVTYP_STATECHANGE_MASK SCLP_EVTYP_MASK(EVTYP_STATECHANGE)
0044 #define EVTYP_PMSGCMD_MASK SCLP_EVTYP_MASK(EVTYP_PMSGCMD)
0045 #define EVTYP_ASYNC_MASK SCLP_EVTYP_MASK(EVTYP_ASYNC)
0046 #define EVTYP_CTLPROGIDENT_MASK SCLP_EVTYP_MASK(EVTYP_CTLPROGIDENT)
0047 #define EVTYP_STORE_DATA_MASK SCLP_EVTYP_MASK(EVTYP_STORE_DATA)
0048 #define EVTYP_ERRNOTIFY_MASK SCLP_EVTYP_MASK(EVTYP_ERRNOTIFY)
0049 #define EVTYP_VT220MSG_MASK SCLP_EVTYP_MASK(EVTYP_VT220MSG)
0050 #define EVTYP_SDIAS_MASK SCLP_EVTYP_MASK(EVTYP_SDIAS)
0051 #define EVTYP_SIGQUIESCE_MASK SCLP_EVTYP_MASK(EVTYP_SIGQUIESCE)
0052 #define EVTYP_OCF_MASK SCLP_EVTYP_MASK(EVTYP_OCF)
0053
0054 #define GNRLMSGFLGS_DOM 0x8000
0055 #define GNRLMSGFLGS_SNDALRM 0x4000
0056 #define GNRLMSGFLGS_HOLDMSG 0x2000
0057
0058 #define LNTPFLGS_CNTLTEXT 0x8000
0059 #define LNTPFLGS_LABELTEXT 0x4000
0060 #define LNTPFLGS_DATATEXT 0x2000
0061 #define LNTPFLGS_ENDTEXT 0x1000
0062 #define LNTPFLGS_PROMPTTEXT 0x0800
0063
0064 typedef unsigned int sclp_cmdw_t;
0065
0066 #define SCLP_CMDW_READ_CPU_INFO 0x00010001
0067 #define SCLP_CMDW_READ_SCP_INFO 0x00020001
0068 #define SCLP_CMDW_READ_STORAGE_INFO 0x00040001
0069 #define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
0070 #define SCLP_CMDW_READ_EVENT_DATA 0x00770005
0071 #define SCLP_CMDW_WRITE_EVENT_DATA 0x00760005
0072 #define SCLP_CMDW_WRITE_EVENT_MASK 0x00780005
0073
0074 #define GDS_ID_MDSMU 0x1310
0075 #define GDS_ID_MDSROUTEINFO 0x1311
0076 #define GDS_ID_AGUNWRKCORR 0x1549
0077 #define GDS_ID_SNACONDREPORT 0x1532
0078 #define GDS_ID_CPMSU 0x1212
0079 #define GDS_ID_ROUTTARGINSTR 0x154D
0080 #define GDS_ID_OPREQ 0x8070
0081 #define GDS_ID_TEXTCMD 0x1320
0082
0083 #define GDS_KEY_SELFDEFTEXTMSG 0x31
0084
0085 typedef u64 sccb_mask_t;
0086
0087 struct sccb_header {
0088 u16 length;
0089 u8 function_code;
0090 u8 control_mask[3];
0091 u16 response_code;
0092 } __attribute__((packed));
0093
0094 struct init_sccb {
0095 struct sccb_header header;
0096 u16 _reserved;
0097 u16 mask_length;
0098 u8 masks[4 * 1021];
0099
0100
0101
0102
0103
0104
0105 } __attribute__((packed));
0106
0107 #define SCLP_MASK_SIZE_COMPAT 4
0108
0109 static inline sccb_mask_t sccb_get_mask(u8 *masks, size_t len, int i)
0110 {
0111 sccb_mask_t res = 0;
0112
0113 memcpy(&res, masks + i * len, min(sizeof(res), len));
0114 return res;
0115 }
0116
0117 static inline void sccb_set_mask(u8 *masks, size_t len, int i, sccb_mask_t val)
0118 {
0119 memset(masks + i * len, 0, len);
0120 memcpy(masks + i * len, &val, min(sizeof(val), len));
0121 }
0122
0123 #define sccb_get_generic_mask(sccb, i) \
0124 ({ \
0125 __typeof__(sccb) __sccb = sccb; \
0126 \
0127 sccb_get_mask(__sccb->masks, __sccb->mask_length, i); \
0128 })
0129 #define sccb_get_recv_mask(sccb) sccb_get_generic_mask(sccb, 0)
0130 #define sccb_get_send_mask(sccb) sccb_get_generic_mask(sccb, 1)
0131 #define sccb_get_sclp_recv_mask(sccb) sccb_get_generic_mask(sccb, 2)
0132 #define sccb_get_sclp_send_mask(sccb) sccb_get_generic_mask(sccb, 3)
0133
0134 #define sccb_set_generic_mask(sccb, i, val) \
0135 ({ \
0136 __typeof__(sccb) __sccb = sccb; \
0137 \
0138 sccb_set_mask(__sccb->masks, __sccb->mask_length, i, val); \
0139 })
0140 #define sccb_set_recv_mask(sccb, val) sccb_set_generic_mask(sccb, 0, val)
0141 #define sccb_set_send_mask(sccb, val) sccb_set_generic_mask(sccb, 1, val)
0142 #define sccb_set_sclp_recv_mask(sccb, val) sccb_set_generic_mask(sccb, 2, val)
0143 #define sccb_set_sclp_send_mask(sccb, val) sccb_set_generic_mask(sccb, 3, val)
0144
0145 struct read_cpu_info_sccb {
0146 struct sccb_header header;
0147 u16 nr_configured;
0148 u16 offset_configured;
0149 u16 nr_standby;
0150 u16 offset_standby;
0151
0152
0153
0154
0155 u8 reserved[];
0156 } __attribute__((packed, aligned(PAGE_SIZE)));
0157
0158 struct read_info_sccb {
0159 struct sccb_header header;
0160 u16 rnmax;
0161 u8 rnsize;
0162 u8 _pad_11[16 - 11];
0163 u16 ncpurl;
0164 u16 cpuoff;
0165 u8 _pad_20[24 - 20];
0166 u8 loadparm[8];
0167 u8 _pad_32[42 - 32];
0168 u8 fac42;
0169 u8 fac43;
0170 u8 _pad_44[48 - 44];
0171 u64 facilities;
0172 u8 _pad_56[66 - 56];
0173 u8 fac66;
0174 u8 _pad_67[76 - 67];
0175 u32 ibc;
0176 u8 _pad80[84 - 80];
0177 u8 fac84;
0178 u8 fac85;
0179 u8 _pad_86[91 - 86];
0180 u8 fac91;
0181 u8 _pad_92[98 - 92];
0182 u8 fac98;
0183 u8 hamaxpow;
0184 u32 rnsize2;
0185 u64 rnmax2;
0186 u32 hsa_size;
0187 u8 fac116;
0188 u8 fac117;
0189 u8 fac118;
0190 u8 fac119;
0191 u16 hcpua;
0192 u8 _pad_122[124 - 122];
0193 u32 hmfai;
0194 u8 _pad_128[134 - 128];
0195 u8 byte_134;
0196 u8 cpudirq;
0197 u16 cbl;
0198 u8 _pad_138[EXT_SCCB_READ_SCP - 138];
0199 } __packed __aligned(PAGE_SIZE);
0200
0201 struct read_storage_sccb {
0202 struct sccb_header header;
0203 u16 max_id;
0204 u16 assigned;
0205 u16 standby;
0206 u16 :16;
0207 u32 entries[0];
0208 } __packed;
0209
0210 static inline void sclp_fill_core_info(struct sclp_core_info *info,
0211 struct read_cpu_info_sccb *sccb)
0212 {
0213 char *page = (char *) sccb;
0214
0215 memset(info, 0, sizeof(*info));
0216 info->configured = sccb->nr_configured;
0217 info->standby = sccb->nr_standby;
0218 info->combined = sccb->nr_configured + sccb->nr_standby;
0219 memcpy(&info->core, page + sccb->offset_configured,
0220 info->combined * sizeof(struct sclp_core_entry));
0221 }
0222
0223 #define SCLP_HAS_CHP_INFO (sclp.facilities & 0x8000000000000000ULL)
0224 #define SCLP_HAS_CHP_RECONFIG (sclp.facilities & 0x2000000000000000ULL)
0225 #define SCLP_HAS_CPU_INFO (sclp.facilities & 0x0800000000000000ULL)
0226 #define SCLP_HAS_CPU_RECONFIG (sclp.facilities & 0x0400000000000000ULL)
0227 #define SCLP_HAS_PCI_RECONFIG (sclp.facilities & 0x0000000040000000ULL)
0228 #define SCLP_HAS_AP_RECONFIG (sclp.facilities & 0x0000000100000000ULL)
0229
0230 struct gds_subvector {
0231 u8 length;
0232 u8 key;
0233 } __attribute__((packed));
0234
0235 struct gds_vector {
0236 u16 length;
0237 u16 gds_id;
0238 } __attribute__((packed));
0239
0240 struct evbuf_header {
0241 u16 length;
0242 u8 type;
0243 u8 flags;
0244 u16 _reserved;
0245 } __attribute__((packed));
0246
0247 struct sclp_req {
0248 struct list_head list;
0249 sclp_cmdw_t command;
0250 void *sccb;
0251 char status;
0252 int start_count;
0253
0254 void (*callback)(struct sclp_req *, void *data);
0255 void *callback_data;
0256 int queue_timeout;
0257
0258
0259
0260 unsigned long queue_expires;
0261 };
0262
0263 #define SCLP_REQ_FILLED 0x00
0264 #define SCLP_REQ_QUEUED 0x01
0265 #define SCLP_REQ_RUNNING 0x02
0266 #define SCLP_REQ_DONE 0x03
0267 #define SCLP_REQ_FAILED 0x05
0268 #define SCLP_REQ_QUEUED_TIMEOUT 0x06
0269
0270 #define SCLP_QUEUE_INTERVAL 5
0271
0272
0273
0274 struct sclp_register {
0275 struct list_head list;
0276
0277 sccb_mask_t receive_mask;
0278
0279 sccb_mask_t send_mask;
0280
0281 sccb_mask_t sclp_receive_mask;
0282
0283 sccb_mask_t sclp_send_mask;
0284
0285 void (*state_change_fn)(struct sclp_register *);
0286
0287 void (*receiver_fn)(struct evbuf_header *);
0288 };
0289
0290
0291 int sclp_add_request(struct sclp_req *req);
0292 void sclp_sync_wait(void);
0293 int sclp_register(struct sclp_register *reg);
0294 void sclp_unregister(struct sclp_register *reg);
0295 int sclp_remove_processed(struct sccb_header *sccb);
0296 int sclp_deactivate(void);
0297 int sclp_reactivate(void);
0298 int sclp_sync_request(sclp_cmdw_t command, void *sccb);
0299 int sclp_sync_request_timeout(sclp_cmdw_t command, void *sccb, int timeout);
0300 int sclp_sdias_init(void);
0301
0302 enum {
0303 sclp_init_state_uninitialized,
0304 sclp_init_state_initializing,
0305 sclp_init_state_initialized
0306 };
0307
0308 extern int sclp_init_state;
0309 extern int sclp_console_pages;
0310 extern int sclp_console_drop;
0311 extern unsigned long sclp_console_full;
0312 extern bool sclp_mask_compat_mode;
0313
0314 void sclp_early_wait_irq(void);
0315 int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb);
0316 unsigned int sclp_early_con_check_linemode(struct init_sccb *sccb);
0317 unsigned int sclp_early_con_check_vt220(struct init_sccb *sccb);
0318 int sclp_early_set_event_mask(struct init_sccb *sccb,
0319 sccb_mask_t receive_mask,
0320 sccb_mask_t send_mask);
0321 struct read_info_sccb * __init sclp_early_get_info(void);
0322
0323
0324
0325
0326 static inline int sclp_service_call(sclp_cmdw_t command, void *sccb)
0327 {
0328 int cc = 4;
0329
0330 asm volatile(
0331 "0: .insn rre,0xb2200000,%1,%2\n"
0332 "1: ipm %0\n"
0333 " srl %0,28\n"
0334 "2:\n"
0335 EX_TABLE(0b, 2b)
0336 EX_TABLE(1b, 2b)
0337 : "+&d" (cc) : "d" (command), "a" (__pa(sccb))
0338 : "cc", "memory");
0339 if (cc == 4)
0340 return -EINVAL;
0341 if (cc == 3)
0342 return -EIO;
0343 if (cc == 2)
0344 return -EBUSY;
0345 return 0;
0346 }
0347
0348
0349
0350 static inline unsigned char
0351 sclp_ascebc(unsigned char ch)
0352 {
0353 return (MACHINE_IS_VM) ? _ascebc[ch] : _ascebc_500[ch];
0354 }
0355
0356
0357 static inline void
0358 sclp_ebcasc_str(char *str, int nr)
0359 {
0360 (MACHINE_IS_VM) ? EBCASC(str, nr) : EBCASC_500(str, nr);
0361 }
0362
0363
0364 static inline void
0365 sclp_ascebc_str(char *str, int nr)
0366 {
0367 (MACHINE_IS_VM) ? ASCEBC(str, nr) : ASCEBC_500(str, nr);
0368 }
0369
0370 static inline struct gds_vector *
0371 sclp_find_gds_vector(void *start, void *end, u16 id)
0372 {
0373 struct gds_vector *v;
0374
0375 for (v = start; (void *) v < end; v = (void *) v + v->length)
0376 if (v->gds_id == id)
0377 return v;
0378 return NULL;
0379 }
0380
0381 static inline struct gds_subvector *
0382 sclp_find_gds_subvector(void *start, void *end, u8 key)
0383 {
0384 struct gds_subvector *sv;
0385
0386 for (sv = start; (void *) sv < end; sv = (void *) sv + sv->length)
0387 if (sv->key == key)
0388 return sv;
0389 return NULL;
0390 }
0391
0392 #endif