From: Sebastian Ott Date: Thu, 22 Apr 2010 15:17:03 +0000 (+0200) Subject: [S390] cio: allow enable_facility from outside init functions X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=818c272bd74b834c3ca9347c6a540c2ec880afdc;p=openwrt%2Fstaging%2Fblogic.git [S390] cio: allow enable_facility from outside init functions Prepare chsc_enable_facility to be used from outside init functions. Use static memory for the chsc call and protect its access by a spinlock (although there is no concurrent usage). Cc: Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 4038f5b4f144..ce7cb87479fe 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -29,6 +29,7 @@ #include "chsc.h" static void *sei_page; +static DEFINE_SPINLOCK(sda_lock); /** * chsc_error_from_response() - convert a chsc response to an error @@ -832,11 +833,10 @@ void __init chsc_free_sei_area(void) kfree(sei_page); } -int __init -chsc_enable_facility(int operation_code) +int chsc_enable_facility(int operation_code) { int ret; - struct { + static struct { struct chsc_header request; u8 reserved1:4; u8 format:4; @@ -849,33 +849,32 @@ chsc_enable_facility(int operation_code) u32 reserved5:4; u32 format2:4; u32 reserved6:24; - } __attribute__ ((packed)) *sda_area; + } __attribute__ ((packed, aligned(4096))) sda_area; - sda_area = (void *)get_zeroed_page(GFP_KERNEL|GFP_DMA); - if (!sda_area) - return -ENOMEM; - sda_area->request.length = 0x0400; - sda_area->request.code = 0x0031; - sda_area->operation_code = operation_code; + spin_lock(&sda_lock); + memset(&sda_area, 0, sizeof(sda_area)); + sda_area.request.length = 0x0400; + sda_area.request.code = 0x0031; + sda_area.operation_code = operation_code; - ret = chsc(sda_area); + ret = chsc(&sda_area); if (ret > 0) { ret = (ret == 3) ? -ENODEV : -EBUSY; goto out; } - switch (sda_area->response.code) { + switch (sda_area.response.code) { case 0x0101: ret = -EOPNOTSUPP; break; default: - ret = chsc_error_from_response(sda_area->response.code); + ret = chsc_error_from_response(sda_area.response.code); } if (ret != 0) 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: - free_page((unsigned long)sda_area); + spin_unlock(&sda_lock); return ret; } diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 2769da54f2b9..19635d47dede 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -870,15 +870,10 @@ static int __init css_bus_init(void) /* Try to enable MSS. */ ret = chsc_enable_facility(CHSC_SDA_OC_MSS); - switch (ret) { - case 0: /* Success. */ - max_ssid = __MAX_SSID; - break; - case -ENOMEM: - goto out; - default: + if (ret) max_ssid = 0; - } + else /* Success. */ + max_ssid = __MAX_SSID; ret = slow_subchannel_init(); if (ret)