[pve-devel] [PATCH qemu-server 2/7] refactor usb functions out of QemuServer.pm

Dominik Csapak d.csapak at proxmox.com
Tue Jun 14 10:50:36 CEST 2016


this moves most of the usb functionality into its own
module, making the QemuServer.pm smaller

Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
 PVE/QemuServer/Makefile |   1 +
 PVE/QemuServer/USB.pm   | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 125 insertions(+)
 create mode 100644 PVE/QemuServer/USB.pm

diff --git a/PVE/QemuServer/Makefile b/PVE/QemuServer/Makefile
index f105d0a..06617c5 100644
--- a/PVE/QemuServer/Makefile
+++ b/PVE/QemuServer/Makefile
@@ -1,4 +1,5 @@
 .PHONY: install
 install:
 	install -D -m 0644 PCI.pm ${DESTDIR}${PERLDIR}/PVE/QemuServer/PCI.pm
+	install -D -m 0644 USB.pm ${DESTDIR}${PERLDIR}/PVE/QemuServer/USB.pm
 	install -D -m 0644 Memory.pm ${DESTDIR}${PERLDIR}/PVE/QemuServer/Memory.pm
diff --git a/PVE/QemuServer/USB.pm b/PVE/QemuServer/USB.pm
new file mode 100644
index 0000000..599641e
--- /dev/null
+++ b/PVE/QemuServer/USB.pm
@@ -0,0 +1,124 @@
+package PVE::QemuServer::USB;
+
+use strict;
+use warnings;
+use PVE::QemuServer::PCI qw(print_pci_addr);
+use PVE::JSONSchema;
+use base 'Exporter';
+
+our @EXPORT_OK = qw(
+parse_usb_device
+get_usb_controllers
+get_usb_devices
+);
+
+sub parse_usb_device {
+    my ($value) = @_;
+
+    return undef if !$value;
+
+    my $res = {};
+    if ($value =~ m/^(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})$/) {
+	$res->{vendorid} = $2;
+	$res->{productid} = $4;
+    } elsif ($value =~ m/^(\d+)\-(\d+(\.\d+)*)$/) {
+	$res->{hostbus} = $1;
+	$res->{hostport} = $2;
+    } elsif ($value =~ m/^spice$/i) {
+	$res->{spice} = 1;
+    } else {
+	return undef;
+    }
+
+    return $res;
+}
+
+sub get_usb_controllers {
+    my ($conf, $bridges, $isq35, $format, $max_usb_devices) = @_;
+
+    my $devices = [];
+    my $pciaddr = "";
+
+    if ($isq35) {
+	# the q35 chipset support native usb2, so we enable usb controller
+	# by default for this machine type
+        push @$devices, '-readconfig', '/usr/share/qemu-server/pve-q35.cfg';
+    } else {
+        $pciaddr = print_pci_addr("piix3", $bridges);
+        push @$devices, '-device', "piix3-usb-uhci,id=uhci$pciaddr.0x2";
+
+        my $use_usb2 = 0;
+	for (my $i = 0; $i < $max_usb_devices; $i++)  {
+	    next if !$conf->{"usb$i"};
+	    my $d = eval { PVE::JSONSchema::parse_property_string($format,$conf->{"usb$i"}) };
+	    next if !$d || $d->{usb3}; # do not add usb2 controller if we have only usb3 devices
+	    $use_usb2 = 1;
+	}
+	# include usb device config
+	push @$devices, '-readconfig', '/usr/share/qemu-server/pve-usb.cfg' if $use_usb2;
+    }
+
+    # add usb3 controller if needed
+
+    my $use_usb3 = 0;
+    for (my $i = 0; $i < $max_usb_devices; $i++)  {
+	next if !$conf->{"usb$i"};
+	my $d = eval { PVE::JSONSchema::parse_property_string($format,$conf->{"usb$i"}) };
+	next if !$d || !$d->{usb3};
+	$use_usb3 = 1;
+    }
+
+    $pciaddr = print_pci_addr("xhci", $bridges);
+    push @$devices, '-device', "nec-usb-xhci,id=xhci$pciaddr" if $use_usb3;
+
+    return @$devices;
+}
+
+sub get_usb_devices {
+    my ($conf, $format, $max_usb_devices) = @_;
+
+    my $devices = [];
+
+    for (my $i = 0; $i < $max_usb_devices; $i++)  {
+	next if !$conf->{"usb$i"};
+	my $d = eval { PVE::JSONSchema::parse_property_string($format,$conf->{"usb$i"}) };
+	next if !$d;
+
+	if (defined($d->{host})) {
+	    my $hostdevice = parse_usb_device($d->{host});
+	    $hostdevice->{usb3} = $d->{usb3};
+	    if (defined($hostdevice->{spice}) && $hostdevice->{spice}) {
+		# usb redir support for spice, currently no usb3
+		push @$devices, '-chardev', "spicevmc,id=usbredirchardev$i,name=usbredir";
+		push @$devices, '-device', "usb-redir,chardev=usbredirchardev$i,id=usbredirdev$i,bus=ehci.0";
+	    } else {
+		push @$devices, '-device', print_usbdevice_full($conf, "usb$i", $hostdevice);
+	    }
+	}
+    }
+
+    return @$devices;
+}
+
+sub print_usbdevice_full {
+    my ($conf, $deviceid, $device) = @_;
+
+    return if !$device;
+    my $usbdevice = "usb-host";
+
+    # if it is a usb3 device, attach it to the xhci controller, else omit the bus option
+    if($device->{usb3}) {
+	$usbdevice .= ",bus=xhci.0";
+    }
+
+    if (defined($device->{vendorid}) && defined($device->{productid})) {
+	$usbdevice .= ",vendorid=0x$device->{vendorid},productid=0x$device->{productid}";
+    } elsif (defined($device->{hostbus}) && defined($device->{hostport})) {
+	$usbdevice .= ",hostbus=$device->{hostbus},hostport=$device->{hostport}";
+    }
+
+    $usbdevice .= ",id=$deviceid";
+    return $usbdevice;
+}
+
+1;
-- 
2.1.4




More information about the pve-devel mailing list