diff options
author | Jan Glauber <jang@linux.vnet.ibm.com> | 2008-12-25 07:38:43 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-12-25 07:38:58 -0500 |
commit | bbd50e172f75b1d12ef9b1bcf593b51a44199016 (patch) | |
tree | 85cffdd66bb9f4da36d604d857959964736f3fde /drivers/s390/cio/qdio_setup.c | |
parent | 43c207e6e5b7e591b59294ee4fc9860b0e3de3b8 (diff) |
[S390] qdio: fix qeth port count detection
qeth needs to get the port count information before
qdio has allocated a page for the chsc operation.
Extend qdio_get_ssqd_desc() to store the data in the
specified structure.
Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/qdio_setup.c')
-rw-r--r-- | drivers/s390/cio/qdio_setup.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index a0b6b46e7466..22ee0272a104 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c | |||
@@ -243,22 +243,31 @@ no_qebsm: | |||
243 | QDIO_DBF_TEXT0(0, setup, "noV=V"); | 243 | QDIO_DBF_TEXT0(0, setup, "noV=V"); |
244 | } | 244 | } |
245 | 245 | ||
246 | static int __get_ssqd_info(struct qdio_irq *irq_ptr) | 246 | /* |
247 | * If there is a qdio_irq we use the chsc_page and store the information | ||
248 | * in the qdio_irq, otherwise we copy it to the specified structure. | ||
249 | */ | ||
250 | int qdio_setup_get_ssqd(struct qdio_irq *irq_ptr, | ||
251 | struct subchannel_id *schid, | ||
252 | struct qdio_ssqd_desc *data) | ||
247 | { | 253 | { |
248 | struct chsc_ssqd_area *ssqd; | 254 | struct chsc_ssqd_area *ssqd; |
249 | int rc; | 255 | int rc; |
250 | 256 | ||
251 | QDIO_DBF_TEXT0(0, setup, "getssqd"); | 257 | QDIO_DBF_TEXT0(0, setup, "getssqd"); |
252 | ssqd = (struct chsc_ssqd_area *)irq_ptr->chsc_page; | 258 | if (irq_ptr != NULL) |
259 | ssqd = (struct chsc_ssqd_area *)irq_ptr->chsc_page; | ||
260 | else | ||
261 | ssqd = (struct chsc_ssqd_area *)__get_free_page(GFP_KERNEL); | ||
253 | memset(ssqd, 0, PAGE_SIZE); | 262 | memset(ssqd, 0, PAGE_SIZE); |
254 | 263 | ||
255 | ssqd->request = (struct chsc_header) { | 264 | ssqd->request = (struct chsc_header) { |
256 | .length = 0x0010, | 265 | .length = 0x0010, |
257 | .code = 0x0024, | 266 | .code = 0x0024, |
258 | }; | 267 | }; |
259 | ssqd->first_sch = irq_ptr->schid.sch_no; | 268 | ssqd->first_sch = schid->sch_no; |
260 | ssqd->last_sch = irq_ptr->schid.sch_no; | 269 | ssqd->last_sch = schid->sch_no; |
261 | ssqd->ssid = irq_ptr->schid.ssid; | 270 | ssqd->ssid = schid->ssid; |
262 | 271 | ||
263 | if (chsc(ssqd)) | 272 | if (chsc(ssqd)) |
264 | return -EIO; | 273 | return -EIO; |
@@ -268,11 +277,17 @@ static int __get_ssqd_info(struct qdio_irq *irq_ptr) | |||
268 | 277 | ||
269 | if (!(ssqd->qdio_ssqd.flags & CHSC_FLAG_QDIO_CAPABILITY) || | 278 | if (!(ssqd->qdio_ssqd.flags & CHSC_FLAG_QDIO_CAPABILITY) || |
270 | !(ssqd->qdio_ssqd.flags & CHSC_FLAG_VALIDITY) || | 279 | !(ssqd->qdio_ssqd.flags & CHSC_FLAG_VALIDITY) || |
271 | (ssqd->qdio_ssqd.sch != irq_ptr->schid.sch_no)) | 280 | (ssqd->qdio_ssqd.sch != schid->sch_no)) |
272 | return -EINVAL; | 281 | return -EINVAL; |
273 | 282 | ||
274 | memcpy(&irq_ptr->ssqd_desc, &ssqd->qdio_ssqd, | 283 | if (irq_ptr != NULL) |
275 | sizeof(struct qdio_ssqd_desc)); | 284 | memcpy(&irq_ptr->ssqd_desc, &ssqd->qdio_ssqd, |
285 | sizeof(struct qdio_ssqd_desc)); | ||
286 | else { | ||
287 | memcpy(data, &ssqd->qdio_ssqd, | ||
288 | sizeof(struct qdio_ssqd_desc)); | ||
289 | free_page((unsigned long)ssqd); | ||
290 | } | ||
276 | return 0; | 291 | return 0; |
277 | } | 292 | } |
278 | 293 | ||
@@ -282,7 +297,7 @@ void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr) | |||
282 | char dbf_text[15]; | 297 | char dbf_text[15]; |
283 | int rc; | 298 | int rc; |
284 | 299 | ||
285 | rc = __get_ssqd_info(irq_ptr); | 300 | rc = qdio_setup_get_ssqd(irq_ptr, &irq_ptr->schid, NULL); |
286 | if (rc) { | 301 | if (rc) { |
287 | QDIO_DBF_TEXT2(0, setup, "ssqdasig"); | 302 | QDIO_DBF_TEXT2(0, setup, "ssqdasig"); |
288 | sprintf(dbf_text, "schn%4x", irq_ptr->schid.sch_no); | 303 | sprintf(dbf_text, "schn%4x", irq_ptr->schid.sch_no); |