- Update Xen patches to 3.3-rc5 and c/s 1157.
[linux-flexiantxendom0-3.2.10.git] / drivers / xen / blktap / xenbus.c
1 /* drivers/xen/blktap/xenbus.c
2  *
3  * Xenbus code for blktap
4  *
5  * Copyright (c) 2004-2005, Andrew Warfield and Julian Chesterfield
6  *
7  * Based on the blkback xenbus code:
8  *
9  * Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
10  * Copyright (C) 2005 XenSource Ltd
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License version 2
14  * as published by the Free Software Foundation; or, when distributed
15  * separately from the Linux kernel or incorporated into other
16  * software packages, subject to the following license:
17  *
18  * Permission is hereby granted, free of charge, to any person obtaining a copy
19  * of this source file (the "Software"), to deal in the Software without
20  * restriction, including without limitation the rights to use, copy, modify,
21  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
22  * and to permit persons to whom the Software is furnished to do so, subject to
23  * the following conditions:
24  *
25  * The above copyright notice and this permission notice shall be included in
26  * all copies or substantial portions of the Software.
27  *
28  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
34  * IN THE SOFTWARE.
35  */
36
37 #include <stdarg.h>
38 #include <linux/kthread.h>
39 #include <xen/xenbus.h>
40 #include "common.h"
41 #include "../core/domctl.h"
42
43
44 struct backend_info
45 {
46         struct xenbus_device *dev;
47         blkif_t *blkif;
48         struct xenbus_watch backend_watch;
49         int xenbus_id;
50         int group_added;
51 };
52
53 static void connect(struct backend_info *);
54 static int connect_ring(struct backend_info *);
55 static int blktap_remove(struct xenbus_device *dev);
56 static int blktap_probe(struct xenbus_device *dev,
57                          const struct xenbus_device_id *id);
58 static void tap_backend_changed(struct xenbus_watch *, const char **,
59                             unsigned int);
60 static void tap_frontend_changed(struct xenbus_device *dev,
61                              enum xenbus_state frontend_state);
62
63 static int strsep_len(const char *str, char c, unsigned int len)
64 {
65         unsigned int i;
66
67         for (i = 0; str[i]; i++)
68                 if (str[i] == c) {
69                         if (len == 0)
70                                 return i;
71                         len--;
72                 }
73         return -ERANGE;
74 }
75
76 static long get_id(const char *str)
77 {
78         int len;
79         const char *ptr;
80         char num[10];
81         
82         len = strsep_len(str, '/', 2);
83         if (len < 0)
84                 return -1;
85         
86         ptr = str + len + 1;
87         strlcpy(num, ptr, ARRAY_SIZE(num));
88         DPRINTK("get_id(%s) -> %s\n", str, num);
89         
90         return simple_strtol(num, NULL, 10);
91 }                               
92
93 static int blktap_name(blkif_t *blkif, char *buf)
94 {
95         char *devpath, *devname;
96         struct xenbus_device *dev = blkif->be->dev;
97
98         devpath = xenbus_read(XBT_NIL, dev->nodename, "dev", NULL);
99         if (IS_ERR(devpath)) 
100                 return PTR_ERR(devpath);
101         
102         if ((devname = strstr(devpath, "/dev/")) != NULL)
103                 devname += strlen("/dev/");
104         else
105                 devname  = devpath;
106
107         snprintf(buf, TASK_COMM_LEN, "blktap.%d.%s", blkif->domid, devname);
108         kfree(devpath);
109         
110         return 0;
111 }
112
113 /****************************************************************
114  *  sysfs interface for I/O requests of blktap device
115  */
116
117 #define VBD_SHOW(name, format, args...)                                 \
118         static ssize_t show_##name(struct device *_dev,                 \
119                                    struct device_attribute *attr,       \
120                                    char *buf)                           \
121         {                                                               \
122                 ssize_t ret = -ENODEV;                                  \
123                 struct xenbus_device *dev;                              \
124                 struct backend_info *be;                                \
125                                                                         \
126                 if (!get_device(_dev))                                  \
127                         return ret;                                     \
128                 dev = to_xenbus_device(_dev);                           \
129                 if ((be = dev_get_drvdata(&dev->dev)) != NULL)          \
130                         ret = sprintf(buf, format, ##args);             \
131                 put_device(_dev);                                       \
132                 return ret;                                             \
133         }                                                               \
134         static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
135
136 VBD_SHOW(oo_req,  "%d\n", be->blkif->st_oo_req);
137 VBD_SHOW(rd_req,  "%d\n", be->blkif->st_rd_req);
138 VBD_SHOW(wr_req,  "%d\n", be->blkif->st_wr_req);
139 VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect);
140 VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect);
141
142 static struct attribute *tapstat_attrs[] = {
143         &dev_attr_oo_req.attr,
144         &dev_attr_rd_req.attr,
145         &dev_attr_wr_req.attr,
146         &dev_attr_rd_sect.attr,
147         &dev_attr_wr_sect.attr,
148         NULL
149 };
150
151 static const struct attribute_group tapstat_group = {
152         .name = "statistics",
153         .attrs = tapstat_attrs,
154 };
155
156 int xentap_sysfs_addif(struct xenbus_device *dev)
157 {
158         int err;
159         struct backend_info *be = dev_get_drvdata(&dev->dev);
160         err = sysfs_create_group(&dev->dev.kobj, &tapstat_group);
161         if (!err)
162                 be->group_added = 1;
163         return err;
164 }
165
166 void xentap_sysfs_delif(struct xenbus_device *dev)
167 {
168         struct backend_info *be = dev_get_drvdata(&dev->dev);
169         sysfs_remove_group(&dev->dev.kobj, &tapstat_group);
170         be->group_added = 0;
171 }
172
173 static int blktap_remove(struct xenbus_device *dev)
174 {
175         struct backend_info *be = dev_get_drvdata(&dev->dev);
176
177         if (be->group_added)
178                 xentap_sysfs_delif(be->dev);
179         if (be->backend_watch.node) {
180                 unregister_xenbus_watch(&be->backend_watch);
181                 kfree(be->backend_watch.node);
182                 be->backend_watch.node = NULL;
183         }
184         if (be->blkif) {
185                 if (be->blkif->xenblkd)
186                         kthread_stop(be->blkif->xenblkd);
187                 signal_tapdisk(be->blkif->dev_num);
188                 tap_blkif_free(be->blkif, dev);
189                 tap_blkif_kmem_cache_free(be->blkif);
190                 be->blkif = NULL;
191         }
192         kfree(be);
193         dev_set_drvdata(&dev->dev, NULL);
194         return 0;
195 }
196
197 static void tap_update_blkif_status(blkif_t *blkif)
198
199         int err;
200         char name[TASK_COMM_LEN];
201
202         /* Not ready to connect? */
203         if(!blkif->irq || !blkif->sectors) {
204                 return;
205         } 
206
207         /* Already connected? */
208         if (blkif->be->dev->state == XenbusStateConnected)
209                 return;
210
211         /* Attempt to connect: exit if we fail to. */
212         connect(blkif->be);
213         if (blkif->be->dev->state != XenbusStateConnected)
214                 return;
215
216         err = blktap_name(blkif, name);
217         if (err) {
218                 xenbus_dev_error(blkif->be->dev, err, "get blktap dev name");
219                 return;
220         }
221
222         if (!blkif->be->group_added) {
223                 err = xentap_sysfs_addif(blkif->be->dev);
224                 if (err) {
225                         xenbus_dev_fatal(blkif->be->dev, err, 
226                                          "creating sysfs entries");
227                         return;
228                 }
229         }
230
231         blkif->xenblkd = kthread_run(tap_blkif_schedule, blkif, name);
232         if (IS_ERR(blkif->xenblkd)) {
233                 err = PTR_ERR(blkif->xenblkd);
234                 blkif->xenblkd = NULL;
235                 xenbus_dev_fatal(blkif->be->dev, err, "start xenblkd");
236                 WPRINTK("Error starting thread %s\n", name);
237         } else
238                 DPRINTK("Thread started for domid %d, connected disk %d\n",
239                         blkif->domid, blkif->dev_num);
240
241 }
242
243 /**
244  * Entry point to this code when a new device is created.  Allocate
245  * the basic structures, and watch the store waiting for the
246  * user-space program to tell us the physical device info.  Switch to
247  * InitWait.
248  */
249 static int blktap_probe(struct xenbus_device *dev,
250                          const struct xenbus_device_id *id)
251 {
252         int err;
253         struct backend_info *be = kzalloc(sizeof(struct backend_info),
254                                           GFP_KERNEL);
255         if (!be) {
256                 xenbus_dev_fatal(dev, -ENOMEM,
257                                  "allocating backend structure");
258                 return -ENOMEM;
259         }
260
261         be->dev = dev;
262         dev_set_drvdata(&dev->dev, be);
263         be->xenbus_id = get_id(dev->nodename);
264
265         be->blkif = tap_alloc_blkif(dev->otherend_id);
266         if (IS_ERR(be->blkif)) {
267                 err = PTR_ERR(be->blkif);
268                 be->blkif = NULL;
269                 xenbus_dev_fatal(dev, err, "creating block interface");
270                 goto fail;
271         }
272
273         /* setup back pointer */
274         be->blkif->be = be;
275         be->blkif->sectors = 0;
276
277         /* set a watch on disk info, waiting for userspace to update details*/
278         err = xenbus_watch_path2(dev, dev->nodename, "info",
279                                  &be->backend_watch, tap_backend_changed);
280         if (err)
281                 goto fail;
282         
283         err = xenbus_switch_state(dev, XenbusStateInitWait);
284         if (err)
285                 goto fail;
286         return 0;
287
288 fail:
289         DPRINTK("blktap probe failed\n");
290         blktap_remove(dev);
291         return err;
292 }
293
294
295 /**
296  * Callback received when the user space code has placed the device
297  * information in xenstore. 
298  */
299 static void tap_backend_changed(struct xenbus_watch *watch,
300                             const char **vec, unsigned int len)
301 {
302         int err;
303         unsigned long info;
304         struct backend_info *be
305                 = container_of(watch, struct backend_info, backend_watch);
306         struct xenbus_device *dev = be->dev;
307         
308         /** 
309          * Check to see whether userspace code has opened the image 
310          * and written sector
311          * and disk info to xenstore
312          */
313         err = xenbus_gather(XBT_NIL, dev->nodename, "info", "%lu", &info, 
314                             "sectors", "%Lu", &be->blkif->sectors, NULL);
315         if (XENBUS_EXIST_ERR(err))
316                 return;
317         if (err) {
318                 xenbus_dev_error(dev, err, "getting info");
319                 return;
320         }
321
322         DPRINTK("Userspace update on disk info, %lu\n",info);
323
324         /* Associate tap dev with domid*/
325         be->blkif->dev_num = dom_to_devid(be->blkif->domid, be->xenbus_id, 
326                                           be->blkif);
327
328         tap_update_blkif_status(be->blkif);
329 }
330
331
332 static void blkif_disconnect(blkif_t *blkif)
333 {
334         if (blkif->xenblkd) {
335                 kthread_stop(blkif->xenblkd);
336                 blkif->xenblkd = NULL;
337         }
338
339         /* idempotent */
340         tap_blkif_free(blkif, blkif->be->dev);
341 }
342
343 /**
344  * Callback received when the frontend's state changes.
345  */
346 static void tap_frontend_changed(struct xenbus_device *dev,
347                              enum xenbus_state frontend_state)
348 {
349         struct backend_info *be = dev_get_drvdata(&dev->dev);
350         int err;
351
352         DPRINTK("fe_changed(%s,%d)\n", dev->nodename, frontend_state);
353
354         switch (frontend_state) {
355         case XenbusStateInitialising:
356                 if (dev->state == XenbusStateClosed) {
357                         pr_info("%s: %s: prepare for reconnect\n",
358                                 __FUNCTION__, dev->nodename);
359                         xenbus_switch_state(dev, XenbusStateInitWait);
360                 }
361                 break;
362
363         case XenbusStateInitialised:
364         case XenbusStateConnected:
365                 /* Ensure we connect even when two watches fire in 
366                    close successsion and we miss the intermediate value 
367                    of frontend_state. */
368                 if (dev->state == XenbusStateConnected)
369                         break;
370
371                 /* Enforce precondition before potential leak point.
372                  * blkif_disconnect() is idempotent.
373                  */
374                 blkif_disconnect(be->blkif);
375
376                 err = connect_ring(be);
377                 if (err)
378                         break;
379                 tap_update_blkif_status(be->blkif);
380                 break;
381
382         case XenbusStateClosing:
383                 blkif_disconnect(be->blkif);
384                 xenbus_switch_state(dev, XenbusStateClosing);
385                 break;
386
387         case XenbusStateClosed:
388                 xenbus_switch_state(dev, XenbusStateClosed);
389                 if (xenbus_dev_is_online(dev))
390                         break;
391                 /* fall through if not online */
392         case XenbusStateUnknown:
393                 /* Implies the effects of blkif_disconnect() via
394                  * blktap_remove().
395                  */
396                 device_unregister(&dev->dev);
397                 break;
398
399         default:
400                 xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
401                                  frontend_state);
402                 break;
403         }
404 }
405
406
407 /**
408  * Switch to Connected state.
409  */
410 static void connect(struct backend_info *be)
411 {
412         int err;
413
414         struct xenbus_device *dev = be->dev;
415         struct xenbus_transaction xbt;
416
417         /* Write feature-barrier to xenstore */
418 again:
419         err = xenbus_transaction_start(&xbt);
420         if (err) {
421                 xenbus_dev_fatal(dev, err, "starting transaction");
422                 return;
423         }
424
425         err = xenbus_printf(xbt, dev->nodename, "feature-barrier",  "1");
426         if (err) {
427                 xenbus_dev_fatal(dev, err, "writing feature-barrier");
428                 xenbus_transaction_end(xbt, 1);
429                 return;
430         }
431
432         err = xenbus_transaction_end(xbt, 0);
433         if (err == -EAGAIN)
434                 goto again;
435
436         /* Switch state */
437         err = xenbus_switch_state(dev, XenbusStateConnected);
438         if (err)
439                 xenbus_dev_fatal(dev, err, "%s: switching to Connected state",
440                                  dev->nodename);
441
442         return;
443 }
444
445
446 static int connect_ring(struct backend_info *be)
447 {
448         struct xenbus_device *dev = be->dev;
449         unsigned int ring_ref, evtchn;
450         char *protocol;
451         int err;
452
453         DPRINTK("%s\n", dev->otherend);
454
455         err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%u",
456                             &ring_ref, "event-channel", "%u", &evtchn, NULL);
457         if (err) {
458                 xenbus_dev_fatal(dev, err,
459                                  "reading %s/ring-ref and event-channel",
460                                  dev->otherend);
461                 return err;
462         }
463
464         be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE;
465         err = xenbus_gather(XBT_NIL, dev->otherend, "protocol",
466                             NULL, &protocol, NULL);
467         if (err) {
468                 protocol = NULL;
469                 be->blkif->blk_protocol = xen_guest_blkif_protocol(be->blkif->domid);
470         }
471         else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE))
472                 be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE;
473         else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32))
474                 be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_32;
475         else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_64))
476                 be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_64;
477         else {
478                 xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol);
479                 kfree(protocol);
480                 return -1;
481         }
482         pr_info("blktap: ring-ref %u, event-channel %u, protocol %d (%s)\n",
483                 ring_ref, evtchn, be->blkif->blk_protocol,
484                 protocol ?: "unspecified");
485         kfree(protocol);
486
487         /* Map the shared frame, irq etc. */
488         err = tap_blkif_map(be->blkif, dev, ring_ref, evtchn);
489         if (err) {
490                 xenbus_dev_fatal(dev, err, "mapping ring-ref %u port %u",
491                                  ring_ref, evtchn);
492                 return err;
493         } 
494
495         return 0;
496 }
497
498
499 /* ** Driver Registration ** */
500
501
502 static const struct xenbus_device_id blktap_ids[] = {
503         { "tap" },
504         { "" }
505 };
506
507 static DEFINE_XENBUS_DRIVER(blktap, ,
508         .probe = blktap_probe,
509         .remove = blktap_remove,
510         .otherend_changed = tap_frontend_changed
511 );
512
513
514 void tap_blkif_xenbus_init(void)
515 {
516         WARN_ON(xenbus_register_backend(&blktap_driver));
517 }