1#ifndef S390_IO_SCH_H
2#define S390_IO_SCH_H
3
4#include <linux/types.h>
5#include <asm/schid.h>
6#include <asm/ccwdev.h>
7#include <asm/irq.h>
8#include "css.h"
9#include "orb.h"
10
11struct io_subchannel_private {
12 union orb orb;
13 struct ccw1 sense_ccw;
14 struct ccw_device *cdev;
15 struct {
16 unsigned int suspend:1;
17 unsigned int prefetch:1;
18 unsigned int inter:1;
19 } __packed options;
20} __aligned(8);
21
22#define to_io_private(n) ((struct io_subchannel_private *) \
23 dev_get_drvdata(&(n)->dev))
24#define set_io_private(n, p) (dev_set_drvdata(&(n)->dev, p))
25
26static inline struct ccw_device *sch_get_cdev(struct subchannel *sch)
27{
28 struct io_subchannel_private *priv = to_io_private(sch);
29 return priv ? priv->cdev : NULL;
30}
31
32static inline void sch_set_cdev(struct subchannel *sch,
33 struct ccw_device *cdev)
34{
35 struct io_subchannel_private *priv = to_io_private(sch);
36 if (priv)
37 priv->cdev = cdev;
38}
39
40#define MAX_CIWS 8
41
42
43
44
45enum io_status {
46 IO_DONE,
47 IO_RUNNING,
48 IO_STATUS_ERROR,
49 IO_PATH_ERROR,
50 IO_REJECTED,
51 IO_KILLED
52};
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71struct ccw_request {
72 struct ccw1 *cp;
73 unsigned long timeout;
74 u16 maxretries;
75 u8 lpm;
76 int (*check)(struct ccw_device *, void *);
77 enum io_status (*filter)(struct ccw_device *, void *, struct irb *,
78 enum io_status);
79 void (*callback)(struct ccw_device *, void *, int);
80 void *data;
81 unsigned int singlepath:1;
82
83 unsigned int cancel:1;
84 unsigned int done:1;
85 u16 mask;
86 u16 retries;
87 int drc;
88} __attribute__((packed));
89
90
91
92
93struct senseid {
94
95 u8 reserved;
96 u16 cu_type;
97 u8 cu_model;
98 u16 dev_type;
99 u8 dev_model;
100 u8 unused;
101
102 struct ciw ciw[MAX_CIWS];
103} __attribute__ ((packed, aligned(4)));
104
105enum cdev_todo {
106 CDEV_TODO_NOTHING,
107 CDEV_TODO_ENABLE_CMF,
108 CDEV_TODO_REBIND,
109 CDEV_TODO_REGISTER,
110 CDEV_TODO_UNREG,
111 CDEV_TODO_UNREG_EVAL,
112};
113
114#define FAKE_CMD_IRB 1
115#define FAKE_TM_IRB 2
116
117struct ccw_device_private {
118 struct ccw_device *cdev;
119 struct subchannel *sch;
120 int state;
121 atomic_t onoff;
122 struct ccw_dev_id dev_id;
123 struct subchannel_id schid;
124 struct ccw_request req;
125 int iretry;
126 u8 pgid_valid_mask;
127 u8 pgid_todo_mask;
128 u8 pgid_reset_mask;
129 u8 path_noirq_mask;
130
131 u8 path_notoper_mask;
132
133 u8 path_gone_mask;
134 u8 path_new_mask;
135 struct {
136 unsigned int fast:1;
137 unsigned int repall:1;
138 unsigned int pgroup:1;
139 unsigned int force:1;
140 unsigned int mpath:1;
141 } __attribute__ ((packed)) options;
142 struct {
143 unsigned int esid:1;
144 unsigned int dosense:1;
145 unsigned int doverify:1;
146 unsigned int donotify:1;
147 unsigned int recog_done:1;
148 unsigned int fake_irb:2;
149 unsigned int resuming:1;
150 unsigned int pgroup:1;
151 unsigned int mpath:1;
152 unsigned int pgid_unknown:1;
153 unsigned int initialized:1;
154 } __attribute__((packed)) flags;
155 unsigned long intparm;
156 struct qdio_irq *qdio_data;
157 struct irb irb;
158 struct senseid senseid;
159 struct pgid pgid[8];
160 struct ccw1 iccws[2];
161 struct work_struct todo_work;
162 enum cdev_todo todo;
163 wait_queue_head_t wait_q;
164 struct timer_list timer;
165 void *cmb;
166 struct list_head cmb_list;
167 u64 cmb_start_time;
168 void *cmb_wait;
169 enum interruption_class int_class;
170};
171
172static inline int rsch(struct subchannel_id schid)
173{
174 register struct subchannel_id reg1 asm("1") = schid;
175 int ccode;
176
177 asm volatile(
178 " rsch\n"
179 " ipm %0\n"
180 " srl %0,28"
181 : "=d" (ccode)
182 : "d" (reg1)
183 : "cc", "memory");
184 return ccode;
185}
186
187static inline int hsch(struct subchannel_id schid)
188{
189 register struct subchannel_id reg1 asm("1") = schid;
190 int ccode;
191
192 asm volatile(
193 " hsch\n"
194 " ipm %0\n"
195 " srl %0,28"
196 : "=d" (ccode)
197 : "d" (reg1)
198 : "cc");
199 return ccode;
200}
201
202static inline int xsch(struct subchannel_id schid)
203{
204 register struct subchannel_id reg1 asm("1") = schid;
205 int ccode;
206
207 asm volatile(
208 " .insn rre,0xb2760000,%1,0\n"
209 " ipm %0\n"
210 " srl %0,28"
211 : "=d" (ccode)
212 : "d" (reg1)
213 : "cc");
214 return ccode;
215}
216
217#endif
218