1 /*
2  * libvirt-gconfig-domain-address-pci.c: libvirt pci device address configuration
3  *
4  * Copyright (C) 2012 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see
18  * <http://www.gnu.org/licenses/>.
19  *
20  * Author: Christophe Fergeau <cfergeau@redhat.com>
21  */
22 
23 #include <config.h>
24 
25 #include "libvirt-gconfig/libvirt-gconfig.h"
26 #include "libvirt-gconfig/libvirt-gconfig-private.h"
27 
28 #define GVIR_CONFIG_DOMAIN_ADDRESS_PCI_GET_PRIVATE(obj)                         \
29         (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_CONFIG_TYPE_DOMAIN_ADDRESS_PCI, GVirConfigDomainAddressPciPrivate))
30 
31 struct _GVirConfigDomainAddressPciPrivate
32 {
33     gboolean unused;
34 };
35 
36 G_DEFINE_TYPE_WITH_PRIVATE(GVirConfigDomainAddressPci, gvir_config_domain_address_pci, GVIR_CONFIG_TYPE_DOMAIN_ADDRESS);
37 
38 
gvir_config_domain_address_pci_class_init(GVirConfigDomainAddressPciClass * klass G_GNUC_UNUSED)39 static void gvir_config_domain_address_pci_class_init(GVirConfigDomainAddressPciClass *klass G_GNUC_UNUSED)
40 {
41 }
42 
43 
gvir_config_domain_address_pci_init(GVirConfigDomainAddressPci * address)44 static void gvir_config_domain_address_pci_init(GVirConfigDomainAddressPci *address)
45 {
46     address->priv = GVIR_CONFIG_DOMAIN_ADDRESS_PCI_GET_PRIVATE(address);
47 }
48 
49 
gvir_config_domain_address_pci_new(void)50 GVirConfigDomainAddressPci *gvir_config_domain_address_pci_new(void)
51 {
52     GVirConfigObject *object;
53 
54     object = gvir_config_object_new(GVIR_CONFIG_TYPE_DOMAIN_ADDRESS_PCI,
55                                     "address", NULL);
56     gvir_config_object_set_attribute(object, "type", "pci", NULL);
57     return GVIR_CONFIG_DOMAIN_ADDRESS_PCI(object);
58 }
59 
gvir_config_domain_address_pci_new_from_xml(const gchar * xml,GError ** error)60 GVirConfigDomainAddressPci *gvir_config_domain_address_pci_new_from_xml(const gchar *xml,
61                                                                         GError **error)
62 {
63     GVirConfigObject *object;
64 
65     object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_ADDRESS_PCI,
66                                              "address", NULL, xml, error);
67     if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "pci") != 0) {
68         g_object_unref(G_OBJECT(object));
69         g_return_val_if_reached(NULL);
70     }
71     return GVIR_CONFIG_DOMAIN_ADDRESS_PCI(object);
72 }
73 
set_attribute_hex(GVirConfigDomainAddressPci * address,const char * attr_name,guint attr_val,guint min_val,guint max_val,guint size)74 static void set_attribute_hex(GVirConfigDomainAddressPci *address,
75                               const char *attr_name,
76                               guint attr_val,
77                               guint min_val,
78                               guint max_val,
79                               guint size)
80 {
81     char *hex_str;
82     char *format;
83     g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_ADDRESS_PCI(address));
84     g_return_if_fail((attr_val >= min_val) && (attr_val <= max_val));
85 
86     format = g_strdup_printf("0x%%0%dx", size);
87     hex_str = g_strdup_printf(format, attr_val);
88     gvir_config_object_set_attribute(GVIR_CONFIG_OBJECT(address),
89                                      attr_name, hex_str, NULL);
90     g_free(hex_str);
91     g_free(format);
92 }
93 
gvir_config_domain_address_pci_get_domain(GVirConfigDomainAddressPci * address)94 int gvir_config_domain_address_pci_get_domain(GVirConfigDomainAddressPci *address)
95 {
96     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_ADDRESS_PCI(address), -1);
97 
98     return gvir_config_object_get_attribute_uint64(GVIR_CONFIG_OBJECT(address),
99                                                    NULL, "domain",
100                                                    -1);
101 }
102 
gvir_config_domain_address_pci_set_domain(GVirConfigDomainAddressPci * address,guint16 pci_domain)103 void gvir_config_domain_address_pci_set_domain(GVirConfigDomainAddressPci *address,
104                                                guint16 pci_domain)
105 {
106     set_attribute_hex(address, "domain", pci_domain, 0, G_MAXUINT16, 4);
107 }
108 
gvir_config_domain_address_pci_get_bus(GVirConfigDomainAddressPci * address)109 int gvir_config_domain_address_pci_get_bus(GVirConfigDomainAddressPci *address)
110 {
111     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_ADDRESS_PCI(address), -1);
112 
113     return gvir_config_object_get_attribute_uint64(GVIR_CONFIG_OBJECT(address),
114                                                    NULL, "bus",
115                                                    -1);
116 }
117 
gvir_config_domain_address_pci_set_bus(GVirConfigDomainAddressPci * address,guchar bus)118 void gvir_config_domain_address_pci_set_bus(GVirConfigDomainAddressPci *address,
119                                             guchar bus)
120 {
121     set_attribute_hex(address, "bus", bus, 0, G_MAXUINT8, 2);
122 }
123 
gvir_config_domain_address_pci_get_slot(GVirConfigDomainAddressPci * address)124 int gvir_config_domain_address_pci_get_slot(GVirConfigDomainAddressPci *address)
125 {
126     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_ADDRESS_PCI(address), -1);
127 
128     return gvir_config_object_get_attribute_uint64(GVIR_CONFIG_OBJECT(address),
129                                                    NULL, "slot",
130                                                    -1);
131 }
132 
gvir_config_domain_address_pci_set_slot(GVirConfigDomainAddressPci * address,guchar slot)133 void gvir_config_domain_address_pci_set_slot(GVirConfigDomainAddressPci *address,
134                                              guchar slot)
135 {
136     set_attribute_hex(address, "slot", slot, 0, 0x1f, 2);
137 }
138 
gvir_config_domain_address_pci_get_function(GVirConfigDomainAddressPci * address)139 int gvir_config_domain_address_pci_get_function(GVirConfigDomainAddressPci *address)
140 {
141     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_ADDRESS_PCI(address), -1);
142 
143     return gvir_config_object_get_attribute_uint64(GVIR_CONFIG_OBJECT(address),
144                                                    NULL, "function",
145                                                    -1);
146 }
147 
gvir_config_domain_address_pci_set_function(GVirConfigDomainAddressPci * address,guchar function)148 void gvir_config_domain_address_pci_set_function(GVirConfigDomainAddressPci *address,
149                                                  guchar function)
150 {
151     set_attribute_hex(address, "function", function, 0, 7, 1);
152 }
153 
gvir_config_domain_address_pci_get_multifunction(GVirConfigDomainAddressPci * address)154 gboolean gvir_config_domain_address_pci_get_multifunction(GVirConfigDomainAddressPci *address)
155 {
156     g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_ADDRESS_PCI(address), FALSE);
157 
158     return gvir_config_object_get_attribute_boolean(GVIR_CONFIG_OBJECT(address),
159                                                     NULL, "multifunction",
160                                                     FALSE);
161 }
162 
gvir_config_domain_address_pci_set_multifunction(GVirConfigDomainAddressPci * address,gboolean multifunction)163 void gvir_config_domain_address_pci_set_multifunction(GVirConfigDomainAddressPci *address,
164                                                       gboolean multifunction)
165 {
166     gvir_config_object_set_attribute(GVIR_CONFIG_OBJECT(address),
167                                      "multifunction",
168                                      multifunction?"on":"off", NULL);
169 }
170