chiark / gitweb /
udev: hwdb - add usb class descriptions
authorKay Sievers <kay@vrfy.org>
Fri, 9 Nov 2012 13:53:55 +0000 (14:53 +0100)
committerKay Sievers <kay@vrfy.org>
Fri, 9 Nov 2012 14:02:58 +0000 (15:02 +0100)
Makefile.am
hwdb/20-usb-classes.hwdb [new file with mode: 0644]
hwdb/ids-update.pl

index 27b505f..2c84fe1 100644 (file)
@@ -1800,6 +1800,7 @@ dist_udevhwdb_DATA = \
        hwdb/20-pci-vendor-product.hwdb \
        hwdb/20-pci-classes.hwdb \
        hwdb/20-usb-vendor-product.hwdb \
+       hwdb/20-usb-classes.hwdb \
        hwdb/20-acpi-vendor.hwdb \
        hwdb/20-OUI.hwdb
 
diff --git a/hwdb/20-usb-classes.hwdb b/hwdb/20-usb-classes.hwdb
new file mode 100644 (file)
index 0000000..1ab4a84
--- /dev/null
@@ -0,0 +1,348 @@
+# This file is part of systemd.
+#
+# Data imported and updated from: http://www.linux-usb.org/usb.ids
+
+usb:v*p*d*dc00*
+ ID_USB_CLASS_FROM_DATABASE=(Defined at Interface level)
+
+usb:v*p*d*dc01*
+ ID_USB_CLASS_FROM_DATABASE=Audio
+
+usb:v*p*d*dc01dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Control Device
+
+usb:v*p*d*dc01dsc02*
+ ID_USB_SUBCLASS_FROM_DATABASE=Streaming
+
+usb:v*p*d*dc01dsc03*
+ ID_USB_SUBCLASS_FROM_DATABASE=MIDI Streaming
+
+usb:v*p*d*dc02*
+ ID_USB_CLASS_FROM_DATABASE=Communications
+
+usb:v*p*d*dc02dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Direct Line
+
+usb:v*p*d*dc02dsc02*
+ ID_USB_SUBCLASS_FROM_DATABASE=Abstract (modem)
+
+usb:v*p*d*dc02dsc02dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (v.25ter)
+
+usb:v*p*d*dc02dsc02dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (PCCA101)
+
+usb:v*p*d*dc02dsc02dp03*
+ ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (PCCA101 + wakeup)
+
+usb:v*p*d*dc02dsc02dp04*
+ ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (GSM)
+
+usb:v*p*d*dc02dsc02dp05*
+ ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (3G)
+
+usb:v*p*d*dc02dsc02dp06*
+ ID_USB_PROTOCOL_FROM_DATABASE=AT-commands (CDMA)
+
+usb:v*p*d*dc02dsc02dpFE*
+ ID_USB_PROTOCOL_FROM_DATABASE=Defined by command set descriptor
+
+usb:v*p*d*dc02dsc02dpFF*
+ ID_USB_PROTOCOL_FROM_DATABASE=Vendor Specific (MSFT RNDIS?)
+
+usb:v*p*d*dc02dsc03*
+ ID_USB_SUBCLASS_FROM_DATABASE=Telephone
+
+usb:v*p*d*dc02dsc04*
+ ID_USB_SUBCLASS_FROM_DATABASE=Multi-Channel
+
+usb:v*p*d*dc02dsc05*
+ ID_USB_SUBCLASS_FROM_DATABASE=CAPI Control
+
+usb:v*p*d*dc02dsc06*
+ ID_USB_SUBCLASS_FROM_DATABASE=Ethernet Networking
+
+usb:v*p*d*dc02dsc07*
+ ID_USB_SUBCLASS_FROM_DATABASE=ATM Networking
+
+usb:v*p*d*dc02dsc08*
+ ID_USB_SUBCLASS_FROM_DATABASE=Wireless Handset Control
+
+usb:v*p*d*dc02dsc09*
+ ID_USB_SUBCLASS_FROM_DATABASE=Device Management
+
+usb:v*p*d*dc02dsc0A*
+ ID_USB_SUBCLASS_FROM_DATABASE=Mobile Direct Line
+
+usb:v*p*d*dc02dsc0B*
+ ID_USB_SUBCLASS_FROM_DATABASE=OBEX
+
+usb:v*p*d*dc02dsc0C*
+ ID_USB_SUBCLASS_FROM_DATABASE=Ethernet Emulation
+
+usb:v*p*d*dc02dsc0Cdp07*
+ ID_USB_PROTOCOL_FROM_DATABASE=Ethernet Emulation (EEM)
+
+usb:v*p*d*dc03*
+ ID_USB_CLASS_FROM_DATABASE=Human Interface Device
+
+usb:v*p*d*dc03dsc00*
+ ID_USB_SUBCLASS_FROM_DATABASE=No Subclass
+
+usb:v*p*d*dc03dsc00dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Keyboard
+
+usb:v*p*d*dc03dsc00dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Mouse
+
+usb:v*p*d*dc03dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Boot Interface Subclass
+
+usb:v*p*d*dc03dsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Keyboard
+
+usb:v*p*d*dc03dsc01dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Mouse
+
+usb:v*p*d*dc05*
+ ID_USB_CLASS_FROM_DATABASE=Physical Interface Device
+
+usb:v*p*d*dc06*
+ ID_USB_CLASS_FROM_DATABASE=Imaging
+
+usb:v*p*d*dc06dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Still Image Capture
+
+usb:v*p*d*dc06dsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Picture Transfer Protocol (PIMA 15470)
+
+usb:v*p*d*dc07*
+ ID_USB_CLASS_FROM_DATABASE=Printer
+
+usb:v*p*d*dc07dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Printer
+
+usb:v*p*d*dc07dsc01dp00*
+ ID_USB_PROTOCOL_FROM_DATABASE=Reserved/Undefined
+
+usb:v*p*d*dc07dsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Unidirectional
+
+usb:v*p*d*dc07dsc01dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Bidirectional
+
+usb:v*p*d*dc07dsc01dp03*
+ ID_USB_PROTOCOL_FROM_DATABASE=IEEE 1284.4 compatible bidirectional
+
+usb:v*p*d*dc07dsc01dpFF*
+ ID_USB_PROTOCOL_FROM_DATABASE=Vendor Specific
+
+usb:v*p*d*dc08*
+ ID_USB_CLASS_FROM_DATABASE=Mass Storage
+
+usb:v*p*d*dc08dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=RBC (typically Flash)
+
+usb:v*p*d*dc08dsc01dp00*
+ ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk/Interrupt
+
+usb:v*p*d*dc08dsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk
+
+usb:v*p*d*dc08dsc01dp50*
+ ID_USB_PROTOCOL_FROM_DATABASE=Bulk-Only
+
+usb:v*p*d*dc08dsc02*
+ ID_USB_SUBCLASS_FROM_DATABASE=SFF-8020i, MMC-2 (ATAPI)
+
+usb:v*p*d*dc08dsc03*
+ ID_USB_SUBCLASS_FROM_DATABASE=QIC-157
+
+usb:v*p*d*dc08dsc04*
+ ID_USB_SUBCLASS_FROM_DATABASE=Floppy (UFI)
+
+usb:v*p*d*dc08dsc04dp00*
+ ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk/Interrupt
+
+usb:v*p*d*dc08dsc04dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk
+
+usb:v*p*d*dc08dsc04dp50*
+ ID_USB_PROTOCOL_FROM_DATABASE=Bulk-Only
+
+usb:v*p*d*dc08dsc05*
+ ID_USB_SUBCLASS_FROM_DATABASE=SFF-8070i
+
+usb:v*p*d*dc08dsc06*
+ ID_USB_SUBCLASS_FROM_DATABASE=SCSI
+
+usb:v*p*d*dc08dsc06dp00*
+ ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk/Interrupt
+
+usb:v*p*d*dc08dsc06dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Control/Bulk
+
+usb:v*p*d*dc08dsc06dp50*
+ ID_USB_PROTOCOL_FROM_DATABASE=Bulk-Only
+
+usb:v*p*d*dc09*
+ ID_USB_CLASS_FROM_DATABASE=Hub
+
+usb:v*p*d*dc09dsc00dp00*
+ ID_USB_PROTOCOL_FROM_DATABASE=Full speed (or root) hub
+
+usb:v*p*d*dc09dsc00dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Single TT
+
+usb:v*p*d*dc09dsc00dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=TT per port
+
+usb:v*p*d*dc0A*
+ ID_USB_CLASS_FROM_DATABASE=CDC Data
+
+usb:v*p*d*dc0Adsc00dp30*
+ ID_USB_PROTOCOL_FROM_DATABASE=I.430 ISDN BRI
+
+usb:v*p*d*dc0Adsc00dp31*
+ ID_USB_PROTOCOL_FROM_DATABASE=HDLC
+
+usb:v*p*d*dc0Adsc00dp32*
+ ID_USB_PROTOCOL_FROM_DATABASE=Transparent
+
+usb:v*p*d*dc0Adsc00dp50*
+ ID_USB_PROTOCOL_FROM_DATABASE=Q.921M
+
+usb:v*p*d*dc0Adsc00dp51*
+ ID_USB_PROTOCOL_FROM_DATABASE=Q.921
+
+usb:v*p*d*dc0Adsc00dp52*
+ ID_USB_PROTOCOL_FROM_DATABASE=Q.921TM
+
+usb:v*p*d*dc0Adsc00dp90*
+ ID_USB_PROTOCOL_FROM_DATABASE=V.42bis
+
+usb:v*p*d*dc0Adsc00dp91*
+ ID_USB_PROTOCOL_FROM_DATABASE=Q.932 EuroISDN
+
+usb:v*p*d*dc0Adsc00dp92*
+ ID_USB_PROTOCOL_FROM_DATABASE=V.120 V.24 rate ISDN
+
+usb:v*p*d*dc0Adsc00dp93*
+ ID_USB_PROTOCOL_FROM_DATABASE=CAPI 2.0
+
+usb:v*p*d*dc0Adsc00dpFD*
+ ID_USB_PROTOCOL_FROM_DATABASE=Host Based Driver
+
+usb:v*p*d*dc0Adsc00dpFE*
+ ID_USB_PROTOCOL_FROM_DATABASE=CDC PUF
+
+usb:v*p*d*dc0Adsc00dpFF*
+ ID_USB_PROTOCOL_FROM_DATABASE=Vendor specific
+
+usb:v*p*d*dc0B*
+ ID_USB_CLASS_FROM_DATABASE=Chip/SmartCard
+
+usb:v*p*d*dc0D*
+ ID_USB_CLASS_FROM_DATABASE=Content Security
+
+usb:v*p*d*dc0E*
+ ID_USB_CLASS_FROM_DATABASE=Video
+
+usb:v*p*d*dc0Edsc00*
+ ID_USB_SUBCLASS_FROM_DATABASE=Undefined
+
+usb:v*p*d*dc0Edsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Video Control
+
+usb:v*p*d*dc0Edsc02*
+ ID_USB_SUBCLASS_FROM_DATABASE=Video Streaming
+
+usb:v*p*d*dc0Edsc03*
+ ID_USB_SUBCLASS_FROM_DATABASE=Video Interface Collection
+
+usb:v*p*d*dc58*
+ ID_USB_CLASS_FROM_DATABASE=Xbox
+
+usb:v*p*d*dc58dsc42*
+ ID_USB_SUBCLASS_FROM_DATABASE=Controller
+
+usb:v*p*d*dcDC*
+ ID_USB_CLASS_FROM_DATABASE=Diagnostic
+
+usb:v*p*d*dcDCdsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Reprogrammable Diagnostics
+
+usb:v*p*d*dcDCdsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=USB2 Compliance
+
+usb:v*p*d*dcE0*
+ ID_USB_CLASS_FROM_DATABASE=Wireless
+
+usb:v*p*d*dcE0dsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Radio Frequency
+
+usb:v*p*d*dcE0dsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Bluetooth
+
+usb:v*p*d*dcE0dsc01dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Ultra WideBand Radio Control
+
+usb:v*p*d*dcE0dsc01dp03*
+ ID_USB_PROTOCOL_FROM_DATABASE=RNDIS
+
+usb:v*p*d*dcE0dsc02*
+ ID_USB_SUBCLASS_FROM_DATABASE=Wireless USB Wire Adapter
+
+usb:v*p*d*dcE0dsc02dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Host Wire Adapter Control/Data Streaming
+
+usb:v*p*d*dcE0dsc02dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Device Wire Adapter Control/Data Streaming
+
+usb:v*p*d*dcE0dsc02dp03*
+ ID_USB_PROTOCOL_FROM_DATABASE=Device Wire Adapter Isochronous Streaming
+
+usb:v*p*d*dcEF*
+ ID_USB_CLASS_FROM_DATABASE=Miscellaneous Device
+
+usb:v*p*d*dcEFdsc01dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Microsoft ActiveSync
+
+usb:v*p*d*dcEFdsc01dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Palm Sync
+
+usb:v*p*d*dcEFdsc02dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Interface Association
+
+usb:v*p*d*dcEFdsc02dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=Wire Adapter Multifunction Peripheral
+
+usb:v*p*d*dcEFdsc03dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=Cable Based Association
+
+usb:v*p*d*dcFE*
+ ID_USB_CLASS_FROM_DATABASE=Application Specific Interface
+
+usb:v*p*d*dcFEdsc01*
+ ID_USB_SUBCLASS_FROM_DATABASE=Device Firmware Update
+
+usb:v*p*d*dcFEdsc02*
+ ID_USB_SUBCLASS_FROM_DATABASE=IRDA Bridge
+
+usb:v*p*d*dcFEdsc03*
+ ID_USB_SUBCLASS_FROM_DATABASE=Test and Measurement
+
+usb:v*p*d*dcFEdsc03dp01*
+ ID_USB_PROTOCOL_FROM_DATABASE=TMC
+
+usb:v*p*d*dcFEdsc03dp02*
+ ID_USB_PROTOCOL_FROM_DATABASE=USB488
+
+usb:v*p*d*dcFF*
+ ID_USB_CLASS_FROM_DATABASE=Vendor Specific Class
+
+usb:v*p*d*dcFFdscFF*
+ ID_USB_SUBCLASS_FROM_DATABASE=Vendor Specific Subclass
+
+usb:v*p*d*dcFFdscFFdpFF*
+ ID_USB_PROTOCOL_FROM_DATABASE=Vendor Specific Protocol
index d51f220..96db87d 100755 (executable)
@@ -4,165 +4,233 @@ use strict;
 use warnings;
 
 sub usb_vendor {
-       my $vendor;
-
-       open(IN, "<", "usb.ids");
-       open(OUT, ">", "20-usb-vendor-product.hwdb");
-       print(OUT "# This file is part of systemd.\n" .
-                 "#\n" .
-                 "# Data imported and updated from: http://www.linux-usb.org/usb.ids\n");
-
-       while (my $line = <IN>) {
-               $line =~ s/\s+$//;
-               $line =~ m/^([0-9a-f]{4})\s*(.*)$/;
-               if (defined $1) {
-                       $vendor = uc $1;
-                       my $text = $2;
-                       print(OUT "\n");
-                       print(OUT "usb:v" . $vendor . "*\n");
-                       print(OUT " ID_VENDOR_FROM_DATABASE=" . $text . "\n");
-                       next;
-               }
-
-               $line =~ m/^\t([0-9a-f]{4})\s*(.*)$/;
-               if (defined $1) {
-                       my $product = uc $1;
-                       my $text = $2;
-                       print(OUT "\n");
-                       print(OUT "usb:v" . $vendor . "p" . $product . "*\n");
-                       print(OUT " ID_PRODUCT_FROM_DATABASE=" . $text . "\n");
-               }
-       }
-
-       close(INP);
-       close(OUTP);
+        my $vendor;
+
+        open(IN, "<", "usb.ids");
+        open(OUT, ">", "20-usb-vendor-product.hwdb");
+        print(OUT "# This file is part of systemd.\n" .
+                  "#\n" .
+                  "# Data imported and updated from: http://www.linux-usb.org/usb.ids\n");
+
+        while (my $line = <IN>) {
+                $line =~ s/\s+$//;
+                $line =~ m/^([0-9a-f]{4})\s*(.*)$/;
+                if (defined $1) {
+                        $vendor = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "usb:v" . $vendor . "*\n");
+                        print(OUT " ID_VENDOR_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                $line =~ m/^\t([0-9a-f]{4})\s*(.*)$/;
+                if (defined $1) {
+                        my $product = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "usb:v" . $vendor . "p" . $product . "*\n");
+                        print(OUT " ID_PRODUCT_FROM_DATABASE=" . $text . "\n");
+                }
+        }
+
+        close(INP);
+        close(OUTP);
+}
+
+sub usb_classes {
+        my $class;
+        my $subclass;
+        my $protocol;
+
+        open(IN, "<", "usb.ids");
+        open(OUT, ">", "20-usb-classes.hwdb");
+        print(OUT "# This file is part of systemd.\n" .
+                  "#\n" .
+                  "# Data imported and updated from: http://www.linux-usb.org/usb.ids\n");
+
+        while (my $line = <IN>) {
+                $line =~ s/\s+$//;
+
+                $line =~ m/^C\ ([0-9a-f]{2})\s*(.*)$/;
+                if (defined $1) {
+                        $class = uc $1;
+                        my $text = $2;
+                        if ($text =~ m/^(\?|None|Unused)$/) {
+                                next;
+                        }
+                        print(OUT "\n");
+                        print(OUT "usb:v*p*d*dc" . $class . "*\n");
+                        print(OUT " ID_USB_CLASS_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                if (not defined $class) {
+                        next;
+                } elsif ($line =~ m/^$/) {
+                        last;
+                }
+
+                $line =~ m/^\t([0-9a-f]{2})\s*(.*)$/;
+                if (defined $1) {
+                        $subclass = uc $1;
+                        my $text = $2;
+                        if ($text =~ m/^(\?|None|Unused)$/) {
+                                next;
+                        }
+                        print(OUT "\n");
+                        print(OUT "usb:v*p*d*dc" . $class . "dsc" . $subclass . "*\n");
+                        print(OUT " ID_USB_SUBCLASS_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                $line =~ m/^\t\t([0-9a-f]{2})\s*(.*)$/;
+                if (defined $1) {
+                        $protocol = uc $1;
+                        my $text = $2;
+                        if ($text =~ m/^(\?|None|Unused)$/) {
+                                next;
+                        }
+                        print(OUT "\n");
+                        print(OUT "usb:v*p*d*dc" .  $class . "dsc" . $subclass . "dp" . $protocol . "*\n");
+                        print(OUT " ID_USB_PROTOCOL_FROM_DATABASE=" . $text . "\n");
+                }
+        }
+
+        close(INP);
+        close(OUTP);
 }
 
 sub pci_vendor {
-       my $vendor;
-       my $device;
-
-       open(IN, "<", "usb.ids");
-       open(IN, "<", "pci.ids");
-       open(OUT, ">", "20-pci-vendor-product.hwdb");
-       print(OUT "# This file is part of systemd.\n" .
-                 "#\n" .
-                 "# Data imported and updated from: http://pciids.sourceforge.net/v2.2/pci.ids\n");
-
-       while (my $line = <IN>) {
-               $line =~ s/\s+$//;
-               $line =~ m/^([0-9a-f]{4})\s*(.*)$/;
-
-               if (defined $1) {
-                       $vendor = uc $1;
-                       my $text = $2;
-                       print(OUT "\n");
-                       print(OUT "pci:v0000" . $vendor . "*\n");
-                       print(OUT " ID_VENDOR_FROM_DATABASE=" . $text . "\n");
-                       next;
-               }
-
-               $line =~ m/^\t([0-9a-f]{4})\s*(.*)$/;
-               if (defined $1) {
-                       $device = uc $1;
-                       my $text = $2;
-                       print(OUT "\n");
-                       print(OUT "pci:v0000" . $vendor . "d0000" . $device . "*\n");
-                       print(OUT " ID_PRODUCT_FROM_DATABASE=" . $text . "\n");
-                       next;
-               }
-
-               $line =~ m/^\t\t([0-9a-f]{4})\s*([0-9a-f]{4})\s*(.*)$/;
-               if (defined $1) {
-                       my $sub_vendor = uc $1;
-                       my $sub_device = uc $2;
-                       my $text = $3;
-                       print(OUT "\n");
-                       print(OUT "pci:v0000" . $vendor . "d0000" . $device . "sv0000" . $sub_vendor . "sd0000" . $sub_device . "*\n");
-                       print(OUT " ID_PRODUCT_FROM_DATABASE=" . $text . "\n");
-               }
-       }
-
-       close(INP);
-       close(OUTP);
+        my $vendor;
+        my $device;
+
+        open(IN, "<", "usb.ids");
+        open(IN, "<", "pci.ids");
+        open(OUT, ">", "20-pci-vendor-product.hwdb");
+        print(OUT "# This file is part of systemd.\n" .
+                  "#\n" .
+                  "# Data imported and updated from: http://pciids.sourceforge.net/v2.2/pci.ids\n");
+
+        while (my $line = <IN>) {
+                $line =~ s/\s+$//;
+                $line =~ m/^([0-9a-f]{4})\s*(.*)$/;
+
+                if (defined $1) {
+                        $vendor = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "pci:v0000" . $vendor . "*\n");
+                        print(OUT " ID_VENDOR_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                $line =~ m/^\t([0-9a-f]{4})\s*(.*)$/;
+                if (defined $1) {
+                        $device = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "pci:v0000" . $vendor . "d0000" . $device . "*\n");
+                        print(OUT " ID_PRODUCT_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                $line =~ m/^\t\t([0-9a-f]{4})\s*([0-9a-f]{4})\s*(.*)$/;
+                if (defined $1) {
+                        my $sub_vendor = uc $1;
+                        my $sub_device = uc $2;
+                        my $text = $3;
+                        print(OUT "\n");
+                        print(OUT "pci:v0000" . $vendor . "d0000" . $device . "sv0000" . $sub_vendor . "sd0000" . $sub_device . "*\n");
+                        print(OUT " ID_PRODUCT_FROM_DATABASE=" . $text . "\n");
+                }
+        }
+
+        close(INP);
+        close(OUTP);
 }
 
 sub pci_classes {
-       my $class;
-       my $subclass;
-       my $interface;
-
-       open(IN, "<", "pci.ids");
-       open(OUT, ">", "20-pci-classes.hwdb");
-       print(OUT "# This file is part of systemd.\n" .
-                 "#\n" .
-                 "# Data imported and updated from: http://pciids.sourceforge.net/v2.2/pci.ids\n");
-
-       while (my $line = <IN>) {
-               $line =~ s/\s+$//;
-
-               $line =~ m/^C\ ([0-9a-f]{2})\s*(.*)$/;
-               if (defined $1) {
-                       $class = uc $1;
-                       my $text = $2;
-                       print(OUT "\n");
-                       print(OUT "pci:v*d*sv*sd*bc" . $class . "*\n");
-                       print(OUT " ID_PCI_CLASS_FROM_DATABASE=" . $text . "\n");
-                       next;
-               }
-
-               if (not defined $class) {
-                       next;
-               }
-
-               $line =~ m/^\t([0-9a-f]{2})\s*(.*)$/;
-               if (defined $1) {
-                       $subclass = uc $1;
-                       my $text = $2;
-                       print(OUT "\n");
-                       print(OUT "pci:v*d*sv*sd*bc" . $class . "sc" . $subclass . "*\n");
-                       print(OUT " ID_PCI_SUBCLASS_FROM_DATABASE=" . $text . "\n");
-                       next;
-               }
-
-               $line =~ m/^\t\t([0-9a-f]{2})\s*(.*)$/;
-               if (defined $1) {
-                       $interface = uc $1;
-                       my $text = $2;
-                       print(OUT "\n");
-                       print(OUT "pci:v*d*sv*sd*bc" .  $class . "sc" . $subclass . "i" . $interface . "*\n");
-                       print(OUT " ID_PCI_INTERFACE_FROM_DATABASE=" . $text . "\n");
-               }
-       }
-
-       close(INP);
-       close(OUTP);
+        my $class;
+        my $subclass;
+        my $interface;
+
+        open(IN, "<", "pci.ids");
+        open(OUT, ">", "20-pci-classes.hwdb");
+        print(OUT "# This file is part of systemd.\n" .
+                  "#\n" .
+                  "# Data imported and updated from: http://pciids.sourceforge.net/v2.2/pci.ids\n");
+
+        while (my $line = <IN>) {
+                $line =~ s/\s+$//;
+
+                $line =~ m/^C\ ([0-9a-f]{2})\s*(.*)$/;
+                if (defined $1) {
+                        $class = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "pci:v*d*sv*sd*bc" . $class . "*\n");
+                        print(OUT " ID_PCI_CLASS_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                if (not defined $class) {
+                        next;
+                } elsif ($line =~ m/^$/) {
+                        last;
+                }
+
+                $line =~ m/^\t([0-9a-f]{2})\s*(.*)$/;
+                if (defined $1) {
+                        $subclass = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "pci:v*d*sv*sd*bc" . $class . "sc" . $subclass . "*\n");
+                        print(OUT " ID_PCI_SUBCLASS_FROM_DATABASE=" . $text . "\n");
+                        next;
+                }
+
+                $line =~ m/^\t\t([0-9a-f]{2})\s*(.*)$/;
+                if (defined $1) {
+                        $interface = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "pci:v*d*sv*sd*bc" .  $class . "sc" . $subclass . "i" . $interface . "*\n");
+                        print(OUT " ID_PCI_INTERFACE_FROM_DATABASE=" . $text . "\n");
+                }
+        }
+
+        close(INP);
+        close(OUTP);
 }
 
 sub oui {
-       open(IN, "<", "oui.txt");
-       open(OUT, ">", "20-OUI.hwdb");
-       print(OUT "# This file is part of systemd.\n" .
-                 "#\n" .
-                 "# Data imported and updated from: http://standards.ieee.org/develop/regauth/oui/oui.txt\n");
-
-       while (my $line = <IN>) {
-               $line =~ s/\s+$//;
-               $line =~ m/^([0-9A-F]{6})\s*\(base 16\)\s*(.*)$/;
-               if (defined $1) {
-                       my $vendor = uc $1;
-                       my $text = $2;
-                       print(OUT "\n");
-                       print(OUT "OUI:" . $vendor . "\n");
-                       print(OUT " ID_OUI_FROM_DATABASE=" . $text . "\n");
-               }
-       }
-
-       close(INP);
-       close(OUTP);
+        open(IN, "<", "oui.txt");
+        open(OUT, ">", "20-OUI.hwdb");
+        print(OUT "# This file is part of systemd.\n" .
+                  "#\n" .
+                  "# Data imported and updated from: http://standards.ieee.org/develop/regauth/oui/oui.txt\n");
+
+        while (my $line = <IN>) {
+                $line =~ s/\s+$//;
+                $line =~ m/^([0-9A-F]{6})\s*\(base 16\)\s*(.*)$/;
+                if (defined $1) {
+                        my $vendor = uc $1;
+                        my $text = $2;
+                        print(OUT "\n");
+                        print(OUT "OUI:" . $vendor . "\n");
+                        print(OUT " ID_OUI_FROM_DATABASE=" . $text . "\n");
+                }
+        }
+
+        close(INP);
+        close(OUTP);
 }
 
 usb_vendor();
+usb_classes();
+
 pci_vendor();
 pci_classes();
+
 oui();