Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2c97843 authored by Rusty Russell's avatar Rusty Russell Committed by Linus Torvalds
Browse files

lguest: documentation III: Drivers



Documentation: The Drivers

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b2b47c21
Loading
Loading
Loading
Loading
+157 −12
Original line number Diff line number Diff line
/* A simple block driver for lguest.
/*D:400
 * The Guest block driver
 *
 * Copyright 2006 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
 * This is a simple block driver, which appears as /dev/lgba, lgbb, lgbc etc.
 * The mechanism is simple: we place the information about the request in the
 * device page, then use SEND_DMA (containing the data for a write, or an empty
 * "ping" DMA for a read).
 :*/
/* Copyright 2006 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
@@ -25,27 +31,50 @@

static char next_block_index = 'a';

/*D:420 Here is the structure which holds all the information we need about
 * each Guest block device.
 *
 * I'm sure at this stage, you're wondering "hey, where was the adventure I was
 * promised?" and thinking "Rusty sucks, I shall say nasty things about him on
 * my blog".  I think Real adventures have boring bits, too, and you're in the
 * middle of one.  But it gets better.  Just not quite yet. */
struct blockdev
{
	/* The block queue infrastructure wants a spinlock: it is held while it
	 * calls our block request function.  We grab it in our interrupt
	 * handler so the responses don't mess with new requests. */
	spinlock_t lock;

	/* The disk structure for the kernel. */
	/* The disk structure registered with kernel. */
	struct gendisk *disk;

	/* The major number for this disk. */
	/* The major device number for this disk, and the interrupt.  We only
	 * really keep them here for completeness; we'd need them if we
	 * supported device unplugging. */
	int major;
	int irq;

	/* The physical address of this device's memory page */
	unsigned long phys_addr;
	/* The mapped block page. */
	/* The mapped memory page for convenient acces. */
	struct lguest_block_page *lb_page;

	/* We only have a single request outstanding at a time. */
	/* We only have a single request outstanding at a time: this is it. */
	struct lguest_dma dma;
	struct request *req;
};

/* Jens gave me this nice helper to end all chunks of a request. */
/*D:495 We originally used end_request() throughout the driver, but it turns
 * out that end_request() is deprecated, and doesn't actually end the request
 * (which seems like a good reason to deprecate it!).  It simply ends the first
 * bio.  So if we had 3 bios in a "struct request" we would do all 3,
 * end_request(), do 2, end_request(), do 1 and end_request(): twice as much
 * work as we needed to do.
 *
 * This reinforced to me that I do not understand the block layer.
 *
 * Nonetheless, Jens Axboe gave me this nice helper to end all chunks of a
 * request.  This improved disk speed by 130%. */
static void end_entire_request(struct request *req, int uptodate)
{
	if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
@@ -55,30 +84,62 @@ static void end_entire_request(struct request *req, int uptodate)
	end_that_request_last(req, uptodate);
}

/* I'm told there are only two stories in the world worth telling: love and
 * hate.  So there used to be a love scene here like this:
 *
 *  Launcher:	We could make beautiful I/O together, you and I.
 *  Guest:	My, that's a big disk!
 *
 * Unfortunately, it was just too raunchy for our otherwise-gentle tale. */

/*D:490 This is the interrupt handler, called when a block read or write has
 * been completed for us. */
static irqreturn_t lgb_irq(int irq, void *_bd)
{
	/* We handed our "struct blockdev" as the argument to request_irq(), so
	 * it is passed through to us here.  This tells us which device we're
	 * dealing with in case we have more than one. */
	struct blockdev *bd = _bd;
	unsigned long flags;

	/* We weren't doing anything?  Strange, but could happen if we shared
	 * interrupts (we don't!). */
	if (!bd->req) {
		pr_debug("No work!\n");
		return IRQ_NONE;
	}

	/* Not done yet?  That's equally strange. */
	if (!bd->lb_page->result) {
		pr_debug("No result!\n");
		return IRQ_NONE;
	}

	/* We have to grab the lock before ending the request. */
	spin_lock_irqsave(&bd->lock, flags);
	/* "result" is 1 for success, 2 for failure: end_entire_request() wants
	 * to know whether this succeeded or not. */
	end_entire_request(bd->req, bd->lb_page->result == 1);
	/* Clear out request, it's done. */
	bd->req = NULL;
	/* Reset incoming DMA for next time. */
	bd->dma.used_len = 0;
	/* Ready for more reads or writes */
	blk_start_queue(bd->disk->queue);
	spin_unlock_irqrestore(&bd->lock, flags);

	/* The interrupt was for us, we dealt with it. */
	return IRQ_HANDLED;
}

