xref: /openbmc/linux/drivers/s390/cio/io_sch.h (revision 6ee73861)
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 		unsigned int resuming:1;    /* recognition while resume */
111 	} __attribute__((packed)) flags;
112 	unsigned long intparm;	/* user interruption parameter */
113 	struct qdio_irq *qdio_data;
114 	struct irb irb;		/* device status */
115 	struct senseid senseid;	/* SenseID info */
116 	struct pgid pgid[8];	/* path group IDs per chpid*/
117 	struct ccw1 iccws[2];	/* ccws for SNID/SID/SPGID commands */
118 	struct work_struct kick_work;
119 	wait_queue_head_t wait_q;
120 	struct timer_list timer;
121 	void *cmb;			/* measurement information */
122 	struct list_head cmb_list;	/* list of measured devices */
123 	u64 cmb_start_time;		/* clock value of cmb reset */
124 	void *cmb_wait;			/* deferred cmb enable/disable */
125 };
126 
127 static inline int ssch(struct subchannel_id schid, union orb *addr)
128 {
129 	register struct subchannel_id reg1 asm("1") = schid;
130 	int ccode = -EIO;
131 
132 	asm volatile(
133 		"	ssch	0(%2)\n"
134 		"0:	ipm	%0\n"
135 		"	srl	%0,28\n"
136 		"1:\n"
137 		EX_TABLE(0b, 1b)
138 		: "+d" (ccode)
139 		: "d" (reg1), "a" (addr), "m" (*addr)
140 		: "cc", "memory");
141 	return ccode;
142 }
143 
144 static inline int rsch(struct subchannel_id schid)
145 {
146 	register struct subchannel_id reg1 asm("1") = schid;
147 	int ccode;
148 
149 	asm volatile(
150 		"	rsch\n"
151 		"	ipm	%0\n"
152 		"	srl	%0,28"
153 		: "=d" (ccode)
154 		: "d" (reg1)
155 		: "cc", "memory");
156 	return ccode;
157 }
158 
159 static inline int csch(struct subchannel_id schid)
160 {
161 	register struct subchannel_id reg1 asm("1") = schid;
162 	int ccode;
163 
164 	asm volatile(
165 		"	csch\n"
166 		"	ipm	%0\n"
167 		"	srl	%0,28"
168 		: "=d" (ccode)
169 		: "d" (reg1)
170 		: "cc");
171 	return ccode;
172 }
173 
174 static inline int hsch(struct subchannel_id schid)
175 {
176 	register struct subchannel_id reg1 asm("1") = schid;
177 	int ccode;
178 
179 	asm volatile(
180 		"	hsch\n"
181 		"	ipm	%0\n"
182 		"	srl	%0,28"
183 		: "=d" (ccode)
184 		: "d" (reg1)
185 		: "cc");
186 	return ccode;
187 }
188 
189 static inline int xsch(struct subchannel_id schid)
190 {
191 	register struct subchannel_id reg1 asm("1") = schid;
192 	int ccode;
193 
194 	asm volatile(
195 		"	.insn	rre,0xb2760000,%1,0\n"
196 		"	ipm	%0\n"
197 		"	srl	%0,28"
198 		: "=d" (ccode)
199 		: "d" (reg1)
200 		: "cc");
201 	return ccode;
202 }
203 
204 #endif
205