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