aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2013-06-05 12:59:22 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-06-26 15:10:15 -0400
commitca4ba153f985d0c1478ccf05ac95314402bc08a7 (patch)
tree101cdcd952ae59fd42192aad4dd1b9bbfb08238e
parentda5b6cb162b6bef39d76446a5e015d6a111459b1 (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.c37
-rw-r--r--drivers/s390/cio/chsc.h22
-rw-r--r--drivers/s390/cio/qdio.h20
-rw-r--r--drivers/s390/cio/qdio_thinint.c48
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}
168EXPORT_SYMBOL_GPL(chsc_ssqd); 169EXPORT_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 */
180int 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}
205EXPORT_SYMBOL_GPL(chsc_sadc);
206
170static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data) 207static 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
90struct 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
90struct chsc_scpd { 110struct 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);
127void chsc_chp_offline(struct chp_id chpid); 147void chsc_chp_offline(struct chp_id chpid);
128int chsc_get_channel_measurement_chars(struct channel_path *chp); 148int chsc_get_channel_measurement_chars(struct channel_path *chp);
129int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd); 149int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd);
150int chsc_sadc(struct subchannel_id schid, struct chsc_scssc_area *scssc,
151 u64 summary_indicator_addr, u64 subchannel_indicator_addr);
130int chsc_error_from_response(int response); 152int chsc_error_from_response(int response);
131 153
132int chsc_siosl(struct subchannel_id schid); 154int 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
143struct 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
163struct qdio_dev_perf_stat { 143struct 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
209static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset) 209static 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; 234out:
235 return rc;
256} 236}
257 237
258/* allocate non-shared indicators and shared indicator */ 238/* allocate non-shared indicators and shared indicator */