diff options
Diffstat (limited to 'drivers/lguest/lguest_bus.c')
-rw-r--r-- | drivers/lguest/lguest_bus.c | 220 |
1 files changed, 0 insertions, 220 deletions
diff --git a/drivers/lguest/lguest_bus.c b/drivers/lguest/lguest_bus.c deleted file mode 100644 index 2e9a202be44e..000000000000 --- a/drivers/lguest/lguest_bus.c +++ /dev/null | |||
@@ -1,220 +0,0 @@ | |||
1 | /*P:050 Lguest guests use a very simple bus for devices. It's a simple array | ||
2 | * of device descriptors contained just above the top of normal memory. The | ||
3 | * lguest bus is 80% tedious boilerplate code. :*/ | ||
4 | #include <linux/init.h> | ||
5 | #include <linux/bootmem.h> | ||
6 | #include <linux/lguest_bus.h> | ||
7 | #include <asm/io.h> | ||
8 | #include <asm/paravirt.h> | ||
9 | |||
10 | struct lguest_device_desc *lguest_devices; | ||
11 | |||
12 | static ssize_t type_show(struct device *_dev, | ||
13 | struct device_attribute *attr, char *buf) | ||
14 | { | ||
15 | struct lguest_device *dev = container_of(_dev,struct lguest_device,dev); | ||
16 | return sprintf(buf, "%hu", lguest_devices[dev->index].type); | ||
17 | } | ||
18 | static ssize_t features_show(struct device *_dev, | ||
19 | struct device_attribute *attr, char *buf) | ||
20 | { | ||
21 | struct lguest_device *dev = container_of(_dev,struct lguest_device,dev); | ||
22 | return sprintf(buf, "%hx", lguest_devices[dev->index].features); | ||
23 | } | ||
24 | static ssize_t pfn_show(struct device *_dev, | ||
25 | struct device_attribute *attr, char *buf) | ||
26 | { | ||
27 | struct lguest_device *dev = container_of(_dev,struct lguest_device,dev); | ||
28 | return sprintf(buf, "%u", lguest_devices[dev->index].pfn); | ||
29 | } | ||
30 | static ssize_t status_show(struct device *_dev, | ||
31 | struct device_attribute *attr, char *buf) | ||
32 | { | ||
33 | struct lguest_device *dev = container_of(_dev,struct lguest_device,dev); | ||
34 | return sprintf(buf, "%hx", lguest_devices[dev->index].status); | ||
35 | } | ||
36 | static ssize_t status_store(struct device *_dev, struct device_attribute *attr, | ||
37 | const char *buf, size_t count) | ||
38 | { | ||
39 | struct lguest_device *dev = container_of(_dev,struct lguest_device,dev); | ||
40 | if (sscanf(buf, "%hi", &lguest_devices[dev->index].status) != 1) | ||
41 | return -EINVAL; | ||
42 | return count; | ||
43 | } | ||
44 | static struct device_attribute lguest_dev_attrs[] = { | ||
45 | __ATTR_RO(type), | ||
46 | __ATTR_RO(features), | ||
47 | __ATTR_RO(pfn), | ||
48 | __ATTR(status, 0644, status_show, status_store), | ||
49 | __ATTR_NULL | ||
50 | }; | ||
51 | |||
52 | /*D:130 The generic bus infrastructure requires a function which says whether a | ||
53 | * device matches a driver. For us, it is simple: "struct lguest_driver" | ||
54 | * contains a "device_type" field which indicates what type of device it can | ||
55 | * handle, so we just cast the args and compare: */ | ||
56 | static int lguest_dev_match(struct device *_dev, struct device_driver *_drv) | ||
57 | { | ||
58 | struct lguest_device *dev = container_of(_dev,struct lguest_device,dev); | ||
59 | struct lguest_driver *drv = container_of(_drv,struct lguest_driver,drv); | ||
60 | |||
61 | return (drv->device_type == lguest_devices[dev->index].type); | ||
62 | } | ||
63 | /*:*/ | ||
64 | |||
65 | struct lguest_bus { | ||
66 | struct bus_type bus; | ||
67 | struct device dev; | ||
68 | }; | ||
69 | |||
70 | static struct lguest_bus lguest_bus = { | ||
71 | .bus = { | ||
72 | .name = "lguest", | ||
73 | .match = lguest_dev_match, | ||
74 | .dev_attrs = lguest_dev_attrs, | ||
75 | }, | ||
76 | .dev = { | ||
77 | .parent = NULL, | ||
78 | .bus_id = "lguest", | ||
79 | } | ||
80 | }; | ||
81 | |||
82 | /*D:140 This is the callback which occurs once the bus infrastructure matches | ||
83 | * up a device and driver, ie. in response to add_lguest_device() calling | ||
84 | * device_register(), or register_lguest_driver() calling driver_register(). | ||
85 | * | ||
86 | * At the moment it's always the latter: the devices are added first, since | ||
87 | * scan_devices() is called from a "core_initcall", and the drivers themselves | ||
88 | * called later as a normal "initcall". But it would work the other way too. | ||
89 | * | ||
90 | * So now we have the happy couple, we add the status bit to indicate that we | ||
91 | * found a driver. If the driver truly loves the device, it will return | ||
92 | * happiness from its probe function (ok, perhaps this wasn't my greatest | ||
93 | * analogy), and we set the final "driver ok" bit so the Host sees it's all | ||
94 | * green. */ | ||
95 | static int lguest_dev_probe(struct device *_dev) | ||
96 | { | ||
97 | int ret; | ||
98 | struct lguest_device*dev = container_of(_dev,struct lguest_device,dev); | ||
99 | struct lguest_driver*drv = container_of(dev->dev.driver, | ||
100 | struct lguest_driver, drv); | ||
101 | |||
102 | lguest_devices[dev->index].status |= LGUEST_DEVICE_S_DRIVER; | ||
103 | ret = drv->probe(dev); | ||
104 | if (ret == 0) | ||
105 | lguest_devices[dev->index].status |= LGUEST_DEVICE_S_DRIVER_OK; | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | /* The last part of the bus infrastructure is the function lguest drivers use | ||
110 | * to register themselves. Firstly, we do nothing if there's no lguest bus | ||
111 | * (ie. this is not a Guest), otherwise we fill in the embedded generic "struct | ||
112 | * driver" fields and call the generic driver_register(). */ | ||
113 | int register_lguest_driver(struct lguest_driver *drv) | ||
114 | { | ||
115 | if (!lguest_devices) | ||
116 | return 0; | ||
117 | |||
118 | drv->drv.bus = &lguest_bus.bus; | ||
119 | drv->drv.name = drv->name; | ||
120 | drv->drv.owner = drv->owner; | ||
121 | drv->drv.probe = lguest_dev_probe; | ||
122 | |||
123 | return driver_register(&drv->drv); | ||
124 | } | ||
125 | |||
126 | /* At the moment we build all the drivers into the kernel because they're so | ||
127 | * simple: 8144 bytes for all three of them as I type this. And as the console | ||
128 | * really needs to be built in, it's actually only 3527 bytes for the network | ||
129 | * and block drivers. | ||
130 | * | ||
131 | * If they get complex it will make sense for them to be modularized, so we | ||
132 | * need to explicitly export the symbol. | ||
133 | * | ||
134 | * I don't think non-GPL modules make sense, so it's a GPL-only export. | ||
135 | */ | ||
136 | EXPORT_SYMBOL_GPL(register_lguest_driver); | ||
137 | |||
138 | /*D:120 This is the core of the lguest bus: actually adding a new device. | ||
139 | * It's a separate function because it's neater that way, and because an | ||
140 | * earlier version of the code supported hotplug and unplug. They were removed | ||
141 | * early on because they were never used. | ||
142 | * | ||
143 | * As Andrew Tridgell says, "Untested code is buggy code". | ||
144 | * | ||
145 | * It's worth reading this carefully: we start with an index into the array of | ||
146 | * "struct lguest_device_desc"s indicating the device which is new: */ | ||
147 | static void add_lguest_device(unsigned int index) | ||
148 | { | ||
149 | struct lguest_device *new; | ||
150 | |||
151 | /* Each "struct lguest_device_desc" has a "status" field, which the | ||
152 | * Guest updates as the device is probed. In the worst case, the Host | ||
153 | * can look at these bits to tell what part of device setup failed, | ||
154 | * even if the console isn't available. */ | ||
155 | lguest_devices[index].status |= LGUEST_DEVICE_S_ACKNOWLEDGE; | ||
156 | new = kmalloc(sizeof(struct lguest_device), GFP_KERNEL); | ||
157 | if (!new) { | ||
158 | printk(KERN_EMERG "Cannot allocate lguest device %u\n", index); | ||
159 | lguest_devices[index].status |= LGUEST_DEVICE_S_FAILED; | ||
160 | return; | ||
161 | } | ||
162 | |||
163 | /* The "struct lguest_device" setup is pretty straight-forward example | ||
164 | * code. */ | ||
165 | new->index = index; | ||
166 | new->private = NULL; | ||
167 | memset(&new->dev, 0, sizeof(new->dev)); | ||
168 | new->dev.parent = &lguest_bus.dev; | ||
169 | new->dev.bus = &lguest_bus.bus; | ||
170 | sprintf(new->dev.bus_id, "%u", index); | ||
171 | |||
172 | /* device_register() causes the bus infrastructure to look for a | ||
173 | * matching driver. */ | ||
174 | if (device_register(&new->dev) != 0) { | ||
175 | printk(KERN_EMERG "Cannot register lguest device %u\n", index); | ||
176 | lguest_devices[index].status |= LGUEST_DEVICE_S_FAILED; | ||
177 | kfree(new); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | /*D:110 scan_devices() simply iterates through the device array. The type 0 | ||
182 | * is reserved to mean "no device", and anything else means we have found a | ||
183 | * device: add it. */ | ||
184 | static void scan_devices(void) | ||
185 | { | ||
186 | unsigned int i; | ||
187 | |||
188 | for (i = 0; i < LGUEST_MAX_DEVICES; i++) | ||
189 | if (lguest_devices[i].type) | ||
190 | add_lguest_device(i); | ||
191 | } | ||
192 | |||
193 | /*D:100 Fairly early in boot, lguest_bus_init() is called to set up the lguest | ||
194 | * bus. We check that we are a Guest by checking paravirt_ops.name: there are | ||
195 | * other ways of checking, but this seems most obvious to me. | ||
196 | * | ||
197 | * So we can access the array of "struct lguest_device_desc"s easily, we map | ||
198 | * that memory and store the pointer in the global "lguest_devices". Then we | ||
199 | * register the bus with the core. Doing two registrations seems clunky to me, | ||
200 | * but it seems to be the correct sysfs incantation. | ||
201 | * | ||
202 | * Finally we call scan_devices() which adds all the devices found in the | ||
203 | * "struct lguest_device_desc" array. */ | ||
204 | static int __init lguest_bus_init(void) | ||
205 | { | ||
206 | if (strcmp(pv_info.name, "lguest") != 0) | ||
207 | return 0; | ||
208 | |||
209 | /* Devices are in a single page above top of "normal" mem */ | ||
210 | lguest_devices = lguest_map(max_pfn<<PAGE_SHIFT, 1); | ||
211 | |||
212 | if (bus_register(&lguest_bus.bus) != 0 | ||
213 | || device_register(&lguest_bus.dev) != 0) | ||
214 | panic("lguest bus registration failed"); | ||
215 | |||
216 | scan_devices(); | ||
217 | return 0; | ||
218 | } | ||
219 | /* Do this after core stuff, before devices. */ | ||
220 | postcore_initcall(lguest_bus_init); | ||