Commit da5b6cb1 authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky

s390/qdio: cleanup chsc SSQD usage

Cleanup the function qdio_setup_get_ssqd. Fix some possible
memleaks and an unchecked allocation and create a wrapper
for SSQD in chsc.c .
Reviewed-by: default avatarUrsula Braun <ursula.braun@de.ibm.com>
Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent d475f942
......@@ -144,6 +144,29 @@ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd)
return ret;
}
/**
* chsc_ssqd() - store subchannel QDIO data (SSQD)
* @schid: id of the subchannel on which SSQD is performed
* @ssqd: request and response block for SSQD
*
* Returns 0 on success.
*/
int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd)
{
memset(ssqd, 0, sizeof(*ssqd));
ssqd->request.length = 0x0010;
ssqd->request.code = 0x0024;
ssqd->first_sch = schid.sch_no;
ssqd->last_sch = schid.sch_no;
ssqd->ssid = schid.ssid;
if (chsc(ssqd))
return -EIO;
return chsc_error_from_response(ssqd->response.code);
}
EXPORT_SYMBOL_GPL(chsc_ssqd);
static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data)
{
spin_lock_irq(sch->lock);
......
......@@ -7,6 +7,7 @@
#include <asm/chpid.h>
#include <asm/chsc.h>
#include <asm/schid.h>
#include <asm/qdio.h>
#define CHSC_SDA_OC_MSS 0x2
......@@ -72,6 +73,20 @@ struct chsc_ssd_info {
u16 fla[8];
};
struct chsc_ssqd_area {
struct chsc_header request;
u16:10;
u8 ssid:2;
u8 fmt:4;
u16 first_sch;
u16:16;
u16 last_sch;
u32:32;
struct chsc_header response;
u32:32;
struct qdio_ssqd_desc qdio_ssqd;
} __packed;
struct chsc_scpd {
struct chsc_header request;
u32:2;
......@@ -111,7 +126,7 @@ int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid,
void chsc_chp_online(struct chp_id chpid);
void chsc_chp_offline(struct chp_id chpid);
int chsc_get_channel_measurement_chars(struct channel_path *chp);
int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd);
int chsc_error_from_response(int response);
int chsc_siosl(struct subchannel_id schid);
......
......@@ -140,20 +140,6 @@ struct siga_flag {
u8:3;
} __attribute__ ((packed));
struct chsc_ssqd_area {
struct chsc_header request;
u16:10;
u8 ssid:2;
u8 fmt:4;
u16 first_sch;
u16:16;
u16 last_sch;
u32:32;
struct chsc_header response;
u32:32;
struct qdio_ssqd_desc qdio_ssqd;
} __attribute__ ((packed));
struct scssc_area {
struct chsc_header request;
u16 operation_code;
......
......@@ -254,40 +254,31 @@ int qdio_setup_get_ssqd(struct qdio_irq *irq_ptr,
int rc;
DBF_EVENT("getssqd:%4x", schid->sch_no);
if (irq_ptr != NULL)
ssqd = (struct chsc_ssqd_area *)irq_ptr->chsc_page;
else
if (!irq_ptr) {
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 = schid->sch_no;
ssqd->last_sch = schid->sch_no;
ssqd->ssid = schid->ssid;
if (chsc(ssqd))
return -EIO;
rc = chsc_error_from_response(ssqd->response.code);
if (!ssqd)
return -ENOMEM;
} else {
ssqd = (struct chsc_ssqd_area *)irq_ptr->chsc_page;
}
rc = chsc_ssqd(*schid, ssqd);
if (rc)
return rc;
goto out;
if (!(ssqd->qdio_ssqd.flags & CHSC_FLAG_QDIO_CAPABILITY) ||
!(ssqd->qdio_ssqd.flags & CHSC_FLAG_VALIDITY) ||
(ssqd->qdio_ssqd.sch != schid->sch_no))
return -EINVAL;
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));
rc = -EINVAL;
if (!rc)
memcpy(data, &ssqd->qdio_ssqd, sizeof(*data));
out:
if (!irq_ptr)
free_page((unsigned long)ssqd);
}
return 0;
return rc;
}
void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr)
......@@ -295,7 +286,7 @@ void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr)
unsigned char qdioac;
int rc;
rc = qdio_setup_get_ssqd(irq_ptr, &irq_ptr->schid, NULL);
rc = qdio_setup_get_ssqd(irq_ptr, &irq_ptr->schid, &irq_ptr->ssqd_desc);
if (rc) {
DBF_ERROR("%4x ssqd ERR", irq_ptr->schid.sch_no);
DBF_ERROR("rc:%x", rc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment