xref: /qemu/hw/core/qdev-fw.c (revision 95a9457fd44ad97c518858a4e1586a5498f9773c)
1bfdec7f8SLaurent Vivier /*
2bfdec7f8SLaurent Vivier  *  qdev fw helpers
3bfdec7f8SLaurent Vivier  *
4bfdec7f8SLaurent Vivier  *  This program is free software; you can redistribute it and/or modify
5bfdec7f8SLaurent Vivier  *  it under the terms of the GNU General Public License as published by
6bfdec7f8SLaurent Vivier  *  the Free Software Foundation; either version 2 of the License,
7bfdec7f8SLaurent Vivier  *  or (at your option) any later version.
8bfdec7f8SLaurent Vivier  *
9bfdec7f8SLaurent Vivier  *  This program is distributed in the hope that it will be useful,
10bfdec7f8SLaurent Vivier  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11bfdec7f8SLaurent Vivier  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12bfdec7f8SLaurent Vivier  *  GNU General Public License for more details.
13bfdec7f8SLaurent Vivier  *
14bfdec7f8SLaurent Vivier  *  You should have received a copy of the GNU General Public License
15bfdec7f8SLaurent Vivier  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
16bfdec7f8SLaurent Vivier  */
17bfdec7f8SLaurent Vivier 
18bfdec7f8SLaurent Vivier #include "qemu/osdep.h"
19bfdec7f8SLaurent Vivier #include "hw/fw-path-provider.h"
20*a27bd6c7SMarkus Armbruster #include "hw/qdev-core.h"
21bfdec7f8SLaurent Vivier 
qdev_fw_name(DeviceState * dev)22bfdec7f8SLaurent Vivier const char *qdev_fw_name(DeviceState *dev)
23bfdec7f8SLaurent Vivier {
24bfdec7f8SLaurent Vivier     DeviceClass *dc = DEVICE_GET_CLASS(dev);
25bfdec7f8SLaurent Vivier 
26bfdec7f8SLaurent Vivier     if (dc->fw_name) {
27bfdec7f8SLaurent Vivier         return dc->fw_name;
28bfdec7f8SLaurent Vivier     }
29bfdec7f8SLaurent Vivier 
30bfdec7f8SLaurent Vivier     return object_get_typename(OBJECT(dev));
31bfdec7f8SLaurent Vivier }
32bfdec7f8SLaurent Vivier 
bus_get_fw_dev_path(BusState * bus,DeviceState * dev)33bfdec7f8SLaurent Vivier static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
34bfdec7f8SLaurent Vivier {
35bfdec7f8SLaurent Vivier     BusClass *bc = BUS_GET_CLASS(bus);
36bfdec7f8SLaurent Vivier 
37bfdec7f8SLaurent Vivier     if (bc->get_fw_dev_path) {
38bfdec7f8SLaurent Vivier         return bc->get_fw_dev_path(dev);
39bfdec7f8SLaurent Vivier     }
40bfdec7f8SLaurent Vivier 
41bfdec7f8SLaurent Vivier     return NULL;
42bfdec7f8SLaurent Vivier }
43bfdec7f8SLaurent Vivier 
qdev_get_fw_dev_path_from_handler(BusState * bus,DeviceState * dev)44bfdec7f8SLaurent Vivier static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
45bfdec7f8SLaurent Vivier {
46bfdec7f8SLaurent Vivier     Object *obj = OBJECT(dev);
47bfdec7f8SLaurent Vivier     char *d = NULL;
48bfdec7f8SLaurent Vivier 
49bfdec7f8SLaurent Vivier     while (!d && obj->parent) {
50bfdec7f8SLaurent Vivier         obj = obj->parent;
51bfdec7f8SLaurent Vivier         d = fw_path_provider_try_get_dev_path(obj, bus, dev);
52bfdec7f8SLaurent Vivier     }
53bfdec7f8SLaurent Vivier     return d;
54bfdec7f8SLaurent Vivier }
55bfdec7f8SLaurent Vivier 
qdev_get_own_fw_dev_path_from_handler(BusState * bus,DeviceState * dev)56bfdec7f8SLaurent Vivier char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
57bfdec7f8SLaurent Vivier {
58bfdec7f8SLaurent Vivier     Object *obj = OBJECT(dev);
59bfdec7f8SLaurent Vivier 
60bfdec7f8SLaurent Vivier     return fw_path_provider_try_get_dev_path(obj, bus, dev);
61bfdec7f8SLaurent Vivier }
62bfdec7f8SLaurent Vivier 
qdev_get_fw_dev_path_helper(DeviceState * dev,char * p,int size)63bfdec7f8SLaurent Vivier static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
64bfdec7f8SLaurent Vivier {
65bfdec7f8SLaurent Vivier     int l = 0;
66bfdec7f8SLaurent Vivier 
67bfdec7f8SLaurent Vivier     if (dev && dev->parent_bus) {
68bfdec7f8SLaurent Vivier         char *d;
69bfdec7f8SLaurent Vivier         l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
70bfdec7f8SLaurent Vivier         d = qdev_get_fw_dev_path_from_handler(dev->parent_bus, dev);
71bfdec7f8SLaurent Vivier         if (!d) {
72bfdec7f8SLaurent Vivier             d = bus_get_fw_dev_path(dev->parent_bus, dev);
73bfdec7f8SLaurent Vivier         }
74bfdec7f8SLaurent Vivier         if (d) {
75bfdec7f8SLaurent Vivier             l += snprintf(p + l, size - l, "%s", d);
76bfdec7f8SLaurent Vivier             g_free(d);
77bfdec7f8SLaurent Vivier         } else {
78bfdec7f8SLaurent Vivier             return l;
79bfdec7f8SLaurent Vivier         }
80bfdec7f8SLaurent Vivier     }
81bfdec7f8SLaurent Vivier     l += snprintf(p + l , size - l, "/");
82bfdec7f8SLaurent Vivier 
83bfdec7f8SLaurent Vivier     return l;
84bfdec7f8SLaurent Vivier }
85bfdec7f8SLaurent Vivier 
qdev_get_fw_dev_path(DeviceState * dev)86bfdec7f8SLaurent Vivier char *qdev_get_fw_dev_path(DeviceState *dev)
87bfdec7f8SLaurent Vivier {
88bfdec7f8SLaurent Vivier     char path[128];
89bfdec7f8SLaurent Vivier     int l;
90bfdec7f8SLaurent Vivier 
91bfdec7f8SLaurent Vivier     l = qdev_get_fw_dev_path_helper(dev, path, 128);
92bfdec7f8SLaurent Vivier 
93bfdec7f8SLaurent Vivier     path[l - 1] = '\0';
94bfdec7f8SLaurent Vivier 
95bfdec7f8SLaurent Vivier     return g_strdup(path);
96bfdec7f8SLaurent Vivier }
97