/*D:480 The block layer's "struct request" contains a number of "struct bio"s,
 * each of which contains "struct bio_vec"s, each of which contains a page, an
 * offset and a length.
 *
 * Fortunately there are iterators to help us walk through the "struct
 * request".  Even more fortunately, there were plenty of places to steal the
 * code from.  We pack the "struct request" into our "struct lguest_dma" and
 * return the total length. */
static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma)
{
	unsigned int i = 0, idx, len = 0;
@@ -87,8 +148,13 @@ static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma)
	rq_for_each_bio(bio, req) {
		struct bio_vec *bvec;
		bio_for_each_segment(bvec, bio, idx) {
			/* We told the block layer not to give us too many. */
			BUG_ON(i == LGUEST_MAX_DMA_SECTIONS);
			/* If we had a zero-length segment, it would look like
			 * the end of the data referred to by the "struct
			 * lguest_dma", so make sure that doesn't happen. */
			BUG_ON(!bvec->bv_len);
			/* Convert page & offset to a physical address */
			dma->addr[i] = page_to_phys(bvec->bv_page)
				+ bvec->bv_offset;
			dma->len[i] = bvec->bv_len;
@@ -96,26 +162,39 @@ static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma)
			i++;
		}
	}
	/* If the array isn't full, we mark the end with a 0 length */
	if (i < LGUEST_MAX_DMA_SECTIONS)
		dma->len[i] = 0;
	return len;
}

/* This creates an empty DMA, useful for prodding the Host without sending data
 * (ie. when we want to do a read) */
static void empty_dma(struct lguest_dma *dma)
{
	dma->len[0] = 0;
}

/*D:470 Setting up a request is fairly easy: */
static void setup_req(struct blockdev *bd,
		      int type, struct request *req, struct lguest_dma *dma)
{
	/* The type is 1 (write) or 0 (read). */
	bd->lb_page->type = type;
	/* The sector on disk where the read or write starts. */
	bd->lb_page->sector = req->sector;
	/* The result is initialized to 0 (unfinished). */
	bd->lb_page->result = 0;
	/* The current request (so we can end it in the interrupt handler). */
	bd->req = req;
	/* The number of bytes: returned as a side-effect of req_to_dma(),
	 * which packs the block layer's "struct request" into our "struct
	 * lguest_dma" */
	bd->lb_page->bytes = req_to_dma(req, dma);
}

/*D:450 Write is pretty straightforward: we pack the request into a "struct
 * lguest_dma", then use SEND_DMA to send the request. */
static void do_write(struct blockdev *bd, struct request *req)
{
	struct lguest_dma send;
@@ -126,6 +205,9 @@ static void do_write(struct blockdev *bd, struct request *req)
	lguest_send_dma(bd->phys_addr, &send);
}

/* Read is similar to write, except we pack the request into our receive
 * "struct lguest_dma" and send through an empty DMA just to tell the Host that
 * there's a request pending. */
static void do_read(struct blockdev *bd, struct request *req)
{
	struct lguest_dma ping;
@@ -137,21 +219,30 @@ static void do_read(struct blockdev *bd, struct request *req)
	lguest_send_dma(bd->phys_addr, &ping);
}

/*D:440 This where requests come in: we get handed the request queue and are
 * expected to pull a "struct request" off it until we've finished them or
 * we're waiting for a reply: */
