xref: /openbmc/linux/drivers/s390/cio/io_sch.h (revision b627b4ed)
1 #ifndef S390_IO_SCH_H
2 #define S390_IO_SCH_H
3 
4 #include <asm/schid.h>
5 
6 /*
7  * command-mode operation request block
8  */
9 struct cmd_orb {
10 	u32 intparm;	/* interruption parameter */
11 	u32 key  : 4;	/* flags, like key, suspend control, etc. */
12 	u32 spnd : 1;	/* suspend control */
13 	u32 res1 : 1;	/* reserved */
14 	u32 mod  : 1;	/* modification control */
15 	u32 sync : 1;	/* synchronize control */
16 	u32 fmt  : 1;	/* format control */
17 	u32 pfch : 1;	/* prefetch control */
18 	u32 isic : 1;	/* initial-status-interruption control */
19 	u32 alcc : 1;	/* address-limit-checking control */
20 	u32 ssic : 1;	/* suppress-suspended-interr. control */
21 	u32 res2 : 1;	/* reserved */
22 	u32 c64  : 1;	/* IDAW/QDIO 64 bit control  */
23 	u32 i2k  : 1;	/* IDAW 2/4kB block size control */
24 	u32 lpm  : 8;	/* logical path mask */
25 	u32 ils  : 1;	/* incorrect length */
26 	u32 zero : 6;	/* reserved zeros */
27 	u32 orbx : 1;	/* ORB extension control */
28 	u32 cpa;	/* channel program address */
29 }  __attribute__ ((packed, aligned(4)));
30 
31 /*
32  * transport-mode operation request block
33  */
34 struct tm_orb {
35 	u32 intparm;
36 	u32 key:4;
37 	u32 :9;
38 	u32 b:1;
39 	u32 :2;
40 	u32 lpm:8;
41 	u32 :7;
42 	u32 x:1;
43 	u32 tcw;
44 	u32 prio:8;
45 	u32 :8;
46 	u32 rsvpgm:8;
47 	u32 :8;
48 	u32 :32;
49 	u32 :32;
50 	u32 :32;
51 	u32 :32;
52 }  __attribute__ ((packed, aligned(4)));
53 
54 union orb {
55 	struct cmd_orb cmd;
56 	struct tm_orb tm;
57 }  __attribute__ ((packed, aligned(4)));
58 
59 struct io_subchannel_private {
60 	union orb orb;		/* operation request block */
61 	struct ccw1 sense_ccw;	/* static ccw for sense command */
62 } __attribute__ ((aligned(8)));
63 
64 #define to_io_private(n) ((struct io_subchannel_private *)n->private)
65 #define sch_get_cdev(n) (dev_get_drvdata(&n->dev))
66 #define sch_set_cdev(n, c) (dev_set_drvdata(&n->dev, c))
67 
68 #define MAX_CIWS 8
69 
70 /*
71  * sense-id response buffer layout
72  */
73 struct senseid {
74 	/* common part */
75 	u8  reserved;	/* always 0x'FF' */
76 	u16 cu_type;	/* control unit type */
77 	u8  cu_model;	/* control unit model */
78 	u16 dev_type;	/* device type */
79 	u8  dev_model;	/* device model */
80 	u8  unused;	/* padding byte */
81 	/* extended part */
82 	struct ciw ciw[MAX_CIWS];	/* variable # of CIWs */
83 }  __attribute__ ((packed, aligned(4)));
84 
85 struct ccw_device_private {
86 	struct ccw_device *cdev;
87 	struct subchannel *sch;
88 	int state;		/* device state */
89 	atomic_t onoff;
90 	unsigned long registered;
91 	struct ccw_dev_id dev_id;	/* device id */
92 	struct subchannel_id schid;	/* subchannel number */
93 	u8 imask;		/* lpm mask for SNID/SID/SPGID */
94 	int iretry;		/* retry counter SNID/SID/SPGID */
95 	struct {
96 		unsigned int fast:1;	/* post with "channel end" */
97 		unsigned int repall:1;	/* report every interrupt status */
98 		unsigned int pgroup:1;	/* do path grouping */
99 		unsigned int force:1;	/* allow forced online */
100 	} __attribute__ ((packed)) options;
101 	struct {
102 		unsigned int pgid_single:1; /* use single path for Set PGID */
103 		unsigned int esid:1;	    /* Ext. SenseID supported by HW */
104 		unsigned int dosense:1;	    /* delayed SENSE required */
105 		unsigned int doverify:1;    /* delayed path verification */
106 		unsigned int donotify:1;    /* call notify function */
107 		unsigned int recog_done:1;  /* dev. recog. complete */
108 		unsigned int fake_irb:1;    /* deliver faked irb */
109 		unsigned int intretry:1;    /* retry internal operation */
110 	} __attribute__((packed)) flags;
111 	unsigned long intparm;	/* user interruption parameter */
112 	struct qdio_irq *qdio_data;
113 	struct irb irb;		/* device status */
114 	struct senseid senseid;	/* SenseID info */
115 	struct pgid pgid[8];	/* path group IDs per chpid*/
116 	struct ccw1 iccws[2];	/* ccws for SNID/SID/SPGID commands */
117 	struct work_struct kick_work;
118 	wait_queue_head_t wait_q;
119 	struct timer_list timer;
120 	void *cmb;			/* measurement information */
121 	struct list_head cmb_list;	/* list of measured devices */
122 	u64 cmb_start_time;		/* clock value of cmb reset */
123 	void *cmb_wait;			/* deferred cmb enable/disable */
124 };
125 
126 static inline int ssch(struct subchannel_id schid, union orb *addr)
127 {
128 	register struct subchannel_id reg1 asm("1") = schid;
129 	int ccode = -EIO;
130 
131 	asm volatile(
132 		"	ssch	0(%2)\n"
133 		"0:	ipm	%0\n"
134 		"	srl	%0,28\n"
135 		"1:\n"
136 		EX_TABLE(0b, 1b)
137 		: "+d" (ccode)
138 		: "d" (reg1), "a" (addr), "m" (*addr)
139 		: "cc", "memory");
140 	return ccode;
141 }
142 
143 static inline int rsch(struct subchannel_id schid)
144 {
145 	register struct subchannel_id reg1 asm("1") = schid;
146 	int ccode;
147 
148 	asm volatile(
149 		"	rsch\n"
150 		"	ipm	%0\n"
151 		"	srl	%0,28"
152 		: "=d" (ccode)
153 		: "d" (reg1)
154 		: "cc", "memory");
155 	return ccode;
156 }
157 
158 static inline int csch(struct subchannel_id schid)
159 {
160 	register struct subchannel_id reg1 asm("1") = schid;
161 	int ccode;
162 
163 	asm volatile(
164 		"	csch\n"
165 		"	ipm	%0\n"
166 		"	srl	%0,28"
167 		: "=d" (ccode)
168 		: "d" (reg1)
169 		: "cc");
170 	return ccode;
171 }
172 
173 static inline int hsch(struct subchannel_id schid)
174 {
175 	register struct subchannel_id reg1 asm("1") = schid;
176 	int ccode;
177 
178 	asm volatile(
179 		"	hsch\n"
180 		"	ipm	%0\n"
181 		"	srl	%0,28"
182 		: "=d" (ccode)
183 		: "d" (reg1)
184 		: "cc");
185 	return ccode;
186 }
187 
188 static inline int xsch(struct subchannel_id schid)
189 {
190 	register struct subchannel_id reg1 asm("1") = schid;
191 	int ccode;
192 
193 	asm volatile(
194 		"	.insn	rre,0xb2760000,%1,0\n"
195 		"	ipm	%0\n"
196 		"	srl	%0,28"
197 		: "=d" (ccode)
198 		: "d" (reg1)
199 		: "cc");
200 	return ccode;
201 }
202 
203 #endif
204