[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