root / pc-bios / s390-ccw / cio.h @ c8cda874
History | View | Annotate | Download (9 kB)
1 |
/*
|
---|---|
2 |
* Channel IO definitions
|
3 |
*
|
4 |
* Copyright (c) 2013 Alexander Graf <agraf@suse.de>
|
5 |
*
|
6 |
* Inspired by various s390 headers in Linux 3.9.
|
7 |
*
|
8 |
* This work is licensed under the terms of the GNU GPL, version 2 or (at
|
9 |
* your option) any later version. See the COPYING file in the top-level
|
10 |
* directory.
|
11 |
*/
|
12 |
|
13 |
#ifndef CIO_H
|
14 |
#define CIO_H
|
15 |
|
16 |
/*
|
17 |
* path management control word
|
18 |
*/
|
19 |
struct pmcw {
|
20 |
__u32 intparm; /* interruption parameter */
|
21 |
__u32 qf : 1; /* qdio facility */ |
22 |
__u32 w : 1;
|
23 |
__u32 isc : 3; /* interruption sublass */ |
24 |
__u32 res5 : 3; /* reserved zeros */ |
25 |
__u32 ena : 1; /* enabled */ |
26 |
__u32 lm : 2; /* limit mode */ |
27 |
__u32 mme : 2; /* measurement-mode enable */ |
28 |
__u32 mp : 1; /* multipath mode */ |
29 |
__u32 tf : 1; /* timing facility */ |
30 |
__u32 dnv : 1; /* device number valid */ |
31 |
__u32 dev : 16; /* device number */ |
32 |
__u8 lpm; /* logical path mask */
|
33 |
__u8 pnom; /* path not operational mask */
|
34 |
__u8 lpum; /* last path used mask */
|
35 |
__u8 pim; /* path installed mask */
|
36 |
__u16 mbi; /* measurement-block index */
|
37 |
__u8 pom; /* path operational mask */
|
38 |
__u8 pam; /* path available mask */
|
39 |
__u8 chpid[8]; /* CHPID 0-7 (if available) */ |
40 |
__u32 unused1 : 8; /* reserved zeros */ |
41 |
__u32 st : 3; /* subchannel type */ |
42 |
__u32 unused2 : 18; /* reserved zeros */ |
43 |
__u32 mbfc : 1; /* measurement block format control */ |
44 |
__u32 xmwme : 1; /* extended measurement word mode enable */ |
45 |
__u32 csense : 1; /* concurrent sense; can be enabled ...*/ |
46 |
/* ... per MSCH, however, if facility */
|
47 |
/* ... is not installed, this results */
|
48 |
/* ... in an operand exception. */
|
49 |
} __attribute__ ((packed)); |
50 |
|
51 |
/* Target SCHIB configuration. */
|
52 |
struct schib_config {
|
53 |
__u64 mba; |
54 |
__u32 intparm; |
55 |
__u16 mbi; |
56 |
__u32 isc:3;
|
57 |
__u32 ena:1;
|
58 |
__u32 mme:2;
|
59 |
__u32 mp:1;
|
60 |
__u32 csense:1;
|
61 |
__u32 mbfc:1;
|
62 |
} __attribute__ ((packed)); |
63 |
|
64 |
struct scsw {
|
65 |
__u16 flags; |
66 |
__u16 ctrl; |
67 |
__u32 cpa; |
68 |
__u8 dstat; |
69 |
__u8 cstat; |
70 |
__u16 count; |
71 |
} __attribute__ ((packed)); |
72 |
|
73 |
#define SCSW_FCTL_CLEAR_FUNC 0x1000 |
74 |
#define SCSW_FCTL_HALT_FUNC 0x2000 |
75 |
#define SCSW_FCTL_START_FUNC 0x4000 |
76 |
|
77 |
/*
|
78 |
* subchannel information block
|
79 |
*/
|
80 |
struct schib {
|
81 |
struct pmcw pmcw; /* path management control word */ |
82 |
struct scsw scsw; /* subchannel status word */ |
83 |
__u64 mba; /* measurement block address */
|
84 |
__u8 mda[4]; /* model dependent area */ |
85 |
} __attribute__ ((packed,aligned(4)));
|
86 |
|
87 |
struct subchannel_id {
|
88 |
__u32 cssid : 8;
|
89 |
__u32 : 4;
|
90 |
__u32 m : 1;
|
91 |
__u32 ssid : 2;
|
92 |
__u32 one : 1;
|
93 |
__u32 sch_no : 16;
|
94 |
} __attribute__ ((packed, aligned(4)));
|
95 |
|
96 |
struct chsc_header {
|
97 |
__u16 length; |
98 |
__u16 code; |
99 |
} __attribute__((packed)); |
100 |
|
101 |
struct chsc_area_sda {
|
102 |
struct chsc_header request;
|
103 |
__u8 reserved1:4;
|
104 |
__u8 format:4;
|
105 |
__u8 reserved2; |
106 |
__u16 operation_code; |
107 |
__u32 reserved3; |
108 |
__u32 reserved4; |
109 |
__u32 operation_data_area[252];
|
110 |
struct chsc_header response;
|
111 |
__u32 reserved5:4;
|
112 |
__u32 format2:4;
|
113 |
__u32 reserved6:24;
|
114 |
} __attribute__((packed)); |
115 |
|
116 |
/*
|
117 |
* TPI info structure
|
118 |
*/
|
119 |
struct tpi_info {
|
120 |
struct subchannel_id schid;
|
121 |
__u32 intparm; /* interruption parameter */
|
122 |
__u32 adapter_IO : 1;
|
123 |
__u32 reserved2 : 1;
|
124 |
__u32 isc : 3;
|
125 |
__u32 reserved3 : 12;
|
126 |
__u32 int_type : 3;
|
127 |
__u32 reserved4 : 12;
|
128 |
} __attribute__ ((packed)); |
129 |
|
130 |
/* channel command word (type 1) */
|
131 |
struct ccw1 {
|
132 |
__u8 cmd_code; |
133 |
__u8 flags; |
134 |
__u16 count; |
135 |
__u32 cda; |
136 |
} __attribute__ ((packed)); |
137 |
|
138 |
#define CCW_FLAG_DC 0x80 |
139 |
#define CCW_FLAG_CC 0x40 |
140 |
#define CCW_FLAG_SLI 0x20 |
141 |
#define CCW_FLAG_SKIP 0x10 |
142 |
#define CCW_FLAG_PCI 0x08 |
143 |
#define CCW_FLAG_IDA 0x04 |
144 |
#define CCW_FLAG_SUSPEND 0x02 |
145 |
|
146 |
#define CCW_CMD_NOOP 0x03 |
147 |
#define CCW_CMD_BASIC_SENSE 0x04 |
148 |
#define CCW_CMD_TIC 0x08 |
149 |
#define CCW_CMD_SENSE_ID 0xe4 |
150 |
|
151 |
#define CCW_CMD_SET_VQ 0x13 |
152 |
#define CCW_CMD_VDEV_RESET 0x33 |
153 |
#define CCW_CMD_READ_FEAT 0x12 |
154 |
#define CCW_CMD_WRITE_FEAT 0x11 |
155 |
#define CCW_CMD_READ_CONF 0x22 |
156 |
#define CCW_CMD_WRITE_CONF 0x21 |
157 |
#define CCW_CMD_WRITE_STATUS 0x31 |
158 |
#define CCW_CMD_SET_IND 0x43 |
159 |
#define CCW_CMD_SET_CONF_IND 0x53 |
160 |
#define CCW_CMD_READ_VQ_CONF 0x32 |
161 |
|
162 |
/*
|
163 |
* Command-mode operation request block
|
164 |
*/
|
165 |
struct cmd_orb {
|
166 |
__u32 intparm; /* interruption parameter */
|
167 |
__u32 key:4; /* flags, like key, suspend control, etc. */ |
168 |
__u32 spnd:1; /* suspend control */ |
169 |
__u32 res1:1; /* reserved */ |
170 |
__u32 mod:1; /* modification control */ |
171 |
__u32 sync:1; /* synchronize control */ |
172 |
__u32 fmt:1; /* format control */ |
173 |
__u32 pfch:1; /* prefetch control */ |
174 |
__u32 isic:1; /* initial-status-interruption control */ |
175 |
__u32 alcc:1; /* address-limit-checking control */ |
176 |
__u32 ssic:1; /* suppress-suspended-interr. control */ |
177 |
__u32 res2:1; /* reserved */ |
178 |
__u32 c64:1; /* IDAW/QDIO 64 bit control */ |
179 |
__u32 i2k:1; /* IDAW 2/4kB block size control */ |
180 |
__u32 lpm:8; /* logical path mask */ |
181 |
__u32 ils:1; /* incorrect length */ |
182 |
__u32 zero:6; /* reserved zeros */ |
183 |
__u32 orbx:1; /* ORB extension control */ |
184 |
__u32 cpa; /* channel program address */
|
185 |
} __attribute__ ((packed, aligned(4)));
|
186 |
|
187 |
struct ciw {
|
188 |
__u8 type; |
189 |
__u8 command; |
190 |
__u16 count; |
191 |
}; |
192 |
|
193 |
/*
|
194 |
* sense-id response buffer layout
|
195 |
*/
|
196 |
struct senseid {
|
197 |
/* common part */
|
198 |
__u8 reserved; /* always 0x'FF' */
|
199 |
__u16 cu_type; /* control unit type */
|
200 |
__u8 cu_model; /* control unit model */
|
201 |
__u16 dev_type; /* device type */
|
202 |
__u8 dev_model; /* device model */
|
203 |
__u8 unused; /* padding byte */
|
204 |
/* extended part */
|
205 |
struct ciw ciw[62]; |
206 |
} __attribute__ ((packed, aligned(4)));
|
207 |
|
208 |
/* interruption response block */
|
209 |
struct irb {
|
210 |
struct scsw scsw;
|
211 |
__u32 esw[5];
|
212 |
__u32 ecw[8];
|
213 |
__u32 emw[8];
|
214 |
} __attribute__ ((packed, aligned(4)));
|
215 |
|
216 |
/*
|
217 |
* Some S390 specific IO instructions as inline
|
218 |
*/
|
219 |
|
220 |
static inline int stsch_err(struct subchannel_id schid, struct schib *addr) |
221 |
{ |
222 |
register struct subchannel_id reg1 asm ("1") = schid; |
223 |
int ccode = -EIO;
|
224 |
|
225 |
asm volatile( |
226 |
" stsch 0(%3)\n"
|
227 |
"0: ipm %0\n"
|
228 |
" srl %0,28\n"
|
229 |
"1:\n"
|
230 |
: "+d" (ccode), "=m" (*addr) |
231 |
: "d" (reg1), "a" (addr) |
232 |
: "cc");
|
233 |
return ccode;
|
234 |
} |
235 |
|
236 |
static inline int msch(struct subchannel_id schid, struct schib *addr) |
237 |
{ |
238 |
register struct subchannel_id reg1 asm ("1") = schid; |
239 |
int ccode;
|
240 |
|
241 |
asm volatile( |
242 |
" msch 0(%2)\n"
|
243 |
" ipm %0\n"
|
244 |
" srl %0,28"
|
245 |
: "=d" (ccode)
|
246 |
: "d" (reg1), "a" (addr), "m" (*addr) |
247 |
: "cc");
|
248 |
return ccode;
|
249 |
} |
250 |
|
251 |
static inline int msch_err(struct subchannel_id schid, struct schib *addr) |
252 |
{ |
253 |
register struct subchannel_id reg1 asm ("1") = schid; |
254 |
int ccode = -EIO;
|
255 |
|
256 |
asm volatile( |
257 |
" msch 0(%2)\n"
|
258 |
"0: ipm %0\n"
|
259 |
" srl %0,28\n"
|
260 |
"1:\n"
|
261 |
: "+d" (ccode)
|
262 |
: "d" (reg1), "a" (addr), "m" (*addr) |
263 |
: "cc");
|
264 |
return ccode;
|
265 |
} |
266 |
|
267 |
static inline int tsch(struct subchannel_id schid, struct irb *addr) |
268 |
{ |
269 |
register struct subchannel_id reg1 asm ("1") = schid; |
270 |
int ccode;
|
271 |
|
272 |
asm volatile( |
273 |
" tsch 0(%3)\n"
|
274 |
" ipm %0\n"
|
275 |
" srl %0,28"
|
276 |
: "=d" (ccode), "=m" (*addr) |
277 |
: "d" (reg1), "a" (addr) |
278 |
: "cc");
|
279 |
return ccode;
|
280 |
} |
281 |
|
282 |
static inline int ssch(struct subchannel_id schid, struct cmd_orb *addr) |
283 |
{ |
284 |
register struct subchannel_id reg1 asm("1") = schid; |
285 |
int ccode = -EIO;
|
286 |
|
287 |
asm volatile( |
288 |
" ssch 0(%2)\n"
|
289 |
"0: ipm %0\n"
|
290 |
" srl %0,28\n"
|
291 |
"1:\n"
|
292 |
: "+d" (ccode)
|
293 |
: "d" (reg1), "a" (addr), "m" (*addr) |
294 |
: "cc", "memory"); |
295 |
return ccode;
|
296 |
} |
297 |
|
298 |
static inline int csch(struct subchannel_id schid) |
299 |
{ |
300 |
register struct subchannel_id reg1 asm("1") = schid; |
301 |
int ccode;
|
302 |
|
303 |
asm volatile( |
304 |
" csch\n"
|
305 |
" ipm %0\n"
|
306 |
" srl %0,28"
|
307 |
: "=d" (ccode)
|
308 |
: "d" (reg1)
|
309 |
: "cc");
|
310 |
return ccode;
|
311 |
} |
312 |
|
313 |
static inline int tpi(struct tpi_info *addr) |
314 |
{ |
315 |
int ccode;
|
316 |
|
317 |
asm volatile( |
318 |
" tpi 0(%2)\n"
|
319 |
" ipm %0\n"
|
320 |
" srl %0,28"
|
321 |
: "=d" (ccode), "=m" (*addr) |
322 |
: "a" (addr)
|
323 |
: "cc");
|
324 |
return ccode;
|
325 |
} |
326 |
|
327 |
static inline int chsc(void *chsc_area) |
328 |
{ |
329 |
typedef struct { char _[4096]; } addr_type; |
330 |
int cc;
|
331 |
|
332 |
asm volatile( |
333 |
" .insn rre,0xb25f0000,%2,0\n"
|
334 |
" ipm %0\n"
|
335 |
" srl %0,28\n"
|
336 |
: "=d" (cc), "=m" (*(addr_type *) chsc_area) |
337 |
: "d" (chsc_area), "m" (*(addr_type *) chsc_area) |
338 |
: "cc");
|
339 |
return cc;
|
340 |
} |
341 |
|
342 |
#endif /* CIO_H */ |