1#
2# Copyright 2009, 2013 Red Hat, Inc.
3#
4# This work is licensed under the GNU GPLv2 or later.
5# See the COPYING file in the top-level directory.
6
7from .device import Device
8from ..nodedev import NodeDevice
9from ..xmlbuilder import XMLProperty
10
11
12class DeviceHostdev(Device):
13    XML_NAME = "hostdev"
14
15    def set_from_nodedev(self, nodedev):
16        if nodedev.device_type == NodeDevice.CAPABILITY_TYPE_PCI:
17            self.type = "pci"
18            self.domain = nodedev.domain
19            self.bus = nodedev.bus
20            self.slot = nodedev.slot
21            self.function = nodedev.function
22
23        elif nodedev.device_type == NodeDevice.CAPABILITY_TYPE_USBDEV:
24            self.type = "usb"
25            self.vendor = nodedev.vendor_id
26            self.product = nodedev.product_id
27
28            count = 0
29            for dev in self.conn.fetch_all_nodedevs():
30                if (dev.device_type == NodeDevice.CAPABILITY_TYPE_USBDEV and
31                    dev.vendor_id == self.vendor and
32                    dev.product_id == self.product):
33                    count += 1
34
35            if count > 1:
36                self.bus = nodedev.bus
37                self.device = nodedev.device
38
39        elif nodedev.device_type == nodedev.CAPABILITY_TYPE_NET:
40            founddev = None
41            for checkdev in self.conn.fetch_all_nodedevs():
42                if checkdev.name == nodedev.parent:
43                    founddev = checkdev
44                    break
45
46            self.set_from_nodedev(founddev)
47
48        elif nodedev.device_type == nodedev.CAPABILITY_TYPE_SCSIDEV:
49            self.type = "scsi"
50            self.scsi_adapter = "scsi_host%s" % nodedev.host
51            self.scsi_bus = nodedev.bus
52            self.scsi_target = nodedev.target
53            self.scsi_unit = nodedev.lun
54            self.managed = False
55
56        else:
57            raise ValueError(_("Unknown node device type %s") % nodedev)
58
59
60    _XML_PROP_ORDER = ["mode", "type", "managed", "vendor", "product",
61                       "domain", "bus", "slot", "function"]
62
63    mode = XMLProperty("./@mode")
64    type = XMLProperty("./@type")
65    managed = XMLProperty("./@managed", is_yesno=True)
66
67    vendor = XMLProperty("./source/vendor/@id")
68    product = XMLProperty("./source/product/@id")
69
70    device = XMLProperty("./source/address/@device")
71    bus = XMLProperty("./source/address/@bus")
72
73    domain = XMLProperty("./source/address/@domain")
74    function = XMLProperty("./source/address/@function")
75    slot = XMLProperty("./source/address/@slot")
76
77    driver_name = XMLProperty("./driver/@name")
78    rom_bar = XMLProperty("./rom/@bar", is_onoff=True)
79
80    # type=scsi handling
81    scsi_adapter = XMLProperty("./source/adapter/@name")
82    scsi_bus = XMLProperty("./source/address/@bus", is_int=True)
83    scsi_target = XMLProperty("./source/address/@target", is_int=True)
84    scsi_unit = XMLProperty("./source/address/@unit", is_int=True)
85
86    # type=net handling
87    net_interface = XMLProperty("./source/interface")
88
89    # type=misc handling
90    misc_char = XMLProperty("./source/char")
91
92    # type=misc handling
93    storage_block = XMLProperty("./source/block")
94
95
96    ##################
97    # Default config #
98    ##################
99
100    def set_defaults(self, guest):
101        if self.managed is None:
102            self.managed = self.conn.is_xen() and "no" or "yes"
103        if not self.mode:
104            self.mode = "subsystem"
105