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