drivers/s390/char/sclp_cpi_sys.c

Source file repositories/reference/linux-study-clean/drivers/s390/char/sclp_cpi_sys.c

File Facts

System
Linux kernel
Corpus path
drivers/s390/char/sclp_cpi_sys.c
Extension
.c
Size
8700 bytes
Lines
428
Domain
Driver Families
Bucket
drivers/s390
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct cpi_evbuf {
	struct evbuf_header header;
	u8	id_format;
	u8	reserved0;
	u8	system_type[CPI_LENGTH_NAME];
	u64	reserved1;
	u8	system_name[CPI_LENGTH_NAME];
	u64	reserved2;
	u64	system_level;
	u64	reserved3;
	u8	sysplex_name[CPI_LENGTH_NAME];
	u8	reserved4[16];
} __attribute__((packed));

struct cpi_sccb {
	struct sccb_header header;
	struct cpi_evbuf cpi_evbuf;
} __attribute__((packed));

static struct sclp_register sclp_cpi_event = {
	.send_mask = EVTYP_CTLPROGIDENT_MASK,
};

static char system_name[CPI_LENGTH_NAME + 1];
static char sysplex_name[CPI_LENGTH_NAME + 1];
static char system_type[CPI_LENGTH_NAME + 1];
static u64 system_level;

static void set_data(char *field, char *data)
{
	memset(field, ' ', CPI_LENGTH_NAME);
	memcpy(field, data, strlen(data));
	sclp_ascebc_str(field, CPI_LENGTH_NAME);
}

static void cpi_callback(struct sclp_req *req, void *data)
{
	struct completion *completion = data;

	complete(completion);
}

static struct sclp_req *cpi_prepare_req(void)
{
	struct sclp_req *req;
	struct cpi_sccb *sccb;
	struct cpi_evbuf *evb;

	req = kzalloc_obj(struct sclp_req);
	if (!req)
		return ERR_PTR(-ENOMEM);
	sccb = (struct cpi_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
	if (!sccb) {
		kfree(req);
		return ERR_PTR(-ENOMEM);
	}

	/* 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 = EVTYP_CTLPROGIDENT;
	evb = &sccb->cpi_evbuf;

	/* set system type */
	set_data(evb->system_type, system_type);

	/* set system name */
	set_data(evb->system_name, system_name);

	/* set system level */
	evb->system_level = system_level;

	/* set sysplex name */
	set_data(evb->sysplex_name, sysplex_name);

	/* prepare request data structure presented to SCLP driver */
	req->command = SCLP_CMDW_WRITE_EVENT_DATA;
	req->sccb = sccb;
	req->status = SCLP_REQ_FILLED;
	req->callback = cpi_callback;
	return req;
}

static void cpi_free_req(struct sclp_req *req)
{
	free_page((unsigned long) req->sccb);
	kfree(req);
}

static int cpi_req(void)

Annotation

Implementation Notes