drivers/xen/xenbus/xenbus_client.c

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

File Facts

System
Linux kernel
Corpus path
drivers/xen/xenbus/xenbus_client.c
Extension
.c
Size
25866 bytes
Lines
975
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

struct xenbus_map_node {
	struct list_head next;
	union {
		struct {
			struct vm_struct *area;
		} pv;
		struct {
			struct page *pages[XENBUS_MAX_RING_PAGES];
			unsigned long addrs[XENBUS_MAX_RING_GRANTS];
			void *addr;
		} hvm;
	};
	grant_handle_t handles[XENBUS_MAX_RING_GRANTS];
	unsigned int   nr_handles;
};

struct map_ring_valloc {
	struct xenbus_map_node *node;

	/* Why do we need two arrays? See comment of __xenbus_map_ring */
	unsigned long addrs[XENBUS_MAX_RING_GRANTS];
	phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS];

	struct gnttab_map_grant_ref map[XENBUS_MAX_RING_GRANTS];
	struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_GRANTS];

	unsigned int idx;
};

static DEFINE_SPINLOCK(xenbus_valloc_lock);
static LIST_HEAD(xenbus_valloc_pages);

struct xenbus_ring_ops {
	int (*map)(struct xenbus_device *dev, struct map_ring_valloc *info,
		   grant_ref_t *gnt_refs, unsigned int nr_grefs,
		   void **vaddr);
	int (*unmap)(struct xenbus_device *dev, void *vaddr);
};

static const struct xenbus_ring_ops *ring_ops __read_mostly;

const char *xenbus_strstate(enum xenbus_state state)
{
	static const char *const name[] = {
		[ XenbusStateUnknown      ] = "Unknown",
		[ XenbusStateInitialising ] = "Initialising",
		[ XenbusStateInitWait     ] = "InitWait",
		[ XenbusStateInitialised  ] = "Initialised",
		[ XenbusStateConnected    ] = "Connected",
		[ XenbusStateClosing      ] = "Closing",
		[ XenbusStateClosed	  ] = "Closed",
		[XenbusStateReconfiguring] = "Reconfiguring",
		[XenbusStateReconfigured] = "Reconfigured",
	};
	return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
}
EXPORT_SYMBOL_GPL(xenbus_strstate);

/**
 * xenbus_watch_path - register a watch
 * @dev: xenbus device
 * @path: path to watch
 * @watch: watch to register
 * @will_handle: events queuing determine callback
 * @callback: callback to register
 *
 * Register a @watch on the given path, using the given xenbus_watch structure
 * for storage, @will_handle function as the callback to determine if each
 * event need to be queued, and the given @callback function as the callback.
 * On success, the given @path will be saved as @watch->node, and remains the
 * caller's to free.  On error, @watch->node will be NULL, the device will
 * switch to %XenbusStateClosing, and the error will be saved in the store.
 *
 * Returns: %0 on success or -errno on error
 */
int xenbus_watch_path(struct xenbus_device *dev, const char *path,
		      struct xenbus_watch *watch,
		      bool (*will_handle)(struct xenbus_watch *,
					  const char *, const char *),
		      void (*callback)(struct xenbus_watch *,
				       const char *, const char *))
{
	int err;

	watch->node = path;
	watch->will_handle = will_handle;
	watch->callback = callback;

	err = register_xenbus_watch(watch);

Annotation

Implementation Notes