/*
* libvirt-gconfig-domain-controller-usb.c: libvirt domain USB controller configuration
*
* Copyright (C) 2012 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Author: Christophe Fergeau <cfergeau@redhat.com>
*/
#include <config.h>
#include "libvirt-gconfig/libvirt-gconfig.h"
#include "libvirt-gconfig/libvirt-gconfig-private.h"
/**
* SECTION:libvirt-gconfig-domain-controller-usb
* @title: USB Controller Configuration
* @short_description: configuration of USB controllers
*
* A #GVirConfigDomainControllerUsb represents an USB controller device.
* A #GVirConfigDomain with #GVirConfigDomainControllerUsb devices will
* be able to use USB devices.
*
* Several USB controllers can be added to the same domain, for example
* to have an USB1 and an USB2 controller.
*
* When using SPICE (see #GVirConfigGraphicsSpice), USB devices plugged
* on the client can be forwarded to the guest through the use of
* #GVirConfigDomainRedirDev.
*
* <example>
* <title>Adding USB controllers to a standard x86 domain</title>
* <para>
* This example shows the recommended USB setup to get a virtual machine
* looking like your usual x86 desktop or laptop.
* </para>
* <programlisting>
* static GVirConfigDomainControllerUsb *
* create_usb_controller(GVirConfigDomainControllerUsbModel model, guint index,
* GVirConfigDomainControllerUsb *master, guint start_port)
* {
* GVirConfigDomainControllerUsb *controller;
*
* controller = gvir_config_domain_controller_usb_new();
* gvir_config_domain_controller_usb_set_model(controller, model);
* gvir_config_domain_controller_set_index(GVIR_CONFIG_DOMAIN_CONTROLLER(controller), index);
* if (master)
* gvir_config_domain_controller_usb_set_master(controller, master, start_port);
*
* return controller;
* }
*
* void setup_default_usb_controllers(GVirConfigDomain *domain)
* {
* GVirConfigDomainControllerUsb *ehci;
* GVirConfigDomainControllerUsb *uhci1;
* GVirConfigDomainControllerUsb *uhci2;
* GVirConfigDomainControllerUsb *uhci3;
*
* ehci = create_usb_controller(GVIR_CONFIG_DOMAIN_CONTROLLER_USB_MODEL_ICH9_EHCI1,
* 0, NULL, 0);
* gvir_config_domain_add_device(domain, GVIR_CONFIG_DOMAIN_DEVICE(ehci));
* uhci1 = create_usb_controller(GVIR_CONFIG_DOMAIN_CONTROLLER_USB_MODEL_ICH9_UHCI1,
* 0, ehci, 0);
* gvir_config_domain_add_device(domain, GVIR_CONFIG_DOMAIN_DEVICE(uhci1));
* g_object_unref(G_OBJECT(uhci1));
* uhci2 = create_usb_controller(GVIR_CONFIG_DOMAIN_CONTROLLER_USB_MODEL_ICH9_UHCI2,
* 0, ehci, 2);
* gvir_config_domain_add_device(domain, GVIR_CONFIG_DOMAIN_DEVICE(uhci2));
* g_object_unref(G_OBJECT(uhci2));
* uhci3 = create_usb_controller(GVIR_CONFIG_DOMAIN_CONTROLLER_USB_MODEL_ICH9_UHCI3,
* 0, ehci, 4);
* gvir_config_domain_add_device(domain, GVIR_CONFIG_DOMAIN_DEVICE(uhci3));
* g_object_unref(G_OBJECT(uhci3));
* g_object_unref(G_OBJECT(ehci));
*}
* </programlisting>
* </example>
*
* This class models libvirt XML nodes located at
* <ulink url="http://libvirt.org/formatdomain.html#elementsControllers">
* /domain/devices/controller[@type="usb"]</ulink>
*/
/**
* GVirConfigDomainControllerUsb:
*
* The #GVirConfigDomainControllerUsb struct is an opaque data structure
* which is used to configure USB controllers on a domain. It should only
* be accessed via the following functions.
*/
#define GVIR_CONFIG_DOMAIN_CONTROLLER_USB_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_CONFIG_TYPE_DOMAIN_CONTROLLER_USB, GVirConfigDomainControllerUsbPrivate))
struct _GVirConfigDomainControllerUsbPrivate
{
gboolean unused;
};
G_DEFINE_TYPE(GVirConfigDomainControllerUsb, gvir_config_domain_controller_usb, GVIR_CONFIG_TYPE_DOMAIN_CONTROLLER);
static void gvir_config_domain_controller_usb_class_init(GVirConfigDomainControllerUsbClass *klass)
{
g_type_class_add_private(klass, sizeof(GVirConfigDomainControllerUsbPrivate));
}
static void gvir_config_domain_controller_usb_init(GVirConfigDomainControllerUsb *controller_usb)
{
controller_usb->priv = GVIR_CONFIG_DOMAIN_CONTROLLER_USB_GET_PRIVATE(controller_usb);
}
/**
* gvir_config_domain_controller_usb_new:
*
* Creates a new #GVirConfigDomainControllerUsb with a reference count of 1.
* gvir_config_domain_controller_set_index() must be called before
* this controller is usable.
*
* Returns: a new #GVirConfigDomainControllerUsb
*/
GVirConfigDomainControllerUsb *gvir_config_domain_controller_usb_new(void)
{
GVirConfigObject *object;
object = gvir_config_object_new(GVIR_CONFIG_TYPE_DOMAIN_CONTROLLER_USB,
"controller", NULL);
gvir_config_object_set_attribute(object, "type", "usb", NULL);
return GVIR_CONFIG_DOMAIN_CONTROLLER_USB(object);
}
/**
* gvir_config_domain_controller_usb_new_from_xml:
* @xml: xml data to create the controller from
* @error: return location for a #GError, or NULL
*
* Creates a new #GVirConfigDomainControllerUsb with a reference count of 1.
* The controller object will be created using the XML description stored
* in @xml. This is a fragment of libvirt domain XML whose root node is
* <controller>.
*
* Returns: a new #GVirConfigDomainControllerUsb, or NULL if @xml failed to
* be parsed.
*/
GVirConfigDomainControllerUsb *gvir_config_domain_controller_usb_new_from_xml(const gchar *xml,
GError **error)
{
GVirConfigObject *object;
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_CONTROLLER_USB,
"controller", NULL, xml, error);
if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "usb") != 0) {
g_object_unref(G_OBJECT(object));
g_return_val_if_reached(NULL);
}
return GVIR_CONFIG_DOMAIN_CONTROLLER_USB(object);
}
/**
* gvir_config_domain_controller_usb_set_model:
* @controller: a #GVirConfigDomainControllerUsb
* @model: the USB controller model
*
* Sets the model of @controller to @model.
*/
void gvir_config_domain_controller_usb_set_model(GVirConfigDomainControllerUsb *controller,
GVirConfigDomainControllerUsbModel model)
{
g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_CONTROLLER_USB(controller));
gvir_config_object_set_attribute_with_type(GVIR_CONFIG_OBJECT(controller),
"model",
GVIR_CONFIG_TYPE_DOMAIN_CONTROLLER_USB_MODEL,
model,
NULL);
}
/**
* gvir_config_domain_controller_usb_set_master:
* @controller: a #GVirConfigDomainControllerUsb
* @master: the master #GVirConfigDomainControllerUsb
* @startport: the start port number
*
* Sets @controller to be a companion controller of @master. @controller
* will be exposed from port @startport on @master in the guest.
* After this call, @controller's index will be set to @master's index.
*/
void gvir_config_domain_controller_usb_set_master(GVirConfigDomainControllerUsb *controller,
GVirConfigDomainControllerUsb *master,
guint startport)
{
guint index;
char *startport_str;
g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_CONTROLLER_USB(controller));
g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_CONTROLLER_USB(master));
index = gvir_config_domain_controller_get_index(GVIR_CONFIG_DOMAIN_CONTROLLER(master));
gvir_config_domain_controller_set_index(GVIR_CONFIG_DOMAIN_CONTROLLER(controller), index);
startport_str = g_strdup_printf("%d", startport);
gvir_config_object_replace_child_with_attribute(GVIR_CONFIG_OBJECT(controller),
"master",
"startport",
startport_str);
g_free(startport_str);
}