mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 11:35:19 +00:00
conf: Introduce @guestReset to hostdev's <source/>
Some USB devices have a buggy firmware that either crashes on device reset, or make the device unusable in some other way. Fortunately, QEMU offers a way to skip device reset either completely, or if device is not initialized yet. Expose this ability to users under: <hostdev mode='subsystem' type='usb'> <source guestReset='off'/> </hostdev> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
dcfbfffd6a
commit
85ea114016
@ -4051,7 +4051,7 @@ for PCI (KVM only) and 1.0.6 for SCSI (KVM only)` :
|
|||||||
...
|
...
|
||||||
<devices>
|
<devices>
|
||||||
<hostdev mode='subsystem' type='usb'>
|
<hostdev mode='subsystem' type='usb'>
|
||||||
<source startupPolicy='optional'>
|
<source startupPolicy='optional' guestReset='off'>
|
||||||
<vendor id='0x1234'/>
|
<vendor id='0x1234'/>
|
||||||
<product id='0xbeef'/>
|
<product id='0xbeef'/>
|
||||||
</source>
|
</source>
|
||||||
@ -4231,6 +4231,19 @@ or:
|
|||||||
optional drop if missing at any start attempt
|
optional drop if missing at any start attempt
|
||||||
========= =====================================================================
|
========= =====================================================================
|
||||||
|
|
||||||
|
:since:`Since 8.6.0`, the ``source`` element can contain ``guestReset``
|
||||||
|
attribute with the following value:
|
||||||
|
|
||||||
|
============= =====================================================
|
||||||
|
off all guest initiated device reset requests are ignored
|
||||||
|
uninitialized device request is ignored if device is initialized,
|
||||||
|
otherwise reset is performed
|
||||||
|
on device is reset on every guest initiated request
|
||||||
|
============= =====================================================
|
||||||
|
|
||||||
|
This attribute can be helpful when assigning an USB device with a
|
||||||
|
firmware that crashes on reset.
|
||||||
|
|
||||||
``pci``
|
``pci``
|
||||||
PCI devices can only be described by their ``address``.
|
PCI devices can only be described by their ``address``.
|
||||||
:since:`Since 6.8.0 (Xen only)` , the ``source`` element of a PCI device
|
:since:`Since 6.8.0 (Xen only)` , the ``source`` element of a PCI device
|
||||||
|
@ -1042,6 +1042,14 @@ VIR_ENUM_IMPL(virDomainHostdevSubsysSCSIProtocol,
|
|||||||
"iscsi",
|
"iscsi",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virDomainHostdevSubsysUSBGuestReset,
|
||||||
|
VIR_DOMAIN_HOSTDEV_USB_GUEST_RESET_LAST,
|
||||||
|
"default",
|
||||||
|
"off",
|
||||||
|
"uninitialized",
|
||||||
|
"on",
|
||||||
|
);
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainHostdevSubsysSCSIHostProtocol,
|
VIR_ENUM_IMPL(virDomainHostdevSubsysSCSIHostProtocol,
|
||||||
VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_LAST,
|
VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_LAST,
|
||||||
"none",
|
"none",
|
||||||
@ -5489,6 +5497,11 @@ virDomainHostdevSubsysUSBDefParseXML(xmlNodePtr node,
|
|||||||
return -1;
|
return -1;
|
||||||
virTristateBoolToBool(autoAddress, &usbsrc->autoAddress);
|
virTristateBoolToBool(autoAddress, &usbsrc->autoAddress);
|
||||||
|
|
||||||
|
if (virXMLPropEnum(node, "guestReset",
|
||||||
|
virDomainHostdevSubsysUSBGuestResetTypeFromString,
|
||||||
|
VIR_XML_PROP_NONZERO, &usbsrc->guestReset) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* Product can validly be 0, so we need some extra help to determine
|
/* Product can validly be 0, so we need some extra help to determine
|
||||||
* if it is uninitialized */
|
* if it is uninitialized */
|
||||||
vendorNode = virXPathNode("./vendor", ctxt);
|
vendorNode = virXPathNode("./vendor", ctxt);
|
||||||
@ -22989,6 +23002,11 @@ virDomainHostdevDefFormatSubsysUSB(virBuffer *buf,
|
|||||||
if (def->missing && !(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE))
|
if (def->missing && !(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE))
|
||||||
virBufferAddLit(&sourceAttrBuf, " missing='yes'");
|
virBufferAddLit(&sourceAttrBuf, " missing='yes'");
|
||||||
|
|
||||||
|
if (usbsrc->guestReset) {
|
||||||
|
virBufferAsprintf(&sourceAttrBuf, " guestReset='%s'",
|
||||||
|
virDomainHostdevSubsysUSBGuestResetTypeToString(usbsrc->guestReset));
|
||||||
|
}
|
||||||
|
|
||||||
if (usbsrc->vendor) {
|
if (usbsrc->vendor) {
|
||||||
virBufferAsprintf(&sourceChildBuf, "<vendor id='0x%.4x'/>\n", usbsrc->vendor);
|
virBufferAsprintf(&sourceChildBuf, "<vendor id='0x%.4x'/>\n", usbsrc->vendor);
|
||||||
virBufferAsprintf(&sourceChildBuf, "<product id='0x%.4x'/>\n", usbsrc->product);
|
virBufferAsprintf(&sourceChildBuf, "<product id='0x%.4x'/>\n", usbsrc->product);
|
||||||
|
@ -233,6 +233,17 @@ typedef enum {
|
|||||||
|
|
||||||
VIR_ENUM_DECL(virDomainHostdevSubsysSCSIProtocol);
|
VIR_ENUM_DECL(virDomainHostdevSubsysSCSIProtocol);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIR_DOMAIN_HOSTDEV_USB_GUEST_RESET_DEFAULT = 0,
|
||||||
|
VIR_DOMAIN_HOSTDEV_USB_GUEST_RESET_OFF, /* reset forbidden */
|
||||||
|
VIR_DOMAIN_HOSTDEV_USB_GUEST_RESET_UNINITIALIZED, /* reset iff uninitialized */
|
||||||
|
VIR_DOMAIN_HOSTDEV_USB_GUEST_RESET_ON, /* reset allowed */
|
||||||
|
|
||||||
|
VIR_DOMAIN_HOSTDEV_USB_GUEST_RESET_LAST
|
||||||
|
} virDomainHostdevSubsysUSBGuestReset;
|
||||||
|
|
||||||
|
VIR_ENUM_DECL(virDomainHostdevSubsysUSBGuestReset);
|
||||||
|
|
||||||
struct _virDomainHostdevSubsysUSB {
|
struct _virDomainHostdevSubsysUSB {
|
||||||
bool autoAddress; /* bus/device were filled automatically based
|
bool autoAddress; /* bus/device were filled automatically based
|
||||||
on vendor/product */
|
on vendor/product */
|
||||||
@ -241,6 +252,8 @@ struct _virDomainHostdevSubsysUSB {
|
|||||||
|
|
||||||
unsigned vendor;
|
unsigned vendor;
|
||||||
unsigned product;
|
unsigned product;
|
||||||
|
|
||||||
|
virDomainHostdevSubsysUSBGuestReset guestReset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _virDomainHostdevSubsysPCI {
|
struct _virDomainHostdevSubsysPCI {
|
||||||
|
@ -5936,6 +5936,15 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<ref name="startupPolicy"/>
|
<ref name="startupPolicy"/>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="guestReset">
|
||||||
|
<choice>
|
||||||
|
<value>off</value>
|
||||||
|
<value>uninitialized</value>
|
||||||
|
<value>on</value>
|
||||||
|
</choice>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
<choice>
|
<choice>
|
||||||
<group>
|
<group>
|
||||||
<ref name="usbproduct"/>
|
<ref name="usbproduct"/>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<input type='mouse' bus='ps2'/>
|
<input type='mouse' bus='ps2'/>
|
||||||
<input type='keyboard' bus='ps2'/>
|
<input type='keyboard' bus='ps2'/>
|
||||||
<hostdev mode='subsystem' type='usb' managed='no'>
|
<hostdev mode='subsystem' type='usb' managed='no'>
|
||||||
<source>
|
<source guestReset='uninitialized'>
|
||||||
<address bus='14' device='6'/>
|
<address bus='14' device='6'/>
|
||||||
</source>
|
</source>
|
||||||
</hostdev>
|
</hostdev>
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
<input type='keyboard' bus='ps2'/>
|
<input type='keyboard' bus='ps2'/>
|
||||||
<audio id='1' type='none'/>
|
<audio id='1' type='none'/>
|
||||||
<hostdev mode='subsystem' type='usb' managed='no'>
|
<hostdev mode='subsystem' type='usb' managed='no'>
|
||||||
<source>
|
<source guestReset='uninitialized'>
|
||||||
<address bus='14' device='6'/>
|
<address bus='14' device='6'/>
|
||||||
</source>
|
</source>
|
||||||
</hostdev>
|
</hostdev>
|
||||||
|
Loading…
Reference in New Issue
Block a user