⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sclp_cpi.c

📁 linux-2.6.15.6
💻 C
字号:
/* * Author: Martin Peschke <mpeschke@de.ibm.com> * Copyright (C) 2001 IBM Entwicklung GmbH, IBM Corporation * * SCLP Control-Program Identification. */#include <linux/config.h>#include <linux/version.h>#include <linux/kmod.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/timer.h>#include <linux/string.h>#include <linux/err.h>#include <linux/slab.h>#include <asm/ebcdic.h>#include <asm/semaphore.h>#include "sclp.h"#include "sclp_rw.h"#define CPI_LENGTH_SYSTEM_TYPE	8#define CPI_LENGTH_SYSTEM_NAME	8#define CPI_LENGTH_SYSPLEX_NAME	8struct cpi_evbuf {	struct evbuf_header header;	u8	id_format;	u8	reserved0;	u8	system_type[CPI_LENGTH_SYSTEM_TYPE];	u64	reserved1;	u8	system_name[CPI_LENGTH_SYSTEM_NAME];	u64	reserved2;	u64	system_level;	u64	reserved3;	u8	sysplex_name[CPI_LENGTH_SYSPLEX_NAME];	u8	reserved4[16];} __attribute__((packed));struct cpi_sccb {	struct sccb_header header;	struct cpi_evbuf cpi_evbuf;} __attribute__((packed));/* Event type structure for write message and write priority message */static struct sclp_register sclp_cpi_event ={	.send_mask = EvTyp_CtlProgIdent_Mask};MODULE_AUTHOR(	"Martin Peschke, IBM Deutschland Entwicklung GmbH "	"<mpeschke@de.ibm.com>");MODULE_DESCRIPTION(	"identify this operating system instance to the S/390 "	"or zSeries hardware");static char *system_name = NULL;module_param(system_name, charp, 0);MODULE_PARM_DESC(system_name, "e.g. hostname - max. 8 characters");static char *sysplex_name = NULL;#ifdef ALLOW_SYSPLEX_NAMEmodule_param(sysplex_name, charp, 0);MODULE_PARM_DESC(sysplex_name, "if applicable - max. 8 characters");#endif/* use default value for this field (as well as for system level) */static char *system_type = "LINUX";static intcpi_check_parms(void){	/* reject if no system type specified */	if (!system_type) {		printk("cpi: bug: no system type specified\n");		return -EINVAL;	}	/* reject if system type larger than 8 characters */	if (strlen(system_type) > CPI_LENGTH_SYSTEM_NAME) {		printk("cpi: bug: system type has length of %li characters - "		       "only %i characters supported\n",		       strlen(system_type), CPI_LENGTH_SYSTEM_TYPE);		return -EINVAL;	}	/* reject if no system name specified */	if (!system_name) {		printk("cpi: no system name specified\n");		return -EINVAL;	}	/* reject if system name larger than 8 characters */	if (strlen(system_name) > CPI_LENGTH_SYSTEM_NAME) {		printk("cpi: system name has length of %li characters - "		       "only %i characters supported\n",		       strlen(system_name), CPI_LENGTH_SYSTEM_NAME);		return -EINVAL;	}	/* reject if specified sysplex name larger than 8 characters */	if (sysplex_name && strlen(sysplex_name) > CPI_LENGTH_SYSPLEX_NAME) {		printk("cpi: sysplex name has length of %li characters"		       " - only %i characters supported\n",		       strlen(sysplex_name), CPI_LENGTH_SYSPLEX_NAME);		return -EINVAL;	}	return 0;}static voidcpi_callback(struct sclp_req *req, void *data){	struct semaphore *sem;	sem = (struct semaphore *) data;	up(sem);}static struct sclp_req *cpi_prepare_req(void){	struct sclp_req *req;	struct cpi_sccb *sccb;	struct cpi_evbuf *evb;	req = (struct sclp_req *) kmalloc(sizeof(struct sclp_req), GFP_KERNEL);	if (req == NULL)		return ERR_PTR(-ENOMEM);	sccb = (struct cpi_sccb *) __get_free_page(GFP_KERNEL | GFP_DMA);	if (sccb == NULL) {		kfree(req);		return ERR_PTR(-ENOMEM);	}	memset(sccb, 0, sizeof(struct cpi_sccb));	/* setup SCCB for Control-Program Identification */	sccb->header.length = sizeof(struct cpi_sccb);	sccb->cpi_evbuf.header.length = sizeof(struct cpi_evbuf);	sccb->cpi_evbuf.header.type = 0x0B;	evb = &sccb->cpi_evbuf;	/* set system type */	memset(evb->system_type, ' ', CPI_LENGTH_SYSTEM_TYPE);	memcpy(evb->system_type, system_type, strlen(system_type));	sclp_ascebc_str(evb->system_type, CPI_LENGTH_SYSTEM_TYPE);	EBC_TOUPPER(evb->system_type, CPI_LENGTH_SYSTEM_TYPE);	/* set system name */	memset(evb->system_name, ' ', CPI_LENGTH_SYSTEM_NAME);	memcpy(evb->system_name, system_name, strlen(system_name));	sclp_ascebc_str(evb->system_name, CPI_LENGTH_SYSTEM_NAME);	EBC_TOUPPER(evb->system_name, CPI_LENGTH_SYSTEM_NAME);	/* set sytem level */	evb->system_level = LINUX_VERSION_CODE;	/* set sysplex name */	if (sysplex_name) {		memset(evb->sysplex_name, ' ', CPI_LENGTH_SYSPLEX_NAME);		memcpy(evb->sysplex_name, sysplex_name, strlen(sysplex_name));		sclp_ascebc_str(evb->sysplex_name, CPI_LENGTH_SYSPLEX_NAME);		EBC_TOUPPER(evb->sysplex_name, CPI_LENGTH_SYSPLEX_NAME);	}	/* prepare request data structure presented to SCLP driver */	req->command = SCLP_CMDW_WRITEDATA;	req->sccb = sccb;	req->status = SCLP_REQ_FILLED;	req->callback = cpi_callback;	return req;}static voidcpi_free_req(struct sclp_req *req){	free_page((unsigned long) req->sccb);	kfree(req);}static int __initcpi_module_init(void){	struct semaphore sem;	struct sclp_req *req;	int rc;	rc = cpi_check_parms();	if (rc)		return rc;	rc = sclp_register(&sclp_cpi_event);	if (rc) {		/* could not register sclp event. Die. */		printk(KERN_WARNING "cpi: could not register to hardware "		       "console.\n");		return -EINVAL;	}	if (!(sclp_cpi_event.sclp_send_mask & EvTyp_CtlProgIdent_Mask)) {		printk(KERN_WARNING "cpi: no control program identification "		       "support\n");		sclp_unregister(&sclp_cpi_event);		return -ENOTSUPP;	}	req = cpi_prepare_req();	if (IS_ERR(req)) {		printk(KERN_WARNING "cpi: couldn't allocate request\n");		sclp_unregister(&sclp_cpi_event);		return PTR_ERR(req);	}	/* Prepare semaphore */	sema_init(&sem, 0);	req->callback_data = &sem;	/* Add request to sclp queue */	rc = sclp_add_request(req);	if (rc) {		printk(KERN_WARNING "cpi: could not start request\n");		cpi_free_req(req);		sclp_unregister(&sclp_cpi_event);		return rc;	}	/* make "insmod" sleep until callback arrives */	down(&sem);	rc = ((struct cpi_sccb *) req->sccb)->header.response_code;	if (rc != 0x0020) {		printk(KERN_WARNING "cpi: failed with response code 0x%x\n",		       rc);		rc = -ECOMM;	} else		rc = 0;	cpi_free_req(req);	sclp_unregister(&sclp_cpi_event);	return rc;}static void __exit cpi_module_exit(void){}/* declare driver module init/cleanup functions */module_init(cpi_module_init);module_exit(cpi_module_exit);

⌨️ 快捷键说明

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