drivers/s390/char/sclp_cmd.c

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

File Facts

System
Linux kernel
Corpus path
drivers/s390/char/sclp_cmd.c
Extension
.c
Size
6334 bytes
Lines
259
Domain
Driver Families
Bucket
drivers/s390
Inferred role
Driver Families: implementation source
Status
source 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 cpu_configure_sccb {
	struct sccb_header header;
} __packed __aligned(8);

struct chp_cfg_sccb {
	struct sccb_header header;
	u8 ccm;
	u8 reserved[6];
	u8 cssid;
} __packed;

struct chp_info_sccb {
	struct sccb_header header;
	u8 recognized[SCLP_CHP_INFO_MASK_SIZE];
	u8 standby[SCLP_CHP_INFO_MASK_SIZE];
	u8 configured[SCLP_CHP_INFO_MASK_SIZE];
	u8 ccm;
	u8 reserved[6];
	u8 cssid;
} __packed;

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

	complete(completion);
}

int sclp_sync_request(sclp_cmdw_t cmd, void *sccb)
{
	return sclp_sync_request_timeout(cmd, sccb, 0);
}

int sclp_sync_request_timeout(sclp_cmdw_t cmd, void *sccb, int timeout)
{
	struct completion completion;
	struct sclp_req *request;
	int rc;

	request = kzalloc_obj(*request);
	if (!request)
		return -ENOMEM;
	if (timeout)
		request->queue_timeout = timeout;
	request->command = cmd;
	request->sccb = sccb;
	request->status = SCLP_REQ_FILLED;
	request->callback = sclp_sync_callback;
	request->callback_data = &completion;
	init_completion(&completion);

	rc = sclp_add_request(request);
	if (rc)
		goto out;
	wait_for_completion(&completion);

	if (request->status != SCLP_REQ_DONE) {
		pr_warn("sync request failed (cmd=0x%08x, status=0x%02x)\n",
			cmd, request->status);
		rc = -EIO;
	}
out:
	kfree(request);
	return rc;
}

int _sclp_get_core_info(struct sclp_core_info *info)
{
	struct read_cpu_info_sccb *sccb;
	int rc, length;

	if (!SCLP_HAS_CPU_INFO)
		return -EOPNOTSUPP;

	length = test_facility(140) ? EXT_SCCB_READ_CPU : PAGE_SIZE;
	sccb = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA | __GFP_ZERO, get_order(length));
	if (!sccb)
		return -ENOMEM;
	sccb->header.length = length;
	sccb->header.control_mask[2] = 0x80;
	rc = sclp_sync_request_timeout(SCLP_CMDW_READ_CPU_INFO, sccb,
				       SCLP_QUEUE_INTERVAL);
	if (rc)
		goto out;
	if (sccb->header.response_code != 0x0010) {
		pr_warn("readcpuinfo failed (response=0x%04x)\n",
			sccb->header.response_code);
		rc = -EIO;
		goto out;
	}

Annotation

Implementation Notes