Ver código fonte

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>
Sebastian Ott 12 anos atrás
pai
commit
ca4ba153f9

+ 37 - 0
drivers/s390/cio/chsc.c

@@ -20,6 +20,7 @@
 #include <asm/chpid.h>
 #include <asm/chsc.h>
 #include <asm/crw.h>
+#include <asm/isc.h>
 
 #include "css.h"
 #include "cio.h"
@@ -167,6 +168,42 @@ int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd)
 }
 EXPORT_SYMBOL_GPL(chsc_ssqd);
 
+/**
+ * chsc_sadc() - set adapter device controls (SADC)
+ * @schid: id of the subchannel on which SADC is performed
+ * @scssc: request and response block for SADC
+ * @summary_indicator_addr: summary indicator address
+ * @subchannel_indicator_addr: subchannel indicator address
+ *
+ * Returns 0 on success.
+ */
+int chsc_sadc(struct subchannel_id schid, struct chsc_scssc_area *scssc,
+	      u64 summary_indicator_addr, u64 subchannel_indicator_addr)
+{
+	memset(scssc, 0, sizeof(*scssc));
+	scssc->request.length = 0x0fe0;
+	scssc->request.code = 0x0021;
+	scssc->operation_code = 0;
+
+	scssc->summary_indicator_addr = summary_indicator_addr;
+	scssc->subchannel_indicator_addr = subchannel_indicator_addr;
+
+	scssc->ks = PAGE_DEFAULT_KEY >> 4;
+	scssc->kc = PAGE_DEFAULT_KEY >> 4;
+	scssc->isc = QDIO_AIRQ_ISC;
+	scssc->schid = schid;
+
+	/* enable the time delay disablement facility */
+	if (css_general_characteristics.aif_tdd)
+		scssc->word_with_d_bit = 0x10000000;
+
+	if (chsc(scssc))
+		return -EIO;
+
+	return chsc_error_from_response(scssc->response.code);
+}
+EXPORT_SYMBOL_GPL(chsc_sadc);
+
 static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data)
 {
 	spin_lock_irq(sch->lock);

+ 22 - 0
drivers/s390/cio/chsc.h

@@ -87,6 +87,26 @@ struct chsc_ssqd_area {
 	struct qdio_ssqd_desc qdio_ssqd;
 } __packed;
 
+struct chsc_scssc_area {
+	struct chsc_header request;
+	u16 operation_code;
+	u16:16;
+	u32:32;
+	u32:32;
+	u64 summary_indicator_addr;
+	u64 subchannel_indicator_addr;
+	u32 ks:4;
+	u32 kc:4;
+	u32:21;
+	u32 isc:3;
+	u32 word_with_d_bit;
+	u32:32;
+	struct subchannel_id schid;
+	u32 reserved[1004];
+	struct chsc_header response;
+	u32:32;
+} __packed;
+
 struct chsc_scpd {
 	struct chsc_header request;
 	u32:2;
@@ -127,6 +147,8 @@ 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_sadc(struct subchannel_id schid, struct chsc_scssc_area *scssc,
+	      u64 summary_indicator_addr, u64 subchannel_indicator_addr);
 int chsc_error_from_response(int response);
 
 int chsc_siosl(struct subchannel_id schid);

+ 0 - 20
drivers/s390/cio/qdio.h

@@ -140,26 +140,6 @@ struct siga_flag {
 	u8:3;
 } __attribute__ ((packed));
 
-struct scssc_area {
-	struct chsc_header request;
-	u16 operation_code;
-	u16:16;
-	u32:32;
-	u32:32;
-	u64 summary_indicator_addr;
-	u64 subchannel_indicator_addr;
-	u32 ks:4;
-	u32 kc:4;
-	u32:21;
-	u32 isc:3;
-	u32 word_with_d_bit;
-	u32:32;
-	struct subchannel_id schid;
-	u32 reserved[1004];
-	struct chsc_header response;
-	u32:32;
-} __attribute__ ((packed));
-
 struct qdio_dev_perf_stat {
 	unsigned int adapter_int;
 	unsigned int qdio_int;

+ 14 - 34
drivers/s390/cio/qdio_thinint.c

@@ -208,51 +208,31 @@ static void tiqdio_thinint_handler(void *alsi, void *data)
 
 static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset)
 {
-	struct scssc_area *scssc_area;
+	struct chsc_scssc_area *scssc = (void *)irq_ptr->chsc_page;
+	u64 summary_indicator_addr, subchannel_indicator_addr;
 	int rc;
 
-	scssc_area = (struct scssc_area *)irq_ptr->chsc_page;
-	memset(scssc_area, 0, PAGE_SIZE);
-
 	if (reset) {
-		scssc_area->summary_indicator_addr = 0;
-		scssc_area->subchannel_indicator_addr = 0;
+		summary_indicator_addr = 0;
+		subchannel_indicator_addr = 0;
 	} else {
-		scssc_area->summary_indicator_addr = virt_to_phys(tiqdio_alsi);
-		scssc_area->subchannel_indicator_addr =
-			virt_to_phys(irq_ptr->dsci);
+		summary_indicator_addr = virt_to_phys(tiqdio_alsi);
+		subchannel_indicator_addr = virt_to_phys(irq_ptr->dsci);
 	}
 
-	scssc_area->request = (struct chsc_header) {
-		.length = 0x0fe0,
-		.code	= 0x0021,
-	};
-	scssc_area->operation_code = 0;
-	scssc_area->ks = PAGE_DEFAULT_KEY >> 4;
-	scssc_area->kc = PAGE_DEFAULT_KEY >> 4;
-	scssc_area->isc = QDIO_AIRQ_ISC;
-	scssc_area->schid = irq_ptr->schid;
-
-	/* enable the time delay disablement facility */
-	if (css_general_characteristics.aif_tdd)
-		scssc_area->word_with_d_bit = 0x10000000;
-
-	rc = chsc(scssc_area);
-	if (rc)
-		return -EIO;
-
-	rc = chsc_error_from_response(scssc_area->response.code);
+	rc = chsc_sadc(irq_ptr->schid, scssc, summary_indicator_addr,
+		       subchannel_indicator_addr);
 	if (rc) {
 		DBF_ERROR("%4x SSI r:%4x", irq_ptr->schid.sch_no,
-			  scssc_area->response.code);
-		DBF_ERROR_HEX(&scssc_area->response, sizeof(void *));
-		return rc;
+			  scssc->response.code);
+		goto out;
 	}
 
 	DBF_EVENT("setscind");
-	DBF_HEX(&scssc_area->summary_indicator_addr, sizeof(unsigned long));
-	DBF_HEX(&scssc_area->subchannel_indicator_addr,	sizeof(unsigned long));
-	return 0;
+	DBF_HEX(&summary_indicator_addr, sizeof(summary_indicator_addr));
+	DBF_HEX(&subchannel_indicator_addr, sizeof(subchannel_indicator_addr));
+out:
+	return rc;
 }
 
 /* allocate non-shared indicators and shared indicator */