static void do_lgb_request(struct request_queue *q)
{
	struct blockdev *bd;
	struct request *req;

again:
	/* This sometimes returns NULL even on the very first time around.  I
	 * wonder if it's something to do with letting elves handle the request
	 * queue... */
	req = elv_next_request(q);
	if (!req)
		return;

	/* We attached the struct blockdev to the disk: get it back */
	bd = req->rq_disk->private_data;
	/* Sometimes we get repeated requests after blk_stop_queue. */
	/* Sometimes we get repeated requests after blk_stop_queue(), but we
	 * can only handle one at a time. */
	if (bd->req)
		return;

	/* We only do reads and writes: no tricky business! */
	if (!blk_fs_request(req)) {
		pr_debug("Got non-command 0x%08x\n", req->cmd_type);
		req->errors++;
@@ -164,20 +255,31 @@ static void do_lgb_request(struct request_queue *q)
	else
		do_read(bd, req);

	/* Wait for interrupt to tell us it's done. */
	/* We've put out the request, so stop any more coming in until we get
	 * an interrupt, which takes us to lgb_irq() to re-enable the queue. */
	blk_stop_queue(q);
}

/*D:430 This is the "struct block_device_operations" we attach to the disk at
 * the end of lguestblk_probe().  It doesn't seem to want much. */
static struct block_device_operations lguestblk_fops = {
	.owner = THIS_MODULE,
};

/*D:425 Setting up a disk device seems to involve a lot of code.  I'm not sure
 * quite why.  I do know that the IDE code sent two or three of the maintainers
 * insane, perhaps this is the fringe of the same disease?
 *
 * As in the console code, the probe function gets handed the generic
 * lguest_device from lguest_bus.c: */
static int lguestblk_probe(struct lguest_device *lgdev)
{
	struct blockdev *bd;
	int err;
	int irqflags = IRQF_SHARED;

	/* First we allocate our own "struct blockdev" and initialize the easy
	 * fields. */
	bd = kmalloc(sizeof(*bd), GFP_KERNEL);
	if (!bd)
		return -ENOMEM;
@@ -187,59 +289,100 @@ static int lguestblk_probe(struct lguest_device *lgdev)
	bd->req = NULL;
	bd->dma.used_len = 0;
	bd->dma.len[0] = 0;
	/* The descriptor in the lguest_devices array provided by the Host
	 * gives the Guest the physical page number of the device's page. */
	bd->phys_addr = (lguest_devices[lgdev->index].pfn << PAGE_SHIFT);

	/* We use lguest_map() to get a pointer to the device page */
	bd->lb_page = lguest_map(bd->phys_addr, 1);
	if (!bd->lb_page) {
		err = -ENOMEM;
		goto out_free_bd;
	}

	/* We need a major device number: 0 means "assign one dynamically". */
	bd->major = register_blkdev(0, "lguestblk");
	if (bd->major < 0) {
		err = bd->major;
		goto out_unmap;
	}

	/* This allocates a "struct gendisk" where we pack all the information
	 * about the disk which the rest of Linux sees.  We ask for one minor
	 * number; I do wonder if we should be asking for more. */
	bd->disk = alloc_disk(1);
	if (!bd->disk) {
		err = -ENOMEM;
		goto out_unregister_blkdev;
	}

	/* Every disk needs a queue for requests to come in: we set up the
	 * queue with a callback function (the core of our driver) and the lock
	 * to use. */
	bd->disk->queue = blk_init_queue(do_lgb_request, &bd->lock);
	if (!bd->disk->queue) {
		err = -ENOMEM;
		goto out_put_disk;
	}

	/* We can only handle a certain number of sg entries */
	/* We can only handle a certain number of pointers in our SEND_DMA
	 * call, so we set that with blk_queue_max_hw_segments().  This is not
	 * to be confused with blk_queue_max_phys_segments() of course!  I
	 * know, who could possibly confuse the two?
	 *
	 * Well, it's simple to tell them apart: this one seems to work and the
	 * other one didn't. */
	blk_queue_max_hw_segments(bd->disk->queue, LGUEST_MAX_DMA_SECTIONS);
	/* Buffers must not cross page boundaries */

	/* Due to technical limitations of our Host (and simple coding) we
	 * can't have a single buffer which crosses a page boundary.  Tell it
	 * here.  This means that our maximum request size is 16
	 * (LGUEST_MAX_DMA_SECTIONS) pages. */
	blk_queue_segment_boundary(bd->disk->queue, PAGE_SIZE-1);

	/* We name our disk: this becomes the device name when udev does its
	 * magic thing and creates the device node, such as /dev/lgba.
	 * next_block_index is a global which starts at 'a'.  Unfortunately
	 * this simple increment logic means that the 27th disk will be called
	 * "/dev/lgb{".  In that case, I recommend having at least 29 disks, so
	 * your /dev directory will be balanced. */
	sprintf(bd->disk->disk_name, "lgb%c", next_block_index++);

	/* We look to the device descriptor again to see if this device's
	 * interrupts are expected to be random.  If they are, we tell the irq
	 * subsystem.  At the moment this bit is always set. */
	if (lguest_devices[lgdev->index].features & LGUEST_DEVICE_F_RANDOMNESS)
		irqflags |= IRQF_SAMPLE_RANDOM;

	/* Now we have the name and irqflags, we can request the interrupt; we
	 * give it the "struct blockdev" we have set up to pass to lgb_irq()
	 * when there is an interrupt. */
	err = request_irq(bd->irq, lgb_irq, irqflags, bd->disk->disk_name, bd);
	if (err)
		goto out_cleanup_queue;

	/* We bind our one-entry DMA pool to the key for this block device so
	 * the Host can reply to our requests.  The key is equal to the
	 * physical address of the device's page, which is conveniently
	 * unique. */
	err = lguest_bind_dma(bd->phys_addr, &bd->dma, 1, bd->irq);
	if (err)
		goto out_free_irq;

	/* We finish our disk initialization and add the disk to the system. */
	bd->disk->major = bd->major;
	bd->disk->first_minor = 0;
	bd->disk->private_data = bd;
	bd->disk->fops = &lguestblk_fops;
	/* This is initialized to the disk size by the other end. */
	/* This is initialized to the disk size by the Launcher. */
	set_capacity(bd->disk, bd->lb_page->num_sectors);
	add_disk(bd->disk);

	printk(KERN_INFO "%s: device %i at major %d\n",
	       bd->disk->disk_name, lgdev->index, bd->major);

	/* We don't need to keep the "struct blockdev" around, but if we ever
	 * implemented device removal, we'd need this. */
	lgdev->private = bd;
	return 0;

@@ -258,6 +401,8 @@ static int lguestblk_probe(struct lguest_device *lgdev)
	return err;
}

/*D:410 The boilerplate code for registering the lguest block driver is just
 * like the console: */
static struct lguest_driver lguestblk_drv = {
	.name = "lguestblk",
	.owner = THIS_MODULE,
+74 −3
Original line number Diff line number Diff line
/* Simple console for lguest.
/*D:300
 * The Guest console driver
 *
 * Copyright (C) 2006 Rusty Russell, IBM Corporation
 * This is a trivial console driver: we use lguest's DMA mechanism to send
 * bytes out, and register a DMA buffer to receive bytes in.  It is assumed to
 * be present and available from the very beginning of boot.
 *
 * Writing console drivers is one of the few remaining Dark Arts in Linux.
 * Fortunately for us, the path of virtual consoles has been well-trodden by
 * the PowerPC folks, who wrote "hvc_console.c" to generically support any
 * virtual console.  We use that infrastructure which only requires us to write
 * the basic put_chars and get_chars functions and call the right register
 * functions.
 :*/

/* Copyright (C) 2006 Rusty Russell, IBM Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
@@ -21,49 +34,81 @@
#include <linux/lguest_bus.h>
#include "hvc_console.h"

/*D:340 This is our single console input buffer, with associated "struct
 * lguest_dma" referring to it.  Note the 0-terminated length array, and the
 * use of physical address for the buffer itself. */
static char inbuf[256];
static struct lguest_dma cons_input = { .used_len = 0,
					.addr[0] = __pa(inbuf),
					.len[0] = sizeof(inbuf),
					.len[1] = 0 };

/*D:310 The put_chars() callback is pretty straightforward.
 *
 * First we put the pointer and length in a "struct lguest_dma": we only have
 * one pointer, so we set the second length to 0.  Then we use SEND_DMA to send
 * the data to (Host) buffers attached to the console key.  Usually a device's
 * key is a physical address within the device's memory, but because the
 * console device doesn't have any associated physical memory, we use the
 * LGUEST_CONSOLE_DMA_KEY constant (aka 0). */
static int put_chars(u32 vtermno, const char *buf, int count)
{
	struct lguest_dma dma;

	/* FIXME: what if it's over a page boundary? */
	/* FIXME: DMA buffers in a "struct lguest_dma" are not allowed
	 * to go over page boundaries.  This never seems to happen,
	 * but if it did we'd need to fix this code. */
	dma.len[0] = count;
	dma.len[1] = 0;
	dma.addr[0] = __pa(buf);

	lguest_send_dma(LGUEST_CONSOLE_DMA_KEY, &dma);
	/* We're expected to return the amount of data we wrote: all of it. */
	return count;
}

/*D:350 get_chars() is the callback from the hvc_console infrastructure when
 * an interrupt is received.
 *
 * Firstly we see if our buffer has been filled: if not, we return.  The rest
 * of the code deals with the fact that the hvc_console() infrastructure only
 * asks us for 16 bytes at a time.  We keep a "cons_offset" variable for
 * partially-read buffers. */
static int get_chars(u32 vtermno, char *buf, int count)
{
	static int cons_offset;

	/* Nothing left to see here... */
	if (!cons_input.used_len)
		return 0;

	/* You want more than we have to give?  Well, try wanting less! */
	if (cons_input.used_len - cons_offset < count)
		count = cons_input.used_len - cons_offset;

	/* Copy across to their buffer and increment offset. */
	memcpy(buf, inbuf + cons_offset, count);
	cons_offset += count;

	/* Finished?  Zero offset, and reset cons_input so Host will use it
	 * again. */
	if (cons_offset == cons_input.used_len) {
		cons_offset = 0;
		cons_input.used_len = 0;
	}
	return count;
}
/*:*/

static struct hv_ops lguest_cons = {
	.get_chars = get_chars,
	.put_chars = put_chars,
};

/*D:320 Console drivers are initialized very early so boot messages can go
 * out.  At this stage, the console is output-only.  Our driver checks we're a
 * Guest, and if so hands hvc_instantiate() the console number (0), priority
 * (0), and the struct hv_ops containing the put_chars() function. */
static int __init cons_init(void)
{
	if (strcmp(paravirt_ops.name, "lguest") != 0)
@@ -73,21 +118,46 @@ static int __init cons_init(void)
}
console_initcall(cons_init);

/*D:370 To set up and manage our virtual console, we call hvc_alloc() and
 * stash the result in the private pointer of the "struct lguest_device".
 * Since we never remove the console device we never need this pointer again,
 * but using ->private is considered good form, and you never know who's going
 * to copy your driver.
 *
 * Once the console is set up, we bind our input buffer ready for input. */
static int lguestcons_probe(struct lguest_device *lgdev)
{
	int err;

	/* The first argument of hvc_alloc() is the virtual console number, so
	 * we use zero.  The second argument is the interrupt number.
	 *
	 * The third argument is a "struct hv_ops" containing the put_chars()
	 * and get_chars() pointers.  The final argument is the output buffer
	 * size: we use 256 and expect the Host to have room for us to send
	 * that much. */
	lgdev->private = hvc_alloc(0, lgdev_irq(lgdev), &lguest_cons, 256);
	if (IS_ERR(lgdev->private))
		return PTR_ERR(lgdev->private);

	/* We bind a single DMA buffer at key LGUEST_CONSOLE_DMA_KEY.
	 * "cons_input" is that statically-initialized global DMA buffer we saw
	 * above, and we also give the interrupt we want. */
	err = lguest_bind_dma(LGUEST_CONSOLE_DMA_KEY, &cons_input, 1,
			      lgdev_irq(lgdev));
	if (err)
		printk("lguest console: failed to bind buffer.\n");
	return err;
}
/* Note the use of lgdev_irq() for the interrupt number.  We tell hvc_alloc()
 * to expect input when this interrupt is triggered, and then tell
 * lguest_bind_dma() that is the interrupt to send us when input comes in. */

/*D:360 From now on the console driver follows standard Guest driver form:
 * register_lguest_driver() registers the device type and probe function, and
 * the probe function sets up the device.
 *
 * The standard "struct lguest_driver": */
static struct lguest_driver lguestcons_drv = {
	.name = "lguestcons",
	.owner = THIS_MODULE,
@@ -95,6 +165,7 @@ static struct lguest_driver lguestcons_drv = {
	.probe = lguestcons_probe,
};

/* The standard init function */
static int __init hvc_lguest_init(void)
{
	return register_lguest_driver(&lguestcons_drv);
+69 −3
Original line number Diff line number Diff line
@@ -46,6 +46,10 @@ static struct device_attribute lguest_dev_attrs[] = {
	__ATTR_NULL
};

/*D:130 The generic bus infrastructure requires a function which says whether a
 * device matches a driver.  For us, it is simple: "struct lguest_driver"
 * contains a "device_type" field which indicates what type of device it can
 * handle, so we just cast the args and compare: */
static int lguest_dev_match(struct device *_dev, struct device_driver *_drv)
{
	struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
@@ -53,6 +57,7 @@ static int lguest_dev_match(struct device *_dev, struct device_driver *_drv)

	return (drv->device_type == lguest_devices[dev->index].type);
}
/*:*/

struct lguest_bus {
	struct bus_type bus;
@@ -71,6 +76,19 @@ static struct lguest_bus lguest_bus = {
	}
};

/*D:140 This is the callback which occurs once the bus infrastructure matches
 * up a device and driver, ie. in response to add_lguest_device() calling
 * device_register(), or register_lguest_driver() calling driver_register().
 *
 * At the moment it's always the latter: the devices are added first, since
 * scan_devices() is called from a "core_initcall", and the drivers themselves
 * called later as a normal "initcall".  But it would work the other way too.
 *
 * So now we have the happy couple, we add the status bit to indicate that we
 * found a driver.  If the driver truly loves the device, it will return
 * happiness from its probe function (ok, perhaps this wasn't my greatest
 * analogy), and we set the final "driver ok" bit so the Host sees it's all
 * green. */
static int lguest_dev_probe(struct device *_dev)
{
	int ret;
@@ -85,6 +103,10 @@ static int lguest_dev_probe(struct device *_dev)
	return ret;
}

/* The last part of the bus infrastructure is the function lguest drivers use
 * to register themselves.  Firstly, we do nothing if there's no lguest bus
 * (ie. this is not a Guest), otherwise we fill in the embedded generic "struct
 * driver" fields and call the generic driver_register(). */
int register_lguest_driver(struct lguest_driver *drv)
{
	if (!lguest_devices)
@@ -97,12 +119,36 @@ int register_lguest_driver(struct lguest_driver *drv)

	return driver_register(&drv->drv);
}

/* At the moment we build all the drivers into the kernel because they're so
 * simple: 8144 bytes for all three of them as I type this.  And as the console
 * really needs to be built in, it's actually only 3527 bytes for the network
 * and block drivers.
 *
 * If they get complex it will make sense for them to be modularized, so we
 * need to explicitly export the symbol.
 *
 * I don't think non-GPL modules make sense, so it's a GPL-only export.
 */
EXPORT_SYMBOL_GPL(register_lguest_driver);

/*D:120 This is the core of the lguest bus: actually adding a new device.
 * It's a separate function because it's neater that way, and because an
 * earlier version of the code supported hotplug and unplug.  They were removed
 * early on because they were never used.
 *
 * As Andrew Tridgell says, "Untested code is buggy code".
 *
 * It's worth reading this carefully: we start with an index into the array of
 * "struct lguest_device_desc"s indicating the device which is new: */
static void add_lguest_device(unsigned int index)
{
	struct lguest_device *new;

	/* Each "struct lguest_device_desc" has a "status" field, which the
	 * Guest updates as the device is probed.  In the worst case, the Host
	 * can look at these bits to tell what part of device setup failed,
	 * even if the console isn't available. */
	lguest_devices[index].status |= LGUEST_DEVICE_S_ACKNOWLEDGE;
	new = kmalloc(sizeof(struct lguest_device), GFP_KERNEL);
	if (!new) {
@@ -111,12 +157,17 @@ static void add_lguest_device(unsigned int index)
		return;
	}

	/* The "struct lguest_device" setup is pretty straight-forward example
	 * code. */
	new->index = index;
	new->private = NULL;
	memset(&new->dev, 0, sizeof(new->dev));
	new->dev.parent = &lguest_bus.dev;
	new->dev.bus = &lguest_bus.bus;
	sprintf(new->dev.bus_id, "%u", index);

	/* device_register() causes the bus infrastructure to look for a
	 * matching driver. */
	if (device_register(&new->dev) != 0) {
		printk(KERN_EMERG "Cannot register lguest device %u\n", index);
		lguest_devices[index].status |= LGUEST_DEVICE_S_FAILED;
@@ -124,6 +175,9 @@ static void add_lguest_device(unsigned int index)
	}
}

/*D:110 scan_devices() simply iterates through the device array.  The type 0
 * is reserved to mean "no device", and anything else means we have found a
 * device: add it. */
static void scan_devices(void)
{
	unsigned int i;
@@ -133,12 +187,23 @@ static void scan_devices(void)
			add_lguest_device(i);
}

/*D:100 Fairly early in boot, lguest_bus_init() is called to set up the lguest
 * bus.  We check that we are a Guest by checking paravirt_ops.name: there are
 * other ways of checking, but this seems most obvious to me.
 *
 * So we can access the array of "struct lguest_device_desc"s easily, we map
 * that memory and store the pointer in the global "lguest_devices".  Then we
 * register the bus with the core.  Doing two registrations seems clunky to me,
 * but it seems to be the correct sysfs incantation.
 *
 * Finally we call scan_devices() which adds all the devices found in the
 * "struct lguest_device_desc" array. */
static int __init lguest_bus_init(void)
{
	if (strcmp(paravirt_ops.name, "lguest") != 0)
		return 0;

	/* Devices are in page above top of "normal" mem. */
	/* Devices are in a single page above top of "normal" mem */
	lguest_devices = lguest_map(max_pfn<<PAGE_SHIFT, 1);

	if (bus_register(&lguest_bus.bus) != 0
@@ -148,4 +213,5 @@ static int __init lguest_bus_init(void)
	scan_devices();
	return 0;
}
/* Do this after core stuff, before devices. */
postcore_initcall(lguest_bus_init);
+201 −17

File changed.

Preview size limit exceeded, changes collapsed.

+4 −1
Original line number Diff line number Diff line
@@ -15,11 +15,14 @@ struct lguest_device {
	void *private;
};

/* By convention, each device can use irq index+1 if it wants to. */
/*D:380 Since interrupt numbers are arbitrary, we use a convention: each device
 * can use the interrupt number corresponding to its index.  The +1 is because
 * interrupt 0 is not usable (it's actually the timer interrupt). */
static inline int lgdev_irq(const struct lguest_device *dev)
{
	return dev->index + 1;
}
/*:*/

/* dma args must not be vmalloced! */
void lguest_send_dma(unsigned long key, struct lguest_dma *dma);
Loading