diff options
author | Jan Glauber <jang@linux.vnet.ibm.com> | 2008-12-25 13:38:43 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-12-25 13:38:58 +0100 |
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 a0b6b46e746..22ee0272a10 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c @@ -243,22 +243,31 @@ no_qebsm: QDIO_DBF_TEXT0(0, setup, "noV=V"); } -static int __get_ssqd_info(struct qdio_irq *irq_ptr) +/* + * If there is a qdio_irq we use the chsc_page and store the information + * in the qdio_irq, otherwise we copy it to the specified structure. + */ +int qdio_setup_get_ssqd(struct qdio_irq *irq_ptr, + struct subchannel_id *schid, + struct qdio_ssqd_desc *data) { struct chsc_ssqd_area *ssqd; int rc; QDIO_DBF_TEXT0(0, setup, "getssqd"); - ssqd = (struct chsc_ssqd_area *)irq_ptr->chsc_page; + if (irq_ptr != NULL) + ssqd = (struct chsc_ssqd_area *)irq_ptr->chsc_page; + else + ssqd = (struct chsc_ssqd_area *)__get_free_page(GFP_KERNEL); memset(ssqd, 0, PAGE_SIZE); ssqd->request = (struct chsc_header) { .length = 0x0010, .code = 0x0024, }; - ssqd->first_sch = irq_ptr->schid.sch_no; - ssqd->last_sch = irq_ptr->schid.sch_no; - ssqd->ssid = irq_ptr->schid.ssid; + ssqd->first_sch = schid->sch_no; + ssqd->last_sch = schid->sch_no; + ssqd->ssid = schid->ssid; if (chsc(ssqd)) return -EIO; @@ -268,11 +277,17 @@ static int __get_ssqd_info(struct qdio_irq *irq_ptr) if (!(ssqd->qdio_ssqd.flags & CHSC_FLAG_QDIO_CAPABILITY) || !(ssqd->qdio_ssqd.flags & CHSC_FLAG_VALIDITY) || - (ssqd->qdio_ssqd.sch != irq_ptr->schid.sch_no)) + (ssqd->qdio_ssqd.sch != schid->sch_no)) return -EINVAL; - memcpy(&irq_ptr->ssqd_desc, &ssqd->qdio_ssqd, - sizeof(struct qdio_ssqd_desc)); + if (irq_ptr != NULL) + memcpy(&irq_ptr->ssqd_desc, &ssqd->qdio_ssqd, + sizeof(struct qdio_ssqd_desc)); + else { + memcpy(data, &ssqd->qdio_ssqd, + sizeof(struct qdio_ssqd_desc)); + free_page((unsigned long)ssqd); + } return 0; } @@ -282,7 +297,7 @@ void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr) char dbf_text[15]; int rc; - rc = __get_ssqd_info(irq_ptr); + rc = qdio_setup_get_ssqd(irq_ptr, &irq_ptr->schid, NULL); if (rc) { QDIO_DBF_TEXT2(0, setup, "ssqdasig"); sprintf(dbf_text, "schn%4x", irq_ptr->schid.sch_no); |