Commit | Line | Data |
---|---|---|
cd6b4f27 CH |
1 | #ifndef S390_IO_SCH_H |
2 | #define S390_IO_SCH_H | |
3 | ||
9d92a7e1 | 4 | #include <asm/schid.h> |
cd6b4f27 CH |
5 | |
6 | /* | |
83262d63 | 7 | * command-mode operation request block |
cd6b4f27 | 8 | */ |
83262d63 | 9 | struct cmd_orb { |
cd6b4f27 CH |
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 | ||
83262d63 PO |
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 | ||
cd6b4f27 | 59 | struct io_subchannel_private { |
83262d63 | 60 | union orb orb; /* operation request block */ |
cd6b4f27 CH |
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) | |
db6a6423 CH |
65 | #define sch_get_cdev(n) (dev_get_drvdata(&n->dev)) |
66 | #define sch_set_cdev(n, c) (dev_set_drvdata(&n->dev, c)) | |
cd6b4f27 CH |
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 | ||
f9c9fe3e | 126 | static inline int ssch(struct subchannel_id schid, union orb *addr) |
cd6b4f27 CH |
127 | { |
128 | register struct subchannel_id reg1 asm("1") = schid; | |
83262d63 | 129 | int ccode = -EIO; |
cd6b4f27 CH |
130 | |
131 | asm volatile( | |
132 | " ssch 0(%2)\n" | |
83262d63 PO |
133 | "0: ipm %0\n" |
134 | " srl %0,28\n" | |
135 | "1:\n" | |
136 | EX_TABLE(0b, 1b) | |
f9c9fe3e PO |
137 | : "+d" (ccode) |
138 | : "d" (reg1), "a" (addr), "m" (*addr) | |
139 | : "cc", "memory"); | |
cd6b4f27 CH |
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" | |
f9c9fe3e PO |
152 | : "=d" (ccode) |
153 | : "d" (reg1) | |
154 | : "cc", "memory"); | |
cd6b4f27 CH |
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" | |
f9c9fe3e PO |
167 | : "=d" (ccode) |
168 | : "d" (reg1) | |
169 | : "cc"); | |
cd6b4f27 CH |
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" | |
f9c9fe3e PO |
182 | : "=d" (ccode) |
183 | : "d" (reg1) | |
184 | : "cc"); | |
cd6b4f27 CH |
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" | |
f9c9fe3e PO |
197 | : "=d" (ccode) |
198 | : "d" (reg1) | |
199 | : "cc"); | |
cd6b4f27 CH |
200 | return ccode; |
201 | } | |
202 | ||
203 | #endif |