diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2013-06-05 12:59:22 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-06-26 15:10:15 -0400 |
commit | ca4ba153f985d0c1478ccf05ac95314402bc08a7 (patch) | |
tree | 101cdcd952ae59fd42192aad4dd1b9bbfb08238e | |
parent | da5b6cb162b6bef39d76446a5e015d6a111459b1 (diff) |
s390/qdio: cleanup chsc SADC usage
Move the code to issue the set adapter device controls command to
chsc.c and make it accessible for the qdio code via the wrapper
chsc_sadc.
Reviewed-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | drivers/s390/cio/chsc.c | 37 | ||||
-rw-r--r-- | drivers/s390/cio/chsc.h | 22 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.h | 20 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_thinint.c | 48 |
4 files changed, 73 insertions, 54 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index d119d0d87e9b..13299f902676 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <asm/chpid.h> | 20 | #include <asm/chpid.h> |
21 | #include <asm/chsc.h> | 21 | #include <asm/chsc.h> |
22 | #include <asm/crw.h> | 22 | #include <asm/crw.h> |
23 | #include <asm/isc.h> | ||
23 | 24 | ||
24 | #include "css.h" | 25 | #include "css.h" |
25 | #include "cio.h" | 26 | #include "cio.h" |
@@ -167,6 +168,42 @@ int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd) | |||
167 | } | 168 | } |
168 | EXPORT_SYMBOL_GPL(chsc_ssqd); | 169 | EXPORT_SYMBOL_GPL(chsc_ssqd); |
169 | 170 | ||
171 | /** | ||
172 | * chsc_sadc() - set adapter device controls (SADC) | ||
173 | * @schid: id of the subchannel on which SADC is performed | ||
174 | * @scssc: request and response block for SADC | ||
175 | * @summary_indicator_addr: summary indicator address | ||
176 | * @subchannel_indicator_addr: subchannel indicator address | ||
177 | * | ||
178 | * Returns 0 on success. | ||
179 | */ | ||
180 | int chsc_sadc(struct subchannel_id schid, struct chsc_scssc_area *scssc, | ||
181 | u64 summary_indicator_addr, u64 subchannel_indicator_addr) | ||
182 | { | ||
183 | memset(scssc, 0, sizeof(*scssc)); | ||
184 | scssc->request.length = 0x0fe0; | ||
185 | scssc->request.code = 0x0021; | ||
186 | scssc->operation_code = 0; | ||
187 | |||
188 | scssc->summary_indicator_addr = summary_indicator_addr; | ||
189 | scssc->subchannel_indicator_addr = subchannel_indicator_addr; | ||
190 | |||
191 | scssc->ks = PAGE_DEFAULT_KEY >> 4; | ||
192 | scssc->kc = PAGE_DEFAULT_KEY >> 4; | ||
193 | scssc->isc = QDIO_AIRQ_ISC; | ||
194 | scssc->schid = schid; | ||
195 | |||
196 | /* enable the time delay disablement facility */ | ||
197 | if (css_general_characteristics.aif_tdd) | ||
198 | scssc->word_with_d_bit = 0x10000000; | ||
199 | |||
200 | if (chsc(scssc)) | ||
201 | return -EIO; | ||
202 | |||
203 | return chsc_error_from_response(scssc->response.code); | ||
204 | } | ||
205 | EXPORT_SYMBOL_GPL(chsc_sadc); | ||
206 | |||
170 | static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data) | 207 | static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data) |
171 | { | 208 | { |
172 | spin_lock_irq(sch->lock); | 209 | spin_lock_irq(sch->lock); |
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h index 2b88e74e6b65..23d072e70eb2 100644 --- a/drivers/s390/cio/chsc.h +++ b/drivers/s390/cio/chsc.h | |||
@@ -87,6 +87,26 @@ struct chsc_ssqd_area { | |||
87 | struct qdio_ssqd_desc qdio_ssqd; | 87 | struct qdio_ssqd_desc qdio_ssqd; |
88 | } __packed; | 88 | } __packed; |
89 | 89 | ||
90 | struct chsc_scssc_area { | ||
91 | struct chsc_header request; | ||
92 | u16 operation_code; | ||
93 | u16:16; | ||
94 | u32:32; | ||
95 | u32:32; | ||
96 | u64 summary_indicator_addr; | ||
97 | u64 subchannel_indicator_addr; | ||
98 | u32 ks:4; | ||
99 | u32 kc:4; | ||
100 | u32:21; | ||
101 | u32 isc:3; | ||
102 | u32 word_with_d_bit; | ||
103 | u32:32; | ||
104 | struct subchannel_id schid; | ||
105 | u32 reserved[1004]; | ||
106 | struct chsc_header response; | ||
107 | u32:32; | ||
108 | } __packed; | ||
109 | |||
90 | struct chsc_scpd { | 110 | struct chsc_scpd { |
91 | struct chsc_header request; | 111 | struct chsc_header request; |
92 | u32:2; | 112 | u32:2; |
@@ -127,6 +147,8 @@ void chsc_chp_online(struct chp_id chpid); | |||
127 | void chsc_chp_offline(struct chp_id chpid); | 147 | void chsc_chp_offline(struct chp_id chpid); |
128 | int chsc_get_channel_measurement_chars(struct channel_path *chp); | 148 | int chsc_get_channel_measurement_chars(struct channel_path *chp); |
129 | int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd); | 149 | int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd); |
150 | int chsc_sadc(struct subchannel_id schid, struct chsc_scssc_area *scssc, | ||
151 | u64 summary_indicator_addr, u64 subchannel_indicator_addr); | ||
130 | int chsc_error_from_response(int response); | 152 | int chsc_error_from_response(int response); |
131 | 153 | ||
132 | int chsc_siosl(struct subchannel_id schid); | 154 | int chsc_siosl(struct subchannel_id schid); |
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index b8bda2175b6c..8acaae18bd11 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -140,26 +140,6 @@ struct siga_flag { | |||
140 | u8:3; | 140 | u8:3; |
141 | } __attribute__ ((packed)); | 141 | } __attribute__ ((packed)); |
142 | 142 | ||
143 | struct scssc_area { | ||
144 | struct chsc_header request; | ||
145 | u16 operation_code; | ||
146 | u16:16; | ||
147 | u32:32; | ||
148 | u32:32; | ||
149 | u64 summary_indicator_addr; | ||
150 | u64 subchannel_indicator_addr; | ||
151 | u32 ks:4; | ||
152 | u32 kc:4; | ||
153 | u32:21; | ||
154 | u32 isc:3; | ||
155 | u32 word_with_d_bit; | ||
156 | u32:32; | ||
157 | struct subchannel_id schid; | ||
158 | u32 reserved[1004]; | ||
159 | struct chsc_header response; | ||
160 | u32:32; | ||
161 | } __attribute__ ((packed)); | ||
162 | |||
163 | struct qdio_dev_perf_stat { | 143 | struct qdio_dev_perf_stat { |
164 | unsigned int adapter_int; | 144 | unsigned int adapter_int; |
165 | unsigned int qdio_int; | 145 | unsigned int qdio_int; |
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index bde5255200dc..417b2557d83e 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c | |||
@@ -208,51 +208,31 @@ static void tiqdio_thinint_handler(void *alsi, void *data) | |||
208 | 208 | ||
209 | static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset) | 209 | static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset) |
210 | { | 210 | { |
211 | struct scssc_area *scssc_area; | 211 | struct chsc_scssc_area *scssc = (void *)irq_ptr->chsc_page; |
212 | u64 summary_indicator_addr, subchannel_indicator_addr; | ||
212 | int rc; | 213 | int rc; |
213 | 214 | ||
214 | scssc_area = (struct scssc_area *)irq_ptr->chsc_page; | ||
215 | memset(scssc_area, 0, PAGE_SIZE); | ||
216 | |||
217 | if (reset) { | 215 | if (reset) { |
218 | scssc_area->summary_indicator_addr = 0; | 216 | summary_indicator_addr = 0; |
219 | scssc_area->subchannel_indicator_addr = 0; | 217 | subchannel_indicator_addr = 0; |
220 | } else { | 218 | } else { |
221 | scssc_area->summary_indicator_addr = virt_to_phys(tiqdio_alsi); | 219 | summary_indicator_addr = virt_to_phys(tiqdio_alsi); |
222 | scssc_area->subchannel_indicator_addr = | 220 | subchannel_indicator_addr = virt_to_phys(irq_ptr->dsci); |
223 | virt_to_phys(irq_ptr->dsci); | ||
224 | } | 221 | } |
225 | 222 | ||
226 | scssc_area->request = (struct chsc_header) { | 223 | rc = chsc_sadc(irq_ptr->schid, scssc, summary_indicator_addr, |
227 | .length = 0x0fe0, | 224 | subchannel_indicator_addr); |
228 | .code = 0x0021, | ||
229 | }; | ||
230 | scssc_area->operation_code = 0; | ||
231 | scssc_area->ks = PAGE_DEFAULT_KEY >> 4; | ||
232 | scssc_area->kc = PAGE_DEFAULT_KEY >> 4; | ||
233 | scssc_area->isc = QDIO_AIRQ_ISC; | ||
234 | scssc_area->schid = irq_ptr->schid; | ||
235 | |||
236 | /* enable the time delay disablement facility */ | ||
237 | if (css_general_characteristics.aif_tdd) | ||
238 | scssc_area->word_with_d_bit = 0x10000000; | ||
239 | |||
240 | rc = chsc(scssc_area); | ||
241 | if (rc) | ||
242 | return -EIO; | ||
243 | |||
244 | rc = chsc_error_from_response(scssc_area->response.code); | ||
245 | if (rc) { | 225 | if (rc) { |
246 | DBF_ERROR("%4x SSI r:%4x", irq_ptr->schid.sch_no, | 226 | DBF_ERROR("%4x SSI r:%4x", irq_ptr->schid.sch_no, |
247 | scssc_area->response.code); | 227 | scssc->response.code); |
248 | DBF_ERROR_HEX(&scssc_area->response, sizeof(void *)); | 228 | goto out; |
249 | return rc; | ||
250 | } | 229 | } |
251 | 230 | ||
252 | DBF_EVENT("setscind"); | 231 | DBF_EVENT("setscind"); |
253 | DBF_HEX(&scssc_area->summary_indicator_addr, sizeof(unsigned long)); | 232 | DBF_HEX(&summary_indicator_addr, sizeof(summary_indicator_addr)); |
254 | DBF_HEX(&scssc_area->subchannel_indicator_addr, sizeof(unsigned long)); | 233 | DBF_HEX(&subchannel_indicator_addr, sizeof(subchannel_indicator_addr)); |
255 | return 0; | 234 | out: |
235 | return rc; | ||
256 | } | 236 | } |
257 | 237 | ||
258 | /* allocate non-shared indicators and shared indicator */ | 238 | /* allocate non-shared indicators and shared indicator */ |