1 #define DPRINTK(fmt, args...) \ 2 pr_debug("xenbus_probe (%s:%d) " fmt ".\n", \ 3 __func__, __LINE__, ##args) 4 5 #include <linux/kernel.h> 6 #include <linux/err.h> 7 #include <linux/string.h> 8 #include <linux/ctype.h> 9 #include <linux/fcntl.h> 10 #include <linux/mm.h> 11 #include <linux/proc_fs.h> 12 #include <linux/notifier.h> 13 #include <linux/kthread.h> 14 #include <linux/mutex.h> 15 #include <linux/io.h> 16 17 #include <asm/page.h> 18 #include <asm/pgtable.h> 19 #include <asm/xen/hypervisor.h> 20 #include <xen/xenbus.h> 21 #include <xen/events.h> 22 #include <xen/page.h> 23 24 #include <xen/platform_pci.h> 25 26 #include "xenbus_comms.h" 27 #include "xenbus_probe.h" 28 29 30 /* device/<type>/<id> => <type>-<id> */ 31 static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename) 32 { 33 nodename = strchr(nodename, '/'); 34 if (!nodename || strlen(nodename + 1) >= XEN_BUS_ID_SIZE) { 35 printk(KERN_WARNING "XENBUS: bad frontend %s\n", nodename); 36 return -EINVAL; 37 } 38 39 strlcpy(bus_id, nodename + 1, XEN_BUS_ID_SIZE); 40 if (!strchr(bus_id, '/')) { 41 printk(KERN_WARNING "XENBUS: bus_id %s no slash\n", bus_id); 42 return -EINVAL; 43 } 44 *strchr(bus_id, '/') = '-'; 45 return 0; 46 } 47 48 /* device/<typename>/<name> */ 49 static int xenbus_probe_frontend(struct xen_bus_type *bus, const char *type, 50 const char *name) 51 { 52 char *nodename; 53 int err; 54 55 nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", bus->root, type, name); 56 if (!nodename) 57 return -ENOMEM; 58 59 DPRINTK("%s", nodename); 60 61 err = xenbus_probe_node(bus, type, nodename); 62 kfree(nodename); 63 return err; 64 } 65 66 static int xenbus_uevent_frontend(struct device *_dev, 67 struct kobj_uevent_env *env) 68 { 69 struct xenbus_device *dev = to_xenbus_device(_dev); 70 71 if (add_uevent_var(env, "MODALIAS=xen:%s", dev->devicetype)) 72 return -ENOMEM; 73 74 return 0; 75 } 76 77 78 static void backend_changed(struct xenbus_watch *watch, 79 const char **vec, unsigned int len) 80 { 81 xenbus_otherend_changed(watch, vec, len, 1); 82 } 83 84 static struct device_attribute xenbus_frontend_dev_attrs[] = { 85 __ATTR_NULL 86 }; 87 88 static struct xen_bus_type xenbus_frontend = { 89 .root = "device", 90 .levels = 2, /* device/type/<id> */ 91 .get_bus_id = frontend_bus_id, 92 .probe = xenbus_probe_frontend, 93 .otherend_changed = backend_changed, 94 .bus = { 95 .name = "xen", 96 .match = xenbus_match, 97 .uevent = xenbus_uevent_frontend, 98 .probe = xenbus_dev_probe, 99 .remove = xenbus_dev_remove, 100 .shutdown = xenbus_dev_shutdown, 101 .dev_attrs = xenbus_frontend_dev_attrs, 102 103 .suspend = xenbus_dev_suspend, 104 .resume = xenbus_dev_resume, 105 }, 106 }; 107 108 static void frontend_changed(struct xenbus_watch *watch, 109 const char **vec, unsigned int len) 110 { 111 DPRINTK(""); 112 113 xenbus_dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend); 114 } 115 116 117 /* We watch for devices appearing and vanishing. */ 118 static struct xenbus_watch fe_watch = { 119 .node = "device", 120 .callback = frontend_changed, 121 }; 122 123 static int read_backend_details(struct xenbus_device *xendev) 124 { 125 return xenbus_read_otherend_details(xendev, "backend-id", "backend"); 126 } 127 128 static int is_device_connecting(struct device *dev, void *data) 129 { 130 struct xenbus_device *xendev = to_xenbus_device(dev); 131 struct device_driver *drv = data; 132 struct xenbus_driver *xendrv; 133 134 /* 135 * A device with no driver will never connect. We care only about 136 * devices which should currently be in the process of connecting. 137 */ 138 if (!dev->driver) 139 return 0; 140 141 /* Is this search limited to a particular driver? */ 142 if (drv && (dev->driver != drv)) 143 return 0; 144 145 xendrv = to_xenbus_driver(dev->driver); 146 return (xendev->state < XenbusStateConnected || 147 (xendev->state == XenbusStateConnected && 148 xendrv->is_ready && !xendrv->is_ready(xendev))); 149 } 150 151 static int exists_connecting_device(struct device_driver *drv) 152 { 153 return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, 154 is_device_connecting); 155 } 156 157 static int print_device_status(struct device *dev, void *data) 158 { 159 struct xenbus_device *xendev = to_xenbus_device(dev); 160 struct device_driver *drv = data; 161 162 /* Is this operation limited to a particular driver? */ 163 if (drv && (dev->driver != drv)) 164 return 0; 165 166 if (!dev->driver) { 167 /* Information only: is this too noisy? */ 168 printk(KERN_INFO "XENBUS: Device with no driver: %s\n", 169 xendev->nodename); 170 } else if (xendev->state < XenbusStateConnected) { 171 enum xenbus_state rstate = XenbusStateUnknown; 172 if (xendev->otherend) 173 rstate = xenbus_read_driver_state(xendev->otherend); 174 printk(KERN_WARNING "XENBUS: Timeout connecting " 175 "to device: %s (local state %d, remote state %d)\n", 176 xendev->nodename, xendev->state, rstate); 177 } 178 179 return 0; 180 } 181 182 /* We only wait for device setup after most initcalls have run. */ 183 static int ready_to_wait_for_devices; 184 185 /* 186 * On a 5-minute timeout, wait for all devices currently configured. We need 187 * to do this to guarantee that the filesystems and / or network devices 188 * needed for boot are available, before we can allow the boot to proceed. 189 * 190 * This needs to be on a late_initcall, to happen after the frontend device 191 * drivers have been initialised, but before the root fs is mounted. 192 * 193 * A possible improvement here would be to have the tools add a per-device 194 * flag to the store entry, indicating whether it is needed at boot time. 195 * This would allow people who knew what they were doing to accelerate their 196 * boot slightly, but of course needs tools or manual intervention to set up 197 * those flags correctly. 198 */ 199 static void wait_for_devices(struct xenbus_driver *xendrv) 200 { 201 unsigned long start = jiffies; 202 struct device_driver *drv = xendrv ? &xendrv->driver : NULL; 203 unsigned int seconds_waited = 0; 204 205 if (!ready_to_wait_for_devices || !xen_domain()) 206 return; 207 208 while (exists_connecting_device(drv)) { 209 if (time_after(jiffies, start + (seconds_waited+5)*HZ)) { 210 if (!seconds_waited) 211 printk(KERN_WARNING "XENBUS: Waiting for " 212 "devices to initialise: "); 213 seconds_waited += 5; 214 printk("%us...", 300 - seconds_waited); 215 if (seconds_waited == 300) 216 break; 217 } 218 219 schedule_timeout_interruptible(HZ/10); 220 } 221 222 if (seconds_waited) 223 printk("\n"); 224 225 bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, 226 print_device_status); 227 } 228 229 int __xenbus_register_frontend(struct xenbus_driver *drv, 230 struct module *owner, const char *mod_name) 231 { 232 int ret; 233 234 drv->read_otherend_details = read_backend_details; 235 236 ret = xenbus_register_driver_common(drv, &xenbus_frontend, 237 owner, mod_name); 238 if (ret) 239 return ret; 240 241 /* If this driver is loaded as a module wait for devices to attach. */ 242 wait_for_devices(drv); 243 244 return 0; 245 } 246 EXPORT_SYMBOL_GPL(__xenbus_register_frontend); 247 248 static int frontend_probe_and_watch(struct notifier_block *notifier, 249 unsigned long event, 250 void *data) 251 { 252 /* Enumerate devices in xenstore and watch for changes. */ 253 xenbus_probe_devices(&xenbus_frontend); 254 register_xenbus_watch(&fe_watch); 255 256 return NOTIFY_DONE; 257 } 258 259 260 static int __init xenbus_probe_frontend_init(void) 261 { 262 static struct notifier_block xenstore_notifier = { 263 .notifier_call = frontend_probe_and_watch 264 }; 265 int err; 266 267 DPRINTK(""); 268 269 /* Register ourselves with the kernel bus subsystem */ 270 err = bus_register(&xenbus_frontend.bus); 271 if (err) 272 return err; 273 274 register_xenstore_notifier(&xenstore_notifier); 275 276 return 0; 277 } 278 subsys_initcall(xenbus_probe_frontend_init); 279 280 #ifndef MODULE 281 static int __init boot_wait_for_devices(void) 282 { 283 if (xen_hvm_domain() && !xen_platform_pci_unplug) 284 return -ENODEV; 285 286 ready_to_wait_for_devices = 1; 287 wait_for_devices(NULL); 288 return 0; 289 } 290 291 late_initcall(boot_wait_for_devices); 292 #endif 293 294 MODULE_LICENSE("GPL"); 295