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>
This commit is contained in:
Sebastian Ott 2013-06-05 18:59:22 +02:00 committed by Martin Schwidefsky
parent da5b6cb162
commit ca4ba153f9
4 changed files with 73 additions and 54 deletions

View File

@ -20,6 +20,7 @@
#include <asm/chpid.h> #include <asm/chpid.h>
#include <asm/chsc.h> #include <asm/chsc.h>
#include <asm/crw.h> #include <asm/crw.h>
#include <asm/isc.h>
#include "css.h" #include "css.h"
#include "cio.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); 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) static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data)
{ {
spin_lock_irq(sch->lock); spin_lock_irq(sch->lock);

View File

@ -87,6 +87,26 @@ struct chsc_ssqd_area {
struct qdio_ssqd_desc qdio_ssqd; struct qdio_ssqd_desc qdio_ssqd;
} __packed; } __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_scpd {
struct chsc_header request; struct chsc_header request;
u32:2; u32:2;
@ -127,6 +147,8 @@ void chsc_chp_online(struct chp_id chpid);
void chsc_chp_offline(struct chp_id chpid); void chsc_chp_offline(struct chp_id chpid);
int chsc_get_channel_measurement_chars(struct channel_path *chp); int chsc_get_channel_measurement_chars(struct channel_path *chp);
int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd); 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_error_from_response(int response);
int chsc_siosl(struct subchannel_id schid); int chsc_siosl(struct subchannel_id schid);

View File

@ -140,26 +140,6 @@ struct siga_flag {
u8:3; u8:3;
} __attribute__ ((packed)); } __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 { struct qdio_dev_perf_stat {
unsigned int adapter_int; unsigned int adapter_int;
unsigned int qdio_int; unsigned int qdio_int;

View 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) 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; int rc;
scssc_area = (struct scssc_area *)irq_ptr->chsc_page;
memset(scssc_area, 0, PAGE_SIZE);
if (reset) { if (reset) {
scssc_area->summary_indicator_addr = 0; summary_indicator_addr = 0;
scssc_area->subchannel_indicator_addr = 0; subchannel_indicator_addr = 0;
} else { } else {
scssc_area->summary_indicator_addr = virt_to_phys(tiqdio_alsi); summary_indicator_addr = virt_to_phys(tiqdio_alsi);
scssc_area->subchannel_indicator_addr = subchannel_indicator_addr = virt_to_phys(irq_ptr->dsci);
virt_to_phys(irq_ptr->dsci);
} }
scssc_area->request = (struct chsc_header) { rc = chsc_sadc(irq_ptr->schid, scssc, summary_indicator_addr,
.length = 0x0fe0, subchannel_indicator_addr);
.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);
if (rc) { if (rc) {
DBF_ERROR("%4x SSI r:%4x", irq_ptr->schid.sch_no, DBF_ERROR("%4x SSI r:%4x", irq_ptr->schid.sch_no,
scssc_area->response.code); scssc->response.code);
DBF_ERROR_HEX(&scssc_area->response, sizeof(void *)); goto out;
return rc;
} }
DBF_EVENT("setscind"); DBF_EVENT("setscind");
DBF_HEX(&scssc_area->summary_indicator_addr, sizeof(unsigned long)); DBF_HEX(&summary_indicator_addr, sizeof(summary_indicator_addr));
DBF_HEX(&scssc_area->subchannel_indicator_addr, sizeof(unsigned long)); DBF_HEX(&subchannel_indicator_addr, sizeof(subchannel_indicator_addr));
return 0; out:
return rc;
} }
/* allocate non-shared indicators and shared indicator */ /* allocate non-shared indicators and shared indicator */