2013-03-18 01:06:52 +04:00
#
2013-10-28 00:59:46 +04:00
# Copyright 2009, 2013 Red Hat, Inc.
2013-03-18 01:06:52 +04:00
#
2018-04-04 16:35:41 +03:00
# This work is licensed under the GNU GPLv2 or later.
2018-03-20 22:00:02 +03:00
# See the COPYING file in the top-level directory.
2013-03-18 01:06:52 +04:00
2018-03-20 19:18:35 +03:00
from . device import Device
2018-03-20 19:27:37 +03:00
from . . nodedev import NodeDevice
from . . xmlbuilder import XMLProperty
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
2018-03-20 19:18:35 +03:00
class DeviceHostdev ( Device ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " hostdev "
2013-03-18 01:06:52 +04:00
2015-07-23 14:15:26 +03:00
def set_from_nodedev ( self , nodedev ) :
2013-03-18 01:06:52 +04:00
"""
2013-09-28 02:06:39 +04:00
@use_full_usb : If set , and nodedev is USB , specify both
vendor and product . Used if user requests bus / add on virt - install
command line , or if virt - manager detects a dup USB device
and we need to differentiate
2013-03-18 01:06:52 +04:00
"""
2013-09-23 02:13:24 +04:00
if nodedev . device_type == NodeDevice . CAPABILITY_TYPE_PCI :
2013-07-16 01:45:43 +04:00
self . type = " pci "
self . domain = nodedev . domain
2013-03-18 01:06:52 +04:00
self . bus = nodedev . bus
2013-07-16 01:45:43 +04:00
self . slot = nodedev . slot
self . function = nodedev . function
2013-03-18 01:06:52 +04:00
2013-09-23 02:13:24 +04:00
elif nodedev . device_type == NodeDevice . CAPABILITY_TYPE_USBDEV :
2013-07-16 01:45:43 +04:00
self . type = " usb "
self . vendor = nodedev . vendor_id
self . product = nodedev . product_id
2013-03-18 01:06:52 +04:00
2015-07-23 14:15:26 +03:00
count = 0
for dev in self . conn . fetch_all_nodedevs ( ) :
if ( dev . device_type == NodeDevice . CAPABILITY_TYPE_USBDEV and
dev . vendor_id == self . vendor and
dev . product_id == self . product ) :
count + = 1
if not count :
raise RuntimeError ( _ ( " Could not find USB device "
" (vendorId: %s , productId: %s ) " )
2015-08-05 14:53:19 +03:00
% ( self . vendor , self . product ) )
2015-07-23 14:15:26 +03:00
if count > 1 :
2013-07-16 01:45:43 +04:00
self . bus = nodedev . bus
self . device = nodedev . device
2013-09-28 02:06:39 +04:00
elif nodedev . device_type == nodedev . CAPABILITY_TYPE_NET :
2014-09-20 19:30:24 +04:00
founddev = None
for checkdev in self . conn . fetch_all_nodedevs ( ) :
if checkdev . name == nodedev . parent :
founddev = checkdev
break
2015-07-23 14:15:26 +03:00
self . set_from_nodedev ( founddev )
2013-09-28 02:06:39 +04:00
2015-04-11 22:52:42 +03:00
elif nodedev . device_type == nodedev . CAPABILITY_TYPE_SCSIDEV :
self . type = " scsi "
self . scsi_adapter = " scsi_host %s " % nodedev . host
self . scsi_bus = nodedev . bus
self . scsi_target = nodedev . target
self . scsi_unit = nodedev . lun
self . managed = False
2013-07-16 01:45:43 +04:00
else :
2016-02-05 18:18:16 +03:00
raise ValueError ( _ ( " Unknown node device type %s " ) % nodedev )
2013-03-18 01:06:52 +04:00
2014-09-20 22:56:57 +04:00
def pretty_name ( self ) :
def dehex ( val ) :
if val . startswith ( " 0x " ) :
val = val [ 2 : ]
return val
def safeint ( val , fmt = " %.3d " ) :
try :
int ( val )
2017-07-24 11:26:48 +03:00
except Exception :
2014-09-20 22:56:57 +04:00
return str ( val )
return fmt % int ( val )
label = self . type . upper ( )
if self . vendor and self . product :
label + = " %s : %s " % ( dehex ( self . vendor ) , dehex ( self . product ) )
elif self . bus and self . device :
label + = " %s : %s " % ( safeint ( self . bus ) , safeint ( self . device ) )
elif self . bus and self . slot and self . function and self . domain :
label + = ( " %s : %s : %s . %s " %
( dehex ( self . domain ) , dehex ( self . bus ) ,
dehex ( self . slot ) , dehex ( self . function ) ) )
return label
2013-03-18 01:06:52 +04:00
2013-07-16 01:45:43 +04:00
_XML_PROP_ORDER = [ " mode " , " type " , " managed " , " vendor " , " product " ,
" domain " , " bus " , " slot " , " function " ]
2013-03-18 01:06:52 +04:00
2018-09-02 03:44:14 +03:00
mode = XMLProperty ( " ./@mode " )
2013-09-19 21:27:30 +04:00
type = XMLProperty ( " ./@type " )
2018-09-02 03:44:14 +03:00
managed = XMLProperty ( " ./@managed " , is_yesno = True )
2013-03-18 01:06:52 +04:00
2013-09-19 21:27:30 +04:00
vendor = XMLProperty ( " ./source/vendor/@id " )
product = XMLProperty ( " ./source/product/@id " )
2013-03-18 01:06:52 +04:00
2013-09-19 21:27:30 +04:00
device = XMLProperty ( " ./source/address/@device " )
bus = XMLProperty ( " ./source/address/@bus " )
2013-03-18 01:06:52 +04:00
2018-09-02 03:44:14 +03:00
domain = XMLProperty ( " ./source/address/@domain " )
2013-09-19 21:27:30 +04:00
function = XMLProperty ( " ./source/address/@function " )
slot = XMLProperty ( " ./source/address/@slot " )
2013-07-24 16:46:55 +04:00
2014-01-15 03:09:21 +04:00
driver_name = XMLProperty ( " ./driver/@name " )
2014-02-10 23:24:22 +04:00
rom_bar = XMLProperty ( " ./rom/@bar " , is_onoff = True )
2014-01-15 03:09:21 +04:00
2015-04-11 22:52:42 +03:00
# type=scsi handling
scsi_adapter = XMLProperty ( " ./source/adapter/@name " )
scsi_bus = XMLProperty ( " ./source/address/@bus " , is_int = True )
scsi_target = XMLProperty ( " ./source/address/@target " , is_int = True )
scsi_unit = XMLProperty ( " ./source/address/@unit " , is_int = True )
2018-06-15 12:29:34 +03:00
# type=net handling
net_interface = XMLProperty ( " ./source/interface " )
2018-06-15 12:29:35 +03:00
# type=misc handling
misc_char = XMLProperty ( " ./source/char " )
2018-06-15 12:29:36 +03:00
# type=misc handling
storage_block = XMLProperty ( " ./source/block " )
2018-09-02 03:44:14 +03:00
##################
# Default config #
##################
def set_defaults ( self , guest ) :
if self . managed is None :
self . managed = self . conn . is_xen ( ) and " no " or " yes "
if not self . mode :
self . mode = " subsystem "
if self . type == " pci " and not self . domain :
self . domain = " 0x0 "