提交 34196f82 编写于 作者: S Sebastian Ott 提交者: Martin Schwidefsky

[S390] chsc: consolidate memory allocations

Most wrappers around the channel subsystem call have their own logic
to allocate memory (with proper alignment) or use preallocated or
static memory. This patch converts most users of the channel
subsystem call to use the same preallocated page (proteced by a
spinlock).

Note: The sei_page which is used in our crw handler to call
"store event information" has to coexist, since
a) in crw context, while accessing the sei_page, sleeping is allowed
   (which will conflict with the spinlock protection of the chsc_page)
b) in crw context, while accessing the sei_page, channel subsystem
   calls are allowed (which itself would require the page).
Signed-off-by: NSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: NMartin Schwidefsky <schwidefsky@de.ibm.com>
上级 34aec07c
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
#include "chsc.h" #include "chsc.h"
static void *sei_page; static void *sei_page;
static DEFINE_SPINLOCK(siosl_lock); static void *chsc_page;
static DEFINE_SPINLOCK(sda_lock); static DEFINE_SPINLOCK(chsc_page_lock);
/** /**
* chsc_error_from_response() - convert a chsc response to an error * chsc_error_from_response() - convert a chsc response to an error
...@@ -85,17 +85,15 @@ struct chsc_ssd_area { ...@@ -85,17 +85,15 @@ struct chsc_ssd_area {
int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd) int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd)
{ {
unsigned long page;
struct chsc_ssd_area *ssd_area; struct chsc_ssd_area *ssd_area;
int ccode; int ccode;
int ret; int ret;
int i; int i;
int mask; int mask;
page = get_zeroed_page(GFP_KERNEL | GFP_DMA); spin_lock_irq(&chsc_page_lock);
if (!page) memset(chsc_page, 0, PAGE_SIZE);
return -ENOMEM; ssd_area = chsc_page;
ssd_area = (struct chsc_ssd_area *) page;
ssd_area->request.length = 0x0010; ssd_area->request.length = 0x0010;
ssd_area->request.code = 0x0004; ssd_area->request.code = 0x0004;
ssd_area->ssid = schid.ssid; ssd_area->ssid = schid.ssid;
...@@ -106,25 +104,25 @@ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd) ...@@ -106,25 +104,25 @@ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd)
/* Check response. */ /* Check response. */
if (ccode > 0) { if (ccode > 0) {
ret = (ccode == 3) ? -ENODEV : -EBUSY; ret = (ccode == 3) ? -ENODEV : -EBUSY;
goto out_free; goto out;
} }
ret = chsc_error_from_response(ssd_area->response.code); ret = chsc_error_from_response(ssd_area->response.code);
if (ret != 0) { if (ret != 0) {
CIO_MSG_EVENT(2, "chsc: ssd failed for 0.%x.%04x (rc=%04x)\n", CIO_MSG_EVENT(2, "chsc: ssd failed for 0.%x.%04x (rc=%04x)\n",
schid.ssid, schid.sch_no, schid.ssid, schid.sch_no,
ssd_area->response.code); ssd_area->response.code);
goto out_free; goto out;
} }
if (!ssd_area->sch_valid) { if (!ssd_area->sch_valid) {
ret = -ENODEV; ret = -ENODEV;
goto out_free; goto out;
} }
/* Copy data */ /* Copy data */
ret = 0; ret = 0;
memset(ssd, 0, sizeof(struct chsc_ssd_info)); memset(ssd, 0, sizeof(struct chsc_ssd_info));
if ((ssd_area->st != SUBCHANNEL_TYPE_IO) && if ((ssd_area->st != SUBCHANNEL_TYPE_IO) &&
(ssd_area->st != SUBCHANNEL_TYPE_MSG)) (ssd_area->st != SUBCHANNEL_TYPE_MSG))
goto out_free; goto out;
ssd->path_mask = ssd_area->path_mask; ssd->path_mask = ssd_area->path_mask;
ssd->fla_valid_mask = ssd_area->fla_valid_mask; ssd->fla_valid_mask = ssd_area->fla_valid_mask;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
...@@ -136,8 +134,8 @@ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd) ...@@ -136,8 +134,8 @@ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd)
if (ssd_area->fla_valid_mask & mask) if (ssd_area->fla_valid_mask & mask)
ssd->fla[i] = ssd_area->fla[i]; ssd->fla[i] = ssd_area->fla[i];
} }
out_free: out:
free_page(page); spin_unlock_irq(&chsc_page_lock);
return ret; return ret;
} }
...@@ -552,7 +550,7 @@ chsc_add_cmg_attr(struct channel_subsystem *css) ...@@ -552,7 +550,7 @@ chsc_add_cmg_attr(struct channel_subsystem *css)
return ret; return ret;
} }
int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page) int __chsc_do_secm(struct channel_subsystem *css, int enable)
{ {
struct { struct {
struct chsc_header request; struct chsc_header request;
...@@ -573,7 +571,9 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page) ...@@ -573,7 +571,9 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
} __attribute__ ((packed)) *secm_area; } __attribute__ ((packed)) *secm_area;
int ret, ccode; int ret, ccode;
secm_area = page; spin_lock_irq(&chsc_page_lock);
memset(chsc_page, 0, PAGE_SIZE);
secm_area = chsc_page;
secm_area->request.length = 0x0050; secm_area->request.length = 0x0050;
secm_area->request.code = 0x0016; secm_area->request.code = 0x0016;
...@@ -584,8 +584,10 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page) ...@@ -584,8 +584,10 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
secm_area->operation_code = enable ? 0 : 1; secm_area->operation_code = enable ? 0 : 1;
ccode = chsc(secm_area); ccode = chsc(secm_area);
if (ccode > 0) if (ccode > 0) {
return (ccode == 3) ? -ENODEV : -EBUSY; ret = (ccode == 3) ? -ENODEV : -EBUSY;
goto out;
}
switch (secm_area->response.code) { switch (secm_area->response.code) {
case 0x0102: case 0x0102:
...@@ -598,37 +600,32 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page) ...@@ -598,37 +600,32 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
if (ret != 0) if (ret != 0)
CIO_CRW_EVENT(2, "chsc: secm failed (rc=%04x)\n", CIO_CRW_EVENT(2, "chsc: secm failed (rc=%04x)\n",
secm_area->response.code); secm_area->response.code);
out:
spin_unlock_irq(&chsc_page_lock);
return ret; return ret;
} }
int int
chsc_secm(struct channel_subsystem *css, int enable) chsc_secm(struct channel_subsystem *css, int enable)
{ {
void *secm_area;
int ret; int ret;
secm_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!secm_area)
return -ENOMEM;
if (enable && !css->cm_enabled) { if (enable && !css->cm_enabled) {
css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!css->cub_addr1 || !css->cub_addr2) { if (!css->cub_addr1 || !css->cub_addr2) {
free_page((unsigned long)css->cub_addr1); free_page((unsigned long)css->cub_addr1);
free_page((unsigned long)css->cub_addr2); free_page((unsigned long)css->cub_addr2);
free_page((unsigned long)secm_area);
return -ENOMEM; return -ENOMEM;
} }
} }
ret = __chsc_do_secm(css, enable, secm_area); ret = __chsc_do_secm(css, enable);
if (!ret) { if (!ret) {
css->cm_enabled = enable; css->cm_enabled = enable;
if (css->cm_enabled) { if (css->cm_enabled) {
ret = chsc_add_cmg_attr(css); ret = chsc_add_cmg_attr(css);
if (ret) { if (ret) {
memset(secm_area, 0, PAGE_SIZE); __chsc_do_secm(css, 0);
__chsc_do_secm(css, 0, secm_area);
css->cm_enabled = 0; css->cm_enabled = 0;
} }
} else } else
...@@ -638,7 +635,6 @@ chsc_secm(struct channel_subsystem *css, int enable) ...@@ -638,7 +635,6 @@ chsc_secm(struct channel_subsystem *css, int enable)
free_page((unsigned long)css->cub_addr1); free_page((unsigned long)css->cub_addr1);
free_page((unsigned long)css->cub_addr2); free_page((unsigned long)css->cub_addr2);
} }
free_page((unsigned long)secm_area);
return ret; return ret;
} }
...@@ -669,13 +665,12 @@ int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt, ...@@ -669,13 +665,12 @@ int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt,
return -EINVAL; return -EINVAL;
if ((rfmt == 2) && !css_general_characteristics.cib) if ((rfmt == 2) && !css_general_characteristics.cib)
return -EINVAL; return -EINVAL;
scpd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!scpd_area)
return -ENOMEM;
spin_lock_irq(&chsc_page_lock);
memset(chsc_page, 0, PAGE_SIZE);
scpd_area = chsc_page;
scpd_area->request.length = 0x0010; scpd_area->request.length = 0x0010;
scpd_area->request.code = 0x0002; scpd_area->request.code = 0x0002;
scpd_area->cssid = chpid.cssid; scpd_area->cssid = chpid.cssid;
scpd_area->first_chpid = chpid.id; scpd_area->first_chpid = chpid.id;
scpd_area->last_chpid = chpid.id; scpd_area->last_chpid = chpid.id;
...@@ -698,7 +693,7 @@ int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt, ...@@ -698,7 +693,7 @@ int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt,
CIO_CRW_EVENT(2, "chsc: scpd failed (rc=%04x)\n", CIO_CRW_EVENT(2, "chsc: scpd failed (rc=%04x)\n",
scpd_area->response.code); scpd_area->response.code);
out: out:
free_page((unsigned long)scpd_area); spin_unlock_irq(&chsc_page_lock);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(chsc_determine_channel_path_desc); EXPORT_SYMBOL_GPL(chsc_determine_channel_path_desc);
...@@ -725,14 +720,8 @@ static void ...@@ -725,14 +720,8 @@ static void
chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv, chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
struct cmg_chars *chars) struct cmg_chars *chars)
{ {
switch (chp->cmg) {
case 2:
case 3:
chp->cmg_chars = kmalloc(sizeof(struct cmg_chars),
GFP_KERNEL);
if (chp->cmg_chars) {
int i, mask;
struct cmg_chars *cmg_chars; struct cmg_chars *cmg_chars;
int i, mask;
cmg_chars = chp->cmg_chars; cmg_chars = chp->cmg_chars;
for (i = 0; i < NR_MEASUREMENT_CHARS; i++) { for (i = 0; i < NR_MEASUREMENT_CHARS; i++) {
...@@ -742,16 +731,11 @@ chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv, ...@@ -742,16 +731,11 @@ chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
else else
cmg_chars->values[i] = 0; cmg_chars->values[i] = 0;
} }
}
break;
default:
/* No cmg-dependent data. */
break;
}
} }
int chsc_get_channel_measurement_chars(struct channel_path *chp) int chsc_get_channel_measurement_chars(struct channel_path *chp)
{ {
struct cmg_chars *cmg_chars;
int ccode, ret; int ccode, ret;
struct { struct {
...@@ -775,13 +759,16 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp) ...@@ -775,13 +759,16 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
u32 data[NR_MEASUREMENT_CHARS]; u32 data[NR_MEASUREMENT_CHARS];
} __attribute__ ((packed)) *scmc_area; } __attribute__ ((packed)) *scmc_area;
scmc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); chp->cmg_chars = NULL;
if (!scmc_area) cmg_chars = kmalloc(sizeof(*cmg_chars), GFP_KERNEL);
if (!cmg_chars)
return -ENOMEM; return -ENOMEM;
spin_lock_irq(&chsc_page_lock);
memset(chsc_page, 0, PAGE_SIZE);
scmc_area = chsc_page;
scmc_area->request.length = 0x0010; scmc_area->request.length = 0x0010;
scmc_area->request.code = 0x0022; scmc_area->request.code = 0x0022;
scmc_area->first_chpid = chp->chpid.id; scmc_area->first_chpid = chp->chpid.id;
scmc_area->last_chpid = chp->chpid.id; scmc_area->last_chpid = chp->chpid.id;
...@@ -792,24 +779,30 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp) ...@@ -792,24 +779,30 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
} }
ret = chsc_error_from_response(scmc_area->response.code); ret = chsc_error_from_response(scmc_area->response.code);
if (ret == 0) { if (ret) {
/* Success. */ CIO_CRW_EVENT(2, "chsc: scmc failed (rc=%04x)\n",
if (!scmc_area->not_valid) { scmc_area->response.code);
chp->cmg = scmc_area->cmg; goto out;
chp->shared = scmc_area->shared; }
chsc_initialize_cmg_chars(chp, scmc_area->cmcv, if (scmc_area->not_valid) {
(struct cmg_chars *)
&scmc_area->data);
} else {
chp->cmg = -1; chp->cmg = -1;
chp->shared = -1; chp->shared = -1;
goto out;
} }
} else { chp->cmg = scmc_area->cmg;
CIO_CRW_EVENT(2, "chsc: scmc failed (rc=%04x)\n", chp->shared = scmc_area->shared;
scmc_area->response.code); if (chp->cmg != 2 && chp->cmg != 3) {
/* No cmg-dependent data. */
goto out;
} }
chp->cmg_chars = cmg_chars;
chsc_initialize_cmg_chars(chp, scmc_area->cmcv,
(struct cmg_chars *) &scmc_area->data);
out: out:
free_page((unsigned long)scmc_area); spin_unlock_irq(&chsc_page_lock);
if (!chp->cmg_chars)
kfree(cmg_chars);
return ret; return ret;
} }
...@@ -818,13 +811,17 @@ int __init chsc_init(void) ...@@ -818,13 +811,17 @@ int __init chsc_init(void)
int ret; int ret;
sei_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); sei_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!sei_page) { chsc_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
CIO_MSG_EVENT(0, "Can't allocate page for processing of " if (!sei_page || !chsc_page) {
"chsc machine checks!\n"); ret = -ENOMEM;
return -ENOMEM; goto out_err;
} }
ret = crw_register_handler(CRW_RSC_CSS, chsc_process_crw); ret = crw_register_handler(CRW_RSC_CSS, chsc_process_crw);
if (ret) if (ret)
goto out_err;
return ret;
out_err:
free_page((unsigned long)chsc_page);
free_page((unsigned long)sei_page); free_page((unsigned long)sei_page);
return ret; return ret;
} }
...@@ -832,13 +829,15 @@ int __init chsc_init(void) ...@@ -832,13 +829,15 @@ int __init chsc_init(void)
void __init chsc_init_cleanup(void) void __init chsc_init_cleanup(void)
{ {
crw_unregister_handler(CRW_RSC_CSS); crw_unregister_handler(CRW_RSC_CSS);
free_page((unsigned long)chsc_page);
free_page((unsigned long)sei_page); free_page((unsigned long)sei_page);
} }
int chsc_enable_facility(int operation_code) int chsc_enable_facility(int operation_code)
{ {
unsigned long flags;
int ret; int ret;
static struct { struct {
struct chsc_header request; struct chsc_header request;
u8 reserved1:4; u8 reserved1:4;
u8 format:4; u8 format:4;
...@@ -851,32 +850,33 @@ int chsc_enable_facility(int operation_code) ...@@ -851,32 +850,33 @@ int chsc_enable_facility(int operation_code)
u32 reserved5:4; u32 reserved5:4;
u32 format2:4; u32 format2:4;
u32 reserved6:24; u32 reserved6:24;
} __attribute__ ((packed, aligned(4096))) sda_area; } __attribute__ ((packed)) *sda_area;
spin_lock(&sda_lock); spin_lock_irqsave(&chsc_page_lock, flags);
memset(&sda_area, 0, sizeof(sda_area)); memset(chsc_page, 0, PAGE_SIZE);
sda_area.request.length = 0x0400; sda_area = chsc_page;
sda_area.request.code = 0x0031; sda_area->request.length = 0x0400;
sda_area.operation_code = operation_code; sda_area->request.code = 0x0031;
sda_area->operation_code = operation_code;
ret = chsc(&sda_area); ret = chsc(sda_area);
if (ret > 0) { if (ret > 0) {
ret = (ret == 3) ? -ENODEV : -EBUSY; ret = (ret == 3) ? -ENODEV : -EBUSY;
goto out; goto out;
} }
switch (sda_area.response.code) { switch (sda_area->response.code) {
case 0x0101: case 0x0101:
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
break; break;
default: default:
ret = chsc_error_from_response(sda_area.response.code); ret = chsc_error_from_response(sda_area->response.code);
} }
if (ret != 0) if (ret != 0)
CIO_CRW_EVENT(2, "chsc: sda (oc=%x) failed (rc=%04x)\n", CIO_CRW_EVENT(2, "chsc: sda (oc=%x) failed (rc=%04x)\n",
operation_code, sda_area.response.code); operation_code, sda_area->response.code);
out: out:
spin_unlock(&sda_lock); spin_unlock_irqrestore(&chsc_page_lock, flags);
return ret; return ret;
} }
...@@ -898,10 +898,9 @@ chsc_determine_css_characteristics(void) ...@@ -898,10 +898,9 @@ chsc_determine_css_characteristics(void)
u32 chsc_char[508]; u32 chsc_char[508];
} __attribute__ ((packed)) *scsc_area; } __attribute__ ((packed)) *scsc_area;
scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); spin_lock_irq(&chsc_page_lock);
if (!scsc_area) memset(chsc_page, 0, PAGE_SIZE);
return -ENOMEM; scsc_area = chsc_page;
scsc_area->request.length = 0x0010; scsc_area->request.length = 0x0010;
scsc_area->request.code = 0x0010; scsc_area->request.code = 0x0010;
...@@ -921,7 +920,7 @@ chsc_determine_css_characteristics(void) ...@@ -921,7 +920,7 @@ chsc_determine_css_characteristics(void)
CIO_CRW_EVENT(2, "chsc: scsc failed (rc=%04x)\n", CIO_CRW_EVENT(2, "chsc: scsc failed (rc=%04x)\n",
scsc_area->response.code); scsc_area->response.code);
exit: exit:
free_page ((unsigned long) scsc_area); spin_unlock_irq(&chsc_page_lock);
return result; return result;
} }
...@@ -976,29 +975,29 @@ int chsc_sstpi(void *page, void *result, size_t size) ...@@ -976,29 +975,29 @@ int chsc_sstpi(void *page, void *result, size_t size)
return (rr->response.code == 0x0001) ? 0 : -EIO; return (rr->response.code == 0x0001) ? 0 : -EIO;
} }
static struct { int chsc_siosl(struct subchannel_id schid)
{
struct {
struct chsc_header request; struct chsc_header request;
u32 word1; u32 word1;
struct subchannel_id sid; struct subchannel_id sid;
u32 word3; u32 word3;
struct chsc_header response; struct chsc_header response;
u32 word[11]; u32 word[11];
} __attribute__ ((packed)) siosl_area __attribute__ ((__aligned__(PAGE_SIZE))); } __attribute__ ((packed)) *siosl_area;
int chsc_siosl(struct subchannel_id schid)
{
unsigned long flags; unsigned long flags;
int ccode; int ccode;
int rc; int rc;
spin_lock_irqsave(&siosl_lock, flags); spin_lock_irqsave(&chsc_page_lock, flags);
memset(&siosl_area, 0, sizeof(siosl_area)); memset(chsc_page, 0, PAGE_SIZE);
siosl_area.request.length = 0x0010; siosl_area = chsc_page;
siosl_area.request.code = 0x0046; siosl_area->request.length = 0x0010;
siosl_area.word1 = 0x80000000; siosl_area->request.code = 0x0046;
siosl_area.sid = schid; siosl_area->word1 = 0x80000000;
siosl_area->sid = schid;
ccode = chsc(&siosl_area); ccode = chsc(siosl_area);
if (ccode > 0) { if (ccode > 0) {
if (ccode == 3) if (ccode == 3)
rc = -ENODEV; rc = -ENODEV;
...@@ -1008,17 +1007,16 @@ int chsc_siosl(struct subchannel_id schid) ...@@ -1008,17 +1007,16 @@ int chsc_siosl(struct subchannel_id schid)
schid.ssid, schid.sch_no, ccode); schid.ssid, schid.sch_no, ccode);
goto out; goto out;
} }
rc = chsc_error_from_response(siosl_area.response.code); rc = chsc_error_from_response(siosl_area->response.code);
if (rc) if (rc)
CIO_MSG_EVENT(2, "chsc: siosl failed for 0.%x.%04x (rc=%04x)\n", CIO_MSG_EVENT(2, "chsc: siosl failed for 0.%x.%04x (rc=%04x)\n",
schid.ssid, schid.sch_no, schid.ssid, schid.sch_no,
siosl_area.response.code); siosl_area->response.code);
else else
CIO_MSG_EVENT(4, "chsc: siosl succeeded for 0.%x.%04x\n", CIO_MSG_EVENT(4, "chsc: siosl succeeded for 0.%x.%04x\n",
schid.ssid, schid.sch_no); schid.ssid, schid.sch_no);
out: out:
spin_unlock_irqrestore(&siosl_lock, flags); spin_unlock_irqrestore(&chsc_page_lock, flags);
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(chsc_siosl); EXPORT_SYMBOL_GPL(chsc_siosl);
...@@ -66,7 +66,7 @@ extern void chsc_init_cleanup(void); ...@@ -66,7 +66,7 @@ extern void chsc_init_cleanup(void);
extern int chsc_enable_facility(int); extern int chsc_enable_facility(int);
struct channel_subsystem; struct channel_subsystem;
extern int chsc_secm(struct channel_subsystem *, int); extern int chsc_secm(struct channel_subsystem *, int);
int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page); int __chsc_do_secm(struct channel_subsystem *css, int enable);
int chsc_chp_vary(struct chp_id chpid, int on); int chsc_chp_vary(struct chp_id chpid, int on);
int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt, int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt,
......
...@@ -790,7 +790,6 @@ static struct notifier_block css_reboot_notifier = { ...@@ -790,7 +790,6 @@ static struct notifier_block css_reboot_notifier = {
static int css_power_event(struct notifier_block *this, unsigned long event, static int css_power_event(struct notifier_block *this, unsigned long event,
void *ptr) void *ptr)
{ {
void *secm_area;
int ret, i; int ret, i;
switch (event) { switch (event) {
...@@ -806,15 +805,8 @@ static int css_power_event(struct notifier_block *this, unsigned long event, ...@@ -806,15 +805,8 @@ static int css_power_event(struct notifier_block *this, unsigned long event,
mutex_unlock(&css->mutex); mutex_unlock(&css->mutex);
continue; continue;
} }
secm_area = (void *)get_zeroed_page(GFP_KERNEL | if (__chsc_do_secm(css, 0))
GFP_DMA);
if (secm_area) {
if (__chsc_do_secm(css, 0, secm_area))
ret = NOTIFY_BAD; ret = NOTIFY_BAD;
free_page((unsigned long)secm_area);
} else
ret = NOTIFY_BAD;
mutex_unlock(&css->mutex); mutex_unlock(&css->mutex);
} }
break; break;
...@@ -830,15 +822,8 @@ static int css_power_event(struct notifier_block *this, unsigned long event, ...@@ -830,15 +822,8 @@ static int css_power_event(struct notifier_block *this, unsigned long event,
mutex_unlock(&css->mutex); mutex_unlock(&css->mutex);
continue; continue;
} }
secm_area = (void *)get_zeroed_page(GFP_KERNEL | if (__chsc_do_secm(css, 1))
GFP_DMA);
if (secm_area) {
if (__chsc_do_secm(css, 1, secm_area))
ret = NOTIFY_BAD;
free_page((unsigned long)secm_area);
} else
ret = NOTIFY_BAD; ret = NOTIFY_BAD;
mutex_unlock(&css->mutex); mutex_unlock(&css->mutex);
} }
/* search for subchannels, which appeared during hibernation */ /* search for subchannels, which appeared during hibernation */
...@@ -867,10 +852,7 @@ static int __init css_bus_init(void) ...@@ -867,10 +852,7 @@ static int __init css_bus_init(void)
if (ret) if (ret)
return ret; return ret;
ret = chsc_determine_css_characteristics(); chsc_determine_css_characteristics();
if (ret == -ENOMEM)
goto out;
/* Try to enable MSS. */ /* Try to enable MSS. */
ret = chsc_enable_facility(CHSC_SDA_OC_MSS); ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
if (ret) if (ret)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册