Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.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/module.h>
39 #include <linux/kthread.h>
40 #include <xen/xenbus.h>
41 #include "common.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 };
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 (len == 0) ? i : -ERANGE;
74 }
75
76 static long get_id(const char *str)
77 {
78         int len,end;
79         const char *ptr;
80         char *tptr, num[10];
81         
82         len = strsep_len(str, '/', 2);
83         end = strlen(str);
84         if ( (len < 0) || (end < 0) ) return -1;
85         
86         ptr = str + len + 1;
87         strncpy(num,ptr,end - len);
88         tptr = num + (end - (len + 1));
89         *tptr = '\0';
90         DPRINTK("Get_id called for %s (%s)\n",str,num);
91         
92         return simple_strtol(num, NULL, 10);
93 }                               
94
95 static void tap_update_blkif_status(blkif_t *blkif)
96
97         int err;
98
99         /* Not ready to connect? */
100         if(!blkif->irq || !blkif->sectors) {
101                 return;
102         } 
103
104         /* Already connected? */
105         if (blkif->be->dev->state == XenbusStateConnected)
106                 return;
107
108         /* Attempt to connect: exit if we fail to. */
109         connect(blkif->be);
110         if (blkif->be->dev->state != XenbusStateConnected)
111                 return;
112
113         blkif->xenblkd = kthread_run(tap_blkif_schedule, blkif,
114                                      "xvd %d",
115                                      blkif->domid);
116
117         if (IS_ERR(blkif->xenblkd)) {
118                 err = PTR_ERR(blkif->xenblkd);
119                 blkif->xenblkd = NULL;
120                 xenbus_dev_fatal(blkif->be->dev, err, "start xenblkd");
121                 WPRINTK("Error starting thread\n");
122         }
123 }
124
125 static int blktap_remove(struct xenbus_device *dev)
126 {
127         struct backend_info *be = dev->dev.driver_data;
128
129         if (be->backend_watch.node) {
130                 unregister_xenbus_watch(&be->backend_watch);
131                 kfree(be->backend_watch.node);
132                 be->backend_watch.node = NULL;
133         }
134         if (be->blkif) {
135                 if (be->blkif->xenblkd)
136                         kthread_stop(be->blkif->xenblkd);
137                 signal_tapdisk(be->blkif->dev_num);
138                 tap_blkif_free(be->blkif);
139                 be->blkif = NULL;
140         }
141         kfree(be);
142         dev->dev.driver_data = NULL;
143         return 0;
144 }
145
146 /**
147  * Entry point to this code when a new device is created.  Allocate
148  * the basic structures, and watch the store waiting for the
149  * user-space program to tell us the physical device info.  Switch to
150  * InitWait.
151  */
152 static int blktap_probe(struct xenbus_device *dev,
153                          const struct xenbus_device_id *id)
154 {
155         int err;
156         struct backend_info *be = kzalloc(sizeof(struct backend_info),
157                                           GFP_KERNEL);
158         if (!be) {
159                 xenbus_dev_fatal(dev, -ENOMEM,
160                                  "allocating backend structure");
161                 return -ENOMEM;
162         }
163
164         be->dev = dev;
165         dev->dev.driver_data = be;
166         be->xenbus_id = get_id(dev->nodename);
167
168         be->blkif = tap_alloc_blkif(dev->otherend_id);
169         if (IS_ERR(be->blkif)) {
170                 err = PTR_ERR(be->blkif);
171                 be->blkif = NULL;
172                 xenbus_dev_fatal(dev, err, "creating block interface");
173                 goto fail;
174         }
175
176         /* setup back pointer */
177         be->blkif->be = be;
178         be->blkif->sectors = 0;
179
180         /* set a watch on disk info, waiting for userspace to update details*/
181         err = xenbus_watch_path2(dev, dev->nodename, "info",
182                                  &be->backend_watch, tap_backend_changed);
183         if (err)
184                 goto fail;
185         
186         err = xenbus_switch_state(dev, XenbusStateInitWait);
187         if (err)
188                 goto fail;
189         return 0;
190
191 fail:
192         DPRINTK("blktap probe failed");
193         blktap_remove(dev);
194         return err;
195 }
196
197
198 /**
199  * Callback received when the user space code has placed the device
200  * information in xenstore. 
201  */
202 static void tap_backend_changed(struct xenbus_watch *watch,
203                             const char **vec, unsigned int len)
204 {
205         int err;
206         unsigned long info;
207         struct backend_info *be
208                 = container_of(watch, struct backend_info, backend_watch);
209         struct xenbus_device *dev = be->dev;
210         
211         /** 
212          * Check to see whether userspace code has opened the image 
213          * and written sector
214          * and disk info to xenstore
215          */
216         err = xenbus_gather(XBT_NIL, dev->nodename, "info", "%lu", &info, 
217                             NULL);      
218         if (err) {
219                 xenbus_dev_error(dev, err, "getting info");
220                 return;
221         }
222
223         DPRINTK("Userspace update on disk info, %lu\n",info);
224
225         err = xenbus_gather(XBT_NIL, dev->nodename, "sectors", "%llu", 
226                             &be->blkif->sectors, NULL);
227
228         /* Associate tap dev with domid*/
229         be->blkif->dev_num = dom_to_devid(be->blkif->domid, be->xenbus_id, 
230                                           be->blkif);
231         DPRINTK("Thread started for domid [%d], connecting disk\n", 
232                 be->blkif->dev_num);
233
234         tap_update_blkif_status(be->blkif);
235 }
236
237 /**
238  * Callback received when the frontend's state changes.
239  */
240 static void tap_frontend_changed(struct xenbus_device *dev,
241                              enum xenbus_state frontend_state)
242 {
243         struct backend_info *be = dev->dev.driver_data;
244         int err;
245
246         DPRINTK("");
247
248         switch (frontend_state) {
249         case XenbusStateInitialising:
250                 if (dev->state == XenbusStateClosed) {
251                         printk("%s: %s: prepare for reconnect\n",
252                                __FUNCTION__, dev->nodename);
253                         xenbus_switch_state(dev, XenbusStateInitWait);
254                 }
255                 break;
256
257         case XenbusStateInitialised:
258         case XenbusStateConnected:
259                 /* Ensure we connect even when two watches fire in 
260                    close successsion and we miss the intermediate value 
261                    of frontend_state. */
262                 if (dev->state == XenbusStateConnected)
263                         break;
264
265                 err = connect_ring(be);
266                 if (err)
267                         break;
268                 tap_update_blkif_status(be->blkif);
269                 break;
270
271         case XenbusStateClosing:
272                 if (be->blkif->xenblkd) {
273                         kthread_stop(be->blkif->xenblkd);
274                         be->blkif->xenblkd = NULL;
275                 }
276                 xenbus_switch_state(dev, XenbusStateClosing);
277                 break;
278
279         case XenbusStateClosed:
280                 xenbus_switch_state(dev, XenbusStateClosed);
281                 if (xenbus_dev_is_online(dev))
282                         break;
283                 /* fall through if not online */
284         case XenbusStateUnknown:
285                 device_unregister(&dev->dev);
286                 break;
287
288         default:
289                 xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
290                                  frontend_state);
291                 break;
292         }
293 }
294
295
296 /**
297  * Switch to Connected state.
298  */
299 static void connect(struct backend_info *be)
300 {
301         int err;
302
303         struct xenbus_device *dev = be->dev;
304
305         err = xenbus_switch_state(dev, XenbusStateConnected);
306         if (err)
307                 xenbus_dev_fatal(dev, err, "switching to Connected state",
308                                  dev->nodename);
309
310         return;
311 }
312
313
314 static int connect_ring(struct backend_info *be)
315 {
316         struct xenbus_device *dev = be->dev;
317         unsigned long ring_ref;
318         unsigned int evtchn;
319         int err;
320
321         DPRINTK("%s", dev->otherend);
322
323         err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", 
324                             &ring_ref, "event-channel", "%u", &evtchn, NULL);
325         if (err) {
326                 xenbus_dev_fatal(dev, err,
327                                  "reading %s/ring-ref and event-channel",
328                                  dev->otherend);
329                 return err;
330         }
331
332         /* Map the shared frame, irq etc. */
333         err = tap_blkif_map(be->blkif, ring_ref, evtchn);
334         if (err) {
335                 xenbus_dev_fatal(dev, err, "mapping ring-ref %lu port %u",
336                                  ring_ref, evtchn);
337                 return err;
338         } 
339
340         return 0;
341 }
342
343
344 /* ** Driver Registration ** */
345
346
347 static struct xenbus_device_id blktap_ids[] = {
348         { "tap" },
349         { "" }
350 };
351
352
353 static struct xenbus_driver blktap = {
354         .name = "tap",
355         .owner = THIS_MODULE,
356         .ids = blktap_ids,
357         .probe = blktap_probe,
358         .remove = blktap_remove,
359         .otherend_changed = tap_frontend_changed
360 };
361
362
363 void tap_blkif_xenbus_init(void)
364 {
365         xenbus_register_backend(&blktap);
366 }