Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 818c272b authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky
Browse files

[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: <stable@kernel.org>
Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 6a5176c4
Loading
Loading
Loading
Loading
+14 −15
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@
#include "chsc.h"
#include "chsc.h"


static void *sei_page;
static void *sei_page;
static DEFINE_SPINLOCK(sda_lock);


/**
/**
 * chsc_error_from_response() - convert a chsc response to an error
 * 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);
	kfree(sei_page);
}
}


int __init
int chsc_enable_facility(int operation_code)
chsc_enable_facility(int operation_code)
{
{
	int ret;
	int ret;
	struct {
	static struct {
		struct chsc_header request;
		struct chsc_header request;
		u8 reserved1:4;
		u8 reserved1:4;
		u8 format:4;
		u8 format:4;
@@ -849,33 +849,32 @@ 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)) *sda_area;
	} __attribute__ ((packed, aligned(4096))) sda_area;


	sda_area = (void *)get_zeroed_page(GFP_KERNEL|GFP_DMA);
	spin_lock(&sda_lock);
	if (!sda_area)
	memset(&sda_area, 0, sizeof(sda_area));
		return -ENOMEM;
	sda_area.request.length = 0x0400;
	sda_area->request.length = 0x0400;
	sda_area.request.code = 0x0031;
	sda_area->request.code = 0x0031;
	sda_area.operation_code = operation_code;
	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:
	free_page((unsigned long)sda_area);
	spin_unlock(&sda_lock);
	return ret;
	return ret;
}
}


+3 −8
Original line number Original line Diff line number Diff line
@@ -870,15 +870,10 @@ static int __init css_bus_init(void)


	/* Try to enable MSS. */
	/* Try to enable MSS. */
	ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
	ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
	switch (ret) {
	if (ret)
	case 0: /* Success. */
		max_ssid = __MAX_SSID;
		break;
	case -ENOMEM:
		goto out;
	default:
		max_ssid = 0;
		max_ssid = 0;
	}
	else /* Success. */
		max_ssid = __MAX_SSID;


	ret = slow_subchannel_init();
	ret = slow_subchannel_init();
	if (ret)
	if (ret)