Commit a817d98d authored by Peter Oberparleiter's avatar Peter Oberparleiter Committed by Alexander Gordeev

s390/cio: rework channel-utilization-block handling

Convert channel-utilization-block (CUB) address variables from separate
named fields to arrays of addresses. Also simplify error handling and
introduce named constants. This is done in preparation of introducing
additional CUBs.

Note: With this change the __packed annotation of secm_area is required
to prevent an alignment hole that would otherwise occur due to the
switch from u32 to dma64_t.
Reviewed-by: default avatarVineeth Vijayan <vneethv@linux.ibm.com>
Acked-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarPeter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
parent d35c34bb
...@@ -161,12 +161,12 @@ static void chp_measurement_copy_block(struct cmg_entry *buf, ...@@ -161,12 +161,12 @@ static void chp_measurement_copy_block(struct cmg_entry *buf,
struct cmg_entry *entry, reference_buf; struct cmg_entry *entry, reference_buf;
int idx; int idx;
if (chpid.id < 128) { if (chpid.id < CSS_CUES_PER_PAGE) {
area = css->cub_addr1; area = css->cub[0];
idx = chpid.id; idx = chpid.id;
} else { } else {
area = css->cub_addr2; area = css->cub[1];
idx = chpid.id - 128; idx = chpid.id - CSS_CUES_PER_PAGE;
} }
entry = area + (idx * sizeof(struct cmg_entry)); entry = area + (idx * sizeof(struct cmg_entry));
do { do {
......
...@@ -874,19 +874,16 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable) ...@@ -874,19 +874,16 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable)
u32 : 30; u32 : 30;
u32 key : 4; u32 key : 4;
u32 : 28; u32 : 28;
u32 zeroes1; dma64_t cub[CSS_NUM_CUB_PAGES];
dma32_t cub_addr1;
u32 zeroes2;
dma32_t cub_addr2;
u32 reserved[13]; u32 reserved[13];
struct chsc_header response; struct chsc_header response;
u32 status : 8; u32 status : 8;
u32 : 4; u32 : 4;
u32 fmt : 4; u32 fmt : 4;
u32 : 16; u32 : 16;
} *secm_area; } __packed *secm_area;
unsigned long flags; unsigned long flags;
int ret, ccode; int ret, ccode, i;
spin_lock_irqsave(&chsc_page_lock, flags); spin_lock_irqsave(&chsc_page_lock, flags);
memset(chsc_page, 0, PAGE_SIZE); memset(chsc_page, 0, PAGE_SIZE);
...@@ -895,8 +892,9 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable) ...@@ -895,8 +892,9 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable)
secm_area->request.code = 0x0016; secm_area->request.code = 0x0016;
secm_area->key = PAGE_DEFAULT_KEY >> 4; secm_area->key = PAGE_DEFAULT_KEY >> 4;
secm_area->cub_addr1 = virt_to_dma32(css->cub_addr1);
secm_area->cub_addr2 = virt_to_dma32(css->cub_addr2); for (i = 0; i < CSS_NUM_CUB_PAGES; i++)
secm_area->cub[i] = (__force dma64_t)virt_to_dma32(css->cub[i]);
secm_area->operation_code = enable ? 0 : 1; secm_area->operation_code = enable ? 0 : 1;
...@@ -922,19 +920,38 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable) ...@@ -922,19 +920,38 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable)
return ret; return ret;
} }
static int cub_alloc(struct channel_subsystem *css)
{
int i;
for (i = 0; i < CSS_NUM_CUB_PAGES; i++) {
css->cub[i] = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!css->cub[i])
return -ENOMEM;
}
return 0;
}
static void cub_free(struct channel_subsystem *css)
{
int i;
for (i = 0; i < CSS_NUM_CUB_PAGES; i++) {
free_page((unsigned long)css->cub[i]);
css->cub[i] = NULL;
}
}
int int
chsc_secm(struct channel_subsystem *css, int enable) chsc_secm(struct channel_subsystem *css, int enable)
{ {
int ret; int ret;
if (enable && !css->cm_enabled) { if (enable && !css->cm_enabled) {
css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); ret = cub_alloc(css);
css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); if (ret)
if (!css->cub_addr1 || !css->cub_addr2) { goto out;
free_page((unsigned long)css->cub_addr1);
free_page((unsigned long)css->cub_addr2);
return -ENOMEM;
}
} }
ret = __chsc_do_secm(css, enable); ret = __chsc_do_secm(css, enable);
if (!ret) { if (!ret) {
...@@ -948,10 +965,11 @@ chsc_secm(struct channel_subsystem *css, int enable) ...@@ -948,10 +965,11 @@ chsc_secm(struct channel_subsystem *css, int enable)
} else } else
chsc_remove_cmg_attr(css); chsc_remove_cmg_attr(css);
} }
if (!css->cm_enabled) {
free_page((unsigned long)css->cub_addr1); out:
free_page((unsigned long)css->cub_addr2); if (!css->cm_enabled)
} cub_free(css);
return ret; return ret;
} }
......
...@@ -34,6 +34,13 @@ ...@@ -34,6 +34,13 @@
#define SNID_STATE3_MULTI_PATH 1 #define SNID_STATE3_MULTI_PATH 1
#define SNID_STATE3_SINGLE_PATH 0 #define SNID_STATE3_SINGLE_PATH 0
/*
* Miscellaneous constants
*/
#define CSS_NUM_CUB_PAGES 2
#define CSS_CUES_PER_PAGE 128
/* /*
* Conditions used to specify which subchannels need evaluation * Conditions used to specify which subchannels need evaluation
*/ */
...@@ -122,8 +129,7 @@ struct channel_subsystem { ...@@ -122,8 +129,7 @@ struct channel_subsystem {
struct mutex mutex; struct mutex mutex;
/* channel measurement related */ /* channel measurement related */
int cm_enabled; int cm_enabled;
void *cub_addr1; void *cub[CSS_NUM_CUB_PAGES];
void *cub_addr2;
/* for orphaned ccw devices */ /* for orphaned ccw devices */
struct subchannel *pseudo_subchannel; struct subchannel *pseudo_subchannel;
}; };
......
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