sclp_info.c

来自「linux 内核源代码」· C语言 代码 · 共 117 行

C
117
字号
/* *  drivers/s390/char/sclp_info.c * *    Copyright IBM Corp. 2007 *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> */#include <linux/init.h>#include <linux/errno.h>#include <linux/string.h>#include <asm/sclp.h>#include "sclp.h"struct sclp_readinfo_sccb {	struct	sccb_header header;	/* 0-7 */	u16	rnmax;			/* 8-9 */	u8	rnsize;			/* 10 */	u8	_reserved0[24 - 11];	/* 11-23 */	u8	loadparm[8];		/* 24-31 */	u8	_reserved1[48 - 32];	/* 32-47 */	u64	facilities;		/* 48-55 */	u8	_reserved2[91 - 56];	/* 56-90 */	u8	flags;			/* 91 */	u8	_reserved3[100 - 92];	/* 92-99 */	u32	rnsize2;		/* 100-103 */	u64	rnmax2;			/* 104-111 */	u8	_reserved4[4096 - 112];	/* 112-4095 */} __attribute__((packed, aligned(4096)));static struct sclp_readinfo_sccb __initdata early_readinfo_sccb;static int __initdata early_readinfo_sccb_valid;u64 sclp_facilities;void __init sclp_readinfo_early(void){	int ret;	int i;	struct sclp_readinfo_sccb *sccb;	sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,				  SCLP_CMDW_READ_SCP_INFO};	/* Enable service signal subclass mask. */	__ctl_set_bit(0, 9);	sccb = &early_readinfo_sccb;	for (i = 0; i < ARRAY_SIZE(commands); i++) {		do {			memset(sccb, 0, sizeof(*sccb));			sccb->header.length = sizeof(*sccb);			sccb->header.control_mask[2] = 0x80;			ret = sclp_service_call(commands[i], sccb);		} while (ret == -EBUSY);		if (ret)			break;		__load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT |				PSW_MASK_WAIT | PSW_DEFAULT_KEY);		local_irq_disable();		/*		 * Contents of the sccb might have changed		 * therefore a barrier is needed.		 */		barrier();		if (sccb->header.response_code == 0x10) {			early_readinfo_sccb_valid = 1;			break;		}		if (sccb->header.response_code != 0x1f0)			break;	}	/* Disable service signal subclass mask again. */	__ctl_clear_bit(0, 9);}void __init sclp_facilities_detect(void){	if (!early_readinfo_sccb_valid)		return;	sclp_facilities = early_readinfo_sccb.facilities;}unsigned long long __init sclp_memory_detect(void){	unsigned long long memsize;	struct sclp_readinfo_sccb *sccb;	if (!early_readinfo_sccb_valid)		return 0;	sccb = &early_readinfo_sccb;	if (sccb->rnsize)		memsize = sccb->rnsize << 20;	else		memsize = sccb->rnsize2 << 20;	if (sccb->rnmax)		memsize *= sccb->rnmax;	else		memsize *= sccb->rnmax2;	return memsize;}/* * This function will be called after sclp_memory_detect(), which gets called * early from early.c code. Therefore the sccb should have valid contents. */void __init sclp_get_ipl_info(struct sclp_ipl_info *info){	struct sclp_readinfo_sccb *sccb;	if (!early_readinfo_sccb_valid)		return;	sccb = &early_readinfo_sccb;	info->is_valid = 1;	if (sccb->flags & 0x2)		info->has_dump = 1;	memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?