s390/qdio: cleanup chsc SADC usage
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Wed, 5 Jun 2013 16:59:22 +0000 (18:59 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 26 Jun 2013 19:10:15 +0000 (21:10 +0200)
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>
drivers/s390/cio/chsc.c
drivers/s390/cio/chsc.h
drivers/s390/cio/qdio.h
drivers/s390/cio/qdio_thinint.c

index d119d0d87e9bf68b784b615d60122ad63f8770d7..13299f902676e647d43dce13d95f864c81300f53 100644 (file)
@@ -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);
index 2b88e74e6b6559d6c07ad544c9b81535fb7ae259..23d072e70eb2f4e87e1a9dbefcd244c35a98b977 100644 (file)
@@ -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);
index b8bda2175b6ce80fdbe74a9188fff633c7e02a72..8acaae18bd11c404d4b6a25e4771846c39e4c837 100644 (file)
@@ -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;
index bde5255200dc3864687fa955e69440503bd46b4b..417b2557d83ea5745657b33d34ec35d7cbb608f0 100644 (file)
@@ -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 */