summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java')
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java295
1 files changed, 295 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java
new file mode 100644
index 0000000..9281500
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java
@@ -0,0 +1,295 @@
+package org.openslx.libvirt.domain.device;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Representation of a slot address from a PCI device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class HostdevPciDeviceAddress
+{
+ /**
+ * Regular expression to parse a PCI device address from a {@link String}.
+ * <p>
+ * The regular expression matches a PCI device address if its textual PCI device address is
+ * well-formed according to the following examples:
+ *
+ * <pre>
+ * 0000:00:02.3
+ * 0000:01:00.0
+ * 0000:00:1f.3
+ * </pre>
+ */
+ private static final String DEVICE_ADDRESS_REGEX = "^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\\.([0-7]{1})$";
+
+ /**
+ * Minimum value for a valid PCI device address component number.
+ */
+ private static final int DEVICE_ADDRESS_MIN_VALUE = 0;
+
+ /**
+ * Maximum value for a valid PCI device domain number.
+ */
+ private static final int DEVICE_ADDRESS_DOMAIN_MAX_VALUE = 0xffff;
+
+ /**
+ * Maximum value for a valid PCI device bus number.
+ */
+ private static final int DEVICE_ADDRESS_BUS_MAX_VALUE = 0xff;
+
+ /**
+ * Maximum value for a valid PCI device device number.
+ */
+ private static final int DEVICE_ADDRESS_DEVICE_MAX_VALUE = 0x1f;
+
+ /**
+ * Maximum value for a valid PCI device function number.
+ */
+ private static final int DEVICE_ADDRESS_FUNCTION_MAX_VALUE = 0x7;
+
+ /**
+ * Domain number of the PCI device address.
+ */
+ final int pciDomain;
+
+ /**
+ * Bus number of the PCI device address.
+ */
+ final int pciBus;
+
+ /**
+ * Device number of the PCI device address.
+ */
+ final int pciDevice;
+
+ /**
+ * Function number of the PCI device address.
+ */
+ final int pciFunction;
+
+ /**
+ * Creates a new PCI device address and sets the address information to the default
+ * address {@code 0000:00:00.0}.
+ */
+ public HostdevPciDeviceAddress()
+ {
+ this( 0, 0, 0, 0 );
+ }
+
+ /**
+ * Creates a new PCI device address consisting of a specified PCI bus, device, and function.
+ * <p>
+ * The domain of the PCI device address is set to the default number {@code 0000}.
+ *
+ * @param pciBus number of the PCI bus.
+ * @param pciDevice number of the PCI device.
+ * @param pciFunction number of the PCI function.
+ *
+ * @throws IllegalArgumentException failed to validate the PCI bus, device and function.
+ */
+ public HostdevPciDeviceAddress( int pciBus, int pciDevice, int pciFunction ) throws IllegalArgumentException
+ {
+ this( 0, pciBus, pciDevice, pciFunction );
+ }
+
+ /**
+ * Creates a new PCI device address consisting of a specified PCI domain, bus, device, and
+ * function.
+ *
+ * @param pciDomain number of the PCI domain.
+ * @param pciBus number of the PCI bus.
+ * @param pciDevice number of the PCI device.
+ * @param pciFunction number of the PCI function.
+ *
+ * @throws IllegalArgumentException failed to validate the PCI domain, bus, device and function.
+ */
+ public HostdevPciDeviceAddress( int pciDomain, int pciBus, int pciDevice, int pciFunction )
+ throws IllegalArgumentException
+ {
+ HostdevPciDeviceAddress.validatePciDeviceAddress( pciDomain, "PCI domain",
+ HostdevPciDeviceAddress.DEVICE_ADDRESS_DOMAIN_MAX_VALUE );
+ HostdevPciDeviceAddress.validatePciDeviceAddress( pciBus, "PCI bus",
+ HostdevPciDeviceAddress.DEVICE_ADDRESS_BUS_MAX_VALUE );
+ HostdevPciDeviceAddress.validatePciDeviceAddress( pciDevice, "PCI device",
+ HostdevPciDeviceAddress.DEVICE_ADDRESS_DEVICE_MAX_VALUE );
+ HostdevPciDeviceAddress.validatePciDeviceAddress( pciFunction, "PCI function",
+ HostdevPciDeviceAddress.DEVICE_ADDRESS_FUNCTION_MAX_VALUE );
+
+ this.pciDomain = pciDomain;
+ this.pciBus = pciBus;
+ this.pciDevice = pciDevice;
+ this.pciFunction = pciFunction;
+ }
+
+ /**
+ * Validates a specified PCI address component (PCI domain, bus, device or function).
+ *
+ * @param address value of the PCI address component.
+ * @param addressName name of the PCI address component.
+ * @param upperLimit maximum value for the PCI address component
+ *
+ * @throws IllegalArgumentException
+ */
+ private static void validatePciDeviceAddress( final int address, final String addressName, final int upperLimit )
+ throws IllegalArgumentException
+ {
+ if ( address < HostdevPciDeviceAddress.DEVICE_ADDRESS_MIN_VALUE ) {
+ throw new IllegalArgumentException(
+ "The " + addressName + " address must be larger or equal than "
+ + HostdevPciDeviceAddress.DEVICE_ADDRESS_MIN_VALUE );
+ } else if ( address > upperLimit ) {
+ throw new IllegalArgumentException(
+ "The " + addressName + " address must be smaller or equal than " + upperLimit );
+ }
+ }
+
+ /**
+ * Returns the PCI domain.
+ *
+ * @return PCI domain.
+ */
+ public int getPciDomain()
+ {
+ return this.pciDomain;
+ }
+
+ /**
+ * Returns the PCI domain as {@link String}.
+ *
+ * @return PCI domain as {@link String}.
+ */
+ public String getPciDomainAsString()
+ {
+ return String.format( "%04x", HostdevPciDeviceAddress.DEVICE_ADDRESS_DOMAIN_MAX_VALUE & this.getPciDomain() );
+ }
+
+ /**
+ * Returns the PCI bus.
+ *
+ * @return PCI bus.
+ */
+ public int getPciBus()
+ {
+ return this.pciBus;
+ }
+
+ /**
+ * Returns the PCI bus as {@link String}.
+ *
+ * @return PCI bus as {@link String}.
+ */
+ public String getPciBusAsString()
+ {
+ return String.format( "%02x", HostdevPciDeviceAddress.DEVICE_ADDRESS_BUS_MAX_VALUE & this.getPciBus() );
+ }
+
+ /**
+ * Returns the PCI device.
+ *
+ * @return PCI device.
+ */
+ public int getPciDevice()
+ {
+ return this.pciDevice;
+ }
+
+ /**
+ * Returns the PCI device as {@link String}.
+ *
+ * @return PCI device as {@link String}.
+ */
+ public String getPciDeviceAsString()
+ {
+ return String.format( "%02x", HostdevPciDeviceAddress.DEVICE_ADDRESS_DEVICE_MAX_VALUE & this.getPciDevice() );
+ }
+
+ /**
+ * Returns the PCI function.
+ *
+ * @return PCI function.
+ */
+ public int getPciFunction()
+ {
+ return this.pciFunction;
+ }
+
+ /**
+ * Returns the PCI function as {@link String}.
+ *
+ * @return PCI function as {@link String}.
+ */
+ public String getPciFunctionAsString()
+ {
+ return String.format( "%01x", HostdevPciDeviceAddress.DEVICE_ADDRESS_FUNCTION_MAX_VALUE & this.getPciFunction() );
+ }
+
+ /**
+ * Creates a new PCI device address parsed from a {@link String}.
+ * <p>
+ * The PCI device address consists of a PCI domain, bus, device and function parsed from the
+ * specified {@link String}.
+ *
+ * @param pciDeviceAddress textual information containing a PCI device address as {@link String}.
+ * The textual PCI device address should be well-formed according to the defined
+ * regular expression {@link #DEVICE_ADDRESS_REGEX}.
+ *
+ * @return PCI device address instance.
+ */
+ public static HostdevPciDeviceAddress valueOf( String pciDeviceAddress )
+ {
+ HostdevPciDeviceAddress parsedPciDeviceAddress;
+
+ if ( pciDeviceAddress == null || pciDeviceAddress.isEmpty() ) {
+ parsedPciDeviceAddress = null;
+ } else {
+ final Pattern pciDeviceAddressPattern = Pattern.compile( HostdevPciDeviceAddress.DEVICE_ADDRESS_REGEX );
+ final Matcher pciDeviceAddressMatcher = pciDeviceAddressPattern.matcher( pciDeviceAddress.toLowerCase() );
+
+ if ( pciDeviceAddressMatcher.find() ) {
+ final int pciDomain = Integer.valueOf( pciDeviceAddressMatcher.group( 1 ), 16 );
+ final int pciBus = Integer.valueOf( pciDeviceAddressMatcher.group( 2 ), 16 );
+ final int pciDevice = Integer.valueOf( pciDeviceAddressMatcher.group( 3 ), 16 );
+ final int pciFunction = Integer.valueOf( pciDeviceAddressMatcher.group( 4 ), 16 );
+
+ try {
+ parsedPciDeviceAddress = new HostdevPciDeviceAddress( pciDomain, pciBus, pciDevice, pciFunction );
+ } catch ( IllegalArgumentException e ) {
+ parsedPciDeviceAddress = null;
+ }
+ } else {
+ parsedPciDeviceAddress = null;
+ }
+ }
+
+ return parsedPciDeviceAddress;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( obj == null ) {
+ return false;
+ } else if ( this.getClass() != obj.getClass() ) {
+ return false;
+ } else {
+ // check if PCI domain, bus, device and function are equal
+ final HostdevPciDeviceAddress other = HostdevPciDeviceAddress.class.cast( obj );
+ if ( this.getPciDomain() == other.getPciDomain() && this.getPciBus() == other.getPciBus()
+ && this.getPciDevice() == other.getPciDevice() && this.getPciFunction() == other.getPciFunction() ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.getPciDomainAsString() + ":" + this.getPciBusAsString() + ":" + this.getPciDeviceAsString() + "."
+ + this.getPciFunctionAsString();
+ }
+}