Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / interface / xen / xenbus.c
1 /*
2  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <stdio.h>
23 #include <errno.h>
24 #include <ipxe/malloc.h>
25 #include <ipxe/device.h>
26 #include <ipxe/timer.h>
27 #include <ipxe/nap.h>
28 #include <ipxe/xen.h>
29 #include <ipxe/xenstore.h>
30 #include <ipxe/xenbus.h>
31
32 /** @file
33  *
34  * Xen device bus
35  *
36  */
37
38 /* Disambiguate the various error causes */
39 #define ETIMEDOUT_UNKNOWN                                               \
40         __einfo_error ( EINFO_ETIMEDOUT_UNKNOWN )
41 #define EINFO_ETIMEDOUT_UNKNOWN                                         \
42         __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateUnknown,          \
43                           "Unknown" )
44 #define ETIMEDOUT_INITIALISING                                          \
45         __einfo_error ( EINFO_ETIMEDOUT_INITIALISING )
46 #define EINFO_ETIMEDOUT_INITIALISING                                    \
47         __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateInitialising,     \
48                           "Initialising" )
49 #define ETIMEDOUT_INITWAIT                                              \
50         __einfo_error ( EINFO_ETIMEDOUT_INITWAIT )
51 #define EINFO_ETIMEDOUT_INITWAIT                                        \
52         __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateInitWait,         \
53                           "InitWait" )
54 #define ETIMEDOUT_INITIALISED                                           \
55         __einfo_error ( EINFO_ETIMEDOUT_INITIALISED )
56 #define EINFO_ETIMEDOUT_INITIALISED                                     \
57         __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateInitialised,      \
58                           "Initialised" )
59 #define ETIMEDOUT_CONNECTED                                             \
60         __einfo_error ( EINFO_ETIMEDOUT_CONNECTED )
61 #define EINFO_ETIMEDOUT_CONNECTED                                       \
62         __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateConnected,        \
63                           "Connected" )
64 #define ETIMEDOUT_CLOSING                                               \
65         __einfo_error ( EINFO_ETIMEDOUT_CLOSING )
66 #define EINFO_ETIMEDOUT_CLOSING                                         \
67         __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateClosing,          \
68                           "Closing" )
69 #define ETIMEDOUT_CLOSED                                                \
70         __einfo_error ( EINFO_ETIMEDOUT_CLOSED )
71 #define EINFO_ETIMEDOUT_CLOSED                                          \
72         __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateClosed,           \
73                           "Closed" )
74 #define ETIMEDOUT_RECONFIGURING                                         \
75         __einfo_error ( EINFO_ETIMEDOUT_RECONFIGURING )
76 #define EINFO_ETIMEDOUT_RECONFIGURING                                   \
77         __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateReconfiguring,    \
78                           "Reconfiguring" )
79 #define ETIMEDOUT_RECONFIGURED                                          \
80         __einfo_error ( EINFO_ETIMEDOUT_RECONFIGURED )
81 #define EINFO_ETIMEDOUT_RECONFIGURED                                    \
82         __einfo_uniqify ( EINFO_ETIMEDOUT, XenbusStateReconfigured,     \
83                           "Reconfigured" )
84 #define ETIMEDOUT_STATE( state )                                        \
85         EUNIQ ( EINFO_ETIMEDOUT, (state), ETIMEDOUT_UNKNOWN,            \
86                 ETIMEDOUT_INITIALISING, ETIMEDOUT_INITWAIT,             \
87                 ETIMEDOUT_INITIALISED, ETIMEDOUT_CONNECTED,             \
88                 ETIMEDOUT_CLOSING, ETIMEDOUT_CLOSED,                    \
89                 ETIMEDOUT_RECONFIGURING, ETIMEDOUT_RECONFIGURED )
90
91 /** Maximum time to wait for backend to reach a given state, in ticks */
92 #define XENBUS_BACKEND_TIMEOUT ( 5 * TICKS_PER_SEC )
93
94 /**
95  * Set device state
96  *
97  * @v xendev            Xen device
98  * @v state             New state
99  * @ret rc              Return status code
100  */
101 int xenbus_set_state ( struct xen_device *xendev, int state ) {
102         int rc;
103
104         /* Attempt to set state */
105         if ( ( rc = xenstore_write_num ( xendev->xen, state, xendev->key,
106                                          "state", NULL ) ) != 0 ) {
107                 DBGC ( xendev, "XENBUS %s could not set state=\"%d\": %s\n",
108                        xendev->key, state, strerror ( rc ) );
109                 return rc;
110         }
111
112         return 0;
113 }
114
115 /**
116  * Get backend state
117  *
118  * @v xendev            Xen device
119  * @ret state           Backend state, or negative error
120  */
121 int xenbus_backend_state ( struct xen_device *xendev ) {
122         unsigned long state;
123         int rc;
124
125         /* Attempt to get backend state */
126         if ( ( rc = xenstore_read_num ( xendev->xen, &state, xendev->backend,
127                                         "state", NULL ) ) != 0 ) {
128                 DBGC ( xendev, "XENBUS %s could not read %s/state: %s\n",
129                        xendev->key, xendev->backend, strerror ( rc ) );
130                 return rc;
131         }
132
133         return state;
134 }
135
136 /**
137  * Wait for backend to reach a given state
138  *
139  * @v xendev            Xen device
140  * @v state             Desired backend state
141  * @ret rc              Return status code
142  */
143 int xenbus_backend_wait ( struct xen_device *xendev, int state ) {
144         unsigned long started = currticks();
145         unsigned long elapsed;
146         unsigned int attempts = 0;
147         int current_state;
148         int rc;
149
150         /* Wait for backend to reach this state */
151         do {
152
153                 /* Get current backend state */
154                 current_state = xenbus_backend_state ( xendev );
155                 if ( current_state < 0 ) {
156                         rc = current_state;
157                         return rc;
158                 }
159                 if ( current_state == state )
160                         return 0;
161
162                 /* Allow time for backend to react */
163                 cpu_nap();
164
165                 /* XenStore is a very slow interface; any fixed delay
166                  * time would be dwarfed by the XenStore access time.
167                  * We therefore use wall clock to time out this
168                  * operation.
169                  */
170                 elapsed = ( currticks() - started );
171                 attempts++;
172
173         } while ( elapsed < XENBUS_BACKEND_TIMEOUT );
174
175         /* Construct status code from current backend state */
176         rc = -ETIMEDOUT_STATE ( current_state );
177         DBGC ( xendev, "XENBUS %s timed out after %d attempts waiting for "
178                "%s/state=\"%d\": %s\n", xendev->key, attempts, xendev->backend,
179                state, strerror ( rc ) );
180
181         return rc;
182 }
183
184 /**
185  * Find driver for Xen device
186  *
187  * @v type              Device type
188  * @ret driver          Driver, or NULL
189  */
190 static struct xen_driver * xenbus_find_driver ( const char *type ) {
191         struct xen_driver *xendrv;
192
193         for_each_table_entry ( xendrv, XEN_DRIVERS ) {
194                 if ( strcmp ( xendrv->type, type ) == 0 )
195                         return xendrv;
196         }
197         return NULL;
198 }
199
200 /**
201  * Probe Xen device
202  *
203  * @v xen               Xen hypervisor
204  * @v parent            Parent device
205  * @v type              Device type
206  * @v instance          Device instance
207  * @ret rc              Return status code
208  */
209 static int xenbus_probe_device ( struct xen_hypervisor *xen,
210                                  struct device *parent, const char *type,
211                                  const char *instance ) {
212         struct xen_device *xendev;
213         size_t key_len;
214         int rc;
215
216         /* Allocate and initialise structure */
217         key_len = ( 7 /* "device/" */ + strlen ( type ) + 1 /* "/" */ +
218                     strlen ( instance ) + 1 /* NUL */ );
219         xendev = zalloc ( sizeof ( *xendev ) + key_len );
220         if ( ! xendev ) {
221                 rc = -ENOMEM;
222                 goto err_alloc;
223         }
224         snprintf ( xendev->dev.name, sizeof ( xendev->dev.name ), "%s/%s",
225                    type, instance );
226         xendev->dev.desc.bus_type = BUS_TYPE_XEN;
227         INIT_LIST_HEAD ( &xendev->dev.children );
228         list_add_tail ( &xendev->dev.siblings, &parent->children );
229         xendev->dev.parent = parent;
230         xendev->xen = xen;
231         xendev->key = ( ( void * ) ( xendev + 1 ) );
232         snprintf ( xendev->key, key_len, "device/%s/%s", type, instance );
233
234         /* Read backend key */
235         if ( ( rc = xenstore_read ( xen, &xendev->backend, xendev->key,
236                                     "backend", NULL ) ) != 0 ) {
237                 DBGC ( xendev, "XENBUS %s could not read backend: %s\n",
238                        xendev->key, strerror ( rc ) );
239                 goto err_read_backend;
240         }
241
242         /* Read backend domain ID */
243         if ( ( rc = xenstore_read_num ( xen, &xendev->backend_id, xendev->key,
244                                         "backend-id", NULL ) ) != 0 ) {
245                 DBGC ( xendev, "XENBUS %s could not read backend-id: %s\n",
246                        xendev->key, strerror ( rc ) );
247                 goto err_read_backend_id;
248         }
249         DBGC ( xendev, "XENBUS %s backend=\"%s\" in domain %ld\n",
250                xendev->key, xendev->backend, xendev->backend_id );
251
252         /* Look for a driver */
253         xendev->driver = xenbus_find_driver ( type );
254         if ( ! xendev->driver ) {
255                 DBGC ( xendev, "XENBUS %s has no driver\n", xendev->key );
256                 /* Not a fatal error */
257                 rc = 0;
258                 goto err_no_driver;
259         }
260         xendev->dev.driver_name = xendev->driver->name;
261         DBGC ( xendev, "XENBUS %s has driver \"%s\"\n", xendev->key,
262                xendev->driver->name );
263
264         /* Probe driver */
265         if ( ( rc = xendev->driver->probe ( xendev ) ) != 0 ) {
266                 DBGC ( xendev, "XENBUS could not probe %s: %s\n",
267                        xendev->key, strerror ( rc ) );
268                 goto err_probe;
269         }
270
271         return 0;
272
273         xendev->driver->remove ( xendev );
274  err_probe:
275  err_no_driver:
276  err_read_backend_id:
277         free ( xendev->backend );
278  err_read_backend:
279         list_del ( &xendev->dev.siblings );
280         free ( xendev );
281  err_alloc:
282         return rc;
283 }
284
285 /**
286  * Remove Xen device
287  *
288  * @v xendev            Xen device
289  */
290 static void xenbus_remove_device ( struct xen_device *xendev ) {
291
292         /* Remove device */
293         xendev->driver->remove ( xendev );
294         free ( xendev->backend );
295         list_del ( &xendev->dev.siblings );
296         free ( xendev );
297 }
298
299 /**
300  * Probe Xen devices of a given type
301  *
302  * @v xen               Xen hypervisor
303  * @v parent            Parent device
304  * @v type              Device type
305  * @ret rc              Return status code
306  */
307 static int xenbus_probe_type ( struct xen_hypervisor *xen,
308                                struct device *parent, const char *type ) {
309         char *children;
310         char *child;
311         size_t len;
312         int rc;
313
314         /* Get children of this key */
315         if ( ( rc = xenstore_directory ( xen, &children, &len, "device",
316                                          type, NULL ) ) != 0 ) {
317                 DBGC ( xen, "XENBUS could not list \"%s\" devices: %s\n",
318                        type, strerror ( rc ) );
319                 goto err_directory;
320         }
321
322         /* Probe each child */
323         for ( child = children ; child < ( children + len ) ;
324               child += ( strlen ( child ) + 1 /* NUL */ ) ) {
325                 if ( ( rc = xenbus_probe_device ( xen, parent, type,
326                                                   child ) ) != 0 )
327                         goto err_probe_device;
328         }
329
330         free ( children );
331         return 0;
332
333  err_probe_device:
334         free ( children );
335  err_directory:
336         return rc;
337 }
338
339 /**
340  * Probe Xen bus
341  *
342  * @v xen               Xen hypervisor
343  * @v parent            Parent device
344  * @ret rc              Return status code
345  */
346 int xenbus_probe ( struct xen_hypervisor *xen, struct device *parent ) {
347         char *types;
348         char *type;
349         size_t len;
350         int rc;
351
352         /* Get children of "device" key */
353         if ( ( rc = xenstore_directory ( xen, &types, &len, "device",
354                                          NULL ) ) != 0 ) {
355                 DBGC ( xen, "XENBUS could not list device types: %s\n",
356                        strerror ( rc ) );
357                 goto err_directory;
358         }
359
360         /* Probe each child type */
361         for ( type = types ; type < ( types + len ) ;
362               type += ( strlen ( type ) + 1 /* NUL */ ) ) {
363                 if ( ( rc = xenbus_probe_type ( xen, parent, type ) ) != 0 )
364                         goto err_probe_type;
365         }
366
367         free ( types );
368         return 0;
369
370         xenbus_remove ( xen, parent );
371  err_probe_type:
372         free ( types );
373  err_directory:
374         return rc;
375 }
376
377 /**
378  * Remove Xen bus
379  *
380  * @v xen               Xen hypervisor
381  * @v parent            Parent device
382  */
383 void xenbus_remove ( struct xen_hypervisor *xen __unused,
384                      struct device *parent ) {
385         struct xen_device *xendev;
386         struct xen_device *tmp;
387
388         /* Remove devices */
389         list_for_each_entry_safe ( xendev, tmp, &parent->children,
390                                    dev.siblings ) {
391                 xenbus_remove_device ( xendev );
392         }
393 }