drivers/xen/xenbus/xenbus_xs.c

Source file repositories/reference/linux-study-clean/drivers/xen/xenbus/xenbus_xs.c

File Facts

System
Linux kernel
Corpus path
drivers/xen/xenbus/xenbus_xs.c
Extension
.c
Size
21742 bytes
Lines
928
Domain
Driver Families
Bucket
drivers/xen
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

if (i == ARRAY_SIZE(xsd_errors) - 1) {
			pr_warn("xen store gave: unknown error %s\n",
				errorstring);
			return EINVAL;
		}
	}
	return xsd_errors[i].errnum;
}

static bool xenbus_ok(void)
{
	switch (xen_store_domain_type) {
	case XS_LOCAL:
		switch (system_state) {
		case SYSTEM_POWER_OFF:
		case SYSTEM_RESTART:
		case SYSTEM_HALT:
			return false;
		default:
			break;
		}
		return true;
	case XS_PV:
	case XS_HVM:
		/* FIXME: Could check that the remote domain is alive,
		 * but it is normally initial domain. */
		return true;
	default:
		break;
	}
	return false;
}

static bool test_reply(struct xb_req_data *req)
{
	if (req->state == xb_req_state_got_reply || !xenbus_ok()) {
		/* read req->state before all other fields */
		virt_rmb();
		return true;
	}

	/* Make sure to reread req->state each time. */
	barrier();

	return false;
}

static void *read_reply(struct xb_req_data *req)
{
	do {
		wait_event(req->wq, test_reply(req));

		if (!xenbus_ok())
			/*
			 * If we are in the process of being shut-down there is
			 * no point of trying to contact XenBus - it is either
			 * killed (xenstored application) or the other domain
			 * has been killed or is unreachable.
			 */
			return ERR_PTR(-EIO);
		if (req->err)
			return ERR_PTR(req->err);

	} while (req->state != xb_req_state_got_reply);

	return req->body;
}

static void xs_send(struct xb_req_data *req, struct xsd_sockmsg *msg)
{
	bool notify;

	req->msg = *msg;
	req->err = 0;
	req->state = xb_req_state_queued;
	init_waitqueue_head(&req->wq);

	/* Save the caller req_id and restore it later in the reply */
	req->caller_req_id = req->msg.req_id;
	req->msg.req_id = xs_request_enter(req);

	/*
	 * Take 2nd ref.  One for this thread, and the second for the
	 * xenbus_thread.
	 */
	kref_get(&req->kref);

	mutex_lock(&xb_write_mutex);
	list_add_tail(&req->list, &xb_write_list);
	notify = list_is_singular(&xb_write_list);

Annotation

Implementation Notes