Skip to content

Instantly share code, notes, and snippets.

@yeetim
Created September 20, 2014 07:07
Show Gist options
  • Save yeetim/6caef7ed547f7869d589 to your computer and use it in GitHub Desktop.
Save yeetim/6caef7ed547f7869d589 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl -w
# $Header: /CVSROOT/yahoo/ops/software/hwconfig/hwconfig,v 1.51.2.1 2008/11/06 01:01:10 filo Exp $
use strict 'vars';
use Getopt::Std;
use POSIX;
# constants
$ENV{PATH} = "/etc/bin:/sbin:/usr/sbin:/bin:/usr/bin:/home/y/bin:/usr/local/bin:/usr/local/sbin:/home/opt:/opt/MegaRAID/MegaCli:/usr/StorMan";
my($version) = '1.8.6';
my($timeout) = 120;
my($email) = '[email protected]';
my($smbinfo) = 'smbinfo';
my($smbiosinfo) = 'smbiosinfo';
my($mptable) = 'mptable';
my($pciconf) = 'pciconf';
my($megarc) = 'megarc';
my($mfiutil) = 'mfiutil';
my($mptutil) = 'mptutil';
my($cissutil) = 'cissutil';
my($camcontrol) = 'camcontrol';
my($atacontrol) = 'atacontrol';
my($grub) = '/etc/grub.conf';
my($dmesg_file) = '/var/run/dmesg.boot';
my($dmesg_prog) = 'dmesg';
my($varrun) = '/home/y/var/run';
my($feature_htt_bit) = 28;
# linux constants
my($cpuinfo) = '/proc/cpuinfo';
my($meminfo) = '/proc/meminfo';
my($proc_ide) = '/proc/ide';
my($proc_scsi) = '/proc/scsi/scsi';
my($proc_cciss) = '/proc/driver/cciss';
my($sys_cciss) = '/sys/bus/pci/drivers/cciss';
my($sys_pci) = '/sys/bus/pci/devices';
my($proc_partitions) = '/proc/partitions';
my($proc_mdstat) = '/proc/mdstat';
my($proc_interrupts) = '/proc/interrupts';
my($proc_ioports) = '/proc/ioports';
my($proc_iomem) = '/proc/iomem';
my($lspci) = 'lspci';
my($lshal) = 'lshal';
my($ethtool) = 'ethtool';
my($dmidecode) = 'dmidecode';
my($hpacucli) = 'hpacucli';
my($twcli) = 'tw_cli';
my($arcconf) = 'arcconf';
my($freebsd_net_devs) = 'bge|em|fxp|xl|rl|nve|dc|bce|myk|msk|lnc|le';
my($perc_names) = 'PERC|ServeRAID-MR10M|SROMBSASFC';
my($lock) = '/var/tmp/hwconfig.lock';
my($need_megarc, $want_megarc, $have_megarc, $got_megarc) = (0, 0, 0, 0);
my($need_megacli, $want_megacli, $have_megacli, $got_megacli) = (0, 0, 0, 0);
my($need_mfiutil, $want_mfiutil, $have_mfiutil, $got_mfiutil) = (0, 0, 0, 0);
my($need_mptutil, $want_mptutil, $have_mptutil, $got_mptutil) = (0, 0, 0, 0);
my($need_arcconf, $want_arcconf, $have_arcconf, $got_arcconf) = (0, 0, 0, 0);
my($need_cissutil, $want_cissutil, $have_cissutil, $got_cissutil) = (0, 0, 0, 0);
my($need_hpacucli, $want_hpacucli, $have_hpacucli, $got_hpacucli) = (0, 0, 0, 0);
my($need_twcli, $want_twcli, $have_twcli, $got_twcli) = (0, 0, 0, 0);
my($need_omreport, $want_omreport, $have_omreport, $got_omreport) = (0, 0, 0, 0);
my($need_mdstat) = 0;
my($need_lvm) = 0;
my($need_ccdconfig) = 0;
my($need_rd) = 0;
my($dmesg_buf) = '';
my($output) = '';
my($stderr) = '';
my($perl_warn) = '';
my($debug) = '';
my($debug_pciconf) = '';
my($debug_lspci) = '';
my($debug_lshal) = '';
my($debug_sysctl_dev) = '';
my($debug_dmidecode) = '';
my($debug_storage) = '';
my($debug_network) = '';
my($debug_cpuinfo) = '';
my($debug_meminfo) = '';
my($sig_pci) = '';
my($os, $os_type, $os_date, $os_version, $os_up, $os_distro, $parent_os);
my($jailed, $jailer) = (0, '');
my($yroot) = '';
my($in) = 'IN';
my($line);
my($zero);
my($hostname) = '';
my(%opts);
my(%success);
my(%other_devices);
my(%smbios);
my(%dmi);
my(%sysctl_dev);
my($clean_smbios_regex) = '(\(null\)|N\/A|_?To Be Filled( By O\.E\.M\.)?_?|Not Specified|empty|<OUT OF SPEC>|System Name|System Manufacturer|NO DIMM|No Module Installed|MemUndefined|None|Unknown|<BAD INDEX>|ModulePartNumber\d+|Manufacturer\d+|SerNum\d+|AssetTagNum\d+|PartNum\d+|0000000000000000*|\.\.\.\.\.\.*)';
my($ignore_disk_models) = 'partitions|LSILogic-MegaRAID|3ware-Logical|COMPAQ-RAID|NETAPP-LUN|MegaRAID-LD|MFI-Logical-Disk|LSILOGIC-1030-IM|1030-IM|Adaptec-Mirror|ADAPTEC-RAID|LD-?\d+-RAID|Dell-VIRTUAL-DISK|DELL-PERC-|PERC-|Logical-Volume|DGC-RAID|VMware-Virtual|SRCSAS18E|RAID-0-Stripe|RAID-1-Mirror|U12U-G4020|AMCC-|LSILOGIC-Logical|Compaq-Logical|RAID-0-1|2120S-RAID|RAID-5|Dell-Virtual-Floppy|VIRTUALFLOPPY|Logical-Disk-\d+';
my(%chipsets) = (
# http://balusc.xs4all.nl/srv/har-chi-int.php
# http://en.wikipedia.org/wiki/List_of_Intel_chipsets
# Intel South - use LPC bridge
# http://en.wikipedia.org/wiki/I/O_Controller_Hub
"0x70008086" => "SB: Intel 82371SB (PIIX3)",
"0x71108086" => "SB: Intel 82371 (PIIX4)",
"0x24108086" => "SB: Intel 82801AA (ICH)",
"0x24208086" => "SB: Intel 82801AB (ICH0)",
"0x24408086" => "SB: Intel 82801BA (ICH2)",
"0x24808086" => "SB: Intel 82801CA (ICH3)",
"0x24c08086" => "SB: Intel 82801DB (ICH4)",
"0x24c08086,0x01" => "SB: Intel 82801DB A1 (ICH4)",
"0x24c08086,0x02" => "SB: Intel 82801DB B0 (ICH4)",
"0x24d08086" => "SB: Intel 82801E (ICH5)", # two steppings A2/A3, both with same rev 0x02
"0x25a18086" => "SB: Intel 6300ESB (ESB)",
"0x25a18086,0x00" => "SB: Intel 6300ESB A0 (ESB)",
"0x25a18086,0x01" => "SB: Intel 6300ESB A1/A2 (ESB)",
"0x25a18086,0x02" => "SB: Intel 6300ESB A3 (ESB)",
"0x26408086" => "SB: Intel 82801FB/FR (ICH6/R)",
"0x26408086,0x03" => "SB: Intel 82801FB/FR B1 (ICH6/R)",
"0x26408086,0x04" => "SB: Intel 82801FB/FR B2 (ICH6/R)",
"0x26408086,0x05" => "SB: Intel 82801FB/FR C0 (ICH6/R)",
"0x26418086" => "SB: Intel 82801FBM (ICH6M)",
"0x26418086,0x03" => "SB: Intel 82801FBM B1 (ICH6M)", # HP NC6220
"0x26418086,0x04" => "SB: Intel 82801FBM B2 (ICH6M)",
"0x26428086" => "SB: Intel 82801FW (ICH6W)",
"0x26708086" => "SB: Intel 631xESB/632xESB (ESB2)",
"0x26708086,0x00" => "IB: Intel 3100 A0 (Whitmore Lake)",
"0x26708086,0x01" => "IB: Intel 3100 A1 (Whitmore Lake)",
"0x26708086,0x08" => "SB: Intel 631xESB/632xESB A0 (ESB2)",
"0x26708086,0x09" => "SB: Intel 631xESB/632xESB A1 (ESB2)",
"0x27b08086" => "SB: Intel 82801GDH (ICH7DH)",
"0x27b88086" => "SB: Intel 82801GB/GR (ICH7/R)",
"0x27b98086" => "SB: Intel 82801GBM (ICH7M)",
"0x27b98086,0x01" => "SB: Intel 82801GBM A1 (ICH7M)",
"0x27b98086,0x02" => "SB: Intel 82801GBM B0 (ICH7M)",
"0x27bd8086" => "SB: Intel 82801GHM (ICH7MDH)",
"0x27bd8086,0x01" => "SB: Intel 82801GHM A1 (ICH7MDH)",
"0x27bd8086,0x02" => "SB: Intel 82801GHM B0 (ICH7MDH)",
"0x28108086" => "SB: Intel 82801HB/HR (ICH8/R)",
"0x28118086" => "SB: Intel 82801HEM (ICH8M-E)",
"0x28118086,0x02" => "SB: Intel 82801HEM B0 (ICH8M-E)",
"0x28118086,0x03" => "SB: Intel 82801HEM B1 (ICH8M-E)", # HP 6910p
"0x28118086,0x04" => "SB: Intel 82801HEM B2 (ICH8M-E)",
"0x28128086" => "SB: Intel 82801HH (ICH8DH)",
"0x28148086" => "SB: Intel 82801HO (ICH8DO)",
"0x28158086" => "SB: Intel 82801HBM (ICH8M)",
"0x28158086,0x02" => "SB: Intel 82801HBM B0 (ICH8M)",
"0x28158086,0x03" => "SB: Intel 82801HBM B1 (ICH8M)", # MSI GM965
"0x28158086,0x04" => "SB: Intel 82801HBM B2 (ICH8M)",
# search for site:intel.com 2912h
"0x29128086" => "SB: Intel 82801IH (ICH9H)", # Home: +AHCI -RAID
"0x29148086" => "SB: Intel 82801IO (ICH9O)", # Office: +AHCI +RAID
"0x29168086" => "SB: Intel 82801IR (ICH9R)", # Raid: +AHCI +RAID
"0x29178086" => "SB: Intel 82801IBM (ICH9M)", # Base Moble:
"0x29178086,0x02" => "SB: Intel 82801IBM A2 (ICH9M)",
"0x29178086,0x03" => "SB: Intel 82801IBM A3 (ICH9M)",
"0x29188086" => "SB: Intel 82801IB (ICH9)", # Base: -AHCI -RAID
"0x29198086" => "SB: Intel 82801IEM (ICH9M-E)", # Enhanced Moble:
"0x29198086,0x02" => "SB: Intel 82801IEM A2 (ICH9M-E)",
"0x29198086,0x03" => "SB: Intel 82801IEM A3 (ICH9M-E)",
"0x3a168086" => "SB: Intel 82801JIR (ICH10R)", # Raid:
"0x3a188086" => "SB: Intel 82801JIB (ICH10)", # Base:
# Intel North
"0x12378086" => "NB: Intel 440FX (Natoma)",
"0x71908086" => "NB: Intel 440BX",
"0x71928086" => "NB: Intel 440BX",
"0x71a08086" => "NB: Intel 440GX",
"0x84ca8086" => "NB: Intel 450NX", # Compaq 6400R
"0x71248086" => "NB: Intel 810E (Whitney)",
"0x11308086" => "NB: Intel 815E (Solano)", # SM P3TSSR
"0x25018086" => "NB: Intel 820 (Camino)",
"0x1a308086" => "NB: Intel 845 (Brookdale)", # HP D500
"0x25608086" => "NB: Intel 845G (Brookdale)", # HP D510
"0x25708086" => "NB: Intel 865 (Springdale)", # HP D530, HP DC5000, Dell GX270
"0x25788086" => "NB: Intel 875P (Canterwood)", # Intel S875WP1, PE750
"0x25808086" => "NB: Intel 915 (Grantsdale)", # HP DC5100, HP DX6120, HP DC7100
"0x27708086" => "NB: Intel 945 (Lakeport)", #
"0x27708086,0x02" => "NB: Intel 945G (Lakeport)", # Dell GX620, HP DC7600
"0x27708086,0x81" => "NB: Intel 945P (Lakeport)", #
"0x27708086,0x82" => "NB: Intel 945PL (Lakeport)", #
"0x29708086" => "NB: Intel 946GZ (Lakeport G)", # SM PDSBM
"0x29908086" => "NB: Intel Q963/Q965 (Broadwater)", # HP DC5700
"0x29f08086" => "NB: Intel 3200 (Bigby)", # Dell R200, DL120 G5
"0x25888086" => "NB: Intel E7221 (Copper River)", # DL320 G3
"0x27788086" => "NB: Intel E7230 (Mukilteo)", #
"0x27788086,0x00" => "NB: Intel E7230 (Mukilteo)", # PE850, DL320 G4, Intel S3000PT, DL320 G5, IR1250
"0x27788086,0xc0" => "NB: Intel 3000 A0 (Mukilteo 2)", # SM PDSML
"0x25408086" => "NB: Intel E7500 (Plumas)",
"0x25408086,0x02" => "NB: Intel E7500 A2 (Plumas)", # SM P4DP6
"0x25408086,0x03" => "NB: Intel E7500 A3 (Plumas)", # SM P4DP6, Tyan i7500 (S2722)
"0x254c8086" => "NB: Intel E7501 (Plumas)", # Intel SE7501CW2
"0x35908086" => "NB: Intel E7520 (Lindenhurst)", # PE2850, DL360 G4, DL380 G4
"0x35908086,0x09" => "NB: Intel E7520 C1 (Lindenhurst)",
"0x35908086,0x0a" => "NB: Intel E7520 C2 (Lindenhurst)",
"0x35908086,0x0c" => "NB: Intel E7520 C4 (Lindenhurst)",
"0x35928086" => "NB: Intel E7320 (Lindenhurst VS)",
"0x35928086,0x09" => "NB: Intel E7320 C1 (Lindenhurst VS)",
"0x35928086,0x0a" => "NB: Intel E7320 C2 (Lindenhurst VS)",
"0x35928086,0x0c" => "NB: Intel E7320 C4 (Lindenhurst VS)", # Intel SE7320VP2
"0x26008086" => "NB: Intel E8500 (Twin Castle)",
"0x26008086,0x10" => "NB: Intel E8500 B0 (Twin Castle)", # PE6850, DL580 G4
"0x26008086,0x11" => "NB: Intel E8500 B1 (Twin Castle)",
"0x25c08086" => "NB: Intel 5000X (Greencreek)", # PE2950, PE1950, DL140 G3, SM X7DAL
"0x25c08086,0x12" => "NB: Intel 5000X B2 (Greencreek)",
"0x25c08086,0x13" => "NB: Intel 5000X B3 (Greencreek)",
"0x25c08086,0x30" => "NB: Intel 5000X G0 (Greencreek)",
"0x25c08086,0x31" => "NB: Intel 5000X G1 (Greencreek)",
"0x25d08086" => "NB: Intel 5000Z (Blackford)",
"0x25d08086,0x93" => "NB: Intel 5000Z B3 (Blackford)",
"0x25d48086" => "NB: Intel 5000V (Blackford VS)", # SM X7DVL-E, X7DVL-L, DL180
"0x25d48086,0x92" => "NB: Intel 5000V B2 (Blackford VS)",
"0x25d48086,0x93" => "NB: Intel 5000V B3 (Blackford VS)",
"0x25d48086,0xb1" => "NB: Intel 5000V G1 (Blackford VS)",
"0x25d88086" => "NB: Intel 5000P (Blackford)", # Intel S5000PSL, PE1955, SM X7DBU, SM X7DBi+
"0x25d88086,0x92" => "NB: Intel 5000P B2 (Blackford)",
"0x25d88086,0x93" => "NB: Intel 5000P B3 (Blackford)",
"0x25d88086,0xb1" => "NB: Intel 5000P G1 (Blackford)",
"0x29c08086" => "NB: Intel G31/G33/P31/P35 (Bearlake)", # Gigabyte P35-S3G, Gigabyte G33M-S2L
"0x29d08086" => "NB: Intel Q33 (Bearlake)", # HP DC5800
"0x29e08086" => "NB: Intel X38/X48 (Bearlake)", # Intel X38ML
"0x2e208086" => "NB: Intel P45 (Eaglelake)", # Gigabyte EP45-DS3R
"0x65c08086" => "NB: Intel 5100 (San Clemente)",
"0x65c08086,0x80" => "NB: Intel 5100 A0 (San Clemente)", # DL180 G5
"0x65c08086,0x90" => "NB: Intel 5100 B0 (San Clemente)", # Dell R300, SM X7DCL, SM X7DCA-L, HP BL260c G5
"0x40018086" => "NB: Intel 5400A (Seaburg)",
"0x40018086,0x20" => "NB: Intel 5400A C0 (Seaburg)",
"0x40038086" => "NB: Intel 5400B (Seaburg)",
"0x40038086,0x20" => "NB: Intel 5400B C0 (Seaburg)", # Intel S5400SF, DL160 G5
"0x36008086" => "NB: Intel 7300 (Clarksboro)",
"0x36008086,0x01" => "NB: Intel 7300 A1 (Clarksboro)", # DL580 G5, Intel S7000FC4UR
# ServerWorks Intel South
# http://www.broadcom.com/products/Enterprise-Networking/SystemI-O-Products
"0x02001166" => "SB: ServerWorks OSB4",
"0x02011166" => "SB: ServerWorks CSB5",
"0x02031166" => "SB: ServerWorks CSB6",
# ServerWorks Intel North
# http://www.broadcom.com/products/Enterprise-Networking/SystemI-O-Products
"0x00081166" => "NB: ServerWorks HE-SL", # DL360 G2, DL380 G2, PE2550
"0x00091166" => "NB: ServerWorks LE", # DL320, DL360
"0x00111166" => "NB: ServerWorks GC-HE", # DL580 G2, PE6650
"0x00121166" => "NB: ServerWorks GC-LE", # DL360 G3, DL380 G3 (rev 13), DL560 G1
"0x00141166" => "NB: ServerWorks GC-LE", # DL360 G3, DL380 G3 (rev 33)
"0x00171166" => "NB: ServerWorks GC-SL", # DL140, DL320 G2
# AMD
"0x59501002" => "SB: ATI Radeon Xpress 200", # HP DX5150
"0x74501022" => "NB: AMD 8131 PCI-X", # DL145 G1, DL385 G1, DL585
"0x74581022" => "NB: AMD 8132 PCI-X 2.0", # DL585 G2
"0x74681022" => "SB: AMD 8111 I/O Hub", # Tyan S2875, DL585
"0x005e10de" => "SB: nVIDIA nForce Professional 2200", # DL145 G2, DL585 G2
"0x036910de" => "SB: nVIDIA nForce Professional 3600", # IR2400
"0x075410de" => "SB: nVIDIA GeForce 8200", # Asus M3N78-VM
"0x06501039" => "SB: SiS 650GX", # ASUS P4SGX-MX
"0x03361106" => "NB: VIA K8M890", # north - HP DX2255
"0x31881106" => "NB: VIA K8T800", # north
"0x32271106" => "SB: VIA VT8237", # south
"0x33371106" => "SB: VIA VT8237A", # south - HP DX2255
# ServerWorks AMD
# http://www.broadcom.com/products/Enterprise-Networking/SystemI-O-Products
"0x02341166" => "ServerWorks HT-1000", # PE6950, PE2970, DL145 G3, DL365 G1, DL385 G2
# Intel Mobile
"0x25908086" => "NB: Intel 915GM (Alviso)", # NC6220
"0x27a08086" => "NB: Intel 945GM (Calistoga)", # NC6400
"0x2a008086" => "NB: Intel PM965/GM965 (Crestline)", # HP 6910p, MSI GM965, AOpen i965GMt-LA
);
my(%pci_classes) = (
# pciutils-2.2.4/lib/header.h
"0x0100" => "Disk-Control", # SCSI
"0x0101" => "Disk-Control", # IDE
"0x0104" => "Disk-Control", # RAID
"0x0105" => "Disk-Control", # ATA
"0x0106" => "Disk-Control", # SATA
"0x0107" => "Disk-Control", # SAS
"0x0180" => "Disk-Control", # Other
"0x0200" => "Network", # Ethernet
"0x0280" => "Network", # Other (e.g. wireless)
"0x0c04" => "Disk-Control", # FC
# "0x0c05" => "SMBus", # SMBus
"0x0c06" => "Network", # InfiniBand
"0x1000" => "Crypto", # Crypt Network
);
my(%pci_devices) = (
# http://www.pcidatabase.com/
# http://www.pcidatabase.com/reports.php?type=tab-delimeted
# http://pciids.sourceforge.net/pci.ids
# 0e11 - Compaq
# 1000 - Symbios/LSI - http://en.wikipedia.org/wiki/Symbios_Logic
# 1002 - ATI
# 100b - National Semiconductor
# 1014 - IBM
# 1022 - AMD
# 1028 - Dell
# 1033 - NEC
# 103c - HP
# 1044 - DPT/Adaptec
# 1069 - Mylex
# 1077 - QLogic
# 107b - Gateway
# 108e - Sun
# 10b7 - 3com
# 10df - Emulex
# 10f1 - Tyan
# 1095 - Silicon Image
# 1148 - SysKonnect
# 1166 - Serverworks
# 1170 - Inventec
# 11ab - Marvell
# 11ad - Netgear
# 13c1 - 3ware
# 1458 - Gigabyte
# 1462 - MSI
# 14c1 - Myricom
# 14e4 - Broadcom
# 152d - Quanta
# 15ad - VMware
# 161f - Arima (Rioworks)
# 17c2 - Newisys
# 1749 - RLX
# 8086 - Intel
# 9004 - Adaptec
# 9005 - Adaptec
# a0a0 - AOpen
'network' => {
"0xf0041385,0x000211ad,0x20" => "Netgear FA310TX 10/100", # Adapter
"0x20001022,0x20001022,0x10" => "AMD 79C971 Lance/PCnet 10/100", # VMware
"0x20001022,0x20001022,0x40" => "AMD 79C971 Lance/PCnet 10/100", # VirtualBox
"0x000914c1,0x000814c1,0x00" => "Myricom Myri-10G", # Adapter
"0x00000000,0x0035100b,0x30" => "NatSemi DP83065 Gigabit",
"0x21001148,0x9e001148,0x12" => "SysKonnect 9E21 Gigabit", # SysKonnect 9E21 Server Adapter
"0x811a1043,0x432011ab,0x14" => "Asus/Marvell Yukon 88E8001 Gigabit", # Asus P5Q-Deluxe
"0x502111ab,0x436111ab,0x16" => "Marvell Yukon 88E8050 Gigabit", # Intel SE7320VP2
"0x50218086,0x436111ab,0x17" => "Intel/Marvell Yukon 88E8050 Gigabit", # Intel SE7320VP2, SE7520BD2
"0x34398086,0x436111ab,0x18" => "Intel/Marvell Yukon 88E8050 Gigabit", # Intel SE7520BB2
"0x826e1043,0x436411ab,0x12" => "Asus/Marvell Yukon 88E8056 Gigabit", # Asus P5BV-C
"0x81f81043,0x436411ab,0x12" => "Asus/Marvell Yukon 88E8056 Gigabit", # Asus P5Q-Deluxe
"0xe0001458,0x813610ec,0x01" => "Gigabyte/RealTek RTL8101E 10/100", # Gigabyte 945GCM-S2C
"0x00018086,0x813610ec,0x02" => "Intel/RealTek RTL8102EL 10/100", # Intel D945GCLF
"0x????????,0x813910ec,0x10" => "RealTek 8139 10/100",
"0x03231154,0x813910ec,0x10" => "RealTek 8139 10/100",
"0x813910ec,0x813910ec,0x10" => "RealTek 8139 10/100",
"0x81091043,0x813910ec,0x10" => "Asus/RealTek 8100C 10/100", # Asus P4GE-MX
"0x301e103c,0x813910ec,0x10" => "HP/RealTek 8100C 10/100", # HP DX2180
"0x3024103c,0x813910ec,0x10" => "HP/RealTek 8100C 10/100", # HP DX2255
"0x3022103c,0x816710ec,0x10" => "HP/RealTek RTL8110SX Gigabit", # HP DX2280
"0xe0001458,0x816810ec,0x01" => "Gigabyte/RealTek 8111C Gigabit", # Gigabyte P35-S3G, Gigabyte G33M-S2L
"0xe0001458,0x816810ec,0x02" => "Gigabyte/RealTek 8111C Gigabit", # Gigabyte EP45-DS3R
"0x063ea0a0,0x816810ec,0x02" => "AOpen/RealTek 8111C Gigabit", # AOpen i965GMt-LA
"0x3022103c,0x816910ec,0x10" => "HP/RealTek RTL8110SX Gigabit", # HP DX2280
"0x301f103c,0x816910ec,0x10" => "HP/RealTek RTL8110SX Gigabit", # HP D290
"0x100010b7,0x920010b7,0x74" => "3Com 3c905C-TX 10/100",
"0x00fe1028,0x920010b7,0x78" => "Dell/3Com 3c905C-TX 10/100", # Dell OptiPlex GX240
"0x00b41028,0x920010b7,0x78" => "Dell/3Com 3c905C-TX 10/100", #
"0x00d81028,0x920010b7,0x78" => "Dell/3Com 3c905C-TX 10/100", # Dell 530
"0x00261170,0x037310de,0xa3" => "Inventec/nVIDIA MCP55 Gigabit", # IR2400
"0x286510f1,0x005710de,0xa3" => "Tyan/nVIDIA nForce CK8-04 Gigabit", # Tyan S2865
"0x5348108e,0x005710de,0xa3" => "Sun/nVIDIA nForce CK8-04 Gigabit", # Sun X2100
# Broadcom
"0x3011103c,0x160014e4,0x01" => "HP/Broadcom BCM5752 Gigabit", # HP DC7600
"0x037c1014,0x163914e4,0x01" => "IBM/Broadcom BCM5709 Gigabit", # IBM x3850 M2
"0x00d11028,0x164414e4,0x10" => "Dell/Broadcom BCM5700 Gigabit", # PE2550
"0x00d11028,0x164414e4,0x12" => "Dell/Broadcom BCM5700 Gigabit", # PE2550
"0x01091028,0x164414e4,0x14" => "Dell/Broadcom BCM5700 Gigabit", # PE6650
"0x????????,0x164514e4,0x15" => "Broadcom BCM5701 Gigabit",
"0x01211028,0x164514e4,0x15" => "Dell/Broadcom BCM5701 Gigabit", # PE2650
"0x007c0e11,0x164514e4,0x15" => "Compaq/Broadcom BCM5701 Gigabit", # DL580 G2
"0x00c10e11,0x164514e4,0x15" => "HP NC6770/Broadcom BCM5701 Gigabit", # HP NC6770 Adapter
"0x00850e11,0x164514e4,0x15" => "Compaq/Broadcom BCM5701 Gigabit", # DL360 G2
"0x100410b7,0x164514e4,0x15" => "3Com/Broadcom BCM5701 Gigabit-SX", # 3Com 3C996-SX
"0x100610b7,0x164514e4,0x15" => "3Com/Broadcom BCM5701 Gigabit", # 3Com 3C996B-T
"0x????????,0x164814e4,0x??" => "Broadcom BCM5704C Gigabit",
"0x164814e4,0x164814e4,0x00" => "Broadcom BCM5704C Gigabit", # DL380 G4
"0x014a1028,0x164814e4,0x02" => "Dell/Broadcom BCM5704C Gigabit", # PE1750
"0x164814e4,0x164814e4,0x02" => "Broadcom BCM5704C Gigabit", # DL140
"0x36c01022,0x164814e4,0x02" => "AMD/Broadcom BCM5704C Gigabit", # DL145 G1
"0x001017c2,0x164814e4,0x03" => "Newisys/Broadcom BCM5704C Gigabit", # V20z
"0x164814e4,0x164814e4,0x03" => "Broadcom BCM5704C Gigabit", # Tyan S4882, Tyan S4881
"0x164414e4,0x164814e4,0x03" => "Broadcom BCM5704C Gigabit", # Tyan S2882, Tyan S2881, Tyan S2880, Tyan S4882
"0x36c01022,0x164814e4,0x03" => "AMD/Broadcom BCM5704C Gigabit", # DL145 G1
"0x16481022,0x164814e4,0x03" => "AMD/Broadcom BCM5704C Gigabit", # DL145 G1
"0x16101462,0x164814e4,0x03" => "MSI/Broadcom BCM5704C Gigabit", # MSI ???
"0x24501462,0x164814e4,0x03" => "MSI/Broadcom BCM5704C Gigabit", # MSI 8480000
"0x00d00e11,0x164814e4,0x10" => "HP/Broadcom BCM5704C Gigabit", # DL360 G4, DL380 G4, DL 385, DL 585
"0x310f103c,0x164814e4,0x10" => "HP/Broadcom BCM5704C Gigabit", # DL185 G5
"0x01701028,0x164814e4,0x10" => "Dell/Broadcom BCM5704C Gigabit", # PE6850
"0x164414e4,0x164814e4,0x10" => "Broadcom BCM5704C Gigabit", # Tyan S2882, Tyan S2880
"0x164814e4,0x164814e4,0x10" => "Broadcom BCM5704C Gigabit", # Arima HDAMA-I
"0x1709103c,0x164a14e4,0x02" => "HP/Broadcom BCM5706 Gigabit", # DL585 G2, DL580 G4
"0x????????,0x164c14e4,0x??" => "Broadcom BCM5708 Gigabit", #
"0x164c14e4,0x164c14e4,0x10" => "Broadcom BCM5708 Gigabit", # Tyan S2865
"0x7038103c,0x164c14e4,0x11" => "HP/Broadcom BCM5708 Gigabit", # DL360 G5, DL380 G5, DL365 G1
"0x01b31028,0x164c14e4,0x11" => "Dell/Broadcom BCM5708 Gigabit", # PE1950
"0x01b21028,0x164c14e4,0x11" => "Dell/Broadcom BCM5708 Gigabit", # PE2950
"0x03421014,0x164c14e4,0x11" => "IBM/Broadcom BCM5708 Gigabit", # IBM x3550
"0x164c14e4,0x164c14e4,0x12" => "Broadcom BCM5708 Gigabit", # Adapter?
"0x01b31028,0x164c14e4,0x12" => "Dell/Broadcom BCM5708 Gigabit", # PE1950
"0x01b21028,0x164c14e4,0x12" => "Dell/Broadcom BCM5708 Gigabit", # PE2950
"0x7037103c,0x164c14e4,0x12" => "HP NC373T/Broadcom BCM5708 Gigabit", # HP NC373T Adapter
"0x7038103c,0x164c14e4,0x12" => "HP NC373i/Broadcom BCM5708 Gigabit", # DL360 G5, DL380 G5, DL365 G1, DL385 G2, DL580 G5
"0x01ea1028,0x164c14e4,0x12" => "Dell/Broadcom BCM5708 Gigabit", # PE6950
"0x01f01028,0x164c14e4,0x12" => "Dell/Broadcom BCM5708 Gigabit", # Dell R900
"0x02051028,0x164c14e4,0x12" => "Dell/Broadcom BCM5708 Gigabit", # PE2970
"0x86531028,0x165314e4,0x01" => "Dell/Broadcom BCM5705 Gigabit",
"0x3100103c,0x165414e4,0x03" => "HP NC1020/Broadcom BCM5705 Gigabit", # HP NC1020 Adapter
"0x????????,0x165914e4,0x??" => "Broadcom BCM5721 Gigabit",
"0x165914e4,0x165914e4,0x00" => "Broadcom BCM5721 Gigabit",
"0x165914e4,0x165914e4,0x01" => "Broadcom BCM5721 Gigabit", # Gigabyte 9ILDR !!! FreeBSD 6 says 5750
"0x01b61028,0x165914e4,0x11" => "Dell/Broadcom BCM5721 Gigabit", # PE850
"0x01e61028,0x165914e4,0x11" => "Dell/Broadcom BCM5721 Gigabit", # PE860
"0x165914e4,0x165914e4,0x11" => "Broadcom BCM5721 Gigabit", # Inventec Tuna, Tyan S2865, Inventec IR2100
"0x00221170,0x165914e4,0x11" => "Inventec/Broadcom BCM5721 Gigabit", # IR1250
"0x1659103c,0x165914e4,0x11" => "HP/Broadcom BCM5721 Gigabit", # DL140 G2
"0x3209103c,0x165914e4,0x11" => "HP/Broadcom BCM5721 Gigabit", # DL145 G2
"0x3260103c,0x165914e4,0x11" => "HP/Broadcom BCM5721 Gigabit", # DL140 G3
"0x81491043,0x165914e4,0x11" => "Asus/Broadcom BCM5721 Gigabit", # Asus K8N-DRE
"0x5348108e,0x165914e4,0x11" => "Sun/Broadcom BCM5721 Gigabit", # Sun X2100
"0x02c61014,0x165914e4,0x11" => "IBM/Broadcom BCM5721 Gigabit", # IBM 306m
"0x81491043,0x165914e4,0x21" => "Asus/Broadcom BCM5721 Gigabit", # Asus K8N-DRE
"0x01eb1028,0x165914e4,0x21" => "Dell/Broadcom BCM5721 Gigabit", # SC1435 !!! FreeBSD 6 says 5750
"0x023c1028,0x165914e4,0x21" => "Dell/Broadcom BCM5721 Gigabit", # Dell R200
"0x020f1028,0x165a14e4,0x00" => "Dell/Broadcom BCM5722 Gigabit", # Dell R300
"0x7051103c,0x165a14e4,0x00" => "HP/Broadcom BCM5722 Gigabit", # DL180 G5, DL120 G5, DL160 G5
"0x7039103c,0x166814e4,0xa3" => "HP/Broadcom BCM5714 Gigabit", # DL320 G5
"0x????????,0x167714e4,0x??" => "Broadcom BCM5751 Gigabit",
"0x3005103c,0x167714e4,0x01" => "HP/Broadcom BCM5751 Gigabit", # HP DC5100, HP DC7100
"0x3006103c,0x167714e4,0x01" => "HP/Broadcom BCM5751 Gigabit", # HP DC5100 (PT005AW)
"0x00221170,0x167714e4,0x11" => "Inventec/Broadcom BCM5751 Gigabit", # IR1250
"0x3009103c,0x167714e4,0x20" => "HP/Broadcom BCM5751 Gigabit", # HP DX5150
"0x01791028,0x167714e4,0x01" => "Dell/Broadcom BCM5751 Gigabit", # Dell GX280
"0x01ad1028,0x167714e4,0x01" => "Dell/Broadcom BCM5751 Gigabit", # Dell GX620
"0x01821028,0x167714e4,0x01" => "Dell/Broadcom BCM5751 Gigabit", # Dell Latitude D610
"0x????????,0x167814e4,0xa3" => "Broadcom BCM5715 Gigabit",
"0x167814e4,0x167814e4,0xa3" => "Broadcom BCM5715 Gigabit", # Huawei Tecal
"0x703e103c,0x167814e4,0xa3" => "HP/Broadcom BCM5715 Gigabit", # DL145 G3
"0x8959152d,0x167814e4,0xa3" => "Quanta/Broadcom BCM5715 Gigabit", # Quanta S47
"0x703c103c,0x167914e4,0xa3" => "HP/Broadcom BCM5715S Gigabit", # HP BL480c G1, HP BL260c G5, HP NC326i Adapter
"0x2808103c,0x167b14e4,0x02" => "HP/Broadcom BCM5755 Gigabit", # HP DC5700
"0x000c103c,0x169614e4,0x03" => "HP/Broadcom BCM5782 Gigabit", #
"0x12bc103c,0x169614e4,0x03" => "HP/Broadcom BCM5782 Gigabit", # HP DC5000, HP D530
"0x0944103c,0x167d14e4,0x11" => "HP/Broadcom BCM5751M Gigabit", # HP NC6220
"0x000c14e4,0x16a614e4,0x02" => "Broadcom BCM5702 Gigabit", # Arima HDAMA
"0x00bb0e11,0x16a614e4,0x02" => "HP/Broadcom BCM5702 Gigabit", # DL320 G2
"0x800914e4,0x16a614e4,0x02" => "Broadcom BCM5702 Gigabit", # AMD Melody
"0x01211028,0x16a714e4,0x02" => "Dell/Broadcom BCM5703 Gigabit", # PE2650
"0x00cb0e11,0x16a714e4,0x02" => "HP/Broadcom BCM5703 Gigabit", # DL360 G3, DL380 G3, DL180, DL560 G1
"0x001017c2,0x16a714e4,0x02" => "Newisys/Broadcom BCM5703 Gigabit", # V20z
"0x002017c2,0x16a714e4,0x02" => "Newisys/Broadcom BCM5703 Gigabit", # V40z
"0x00ca0e11,0x16c714e4,0x10" => "HP NC7771/Broadcom BCM5703 Gigabit", # HP NC7771 adapter
"0x03011014,0x16a814e4,0x10" => "IBM/Broadcom BCM5704S Gigabit", # IBM eServer BladeCenter LS20
"0x01bb1028,0x16ac14e4,0x12" => "Dell/Broadcom BCM5708S Gigabit", # PE1955
"0x703b103c,0x16ac14e4,0x12" => "HP/Broadcom BCM5708S Gigabit", # HP BL460c G1, HP BL480c G1, HP SB600c
"0x30ad103c,0x16fd14e4,0x21" => "HP/Broadcom BCM5753M Gigabit", # HP NC6400
# Intel
# http://support.intel.com/support/network/sb/cs-008441.htm
"0x004a0e11,0x10018086,0x02" => "HP NC6136/Intel 82543GC Gigabit", # HP NC6136 adapter
"0x10048086,0x10048086,0x02" => "Intel 82543GC Gigabit", # Intel PRO/1000 T Server Adapter
"0x011b1028,0x10088086,0x02" => "Dell/Intel 82544EI Gigabit", # PE1650
"0x21201749,0x10088086,0x02" => "RLX/Intel 82544EI Gigabit", # RLX ServerBlade
"0x11078086,0x10088086,0x02" => "Intel 82544EI Gigabit", # Intel PRO/1000 XT Server Adapter
"0x34128086,0x100d8086,0x02" => "Intel 82544GC Gigabit", # Intel SRSH4
"0x????????,0x100e8086,0x02" => "Intel 82540EM Gigabit",
"0x004e8086,0x100e8086,0x02" => "Intel 82540EM Gigabit", # SM P4SGR
"0x34188086,0x100e8086,0x02" => "Intel 82540EM Gigabit", # Intel SE7501BR2
"0x34258086,0x100e8086,0x02" => "Intel 82540EM Gigabit", # Intel SE7501CW2
"0x002e8086,0x100e8086,0x02" => "Intel 82540EM Gigabit", # Intel adapter
"0x892d152d,0x100e8086,0x02" => "Quanta/Intel 82540EM Gigabit", # SU2-4200
"0x01341028,0x100e8086,0x02" => "Dell/Intel 82540EM Gigabit", # SU2-4200
"0x01351028,0x100e8086,0x02" => "Dell/Intel 82540EM Gigabit", # Dell 1600SC
"0x01511028,0x100e8086,0x02" => "Dell/Intel 82540EM Gigabit", # Dell GX270
"0x01381028,0x100e8086,0x02" => "Dell/Intel 82540EM Gigabit", # Dell SX260
"0x10018086,0x100f8086,0x01" => "Intel 82545EM Gigabit", # Tyan S2722
"0x075015ad,0x100f8086,0x01" => "VMware/Intel 82545EM Gigabit", #
"0x????????,0x10108086,0x01" => "Intel 82546EB Gigabit",
"0x00db0e11,0x10108086,0x01" => "HP NC7170/Intel 82546EB Gigabit", # HP NC7170 adapter
"0x10128086,0x10108086,0x01" => "Intel 82546EB Gigabit", # Intel PRO/1000 MT Server Adapter
"0x34158086,0x10108086,0x01" => "Intel 82546EB Gigabit", # Intel SE7500WV2
"0x34168086,0x10108086,0x01" => "Intel 82546EB Gigabit", # Intel SE7500WV2A
"0x341a8086,0x10108086,0x01" => "Intel 82546EB Gigabit", # Intel SE7501WV2S
"0x341b8086,0x10108086,0x01" => "Intel 82546EB Gigabit", # Intel SE7501WV2A
"0x10118086,0x10108086,0x01" => "Intel 82546EB Gigabit", # SM X5DP8
"0x10138086,0x10138086,0x00" => "Intel 82541EI Gigabit", # Tyan S2875
"0x34288086,0x10198086,0x00" => "Intel 82547EI Gigabit", # Intel S875WP1
"0x10018086,0x10268086,0x04" => "Intel 82545GM Gigabit", # Intel PRO/1000 MT Server Adapter
"0x10028086,0x10268086,0x04" => "Intel 82545GM Gigabit", # Intel PRO/1000 MT Server Adapter
"0x30001458,0x10268086,0x04" => "Gigabyte/Intel 82545GM Gigabit", # Gigabyte GA-7A8DRH
"0x00120e11,0x103b8086,0x81" => "Compaq/Intel 82801DB ICH4 10/100 VM", # HP D510
"0x30be103c,0x10498086,0x03" => "Intel 82566MM Gigabit", # HP 6910p
"0x30c1103c,0x10498086,0x03" => "Intel 82566MM Gigabit", # HP 6910p
"0x00008086,0x104b8086,0x03" => "Intel 82566DC Gigabit", # MSI GM965
"0x34288086,0x10508086,0x01" => "Intel 82562ET 10/100", # Intel S875WP1
"0x????????,0x105e8086,0x06" => "Intel 82571EB Gigabit",
"0x115e8086,0x105e8086,0x06" => "Intel 82571EB Gigabit", # Intel PRO/1000 PT Server Adapter
"0x125e8086,0x105e8086,0x06" => "Intel 82571EB Gigabit", # Intel PRO/1000 PT Server Adapter
"0x135e8086,0x105e8086,0x06" => "Intel 82571EB Gigabit", # Intel PRO/1000 PT Server Adapter
"0x7044103c,0x105e8086,0x06" => "HP NC360T/Intel 82571EB Gigabit", # HP NC360T adapter
"0x30548086,0x10648086,0x01" => "Intel 82562EZ 10/100", # Intel D915GAG
"0x305d8086,0x10648086,0x01" => "Intel 82562EZ 10/100", # Intel D915GUX
"0x01651028,0x10758086,0x00" => "Dell/Intel 82547GI Gigabit", # PE750
"0x10761458,0x10768086,0x00" => "Gigabyte/Intel 82541GI Gigabit", # Gigabyte GA-7A8DRH
"0x????????,0x10768086,0x05" => "Intel 82541PI Gigabit", #
"0x347e8086,0x10768086,0x05" => "Intel 82541PI Gigabit", # Intel SE7520BB2
"0x016d1028,0x10768086,0x05" => "Dell/Intel 82541PI Gigabit", # PE1850, PE2850
"0x019a1028,0x10768086,0x05" => "Dell/Intel 82541PI Gigabit", # SC1425
"0x30a18086,0x10768086,0x05" => "Intel 82541PI Gigabit", # Intel SE7230NH1LX
"0x34398086,0x10768086,0x05" => "Intel 82541PI Gigabit", # Intel SE7520BD2
"0x34448086,0x10768086,0x05" => "Intel 82541PI Gigabit", # Intel SE7320VP2
"0x34508086,0x10768086,0x05" => "Intel 82541PI Gigabit", # Intel SE7320VP2
"0x348d8086,0x10768086,0x05" => "Intel 82541GI Gigabit", # Intel AspenHill
"0x01651028,0x10768086,0x00" => "Dell/Intel 82541GI Gigabit", # PE750
"0x????????,0x10798086,0x03" => "Intel 82546GB Gigabit",
"0x10798086,0x10798086,0x03" => "Intel 82546GB Gigabit", # Intel SE7520JR2
"0x11798086,0x10798086,0x03" => "Intel 82546GB Gigabit", # Intel PRO/1000 MT Server Adapter
"0x118a8086,0x10798086,0x03" => "Intel 82546GB Gigabit", # Intel Server Adapter
"0x018a1028,0x107b8086,0x03" => "Dell/Intel 82546GB Gigabit", # PE1855
"0x10828086,0x107d8086,0x06" => "Intel 82572EI Gigabit", # Intel PRO/1000 PT Server Adapter
"0x????????,0x108b8086,0x03" => "Intel 82573V Gigabit",
"0x349b8086,0x108b8086,0x03" => "Intel 82573V Gigabit", # Intel Coretta, S3000PT
"0x00008086,0x108b8086,0x03" => "Intel 82573V Gigabit", # Quanta QSSC-295MB, DCS S45
"0x00001458,0x108b8086,0x03" => "Gigabyte/Intel 82573V Gigabit", # Gigabyte R116
"0x521110f1,0x108b8086,0x03" => "Tyan/Intel 82573V Gigabit", # Tyan S5376
"0x????????,0x108c8086,0x03" => "Intel 82573E Gigabit",
"0x30a28086,0x108c8086,0x03" => "Intel 82573E Gigabit", # Intel SE7230NH1LX
"0x348d8086,0x108c8086,0x03" => "Intel 82573E Gigabit", # Intel AspenHill
"0x349b8086,0x108c8086,0x03" => "Intel 82573E Gigabit", # Intel Coretta, S3000PT
"0x108c15d9,0x108c8086,0x03" => "Supermicro/Intel 82573E Gigabit", # SM X6DLP, SM X7DCL-3, SM X7DCT
"0x????????,0x10968086,0x01" => "Intel 82563EB Gigabit",
"0x00008086,0x10968086,0x01" => "Intel 82563EB Gigabit", # Tyan S5397
"0x346c8086,0x10968086,0x01" => "Intel 82563EB Gigabit", # Intel S5000PAL
"0x34768086,0x10968086,0x01" => "Intel 82563EB Gigabit", # Intel S5000PSL
"0x34848086,0x10968086,0x01" => "Intel 82563EB Gigabit", # Intel S5000VSA
"0x34d48086,0x10968086,0x01" => "Intel 82563EB Gigabit", # Intel S5400SF
"0x000015d9,0x10968086,0x01" => "Supermicro/Intel 82563EB Gigabit", # SM X7DB8, X7DVL-E, X7DVL-L
"0x109615d9,0x10968086,0x01" => "Supermicro/Intel 82563EB Gigabit", # SM X7DBR, X7DBi+
"0x8949152d,0x10968086,0x01" => "Quanta/Intel 82563EB Gigabit", # DCS S29, DCS S58
"0x34cc8086,0x10968086,0x01" => "Intel 82563EB Gigabit", # Intel Tigerton
"0x00231170,0x10968086,0x01" => "Inventec/Intel 82563EB Gigabit", # eslim, Inventec Seabream
"0x003a1170,0x10968086,0x01" => "Inventec/Intel 82563EB Gigabit", # Inventec 5220
"0x83361033,0x10968086,0x01" => "NEC/Intel 82563EB Gigabit", # NEC Express5800/120Ri-2
"0x82171043,0x10968086,0x01" => "Asus/Intel 82563EB Gigabit", # IBM dx340
"0x00008086,0x10988086,0x01" => "Intel 82563EB Gigabit", # SM B7DBE
"0x????????,0x109a8086,0x00" => "Intel 82573L Gigabit",
"0x00008086,0x109a8086,0x00" => "Intel 82573L Gigabit", # Rackable S45
"0x109a15d9,0x109a8086,0x00" => "Supermicro/Intel 82573L Gigabit", # SM X6DLP, SM PDSML, SM X7DCA-L, SM X7DCT
"0x80301462,0x109a8086,0x00" => "MSI/Intel 82573L Gigabit", # MSI GM965
"0x83661033,0x109a8086,0x00" => "NEC/Intel 82573L Gigabit", # NEC Express5800/i120Ra-e1
"0x10a48086,0x10a48086,0x06" => "Intel 82571EB Quad Gigabit", # PRO/1000 PT Quad Port Server Adapter
"0x????????,0x10a78086,0x02" => "Intel 82575EB Gigabit",
"0x34ce8086,0x10a78086,0x02" => "Intel 82575EB Gigabit", # Intel X38ML
"0x10a88086,0x10a78086,0x02" => "Intel 82575EB Gigabit", # Intel S7000FC4UR
"0x10a715d9,0x10a78086,0x02" => "Supermicro/Intel 82575EB Gigabit", # SM X8DTN
"0x11998086,0x10b58086,0x03" => "Intel 82546GB Quad Gigabit", # PRO/1000 GT Quad Port Server Adapter
"0x704a103c,0x10b98086,0x06" => "HP NC110T/Intel 82572EI Gigabit", # HP NC110T adapter
"0x704b103c,0x10bc8086,0x06" => "HP NC364T/Intel 82571EB Quad Gigabit", # HP NC364T adapter
"0x????????,0x10bd8086,0x02" => "Intel 82566DM-2 Gigabit",
"0x00008086,0x10bd8086,0x02" => "Intel 82566DM-2 Gigabit", # DCS S45, Quanta QSSC-295MB
"0x281e103c,0x10bd8086,0x02" => "HP/Intel 82566DM-2 Gigabit", # HP DC5800
"0x83661033,0x10bd8086,0x02" => "NEC/Intel 82566DM-2 Gigabit", # NEC Express5800/i120Ra-e1
"0x145a8086,0x10d68086,0x02" => "Intel 82575GB Quad Gigabit", # VT Quad Port Server Adapter
# http://download.intel.com/design/network/manuals/8255X_OpenSDM.pdf
"0x????????,0x12298086,0x01" => "Intel 82557 A 10/100",
"0x00000000,0x12298086,0x01" => "Intel 82557 A 10/100",
"0x????????,0x12298086,0x02" => "Intel 82557 B 10/100",
"0x00018086,0x12298086,0x02" => "Intel 82557 B 10/100",
"0x????????,0x12298086,0x03" => "Intel 82557 C 10/100",
"0x????????,0x12298086,0x04" => "Intel 82558 A 10/100",
"0x????????,0x12298086,0x05" => "Intel 82558 B 10/100",
"0x00088086,0x12298086,0x05" => "Intel 82558 B 10/100",
"0x00098086,0x12298086,0x05" => "Intel 82558 B 10/100", # adapter
"0x10f08086,0x12298086,0x05" => "Intel 82558 B 10/100", # PRO/100+ Dual Port Adapter
"0xb0dd0e11,0x12298086,0x05" => "Compaq NC3131/Intel 82558 B 10/100", # Compaq 6400R
"0x????????,0x12298086,0x06" => "Intel 82559 A 10/100",
"0x????????,0x12298086,0x07" => "Intel 82559 B 10/100",
"0x????????,0x12298086,0x08" => "Intel 82559 C 10/100",
"0x00000000,0x12298086,0x08" => "Intel 82559 C 10/100", # Compaq ML370
"0x000b8086,0x12298086,0x08" => "Intel 82559 C 10/100",
"0x000c8086,0x12298086,0x08" => "Intel 82559 C 10/100", # Tyan S2510
"0x100c8086,0x12298086,0x08" => "Intel 82559 C 10/100", # SM P3TSSR, SM 370SSR
"0x12298086,0x12298086,0x08" => "Intel 82559 C 10/100", # Intel STL2
"0x30008086,0x12298086,0x08" => "Intel 82559 C 10/100", # Quanta SU2, Intel TR440BX
"0x30108086,0x12298086,0x08" => "Intel 82559 C 10/100", # SM P3TSSR
"0x34148086,0x12298086,0x08" => "Intel 82559 C 10/100", # Intel SAI2
"0x009b1028,0x12298086,0x08" => "Dell/Intel 82559 C 10/100", # PE2450, PE2550
"0x00da1028,0x12298086,0x08" => "Dell/Intel 82559 C 10/100", # PE1550
"0x10ca103c,0x12298086,0x08" => "HP/Intel 82559 C 10/100", # HP NetServer
"0x8916152d,0x12298086,0x08" => "Quanta/Intel 82559 C 10/100", # Quanta SU6
"0x8917152d,0x12298086,0x08" => "Quanta/Intel 82559 C 10/100", # Gateway 7450R, Quanta SU2-3000
"0xb1340e11,0x12298086,0x08" => "Compaq NC3163/Intel 82559 C 10/100", # DL320, DL360, DL380 G2, ML530 G2
"0xb1440e11,0x12298086,0x08" => "Compaq NC3123/Intel 82559 C 10/100", # Compaq NC3123 adapter
"0x????????,0x12298086,0x09" => "Intel 82559ER A 10/100",
"0x10128086,0x12298086,0x09" => "Intel 82559ER A 10/100", # PRO/100 S Server Adapter
"0x????????,0x12298086,0x0c" => "Intel 82550 10/100",
"0x00408086,0x12298086,0x0c" => "Intel 82550 10/100", # PRO/100 S Desktop Adapter
"0x????????,0x12298086,0x0d" => "Intel 82550 10/100",
"0x10508086,0x12298086,0x0d" => "Intel 82550 10/100", # SM P4DP6
"0x301a8086,0x12298086,0x0d" => "Intel 82550 10/100", # Intel S845WD1
"0x340f8086,0x12298086,0x0d" => "Intel 82550 10/100", # Intel SCB20-S
"0x34108086,0x12298086,0x0d" => "Intel 82550 10/100", # Intel SCB20-A
"0x34128086,0x12298086,0x0d" => "Intel 82550 10/100", # Intel SRSH4
"0x34188086,0x12298086,0x0d" => "Intel 82550 10/100", # Intel SE7501BR2
"0x34198086,0x12298086,0x0d" => "Intel 82550 10/100", # Intel SE7500CW2
"0x34258086,0x12298086,0x0d" => "Intel 82550 10/100", # Intel SE7501CW2
"0x????????,0x12298086,0x0e" => "Intel 82550 10/100",
"0x????????,0x12298086,0x0f" => "Intel 82551 10/100", #
"0x????????,0x12298086,0x10" => "Intel 82551 10/100", #
"0x10408086,0x12298086,0x10" => "Intel 82551 10/100", # Tyan S2722, Tyan S2882
"0x00708086,0x12298086,0x10" => "Intel 82551 10/100", #
"0x00120e11,0x24498086,0x01" => "Compaq/Intel 82801BA ICH2 10/100 VM",
"0x00120e11,0x24498086,0x03" => "Compaq/Intel 82801BA ICH2 10/100 VM", # HP D500
"0x30108086,0x24498086,0x03" => "Intel 82801BA ICH2 10/100 VE", # SM 370SSR
"0x20101749,0x24498086,0x42" => "RLX/Intel 82801BA ICH2 10/100", # RLX ServerBlade
"0x308d8086,0x27dc8086,0x01" => "Intel 82562GX (82801G ICH7) 10/100", # Intel D945GTP
"0x30001458,0x294c8086,0x02" => "Gigabyte/Intel 82566DC-2 Gigabit", # Gigabyte R116
# wireless
"0x27228086,0x42208086,0x05" => "Intel 2200BG Wireless", # Dell Latitude D610
"0x12f6103c,0x42208086,0x05" => "HP/Intel 2200BG Wireless", # HP NC6220
"0x135b103c,0x42228086,0x02" => "HP/Intel 3945ABG Wireless", # HP NC6400
"0x135c103c,0x42228086,0x02" => "HP/Intel 3945ABG Wireless", # HP NC6400
"0x10008086,0x42298086,0x61" => "Intel 4965AG Wireless", # HP 6910p
"0x10018086,0x42298086,0x61" => "Intel 4965AG Wireless", # HP 6910p
# infiniband
"0x627415b3,0x627415b3,0x20" => "Mellanox MT25204 InfiniHost III",
"0x627815b3,0x627815b3,0x20" => "Mellanox MT25208 InfiniHost III",
},
'storage' => {
"0x0944103c,0x8033104c,0x00" => "HP/TI PCIxx21 SD Flash Reader", # NC6220
"0x30ad103c,0x803b104c" => "HP/TI 5-in-1 Multimedia Card Reader", # NC6400
"0x40500e11,0x00461011,0x01" => "Compaq Smart Array 4200", # ML530 G2
"0x40580e11,0x00461011,0x01" => "Compaq Smart Array 431", # ML370
"0x40800e11,0xb1780e11" => "Compaq Smart Array 5i", # DL560 G1, DL585 G1
"0x40830e11,0xb1780e11" => "Compaq Smart Array 5i",
"0x40910e11,0x00460e11" => "HP Smart Array 6i",
"0x40700e11,0xb0600e11" => "Compaq Smart Array 5300",
"0x409b0e11,0x00460e11" => "HP Smart Array 642",
"0x409c0e11,0x00460e11" => "HP Smart Array 6400",
"0x409d0e11,0x00460e11" => "HP Smart Array 6400 EM",
"0x001b0e11,0x00121000" => "Compaq/Symbios 895A Ultra2",
"0x3225103c,0x3220103c" => "HP Smart Array P600",
"0x3223103c,0x3230103c" => "HP Smart Array P800", # DL360 G5
"0x3234103c,0x3230103c" => "HP Smart Array P400", # DL380 G5, DL385 G2
"0x3235103c,0x3230103c" => "HP Smart Array P400i", # DL360 G5, DL365 G1
"0x3211103c,0x3238103c" => "HP Smart Array E200i", # DL360 G5, HP SB600c
"0x3212103c,0x3238103c" => "HP Smart Array E200i", # DL360 G5
"0x0475101e,0x1960101e" => "MegaRAID Express 500 Ultra160",
"0x04711028,0x1960101e" => "Dell/MegaRAID PERC 3/QC", # PE6650
"0x04931028,0x1960101e" => "Dell/MegaRAID PERC 3/DC",
"0x05111028,0x1960101e,0x02" => "Dell/MegaRAID CERC QC SATA/150", # Dell 1600SC
"0x05181028,0x19601000" => "Dell/MegaRAID PERC 4/DC",
"0x05201028,0x19601000" => "Dell/MegaRAID PERC 4/SC",
"0x05181000,0x19601000" => "LSILogic MegaRAID Ultra320-2",
"0x05201000,0x19601000" => "LSILogic MegaRAID Ultra320-1",
"0x00d11028,0x00021028,0x01" => "Dell PERC 3/Di", # PE2550
"0x00031028,0x00031028" => "Dell PERC 3/Si",
"0x01211028,0x000a1028" => "Dell PERC 3/Di", # PE2650
"0x014a1028,0x000f1028" => "Dell PE1750/LSILogic PERC 4/Di",
"0x????????,0x00131028" => "LSILogic PERC 4",
"0x016c1028,0x00131028" => "Dell PE1850/LSILogic PERC 4e/Si",
"0x016d1028,0x00131028" => "Dell PE2850/LSILogic PERC 4e/Di",
"0x01701028,0x00131028" => "Dell PE6850/LSILogic PERC 4e/Di", # PE6850
"0x????????,0x00151028" => "LSILogic PERC 5",
"0x1f011028,0x00151028" => "Dell/LSILogic PERC 5/E",
"0x1f021028,0x00151028" => "Dell PE6950/LSILogic PERC 5/i", # PE6950
"0x1f031028,0x00151028" => "Dell/LSILogic PERC 5/i", # PE2950, PE1950
"0xb1430e11,0x000a1000" => "Compaq/LSILogic 1510 Ultra2", # DL360, ML570
"0x????????,0x000f1000" => "LSILogic 53C875 Ultra",
"0x00000000,0x000f1000" => "LSILogic 53C875 Ultra",
"0x10001000,0x000f1000" => "LSILogic 53C876 Ultra",
"0x70040e11,0x000f1000,0x14" => "LSILogic 53C875 Ultra", # Compaq 6400R
"0x40400e11,0x00101000" => "Compaq/LSILogic 1510 Ultra2", # DL360
"0x60b0103c,0x00201000" => "HP/LSILogic 1010-33 Ultra160", # HP NetServer
"0x10001000,0x00201000" => "LSILogic 1010-33 Ultra160", # Tyan S2510
"0x10001000,0x00211000" => "LSILogic 1010-66 Ultra160",
"0x????????,0x00301000" => "LSILogic 1030 Ultra320",
"0x00000000,0x00301000" => "LSILogic 1030 Ultra320", # VMware
"0x10001000,0x00301000" => "LSILogic 1030 Ultra320", # Tyan S4882
"0x10101000,0x00301000" => "LSILogic 1030 Ultra320", # Tyan S4881
"0x10601000,0x00301000" => "LSILogic 1030 Ultra320", # Inventec IR2300 (onboard?)
"0x10005100,0x00301000" => "LSILogic 1030 Ultra320", # Arima HDAMA
"0x30e01000,0x00301000" => "LSILogic 1030 Ultra320", # Tyan S2880
"0x51001000,0x00301000" => "LSILogic 1030 Ultra320", # Arima HDAMA
"0x71301000,0x00301000" => "LSILogic 1030 Ultra320",
"0x24501462,0x00301000" => "MSI/LSILogic 1030 Ultra320",
"0x014a1028,0x00301000" => "Dell PE1750/LSILogic 1030 Ultra320",
"0x016c1028,0x00301000" => "Dell PE1850/LSILogic 1030 Ultra320",
"0x016d1028,0x00301000" => "Dell PE2850/LSILogic 1030 Ultra320",
"0x01701028,0x00301000" => "Dell PE6850/LSILogic 1030 Ultra320",
"0x018a1028,0x00301000" => "Dell PE1855/LSILogic 1030 Ultra320",
"0x10401028,0x00301000" => "Dell/LSILogic 1030 Ultra320",
"0x00da0e11,0x00301000" => "HP/LSILogic 1030 Ultra320", # DL145 G1
"0x00f40e11,0x00301000" => "HP/LSILogic 1030 Ultra320", # DL140 G2
"0x3108103c,0x00301000" => "HP/LSILogic 1030 Ultra320",
"0x34628086,0x00301000" => "Intel/LSILogic 1030 Ultra320", # Intel SE7520BD2
"0x34358086,0x00301000" => "Intel/LSILogic 1030 Ultra320", # Intel SE7520JR2
"0x03011014,0x00301000" => "IBM/LSILogic 1030 Ultra320", # IBM eServer BladeCenter LS20
"0x001017c2,0x00301000" => "Newisys/LSILogic 1030 Ultra320", # V20z
"0x002017c2,0x00301000" => "Newisys/LSILogic 1030 Ultra320", # V40z
"0x10051000,0x04131000" => "MegaRAID SAS 8300XLP",
"0x????????,0x00501000" => "LSILogic SAS 1064",
"0x10001000,0x00501000,0x02" => "LSILogic SAS 1064",
"0x????????,0x00541000" => "LSILogic SAS 1068",
"0x1f061028,0x00541000" => "Dell/LSILogic SAS 5/i", # PE2950
"0x1f081028,0x00541000" => "Dell/LSILogic SAS 5/i", # PE1955
"0x1f091028,0x00541000" => "Dell/LSILogic SAS 5/i", # PE860, SC1435
"0x3228103c,0x00541000" => "HP/LSILogic SAS 1068", # DL140 G3
"0x????????,0x00561000" => "LSILogic SAS 1064E",
"0x10001000,0x00561000" => "LSILogic SAS 1064E",
"0x34798086,0x00561000" => "Intel/LSILogic SAS 1064E", # Intel S5000PSL
"0x894b152d,0x00561000" => "Quanta/LSILogic SAS 1064E", # DCS-SAS
"0x322b103c,0x00561000" => "HP/LSILogic SAS 1064E", # DL160 G5
"0x????????,0x00581000" => "LSILogic SAS 1068E",
"0x10001000,0x00581000,0x04" => "LSILogic SAS 1068E", # Tyan S5397 (onboard)
"0x31401000,0x00581000,0x08" => "LSILogic SAS 1068E", # Dell S45
"0x1f0e1028,0x00581000" => "Dell/LSILogic SAS 6/iR", # Dell R200 (card)
"0x1f101028,0x00581000" => "Dell/LSILogic SAS 6/iR", # Dell PE1950 (integrated)
"0xa38015d9,0x00581000,0x08" => "Supermicro/LSILogic SAS 1068E", # SM X7DCT (add-on card?)
"0xa48015d9,0x00581000,0x08" => "Supermicro/LSILogic SAS 1068E", # SM X7DCL-3
"0xa18015d9,0x00591000" => "Supermicro/LSILogic 1068E AOC-SAS-L4iR", # SM UIO
"0xa48015d9,0x00591000" => "Supermicro/LSILogic 1068E AOC-SAS-L4iR", # SM X7DCL-3
"0x002f1170,0x00601000,0x03" => "Inventec/LSILogic MegaRAID SAS 1078", # Inventec 5220
"0x10131000,0x00601000,0x04" => "LSILogic MegaRAID SAS 1078",
"0x34cc8086,0x00601000" => "Intel/LSILogic MegaRAID SAS 1078", # Intel Tigerton
"0x1f0a1028,0x00601000,0x04" => "Dell/LSILogic PERC 6/E", # DCS
"0x1f0c1028,0x00601000" => "Dell/LSILogic PERC 6/i", # PE2950 III, Dell R900
"0x03791014,0x00601000,0x04" => "IBM/LSILogic ServeRAID-MR10M",
"0x03661014,0x00621000" => "IBM/LSILogic SAS 1078", # IBM x3859 M2
"0x05321000,0x04071000" => "MegaRAID 320-2X Ultra320 RAID",
"0x00021028,0x04081000" => "Dell/LSILogic PERC 4e/DC",
"0x10018086,0x04111000" => "Intel/MegaRAID SRCSAS18E SAS", # Intel S5000PAL
"0x00000000,0x80789004" => "Adaptec AIC-7880 Ultra",
"0x????????,0x81789004" => "Adaptec 2940 Ultra",
"0x00000000,0x81789004" => "Adaptec 2940 Ultra",
"0x78819004,0x81789004" => "Adaptec 2940 Ultra",
"0x78879004,0x87789004" => "Adaptec 2940 Ultra", # 2940UW Pro Ultra-Wide SCSI Controller
"0x????????,0x00109005" => "Adaptec 2940 Ultra2",
"0x21809005,0x00109005" => "Adaptec 2940 Ultra2",
"0xa1809005,0x00109005" => "Adaptec 2940 Ultra2",
"0x????????,0x005f9005" => "Adaptec AIC-7896/97 Ultra2",
"0x00539004,0x005f9005" => "Adaptec AIC-7896/97 Ultra2",
"0x080f9005,0x005f9005" => "Adaptec AIC-7896/97 Ultra2",
"0xe2a09005,0x00809005" => "Adaptec 29160 Ultra160",
"0xe2a00e11,0x00809005" => "Compaq/Adaptec AIC-7892A Ultra160",
"0x????????,0x008f9005" => "Adaptec AIC-7892P Ultra160", #
"0x010a1028,0x008f9005" => "Dell/Adaptec AIC-7892P Ultra160", # PE6650
"0x8916152d,0x008f9005" => "Quanta/Adaptec AIC-7892P Ultra160", # Quanta SU6
"0x8917152d,0x008f9005" => "Quanta/Adaptec AIC-7892P Ultra160", # Quanta SU2-3000
"0xf6209005,0x00c09005" => "Adaptec 3960D Ultra160",
"0xf6200e11,0x00c09005,0x01" => "Compaq/Adaptec AIC-7899A Ultra160", # ML530 G2
"0x00c51028,0x00c59005" => "Dell/Adaptec RAID subsystem HBA", # PE2450, PE2550, PE2650 (noop SCSI channels of a Dell PERC card, see /sys/dev/aac/aac_pci.c)
"0x????????,0x00cf9005" => "Adaptec AIC-7899 Ultra160",
"0xffffffff,0x00cf9005" => "Adaptec AIC-7899 Ultra160",
"0xffff9005,0x00cf9005" => "Adaptec AIC-7899 Ultra160",
"0x00cf8086,0x00cf9005" => "Intel/Adaptec AIC-7899 Ultra160",
"0x340f8086,0x00cf9005" => "Intel/Adaptec AIC-7899 Ultra160", # Intel SCB20-S
"0x34158086,0x00cf9005" => "Intel/Adaptec AIC-7899 Ultra160", # Intel SE7500WV2
"0x00a61028,0x00cf9005" => "Dell PE2450/Adaptec AIC-7899 Ultra160",
"0x00d11028,0x00cf9005" => "Dell PE2550/Adaptec AIC-7899 Ultra160",
"0x00df1028,0x00cf9005,0x01" => "Dell/Adaptec AIC-7899 Ultra160", # PE1550
"0x011b1028,0x00cf9005" => "Dell PE1650/Adaptec AIC-7899 Ultra160",
"0x01211028,0x00cf9005" => "Dell PE2650/Adaptec AIC-7899 Ultra160",
"0x900515d9,0x00cf9005" => "Supermicro/Adaptec AIC-7899 Ultra160", # SM P4DP6
"0x5539d915,0x00cf9005" => "Supermicro/Adaptec AIC-7899 Ultra160", # SM P4DLR
"0x00609005,0x80009005" => "Adaptec ASC-29320A Ultra320",
"0x91661462,0x800f9005" => "MSI/Adaptec AIC-7901 Ultra320", # MSI ???
"0x005e9005,0x801d9005" => "Adaptec AIC-7902B Ultra320",
"0x90059005,0x801d9005" => "Adaptec AIC-7902B Ultra320",
"0xb0101458,0x801d9005" => "Gigabyte/Adaptec AIC-7902B Ultra320", # Gigabyte GA-7A8DRH
"0x????????,0x801f9005" => "Adaptec AIC-7902 Ultra320",
"0x34128086,0x801f9005,0x03" => "Intel/Adaptec AIC-7902 Ultra320", # Intel SRSH4
"0x341a8086,0x801f9005" => "Intel/Adaptec AIC-7902 Ultra320", # Intel SE7501WV2S
"0x90059005,0x801f9005" => "Adaptec AIC-7902 Ultra320",
"0xffff9005,0x801f9005" => "Adaptec AIC-7902 Ultra320", # Tyan S2881
"0x01681028,0x80959005" => "Dell/Adaptec ASC-39320 Ultra320 RAID", # SC1425
"0x005e9005,0x809d9005" => "Adaptec AIC-7902B Ultra320 RAID",
"0xb0101458,0x809d9005" => "Gigabyte/Adaptec AIC-7902B Ultra320 RAID", # Gigabyte GA-7A8DRH
"0x90059005,0x809f9005" => "Adaptec AIC-7902 Ultra320 RAID",
"0x02859005,0x02859005" => "Adaptec 2200S Ultra320 RAID",
"0x02869005,0x02859005" => "Adaptec 2120S Ultra320 RAID",
"0x02911028,0x02859005" => "Dell/Adaptec CERC SATA 2", # PE850
"0x02ca15d9,0x02859005" => "Supermicro/Adaptec AOC-USAS-S8iR", # SM UIO
"0x608015d9,0x041e9005" => "Supermicro/Adaptec 9410W SAS", # SM X7DB8?
"0x928015d9,0x041e9005" => "Supermicro/Adaptec 9410W SAS", # SM X7DBR-3
"0x100013c1,0x100013c1" => "3ware ATA-RAID",
"0x100113c1,0x100113c1" => "3ware 7xxx/8xxx ATA/SATA RAID",
"0x100213c1,0x100213c1" => "3ware 9xxx SATA RAID",
"0x100313c1,0x100313c1" => "3ware 9550X SATA RAID",
"0xc0331044,0xa5111044" => "DPT/Adaptec 2000S Ultra160 RAID",
"0xc05a1044,0xa5011044" => "DPT/Adaptec 2400A ATA RAID",
"0x00541069,0x00501069" => "Mylex AcceleRAID 160",
"0x00091077,0x23001077" => "QLogic QLA2300 2G FC",
"0x01061077,0x23001077,0x01" => "QLogic QLA2300 2G FC",
"0x01001077,0x23121077" => "QLogic ISP2312 2G FC",
"0x01011077,0x23121077" => "QLogic ISP2312 2G FC",
"0x01021077,0x23121077" => "QLogic ISP2312 2G FC",
"0x010d1077,0x23121077,0x02" => "QLogic ISP2312 2G FC",
"0x01331077,0x24221077" => "QLogic ISP2422 4G FC",
"0x01341077,0x24221077" => "QLogic ISP2422 4G FC",
"0x01371077,0x24321077,0x03" => "QLogic ISP2432 4G FC",
"0x01381077,0x24321077" => "QLogic ISP2432 4G FC",
"0x7040103c,0x24321077,0x02" => "HP/QLogic ISP2432 4G FC",
"0x7041103c,0x24321077" => "HP/QLogic ISP2432 4G FC",
"0x7041103c,0x24321077" => "HP/QLogic ISP2432 4G FC",
"0x8471101e,0x12161077" => "QLogic ISP12160 Ultra160 RAID", # PE6650
"0x8493101e,0x12161077" => "QLogic ISP12160 Ultra160 RAID", # PE2650
"0xf0a510df,0xf0a510df" => "Emulex LP1050 2G FC", # Emulex Thor LightPulse
"0xf90010df,0xf90010df" => "Emulex LP9000 2G FC",
"0xfa0010df,0xfa0010df" => "Emulex LP10000 2G FC", # Emulex Thor-X LightPulse
"0x72119005,0x564a9005" => "Adaptec iSCSI ASA-7211",
"0xa48015d9,0x82131283" => "Supermicro/ITE IT8213F ATA/133",
"0x82121043,0x612111ab,0xb1" => "Asus/Marvell 88SE6121 ATA/133 + SATA/300", # Asus P5Q-Deluxe
"0x2368197b,0x2368197b,0x00" => "JMicron JMB368 ATA/133", # SM X8DTN
"0xb0001458,0x2368197b,0x00" => "Gigabyte/JMicron JMB368 ATA/133",
"0x3009103c,0x43761002" => "HP/ATI ATA", # HP DX5150
"0x3009103c,0x43791002" => "HP/ATI 4379 SATA/150", # HP DX5150
"0x807a1043,0x55131039" => "Asus/SiS 5513 ATA/100", # Asus P4SGX-MX
"0x3024103c,0x53371106,0x07" => "HP/VIA VT8237S SATA/300", # HP DX2255
"0x00000000,0x05711106" => "VIA VT82C686 ATA/66", # Asus CUV4X
"0x3024103c,0x05711106" => "HP/VIA VT82C686 ATA/66", # HP DX2255
"0x50021458,0x05711106" => "Gigabyte/VIA VT82C686 ATA/66",
"0x3024103c,0x05911106" => "HP/VIA VT8237A SATA/150", # HP DX2255
"0xb0031458,0x31491106" => "Gigabyte/VIA VT6420 SATA/150 RAID", # Gigabyte EP45-DS3R
"0x????????,0x74691022" => "AMD-8111 ATA/133", #
"0x001017c2,0x74691022" => "Newisys/AMD-8111 ATA/133", # V20z
"0x002017c2,0x74691022" => "Newisys/AMD-8111 ATA/133", # V40z
"0x3016161f,0x74691022" => "Arima/AMD-8111 ATA/133", # Arima HDAMA
"0x2b801022,0x74691022" => "AMD-8111 ATA/133", # Tyan S4882
"0x36c01022,0x74691022" => "AMD-8111 ATA/133", # DL145 G1
"0x74691022,0x74691022" => "AMD-8111 ATA/133", # Tyan S2882, Tyan S2881, Tyan S2880, MSI 8480000
"0x74691462,0x74691022" => "MSI/AMD-8111 ATA/133", # MSI 8480000
"0x32040e11,0x74691022" => "Compaq/AMD-8111 ATA/133", # DL385, DL585
"0x4d33105a,0x0d30105a,0x02" => "Promise PDC20265 ATA/100", # FastTrak100 Adapter
"0x6619105a,0x3373105a" => "Promise PDC20378 SATA/150", # Tyan S2880
"0x34108086,0x4d30105a" => "Intel/Promise PDC20267 ATA/100", # Intel SCB20-A
"0x06801095,0x06801095" => "SiI 0680A ATA/133", # Silicon Image
"0x61141095,0x31141095" => "SiI 3114 SATA/150 RAID", # Arima HDAMA
"0x31141095,0x31141095" => "SiI 3114 SATA/150 RAID", # Tyan S2882, Tyan S2881
"0x31248086,0x31241095" => "SiI 3124 SATA/150 RAID", # Intel SE7520BB2
"0x71248086,0x31241095" => "SiI 3124 SATA/150 RAID", # Intel SE7520BB2
"0x00450e11,0x06491095" => "Compaq/CMD 649 ATA/100", # DL320
"0x007e0e11,0x06491095" => "Compaq/CMD 649 ATA/100", # DL320 G2
"0x00000000,0x02111166" => "ServerWorks OSB4 ATA/33", # DL320, DL360, DL380 G2, ML570, Quanta SU2-3000, PE2550, Tyan S2510
"0x????????,0x02121166" => "ServerWorks CSB5 ATA/100", #
"0x02121166,0x02121166" => "ServerWorks CSB5 ATA/100", # DL360 G2, DL360 G3, DL380 G3, PE6650, DL580 G2, DL560 G1
"0x014a1028,0x02121166" => "Dell/ServerWorks CSB5 ATA/100", # PE1750
"0x810b1028,0x02121166" => "Dell/ServerWorks CSB5 ATA/100", # PE1650
"0x41351028,0x02121166,0x93" => "Dell/ServerWorks CSB5 ATA/100", # Dell 1600SC
"0x340f8086,0x02121166" => "Intel/ServerWorks CSB5 ATA/100", # Intel SCB20-S
"0x34108086,0x02121166" => "Intel/ServerWorks CSB5 ATA/100", # Intel SCB20-A
"0x34148086,0x02121166" => "Intel/ServerWorks CSB5 ATA/100", # Intel SAI2
"0x????????,0x02131166" => "ServerWorks CSB6 ATA/100", #
"0x02201166,0x02131166" => "ServerWorks CSB6 ATA/100", # SU2-4200
"0x02121166,0x02131166" => "ServerWorks CSB6 ATA/100", # DL320 G2, DL140
"0x8920107b,0x02131166,0xa0" => "Gateway/ServerWorks CSB6 ATA/100", # SU2-4200
"0x????????,0x02141166" => "ServerWorks HT-1000 ATA/100", #
"0x01ea1028,0x02141166" => "Dell/ServerWorks HT-1000 ATA/100", # PE6950
"0x01eb1028,0x02141166" => "Dell/ServerWorks HT-1000 ATA/100", # SC1435
"0x02051028,0x02141166" => "Dell/ServerWorks HT-1000 ATA/100", # PE2970
"0x320b103c,0x02141166" => "HP/ServerWorks HT-1000 ATA/100", # DL145 G3, DL365 G1, DL385 G2
"0x320b103c,0x024a1166" => "HP/ServerWorks HT-1000 SATA/150", # DL145 G3 (native SATA mode), DL185 G5
"0x????????,0x024b1166" => "ServerWorks HT-1000 SATA/150 (PATA mode)", #
"0x01eb1028,0x024b1166" => "Dell/ServerWorks HT-1000 SATA/150 (PATA mode)", # SC1435
"0x02051028,0x024b1166" => "Dell/ServerWorks HT-1000 SATA/150 (PATA mode)", # PE2970
"0x320b103c,0x024b1166" => "HP/ServerWorks HT-1000 SATA/150 (PATA mode)", # DL145 G3 (PATA mode)
"0x00000000,0x70108086" => "Intel 82371SB PIIX3 ATA/33", #
"0x00000000,0x71118086" => "Intel 82371AB PIIX4 ATA/33", # L440GX, TR440BX
"0x197615ad,0x71118086" => "VMware/Intel 82371AB PIIX4 ATA/33", #
"0x24118086,0x24118086" => "Intel ICH 82801AA ATA/66", # 810
"0x????????,0x244b8086" => "Intel 82801BA ICH2 ATA/100", #
"0x57448086,0x244b8086" => "Intel 82801BA ICH2 ATA/100", # Intel S845WD1
"0x24118086,0x244b8086" => "Intel 82801BA ICH2 ATA/100", #
"0x24110e11,0x244b8086" => "Compaq/Intel 82801BA ICH2 ATA/100", # HP D500
"0x113015d9,0x244b8086" => "Supermicro/Intel 82801BA ICH2 ATA/100", # SM P3TSSR
"0x010e1028,0x244b8086" => "Dell/Intel 82801BA ICH2 ATA/100", # Dell OptiPlex GX240
"0x00d81028,0x244b8086" => "Dell/Intel 82801BA ICH2 ATA/100", # Dell 530
"0x????????,0x248b8086" => "Intel 82801CA ICH3 ATA/100", #
"0x00000000,0x248b8086" => "Intel 82801CA ICH3 ATA/100", # Tyan S2722
"0x34158086,0x248b8086" => "Intel 82801CA ICH3 ATA/100", # Intel SE7500WV2
"0x34168086,0x248b8086" => "Intel 82801CA ICH3 ATA/100", # Intel SE7500WV2A
"0x34188086,0x248b8086" => "Intel 82801CA ICH3 ATA/100", # Intel SE7501BR2
"0x34198086,0x248b8086" => "Intel 82801CA ICH3 ATA/100", # Intel SE7500CW2
"0x341a8086,0x248b8086" => "Intel 82801CA ICH3 ATA/100", # Intel SE7501WV2S
"0x341b8086,0x248b8086" => "Intel 82801CA ICH3 ATA/100", # Intel SE7501WV2A
"0x34258086,0x248b8086" => "Intel 82801CA ICH3 ATA/100", # Intel SE7501CW2
"0x00001749,0x248b8086" => "RLX/Intel 82801CA ICH3 ATA/100", # RLX ServerBlade
"0x348015d9,0x248b8086" => "Supermicro/Intel 82801CA ICH3 ATA/100", # SM P4DP6, SM X5DP8
"0x????????,0x24cb8086" => "Intel ICH4 82801DB ATA/100", #
"0x00b80e11,0x24cb8086" => "Compaq/Intel ICH4 82801DB ATA/100", # HP D510
"0x00b90e11,0x24cb8086" => "Compaq/Intel ICH4 82801DB ATA/100", # HP D510
"0x01381028,0x24cb8086,0x01" => "Dell/Intel ICH4 82801DB ATA/100", # Dell SX260
"0x368015d9,0x24cb8086" => "Supermicro/Intel ICH4 82801DB ATA/100", # SM P4SGR
"0x80891043,0x24cb8086,0x02" => "Asus/Intel ICH4 82801DB ATA/100", # Asus P4GE-MX
"0x????????,0x24d18086" => "Intel ICH5 82801EB SATA/150", #
"0x00000000,0x24d18086" => "Intel ICH5 82801EB SATA/150", # NEC Express5800/120Re-1
"0x34288086,0x24d18086" => "Intel ICH5 82801EB SATA/150", # Intel S875WP1
"0x34398086,0x24d18086" => "Intel ICH5 82801EB SATA/150", # Intel SE7520BD2
"0x343b8086,0x24d18086" => "Intel ICH5 82801EB SATA/150", # Intel SE7520BD2S
"0x347e8086,0x24d18086" => "Intel ICH5 82801EB SATA/150", # Intel SE7520BB2
"0x3208103c,0x24d18086" => "HP/Intel ICH5 82801EB SATA/150", # DL140 G2
"0x12bc103c,0x24d18086" => "HP/Intel ICH5 82801EB SATA/150", # HP D530
"0x12bd103c,0x24d18086,0x02" => "HP/Intel ICH5 82801EB SATA/150", # HP ??
"0x01511028,0x24d18086" => "Dell/Intel ICH5 82801EB SATA/150", # Dell GX270
"0x01561028,0x24d18086,0x02" => "Dell/Intel ICH5 82801EB SATA/150", # Dell Precision 360
"0x019a1028,0x24d18086" => "Dell/Intel ICH5 82801EB SATA/150", # SC1425
"0xb0021458,0x24d18086" => "Gigabyte/Intel ICH5 82801EB SATA/150", # Gigabyte 9ILDR
"0x????????,0x24db8086" => "Intel ICH5 82801EB ATA/100", #
"0x000c1170,0x24db8086" => "Inventec/Intel ICH5 82801EB ATA/100", # Inventec IR2100
"0x34288086,0x24db8086" => "Intel ICH5 82801EB ATA/100", # Intel S875WP1
"0x347e8086,0x24db8086" => "Intel ICH5 82801EB ATA/100", # Intel SE7520BB2
"0x34398086,0x24db8086" => "Intel ICH5 82801EB ATA/100", # Intel SE7520BD2
"0x10798086,0x24db8086" => "Intel ICH5 82801EB ATA/100", # Intel SE7520JR2
"0x12bc103c,0x24db8086" => "HP/Intel ICH5 82801EB ATA/100", # HP D530, DC5000
"0x12bd103c,0x24db8086,0x02" => "HP/Intel ICH5 82801EB ATA/100", # HP ??
"0x3201103c,0x24db8086" => "HP/Intel ICH5 82801EB ATA/100", # DL580 G4
"0x3208103c,0x24db8086" => "HP/Intel ICH5 82801EB ATA/100", # DL140 G2
"0x01511028,0x24db8086" => "Dell/Intel ICH5 82801EB ATA/100", # Dell GX270
"0x01561028,0x24db8086,0x02" => "Dell/Intel ICH5 82801EB ATA/100", # Dell Precision 360
"0x016c1028,0x24db8086" => "Dell/Intel ICH5 82801EB ATA/100", # PE1850
"0x016d1028,0x24db8086" => "Dell/Intel ICH5 82801EB ATA/100", # PE2850
"0x01701028,0x24db8086" => "Dell/Intel ICH5 82801EB ATA/100", # PE6850
"0x019a1028,0x24db8086" => "Dell/Intel ICH5 82801EB ATA/100", # SC1425
"0x32010e11,0x24db8086" => "Compaq/Intel ICH5 82801EB ATA/100", # DL380 G4
"0x50061458,0x24db8086" => "Gigabyte/Intel ICH5 82801EB ATA/100", # Gigabyte 9ILDR
"0x019a1028,0x24df8086" => "Dell/Intel ICH5R 82801ER SATA/150", # SC1425
"0x????????,0x26518086" => "Intel ICH6 82801FB SATA/150",
"0x3005103c,0x26518086" => "HP/Intel ICH6 82801FB SATA/150", # HP DC7100
"0x300a103c,0x26518086" => "HP/Intel ICH6 82801FB SATA/150", # HP DX6120
"0x300c103c,0x26518086" => "HP/Intel ICH6 82801FB SATA/150", # HP DC5100
"0x300d103c,0x26518086" => "HP/Intel ICH6 82801FB SATA/150", # HP DC5100 (PT005AW)
"0x301e103c,0x26518086" => "HP/Intel ICH6 82801FB SATA/150", # HP DX2180
"0x301f103c,0x26518086" => "HP/Intel ICH6 82801FB SATA/150", # HP D290
"0x41478086,0x26518086" => "Intel ICH6 82801FB SATA/150", # Intel D915GAG
"0x4c588086,0x26518086" => "Intel ICH6 82801FB SATA/150", # Intel D915GUX
"0x01791028,0x26518086" => "Dell/Intel ICH6 82801FB SATA/150", # Dell GX280
"0x32010e11,0x26528086" => "Compaq/Intel ICH6R 82801FR SATA/150", # DL320 G3
"0x01821028,0x26538086,0x03" => "Dell/Intel ICH6M 82801FBM SATA/150", # Dell Latitude D610
"0x????????,0x266f8086" => "Intel ICH6 82801FB ATA/100",
"0x32010e11,0x266f8086" => "Compaq/Intel ICH6 82801FB ATA/100", # DL320 G3
"0x3005103c,0x266f8086" => "HP/Intel ICH6 82801FB ATA/100", # HP DC7100
"0x300a103c,0x266f8086" => "HP/Intel ICH6 82801FB ATA/100", # HP DX6120
"0x300c103c,0x266f8086" => "HP/Intel ICH6 82801FB ATA/100", # HP DC5100
"0x300d103c,0x266f8086" => "HP/Intel ICH6 82801FB ATA/100", # HP DC5100 (PT005AW)
"0x301e103c,0x266f8086" => "HP/Intel ICH6 82801FB ATA/100", # HP DX2180
"0x301f103c,0x266f8086" => "HP/Intel ICH6 82801FB ATA/100", # HP D290
"0x0944103c,0x266f8086,0x03" => "HP/Intel ICH6 82801FB ATA/100", # HP NC6220
"0x41478086,0x266f8086" => "Intel ICH6 82801FB ATA/100", # Intel D915GAG
"0x4c588086,0x266f8086" => "Intel ICH6 82801FB ATA/100", # Intel D915GUX
"0x01791028,0x266f8086" => "Dell/Intel ICH6 82801FB ATA/100", # Dell GX280
"0x????????,0x27c08086" => "Intel ICH7 82801GB SATA/300", #
"0x348f8086,0x27c08086" => "Intel ICH7 82801GB SATA/300", # Intel Coretta
"0x349a8086,0x27c08086" => "Intel ICH7 82801GB SATA/300", # Intel S3000PT
"0x349b8086,0x27c08086" => "Intel ICH7 82801GB SATA/300", # Intel S3000PT
"0x348d8086,0x27c08086" => "Intel ICH7 82801GB SATA/300", # Intel AspenHill
"0x464c8086,0x27c08086,0x01" => "Intel ICH7 82801GB SATA/300", # Intel D945GCLF
"0x544e8086,0x27c08086" => "Intel ICH7 82801GB SATA/300", # Intel D945GTP
"0x3011103c,0x27c08086" => "HP/Intel ICH7 82801GB SATA/300", # HP DC7600
"0x31fe103c,0x27c08086" => "HP/Intel ICH7 82801GB SATA/300", # DL320 G5
"0x3022103c,0x27c08086" => "HP/Intel ICH7 82801GB SATA/300", # HP DX2280
"0x00000000,0x27c08086" => "HP/Intel ICH7 82801GB SATA/300", # DL320s
"0x01ad1028,0x27c08086,0x01" => "Dell/Intel ICH7 82801GB SATA/300", # Dell GX620
"0x01b61028,0x27c08086" => "Dell/Intel ICH7 82801GB SATA/300", # PE850
"0x01e61028,0x27c08086" => "Dell/Intel ICH7 82801GB SATA/300", # PE860
"0x02fd1014,0x27c08086" => "IBM/Intel ICH7 82801GB SATA/300", # IBM 306m
"0x858015d9,0x27c08086" => "Supermicro/Intel ICH7 82801GB SATA/300", # SM PDSML
"0x798015d9,0x27c08086" => "Supermicro/Intel ICH7 82801GB SATA/300", # SM PDSMi
"0xb58015d9,0x27c08086" => "Supermicro/Intel ICH7 82801GB SATA/300", # SM PDSBM
"0x00221170,0x27c08086" => "Inventec/Intel ICH7 82801GB SATA/300", # IR1250
"0x81901043,0x27c08086,0x01" => "Asus/Intel ICH7 82801GB SATA/300", # Asus P5BV-C
"0xb0021458,0x27c08086,0x01" => "Gigabyte/Intel ICH7 82801GB SATA/300", # Gigabyte 945GCM-S2C
"0x????????,0x27c18086,0x01" => "Intel ICH7 82801GR SATA/300 AHCI",
"0x346a8086,0x27c18086,0x01" => "Intel ICH7 82801GR SATA/300 AHCI", # Intel Allagash
"0x858015d9,0x27c18086,0x01" => "Supermicro/Intel ICH7 82801GR SATA/300 AHCI", # SM PDSML
"0x81901043,0x27c18086,0x01" => "Asus/Intel ICH7 82801GR SATA/300 AHCI", # Asus P5BV-C
"0x????????,0x27c38086,0x01" => "Intel ICH7 82801GB SATA/300 RAID",
"0x3206103c,0x27c38086,0x01" => "HP/Intel ICH7 82801GB SATA/300 RAID", # DL320 G5
"0x????????,0x27c58086,0x01" => "Intel ICH7 82801GBM SATA/300 AHCI",
"0x30ad103c,0x27c58086,0x01" => "HP/Intel ICH7 82801GBM SATA/300 AHCI", # HP NC6400
"0x????????,0x27df8086" => "Intel ICH7 82801G ATA/100", #
"0x346a8086,0x27df8086" => "Intel ICH7 82801G ATA/100", # Intel Allagash
"0x348d8086,0x27df8086" => "Intel ICH7 82801G ATA/100", # Intel AspenHill
"0x348f8086,0x27df8086" => "Intel ICH7 82801G ATA/100", # Intel Coretta
"0x349a8086,0x27df8086" => "Intel ICH7 82801G ATA/100", # Intel S3000PT
"0x349b8086,0x27df8086" => "Intel ICH7 82801G ATA/100", # Intel S3000PT
"0x464c8086,0x27df8086,0x01" => "Intel ICH7 82801G ATA/100", # Intel D945GCLF
"0x544e8086,0x27df8086" => "Intel ICH7 82801G ATA/100", # Intel D945GTP
"0x3011103c,0x27df8086" => "HP/Intel ICH7 82801G ATA/100", # HP DC7600
"0x30ad103c,0x27df8086" => "HP/Intel ICH7 82801G ATA/100", # HP NC6400
"0x31fe103c,0x27df8086" => "HP/Intel ICH7 82801G ATA/100", # DL320 G5
"0x3022103c,0x27df8086" => "HP/Intel ICH7 82801G ATA/100", # HP DX2280
"0x01ad1028,0x27df8086,0x01" => "Dell/Intel ICH7 82801G ATA/100", # Dell GX620
"0x01b61028,0x27df8086" => "Dell/Intel ICH7 82801G ATA/100", # PE850
"0x01e61028,0x27df8086" => "Dell/Intel ICH7 82801G ATA/100", # PE860
"0x00221170,0x27df8086" => "Inventec/Intel ICH7 82801G ATA/100", # IR1250
"0x858015d9,0x27df8086" => "Supermicro/Intel ICH7 82801G ATA/100", # SM PDSML
"0x03811014,0x27df8086" => "IBM/Intel ICH7 82801G ATA/100", # IBM x3850 M2
"0x819e1043,0x27df8086,0x01" => "Asus/Intel ICH7 82801G ATA/100", # Asus P5BV-C
"0xb0011458,0x27df8086,0x01" => "Gigabyte/Intel ICH7 82801G ATA/100", # Gigabyte 945GCM-S2C
"0x2808103c,0x28208086" => "HP/Intel ICH8 82801H 4 Port SATA/300", # HP DC5700
"0x31f4103c,0x28228086,0x02" => "HP/Intel ICH8 82801H SATA/300 RAID", # DL180 G5
"0x28228086,0x28228086,0x02" => "Intel ICH8 82801H SATA/300 RAID", # Dell S45, SM X8DTN
"0x2808103c,0x28258086" => "HP/Intel ICH8 82801H 2 Port SATA/300", # HP DC5700
"0x????????,0x28288086,0x03" => "Intel ICH8M 82801HBM SATA/300",
"0x80301462,0x28288086,0x03" => "MSI/Intel ICH8M 82801HBM SATA/300", # MSI GM965
"0x063ea0a0,0x28288086,0x03" => "AOpen/Intel ICH8M 82801HBM SATA/300", # AOpen i965GMt-LA
"0x????????,0x28298086,0x03" => "Intel ICH8M 82801HBM SATA/300 AHCI",
"0x30c1103c,0x28298086,0x03" => "HP/Intel ICH8M 82801HBM SATA/300 AHCI", # HP 6910p
"0x80301462,0x28298086,0x03" => "MSI/Intel ICH8M 82801HBM SATA/300 AHCI", # MSI GM965
"0x????????,0x28508086,0x03" => "Intel ICH8M 82801HBM ATA/100",
"0x30be103c,0x28508086" => "HP/Intel ICH8M 82801HBM ATA/100", # HP 6910p
"0x30c1103c,0x28508086,0x03" => "HP/Intel ICH8M 82801HBM ATA/100", # HP 6910p
"0x80301462,0x28508086,0x03" => "MSI/Intel ICH8M 82801HBM ATA/100", # MSI GM965
"0x063ea0a0,0x28508086,0x03" => "AOpen/Intel ICH8M 82801HBM ATA/100", # AOpen i965GMt-LA
"0x????????,0x29208086" => "Intel ICH9 82801I 4 Port SATA/300",
"0x29208086,0x29208086" => "Intel ICH9 82801I 4 Port SATA/300", # DCS S45
"0x31f4103c,0x29208086" => "HP/Intel ICH9 82801I 4 Port SATA/300", # DL180 G5, DL120 G5
"0x31fe103c,0x29208086" => "HP/Intel ICH9 82801I 4 Port SATA/300", # BL260c G5
"0x023c1028,0x29208086" => "Dell/Intel ICH9 82801I 4 Port SATA/300", # Dell R200
"0x020f1028,0x29208086" => "Dell/Intel ICH9 82801I 4 Port SATA/300", # Dell R300
"0xdc8015d9,0x29208086,0x02" => "Supermicro/Intel ICH9 82801I 4 Port SATA/300", # SM X7DCA-L
"0xa48015d9,0x29208086" => "Supermicro/Intel ICH9 82801I 4 Port SATA/300", # SM X7DCL
"0x8954152d,0x29208086" => "Quanta/Intel ICH9 82801I 4 Port SATA/300", # Quanta QSSC-295MB
"0x8959152d,0x29208086,0x02" => "Quanta/Intel ICH9 82801I 4 Port SATA/300", # Quanta S47
"0x????????,0x29218086,0x02" => "Intel ICH9 82801IB 2 Port SATA/300",
"0x281e103c,0x29218086,0x02" => "HP/Intel ICH9 82801IB 2 Port SATA/300", # HP DC5800
"0x????????,0x29228086,0x02" => "Intel ICH9 82801I 6 Port SATA/300 AHCI",
"0x10001458,0x29228086" => "Gigabyte/Intel ICH9 82801I 6 Port SATA/300 AHCI", # Gigabyte R116
"0xdc8015d9,0x29228086" => "Supermicro/Intel ICH9 82801I 6 Port SATA/300 AHCI", # SM X7DCA-L
"0xd88015d9,0x29228086,0x02" => "Supermicro/Intel ICH9 82801I 6 Port SATA/300 AHCI", # SM X7SBL
"0x29228086,0x29228086,0x02" => "Intel ICH9 82801I 6 Port SATA/300 AHCI", # DCS S45, SM X8DTN
"0x34d08086,0x29228086,0x02" => "Intel ICH9 82801I 6 Port SATA/300 AHCI", # Intel X38ML
"0x537610f1,0x29228086,0x02" => "Tyan/Intel ICH9 82801I 6 Port SATA/300 AHCI", # Tyan S5376
"0x8954152d,0x29228086,0x02" => "Quanta/Intel ICH9 82801I 6 Port SATA/300 AHCI", # Quanta S45
"0x8959152d,0x29228086,0x02" => "Quanta/Intel ICH9 82801I 6 Port SATA/300 AHCI", # Quanta S47
"0x83661033,0x29228086,0x02" => "NEC/Intel ICH9 82801I 6 Port SATA/300 AHCI", # NEC Express5800/i120Ra-e1
"0x????????,0x29238086,0x02" => "Intel ICH9 82801IB 4 Port SATA/300 AHCI",
"0xb0051458,0x29238086,0x02" => "Gigabyte/Intel ICH9 82801IB 4 Port SATA/300 AHCI", # Gigabyte P35-S3G, Gigabyte G33M-S2L
"0x????????,0x29268086" => "Intel ICH9 82801I 2 Port SATA/300",
"0x00000000,0x29268086" => "Intel ICH9 82801I 2 Port SATA/300", # Dell R300
"0x020f1028,0x29268086,0x02" => "Dell/Intel ICH9 82801I 2 Port SATA/300", # Dell R300
"0x29268086,0x29268086" => "Intel ICH9 82801I 2 Port SATA/300", # DCS S45
"0x281e103c,0x29268086,0x02" => "HP/Intel ICH9 82801I 2 Port SATA/300", # HP DC5800
"0x31f4103c,0x29268086" => "HP/Intel ICH9 82801I 2 Port SATA/300", # DL180 G5, DL120 G5
"0xa48015d9,0x29268086" => "Supermicro/Intel ICH9 82801I 2 Port SATA/300", # SM X7DCL
"0xdc8015d9,0x29268086,0x02" => "Supermicro/Intel ICH9 82801I 2 Port SATA/300", # SM X7DCA-L
"0x8954152d,0x29268086" => "Quanta/Intel ICH9 82801I 2 Port SATA/300", # Quanta QSSC-295MB
"0x8959152d,0x29268086,0x02" => "Quanta/Intel ICH9 82801I 2 Port SATA/300", # Quanta S47
"0x????????,0x25a28086" => "Intel 6300ESB ATA/100", #
"0x32010e11,0x25a28086" => "Compaq/Intel 6300ESB ATA/100", # DL360 G4
"0x25a18086,0x25a28086" => "Intel 6300ESB ATA/100", # Intel
"0x34508086,0x25a28086" => "Intel 6300ESB ATA/100", # Intel SE7320VP2
"0x????????,0x25a38086" => "Intel 6300ESB SATA/150", #
"0x01651028,0x25a38086" => "Dell/Intel 6300ESB SATA/150", # PE750
"0x698015d9,0x25a38086" => "Supermicro/Intel 6300ESB SATA/150", # SM X6DLP
# http://download.intel.com/design/chipsets/datashts/31308201.pdf
"0x????????,0x26808086" => "Intel 631xESB SATA/300", #
"0x346c8086,0x26808086" => "Intel 631xESB SATA/300", # Intel S5000PAL
"0x34768086,0x26808086" => "Intel 631xESB SATA/300", # Intel S5000PSL
"0x34788086,0x26808086" => "Intel 631xESB SATA/300", # Intel S5000PSL-SAS
"0x347a8086,0x26808086,0x09" => "Intel 631xESB SATA/300", # Intel S5000XSL
"0x34848086,0x26808086" => "Intel 631xESB SATA/300", # Intel S5000VSA
"0x34cc8086,0x26808086,0x09" => "Intel 631xESB SATA/300", # Intel S7000FC4UR
"0x34d48086,0x26808086" => "Intel 631xESB SATA/300", # Intel S5400SF
"0x808015d9,0x26808086" => "Supermicro/Intel 631xESB SATA/300", # SM X7DB8
"0x848015d9,0x26808086" => "Supermicro/Intel 631xESB SATA/300", # SM X7DBR
"0x868015d9,0x26808086" => "Supermicro/Intel 631xESB SATA/300", # SM X7DVL-E
"0x928015d9,0x26808086" => "Supermicro/Intel 631xESB SATA/300", # SM X7DBR-3 (SATA)
"0x978015d9,0x26808086" => "Supermicro/Intel 631xESB SATA/300", # SM X7DBU
"0xb08015d9,0x26808086" => "Supermicro/Intel 631xESB SATA/300", # SM B7DBE
"0xb28015d9,0x26808086" => "Supermicro/Intel 631xESB SATA/300", # SM X7DVL-L
"0x01b21028,0x26808086" => "Dell/Intel 631xESB SATA/300", # PE2950
"0x01b31028,0x26808086" => "Dell/Intel 631xESB SATA/300", # PE1950
"0x31f6103c,0x26808086" => "HP/Intel 631xESB SATA/300", # DL180, DL160 G5
"0x31fe103c,0x26808086" => "HP/Intel 631xESB SATA/300", # DL140 G3
"0x8949152d,0x26808086" => "Quanta/Intel 631xESB SATA/300", # DCS S29
"0x894b152d,0x26808086" => "Quanta/Intel 631xESB SATA/300", # DCS S58
"0x00231170,0x26808086" => "Inventec/Intel 631xESB SATA/300", # Inventec Seabream
"0x003a1170,0x26808086,0x09" => "Inventec/Intel 631xESB SATA/300", # Inventec 5220
"0x539710f1,0x26808086,0x09" => "Tyan/Intel 631xESB SATA/300", # Tyan S5397
"0x????????,0x26818086" => "Intel 631xESB SATA/300 AHCI", #
"0x347a8086,0x26818086" => "Intel 631xESB SATA/300 AHCI", # Intel S5000XSL
"0x34768086,0x26818086" => "Intel 631xESB SATA/300 AHCI", # Intel S5000PSL
"0x34788086,0x26818086" => "Intel 631xESB SATA/300 AHCI", # Intel S5000PSL-SAS
"0x34848086,0x26818086" => "Intel 631xESB SATA/300 AHCI", # Intel S5000VSA
"0x34d48086,0x26818086,0x09" => "Intel 631xESB SATA/300 AHCI", # Intel S5400SF
"0x808015d9,0x26818086" => "Supermicro/Intel 631xESB SATA/300 AHCI", # SM X7DB8
"0x848015d9,0x26818086" => "Supermicro/Intel 631xESB SATA/300 AHCI", # SM X7DBR
"0x868015d9,0x26818086" => "Supermicro/Intel 631xESB SATA/300 AHCI", # SM X7DVL-E
"0x928015d9,0x26818086" => "Supermicro/Intel 631xESB SATA/300 AHCI", # SM X7DBR-3 (SATA)
"0x948015d9,0x26818086" => "Supermicro/Intel 631xESB SATA/300 AHCI", # SM X7DAL
"0x978015d9,0x26818086" => "Supermicro/Intel 631xESB SATA/300 AHCI", # SM X7DBU
"0xb28015d9,0x26818086" => "Supermicro/Intel 631xESB SATA/300 AHCI", # SM X7DVL-L
"0x00231170,0x26818086" => "Inventec/Intel 631xESB SATA/300 AHCI", # eslim
"0x31f6103c,0x26818086,0x09" => "HP/Intel 631xESB SATA/300 AHCI", # DL160 G5
"0x31fe103c,0x26818086" => "HP/Intel 631xESB SATA/300 AHCI", # DL140 G3
"0x8949152d,0x26818086" => "Quanta/Intel 631xESB SATA/300 AHCI", # DCS S29
"0x894b152d,0x26818086" => "Quanta/Intel 631xESB SATA/300 AHCI", # DCS S58
"0x03251014,0x26818086,0x09" => "IBM/Intel 631xESB SATA/300 AHCI", # IBM dx340
"0x????????,0x26828086" => "Intel 631xESB SATA/300 RAID", #
"0x346d8086,0x26828086" => "Intel 631xESB SATA/300 RAID", # Intel S5000PAL
"0x34d48086,0x26828086,0x09" => "Intel 631xESB SATA/300 RAID", # Intel S5400SF
"0x02dd1014,0x26828086" => "IBM/Intel 631xESB SATA/300 RAID", # IBM x3550
"0x31f6103c,0x26828086,0x09" => "HP/Intel 631xESB SATA/300 RAID", # DL160 G5
"0x31fe103c,0x26828086" => "HP/Intel 631xESB SATA/300 RAID", # DL140 G3
"0x8949152d,0x26828086" => "Quanta/Intel 631xESB SATA/300 RAID", # DCS S29
"0x8950152d,0x26828086" => "Quanta/Intel 631xESB SATA/300 RAID", # DCS S29, DCS S58
"0x868015d9,0x26828086" => "Supermicro/Intel 631xESB SATA/300 RAID", # SM X7DVL-E
"0x928015d9,0x26828086,0x09" => "Supermicro/Intel 631xESB SATA/300 RAID", # SM X7DBR-3 (SATA)
"0x978015d9,0x26828086,0x09" => "Supermicro/Intel 631xESB SATA/300 RAID", # SM X7DBU
"0x978115d9,0x26828086,0x09" => "Supermicro/Intel 631xESB SATA/300 RAID", # SM X7DBU
"0xb28015d9,0x26828086" => "Supermicro/Intel 631xESB SATA/300 RAID", # SM X7DVL-L
"0x????????,0x269e8086" => "Intel 631xESB ATA/133", #
"0x00000000,0x269e8086" => "Intel 631xESB ATA/133", # Dell R900
"0x346c8086,0x269e8086" => "Intel 631xESB ATA/133", # Intel S5000PAL
"0x346d8086,0x269e8086" => "Intel 631xESB ATA/133", # Intel S5000PAL
"0x34768086,0x269e8086" => "Intel 631xESB ATA/133", # Intel S5000PSL
"0x34788086,0x269e8086" => "Intel 631xESB ATA/133", # Intel S5000PSL-SAS
"0x347a8086,0x269e8086,0x09" => "Intel 631xESB ATA/133", # Intel S5000XSL
"0x34848086,0x269e8086" => "Intel 631xESB ATA/133", # Intel S5000VSA
"0x34d48086,0x269e8086" => "Intel 631xESB ATA/133", # Intel S5400SF
"0x01b21028,0x269e8086" => "Dell/Intel 631xESB ATA/133", # PE2950
"0x01b31028,0x269e8086" => "Dell/Intel 631xESB ATA/133", # PE1950
"0x01f01028,0x269e8086,0x09" => "Dell/Intel 631xESB ATA/133", # Dell R900
"0x31fe103c,0x269e8086" => "HP/Intel 631xESB ATA/133", # DL360 G5, DL380 G5, DL140 G3, DL180, DL580 G5
"0x02dd1014,0x269e8086" => "IBM/Intel 631xESB ATA/133", # IBM x3550
"0x808015d9,0x269e8086" => "Supermicro/Intel 631xESB ATA/133", # SM X7DB8
"0x838015d9,0x269e8086,0x09" => "Supermicro/Intel 631xESB ATA/133", # SM X7DBP
"0x848015d9,0x269e8086" => "Supermicro/Intel 631xESB ATA/133", # SM X7DBR
"0x868015d9,0x269e8086" => "Supermicro/Intel 631xESB ATA/133", # SM X7DVL-E
"0x928015d9,0x269e8086" => "Supermicro/Intel 631xESB ATA/133", # SM X7DBR-3 (SAS)
"0x948015d9,0x269e8086" => "Supermicro/Intel 631xESB ATA/133", # SM X7DAL
"0xb18015d9,0x269e8086" => "Supermicro/Intel 631xESB ATA/133", # SM X7DBi+
"0xb28015d9,0x269e8086" => "Supermicro/Intel 631xESB ATA/133", # SM X7DVL-L
"0x8949152d,0x269e8086" => "Quanta/Intel 631xESB ATA/133", # DCS S29
"0x894b152d,0x269e8086" => "Quanta/Intel 631xESB ATA/133", # DCS-SAS
"0x00231170,0x269e8086" => "Inventec/Intel 631xESB ATA/133", # eslim, Inventec Seabream
"0x003a1170,0x269e8086,0x09" => "Inventec/Intel 631xESB ATA/133", # Inventec 5220
"0x83361033,0x269e8086" => "NEC/Intel 631xESB ATA/133", # NEC Express5800/120Ri-2
"0x539710f1,0x269e8086,0x09" => "Tyan/Intel 631xESB ATA/133", # Tyan S5397
"0x????????,0x3a208086,0x00" => "Intel ICH10 82801J 4 Port SATA/300",
"0xb0021458,0x3a208086,0x00" => "Gigabyte/Intel ICH10 82801J 4 Port SATA/300", # Gigabyte EP45-DS3R
"0x????????,0x3a228086,0x00" => "Intel ICH10 82801J 6 Port SATA/300 AHCI",
"0x82d41043,0x3a228086,0x00" => "Asus/Intel ICH10 82801J 6 Port SATA/300 AHCI", # Asus P5Q-Deluxe
"0xb0051458,0x3a228086,0x00" => "Gigabyte/Intel ICH10 82801J 6 Port SATA/300 AHCI", # Gigabyte EP45-DS3R
"0x????????,0x3a268086,0x00" => "Intel ICH10 82801J 2 Port SATA/300",
"0xb0021458,0x3a268086,0x00" => "Gigabyte/Intel ICH10 82801J 2 Port SATA/300", # Gigabyte EP45-DS3R
"0x00261170,0x036e10de" => "Inventec/nVIDIA MCP55 ATA/133", # IR2400
"0x00261170,0x037f10de" => "Inventec/nVIDIA MCP55 SATA/300", # IR2400
"0x????????,0x005310de" => "nVIDIA nForce4 ATA/133", #
"0x3207103c,0x005310de" => "HP/nVIDIA nForce4 ATA/133", # DL145 G2
"0x31f8103c,0x005310de" => "HP/nVIDIA nForce4 ATA/133", # DL585 G2
"0x286510f1,0x005310de" => "Tyan/nVIDIA nForce4 ATA/133", # Tyan S2865
"0x289110f1,0x005310de" => "Tyan/nVIDIA nForce4 ATA/133", # Tyan S4881
"0x00161170,0x005310de" => "Inventec/nVIDIA nForce4 ATA/133", # Inventec IR2300
"0x00171170,0x005310de" => "Inventec/nVIDIA nForce4 ATA/133", # Inventec IR2350
"0x81621043,0x005310de" => "Asus/nVIDIA nForce4 ATA/133", # Asus K8N-DRE
"0x5348108e,0x005310de" => "Sun/nVIDIA nForce4 ATA/133", # Sun X2100
"0x????????,0x005410de" => "nVIDIA nForce4 SATA/150", #
"0x286510f1,0x005410de" => "Tyan/nVIDIA nForce4 SATA/150", # Tyan S2865
"0x289110f1,0x005410de" => "Tyan/nVIDIA nForce4 SATA/150", # Tyan S4881
"0x00161170,0x005410de" => "Inventec/nVIDIA nForce4 SATA/150", # Inventec IR2300
"0x00171170,0x005410de" => "Inventec/nVIDIA nForce4 SATA/150", # Inventec IR2350
"0x81621043,0x005410de" => "Asus/nVIDIA nForce4 SATA/150", # Asus K8N-DRE
"0x5348108e,0x005410de" => "Sun/nVIDIA nForce4 SATA/150", # Sun X2100
"0x????????,0x005510de" => "nVIDIA nForce4 SATA/150", #
"0x3207103c,0x005510de" => "HP/nVIDIA nForce4 SATA/150", # DL145 G2
"0x286510f1,0x005510de" => "Tyan/nVIDIA nForce4 SATA/150", # Tyan S2865
"0x289110f1,0x005510de" => "Tyan/nVIDIA nForce4 SATA/150", # Tyan S4881
"0x00161170,0x005510de" => "Inventec/nVIDIA nForce4 SATA/150", # Inventec IR2300
"0x00171170,0x005510de" => "Inventec/nVIDIA nForce4 SATA/150", # Inventec IR2350
"0x81621043,0x005510de" => "Asus/nVIDIA nForce4 SATA/150", # Asus K8N-DRE
"0x5348108e,0x005510de" => "Sun/nVIDIA nForce4 SATA/150", # Sun X2100
},
'other' => {
"0x0001177d,0x0001177d,0x01" => { "type" => "Crypto", "model" => "Cavium Nitrox XL" },
# Nitrox PX Processor - CN1620(proc) NHB(half-height)
# "0x0001177d,0x0010177d,0x01" => { "type" => "Crypto", "model" => "Cavium Nitrox XL" },
},
);
my(%cpu_models) = (
# http://www.cpu-world.com/index.html
# for AMD, many procs will share same family/model/stepping - e.g. normal, HE, EE, etc.
# for HE info you have to read cpu string
# http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf
"AMD-15,4,8" => ["Newcastle CG, 64-bit, 130nm, L2: 512KB",1,1,0], # e.g. Athlon 64 3000+
"AMD-15,5,0" => ["SledgeHammer, 64-bit, 130nm, L2: 1MB",1,1,0], # e.g. 242
"AMD-15,5,1" => ["SledgeHammer B3, 64-bit, 130nm, L2: 1MB",1,1,0], # stepping SH7-B3, socket940 - e.g. 242, 240
"AMD-15,5,8" => ["SledgeHammer C0, 64-bit, 130nm, L2: 1MB",1,1,0], # stepping SH7-C0, socket940 - e.g. 848, 246, 244, 240
"AMD-15,5,10" => ["SledgeHammer CG, 64-bit, 130nm, L2: 1MB",1,1,0], # stepping CG, socket940 - e.g. 250, 244, 850, 240EE, 246HE
"AMD-15,31,0" => ["64-bit, 90nm, L2: 512KB",1,1,0], # e.g. Athlon 64 3200+
"AMD-15,33,0" => ["64-bit, dual-core, 90nm, L2: 2MB",2,1,0], # e.g. 875 (dual-core)
"AMD-15,33,2" => ["64-bit, dual-core, 90nm, L2: 2MB",2,1,0], # e.g. 275 (dual-core)
"AMD-15,1,2" => ["64-bit, dual-core, 90nm, L2: 2MB",2,1,0], # buggy linux kernel 2.4.22-y24 on bangles.ink?
"AMD-15,35,2" => ["64-bit, dual-core, 90nm, L2: 2MB",2,1,0], # e.g. 180 (dual-core)
"AMD-15,37,1" => ["64-bit, 90nm, L2: 1MB",1,1,0], # stepping SH-E4, socket940 (not dual-core)
"AMD-15,65,2" => ["64-bit, dual-core, 90nm, L2: 2MB",2,1,0], # e.g. 8220 SE
"AMD-15,65,3" => ["64-bit, dual-core, 65nm, L2: 2MB",2,1,0], # e.g. 2220, not sure about 65nm - YYYY
"AMD-15,75,2" => ["Windsor F2, 64-bit, dual-core, 90nm, L2: 1MB",2,1,0], # e.g. Athlon 64 X2 4200+
"AMD-15,107,1" => ["64-bit, dual-core, 90nm, L2: 2MB",2,1,0], # e.g. Athlon 64 X2 4000+
"AMD-16,2,3" => [
["Opteron", ["Barcelona B3, 64-bit, quad-core, 65nm, L2: 2MB, L3: 2MB",4,1,0]], # e.g. Opteron 2352
["Phenom", ["Agena B3, 64-bit, quad-core, 65nm, L2: 2MB, L3: 2MB",4,1,0]], # e.g. Phenom 9850
],
# http://processorfinder.intel.com/
# http://www.intel.com/design/xeon/applnots/24161830.pdf#search='intel%20cpuid'
# http://en.wikipedia.org/wiki/Intel_Next_Generation_Microarchitecture
# http://balusc.xs4all.nl/srv/har-cpu-int-p1.php
# click "cpu search", select intel brand, and type f-6-5 in family, search
# http://www.cpu-world.com/index.html
"Intel-6,1,7" => ["PPro, 350nm, L2: 256KB/512KB",1,1,0], # PPro
"Intel-6,1,9" => ["PPro, 350nm, L2: 256KB/512KB/1MB",1,1,0], # PPro
"Intel-6,3,3" => ["Klamath C0, 350nm, L2: 512KB half-speed",1,1,0], # P2
"Intel-6,3,4" => ["Klamath C1, 350nm, L2: 512KB half-speed",1,1,0], # P2
"Intel-6,5,0" => ["Deschutes A0, 250nm, L2: 512KB half-speed",1,1,0], # P2
"Intel-6,5,1" => ["Deschutes A1, 250nm, L2: 512KB half-speed",1,1,0], # P2
"Intel-6,5,2" => ["Deschutes B0, 250nm, L2: 512KB half-speed",1,1,0], # P2
"Intel-6,5,3" => ["Deschutes B1, 250nm, L2: 512KB half-speed",1,1,0], # P2
"Intel-6,7,2" => ["Katmai, 250nm, L2: 512KB half-speed",1,1,0], # P3
"Intel-6,7,3" => ["Katmai, 250nm, L2: 512KB half-speed",1,1,0], # P3
"Intel-6,8,1" => ["Coppermine, 180nm, L2: 256KB",1,1,0], # P3
"Intel-6,8,3" => ["Coppermine, 180nm, L2: 256KB",1,1,0], # P3
"Intel-6,8,6" => ["Coppermine, 180nm, L2: 256KB",1,1,0], # P3
"Intel-6,9,5" => ["Banias B1, 130nm, L2: 1MB",1,1,0], # Pentium M
"Intel-6,8,10" => ["Coppermine, 180nm, L2: 256KB",1,1,0], # P3
"Intel-6,10,1" => ["Cascades A1, 180nm, L2: 2MB",1,1,0], # Pentium III Xeon 700
"Intel-6,11,1" => ["Tualatin, 130nm, L2: 256KB/512KB",1,1,0], # P3
"Intel-6,11,4" => ["Tualatin, 130nm, L2: 512KB",1,1,0], # P3
"Intel-6,13,8" => ["Dothan C0, 90nm, L2: 2MB",1,1,0], # e.g. Pentium M 740
"Intel-6,14,4" => ["Sossaman B0, dual-core, 65nm, L2: 2MB",2,1,2], # mobile P3 (same as Yonah)
"Intel-6,14,8" => ["Sossaman C0, dual-core, 65nm, L2: 2MB",2,1,2], # mobile P3 (same as Yonah)
"Intel-6,14,12" => ["Sossaman D0, dual-core, 65nm, L2: 2MB",2,1,2], # mobile P3 (same as Yonah)
"Intel-6,15,2" => [
["Core", ["Allendale L2, 64-bit, dual-core, 65nm, L2: 2MB",2,1,2]],
["Xeon", ["Conroe L2, 64-bit, dual-core, 65nm, L2: 2MB",2,1,2]], # only 3040, 3050
],
"Intel-6,15,4" => ["Woodcrest, 64-bit, dual-core, 65nm, L2: 4MB",2,1,2],
"Intel-6,15,5" => [
["Core", ["Conroe B1, 64-bit, dual-core, 65nm, L2: 2MB",2,1,2]], # Core 2 Duo
["Xeon 3", ["Conroe B1, 64-bit, dual-core, 65nm, L2: 2MB",2,1,2]], # Core 2 Duo
["Xeon", ["Woodcrest B1, 64-bit, dual-core, 65nm, L2: 4MB",2,1,2]], # Core 2 Duo DP
],
"Intel-6,15,6" => [
["Core 2 [LTX]7", ["Merom B2, 64-bit, dual-core, 65nm, L2: 4MB",2,1,2]],
["Core 2 T5", ["Merom B2, 64-bit, dual-core, 65nm, L2: 2MB",2,1,2]],
["Core 2 6(300|400)", ["Conroe B2, 64-bit, dual-core, 65nm, L2: 2MB",2,1,2]],
["Core", ["Conroe B2, 64-bit, dual-core, 65nm, L2: 4MB",2,1,2]],
["Xeon 30(40|50)", ["Conroe B2, 64-bit, dual-core, 65nm, L2: 2MB",2,1,2]],
["Xeon 3", ["Conroe B2, 64-bit, dual-core, 65nm, L2: 4MB",2,1,2]],
["Xeon", ["Woodcrest B2, 64-bit, dual-core, 65nm, L2: 4MB",2,1,2]],
],
"Intel-6,15,7" => [ # B3 stepping is only quad-core
["Quad", ["Kentsfield B3, 64-bit, quad-core, 65nm, L2: 8MB",4,1,2]], # Core 2 Quad
["Xeon X3", ["Kentsfield B3, 64-bit, quad-core, 65nm, L2: 8MB",4,1,2]], # Core 2 Quad
["Xeon", ["Clovertown B3, 64-bit, quad-core, 65nm, L2: 8MB",4,1,2]], # Core 2 Xeon DP
["Core", ["Kentsfield B3, 64-bit, quad-core, 65nm, L2: 8MB",4,1,2]], # Core 2 Quad
],
"Intel-6,15,9" => ["Tigerton, 64-bit, quad-core, 65nm, L2: 8MB",4,1,2],
"Intel-6,15,10" => [
["Core 2 [LTX]7", ["Merom E1, 64-bit, dual-core, 65nm, L2: 4MB",2,1,2]],
],
"Intel-6,15,11" => [
["Xeon 30", ["Conroe G0, 64-bit, dual-core, 65nm, L2: 4MB",2,1,2]],
["Xeon 51", ["Woodcrest G0, 64-bit, dual-core, 65nm, L2: 4MB",2,1,2]],
["Xeon 72", ["Tigerton-DC G0, 64-bit, dual-core, 65nm, L2: 8MB",2,1,2]],
["Xeon X32", ["Kentsfield G0, 64-bit, quad-core, 65nm, L2: 8MB",4,1,2]],
["Xeon [LEX]53", ["Clovertown G0, 64-bit, quad-core, 65nm, L2: 8MB",4,1,2]],
["Xeon [LEX]73", ["Tigerton G0, 64-bit, quad-core, 65nm, L2: 8MB",4,1,2]],
["Xeon", ["Clovertown G0, 64-bit, quad-core, 65nm, L2: 8MB",4,1,2]],
["Solo", ["Merom G0, 64-bit, single-core, 65nm, L2: 1MB",1,1,2]],
["Duo Mobile", ["Merom G0, 64-bit, dual-core, 65nm, L2: 4MB",2,1,2]],
["Core 2 [LTX]7", ["Merom G0, 64-bit, dual-core, 65nm, L2: 4MB",2,1,2]],
["Duo", ["Allendale G0, 64-bit, dual-core, 65nm, L2: 4MB",2,1,2]],
["Quad", ["Kentsfield G0, 64-bit, quad-core, 65nm, L2: 8MB",4,1,2]],
],
"Intel-6,22,1" => [
["Celeron", ["Merom A1, 64-bit, 65nm, L2: 1M",1,1,2]],
],
"Intel-6,23,1" => [
["Xeon", ["Harpertown, 64-bit, quad-core, 45nm, L2: 12MB",4,1,3]],
],
"Intel-6,23,4" => [
["Xeon", ["Harpertown, 64-bit, quad-core, 45nm, L2: 12MB",4,1,3]],
],
"Intel-6,23,6" => [
["Core 2 Duo [PT]8", ["Penryn M0, 64-bit, dual-core, 45nm, L2: 3MB",2,1,3]],
["Core 2 Duo E7", ["Wolfdale M0, 64-bit, dual-core, 45nm, L2: 3MB",2,1,3]],
["Core 2 Duo E8", ["Wolfdale C0, 64-bit, dual-core, 45nm, L2: 6MB",2,1,3]],
["Xeon [LEX]52", ["Wolfdale-DP C0, 64-bit, dual-core, 45nm, L2: 6MB",2,1,3]],
["Xeon [LEX]54", ["Harpertown C0, 64-bit, quad-core, 45nm, L2: 12MB",4,1,3]],
["Xeon", ["Harpertown C0, 64-bit, quad-core, 45nm, L2: 12MB",4,1,3]],
],
"Intel-6,23,7" => [
["Quad Q93", ["Yorkfield M1, 64-bit, quad-core, 45nm, L2: 6MB",4,1,3]],
["Quad Q9", ["Yorkfield C1, 64-bit, quad-core, 45nm, L2: 12MB",4,1,3]],
["Xeon X33", ["Yorkfield C1, 64-bit, quad-core, 45nm, L2: 12MB",4,1,3]],
["Xeon [LEX]52", ["Wolfdale-DP C1, 64-bit, dual-core, 45nm, L2: 6MB",2,1,3]],
["Xeon [LEX]54", ["Harpertown C1, 64-bit, quad-core, 45nm, L2: 12MB",4,1,3]],
["Xeon", ["Harpertown C1, 64-bit, quad-core, 45nm, L2: 12MB",4,1,3]],
],
"Intel-6,23,10" => [
["Quad Q9", ["Yorkfield E0, 64-bit, quad-core, 45nm, L2: 12MB",4,1,3]],
["Xeon X3320", ["Yorkfield R0, 64-bit, quad-core, 45nm, L2: 6MB",4,1,3]],
["Xeon X33", ["Yorkfield E0, 64-bit, quad-core, 45nm, L2: 12MB",4,1,3]],
["Xeon [LEX]52", ["Wolfdale-DP E0, 64-bit, dual-core, 45nm, L2: 6MB",2,1,3]],
["Xeon [LEX]54", ["Harpertown E0, 64-bit, quad-core, 45nm, L2: 12MB",4,1,3]],
["Xeon", ["Harpertown E0, 64-bit, quad-core, 45nm, L2: 12MB",4,1,3]],
],
"Intel-6,26,2" => [
["Xeon", ["Nehalem B0, 64-bit, 45nm, L3: 8MB",4,2,4]],
],
"Intel-6,28,2" => [
["Atom", ["Silverthorne C0, 64-bit, 45nm, L2: 512KB",1,2,3]],
],
"Intel-15,1,2" => ["Willamette D0, 180nm, L2: 256KB",1,1,0], # P4
"Intel-15,1,3" => [
["Celeron", ["Willamette E0, 180nm, L2: 128KB",1,1,0]], # P4
["Pentium", ["Willamette E0, 180nm, L2: 256KB",1,1,0]], # P4
],
"Intel-15,2,2" => ["Gallatin A0, 130nm, L3: 1MB",1,2,0], # P4 Xeon MP
"Intel-15,2,4" => [
["Pentium", ["Northwood B0, 130nm, L2: 512KB",1,1,0]], # P4, no support for HT
["Xeon", ["Prestonia B0, 130nm, L2: 512KB",1,2,0]], # P4 Xeon DP
],
"Intel-15,2,5" => [
["Pentium", ["Northwood M0, 130nm, L2: 512KB",1,2,0]], # P4, some low end GHz parts do not support HT
["Xeon MP", ["Gallatin B1, 130nm, L3: 1MB",1,2,0]], # P4 Xeon MP
["Xeon", ["Prestonia M0, 130nm, L2: 512KB",1,2,0]], # P4 Xeon DP
],
"Intel-15,2,6" => ["Gallatin C0, 130nm, L3: 2MB",1,2,0], # P4 Xeon MP
"Intel-15,2,7" => [
["Pentium 4 3060", ["Northwood C1, 130nm, L2: 512KB",1,2,0]], # P4, accoring to Intel only 3.06GHz parts do support HT (e.g. fe2.rd.aue)
["Pentium", ["Northwood C1, 130nm, L2: 512KB",1,1,0]], # P4, accoring to Intel only 3.06GHz parts do support HT (e.g. fe2.rd.aue)
["Xeon", ["Prestonia C1, 130nm, L2: 512KB",1,2,0]], # P4 Xeon DP
],
"Intel-15,2,9" => [
["Celeron", ["Northwood D1, 130nm, L2: 128KB",1,1,0]], # P4
["Pentium", ["Northwood D1, 130nm, L2: 512KB",1,2,0]], # P4, some low end GHz parts do not support HT
["Xeon", ["Prestonia D1, 130nm, L2: 512KB",1,2,0]], # P4 Xeon DP
],
"Intel-15,3,3" => [
["Celeron", ["Prescott C0, 64-bit, 90nm, L2: 1MB",1,1,0]], # P4
["Pentium", ["Prescott C0, 64-bit, 90nm, L2: 1MB",1,2,0]], # P4, some low end GHz parts do not support HT
],
"Intel-15,3,4" => [
["Celeron", ["Prescott D0, 64-bit, 90nm, L2: 1MB",1,1,0]], # P4
["Pentium", ["Prescott D0, 64-bit, 90nm, L2: 1MB",1,2,0]], # P4, some low end GHz parts do not support HT
["Xeon", ["Nocona D0, 64-bit, 90nm, L2: 1MB",1,2,0]], # P4 Xeon DP
],
"Intel-15,4,1" => [
["Celeron", ["Prescott E0, 64-bit, 90nm, L2: 1MB",1,1,0]], # P4
["Pentium", ["Prescott E0, 64-bit, 90nm, L2: 1MB",1,2,0]], # P4, some low end GHz parts do not support HT
["Xeon MP", ["Cranford A0, 64-bit, 90nm, L2: 1MB",1,2,0]], # P4 Xeon MP
["Xeon", ["Nocona E0, 64-bit, 90nm, L2: 1MB",1,2,0]], # P4 Xeon DP
],
"Intel-15,4,3" => [
["Pentium", ["Prescott N0, 64-bit, 90nm, L2: 2MB",1,2,0]], # P4, full support for HT
["Xeon", ["Irwindale N0, 64-bit, 90nm, L2: 2MB",1,2,0]], # P4 Xeon DP
],
"Intel-15,4,4" => ["Smithfield A0, 64-bit, dual-core, 90nm, L2: 2MB",2,1,0], # Pentium D
"Intel-15,4,7" => ["Smithfield B0, 64-bit, dual-core, 90nm, L2: 2MB",2,1,0], # Pentium D
"Intel-15,4,8" => ["Paxville A0, 64-bit, dual-core, 90nm, L2: 2MB",2,2,0], # PD Xeon MP
"Intel-15,4,9" => [
["Pentium", ["Prescott G1, 64-bit, 90nm, L2: 1MB",1,2,0]], # P4
["Xeon", ["Nocona G1, 64-bit, 90nm, L2: 1MB",1,2,0]], # P4 Xeon DP
],
"Intel-15,4,10" => [
["Pentium", ["Prescott R0, 64-bit, 90nm, L2: 2MB",1,2,0]], # P4
["Xeon", ["Irwindale R0, 64-bit, 90nm, L2: 2MB",1,2,0]], # P4 Xeon DP
],
"Intel-15,6,2" => [
["Pentium", ["Presler B1, 64-bit, dual-core, 65nm, L2: 4MB",2,1,0]], # Pentium D
["Xeon", ["Dempsey B1, 64-bit, dual-core, 65nm, L2: 4MB",2,1,0]], # PD Xeon DP
],
"Intel-15,6,4" => [
["Pentium", ["Presler C1, 64-bit, dual-core, 65nm, L2: 4MB",2,1,0]], # Pentium D
["Xeon", ["Dempsey C1, 64-bit, dual-core, 65nm, L2: 4MB",2,2,0]], # PD Xeon DP
],
"Intel-15,6,5" => [
["Pentium", ["Presler D0, 64-bit, dual-core, 65nm, L2: 4MB",2,1,0]], # Pentium D
],
"Intel-15,6,8" => [
["Xeon", ["Tulsa B0, 64-bit, dual-core, 65nm, L2: 4MB",2,2,0]], # PD Xeon MP
],
);
# http://www.stchas.edu/faculty/mcse-cisco/a-plus/Fuszner/SANDRA/program/Sandra.bio
my(%jedec) = (
"2C" => "Micron",
"AD" => "Hynix",
"C1" => "Infineon",
"CE" => "Samsung",
"7F61" => "Wintec",
"7F94" => "Smart Modular",
"7F98" => "Kingston",
"7FA8" => "Simple Tech",
"7F7F9E" => "Corsair",
"7F7FFE" => "Elpida",
"7F7F7F0B" => "Nanya",
"7F7F7F16" => "Netlist",
"7F7F7F83" => "Buffalo",
"7F7F7F7F46" => "Legacy",
"7F7F7F7F43" => "Ramaxel",
);
my(%memory_models) = (
# 2Rx4 with ECC ==> 36 chips (2R ==> 144 bits / x4 == 36)
# 1Rx4 with ECC ==> 18 chips (1R ==> 72 bits / x4 == 18)
# 4Rx8 with ECC ==> 36 chips (4R ==> 288 bits / x8 == 36)
# 2Rx8 with ECC ==> 18 chips
# 1Rx8 with ECC ==> 9 chips
# 2Rx16 ==> 8 chips
# 1Rx16 ==> 4 chips
# 2Rx4 DDP ==> 36 chips / 2 (DDP) == 18 chips
# DDP = dual die package (2 dies embedded on one chip)
# http://www.digchips.com/datasheets/search.php
# http://www.datasheetcatalog.com/
# amb info for fbdimms
# http://developer.intel.com/technology/memory/FBDIMM/667_FBDIMM_web_posting_results_ww30_5.pdf
# Unknown
"GM431-QAA-INTD1F" => "2GB PC2-5300 DDR2-667 ECC Fully Buffered CL5",
"GR2DF56724QB667C" => "2GB PC2-5300 DDR2-667 ECC Fully Buffered CL5",
"GR2DF56728MT667N" => "2GB PC2-5300 DDR2-667 ECC Fully Buffered CL5",
"GR2DF56728EL667Q" => "2GB PC2-5300 DDR2-667 ECC Fully Buffered CL5",
"GC6CD404" => "512MB PC-2700 Legend DDR-333 Unbuffered CL2.5 2R",
"FC7CD905" => "256MB PC-3200 Legend DDR-400 Unbuffered CL3",
"GC7CD905" => "512MB PC-3200 Legend DDR-400 Unbuffered CL3 2R",
"7D-22KB5K1FPP" => "1GB PC2-4200 DDR2-533 Unbuffered CL4 2R",
"HPQ00-21183-723SCU" => "2GB PC-2700 HP/Simple DDR-333 ECC Registered CL2.5 2Rx4",
"140134-031" => "256MB PC133 HP SDRAM Unbuffered CL3",
"127006-041" => "512MB PC133 HP/Micron SDRAM ECC Registered CL3 1Rx4",
"512E40K3R24" => "512MB PC2-3200 Itaucom DDR2-400 ECC Registered CL3",
"M0840038" => "2GB PC2-4200 PQI DDR2-533 Unbuffered CL3",
# Ramaxel
"RML1040HB38D6F-533" => "512MB PC2-4200 Ramaxel DDR2-533 Unbuffered CL4 1Rx4",
"RML1040MD38D6F-533" => "512MB PC2-4200 Ramaxel DDR2-533 Unbuffered CL4 1Rx8",
"RML1040EG38D6W-533" => "512MB PC2-4200 Ramaxel DDR2-533 Unbuffered CL4",
"RML1040EG38D6F-533" => "512MB PC2-4200 Ramaxel DDR2-533 Unbuffered CL4 1Rx8",
"RML1040E38D6F-533" => "512MB PC2-4200 Ramaxel DDR2-533 Unbuffered CL4",
"RML1040S38D6F-533" => "512MB PC2-4200 Ramaxel DDR2-533 Unbuffered CL4 1Rx8",
"RML1320EG38D7W-667" => "1GB PC2-5300 Ramaxel DDR2-667 Unbuffered CL5",
"RML1520EC48D7W-800" => "1GB PC2-6400 Ramaxel DDR2-800 Unbuffered CL6",
# Transend
"TS64MLD64V4F" => "512MB PC-3200 Transend DDR-400 Unbuffered CL2.5 2Rx8",
"TS128MLD64V3J" => "1GB PC-2700 Transend DDR-333 Unbuffered CL2.5 2Rx8",
"TS128MLD64V4J" => "1GB PC-3200 Transend DDR-400 Unbuffered CL3 2Rx8",
"TS64MLQ64V4J" => "512MB PC2-3200 Transend DDR2-400 Unbuffered CL3 1Rx8",
"TS64MLQ64V5J" => "512MB PC2-4200 Transend DDR2-533 Unbuffered CL4 1Rx8",
"JM388Q643A-5" => "1GB PC2-4200 Transend DDR2-533 Unbuffered CL4 2Rx8",
"JM667QLJ-1G" => "1GB PC2-5300 Transend DDR2-667 Unbuffered CL5 2Rx8",
"JM667QLU-2G" => "2GB PC2-5300 Transend DDR2-667 Unbuffered CL5 2Rx8",
# Aeneon
"AET660UD00-30DB97X" => "512MB PC2-5300 Aeneon DDR2-667 Unbuffered CL5 1Rx8",
# http://www.corsairmicro.com/main/prddr.html
"CM766S512-133" => "512MB PC133 Corsair SDRAM ECC Registered CL3 1Rx4",
"CM73SD512R-2100" => "512MB PC-2100 Corsair DDR-266 ECC Registered CL2.5 1Rx4",
"CM74SD1024R-2100" => "1GB PC-2100 Corsair DDR-266 ECC Registered CL2.5 2Rx4",
"CM66SD1024-2700" => "1GB PC-2700 Corsair DDR-333 Unbuffered CL2.5 2Rx4",
"CM73DD1024R-400" => "1GB PC2-3200 Corsair DDR2-400 ECC Registered CL3 1Rx4",
"CM2X512-5400C4" => "512MB PC2-5400 Corsair DDR2-675 Unbuffered CL4 2Rx8", # specs are correct
# Kingston
"KT326667-041-INCE5" => "256MB PC-3200 Kingston DDR-400 Unbuffered CL3",
"KT305957-041-INCE5" => "256MB PC-2700 Kingston DDR-333 Unbuffered CL2.5",
"UW728-IFA-INTC0S" => "1GB PC2-4200 Dell/Kingston DDR2-533 ECC Fully Buffered CL4",
"UW729-IFA-INTC0S" => "2GB PC2-4200 Dell/Kingston DDR2-533 ECC Fully Buffered CL4 2Rx4",
"KG7132-IFA-INTC0S" => "2GB PC2-4200 Dell/Kingston DDR2-533 ECC Fully Buffered CL4",
"9W657-NAA-INTC0F" => "2GB PC2-5300 Dell/Kingston DDR2-667 ECC Fully Buffered CL5 2R",
"GM431-NAA-INTD1F" => "2GB PC2-5300 Dell/Kingston DDR2-667 ECC Fully Buffered CL5",
"KD6502-ELG" => "1GB PC2-5300 Kingston DDR2-667 Unbuffered CL5 2Rx8",
"KD6502-ELJ" => "1GB PC2-5300 Kingston DDR2-667 Unbuffered CL5 2Rx8",
"KX1563-NAB" => "2GB PC2-3200 Kingston DDR2-400 ECC Registered CL3",
"9905316-005.A04LF" => "1GB PC2-5300 Kingston DDR2-667 Unbuffered CL5 2Rx8", # KVR667D2N5/1G
"9905316-131.A01LF" => "1GB PC2-6400 Kingston DDR2-800 Unbuffered CL6",
"9905316-132.A01LF" => "2GB PC2-6400 Kingston DDR2-800 Unbuffered CL6",
"DGM431NABINTD1F" => "2GB PC2-5300 Kingston DDR2-667 ECC Fully Buffered CL5 2R",
# Viking
# http://www.vikingcomponents.com/brochure/details.asp
"VR5ER567214EBPD1" => "2GB PC2-3200 Viking DDR2-400 ECC Registered CL3 2Rx4",
# Simple Tech
"ST72P4T128M-A05A" => "1GB PC2-3200 Simple DDR2-400 ECC Registered CL3 1R",
"S1024R3NN2QK-I" => "1GB PC2-5300 Simple DDR2-667 Unbuffered CL5 2R",
# http://www.legacyelectronics.com/products.php
"L512872M20A-50." => "1GB PC2-3200 Legacy DDR2-400 ECC Registered CL3 1Rx4",
"L527R5A2AHA-50." => "2GB PC2-3200 Legacy DDR2-400 ECC Registered CL3 1Rx4",
"L527R5A2AHA-37R" => "2GB PC2-4200 Legacy DDR2-533 ECC Registered CL4 1Rx4",
"L547R5A2A4B-50Y" => "4GB PC2-3200 Legacy DDR2-400 ECC Registered CL3 2Rx4",
# http://www.qimonda.com/index.html
"HYS64V32220GU-7.5." => "256MB PC133 Infineon SDRAM Unbuffered CL3",
# http://www.qimonda.com/system/galleries/download/products/nomenclature_ddr_ddr2.pdf
"64D16301[GHE]U6B" => "128MB PC-2700 Infineon DDR-333 Unbuffered CL2.5 1Rx8",
"64D32000[GHE]U7B" => "256MB PC-2100 Infineon DDR-266 Unbuffered CL2 1Rx8",
"64D32300[GHE]U6C" => "256MB PC-2700 Infineon DDR-333 Unbuffered CL2.5 1Rx4",
"64D32300[GHE]U5C" => "256MB PC-3200 Infineon DDR-400 Unbuffered CL3 1Rx4",
"64D64020[GHE]U7B" => "512MB PC-2100 Infineon DDR-266 Unbuffered CL2 2Rx8",
"64D64320[GHE]U5C" => "512MB PC-3200 Infineon DDR-400 Unbuffered CL3 2Rx8",
"72D128521[GHE]R7B" => "1GB PC-2100 Infineon DDR-266 ECC Registered CL2 2Rx4",
"HYS72D128520[GHE]R-7" => "1GB PC-2100 Infineon DDR-266 ECC Registered CL2 2Rx4",
# http://www.qimonda.com/computing-dram/ddr2/registered-dimms.html
# http://www.qimonda.com/download.jsp?ref=/qis_docs/Downloads%20Computing/DDR2%20%26%20DDR_SDRAM_Mod.pdf
# HYS prefix
"72T32000[EH]R5." => "256MB PC2-3200 Infineon DDR2-400 ECC Registered CL3 1Rx8",
"72T64001[EH]R5." => "512MB PC2-3200 Infineon DDR2-400 ECC Registered CL3 1Rx8",
"72T128000[EH]R3.7." => "1GB PC2-4200 Infineon DDR2-533 ECC Registered CL4 1Rx4",
"72T128000[EH]R5." => "1GB PC2-3200 Infineon DDR2-400 ECC Registered CL3 1Rx4",
"72T128001[EH]R5." => "1GB PC2-3200 Infineon DDR2-400 ECC Registered CL3 1Rx8",
"72T128020[EH]R5." => "1GB PC2-3200 Infineon DDR2-400 ECC Registered CL3 2Rx8",
"72T128000[EH]R3S..?" => "1GB PC2-5300 Infineon DDR2-667 ECC Registered CL5 1Rx4",
"72T128000[EH]P3S..?" => "1GB PC2-5300 Infineon DDR2-667 ECC Registered CL5 1Rx4",
"72T256220[EH]R5." => "2GB PC2-3200 Infineon DDR2-400 ECC Registered CL3 2Rx4",
"72T256000[EH]R5." => "2GB PC2-3200 Infineon DDR2-400 ECC Registered CL3 1Rx4", # R = reg
"72T256220[EH]P3S..?" => "2GB PC2-5300 Infineon DDR2-667 ECC Registered CL5 2Rx4", # P = reg with addr parity
"72T256920[EH]P3S..?" => "2GB PC2-5300 Infineon DDR2-667 ECC Registered CL5 2Rx4",
"72T512022[EH]R5." => "4GB PC2-3200 Qimonda DDR2-400 ECC Registered CL3 2Rx4 DDP",
"72T512022[EH]R3.7." => "4GB PC2-4200 Qimonda DDR2-533 ECC Registered CL4 2Rx4 DDP",
"72T512022[EH]P3S..?" => "4GB PC2-5300 Qimonda DDR2-667 ECC Registered CL5 2Rx4 DDP",
"72T512220[EH]P3S..?" => "4GB PC2-5300 Qimonda DDR2-667 ECC Registered CL5 2Rx4",
"72T512922[EH]P3S..?" => "4GB PC2-5300 Qimonda DDR2-667 ECC Registered CL5 2Rx4 DDP",
"72T512040[EH]P3S..?" => "4GB PC2-5300 Qimonda DDR2-667 ECC Registered CL5 4Rx8",
# ^ ^
# | |-- R=registered, P=registerd/addr parity
# |-------- rank: 0=1R, 2=2R, 4=4R
# http://www.qimonda.com/computing-dram/ddr2/unbuffered.html
"64T32000[EH]U3.7." => "256MB PC2-4200 Infineon DDR2-533 Unbuffered CL4 1Rx16",
"64T64000[EH]U5." => "512MB PC2-3200 Infineon DDR2-400 Unbuffered CL3 1Rx8",
"64T64000[EH]U3.7." => "512MB PC2-4200 Infineon DDR2-533 Unbuffered CL4 1Rx8",
"64T64000[EH]U3S..?" => "512MB PC2-5300 Infineon DDR2-667 Unbuffered CL5 1Rx8",
"64T128020[EH]U3S..?" => "1GB PC2-5300 Infineon DDR2-667 Unbuffered CL5 2Rx8",
"72T64000[EH]U3.7." => "512MB PC2-4200 Infineon DDR2-533 ECC Unbuffered CL4 1Rx8",
"72T64000[EH]U3S..?" => "512MB PC2-5300 Infineon DDR2-667 ECC Unbuffered CL4 1Rx8",
"72T128020[EH]U3.7." => "1GB PC2-4200 Infineon DDR2-533 ECC Unbuffered CL4 2Rx8",
"72T128020[EH]U3S..?" => "1GB PC2-5300 Infineon DDR2-667 ECC Unbuffered CL5 2Rx8",
"64T128020[EH]U2.5.." => "1GB PC2-6400 Infineon DDR2-800 ECC Unbuffered CL6 2Rx8",
"72T256020[EH]U3.7." => "2GB PC2-4200 Infineon DDR2-533 ECC Unbuffered CL4 2Rx8",
"72T256020[EH]U3S..?" => "2GB PC2-5300 Infineon DDR2-667 ECC Unbuffered CL5 2Rx8",
# http://www.qimonda.com/download.jsp?ref=/qis_docs/Downloads%20Computing/Nomenclature_DDR_DDR2.pdf
# http://www.qimonda.com/computing-dram/ddr2/fully-buffered-dimms.html
"72T64.00[EH]F[AND]3S..?" => "512MB PC2-5300 Infineon DDR2-667 ECC Fully Buffered CL5 1Rx8",
"72T64.00[EH]F[AND]3.7." => "512MB PC2-4200 Infineon DDR2-533 ECC Fully Buffered CL4 1Rx8",
"72T128.20[EH]F[AND]3.7." => "1GB PC2-4200 Infineon DDR2-533 ECC Fully Buffered CL4 2Rx8",
"72T128.20[EH]F[AND]3S..?" => "1GB PC2-5300 Infineon DDR2-667 ECC Fully Buffered CL5 2Rx8", # A=?, N=Intel C0 AMB, D=IDT 1.5 AMB
"72T256.20[EH]F[AND]3.7." => "2GB PC2-4200 Infineon DDR2-533 ECC Fully Buffered CL4 2Rx4",
"72T256.20[EH]F[AND]3S..?" => "2GB PC2-5300 Infineon DDR2-667 ECC Fully Buffered CL5 2Rx4",
"72T512.20[EH]F[AND]3S..?" => "4GB PC2-5300 Infineon DDR2-667 ECC Fully Buffered CL5 2Rx4",
# http://www.qimonda.com/computing-dram/ddr/registered-dimms.html
"72D128320GBR6C" => "1GB PC-2700 Infineon DDR-333 ECC Registered CL2.5 2Rx4",
"72D128300GBR5B" => "1GB PC-3200 Infineon DDR-400 ECC Registered CL3 1Rx4",
"72D256220HBR5B" => "2GB PC-3200 Infineon DDR-400 ECC Registered CL3 2Rx4",
"72D256220GBR5B" => "2GB PC-3200 Infineon DDR-400 ECC Registered CL3 2Rx4",
# Nanya
# http://www.nanya.com/e-htm/B/2abc/2abc-01.htm
# http://www.nanya.com/PageEdition1.aspx?Menu_ID=23&lan=en-us&def=210&isPrint=&KeyWords=
# http://www.nanya.com/NanyaAdmin/GetFiles.ashx?ID=351
"NT256D64S88B1G-6K" => "256MB PC-2700 Nanya DDR-333 Unbuffered CL2.5 1Rx8",
"NT256D64S88C0G-5T" => "256MB PC-3200 Nanya DDR-400 Unbuffered CL3 1Rx8",
"NT512D64S8HB0G-75B" => "512MB PC-2100 Nanya DDR-266 Unbuffered CL2.5 2Rx8",
"NT1GT72U4P...U-5A" => "1GB PC2-3200 Nanya DDR2-400 ECC Registered CL3 1Rx4",
"NT1GT72U4P...V-5A" => "1GB PC2-3200 Nanya DDR2-400 ECC Registered CL3 1Rx4",
"NT1GT72U4P...V-3C" => "1GB PC2-5300 Nanya DDR2-667 ECC Registered CL5 1Rx4",
"NT2GT72U4N...V-5A" => "2GB PC2-3200 Nanya DDR2-400 ECC Registered CL3 2Rx4",
"NT2GT72U4N...V-3C" => "2GB PC2-5300 Nanya DDR2-667 ECC Registered CL5 2Rx4",
"NT256T64UH4...Y-37B?" => "256MB PC2-4200 Nanya DDR2-533 Unbuffered CL4 1Rx16",
"NT512T64U88..(F|B|BY)-5A" => "512MB PC2-3200 Nanya DDR2-400 Unbuffered CL3 1Rx8",
"NT512T64U88..(F|B|BY)-37B?" => "512MB PC2-4200 Nanya DDR2-533 Unbuffered CL4 1Rx8",
"NT512T72U89...Y-37B?" => "512MB PC2-4200 Nanya DDR2-533 ECC Unbuffered CL4 1Rx8",
"NT512T72U89...Y-3C" => "512MB PC2-5300 Nanya DDR2-667 ECC Unbuffered CL5 1Rx8",
"NT1GT64U8H..(F|B|BY)-37B?" => "1GB PC2-4200 Nanya DDR2-533 Unbuffered CL4 2Rx8",
"NT1GT64U8H..(F|B|BY)-3C" => "1GB PC2-5300 Nanya DDR2-667 Unbuffered CL5 2Rx8",
"NT1GT64U8H..(F|B|BY)-25C" => "1GB PC2-6400 Nanya DDR2-800 Unbuffered CL5 2Rx8",
"NT1GT64U8H..(F|B|BY)-25D" => "1GB PC2-6400 Nanya DDR2-800 Unbuffered CL6 2Rx8",
"NT1GT72U8P...Y-37B" => "1GB PC2-4200 Nanya DDR2-533 ECC Unbuffered CL4 2Rx8",
"NT1GT72U8P...Y-3C" => "1GB PC2-5300 Nanya DDR2-667 ECC Unbuffered CL5 2Rx8",
"NT1GT64U88...Y-AC" => "1GB PC2-6400 Nanya DDR2-800 Unbuffered CL5 1Rx8",
"NT1GT64U88...Y-AD" => "1GB PC2-6400 Nanya DDR2-800 Unbuffered CL6 1Rx8",
"NT2GT72U8P...Y-3C" => "2GB PC2-5300 Nanya DDR2-667 ECC Unbuffered CL5 2Rx8",
"NT2GT72U8P...Y-AC" => "2GB PC2-6400 Nanya DDR2-800 ECC Unbuffered CL5 2Rx8",
"NT2GT72U8P...Y-AD" => "2GB PC2-6400 Nanya DDR2-800 ECC Unbuffered CL6 2Rx8",
"NT1GT72U8P..BD-3C" => "1GB PC2-5300 Nanya DDR2-667 ECC Fully Buffered CL5 2Rx8", # IDT AMB
"NT1GT72U8P..BN-3C" => "1GB PC2-5300 Nanya DDR2-667 ECC Fully Buffered CL5 2Rx8", # Intel AMB
"NT2GT72U4N..BD-3C" => "2GB PC2-5300 Nanya DDR2-667 ECC Fully Buffered CL5 2Rx4", # IDT AMB
"NT2GT72U4N..BN-3C" => "2GB PC2-5300 Nanya DDR2-667 ECC Fully Buffered CL5 2Rx4", # Intel AMB
"NT2GT72U8P..BN-3C" => "2GB PC2-5300 Nanya DDR2-667 ECC Fully Buffered CL5 2Rx8", # Intel AMB
"NT2GT72U8P..BD-3C" => "2GB PC2-5300 Nanya DDR2-667 ECC Fully Buffered CL5 2Rx8", # IDT AMB
"NT4GT72U4N..BD-3C" => "4GB PC2-5300 Nanya DDR2-667 ECC Fully Buffered CL5 2Rx4", # IDT AMB
# ^^ ^
# || |- AMB: D=IDT, N=Intel, E=NEC
# ||----- #chips: 4=4, 8=8, 9=9, H=16, P=18, N=36
# |------ 4=x4, 8=x8, H=x16
#
"NT4GTT72U4P..UN-3C" => "4GB PC2-5300 Nanya DDR2-667 ECC Fully Buffered CL5 2Rx4 DDP", # Intel AMB
# 2Rx4 DDP ==> 36 chips / 2 (DDP) == 18 chips
# Elixir (brand of Nanya)
# http://www.elixir-memory.com/product_elixir_1.asp?pro_Name=elixir&pro_Class=DDR+SDRAM&pro_Type=All
"M2U51264DS8HC3G-5T" => "512MB PC-3200 Elixir DDR-400 Unbuffered CL3 2Rx8",
"M2Y51264DS8HC3G-5T" => "512MB PC-3200 Elixir DDR-400 Unbuffered CL3 2Rx8",
"M2Y51264DS88C1G-5T" => "512MB PC-3200 Elixir DDR-400 Unbuffered CL3 1Rx8",
"M2Y1G64DS8HC1G-5T" => "1GB PC-3200 Elixir DDR-400 Unbuffered CL3 2Rx8",
"M2U51264TU88A2B-37" => "512MB PC2-4200 Elixir DDR2-533 Unbuffered CL4 1Rx8",
"M2Y51264TU88A4B-3C" => "512MB PC2-5300 Elixir DDR2-667 Unbuffered CL5 1Rx8",
"M2Y1G64TU8HB4B-3C" => "1GB PC2-5300 Elixir DDR2-667 Unbuffered CL5 2Rx8",
"M2Y1G64TU8HA2B-3C" => "1GB PC2-5300 Elixir DDR2-667 Unbuffered CL5 2Rx8",
"M2Y1G64TU8HA4B-3C" => "1GB PC2-5300 Elixir DDR2-667 Unbuffered CL5 2Rx8",
# http://www.samsung.com/Products/Semiconductor/Support/ProductLists/index.htm
# http://www.samsung.com/Products/Semiconductor/Support/Label_CodeInfo/PartNumberDecoder.htm
# http://www.samsung.com/Products/Semiconductor/Support/Label_CodeInfo/DDR_SDRAM_Module.pdf
# http://www.samsung.com/Products/Semiconductor/Support/Label_CodeInfo/ddr2_product_guide_aug_04.pdf
# http://www.samsung.com/Products/Semiconductor/common/product_list.aspx?family_cd=DDR020201
# http://www.samsung.com/global/system/business/semiconductor/family/2007/8/30/746403DDR_SDRAM_Module.pdf
"M3 12L6420...-CB0" => "512MB PC-2100 Samsung DDR-266 ECC Registered CL2.5 1Rx4",
"M3 12L6523...-CB3" => "512MB PC-2700 Samsung DDR-333 ECC Registered CL2.5 1Rx8",
"M3 12L2920...-CB3" => "1GB PC-2700 Samsung DDR-333 ECC Registered CL2.5 1Rx4",
"M3 68L1624...-CB3" => "128MB PC-2700 Samsung DDR-333 Unbuffered CL2.5 1Rx16",
"M3 68L3223...-CB0" => "256MB PC-2100 Samsung DDR-266 Unbuffered CL2.5 1Rx8",
"M3 68L3223...-CB3" => "256MB PC-2700 Samsung DDR-333 Unbuffered CL2.5 1Rx8",
"M3 68L3223...-CCC" => "256MB PC-3200 Samsung DDR-400 Unbuffered CL3 1Rx8",
"M3 68L6523...-CB3" => "512MB PC-2700 Samsung DDR-333 Unbuffered CL2.5 1Rx8",
"M3 68L6523...-CCC" => "512MB PC-3200 Samsung DDR-400 Unbuffered CL3 1Rx8",
"M3 68L6423...-CCC" => "512MB PC-3200 Samsung DDR-400 Unbuffered CL3 2Rx8",
"M3 68L2923...-CCC" => "1GB PC-3200 Samsung DDR-400 Unbuffered CL3 2Rx8",
# ^
# |-- 0=x4, 3=x8, 4=x16
# http://www.samsung.com/global/business/semiconductor/products/dram/downloads/ddr2_product_guide_apr_07.pdf
"M3 93T6450...-CCC" => "512MB PC2-3200 Samsung DDR2-400 ECC Registered CL3 1Rx4",
"M3 93T6453...-CCC" => "512MB PC2-3200 Samsung DDR2-400 ECC Registered CL3 2Rx8",
"M3 93T6553...-CCC" => "512MB PC2-3200 Samsung DDR2-400 ECC Registered CL3 1Rx8",
"M3 93T6553...-CE6" => "512MB PC2-5300 Samsung DDR2-667 ECC Registered CL5 1Rx8",
"M3 93T2950...-CCC" => "1GB PC2-3200 Samsung DDR2-400 ECC Registered CL3 1Rx4",
"M3 93T2950...-CE6" => "1GB PC2-5300 Samsung DDR2-667 ECC Registered CL5 1Rx4",
"M3 93T2953...-CCC" => "1GB PC2-3200 Samsung DDR2-400 ECC Registered CL3 2Rx8",
"M3 93T5750...-CCC" => "2GB PC2-3200 Samsung DDR2-400 ECC Registered CL3 2Rx4",
"M3 93T5750...-CD5" => "2GB PC2-4200 Samsung DDR2-533 ECC Registered CL4 2Rx4",
"M3 93T5660...-CCC" => "2GB PC2-3200 Samsung DDR2-400 ECC Registered CL3 1Rx4",
"M3 93T5660...-CD5" => "2GB PC2-4200 Samsung DDR2-533 ECC Registered CL4 1Rx4",
"M3 93T5750...-CE6" => "2GB PC2-5300 Samsung DDR2-667 ECC Registered CL5 2Rx4",
"M3 93T5160...-CE6" => "4GB PC2-5300 Samsung DDR2-667 ECC Registered CL5 2Rx4",
"M3 78T3253...-CD5" => "256MB PC2-4200 Samsung DDR2-533 Unbuffered CL4 1Rx8",
"M3 78T6453...-CD5" => "512MB PC2-4200 Samsung DDR2-533 Unbuffered CL4 2Rx8",
"M3 78T6553...-CD5" => "512MB PC2-4200 Samsung DDR2-533 Unbuffered CL4 1Rx8",
"M3 78T6553...-CE6" => "512MB PC2-5300 Samsung DDR2-667 Unbuffered CL5 1Rx8",
"M3 78T2953...-CD5" => "1GB PC2-4200 Samsung DDR2-533 Unbuffered CL4 2Rx8",
"M3 78T2953...-CE6" => "1GB PC2-5300 Samsung DDR2-667 Unbuffered CL5 2Rx8",
"M3 78T2953...-CF7" => "1GB PC2-6400 Samsung DDR2-800 Unbuffered CL6 2Rx8",
"M3 78T2863...-CE6" => "1GB PC2-5300 Samsung DDR2-667 Unbuffered CL5 1Rx8",
"M3 78T2863...-CF7" => "1GB PC2-6400 Samsung DDR2-800 Unbuffered CL6 1Rx8",
"M3 91T2953...-CD5" => "1GB PC2-4200 Samsung DDR2-533 ECC Unbuffered CL4 2Rx8",
"M3 91T2953...-CE6" => "1GB PC2-5300 Samsung DDR2-667 ECC Unbuffered CL5 2Rx8",
"M3 91T5663...-CD5" => "2GB PC2-4200 Samsung DDR2-533 ECC Unbuffered CL4 2Rx8",
"M3 91T5663...-CE6" => "2GB PC2-5300 Samsung DDR2-667 ECC Unbuffered CL5 2Rx8",
# http://www.samsung.com/global/system/business/semiconductor/family/2008/5/26/041421DDR2_SDRAM_Module.pdf
# http://www.samsung.com/Products/Semiconductor/common/product_list.aspx?family_cd=DDR020204
"M395T6553...-CE60" => "512MB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 1Rx8", # Intel C0 AMB
"M395T6553...-CE61" => "512MB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 1Rx8", # IDT A1.5 AMB
"M395T6553...-CE66" => "512MB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 1Rx8", # IDT C1 AMB
"M395T6553...-CE6." => "512MB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 1Rx8", # wildcard AMB
"M395T2953...-CD50" => "1GB PC2-4200 Samsung DDR2-533 ECC Fully Buffered CL4 2Rx8", # Intel C0 AMB
"M395T2953...-CD51" => "1GB PC2-4200 Samsung DDR2-533 ECC Fully Buffered CL4 2Rx8", # IDT A1.5 AMB
"M395T2953...-CE60" => "1GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx8", # Intel C0 AMB
"M395T2953...-CE61" => "1GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx8", # IDT A1.5 AMB
"M395T2953...-CE62" => "1GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx8", # NEC B5 AMB
"M395T2953...-CE65" => "1GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx8", # Intel D1 AMB
"M395T2953...-CE66" => "1GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx8", # IDT C1 AMB
"M395T2953...-CE6." => "1GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx8", # wildcard AMB
"M395T5750...-CD50.?" => "2GB PC2-4200 Samsung DDR2-533 ECC Fully Buffered CL4 2Rx4", # Intel C0 AMB
"M395T5750...-CD51" => "2GB PC2-4200 Samsung DDR2-533 ECC Fully Buffered CL4 2Rx4", # IDT A1.5 AMB
"M395T5750...-CE60.?" => "2GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx4", # Intel C0 AMB
"M395T5750...-CE61" => "2GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx4", # IDT A1.5 AMB
"M395T5750...-CE62" => "2GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx4", # NEC B5 AMB
"M395T5750...-CE65" => "2GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx4", # Intel D1 AMB
"M395T5750...-CE66" => "2GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx4", # IDT C1 AMB
"M395T5750...-CE6." => "2GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx4", # wildcard AMB
"M395T5663...-CE65" => "2GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx8", # Intel D1 AMB
"M395T5663...-CE66" => "2GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx8", # IDT C1 AMB
"M395T5663...-CE6." => "2GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx8", # wildcard AMB
"M395T5160...-CE65" => "4GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx4", # Intel D1 AMB
"M395T5160...-CE6." => "4GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx4", # wildcard AMB
"M395T5166...-CE65" => "4GB PC2-5300 Samsung DDR2-667 ECC Fully Buffered CL5 2Rx4", # Intel D1 AMB
# ^
# |-- 0=x4, 3=x8, 4=x16, 6=x4:stack, 7=x8:stack
# http://www.amd.com/us-en/assets/content_type/DownloadableAssets/Opteron_Registered_DIMM_AVL.pdf
# http://www.samsung.com/Products/Semiconductor/Support/Label_CodeInfo/DDR_SDRAM_Module.pdf
"M3 12L5720CZ0-CB3" => "2GB PC-2700 Samsung DDR-333 ECC Registered CL2.5 2Rx4",
"M3 12L5720CZ3-CCC" => "2GB PC-3200 Samsung DDR-400 ECC Registered CL3 2Rx4",
# http://download.micron.com/pdf/guide/modguide.pdf
# http://www.micron.com/products/modules/ddr2sdram/partlist.aspx?pincount=240-pin&version=Registered&package=DIMM
# http://www.micron.com/products/search.aspx
# http://www.micron.com/products/modules/
"9VDDF6472G-335.." => "512MB PC-2700 Micron DDR-333 ECC Registered CL2.5 1Rx8",
"8LSDT3264AG-133.." => "256MB PC133 Micron SDRAM Unbuffered CL3 1Rx8",
"18LSDT6472G-133.." => "512MB PC133 Micron SDRAM ECC Registered CL3 1Rx4",
"18VDDT6472G-265.." => "512MB PC-2100 Micron DDR-266 ECC Registered CL2.5 1Rx4",
"18VDDF12872G-335.." => "1GB PC-2700 Micron DDR-333 ECC Registered CL2.5 1Rx4",
# http://www.micron.com/products/modules/udimm/partlist?tech=DDR%20SDRAM
"4VDDT1664AG-335.." => "128MB PC-2700 Micron DDR-333 Unbuffered CL2.5 1Rx16",
"8VDDT3264AG-265.." => "256MB PC-2100 Micron DDR-266 Unbuffered CL2.5 1Rx8",
"8VDDT3264AG-335.." => "256MB PC-2700 Micron DDR-333 Unbuffered CL2.5 1Rx8",
"8VDDT3264AG-40B.." => "256MB PC-3200 Micron DDR-400 Unbuffered CL3 1Rx8",
"8VDDT6464AG-335.." => "512MB PC-2700 Micron DDR-333 Unbuffered CL2.5 1Rx8",
"16VDDT6464AY-40B.." => "512MB PC-3200 Micron DDR-400 Unbuffered CL3 2Rx8",
"9HTF3272Y-40E.." => "256MB PC2-3200 Micron DDR2-400 ECC Registered CL3 1Rx8",
"9HTF6472Y-40E.." => "512MB PC2-3200 Micron DDR2-400 ECC Registered CL3 1Rx8",
"18HTF6472DY-40E.." => "512MB PC2-3200 Micron DDR2-400 ECC Registered CL3 2Rx8",
"18HTF6472Y-40E.." => "512MB PC2-3200 Micron DDR2-400 ECC Registered CL3 1Rx4",
"18HTF12872Y-40E.." => "1GB PC2-3200 Micron DDR2-400 ECC Registered CL3 1Rx4",
"18HTF12872DY-40E.." => "1GB PC2-3200 Micron DDR2-400 ECC Registered CL3 2Rx8",
"18HTF12872PY-667.." => "1GB PC2-5300 Micron DDR2-667 ECC Registered CL5 1Rx4",
"18HTF25672Y-40E.." => "2GB PC2-3200 Micron DDR2-400 ECC Registered CL3 1Rx4",
"36HTF25672Y-40E.." => "2GB PC2-3200 Micron DDR2-400 ECC Registered CL3 2Rx4", # Non-Parity
"36HTF25672PY-667.." => "2GB PC2-5300 Micron DDR2-667 ECC Registered CL5 2Rx4", # Parity
"36HTF51272PY-667.." => "4GB PC2-5300 Micron DDR2-667 ECC Registered CL5 2Rx4", # Parity
"4HTF3264AY-53E.." => "256MB PC2-4200 Micron DDR2-533 Unbuffered CL4 1Rx16",
"8HTF6464AY-53E.." => "512MB PC2-4200 Micron DDR2-533 Unbuffered CL4 1Rx8",
"9HTF6472AY-53E.." => "512MB PC2-4200 Micron DDR2-533 ECC Unbuffered CL4 1Rx8",
"8HTF12864AY-667.." => "1GB PC2-5300 Micron DDR2-667 Unbuffered CL5 1Rx8",
"8HTF12864AY-800.." => "1GB PC2-6400 Micron DDR2-800 Unbuffered CL6 1Rx8",
"16HTF12864AY-667.." => "1GB PC2-5300 Micron DDR2-667 Unbuffered CL5 2Rx8",
"18HTF12872AY-53E.." => "1GB PC2-4200 Micron DDR2-533 ECC Unbuffered CL4 2Rx8",
"18HTF25672AY-53E.." => "2GB PC2-4200 Micron DDR2-533 ECC Unbuffered CL4 2Rx8",
"MT9HTF6472FY-53E.." => "512MB PC2-4200 Micron DDR2-533 ECC Fully Buffered CL4 1Rx8",
"18HTF12872FDY-53EB" => "1GB PC2-4200 Micron DDR2-533 ECC Fully Buffered CL4 2Rx8",
"18HF12872FD667...." => "1GB PC2-5300 Micron DDR2-667 ECC Fully Buffered CL5 1Rx4",
"36HTF25672F667...." => "2GB PC2-5300 Micron DDR2-667 ECC Fully Buffered CL5 2Rx4",
"36HTF51272F667...." => "4GB PC2-5300 Micron DDR2-667 ECC Fully Buffered CL5 2Rx4",
# http://www.elpida.com/en/products/index.html
# http://www.elpida.com/pdfs/ECT-TS-1971.pdf
"EBD25UC8AMFA-5B" => "256MB PC-3200 Elpida DDR-400 Unbuffered CL3 1Rx8",
"EBE51UD8A.WA-6E-E" => "512MB PC2-5300 Elpida DDR2-667 Unbuffered CL5 1Rx8",
"EBE11UD8A.WA-6E-E" => "1GB PC2-5300 Elpida DDR2-667 Unbuffered CL5 2Rx8",
"EBE11UD8A.WA-8E-E" => "1GB PC2-6400 Elpida DDR2-800 Unbuffered CL5 2Rx8",
"EBE11UD8A.WA-8G-E" => "1GB PC2-6400 Elpida DDR2-800 Unbuffered CL6 2Rx8",
"EBE51RD8A.FA-4A-E" => "512MB PC2-3200 Elpida DDR2-400 ECC Registered CL3 1Rx8",
"EBE10RD4A.FA-4A-E" => "1GB PC2-3200 Elpida DDR2-400 ECC Registered CL3 1Rx4",
"EBE20RE4A.FA-4A-E" => "2GB PC2-3200 Elpida DDR2-400 ECC Registered CL3 1Rx4",
"EBE20AE4A.FA-6E-E" => "2GB PC2-5300 Elpida DDR2-667 ECC Registered CL5 1Rx4",
"EBE21AD4A.FA-6E-E" => "2GB PC2-5300 Elpida DDR2-667 ECC Registered CL5 2Rx4",
"EBE41AE4A.FA-6E-E" => "4GB PC2-5300 Elpida DDR2-667 ECC Registered CL5 2Rx4",
# ^^^ ^
# || |- 4=x4, 8=x8, 6=x16
# ||--- A=registered/addr parity, R=registered
# |---- density/rank: 10=1G/1R, 11=1G/2R, 20=2G/1R, 21=2G/2R, 41=4G/2R, 51=512M/1R
# e.g. http://www.elpida.com/pdfs/E0868E30.pdf
"EBE11FD8A.F.-6E-E" => "1GB PC2-5300 Elpida DDR2-667 ECC Fully Buffered CL5 2Rx8",
"EBE21FD4A.F.-5C-E" => "2GB PC2-4200 Elpida DDR2-533 ECC Fully Buffered CL4 2Rx4",
"EBE21FD4A.F.-6E-E" => "2GB PC2-5300 Elpida DDR2-667 ECC Fully Buffered CL5 2Rx4",
"EBE21FE8A.F.-6E-E" => "2GB PC2-5300 Elpida DDR2-667 ECC Fully Buffered CL5 2Rx8",
# http://www.hynix.com/inc/pdfDownload.jsp?path=/upload/products/gl/products/dram/down/DDR2.pdf
# http://hynix.com/datasheet/eng/module/module_sub.jsp?RK=08&SK=RD&RAM_NAME=DDR2+SDRAM&SUB_RAM=512MB&SUB_RAM1=1GB&SUB_RAM2=2GB&SUB_RAM3=4GB
# P == lead-free, M == 36 chips?
"71V32635HCT8-H" => "256MB PC133 Hynix SDRAM Unbuffered CL3 2Rx8",
"HYMP564R72P?8-E3" => "512MB PC2-3200 Hynix DDR2-400 ECC Registered CL3 1Rx8",
"HYMP512R72B?P?4-E3" => "1GB PC2-3200 Hynix DDR2-400 ECC Registered CL3 1Rx4",
"HYMP512R72P?8-E3" => "1GB PC2-3200 Hynix DDR2-400 ECC Registered CL3 2Rx8",
"HYMP125R72P?4-E3" => "2GB PC2-3200 Hynix DDR2-400 ECC Registered CL3 1Rx4",
"HYMP125R72MP?4-E3" => "2GB PC2-3200 Hynix DDR2-400 ECC Registered CL3 2Rx4",
"HYMP525R72B?P?4-E3" => "2GB PC2-3200 Hynix DDR2-400 ECC Registered CL3 2Rx4",
"HYMP512P72.P4-Y5" => "1GB PC2-5300 Hynix DDR2-667 Parity Registered CL5 1Rx4",
"HYMP525P72.P4-Y5" => "2GB PC2-5300 Hynix DDR2-667 Parity Registered CL5 2Rx4",
"HYMP125P72.P4-Y5" => "2GB PC2-5300 Hynix DDR2-667 Parity Registered CL5 1Rx4",
"HYMP151P72.P4-Y5" => "4GB PC2-5300 Hynix DDR2-667 Parity Registered CL5 2Rx4",
"HYMP351P72.MP4-Y5" => "4GB PC2-5300 Hynix DDR2-667 Parity Registered CL5 2Rx4 DDP",
# ^ ^ ^
# | | |-- 4=x4, 8=x8, 6=x16
# | |---- M=DDP
# |-------- R=registered, P=registered/addr parity
# http://hynix.com/datasheet/eng/module/module_sub.jsp?menu3=03&RK=07&SK=UD&RAM_NAME=DDR%20SDRAM&SUB_RAM1=256MB&SUB_RAM2=512MB&SUB_RAM3=
# http://www.hynix.com/inc/pdfDownload.jsp?path=/gl/products/down/DDR_MODULE_Old.pdf
"HYMD216 646[A-D]6J-J" => "128MB PC-2700 Hynix DDR-333 Unbuffered CL2.5 1Rx16",
"HYMD232 646[A-D]8-H" => "256MB PC-2100 Hynix DDR-266 Unbuffered CL2.5 1Rx8",
"HYMD232 646[A-D]8J-J" => "256MB PC-2700 Hynix DDR-333 Unbuffered CL2.5 1Rx8",
"HYMD232 646[A-D]8J-D43" => "256MB PC-3200 Hynix DDR-400 Unbuffered CL3 1Rx8",
"HYMD264 646[A-D]8J-J" => "512MB PC-2700 Hynix DDR-333 Unbuffered CL2.5 2Rx8",
"HYMD264 646[A-D]8J-D43" => "512MB PC-3200 Hynix DDR-400 Unbuffered CL3 2Rx8",
# http://hynix.com/datasheet/eng/module/module_sub.jsp?menu3=02&RK=08&SK=UD&RAM_NAME=DDR2%20SDRAM&SUB_RAM=256MB&SUB_RAM1=512MB&SUB_RAM2=
# http://hynix.com/eng/02_products/01_dram/down/DDR2MODULE.pdf
"HYMP532U64[A-G]?P6-E3" => "256MB PC2-3200 Hynix DDR2-400 Unbuffered CL3 1Rx16",
"HYMP564U64[A-G]?P8-C4" => "512MB PC2-4200 Hynix DDR2-533 Unbuffered CL4 1Rx8",
"HYMP512U64[A-G]?P8-Y5" => "1GB PC2-5300 Hynix DDR2-667 Unbuffered CL5 2Rx8",
"HYMP112U64[A-G]?P8-Y5" => "1GB PC2-5300 Hynix DDR2-667 Unbuffered CL5 1Rx8",
"HYMP564U72[A-G]?P8-C4" => "512MB PC2-4200 Hynix DDR2-533 ECC Unbuffered CL4 1Rx8",
"HYMP564U72[A-G]?P8-Y5" => "512MB PC2-5300 Hynix DDR2-667 ECC Unbuffered CL5 1Rx8",
"HYMP512U72[A-G]?P8-C4" => "1GB PC2-4200 Hynix DDR2-533 ECC Unbuffered CL4 2Rx8",
"HYMP512U72[A-G]?P8-Y5" => "1GB PC2-5300 Hynix DDR2-667 ECC Unbuffered CL5 2Rx8",
"HYMP125U72[A-G]?P8-C4" => "2GB PC2-4200 Hynix DDR2-533 ECC Unbuffered CL4 2Rx8",
"HYMP125U72[A-G]?P8-Y5" => "2GB PC2-5300 Hynix DDR2-667 ECC Unbuffered CL5 2Rx8",
"HYMP125U72[A-G]?P8-S5" => "2GB PC2-6400 Hynix DDR2-800 ECC Unbuffered CL5 2Rx8",
"HYMP125U72[A-G]?P8-S6" => "2GB PC2-6400 Hynix DDR2-800 ECC Unbuffered CL6 2Rx8",
# http://hynix.com/datasheet/eng/module/module_sub.jsp?menu3=02&RK=08&SK=FB&RAM_NAME=DDR2%20SDRAM
"HYMP564[BF]72[A-G]?P8D2-C4" => "512MB PC2-4200 Hynix DDR2-533 ECC Fully Buffered CL4 1Rx8", # IDT A1.5 AMB
"HYMP564[BF]72[A-G]?P8N2-C4" => "512MB PC2-4200 Hynix DDR2-533 ECC Fully Buffered CL4 1Rx8", # Intel C0 AMB
"HYMP564[BF]72[A-G]?P8D2-Y5" => "512MB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 1Rx8", # IDT A1.5 AMB
"HYMP564[BF]72[A-G]?P8N2-Y5" => "512MB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 1Rx8", # Intel C0 AMB
"HYMP564[BF]72[A-G]?P8N3-Y5" => "512MB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 1Rx8", # Intel D1 AMB
"HYMP512[BF]72[A-G]?P8D2-C4" => "1GB PC2-4200 Hynix DDR2-533 ECC Fully Buffered CL4 2Rx8", # IDT A1.5 AMB
"HYMP512[BF]72[A-G]?P8N2-C4" => "1GB PC2-4200 Hynix DDR2-533 ECC Fully Buffered CL4 2Rx8", # Intel C0 AMB
"HYMP512[BF]72[A-G]?P8N3-C4" => "1GB PC2-4200 Hynix DDR2-533 ECC Fully Buffered CL4 2Rx8", # Intel D1 AMB
"HYMP512[BF]72[A-G]?P8D2-Y5" => "1GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx8", # IDT A1.5 AMB
"HYMP512[BF]72[A-G]?P8D3-Y5" => "1GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx8", # IDT C1 AMB
"HYMP512[BF]72[A-G]?P8N2-Y5" => "1GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx8", # Intel C0 AMB
"HYMP512[BF]72[A-G]?P8N3-Y5" => "1GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx8", # Intel D1 AMB
"HYMP512[BF]72[A-G]?P8E4-Y5" => "1GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx8", # NEC B5+ AMB
"HYMP525[BF]72[A-G]?P4D2-C4" => "2GB PC2-4200 Hynix DDR2-533 ECC Fully Buffered CL4 2Rx4", # IDT A1.5 AMB
"HYMP525[BF]72[A-G]?P4N2-C4" => "2GB PC2-4200 Hynix DDR2-533 ECC Fully Buffered CL4 2Rx4", # Intel C0 AMB
"HYMP525[BF]72[A-G]?P4N3-C4" => "2GB PC2-4200 Hynix DDR2-533 ECC Fully Buffered CL4 2Rx4", # Intel D1 AMB
"HYMP525[BF]72[A-G]?P4D2-Y5" => "2GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx4", # IDT A1.5 AMB
"HYMP525[BF]72[A-G]?P4D3-Y5" => "2GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx4", # IDT C1 AMB
"HYMP525[BF]72[A-G]?P4N2-Y5" => "2GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx4", # Intel C0 AMB
"HYMP525[BF]72[A-G]?P4N3-Y5" => "2GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx4", # Intel D1 AMB
"HYMP525[BF]72[A-G]?P4E4-Y5" => "2GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx4", # NEC B5+ AMB
"HYMP125[BF]72[A-G]?P8D3-Y5" => "2GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx8", # IDT C1 AMB
"HYMP125[BF]72[A-G]?P8N3-Y5" => "2GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx8", # Intel D1 AMB
"HYMP151[BF]72[A-G]?P4D3-Y5" => "4GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx4", # IDT C1 AMB
"HYMP151[BF]72[A-G]?P4N3-Y5" => "4GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx4", # Intel D1 AMB
"HYMP351[BF]72[A-G]?MP4N3Y5" => "4GB PC2-5300 Hynix DDR2-667 ECC Fully Buffered CL5 2Rx4 DDP", # Intel D1 AMB
# SODIMM
"HYMP564S64[A-G]?P6-Y5" => "512MB PC2-5300 Hynix DDR2-667 Unbuffered CL5 2Rx16",
"HYMP512S64[A-G]?P8-Y5" => "1GB PC2-5300 Hynix DDR2-667 Unbuffered CL5 2Rx8",
# http://www.netlistinc.com/technology_products.aspx?sm=pr
"NLD127R21203F-D32K" => "1GB PC2-3200 Netlist DDR2-400 ECC Registered CL3 1R",
"NLD257R21203F-D32K" => "2GB PC2-3200 Netlist DDR2-400 ECC Registered CL3 2R",
"NLD257R22503F-D32K" => "2GB PC2-3200 Netlist DDR2-400 ECC Registered CL3 2R",
"NMD257A26407FD53N1" => "2GB PC2-5300 Netlist DDR2-667 ECC Fully Buffered CL5 4Rx8",
"N.D517A21207FD53.." => "4GB PC2-5300 Netlist DDR2-667 ECC Fully Buffered CL5 4Rx8",
# http://www.smartm.com/product/productCat.cfm?productCatID=1
# http://www.smartupgradeconfigurator.com/config/
"SX5643285D8N6CLICH" => "256MB PC-2700 Smart DDR-333 Unbuffered CL2.5",
"SM5643285D8N6CLIBH" => "256MB PC-2700 Smart DDR-333 Unbuffered CL2.5",
"SM5643285D8N6CHIBH" => "256MB PC-2100 Smart DDR-266 Unbuffered CL2.5",
"SM5643285D8N6CHM1H" => "256MB PC-2100 Smart DDR-266 Unbuffered CL2.5",
"SG2567UDR212852HC" => "2GB PC2-5300 Smart DDR2-667 ECC Unbuffered CL5 2Rx8",
"SM5643285D8N6CHHAH" => "256MB PC-2100 Smart DDR-266 Unbuffered CL2.5",
"SB2567RDR212835IA" => "2GB PC2-3200 Smart DDR2-400 ECC Registered CL3 2R",
"SB1287RDR212435IA" => "1GB PC2-3200 Smart DDR2-400 ECC Registered CL3 1Rx4",
"SB572284FG8E03BIAH" => "1GB PC2-3200 Smart DDR2-400 ECC Registered CL3 1Rx4",
"SG572284FG8E0DBHBH" => "1GB PC2-3200 Smart DDR2-400 ECC Registered CL3 1Rx4",
"SG5SC82N2G1CDNDSED" => "1GB PC2-5300 Smart DDR2-667 ECC Fully Buffered CL5",
"SG5SD42N2G1CDNDSCD" => "2GB PC2-5300 Smart DDR2-667 ECC Fully Buffered CL5 1Rx4",
"SG5SD42N2G1CDNDSED" => "2GB PC2-5300 Smart DDR2-667 ECC Fully Buffered CL5 1Rx4",
"SG5SD42N2G1BDDEHCH" => "2GB PC2-5300 Smart DDR2-667 ECC Fully Buffered CL5 1Rx4",
"SG2567RDR212452IB" => "2GB PC2-5300 Smart DDR2-667 ECC Fully Buffered CL5 2Rx4",
"SG5SE84N2G1CDDGSD" => "4GB PC2-5300 Smart DDR2-667 ECC Fully Buffered CL5 2Rx4",
"SG5127FBD12852HCDL" => "4GB PC2-5300 Smart DDR2-667 ECC Fully Buffered CL5 4Rx8",
);
my(%drive_models) = (
# http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/knowndrives.cpp?view=log
# Toshiba
"MK4032GAX" => "40GB 5.4K ATA/100 2.5\" Toshiba 8MB",
"MK4026GAX" => "40GB 5.4K ATA/100 2.5\" Toshiba 16MB",
# Fujitsu
# http://www.fujitsu.com/us/services/computing/storage/hdd/support/docs.html
"MHS2020AT" => "20GB 4.2K ATA/100 2.5\" Fujitsu Mobile MHS 2MB",
"MHS2030AT" => "30GB 4.2K ATA/100 2.5\" Fujitsu Mobile MHS 2MB",
"MHS2040AT" => "40GB 4.2K ATA/100 2.5\" Fujitsu Mobile MHS 2MB",
"MHS2060AT" => "60GB 4.2K ATA/100 2.5\" Fujitsu Mobile MHS 2MB",
"MHV2040AH" => "40GB 5.4K ATA/100 2.5\" Fujitsu Mobile MHV2 AH 8MB",
"MHV2060AH" => "60GB 5.4K ATA/100 2.5\" Fujitsu Mobile MHV2 AH 8MB",
"MHV2080AH" => "80GB 5.4K ATA/100 2.5\" Fujitsu Mobile MHV2 AH 8MB",
"MHV2100AH" => "100GB 5.4K ATA/100 2.5\" Fujitsu Mobile MHV2 AH 8MB",
"MHV2120AH" => "120GB 5.4K ATA/100 2.5\" Fujitsu Mobile MHV2 AH 8MB",
"MHV2040AS" => "40GB 5.4K ATA/100 2.5\" Fujitsu Extended Duty Mobile 8MB",
"MHV2060AS" => "60GB 5.4K ATA/100 2.5\" Fujitsu Extended Duty Mobile 8MB",
"MHV2080AS" => "80GB 5.4K ATA/100 2.5\" Fujitsu Extended Duty Mobile 8MB",
"MHV2040BS" => "40GB 5.4K SATA/150 2.5\" Fujitsu Extended Duty Mobile 8MB",
"MHV2060BS" => "60GB 5.4K SATA/150 2.5\" Fujitsu Extended Duty Mobile 8MB",
"MHV2080BS" => "80GB 5.4K SATA/150 2.5\" Fujitsu Extended Duty Mobile 8MB",
"MHV2040BH" => "40GB 5.4K SATA/150 2.5\" Fujitsu Mobile 8MB",
"MHV2060BH" => "60GB 5.4K SATA/150 2.5\" Fujitsu Mobile 8MB",
"MHV2080BH" => "80GB 5.4K SATA/150 2.5\" Fujitsu Mobile 8MB",
"MHV2100BH" => "100GB 5.4K SATA/150 2.5\" Fujitsu Mobile 8MB",
"MHV2120BH" => "120GB 5.4K SATA/150 2.5\" Fujitsu Mobile 8MB",
# Samsung
"SP0411N" => "40GB 7.2K ATA/133 Samsung SpinPoint PL40 2MB",
"SP2514N" => "250GB 7.2K ATA/133 Samsung SpinPoint P120 8MB",
"SP0411C" => "40GB 7.2K SATA/300 Samsung SpinPoint PL40 2MB",
"HD040GJ" => "40GB 7.2K SATA/300 Samsung SpinPoint P80 SD 8MB",
"HD080HJ" => "80GB 7.2K SATA/300 Samsung SpinPoint P80 SD 8MB",
"HD160JJ" => "160GB 7.2K SATA/300 Samsung SpinPoint P80 SD 8MB",
"HD041GJ" => "40GB 7.2K SATA/300 Samsung SpinPoint S166 2MB",
"HD042GJ" => "40GB 7.2K SATA/300 Samsung SpinPoint S166 8MB",
"HD081GJ" => "80GB 7.2K SATA/300 Samsung SpinPoint S166 2MB",
"HD082GJ" => "80GB 7.2K SATA/300 Samsung SpinPoint S166 8MB",
"HD120HJ" => "120GB 7.2K SATA/300 Samsung SpinPoint S166 8MB",
"HD161HJ" => "160GB 7.2K SATA/300 Samsung SpinPoint S166 8MB",
"HD080GJ" => "80GB 7.2K SATA/300 Samsung SpinPoint T166 8MB",
"HD160HJ" => "160GB 7.2K SATA/300 Samsung SpinPoint T166 8MB",
"HD320KJ" => "320GB 7.2K SATA/300 Samsung SpinPoint T166 8MB",
"HD321KJ" => "320GB 7.2K SATA/300 Samsung SpinPoint T166 16MB",
"HD500LJ" => "500GB 7.2K SATA/300 Samsung SpinPoint T166 8MB",
"HD501LJ" => "500GB 7.2K SATA/300 Samsung SpinPoint T166 16MB",
"HD161GJ" => "160GB 7.2K SATA/300 Samsung SpinPoint F1 8MB",
"HD162GJ" => "160GB 7.2K SATA/300 Samsung SpinPoint F1 16MB",
"HD251HJ" => "250GB 7.2K SATA/300 Samsung SpinPoint F1 8MB",
"HD252HJ" => "250GB 7.2K SATA/300 Samsung SpinPoint F1 16MB",
"HD321HJ" => "320GB 7.2K SATA/300 Samsung SpinPoint F1 8MB",
"HD322HJ" => "320GB 7.2K SATA/300 Samsung SpinPoint F1 16MB",
"HD501IJ" => "500GB 7.2K SATA/300 Samsung SpinPoint F1 8MB",
"HD502IJ" => "500GB 7.2K SATA/300 Samsung SpinPoint F1 16MB",
"HD642JJ" => "640GB 7.2K SATA/300 Samsung SpinPoint F1 16MB",
"HD753LJ" => "750GB 7.2K SATA/300 Samsung SpinPoint F1 32MB",
"HD103UJ" => "1TB 7.2K SATA/300 Samsung SpinPoint F1 32MB",
# need more info on this model
"HE160HJ" => "160GB 7.2K SATA/300 Samsung 8MB",
"HE252HJ" => "250GB 7.2K SATA/300 Samsung SpinPoint F1 RAID 16MB",
"HE322HJ" => "320GB 7.2K SATA/300 Samsung SpinPoint F1 RAID 16MB",
"HE502IJ" => "500GB 7.2K SATA/300 Samsung SpinPoint F1 RAID 16MB",
"HE753LJ" => "750GB 7.2K SATA/300 Samsung SpinPoint F1 RAID 32MB",
"HE103UJ" => "1TB 7.2K SATA/300 Samsung SpinPoint F1 RAID 32MB",
# http://www.wdc.com/en/products/productcatalog.asp?Language=en
# http://websupport.wdc.com/products/pf.asp?fid=18
"WD100EB" => "10GB 5.4K ATA/100 WD Protege 2MB",
"WD200EB" => "20GB 5.4K ATA/100 WD Protege 2MB",
"WD300EB" => "30GB 5.4K ATA/100 WD Protege 2MB",
"WD400EB" => "40GB 5.4K ATA/100 WD Protege 2MB",
"WD600EB" => "60GB 5.4K ATA/100 WD Protege 2MB",
"WD800EB" => "80GB 5.4K ATA/100 WD Protege 2MB",
"WD64AA" => "6GB 5.4K ATA/66 WD Caviar 2MB",
"WD75AA" => "7GB 5.4K ATA/66 WD Caviar 2MB",
"WD84AA" => "8GB 5.4K ATA/66 WD Caviar 2MB",
"WD102AA" => "10GB 5.4K ATA/66 WD Caviar 2MB",
"WD136AA" => "13GB 5.4K ATA/66 WD Caviar 2MB",
"WD153AA" => "15GB 5.4K ATA/66 WD Caviar 2MB",
"WD205AA" => "20GB 5.4K ATA/66 WD Caviar 2MB",
"WD307AA" => "30GB 5.4K ATA/66 WD Caviar 2MB",
"WD450AA" => "45GB 5.4K ATA/66 WD Caviar 2MB",
"WD102BA" => "10GB 7.2K ATA/66 WD Caviar 2MB",
"WD136BA" => "13GB 7.2K ATA/66 WD Caviar 2MB",
"WD153BA" => "15GB 7.2K ATA/66 WD Caviar 2MB",
"WD205BA" => "20GB 7.2K ATA/66 WD Caviar 2MB",
"WD100AB" => "10GB 5.4K ATA/100 WD Caviar 2MB",
"WD200AB" => "20GB 5.4K ATA/100 WD Caviar 2MB",
"WD300AB" => "30GB 5.4K ATA/100 WD Caviar 2MB",
"WD400AB" => "40GB 5.4K ATA/100 WD Caviar 2MB",
"WD600AB" => "60GB 5.4K ATA/100 WD Caviar 2MB",
"WD800AB" => "80GB 5.4K ATA/100 WD Caviar 2MB",
"WD1000AB" => "100GB 5.4K ATA/100 WD Caviar 2MB",
"WD1200AB" => "120GB 5.4K ATA/100 WD Caviar 2MB",
"WD1600AB" => "160GB 5.4K ATA/100 WD Caviar 2MB",
# http://websupport.wdc.com/products/pf.asp?fid=2
"WD100BB" => "10GB 7.2K ATA/100 WD Caviar 2MB",
"WD200BB" => "20GB 7.2K ATA/100 WD Caviar 2MB",
"WD300BB" => "30GB 7.2K ATA/100 WD Caviar 2MB",
"WD400BB" => "40GB 7.2K ATA/100 WD Caviar 2MB",
"WD600BB" => "60GB 7.2K ATA/100 WD Caviar 2MB",
"WD800BB" => "80GB 7.2K ATA/100 WD Caviar 2MB",
"WD1000BB" => "100GB 7.2K ATA/100 WD Caviar 2MB",
"WD1200BB" => "120GB 7.2K ATA/100 WD Caviar 2MB",
"WD1600BB" => "160GB 7.2K ATA/100 WD Caviar 2MB",
"WD1800BB" => "180GB 7.2K ATA/100 WD Caviar 2MB",
"WD2000BB" => "200GB 7.2K ATA/100 WD Caviar 2MB",
"WD2500BB" => "250GB 7.2K ATA/100 WD Caviar 2MB",
"WD3000BB" => "300GB 7.2K ATA/100 WD Caviar 2MB",
"WD3200BB" => "320GB 7.2K ATA/100 WD Caviar 2MB",
# http://websupport.wdc.com/products/pf.asp?fid=6
"WD400JB" => "40GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD800JB" => "80GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD1000JB" => "100GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD1200JB" => "120GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD1600JB" => "160GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD1800JB" => "180GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD2000JB" => "200GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD2500JB" => "250GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD3000JB" => "300GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD3200JB" => "320GB 7.2K ATA/100 WD Caviar SE 8MB",
# same as JB drives above
"WD800AAJB" => "80GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD1600AAJB" => "160GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD2500AAJB" => "250GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD3200AAJB" => "320GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD4000AAJB" => "400GB 7.2K ATA/100 WD Caviar SE 8MB",
"WD5000AAJB" => "500GB 7.2K ATA/100 WD Caviar SE 8MB",
# same as BB line with liquid bearing?
"WD800LB" => "80GB 7.2K ATA/100 WD Caviar 2MB",
"WD1200LB" => "120GB 7.2K ATA/100 WD Caviar 2MB",
"WD1600LB" => "160GB 7.2K ATA/100 WD Caviar 2MB",
# PB drives sold in korea only?
"WD800PB" => "80GB 7.2K ATA/100 WD Caviar",
"WD1200JD" => "120GB 7.2K SATA/150 WD Caviar SE 8MB",
"WD1600JD" => "160GB 7.2K SATA/150 WD Caviar SE 8MB",
"WD2000JD" => "200GB 7.2K SATA/150 WD Caviar SE 8MB",
"WD2500JD" => "250GB 7.2K SATA/150 WD Caviar SE 8MB",
"WD3000JD" => "300GB 7.2K SATA/150 WD Caviar SE 8MB",
"WD3200JD" => "320GB 7.2K SATA/150 WD Caviar SE 8MB",
"WD400BD" => "40GB 7.2K SATA/150 WD Caviar",
"WD800BD" => "80GB 7.2K SATA/150 WD Caviar",
"WD400PD" => "40GB 7.2K SATA/150 WD Caviar SE",
"WD800PD" => "80GB 7.2K SATA/150 WD Caviar SE",
"WD1200PD" => "120GB 7.2K SATA/150 WD Caviar SE",
"WD1600PD" => "160GB 7.2K SATA/150 WD Caviar SE",
"WD2000PD" => "200GB 7.2K SATA/150 WD Caviar SE",
"WD2500PD" => "250GB 7.2K SATA/150 WD Caviar SE",
"WD400JD" => "40GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD800JD" => "80GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD1200JS" => "120GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD1600JS" => "160GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD2000JS" => "200GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD2500JS" => "250GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD3000JS" => "300GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD800AAJS" => "80GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD1600AAJS" => "160GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD2500AAJS" => "250GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD3200AAJS" => "320GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD4000AAJS" => "400GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD5000AAJS" => "500GB 7.2K SATA/300 WD Caviar SE 8MB",
"WD1600SB" => "160GB 7.2K ATA/100 WD Caviar RE 8MB",
"WD2500SB" => "250GB 7.2K ATA/100 WD Caviar RE 8MB",
"WD3200SB" => "320GB 7.2K ATA/100 WD Caviar RE 8MB",
"WD1200SD" => "120GB 7.2K SATA/150 WD Caviar RE 8MB",
"WD1600SD" => "160GB 7.2K SATA/150 WD Caviar RE 8MB",
"WD2500SD" => "250GB 7.2K SATA/150 WD Caviar RE 8MB",
"WD3200SD" => "320GB 7.2K SATA/150 WD Caviar RE 8MB",
"WD1600YD" => "160GB 7.2K SATA/300 WD Caviar RE 16MB",
"WD2500YD" => "250GB 7.2K SATA/300 WD Caviar RE 16MB",
"WD4000YR" => "400GB 7.2K SATA/150 WD Caviar RE2 16MB",
"WD2500KS" => "250GB 7.2K SATA/300 WD Caviar SE16 16MB",
"WD3200KS" => "320GB 7.2K SATA/300 WD Caviar SE16 16MB",
"WD4000KS" => "400GB 7.2K SATA/300 WD Caviar SE16 16MB",
"WD5000KS" => "500GB 7.2K SATA/300 WD Caviar SE16 16MB",
"WD3200AAKB" => "320GB 7.2K ATA/100 WD Caviar SE16 16MB", # Now called "Caviar Blue"
"WD4000AAKB" => "400GB 7.2K ATA/100 WD Caviar SE16 16MB",
"WD5000AAKB" => "500GB 7.2K ATA/100 WD Caviar SE16 16MB",
"WD2500AAKS" => "250GB 7.2K SATA/300 WD Caviar SE16 16MB",
"WD3200AAKS" => "320GB 7.2K SATA/300 WD Caviar SE16 16MB",
"WD4000AAKS" => "400GB 7.2K SATA/300 WD Caviar SE16 16MB",
"WD5000AAKS" => "500GB 7.2K SATA/300 WD Caviar SE16 16MB",
"WD7500AAKS" => "750GB 7.2K SATA/300 WD Caviar SE16 16MB",
"WD5000AACS" => "500GB 7.2K SATA/300 WD Caviar GP 16MB",
"WD7500AACS" => "750GB 7.2K SATA/300 WD Caviar GP 16MB",
"WD10EACS" => "1TB 7.2K SATA/300 WD Caviar GP 16MB",
# Enterprise drives
"WD1600YS" => "160GB 7.2K SATA/300 WD RE 16MB",
"WD2500YS" => "250GB 7.2K SATA/300 WD RE 16MB",
"WD3200YS" => "320GB 7.2K SATA/300 WD RE 16MB",
"WD1601ABYS" => "160GB 7.2K SATA/300 WD RE2 16MB",
"WD3201ABYS" => "320GB 7.2K SATA/300 WD RE2 16MB",
"WD4000YS" => "400GB 7.2K SATA/300 WD RE2 16MB",
"WD4000ABYS" => "400GB 7.2K SATA/300 WD RE2 16MB",
"WD4001ABYS" => "400GB 7.2K SATA/300 WD RE2 16MB",
"WD5000YS" => "500GB 7.2K SATA/300 WD RE2 16MB",
"WD5000ABYS" => "500GB 7.2K SATA/300 WD RE2 16MB",
"WD5001ABYS" => "500GB 7.2K SATA/300 WD RE2 16MB",
"WD7500AYYS" => "750GB 7.2K SATA/300 WD RE2 16MB",
"WD2502ABYS" => "250GB 7.2K SATA/300 WD RE3 16MB",
"WD3202ABYS" => "320GB 7.2K SATA/300 WD RE3 16MB",
"WD5002ABYS" => "500GB 7.2K SATA/300 WD RE3 16MB",
"WD7502ABYS" => "750GB 7.2K SATA/300 WD RE3 32MB",
"WD1002FBYS" => "1TB 7.2K SATA/300 WD RE3 32MB",
"WD5000ABPS" => "500GB 7.2K SATA/300 WD RE2-GP 16MB",
"WD7500AYPS" => "750GB 7.2K SATA/300 WD RE2-GP 16MB",
"WD1000FYPS" => "1TB 7.2K SATA/300 WD RE2-GP 16MB",
# Hitachi
"DK32DJ-18M" => "18GB 10K U320 Hitachi Ultrastar",
"DK32DJ-36M" => "36GB 10K U320 Hitachi Ultrastar",
"DK32DJ-72M" => "73GB 10K U320 Hitachi Ultrastar",
"DK32EJ-36N" => "36GB 10K U320 Hitachi Ultrastar",
"DK32EJ-72N" => "73GB 10K U320 Hitachi Ultrastar",
"DK32EJ-14N" => "147GB 10K U320 Hitachi Ultrastar",
"DNES-309170W" => "9GB 7.2K Ultra IBM Ultrastar 18ES 2MB",
"DNES-318350W" => "18GB 7.2K Ultra IBM Ultrastar 18ES 2MB",
"DPSS-309170" => "9GB 10K U160 IBM Ultrastar 36LP",
"DPSS-318350" => "18GB 10K U160 IBM Ultrastar 36LP",
"DPSS-336950" => "36GB 10K U160 IBM Ultrastar 36LP",
"DMVS18M" => "18GB 10K U160 IBM",
"DMVS18V" => "18GB 10K Ultra2 IBM Ultrastar 18LZX",
"DDYS-T09170" => "9GB 10K U160 IBM Ultrastar 36LZX",
"DDYS-T18350" => "18GB 10K U160 IBM Ultrastar 36LZX",
"DDYS-T36950" => "36GB 10K U160 IBM Ultrastar 36LZX",
"IC35L009UWD210" => "9GB 10K U160 IBM Ultrastar 73LZX",
"IC35L018UWD210" => "18GB 10K U160 IBM Ultrastar 73LZX",
"IC35L036UWD210" => "36GB 10K U160 IBM Ultrastar 73LZX",
"IC35L073UWD210" => "73GB 10K U160 IBM Ultrastar 73LZX",
"IC35L009XWD210" => "9GB 10K U320 IBM Ultrastar 73LZX",
"IC35L018XWD210" => "18GB 10K U320 IBM Ultrastar 73LZX",
"IC35L036XWD210" => "36GB 10K U320 IBM Ultrastar 73LZX",
"IC35L073XWD210" => "73GB 10K U320 IBM Ultrastar 73LZX",
"IC35L018U[CW]DY10" => "18GB 10K U320 IBM Ultrastar 146Z10",
"IC35L036U[CW]DY10" => "36GB 10K U320 IBM Ultrastar 146Z10",
"IC35L073U[CW]DY10" => "73GB 10K U320 IBM Ultrastar 146Z10",
"IC35L146U[CW]DY10" => "146GB 10K U320 IBM Ultrastar 146Z10",
"HUS151436VL3[68]00" => "36GB 15K U320 Hitachi Ultrastar 15K147",
"HUS151473VL3[68]00" => "73GB 15K U320 Hitachi Ultrastar 15K147",
"HUS151414VL3[68]00" => "147GB 15K U320 Hitachi Ultrastar 15K147",
"HUS151436VLS300" => "36GB 15K SAS/3 Hitachi Ultrastar 15K147 16MB",
"HUS151473VLS300" => "73GB 15K SAS/3 Hitachi Ultrastar 15K147 16MB",
"HUS151414VLS300" => "147GB 15K SAS/3 Hitachi Ultrastar 15K147 16MB",
"HUS153073VLS300" => "73GB 15K SAS/3 Hitachi Ultrastar 15K300 16MB",
"HUS153014VLS300" => "147GB 15K SAS/3 Hitachi Ultrastar 15K300 16MB",
"HUS153030VLS300" => "300GB 15K SAS/3 Hitachi Ultrastar 15K300 16MB",
"HUC101473CSS300" => "73GB 10K SAS/3 2.5\" Hitachi Ultrastar C10K147",
"HUC101414CSS300" => "147GB 10K SAS/3 2.5\" Hitachi Ultrastar C10K147",
"DHEA-34330" => "4GB 5.4K ATA/33 IBM Desktar 5",
"DHEA-36480" => "6GB 5.4K ATA/33 IBM Desktar 5",
"DHEA-34331" => "4GB 5.4K ATA/33 IBM Desktar 8",
"DHEA-36481" => "6GB 5.4K ATA/33 IBM Desktar 8",
"DHEA-38451" => "8GB 5.4K ATA/33 IBM Desktar 8",
"DPTA-371360" => "14GB 7.2K ATA/66 IBM Deskstar 34GXP",
"DPTA-372050" => "20GB 7.2K ATA/66 IBM Deskstar 34GXP",
"DPTA-372730" => "27GB 7.2K ATA/66 IBM Deskstar 34GXP",
"DPTA-373420" => "34GB 7.2K ATA/66 IBM Deskstar 34GXP",
"HDS728040PLAT20" => "40GB 7.2K ATA/133 Hitachi Deskstar 7K80",
"HDS728080PLAT20" => "80GB 7.2K ATA/133 Hitachi Deskstar 7K80",
"HTS548020M9AT00" => "20GB 5.4K ATA/100 2.5\" Hitachi Travelstar 5K80 8MB",
"HTS548040M9AT00" => "40GB 5.4K ATA/100 2.5\" Hitachi Travelstar 5K80 8MB",
"HTS548060M9AT00" => "60GB 5.4K ATA/100 2.5\" Hitachi Travelstar 5K80 8MB",
"HTS548080M9AT00" => "80GB 5.4K ATA/100 2.5\" Hitachi Travelstar 5K80 8MB",
"HTS541640J9AT00" => "40GB 5.4K ATA/100 2.5\" Hitachi Travelstar 5K160 8MB",
"HTS541660J9AT00" => "60GB 5.4K ATA/100 2.5\" Hitachi Travelstar 5K160 8MB",
"HTS541680J9AT00" => "80GB 5.4K ATA/100 2.5\" Hitachi Travelstar 5K160 8MB",
"HTS541612J9AT00" => "120GB 5.4K ATA/100 2.5\" Hitachi Travelstar 5K160 8MB",
"HTS541616J9AT00" => "160GB 5.4K ATA/100 2.5\" Hitachi Travelstar 5K160 8MB",
"HTS541640J9SA00" => "40GB 5.4K SATA/150 2.5\" Hitachi Travelstar 5K160 8MB",
"HTS541660J9SA00" => "60GB 5.4K SATA/150 2.5\" Hitachi Travelstar 5K160 8MB",
"HTS541680J9SA00" => "80GB 5.4K SATA/150 2.5\" Hitachi Travelstar 5K160 8MB",
"HTS541612J9SA00" => "120GB 5.4K SATA/150 2.5\" Hitachi Travelstar 5K160 8MB",
"HTS541616J9SA00" => "160GB 5.4K SATA/150 2.5\" Hitachi Travelstar 5K160 8MB",
"HTE542580K9A300" => "80GB 5.4K SATA/300 2.5\" Hitachi Travelstar E5K250 8MB",
"HTE542512K9A300" => "120GB 5.4K SATA/300 2.5\" Hitachi Travelstar E5K250 8MB",
"HTE542516K9A300" => "160GB 5.4K SATA/300 2.5\" Hitachi Travelstar E5K250 8MB",
"HTE542525K9A300" => "250GB 5.4K SATA/300 2.5\" Hitachi Travelstar E5K250 8MB",
"HTS721060G9AT00" => "60GB 7.2K ATA/100 2.5\" Hitachi Travelstar 7K100 8MB",
"HTS721080G9AT00" => "80GB 7.2K ATA/100 2.5\" Hitachi Travelstar 7K100 8MB",
"HTS721010G9AT00" => "100GB 7.2K ATA/100 2.5\" Hitachi Travelstar 7K100 8MB",
"HTS721060G9SA00" => "60GB 7.2K SATA/150 2.5\" Hitachi Travelstar 7K100 8MB",
"HTS721080G9SA00" => "80GB 7.2K SATA/150 2.5\" Hitachi Travelstar 7K100 8MB",
"HTS721010G9SA00" => "100GB 7.2K SATA/150 2.5\" Hitachi Travelstar 7K100 8MB",
"HDS721680PLA380" => "80GB 7.2K SATA/300 Hitachi Deskstar 7K160",
"HDS721616PLA380" => "160GB 7.2K SATA/300 Hitachi Deskstar 7K160",
"HDS722540VLAT20" => "40GB 7.2K ATA/100 Hitachi Deskstar 7K250 2MB",
"HDS722580VLAT20" => "80GB 7.2K ATA/100 Hitachi Deskstar 7K250 2MB",
"HDS722512VLAT20" => "120GB 7.2K ATA/100 Hitachi Deskstar 7K250 2MB",
"HDS722512VLAT80" => "120GB 7.2K ATA/100 Hitachi Deskstar 7K250 8MB",
"HDS722516VLAT20" => "160GB 7.2K ATA/100 Hitachi Deskstar 7K250 2MB",
"HDS722516VLAT80" => "160GB 7.2K ATA/100 Hitachi Deskstar 7K250 8MB",
"HDS722525VLAT80" => "250GB 7.2K ATA/100 Hitachi Deskstar 7K250 8MB",
"HDS722540VLSA80" => "40GB 7.2K SATA/150 Hitachi Deskstar 7K250 8MB",
"HDS722580VLSA80" => "80GB 7.2K SATA/150 Hitachi Deskstar 7K250 8MB",
"HDS722512VLSA80" => "120GB 7.2K SATA/150 Hitachi Deskstar 7K250 8MB",
"HDS722516VLSA80" => "160GB 7.2K SATA/150 Hitachi Deskstar 7K250 8MB",
"HDS722525VLSA80" => "250GB 7.2K SATA/150 Hitachi Deskstar 7K250 8MB",
"HDS724040KLAT80" => "400GB 7.2K ATA/133 Hitachi Deskstar 7K400 8MB",
"HDS724040KLSA80" => "400GB 7.2K SATA/150 Hitachi Deskstar 7K400 8MB",
"HDS725050KLAT80" => "500GB 7.2K ATA/133 Hitachi Deskstar 7K500 8MB",
"HDS725050KLA361" => "400GB 7.2K SATA/300 Hitachi Deskstar E7K500 16MB",
"HDS725050KLA360" => "500GB 7.2K SATA/300 Hitachi Deskstar E7K500 16MB",
"HDP725016GLA380" => "160GB 7.2K SATA/300 Hitachi Deskstar P7K500 8MB",
"HDP725025GLA380" => "250GB 7.2K SATA/300 Hitachi Deskstar P7K500 8MB",
"HDP725032GLA380" => "320GB 7.2K SATA/300 Hitachi Deskstar P7K500 8MB",
"HDP725032GLA360" => "320GB 7.2K SATA/300 Hitachi Deskstar P7K500 16MB",
"HDP725040GLA380" => "400GB 7.2K SATA/300 Hitachi Deskstar P7K500 8MB",
"HDP725040GLA360" => "400GB 7.2K SATA/300 Hitachi Deskstar P7K500 16MB",
"HDP725050GLA380" => "500GB 7.2K SATA/300 Hitachi Deskstar P7K500 8MB",
"HDP725050GLA360" => "500GB 7.2K SATA/300 Hitachi Deskstar P7K500 16MB",
"HDT725025VLA380" => "250GB 7.2K SATA/300 Hitachi Deskstar T7K500 8MB",
"HDT725025VLA360" => "250GB 7.2K SATA/300 Hitachi Deskstar T7K500 16MB",
"HDT725032VLA380" => "320GB 7.2K SATA/300 Hitachi Deskstar T7K500 8MB",
"HDT725032VLA360" => "320GB 7.2K SATA/300 Hitachi Deskstar T7K500 16MB",
"HDT725040VLA380" => "400GB 7.2K SATA/300 Hitachi Deskstar T7K500 8MB",
"HDT725040VLA360" => "400GB 7.2K SATA/300 Hitachi Deskstar T7K500 16MB",
"HDT725050VLA380" => "500GB 7.2K SATA/300 Hitachi Deskstar T7K500 8MB",
"HDT725050VLA360" => "500GB 7.2K SATA/300 Hitachi Deskstar T7K500 16MB",
"HDS721075KLA330" => "750GB 7.2K SATA/300 Hitachi Deskstar 7K1000 32MB",
"HDS721010KLA330" => "1TB 7.2K SATA/300 Hitachi Deskstar 7K1000 32MB",
"HDT721016SLA380" => "160GB 7.2K SATA/300 Hitachi Deskstar 7K1000.B 8MB",
"HDT721025SLA380" => "250GB 7.2K SATA/300 Hitachi Deskstar 7K1000.B 8MB",
"HDT721032SLA360" => "320GB 7.2K SATA/300 Hitachi Deskstar 7K1000.B 8MB",
"HDT721050SLA360" => "500GB 7.2K SATA/300 Hitachi Deskstar 7K1000.B 8MB",
"HDT721064SLA360" => "640GB 7.2K SATA/300 Hitachi Deskstar 7K1000.B 8MB",
"HDT721075SLA360" => "750GB 7.2K SATA/300 Hitachi Deskstar 7K1000.B 8MB",
"HDT721010SLA360" => "1TB 7.2K SATA/300 Hitachi Deskstar 7K1000.B 8MB",
"HDE721050SLA330" => "500GB 7.2K SATA/300 Hitachi Deskstar E7K1000 32MB",
"HDE721075SLA330" => "750GB 7.2K SATA/300 Hitachi Deskstar E7K1000 32MB",
"HDE721010SLA330" => "1TB 7.2K SATA/300 Hitachi Deskstar E7K1000 32MB",
"HUA721050KLA330" => "500GB 7.2K SATA/300 Hitachi Ultrastar A7K1000 32MB",
"HUA721075KLA330" => "750GB 7.2K SATA/300 Hitachi Ultrastar A7K1000 32MB",
"HUA72107A74A" => "750GB 7.2K SATA/300 Hitachi Ultrastar A7K1000 32MB", # megacli on momentum-pr-q95.data.corp.sp1.yahoo.com
"HUA721010KLA330" => "1TB 7.2K SATA/300 Hitachi Ultrastar A7K1000 32MB",
"IC35L010AVER07" => "10GB 7.2K ATA/100 IBM Deskstar 60GXP",
"IC35L020AVER07" => "21GB 7.2K ATA/100 IBM Deskstar 60GXP",
"IC35L030AVER07" => "31GB 7.2K ATA/100 IBM Deskstar 60GXP",
"IC35L040AVER07" => "41GB 7.2K ATA/100 IBM Deskstar 60GXP",
"IC35L060AVER07" => "61GB 7.2K ATA/100 IBM Deskstar 60GXP",
"IC35L020AVVA07" => "20GB 7.2K ATA/100 IBM Deskstar 120GXP",
"IC35L020AVVN07" => "20GB 7.2K ATA/100 IBM Deskstar 120GXP",
"IC35L040AVVA07" => "40GB 7.2K ATA/100 IBM Deskstar 120GXP",
"IC35L040AVVN07" => "40GB 7.2K ATA/100 IBM Deskstar 120GXP",
"IC35L060AVVA07" => "60GB 7.2K ATA/100 IBM Deskstar 120GXP",
"IC35L060AVVN07" => "60GB 7.2K ATA/100 IBM Deskstar 120GXP",
"IC35L080AVVA07" => "80GB 7.2K ATA/100 IBM Deskstar 120GXP",
"IC35L080AVVN07" => "80GB 7.2K ATA/100 IBM Deskstar 120GXP",
"IC35L100AVVN07" => "100GB 7.2K ATA/100 IBM Deskstar 120GXP",
"IC35L100AVVA07" => "100GB 7.2K ATA/100 IBM Deskstar 120GXP",
"IC35L120AVVN07" => "120GB 7.2K ATA/100 IBM Deskstar 120GXP",
"IC35L120AVVA07" => "120GB 7.2K ATA/100 IBM Deskstar 120GXP",
"IC35L030AVV207" => "30GB 7.2K ATA/100 IBM Deskstar 180GXP",
"IC35L060AVV207" => "40GB 7.2K ATA/100 IBM Deskstar 180GXP",
"IC35L090AVV207" => "80GB 7.2K ATA/100 IBM Deskstar 180GXP",
"IC35L120AVV207" => "120GB 7.2K ATA/100 IBM Deskstar 180GXP",
"IC35L180AVV207" => "180GB 7.2K ATA/100 IBM Deskstar 180GXP",
"DJNA-351010" => "10GB 5.4K ATA/66 IBM Deskstar 25GP",
"DJNA-351520" => "15GB 5.4K ATA/66 IBM Deskstar 25GP",
"DJNA-352030" => "20GB 5.4K ATA/66 IBM Deskstar 25GP",
"DJNA-352500" => "25GB 5.4K ATA/66 IBM Deskstar 25GP",
"DJNA-379100" => "9GB 7.2K ATA/66 IBM Deskstar 22GXP",
"DJNA-371350" => "13GB 7.2K ATA/66 IBM Deskstar 22GXP",
"DJNA-371800" => "18GB 7.2K ATA/66 IBM Deskstar 22GXP",
"DJNA-372200" => "22GB 7.2K ATA/66 IBM Deskstar 22GXP",
"DTTA-350320" => "3GB 5.4K ATA/33 IBM Deskstar 16GP",
"DTTA-350403" => "4GB 5.4K ATA/33 IBM Deskstar 16GP",
"DTTA-350640" => "6GB 5.4K ATA/33 IBM Deskstar 16GP",
"DTTA-350840" => "8GB 5.4K ATA/33 IBM Deskstar 16GP",
"DTTA-351010" => "10GB 5.4K ATA/33 IBM Deskstar 16GP",
"DTTA-351290" => "12GB 5.4K ATA/33 IBM Deskstar 16GP",
"DTTA-351680" => "16GB 5.4K ATA/33 IBM Deskstar 16GP",
"DTTA-371010" => "10GB 7.2K ATA/33 IBM Deskstar 14GXP",
"DTTA-371290" => "12GB 7.2K ATA/33 IBM Deskstar 14GXP",
"DTTA-371440" => "14GB 7.2K ATA/33 IBM Deskstar 14GXP",
"DTLA-305010" => "10GB 5.4K ATA/100 IBM Deskstar 40GV",
"DTLA-305020" => "20GB 5.4K ATA/100 IBM Deskstar 40GV",
"DTLA-305030" => "30GB 5.4K ATA/100 IBM Deskstar 40GV",
"DTLA-305040" => "40GB 5.4K ATA/100 IBM Deskstar 40GV",
"DTLA-307015" => "15GB 7.2K ATA/100 IBM Deskstar 75GXP",
"DTLA-307020" => "20GB 7.2K ATA/100 IBM Deskstar 75GXP",
"DTLA-307030" => "30GB 7.2K ATA/100 IBM Deskstar 75GXP",
"DTLA-307045" => "45GB 7.2K ATA/100 IBM Deskstar 75GXP",
"DTLA-307060" => "60GB 7.2K ATA/100 IBM Deskstar 75GXP",
"DTLA-307075" => "75GB 7.2K ATA/100 IBM Deskstar 75GXP",
"ST34501" => "4GB 10K Ultra Seagate Cheetah 4LP",
"ST34573" => "4GB 7.2K Ultra2 Seagate Barracuda 9LP",
"ST39173" => "9GB 7.2K Ultra2 Seagate Barracuda 9LP",
"ST118273" => "18GB 7.2K Ultra2 Seagate Barracuda 18",
"ST39175" => "9GB 7.2K Ultra2 Seagate Barracuda 18LP",
"ST318275" => "18GB 7.2K Ultra2 Seagate Barracuda 18LP",
"ST39236" => "9GB 7.2K U160 Seagate Barracuda 18XL",
"ST318436" => "18GB 7.2K U160 Seagate Barracuda 18XL",
"ST150176" => "50GB 7.2K Ultra2 Seagate Barracuda 50",
"ST39102" => "9GB 10K Ultra2 Seagate Cheetah 9LP",
"ST39103" => "9GB 10K Ultra2 Seagate Cheetah 18LP",
"ST318203" => "18GB 10K Ultra2 Seagate Cheetah 18LP",
"ST39204" => "9GB 10K U160 Seagate Cheetah 18XL",
"ST318404" => "18GB 10K U160 Seagate Cheetah 18XL",
"ST336704" => "36GB 10K U160 Seagate Cheetah 36LP",
"ST318305" => "18GB 10K U160 Seagate Cheetah 18XL",
"ST318405" => "18GB 10K U160 Seagate 36XL",
"ST336705" => "36GB 10K U160 Seagate 36XL",
"ST336605" => "36GB 10K U160 Seagate 73LP",
"ST373405" => "73GB 10K U160 Seagate 73LP",
"ST318406" => "18GB 10K U160 Seagate 36ES",
"ST336706" => "37GB 10K U160 Seagate 36ES",
"ST336607" => "37GB 10K U320 Seagate 10K.6",
"ST373307" => "73GB 10K U320 Seagate 10K.6",
"ST3146807" => "147GB 10K U320 Seagate 10K.6",
"ST336807" => "36GB 10K U320 Seagate 10K.7",
"ST373207" => "72GB 10K U320 Seagate 10K.7",
"ST3146707" => "146GB 10K U320 Seagate 10K.7",
"ST3300007" => "300GB 10K U320 Seagate 10K.7",
"ST373355SS" => "72GB 15K SAS/3 Seagate T10",
"ST3146755SS" => "146GB 15K SAS/3 Seagate T10",
"ST3300555SS" => "300GB 15K SAS/3 Seagate T10",
"ST318452" => "18GB 15K U160 Seagate X15 36LP",
"ST336752" => "36GB 15K U160 Seagate X15 36LP",
"ST318432" => "18GB 15K U320 Seagate X15 36LP",
"ST336732" => "36GB 15K U320 Seagate X15 36LP",
"ST318453" => "18GB 15K U320 Seagate 15K.3",
"ST336753" => "37GB 15K U320 Seagate 15K.3",
"ST373453" => "73GB 15K U320 Seagate 15K.3",
"ST336754SS" => "37GB 15K SAS/3 Seagate 15K.4",
"ST373454SS" => "73GB 15K SAS/3 Seagate 15K.4",
"ST3146854SS" => "146GB 15K SAS/3 Seagate 15K.4",
"ST336754" => "37GB 15K U320 Seagate 15K.4",
"ST373454" => "73GB 15K U320 Seagate 15K.4",
"ST3146854" => "146GB 15K U320 Seagate 15K.4",
"ST373455LC" => "73GB 15K U320 Seagate 15K.5",
"ST3146855LC" => "146GB 15K U320 Seagate 15K.5",
"ST3300655LC" => "300GB 15K U320 Seagate 15K.5",
"ST373455SS" => "73GB 15K SAS/3 Seagate 15K.5",
"ST3146855SS" => "146GB 15K SAS/3 Seagate 15K.5",
"ST3300655SS" => "300GB 15K SAS/3 Seagate 15K.5",
"ST3400755SS" => "400GB 10K SAS/3 Seagate Cheetah NS",
"ST3146356SS" => "146GB 15K SAS/3 Seagate 15K.6",
"ST3300656SS" => "300GB 15K SAS/3 Seagate 15K.6",
"ST3450856SS" => "450GB 15K SAS/3 Seagate 15K.6",
"ST34520A" => "4GB 7.2K ATA/33 Seagate Medalist Pro",
"ST36530A" => "6GB 7.2K ATA/33 Seagate Medalist Pro",
"ST39140A" => "9GB 7.2K ATA/33 Seagate Medalist Pro",
"ST310211A" => "10GB 5.4K ATA/100 Seagate U5",
"ST315311A" => "15GB 5.4K ATA/100 Seagate U5",
"ST320413A" => "20GB 5.4K ATA/100 Seagate U5",
"ST330621A" => "30GB 5.4K ATA/100 Seagate U5",
"ST340823A" => "40GB 5.4K ATA/100 Seagate U5",
"ST320423A" => "10GB 5.4K ATA/66 Seagate U10",
"ST315323A" => "15GB 5.4K ATA/66 Seagate U10",
"ST310212A" => "20GB 5.4K ATA/66 Seagate U10",
"ST36810A" => "7GB 7.2K ATA/66 Seagate Barracuda",
"ST310220A" => "10GB 7.2K ATA/66 Seagate Barracuda",
"ST313620A" => "14GB 7.2K ATA/66 Seagate Barracuda",
"ST320430A" => "20GB 7.2K ATA/66 Seagate Barracuda",
"ST328040A" => "28GB 7.2K ATA/66 Seagate Barracuda",
"ST310210A" => "10GB 7.2K ATA/66 Seagate Barracuda II",
"ST315320A" => "15GB 7.2K ATA/66 Seagate Barracuda II",
"ST320420A" => "20GB 7.2K ATA/66 Seagate Barracuda II",
"ST330630A" => "30GB 7.2K ATA/66 Seagate Barracuda II",
"ST310216A" => "10GB 7.2K ATA/100 Seagate Barracuda II 100",
"ST315324A" => "15GB 7.2K ATA/100 Seagate Barracuda II 100",
"ST320424A" => "20GB 7.2K ATA/100 Seagate Barracuda II 100",
"ST330631A" => "30GB 7.2K ATA/100 Seagate Barracuda II 100",
"ST320410A" => "20GB 5.4K ATA/100 Seagate U Series",
"ST330610A" => "30GB 5.4K ATA/100 Seagate U Series",
"ST340810A" => "40GB 5.4K ATA/100 Seagate U Series",
"ST360020A" => "60GB 5.4K ATA/100 Seagate U Series",
"ST380020A" => "80GB 5.4K ATA/100 Seagate U Series",
"ST310215A" => "10GB 7.2K ATA/100 Seagate Barracuda III",
"ST315310A" => "15GB 7.2K ATA/100 Seagate Barracuda III",
"ST320414A" => "20GB 7.2K ATA/100 Seagate Barracuda III",
"ST330620A" => "30GB 7.2K ATA/100 Seagate Barracuda III",
"ST340824A" => "40GB 7.2K ATA/100 Seagate Barracuda III",
"ST320011A" => "20GB 7.2K ATA/100 Seagate Barracuda IV",
"ST340016A" => "40GB 7.2K ATA/100 Seagate Barracuda IV",
"ST360021A" => "60GB 7.2K ATA/100 Seagate Barracuda IV",
"ST380021A" => "80GB 7.2K ATA/100 Seagate Barracuda IV",
"ST340017A" => "40GB 7.2K ATA/100 Seagate Barracuda V",
"ST360015A" => "60GB 7.2K ATA/100 Seagate Barracuda V",
"ST380023A" => "80GB 7.2K ATA/100 Seagate Barracuda V",
"ST3120023A" => "120GB 7.2K ATA/100 Seagate Barracuda V",
"ST340014A" => "40GB 7.2K ATA/100 Seagate 7200.7",
"ST380011A" => "80GB 7.2K ATA/100 Seagate 7200.7",
"ST380013A" => "80GB 7.2K ATA/100 Seagate 7200.7",
"ST3120022A" => "120GB 7.2K ATA/100 Seagate 7200.7",
"ST3160021A" => "160GB 7.2K ATA/100 Seagate 7200.7",
"ST3120026A" => "120GB 7.2K ATA/100 Seagate 7200.7 Plus",
"ST3160023A" => "160GB 7.2K ATA/100 Seagate 7200.7 Plus",
"ST3200021A" => "200GB 7.2K ATA/100 Seagate 7200.7 Plus",
"ST3200822A" => "200GB 7.2K ATA/100 Seagate 7200.7 Plus",
"ST340014AS" => "40GB 7.2K SATA/150 Seagate 7200.7 2MB",
"ST380011AS" => "80GB 7.2K SATA/150 Seagate 7200.7 2MB",
"ST3120022AS" => "120GB 7.2K SATA/150 Seagate 7200.7 2MB",
"ST3160021AS" => "160GB 7.2K SATA/150 Seagate 7200.7 2MB",
"ST380013AS" => "80GB 7.2K SATA/150 Seagate 7200.7 8MB",
"ST3120026AS" => "120GB 7.2K SATA/150 Seagate 7200.7 8MB",
"ST3160023AS" => "160GB 7.2K SATA/150 Seagate 7200.7 8MB",
"ST3200822AS" => "200GB 7.2K SATA/150 Seagate 7200.7 8MB",
"ST380817AS" => "80GB 7.2K SATA/150 Seagate 7200.7 NCQ 8MB",
"ST3120827AS" => "120GB 7.2K SATA/150 Seagate 7200.7 NCQ 8MB",
"ST3160827AS" => "160GB 7.2K SATA/150 Seagate 7200.7 NCQ 8MB",
# Dell specials?
"ST340212AS" => "40GB 7.2K SATA/150 Seagate 7200.7 NCQ 2MB",
"ST340812AS" => "40GB 7.2K SATA/150 Seagate 7200.7 NCQ 8MB",
"ST380219AS" => "80GB 7.2K SATA/150 Seagate 7200.7 NCQ 2MB",
"ST380819AS" => "80GB 7.2K SATA/150 Seagate 7200.7 NCQ 8MB",
"ST3120228AS" => "120GB 7.2K SATA/150 Seagate 7200.7 NCQ 2MB",
"ST3120828AS" => "120GB 7.2K SATA/150 Seagate 7200.7 NCQ 8MB",
"ST3160228AS" => "160GB 7.2K SATA/150 Seagate 7200.7 NCQ 2MB",
"ST3160828AS" => "160GB 7.2K SATA/150 Seagate 7200.7 NCQ 8MB",
"ST3250823A" => "250GB 7.2K ATA/100 Seagate 7200.8",
"ST3300831A" => "300GB 7.2K ATA/100 Seagate 7200.8",
"ST3400832A" => "400GB 7.2K ATA/100 Seagate 7200.8",
"ST3200826AS" => "200GB 7.2K SATA/150 Seagate 7200.8 NCQ",
"ST3250823AS" => "250GB 7.2K SATA/150 Seagate 7200.8 NCQ",
"ST3300831AS" => "300GB 7.2K SATA/150 Seagate 7200.8 NCQ",
"ST3400832AS" => "400GB 7.2K SATA/150 Seagate 7200.8 NCQ",
"ST3402111A" => "40GB 7.2K ATA/100 Seagate 7200.9 2MB",
"ST3802110A" => "80GB 7.2K ATA/100 Seagate 7200.9 2MB",
"ST3120213A" => "120GB 7.2K ATA/100 Seagate 7200.9 2MB",
"ST3120814A" => "120GB 7.2K ATA/100 Seagate 7200.9 8MB",
"ST3160212A" => "160GB 7.2K ATA/100 Seagate 7200.9 2MB",
"ST3160812A" => "160GB 7.2K ATA/100 Seagate 7200.9 8MB",
"ST3200827A" => "200GB 7.2K ATA/100 Seagate 7200.9 8MB",
"ST3250824A" => "250GB 7.2K ATA/100 Seagate 7200.9 8MB",
"ST3250624A" => "250GB 7.2K ATA/100 Seagate 7200.9 16MB",
"ST3300822A" => "300GB 7.2K ATA/100 Seagate 7200.9 8MB",
"ST3300622A" => "300GB 7.2K ATA/100 Seagate 7200.9 16MB",
"ST3400833A" => "400GB 7.2K ATA/100 Seagate 7200.9 8MB",
"ST3400633A" => "400GB 7.2K ATA/100 Seagate 7200.9 16MB",
"ST3500841A" => "500GB 7.2K ATA/100 Seagate 7200.9 8MB",
"ST3500641A" => "500GB 7.2K ATA/100 Seagate 7200.9 16MB",
"ST340211AS" => "40GB 7.2K SATA/300 Seagate 7200.9 2MB",
"ST380211AS" => "80GB 7.2K SATA/300 Seagate 7200.9 2MB",
"ST380811AS" => "80GB 7.2K SATA/300 Seagate 7200.9 8MB",
"ST3120211AS" => "120GB 7.2K SATA/300 Seagate 7200.9 2MB",
"ST3120811AS" => "120GB 7.2K SATA/300 Seagate 7200.9 8MB",
"ST3160211AS" => "160GB 7.2K SATA/300 Seagate 7200.9 2MB",
"ST3160811AS" => "160GB 7.2K SATA/300 Seagate 7200.9 8MB",
"ST3402111AS" => "40GB 7.2K SATA/300 Seagate 7200.9 2MB",
"ST3402112AS" => "40GB 7.2K SATA/300 Seagate 7200.9 2MB",
"ST3802110AS" => "80GB 7.2K SATA/300 Seagate 7200.9 2MB",
"ST3808110AS" => "80GB 7.2K SATA/300 Seagate 7200.9 8MB",
"ST3120213AS" => "120GB 7.2K SATA/300 Seagate 7200.9 2MB",
"ST3120813AS" => "120GB 7.2K SATA/300 Seagate 7200.9 8MB",
"ST3160212AS" => "160GB 7.2K SATA/300 Seagate 7200.9 2MB",
"ST3160812AS" => "160GB 7.2K SATA/300 Seagate 7200.9 8MB",
"ST3200827AS" => "200GB 7.2K SATA/300 Seagate 7200.9 8MB",
"ST3250824AS" => "250GB 7.2K SATA/300 Seagate 7200.9 8MB",
"ST3250624AS" => "250GB 7.2K SATA/300 Seagate 7200.9 16MB",
"ST3300822AS" => "300GB 7.2K SATA/300 Seagate 7200.9 8MB",
"ST3300622AS" => "300GB 7.2K SATA/300 Seagate 7200.9 16MB",
"ST3400833AS" => "400GB 7.2K SATA/300 Seagate 7200.9 8MB",
"ST3400633AS" => "400GB 7.2K SATA/300 Seagate 7200.9 16MB",
"ST3500841AS" => "500GB 7.2K SATA/300 Seagate 7200.9 8MB",
"ST3500641AS" => "500GB 7.2K SATA/300 Seagate 7200.9 16MB",
"ST340215A" => "40GB 7.2K ATA/100 Seagate 7200.10 2MB",
"ST340815A" => "40GB 7.2K ATA/100 Seagate 7200.10 8MB",
"ST380215A" => "80GB 7.2K ATA/100 Seagate 7200.10 2MB",
"ST380815A" => "80GB 7.2K ATA/100 Seagate 7200.10 8MB",
"ST3120215A" => "120GB 7.2K ATA/100 Seagate 7200.10 2MB",
"ST3120815A" => "120GB 7.2K ATA/100 Seagate 7200.10 8MB",
"ST3160215A" => "160GB 7.2K ATA/100 Seagate 7200.10 2MB",
"ST3160815A" => "160GB 7.2K ATA/100 Seagate 7200.10 8MB",
"ST3200820A" => "200GB 7.2K ATA/100 Seagate 7200.10 8MB",
"ST3250820A" => "250GB 7.2K ATA/100 Seagate 7200.10 8MB",
"ST3250620A" => "250GB 7.2K ATA/100 Seagate 7200.10 16MB",
"ST3300820A" => "300GB 7.2K ATA/100 Seagate 7200.10 8MB",
"ST3300620A" => "300GB 7.2K ATA/100 Seagate 7200.10 16MB",
"ST3320820A" => "320GB 7.2K ATA/100 Seagate 7200.10 8MB",
"ST3320620A" => "320GB 7.2K ATA/100 Seagate 7200.10 16MB",
"ST3400820A" => "400GB 7.2K ATA/100 Seagate 7200.10 8MB",
"ST3400620A" => "400GB 7.2K ATA/100 Seagate 7200.10 16MB",
"ST3500830A" => "500GB 7.2K ATA/100 Seagate 7200.10 8MB",
"ST3500630A" => "500GB 7.2K ATA/100 Seagate 7200.10 16MB",
"ST3750840A" => "750GB 7.2K ATA/100 Seagate 7200.10 8MB",
"ST3750640A" => "750GB 7.2K ATA/100 Seagate 7200.10 16MB",
"ST380215AS" => "80GB 7.2K SATA/300 Seagate 7200.10 2MB",
"ST380815AS" => "80GB 7.2K SATA/300 Seagate 7200.10 8MB",
"ST3160215AS" => "160GB 7.2K SATA/300 Seagate 7200.10 2MB",
"ST3160815AS" => "160GB 7.2K SATA/300 Seagate 7200.10 8MB",
"ST3160310AS" => "160GB 7.2K SATA/300 Seagate 7200.10 8MB",
"ST3200820AS" => "200GB 7.2K SATA/300 Seagate 7200.10 8MB",
"ST3250310AS" => "250GB 7.2K SATA/300 Seagate 7200.10 8MB", # 1 platter
"ST3250410AS" => "250GB 7.2K SATA/300 Seagate 7200.10 16MB", # 1 platter
"ST3250820AS" => "250GB 7.2K SATA/300 Seagate 7200.10 8MB", # 2 platters
"ST3250620AS" => "250GB 7.2K SATA/300 Seagate 7200.10 16MB", # 2 platters
"ST3300820AS" => "300GB 7.2K SATA/300 Seagate 7200.10 8MB",
"ST3300620AS" => "300GB 7.2K SATA/300 Seagate 7200.10 16MB",
"ST3320820AS" => "320GB 7.2K SATA/300 Seagate 7200.10 8MB",
"ST3320620AS" => "320GB 7.2K SATA/300 Seagate 7200.10 16MB",
"ST3400820AS" => "400GB 7.2K SATA/300 Seagate 7200.10 8MB",
"ST3400620AS" => "400GB 7.2K SATA/300 Seagate 7200.10 16MB",
"ST3500830AS" => "500GB 7.2K SATA/300 Seagate 7200.10 8MB",
"ST3500630AS" => "500GB 7.2K SATA/300 Seagate 7200.10 16MB",
"ST3750840AS" => "750GB 7.2K SATA/300 Seagate 7200.10 8MB",
"ST3750640AS" => "750GB 7.2K SATA/300 Seagate 7200.10 16MB",
"ST3160813AS" => "160GB 7.2K SATA/300 Seagate 7200.11 8MB",
"ST3320613AS" => "320GB 7.2K SATA/300 Seagate 7200.11 16MB",
"ST3500620AS" => "500GB 7.2K SATA/300 Seagate 7200.11 16MB",
"ST3500320AS" => "500GB 7.2K SATA/300 Seagate 7200.11 32MB",
"ST3640323AS" => "640GB 7.2K SATA/300 Seagate 7200.11 32MB",
"ST3750630AS" => "750GB 7.2K SATA/300 Seagate 7200.11 16MB",
"ST3750330AS" => "750GB 7.2K SATA/300 Seagate 7200.11 32MB",
"ST31000333AS" => "1TB 7.2K SATA/300 Seagate 7200.11 32MB",
"ST31000340AS" => "1TB 7.2K SATA/300 Seagate 7200.11 32MB",
"ST31500341AS" => "1.5TB 7.2K SATA/300 Seagate 7200.11 32MB",
"ST3250823NS" => "250GB 7.2K SATA/150 Seagate NL35 8MB",
"ST3250623NS" => "250GB 7.2K SATA/150 Seagate NL35 16MB",
"ST3400832NS" => "400GB 7.2K SATA/150 Seagate NL35 8MB",
"ST3400632NS" => "400GB 7.2K SATA/150 Seagate NL35 16MB",
"ST3250824NS" => "250GB 7.2K SATA/300 Seagate NL35 8MB",
"ST3250624NS" => "250GB 7.2K SATA/300 Seagate NL35 16MB",
"ST3400833NS" => "400GB 7.2K SATA/300 Seagate NL35 8MB",
"ST3400633NS" => "400GB 7.2K SATA/300 Seagate NL35 16MB",
"ST3500841NS" => "500GB 7.2K SATA/300 Seagate NL35 8MB",
"ST3500641NS" => "500GB 7.2K SATA/300 Seagate NL35 16MB",
"ST3250820NS" => "250GB 7.2K SATA/300 Seagate Barracuda ES 8MB",
"ST3250620NS" => "250GB 7.2K SATA/300 Seagate Barracuda ES 16MB",
"ST3320620NS" => "320GB 7.2K SATA/300 Seagate Barracuda ES 16MB",
"ST3400620NS" => "400GB 7.2K SATA/300 Seagate Barracuda ES 16MB",
"ST3500630NS" => "500GB 7.2K SATA/300 Seagate Barracuda ES 16MB",
"ST3750640NS" => "750GB 7.2K SATA/300 Seagate Barracuda ES 16MB",
"ST325082-0NS" => "250GB 7.2K SATA/300 Seagate Barracuda ES 8MB",
"ST325062-0NS" => "250GB 7.2K SATA/300 Seagate Barracuda ES 16MB",
"ST332062-0NS" => "320GB 7.2K SATA/300 Seagate Barracuda ES 16MB",
"ST340062-0NS" => "400GB 7.2K SATA/300 Seagate Barracuda ES 16MB",
"ST350063-0NS" => "500GB 7.2K SATA/300 Seagate Barracuda ES 16MB",
"ST375064-0NS" => "750GB 7.2K SATA/300 Seagate Barracuda ES 16MB",
"ST3160815SV" => "160GB 7.2K SATA/300 Seagate SV35.2 8MB",
"ST3250820SV" => "250GB 7.2K SATA/300 Seagate SV35.2 8MB",
"ST3320620SV" => "320GB 7.2K SATA/300 Seagate SV35.2 16MB",
"ST3500630SV" => "500GB 7.2K SATA/300 Seagate SV35.2 16MB",
"ST3750640SV" => "750GB 7.2K SATA/300 Seagate SV35.2 16MB",
"ST3250310SV" => "250GB 7.2K SATA/300 Seagate SV35.3 8MB",
"ST3500320SV" => "500GB 7.2K SATA/300 Seagate SV35.3 32MB",
"ST3750330SV" => "750GB 7.2K SATA/300 Seagate SV35.3 32MB",
"ST31000340SV" => "1TB 7.2K SATA/300 Seagate SV35.3 32MB",
"ST3250310NS" => "250GB 7.2K SATA/300 Seagate Barracuda ES.2 32MB",
"ST3500320NS" => "500GB 7.2K SATA/300 Seagate Barracuda ES.2 32MB",
"ST3750330NS" => "750GB 7.2K SATA/300 Seagate Barracuda ES.2 32MB",
"ST31000340NS" => "1TB 7.2K SATA/300 Seagate Barracuda ES.2 32MB",
"ST3500620SS" => "500GB 7.2K SAS/3 Seagate Barracuda ES.2 16MB",
"ST3750630SS" => "750GB 7.2K SAS/3 Seagate Barracuda ES.2 16MB",
"ST31000640SS" => "1TB 7.2K SAS/3 Seagate Barracuda ES.2 16MB",
# http://www.seagate.com/support/disc/manuals/ata/100367120a.pdf
"ST93811A" => "30GB 5.4K ATA/100 2.5\" Seagate Momentus 5400.2 8MB",
"ST94813A" => "40GB 5.4K ATA/100 2.5\" Seagate Momentus 5400.2 8MB",
"ST96812A" => "60GB 5.4K ATA/100 2.5\" Seagate Momentus 5400.2 8MB",
"ST98823A" => "80GB 5.4K ATA/100 2.5\" Seagate Momentus 5400.2 8MB",
"ST9100824A" => "100GB 5.4K ATA/100 2.5\" Seagate Momentus 5400.2 8MB",
"ST9120821A" => "120GB 5.4K ATA/100 2.5\" Seagate Momentus 5400.2 8MB",
"ST9120817AS" => "120GB 5.4K SATA/300 2.5\" Seagate Momentus 5400.4 8MB",
"ST9160827AS" => "160GB 5.4K SATA/300 2.5\" Seagate Momentus 5400.4 8MB",
"ST9200827AS" => "200GB 5.4K SATA/300 2.5\" Seagate Momentus 5400.4 8MB",
"ST9250827AS" => "250GB 5.4K SATA/300 2.5\" Seagate Momentus 5400.4 8MB",
"ST980310AS" => "80GB 5.4K SATA/300 2.5\" Seagate Momentus 5400.5 8MB",
"ST9120310AS" => "120GB 5.4K SATA/300 2.5\" Seagate Momentus 5400.5 8MB",
"ST9160310AS" => "160GB 5.4K SATA/300 2.5\" Seagate Momentus 5400.5 8MB",
"ST9320320AS" => "320GB 5.4K SATA/300 2.5\" Seagate Momentus 5400.5 8MB",
"ST96023AS" => "60GB 7.2K SATA/150 2.5\" Seagate Momentus 7200.1 8MB",
"ST98025AS" => "80GB 7.2K SATA/150 2.5\" Seagate Momentus 7200.1 8MB",
"ST910021AS" => "100GB 7.2K SATA/150 2.5\" Seagate Momentus 7200.1 8MB",
"ST980411AS" => "80GB 7.2K SATA/300 2.5\" Seagate Momentus 7200.3 16MB",
"ST9120411AS" => "120GB 7.2K SATA/300 2.5\" Seagate Momentus 7200.3 16MB",
"ST9160411AS" => "160GB 7.2K SATA/300 2.5\" Seagate Momentus 7200.3 16MB",
"ST9250421AS" => "250GB 7.2K SATA/300 2.5\" Seagate Momentus 7200.3 16MB",
"ST9320421AS" => "320GB 7.2K SATA/300 2.5\" Seagate Momentus 7200.3 16MB",
"ST936701SS" => "37GB 10K SAS/3 2.5\" Seagate Savvio 8MB",
"ST973401SS" => "73GB 10K SAS/3 2.5\" Seagate Savvio 8MB",
"ST936701LC" => "37GB 10K U320 2.5\" Seagate Savvio 8MB",
"ST973401LC" => "73GB 10K U320 2.5\" Seagate Savvio 8MB",
"ST936751SS" => "37GB 15K SAS/3 2.5\" Seagate Savvio 15K 16MB",
"ST973451SS" => "73GB 15K SAS/3 2.5\" Seagate Savvio 15K 16MB",
"ST973402SS" => "73GB 10K SAS/3 2.5\" Seagate Savvio 10K.2 16MB",
"ST9146802SS" => "146GB 10K SAS/3 2.5\" Seagate Savvio 10K.2 16MB",
"MAG3091" => "9GB 10K Ultra2 Fujitsu MAG",
"MAG3182" => "18GB 10K Ultra2 Fujitsu MAG",
"MAH3091" => "9GB 7.2K U160 Fujitsu MAH",
"MAH3182" => "18GB 7.2K U160 Fujitsu MAH",
"MAJ3091" => "9GB 10K U160 Fujitsu MAJ",
"MAJ3182" => "18GB 10K U160 Fujitsu MAJ",
"MAJ3364" => "36GB 10K U160 Fujitsu MAJ",
"MAN3184" => "18GB 10K U160 Fujitsu MAN",
"MAN3367" => "36GB 10K U160 Fujitsu MAN",
"MAN3735" => "73GB 10K U160 Fujitsu MAN",
"MAM3184" => "18GB 15K U160 Fujitsu MAM",
"MAM3367" => "36GB 15K U160 Fujitsu MAM",
"MAS3184" => "18GB 15K U320 Fujitsu MAS",
"MAS3367" => "36GB 15K U320 Fujitsu MAS",
"MAS3735" => "73GB 15K U320 Fujitsu MAS",
"MAP3367" => "36GB 10K U320 Fujitsu MAP",
"MAP3735" => "73GB 10K U320 Fujitsu MAP",
"MAP3147" => "147GB 10K U320 Fujitsu MAP",
"MAT3073" => "73GB 10K U320 Fujitsu MAT",
"MAT3147" => "147GB 10K U320 Fujitsu MAT",
"MAT3300" => "300GB 10K U320 Fujitsu MAT",
"MAW3073" => "73GB 10K U320 Fujitsu MAW",
"MAW3147" => "147GB 10K U320 Fujitsu MAW",
"MAW3300" => "300GB 10K U320 Fujitsu MAW",
"MAU3036" => "36GB 15K U320 Fujitsu MAU",
"MAU3073" => "73GB 15K U320 Fujitsu MAU",
"MAU3147" => "147GB 15K U320 Fujitsu MAU",
"MAX3036" => "36GB 15K U320 Fujitsu MAX",
"MAX3073" => "73GB 15K U320 Fujitsu MAX",
"MAX3147" => "147GB 15K U320 Fujitsu MAX",
"MAX3036RC" => "36GB 15K SAS/3 Fujitsu MAX",
"MAX3073RC" => "73GB 15K SAS/3 Fujitsu MAX",
"MAX3147RC" => "147GB 15K SAS/3 Fujitsu MAX",
"MBA3073NC" => "73GB 15K U320 Fujitsu MBA 16MB",
"MBA3147NC" => "147GB 15K U320 Fujitsu MBA 16MB",
"MBA3300NC" => "300GB 15K U320 Fujitsu MBA 16MB",
"MBA3073RC" => "73GB 15K SAS/3 Fujitsu MBA 16MB",
"MBA3147RC" => "147GB 15K SAS/3 Fujitsu MBA 16MB",
"MBA3300RC" => "300GB 15K SAS/3 Fujitsu MBA 16MB",
"MAV2036" => "36GB 10K SAS/3 2.5\" Fujitsu MAV",
"MAV2073" => "73GB 10K SAS/3 2.5\" Fujitsu MAV",
"MAY2036" => "36GB 10K SAS/3 2.5\" Fujitsu MAY",
"MAY2073" => "73GB 10K SAS/3 2.5\" Fujitsu MAY",
"MBB2073RC" => "73GB 10K SAS/3 2.5\" Fujitsu MBB 16MB",
"MBB2147RC" => "147GB 10K SAS/3 2.5\" Fujitsu MBB 16MB",
"MBC2036RC" => "36GB 15K SAS/3 2.5\" Fujitsu MBC 16MB",
"MBC2073RC" => "73GB 15K SAS/3 2.5\" Fujitsu MBC 16MB",
# HP/Compaq
"BB01813467" => "18GB 7.2K Ultra2 Compaq",
"BB01823469" => "18GB 7.2K Ultra2 Compaq",
"BD0096349A" => "9GB 10K U160 Compaq",
"BD0186349B" => "18GB 10K U160 Compaq",
"BD0366349C" => "36GB 10K U160 Compaq",
"BD009635C3" => "9GB 10K U160 Compaq/Fujitsu",
"BD018635C4" => "18GB 10K U160 Compaq/Fujitsu",
"BD036635C5" => "36GB 10K U160 Compaq/Fujitsu",
"BD03663622" => "36GB 10K U160 Compaq",
"BD01864544" => "18GB 10K U160 Compaq",
"BD03664545" => "36GB 10K U160 Compaq",
"BD07264546" => "72GB 10K U160 Compaq",
"BD01864552" => "18GB 10K U320 Compaq",
"BD03664553" => "36GB 10K U320 Compaq",
"BD0186459A" => "18GB 10K U160 Compaq/Fujitsu MAN",
"BD0366459B" => "36GB 10K U160 Compaq/Fujitsu MAN",
"BD0726459C" => "72GB 10K U160 Compaq/Fujitsu MAN",
"BD0366536B" => "36GB 10K U160 Compaq/Seagate 73LP", # Seagate Cheetah 5
"BD0726536C" => "72GB 10K U160 Compaq/Seagate 73LP",
"BD036659CC" => "36GB 10K U160 Compaq",
"BD07265A22" => "72GB 10K U160 Compaq",
"BD01865CC4" => "18GB 10K U160 Compaq/Fujitsu MAP", # MAP3367
"BD01872377" => "18GB 10K U160 Compaq",
"BD009734A3" => "9GB 10K U160 Compaq",
"BD018734A4" => "18GB 10K U160 Compaq",
"BD009735C6" => "9GB 10K U160 Compaq/Fujitsu",
"BD018735C7" => "18GB 10K U160 Compaq/Fujitsu",
"BD036735C8" => "36GB 10K U160 Compaq/Fujitsu",
"BD01875CC7" => "18GB 10K U160 Compaq/Fujitsu MAP", # related to BD01865CC4
"BD03685A24" => "36GB 10K U320 Compaq/Seagate 10K.6",
"BD07285A25" => "72GB 10K U320 Compaq/Seagate 10K.6",
"BD14685A26" => "146GB 10K U320 Compaq/Seagate 10K.6",
"BD03686223" => "36GB 10K U320 Compaq/Fujitsu MAP",
"BD07286224" => "72GB 10K U320 Compaq/Fujitsu MAP",
"BD14686225" => "146GB 10K U320 Compaq/Fujitsu MAP",
"BD036863AC" => "36GB 10K U320 Compaq/Atlas 10K IV",
"BD072863B2" => "72GB 10K U320 Compaq/Atlas 10K IV",
"BD146863B3" => "146GB 10K U320 Compaq/Atlas 10K IV",
"BD07287B4C" => "72GB 10K U320 Compaq/Atlas 10K V",
"BD14687B52" => "146GB 10K U320 Compaq/Atlas 10K V",
"BD30087B53" => "300GB 10K U320 Compaq/Atlas 10K V",
"BD03688272" => "36GB 10K U320 Compaq/Seagate 10K.7", # ST373207 - looks like a 72G drive!!
"BD07288277" => "72GB 10K U320 Compaq/Seagate 10K.7", # ST373207
"BD14688278" => "146GB 10K U320 Compaq/Seagate 10K.7", # ST3146707
"BD30088279" => "300GB 10K U320 Compaq/Seagate 10K.7", # ST3300007
"BD300884C2" => "300GB 10K U320 Compaq", # related to BD3008A527
"BD0728856A" => "72GB 10K U320 Compaq/Fujitsu MAT", # MAT3073
"BD1468856B" => "146GB 10K U320 Compaq/Fujitsu MAT", # MAT3147
"BD3008856C" => "300GB 10K U320 Compaq/Fujitsu MAT", # MAT3300
"BD07289BB8" => "72GB 10K U320 Compaq/Fujitsu MAW", # MAW3073
"BD14689BB9" => "146GB 10K U320 Compaq/Fujitsu MAW", # MAW3147
"BD30089BBA" => "300GB 10K U320 Compaq/Fujitsu MAW", # MAW3300
"BD0728A4B4" => "72GB 10K U320 Compaq", # related to BD0729A4B7
"BD1468A4B5" => "146GB 10K U320 Compaq",
"BD3008A4B6" => "300GB 10K U320 Compaq",
"BD0728A4C4" => "72GB 10K U320 Compaq", # related to BD0729A4C7
"BD1468A4C5" => "146GB 10K U320 Compaq",
"BD3008A4C6" => "300GB 10K U320 Compaq",
"BD03695A27" => "36GB 10K U320 Compaq/Seagate 10K.6", # related to BD03685A24
"BD03695CC8" => "36GB 10K U320 Compaq/Fujitsu MAP", # related to BD03686223
"BD07296B44" => "72GB 10K U320 Compaq/Fujitsu MAP", # related to BD07286224
"BD03697633" => "36GB 10K U320 Compaq/Atlas 10K IV", # related to BD036863AC
"BD07297B57" => "72GB 10K U320 Compaq/Atlas 10K V", # http://www.ad-min.com/productDetail.aspx?A_ID=2222
"BD14697B58" => "146GB 10K U320 Compaq/Atlas 10K V",
"BD03698276" => "36GB 10K U320 Compaq/Seagate 10K.7", # related to BD03688272, real 72G drive
"BD0729827A" => "72GB 10K U320 Compaq/Seagate 10K.7",
"BD1469827B" => "146GB 10K U320 Compaq/Seagate 10K.7",
"BD3009827C" => "300GB 10K U320 Compaq/Seagate 10K.7",
"BD07298572" => "72GB 10K U320 Compaq/Fujitsu MAT", # related to BD0728856A
"BD14698573" => "146GB 10K U320 Compaq/Fujitsu MAT",
"BD30098574" => "300GB 10K U320 Compaq/Fujitsu MAT",
"BD0729A4C7" => "72GB 10K U320 Compaq", # related to BD0728A4C4
"BD1469A4C8" => "146GB 10K U320 Compaq",
"BD3009A4C9" => "300GB 10K U320 Compaq",
"BD07299BBB" => "72GB 10K U320 Compaq",
# http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?objectID=PSD_CN0304W
"BF01864663" => "18GB 15K U160 Compaq", # WU3 == U160
"BF03664664" => "36GB 15K U160 Compaq", # WU3 == U160
"BF01865222" => "18GB 15K U160 Compaq",
"BF03665223" => "36GB 15K U160 Compaq",
"BF03665A32" => "36GB 15K U160 Compaq",
"BF07284961" => "72GB 15K U320 Compaq",
"BF14684970" => "146GB 15K U320 Compaq",
"BF01885A34" => "18GB 15K U320 Compaq/Seagate 15K.3",
"BF03685A35" => "36GB 15K U320 Compaq/Seagate 15K.3",
"BF07285A36" => "72GB 15K U320 Compaq/Seagate 15K.3", # Seagate ST373453
"BF018863B4" => "18GB 15K U320 Compaq",
"BF036863B5" => "36GB 15K U320 Compaq",
"BF072863B6" => "72GB 15K U320 Compaq",
"BF018863B8" => "18GB 15K U320 Compaq",
"BF036863B9" => "36GB 15K U320 Compaq",
"BF072863BA" => "72GB 15K U320 Compaq",
"BF0368683B" => "36GB 15K U160 Compaq",
"BF0728683C" => "72GB 15K U160 Compaq",
"BF03687B54" => "36GB 15K U320 Compaq", # related to BF03697B5A
"BF07287B55" => "72GB 15K U320 Compaq",
"BF14687B56" => "146GB 15K U320 Compaq",
"BF03688575" => "36GB 15K U320 Compaq/Fujitsu MAU", # MAU3036
"BF07288576" => "72GB 15K U320 Compaq/Fujitsu MAU", # MAU3073
"BF14688577" => "146GB 15K U320 Compaq/Fujitsu MAU", # MAU3147
"BF00988282" => "9GB 15K U320 Compaq",
"BF01888283" => "18GB 15K U320 Compaq",
"BF03688284" => "36GB 15K U320 Compaq/Seagate 15K.4",
"BF07288285" => "72GB 15K U320 Compaq/Seagate 15K.4", # ST373454
"BF14688286" => "146GB 15K U320 Compaq/Seagate 15K.4",
"BF03689BC3" => "36GB 15K U320 Compaq/Fujitsu MAX",
"BF07289BC4" => "72GB 15K U320 Compaq/Fujitsu MAX", # MAX3073
"BF14689BC5" => "146GB 15K U320 Compaq/Fujitsu MAX",
"BF0728A4B2" => "72GB 15K U320 Compaq",
"BF1468A4B3" => "146GB 15K U320 Compaq",
"BF0368A4B9" => "36GB 15K U320 Compaq", # related to BF0369A4BC
"BF0728A4BA" => "72GB 15K U320 Compaq", # related to BF0729A4C2
"BF1468A4BB" => "146GB 15K U320 Compaq", # related to BF1469A4C3
"BF0368A4CA" => "36GB 15K U320 Compaq/Seagate 15K.4", #
"BF0728A4CB" => "72GB 15K U320 Compaq/Seagate 15K.4", # ST373454
"BF1468A4CC" => "146GB 15K U320 Compaq/Seagate 15K.4", #
"BF0728AFEA" => "72GB 15K U320 Compaq",
"BF1468AFEB" => "72GB 15K U320 Compaq", # e.g. pud102.udb.hk2, related to BF14689BC5?
"BF0368B269" => "36GB 15K U320 Compaq",
"BF0728B26A" => "72GB 15K U320 Compaq",
"BF1468B26B" => "146GB 15K U320 Compaq",
"BF03697B5A" => "36GB 15K U320 Compaq", # related to BF03687B54
"BF07297B5B" => "72GB 15K U320 Compaq",
"BF14697B5C" => "146GB 15K U320 Compaq",
"BF03698287" => "36GB 15K U320 Compaq",
"BF07298288" => "72GB 15K U320 Compaq",
"BF14698289" => "146GB 15K U320 Compaq",
"BF03698782" => "36GB 15K U320 Compaq/Fujitsu MAS", # MAS3367
#
# http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?lang=en&cc=us&objectID=c00305257&jumpid=reg_R1002_USEN
#
# search for HP part number at - http://www.lamicrogroup.com/
"DD400B8541" => "400GB 10K SAS HP/Seagate Cheetah NS", # ST3400755SS
"DF146A4941" => "146GB 15K SAS HP",
"DF036A9843" => "36GB 15K SAS HP/Fujitsu MAX",
"DF072A9844" => "72GB 15K SAS HP/Fujitsu MAX", # MAX3073RC
"DF146A9845" => "146GB 15K SAS HP/Fujitsu MAX",
"DF036ABAA7" => "36GB 15K SAS HP/Seagate 15K.5",
"DF072ABAA8" => "72GB 15K SAS HP/Seagate 15K.5",
"DF146ABAA9" => "146GB 15K SAS HP/Seagate 15K.5",
"DF300ABAAA" => "300GB 15K SAS HP/Seagate 15K.5", # ST3300655SS
"DF072BABUD" => "72GB 15K SAS HP/Hitachi Ultrastar 15K300", # HUS153073VLS300
"DF146BABUE" => "146GB 15K SAS HP/Hitachi Ultrastar 15K300",
"DF300BABUF" => "300GB 15K SAS HP/Hitachi Ultrastar 15K300",
"DF072BAFDT" => "72GB 15K SAS HP",
"DF146BAFDU" => "146GB 15K SAS HP",
"DF300BAFDV" => "300GB 15K SAS HP",
"DF072BB6BC" => "72GB 15K SAS HP/Seagate 15K.5",
"DF146BB6C2" => "146GB 15K SAS HP/Seagate 15K.5", # ST3146855SS
"DF300BB6C3" => "300GB 15K SAS HP/Seagate 15K.5",
"DF0146B8052" => "146GB 15K SAS HP/Seagate 15K.6",
"DF0300B8053" => "300GB 15K SAS HP/Seagate 15K.6", # ST3300656SS
"DF0450B8054" => "450GB 15K SAS HP/Seagate 15K.6", # ST3450856SS
"DG072A4951" => "73GB 10K SAS 2.5\" HP/Hitachi Ultrastar C10K147", # HUC101473CSS300
"DG146A4960" => "147GB 10K SAS 2.5\" HP/Hitachi Ultrastar C10K147",
"DG072A3515" => "72GB 10K SAS 2.5\" HP/Seagate Savvio 10K.2 16MB", # ST973402SS
"DG146A3516" => "146GB 10K SAS 2.5\" HP/Seagate Savvio 10K.2 16MB",
"DG036A8B53" => "36GB 10K SAS 2.5\" HP/Seagate Savvio 8MB",
"DG072A8B54" => "72GB 10K SAS 2.5\" HP/Seagate Savvio 8MB", # ST973401SS
"DG036A8B5B" => "36GB 10K SAS 2.5\" HP/Fujitsu MAV", # MAV2036RC
"DG072A8B5C" => "72GB 10K SAS 2.5\" HP/Fujitsu MAV",
"DG036A9BB6" => "36GB 10K SAS 2.5\" HP/Fujitsu MAY",
"DG072A9BB7" => "72GB 10K SAS 2.5\" HP/Fujitsu MAY", # MAY2073RC
"DG072ABAB3" => "73GB 10K SAS 2.5\" HP/Seagate Savvio 10K.2 16MB", # ST973402SS
"DG146ABAB4" => "146GB 10K SAS 2.5\" HP/Seagate Savvio 10K.2 16MB",
"DG072BB975" => "73GB 10K SAS 2.5\" HP/Seagate Savvio 10K.2 16MB",
"DG146BB976" => "146GB 10K SAS 2.5\" HP/Seagate Savvio 10K.2 16MB", # ST9146802SS
"DH036ABAA5" => "36GB 15K SAS 2.5\" HP/Seagate Savvio 15K 16MB",
"DH072ABAA6" => "72GB 15K SAS 2.5\" HP/Seagate Savvio 15K 16MB", # ST973451SS
"DH036BB977" => "36GB 15K SAS 2.5\" HP/Seagate Savvio 15K 16MB",
"DH072BB978" => "72GB 15K SAS 2.5\" HP/Seagate Savvio 15K 16MB", # ST973451SS
# SATA
# FB drives are SATA/150, but these are definitely seagate 7200.10 drives SATA/300
"FB080C4080" => "80GB 7.2K SATA/150 HP/Seagate 7200.10", # ST380815AS
"FB160C4081" => "160GB 7.2K SATA/150 HP/Seagate 7200.10", # ST3160815AS
"FJ060C4980" => "60GB 5.4K SATA/150 HP",
"FJ120C4981" => "120GB 5.4K SATA/150 HP",
"GB0500C4413" => "500GB 7.2K SATA/300 HP/Seagate Barracude ES 16MB",
"GB0750C4414" => "750GB 7.2K SATA/300 HP/Seagate Barracuda ES 16MB", # ST3750640NS
# looks like GB can be mix of 1.5/3.0 sata
"GB0250C8045" => "250B 7.2K SATA/150 HP",
"GB0500C8046" => "500B 7.2K SATA/150 HP",
"GB0750C8047" => "750B 7.2K SATA/150 HP",
"GB0160CAABV" => "160GB 7.2K SATA/300 HP",
"GB0160EAFJE" => "160GB 7.2K SATA/300 HP",
"GB0250EAFJF" => "250GB 7.2K SATA/300 HP",
"GB0500EAFJH" => "500GB 7.2K SATA/300 HP",
"GB0750EAFJK" => "750GB 7.2K SATA/300 HP",
"GB1000EAFJL" => "1TB 7.2K SATA/300 HP",
# http://www.maxtor.com/portal/site/Maxtor/menuitem.2d55600ff3a2577ee77bd88591346068/?channelpath=/en_us/Support/Product%20Support/Enterprise%20Storage
"ATLAS-IV-9" => "9GB 7.2K U160 Quantum Atlas IV",
"ATLAS-IV-18" => "18GB 7.2K U160 Quantum Atlas IV",
"ATLAS-IV-36" => "36GB 7.2K U160 Quantum Atlas IV",
"ATLAS-V-9" => "9GB 7.2K U160 Quantum Atlas V",
"ATLAS-V-18" => "18GB 7.2K U160 Quantum Atlas V",
"ATLAS-V-36" => "36GB 7.2K U160 Quantum Atlas V",
"ATLASU320-18" => "18GB 10K U320 Maxtor Atlas ??",
"ATLASU320-36" => "36GB 10K U320 Maxtor Atlas ??",
"ATLAS10K2-TY092" => "9GB 10K U160 Maxtor Atlas 10K II",
"ATLAS10K2-TY184" => "18GB 10K U160 Maxtor Atlas 10K II",
"ATLAS10K2-TY367" => "36GB 10K U160 Maxtor Atlas 10K II",
"ATLAS10K2-TY734" => "73GB 10K U160 Maxtor Atlas 10K II",
"ATLAS10K3-18" => "18GB 10K U320 Maxtor Atlas 10K III",
"ATLAS10K3-36" => "36GB 10K U320 Maxtor Atlas 10K III",
"ATLAS10K3-73" => "73GB 10K U320 Maxtor Atlas 10K III",
"ATLAS10K4-36" => "36GB 10K U320 Maxtor Atlas 10K IV",
"ATLAS10K4-73" => "73GB 10K U320 Maxtor Atlas 10K IV",
"ATLAS10K5-73" => "73GB 10K U320 Maxtor Atlas 10K V",
"ATLAS10K5-146" => "146GB 10K U320 Maxtor Atlas 10K V",
"ATLAS10K5-300" => "300GB 10K U320 Maxtor Atlas 10K V",
# 16MB cache
"ATLAS10K5-073SAS" => "73GB 10K SAS Maxtor Atlas 10K V",
"ATLAS10K5-147SAS" => "147GB 10K SAS Maxtor Atlas 10K V",
"ATLAS10K5-300SAS" => "300GB 10K SAS Maxtor Atlas 10K V",
# http://www.seagate.com/staticfiles/maxtor/en_us/documentation/manuals/atlas_15k_product_manual.pdf
"ATLAS15K-18" => "18GB 15K U320 Maxtor Atlas 15K",
"ATLAS15K-36" => "36GB 15K U320 Maxtor Atlas 15K",
"ATLAS15K-73" => "73GB 15K U320 Maxtor Atlas 15K",
"ATLAS15K2-36" => "36GB 15K U320 Maxtor Atlas 15K II",
"ATLAS15K2-73" => "73GB 15K U320 Maxtor Atlas 15K II",
"ATLAS15K2-146" => "146GB 15K U320 Maxtor Atlas 15K II",
# http://www.maxtor.com/_files/maxtor/en_us/documentation/data_sheets/product_line_card.pdf
"QUANTUM-FIREBALLP-AS10" => "10GB 7.2K ATA/100 Fireball Plus AS",
"QUANTUM-FIREBALLP-AS20" => "20GB 7.2K ATA/100 Fireball Plus AS",
"QUANTUM-FIREBALLP-AS30" => "30GB 7.2K ATA/100 Fireball Plus AS",
"QUANTUM-FIREBALLP-AS40" => "40GB 7.2K ATA/100 Fireball Plus AS",
"QUANTUM-FIREBALLP-AS60" => "60GB 7.2K ATA/100 Fireball Plus AS",
"2F020J0" => "20GB 5.4K ATA/133 Quantum Fireball 3",
"2F020L0" => "20GB 5.4K ATA/133 Quantum Fireball 3",
"2F030J0" => "30GB 5.4K ATA/133 Quantum Fireball 3",
"2F030L0" => "30GB 5.4K ATA/133 Quantum Fireball 3",
"2F040J0" => "40GB 5.4K ATA/133 Quantum Fireball 3",
"2F040L0" => "40GB 5.4K ATA/133 Quantum Fireball 3",
"2B010H1" => "10GB 5.4K ATA/100 Maxtor Fireball 541DX 2MB",
"2B015H1" => "15GB 5.4K ATA/100 Maxtor Fireball 541DX 2MB",
"2B020H1" => "20GB 5.4K ATA/100 Maxtor Fireball 541DX 2MB",
"93073H4" => "30GB 7.2K ATA/100 Maxtor DiamondMax 60",
"98196H8" => "80GB 5.4K ATA/100 Maxtor DiamondMax 80",
"51024U2" => "10GB 7.2K ATA/66 Maxtor DiamondMax Plus 40",
"51369U3" => "13GB 7.2K ATA/66 Maxtor DiamondMax Plus 40",
"51536U3" => "15GB 7.2K ATA/66 Maxtor DiamondMax Plus 40",
"52049U4" => "20GB 7.2K ATA/66 Maxtor DiamondMax Plus 40",
"52732U6" => "27GB 7.2K ATA/66 Maxtor DiamondMax Plus 40",
"53073U6" => "30GB 7.2K ATA/66 Maxtor DiamondMax Plus 40",
"54098U8" => "40GB 7.2K ATA/66 Maxtor DiamondMax Plus 40",
"51024H2" => "10GB 7.2K ATA/100 Maxtor DiamondMax Plus 40",
"51369H3" => "13GB 7.2K ATA/100 Maxtor DiamondMax Plus 40",
"51536H3" => "15GB 7.2K ATA/100 Maxtor DiamondMax Plus 40",
"52049H4" => "20GB 7.2K ATA/100 Maxtor DiamondMax Plus 40",
"52732H6" => "27GB 7.2K ATA/100 Maxtor DiamondMax Plus 40",
"53073H6" => "30GB 7.2K ATA/100 Maxtor DiamondMax Plus 40",
"54098H8" => "40GB 7.2K ATA/100 Maxtor DiamondMax Plus 40",
"5T020H2" => "20GB 7.2K ATA/100 Maxtor DiamondMax Plus 60",
"5T030H3" => "30GB 7.2K ATA/100 Maxtor DiamondMax Plus 60",
"5T040H4" => "40GB 7.2K ATA/100 Maxtor DiamondMax Plus 60",
"6E020L0" => "20GB 7.2K ATA/133 Maxtor DiamondMax Plus 8",
"6E030L0" => "30GB 7.2K ATA/133 Maxtor DiamondMax Plus 8",
"6E040L0" => "40GB 7.2K ATA/133 Maxtor DiamondMax Plus 8",
"6K040L0" => "40GB 7.2K ATA/133 Maxtor DiamondMax Plus 8", # RoHS
"6N040T0" => "40GB 7.2K SATA/150 Maxtor DiamondMax 8S 2MB",
"6E040T0" => "40GB 7.2K SATA/150 Maxtor DiamondMax 8S 2MB",
"6Y060L0" => "60GB 7.2K ATA/133 Maxtor DiamondMax Plus 9 2MB",
"6Y080L0" => "80GB 7.2K ATA/133 Maxtor DiamondMax Plus 9 2MB",
"6Y120L0" => "120GB 7.2K ATA/133 Maxtor DiamondMax Plus 9 2MB",
"6Y160L0" => "160GB 7.2K ATA/133 Maxtor DiamondMax Plus 9 2MB",
"6Y060P0" => "60GB 7.2K ATA/133 Maxtor DiamondMax Plus 9 8MB",
"6Y080P0" => "80GB 7.2K ATA/133 Maxtor DiamondMax Plus 9 8MB",
"6Y120P0" => "120GB 7.2K ATA/133 Maxtor DiamondMax Plus 9 8MB",
"6Y160P0" => "160GB 7.2K ATA/133 Maxtor DiamondMax Plus 9 8MB",
"6Y200P0" => "200GB 7.2K ATA/133 Maxtor DiamondMax Plus 9 8MB",
"6Y250P0" => "250GB 7.2K ATA/133 Maxtor DiamondMax Plus 9 8MB",
"6Y060M0" => "60GB 7.2K SATA/150 Maxtor DiamondMax Plus 9 8MB",
"6Y080M0" => "80GB 7.2K SATA/150 Maxtor DiamondMax Plus 9 8MB",
"6Y120M0" => "120GB 7.2K SATA/150 Maxtor DiamondMax Plus 9 8MB",
"6Y160M0" => "160GB 7.2K SATA/150 Maxtor DiamondMax Plus 9 8MB",
"6Y200M0" => "200GB 7.2K SATA/150 Maxtor DiamondMax Plus 9 8MB",
"6Y250M0" => "250GB 7.2K SATA/150 Maxtor DiamondMax Plus 9 8MB",
# http://www.seagate.com/staticfiles/maxtor/en_us/documentation/data_sheets/diamondmax_10_data_sheet.pdf
"6L080L0" => "80GB 7.2K ATA/133 Maxtor DiamondMax 10 2MB",
"6B080P0" => "80GB 7.2K ATA/133 Maxtor DiamondMax 10 8MB",
"6L080P0" => "80GB 7.2K ATA/133 Maxtor DiamondMax 10 8MB",
"6B120P0" => "120GB 7.2K ATA/133 Maxtor DiamondMax 10 8MB",
"6L120P0" => "120GB 7.2K ATA/133 Maxtor DiamondMax 10 8MB",
"6B160P0" => "160GB 7.2K ATA/133 Maxtor DiamondMax 10 8MB",
"6L160P0" => "160GB 7.2K ATA/133 Maxtor DiamondMax 10 8MB",
"6B200P0" => "200GB 7.2K ATA/133 Maxtor DiamondMax 10 8MB",
"6L200P0" => "200GB 7.2K ATA/133 Maxtor DiamondMax 10 8MB",
"6B200R0" => "200GB 7.2K ATA/133 Maxtor DiamondMax 10 16MB",
"6L200R0" => "200GB 7.2K ATA/133 Maxtor DiamondMax 10 16MB",
"6B250R0" => "250GB 7.2K ATA/133 Maxtor DiamondMax 10 16MB",
"6L250R0" => "250GB 7.2K ATA/133 Maxtor DiamondMax 10 16MB",
"6B300R0" => "300GB 7.2K ATA/133 Maxtor DiamondMax 10 16MB",
"6L300R0" => "300GB 7.2K ATA/133 Maxtor DiamondMax 10 16MB",
"6B080M0" => "80GB 7.2K SATA/150 Maxtor DiamondMax 10 8MB",
"6L080M0" => "80GB 7.2K SATA/150 Maxtor DiamondMax 10 8MB",
"6B120M0" => "120GB 7.2K SATA/150 Maxtor DiamondMax 10 8MB",
"6L120M0" => "120GB 7.2K SATA/150 Maxtor DiamondMax 10 8MB",
"6B160M0" => "160GB 7.2K SATA/150 Maxtor DiamondMax 10 8MB",
"6L160M0" => "160GB 7.2K SATA/150 Maxtor DiamondMax 10 8MB",
"6B200M0" => "200GB 7.2K SATA/150 Maxtor DiamondMax 10 8MB",
"6L200M0" => "200GB 7.2K SATA/150 Maxtor DiamondMax 10 8MB",
"6B200S0" => "200GB 7.2K SATA/150 Maxtor DiamondMax 10 16MB",
"6L200S0" => "200GB 7.2K SATA/150 Maxtor DiamondMax 10 16MB",
"6B250S0" => "250GB 7.2K SATA/150 Maxtor DiamondMax 10 16MB",
"6L250S0" => "250GB 7.2K SATA/150 Maxtor DiamondMax 10 16MB",
"6B300S0" => "300GB 7.2K SATA/150 Maxtor DiamondMax 10 16MB",
"6L300S0" => "300GB 7.2K SATA/150 Maxtor DiamondMax 10 16MB",
"6V080E0" => "80GB 7.2K SATA/300 Maxtor DiamondMax 10 8MB",
"6V160E0" => "160GB 7.2K SATA/300 Maxtor DiamondMax 10 8MB",
"6V200E0" => "200GB 7.2K SATA/300 Maxtor DiamondMax 10 8MB",
"6V250F0" => "250GB 7.2K SATA/300 Maxtor DiamondMax 10 16MB",
"6V300F0" => "300GB 7.2K SATA/300 Maxtor DiamondMax 10 16MB",
"6V320F0" => "320GB 7.2K SATA/300 Maxtor DiamondMax 10 16MB",
"6H400R0" => "400GB 7.2K ATA/133 Maxtor DiamondMax 11 16MB",
"6H500R0" => "500GB 7.2K ATA/133 Maxtor DiamondMax 11 16MB",
"6H400F0" => "400GB 7.2K SATA/300 Maxtor DiamondMax 11 16MB",
"6H500F0" => "500GB 7.2K SATA/300 Maxtor DiamondMax 11 16MB",
"STM3802110A" => "80GB 7.2K ATA/100 Maxtor DiamondMax 20 2MB",
"STM340211AS" => "40GB 7.2K SATA/300 Maxtor DiamondMax 20 2MB",
"STM380211AS" => "80GB 7.2K SATA/300 Maxtor DiamondMax 20 2MB",
"STM380811AS" => "80GB 7.2K SATA/300 Maxtor DiamondMax 20 8MB",
"STM380811" => "80GB 7.2K SATA/300 Maxtor DiamondMax 20 8MB",
"STM3160211AS" => "160GB 7.2K SATA/300 Maxtor DiamondMax 20 2MB",
"STM3250820AS" => "250GB 7.2K SATA/300 Maxtor DiamondMax 21 8MB",
"STM3320820AS" => "250GB 7.2K SATA/300 Maxtor DiamondMax 21 8MB",
"STM340215AS" => "40GB 7.2K SATA/300 Maxtor DiamondMax 21 2MB",
"STM380215AS" => "80GB 7.2K SATA/300 Maxtor DiamondMax 21 2MB",
"STM3160215AS" => "160GB 7.2K SATA/300 Maxtor DiamondMax 21 2MB",
"7H500R0" => "500GB 7.2K ATA/133 Maxtor MaXLine Pro 500 16MB",
"7H500F0" => "500GB 7.2K SATA/300 Maxtor MaXLine Pro 500 16MB",
"4W100H6" => "100GB 5.4K ATA/100 Maxtor DiamondMax 536DX",
"4D020H1" => "20GB 5.4K ATA/100 Maxtor DiamondMax D540X",
"4D040H2" => "40GB 5.4K ATA/100 Maxtor DiamondMax D540X",
"4D060H3" => "60GB 5.4K ATA/100 Maxtor DiamondMax D540X",
"4D080H4" => "80GB 5.4K ATA/100 Maxtor DiamondMax D540X",
"4K020H1" => "20GB 5.4K ATA/100 Maxtor DiamondMax D540X",
"4K040H2" => "40GB 5.4K ATA/100 Maxtor DiamondMax D540X",
"4K060H3" => "60GB 5.4K ATA/100 Maxtor DiamondMax D540X",
"4K080H4" => "80GB 5.4K ATA/100 Maxtor DiamondMax D540X",
"4G120J6" => "120GB 5.4K ATA/133 Maxtor DiamondMax D540X",
"4G160J8" => "160GB 5.4K ATA/133 Maxtor DiamondMax D540X",
"4R060L0" => "60GB 5.4K ATA/133 Maxtor DiamondMax 16",
"4R060J0" => "60GB 5.4K ATA/133 Maxtor DiamondMax 16",
"4R080L0" => "80GB 5.4K ATA/133 Maxtor DiamondMax 16",
"4R080J0" => "80GB 5.4K ATA/133 Maxtor DiamondMax 16",
"4R120L0" => "120GB 5.4K ATA/133 Maxtor DiamondMax 16",
"4R160L0" => "160GB 5.4K ATA/133 Maxtor DiamondMax 16",
"4A160J0" => "160GB 5.4K ATA/133 Maxtor DiamondMax 16",
"4A250J0" => "250GB 5.4K ATA/133 Maxtor DiamondMax 16",
"4A300J0" => "300GB 5.4K ATA/133 Maxtor DiamondMax 16",
"6G080E0" => "80GB 7.2K SATA/300 Maxtor DiamondMax 17 8MB",
"6G160E0" => "160GB 7.2K SATA/300 Maxtor DiamondMax 17 8MB",
"6G250E0" => "250GB 7.2K SATA/300 Maxtor DiamondMax 17 8MB",
"6G320E0" => "320GB 7.2K SATA/300 Maxtor DiamondMax 17 8MB",
"6L020J1" => "20GB 7.2K ATA/133 Maxtor DiamondMax Plus D740X",
"6L040J2" => "40GB 7.2K ATA/133 Maxtor DiamondMax Plus D740X",
"6L060J3" => "60GB 7.2K ATA/133 Maxtor DiamondMax Plus D740X",
"6L080J4" => "80GB 7.2K ATA/133 Maxtor DiamondMax Plus D740X",
"6L020L1" => "20GB 7.2K ATA/133 Maxtor DiamondMax Plus D740X",
"6L040L2" => "40GB 7.2K ATA/133 Maxtor DiamondMax Plus D740X",
"6L060L3" => "60GB 7.2K ATA/133 Maxtor DiamondMax Plus D740X",
"6L080L4" => "80GB 7.2K ATA/133 Maxtor DiamondMax Plus D740X",
"5A250J0" => "250GB 5.4K ATA/133 Maxtor MaXLine II 2MB",
"5A300J0" => "300GB 5.4K ATA/133 Maxtor MaXLine II 2MB",
"5A320J0" => "320GB 5.4K ATA/133 Maxtor MaXLine II 2MB",
"7Y250P0" => "250GB 7.2K ATA/133 Maxtor MaXLine Plus II 8MB",
"7Y250M0" => "250GB 7.2K SATA/150 Maxtor MaXLine Plus II 8MB",
"7L250R0" => "250GB 7.2K ATA/133 Maxtor MaXLine III 16MB",
"7L300R0" => "300GB 7.2K ATA/133 Maxtor MaXLine III 16MB",
"7L250S0" => "250GB 7.2K SATA/150 Maxtor MaXLine III 16MB",
"7L300S0" => "300GB 7.2K SATA/150 Maxtor MaXLine III 16MB",
"7V250F0" => "250GB 7.2K SATA/300 Maxtor MaXLine III 16MB",
"7V300F0" => "300GB 7.2K SATA/300 Maxtor MaXLine III 16MB",
# SSD
"MTRON-MSP-SATA3025-032" => "32GB SSD SATA/150 2.5\" Mtron SSD MOBI 3000",
"MTRON-MSP-SATA3035-032" => "32GB SSD SATA/150 Mtron SSD MOBI 3000",
"MTRON-MSP-SATA7025-032" => "32GB SSD SATA/150 2.5\" Mtron SSD Pro 7000",
"MTRON-MSP-SATA7035-032" => "32GB SSD SATA/150 Mtron SSD Pro 7000",
"MTRON-MSP-SATA7525-032" => "32GB SSD SATA/300 2.5\" Mtron SSD Pro 7500",
"MTRON-MSP-SATA7535-032" => "32GB SSD SATA/300 Mtron SSD Pro 7500",
"SanDisk-SSD-SATA-5000-2.5" => "32GB SSD SATA/150 2.5\" SanDisk SSD 5000",
);
my(@system_models) = (
{
"model" => "AOpen i965GMt-LA",
"ids" => [
"0x063ea0a0,0x816810ec,0x02", # Network
"0x063ea0a0,0x28288086,0x03", # SATA
],
"sockets" => 1,
"socket-type" => "Intel-mPGA478 - Socket P",
"dimms" => 2,
"memory-type" => "DDR2-667 non-ECC Unbuffered",
"memory-form" => "200pin SO-DIMM DDR2",
"max-memory" => "4G",
},
{
"model" => "MSI GM965",
"ugly-model" => "MSI MS-9803",
"ids" => [
"0x80301462,0x109a8086,0x00", # Network
"0x80301462,0x282[89]8086,0x03", # SATA
],
"sockets" => 1,
"socket-type" => "Intel-mPGA478 - Socket P",
"dimms" => 2,
"memory-type" => "DDR2-667 non-ECC Unbuffered",
"memory-form" => "240pin DDR2",
"max-memory" => "4G",
},
{
"model" => "Intel X38ML",
"ids" => [
"0x34ce8086,0x10a78086,0x02", # Network
"0x34d08086,0x292[02]8086,0x02", # SATA
],
"sockets" => 1,
"socket-type" => "Intel-LGA775",
"dimms" => 4,
"memory-type" => "DDR2-800 ECC Unbuffered",
"max-memory" => "8G",
},
{
"model" => "Intel D945GCLF",
"ids" => [
"0x00018086,0x813610ec,0x02", # Network
"0x464c8086,0x27c08086,0x01", # SATA
],
"sockets" => 1,
"dimms" => 1,
"memory-type" => "DDR2-667 ECC Unbuffered",
"max-memory" => "2G",
},
{
"model" => "Quanta SU2-3000",
"ids" => [
"0x00000000,0x02111166,0x00", # ATA
"0x8917152d,0x12298086,0x08", # Network
"0x8917152d,0x008f9005,0x02", # SCSI
],
"sockets" => 2,
},
{
"model" => "Gateway SU2-4200",
"ids" => [
"0x8920107b,0x02131166,0xa0", # ATA
"0x(892d152d|01341028),0x100e8086,0x02", # Network
],
"sockets" => 2,
},
{
"model" => "Quanta SU2-4200",
"ids" => [
"0x02201166,0x02131166,0xa0", # ATA
"0x892d152d,0x100e8086,0x02", # Network
],
"sockets" => 2,
},
{
"model" => "Asus P5Q-Deluxe",
"ids" => [
"0x811a1043,0x432011ab,0x14", # Network
"0x81f81043,0x436411ab,0x12", # Network
"0x82d41043,0x3a228086,0x00", # SATA
],
"sockets" => 1,
"socket-type" => "Intel-LGA775",
"dimms" => 4,
"memory-type" => "DDR2-1200 non-ECC Unbuffered",
"max-memory" => "16G",
},
{
"model" => "Asus P5BV-C",
"ids" => [
"0x819e1043,0x27df8086,0x01", # ATA
"0x81901043,0x27c[013]8086,0x01", # SATA
"0x826e1043,0x436411ab,0x12", # Network
],
"sockets" => 1,
"socket-type" => "Intel-LGA775",
"dimms" => 4,
"memory-type" => "DDR2-800 ECC Unbuffered",
"max-memory" => "8G",
},
{
"model" => "Gigabyte 945GCM-S2C",
"ids" => [
"0xe0001458,0x813610ec,0x01", # Network
"0xb0021458,0x27c08086,0x01", # SATA
],
"sockets" => 1,
"socket-type" => "Intel-LGA775",
"dimms" => 2,
"memory-type" => "DDR2-667 non-ECC Unbuffered",
"max-memory" => "4G",
},
{
"model" => "Gigabyte G33M-S2L", # needs to come before Gigabyte P35-S3G
"ids" => [
"0xd0001458,0x29c28086,0x02", # VGA
"0xb0051458,0x29238086,0x02", # SATA
"0xe0001458,0x816810ec,0x01", # Network
],
"sockets" => 1,
"socket-type" => "Intel-LGA775",
"dimms" => 4,
"memory-type" => "DDR2-1066 non-ECC Unbuffered",
"max-memory" => "8G",
},
{
"model" => "Gigabyte P35-S3G",
"ids" => [
"0xb0051458,0x29238086,0x02", # SATA
"0xe0001458,0x816810ec,0x01", # Network
],
"sockets" => 1,
"socket-type" => "Intel-LGA775",
"dimms" => 4,
"memory-type" => "DDR2-1066 non-ECC Unbuffered",
"max-memory" => "8G",
},
{
"model" => "Gigabyte EP45-DS3R",
"ids" => [
"(0xb0051458,0x3a228086,0x00|0xb0021458,0x3a208086,0x00)", # SATA
"0xe0001458,0x816810ec,0x02", # Network
],
"sockets" => 1,
"socket-type" => "Intel-LGA775",
"dimms" => 4,
"memory-type" => "DDR2-1200 non-ECC Unbuffered",
"max-memory" => "16G",
},
{
"model" => "Gigabyte GA-7A8DRH",
"ids" => [
"0xb0101458,0x80[19]d9005,0x10", # SCSI
"0x30001458,0x10268086,0x04", # Network
"0x10761458,0x10768086,0x00", # Network
],
"sockets" => 2,
},
{
"model" => "MSI 8480000",
"ids" => [
"0x24501462,0x164814e4,0x03", # Network
"0x7469(1462|1022),0x74691022,0x03", # ATA
],
"dimms" => 8,
"memory-type" => "DDR-333 ECC Registered",
"max-memory" => "16G",
"sockets" => 2,
"socket-type" => "AMD-Socket 940",
},
{
"model" => "Tyan S5397",
"ids" => [
"0x10001000,0x00581000,0x04", # SAS
"0x00008086,0x10968086,0x01", # Network
"0x539710f1,0x268[012]08086,0x09", # SATA
],
"dimms" => 16,
"memory-type" => "DDR2-800 ECC Fully Buffered",
"max-memory" => "128G",
"sockets" => 2,
"socket-type" => "Intel-LGA771",
'url' => 'http://www.tyan.com/product_board_detail.aspx?pid=560',
},
{
"model" => "Tyan S5376",
"ids" => [
"0x521110f1,0x108b8086,0x03", # Network
"0x537610f1,0x292[02]8086,0x02", # SATA
],
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Registered",
"max-memory" => "48G",
"max-ranks" => 12,
"sockets" => 2,
},
{
"model" => "Intel SRSH4",
"ids" => [
"0x34128086,0x12298086,0x0d", # Network
"0x34128086,0x100d8086,0x02", # Network
"0x34128086,0x801f9005,0x03", # SCSI
],
"sockets" => 4,
},
{
"model" => "Tyan S4881",
"ids" => [
"0x289110f1,0x005310de,0xf2", # ATA
"0x164814e4,0x164814e4,0x03", # Network
],
"sockets" => 4,
},
{
"model" => "Tyan S4882",
"ids" => [
"0x(2b80|36c0)1022,0x74691022,0x03", # ATA
"0x10001000,0x00301000,0x07", # MPT
"0x164[48]14e4,0x164814e4,0x03", # Network
],
"sockets" => 4,
},
{
"model" => "Tyan S2880",
"ids" => [
"0x6619105a,0x3373105a,0x02", # SATA
"0x164414e4,0x164814e4,0x(03|10)", # Network
],
"sockets" => 2,
},
{
"model" => "Tyan S2882", # Must come before Tyan S2881
"ids" => [
"0x74691022,0x74691022,0x03", # ATA
"0x164414e4,0x164814e4,0x(03|10)", # Network
"0x10408086,0x12298086,0x10", # Network
],
"sockets" => 2,
},
{
"model" => "Tyan S2881",
"ids" => [
"0x74691022,0x74691022,0x03", # ATA
"0x164414e4,0x164814e4,0x(03|10)", # Network
],
"sockets" => 2,
},
{
"model" => "Tyan S2865",
"ids" => [
"0x286510f1,0x005710de,0xa3",
],
"sockets" => 1,
},
{
"model" => "Tyan S2722",
"ids" => [
"0x10408086,0x12298086,0x10", # Network
"0x10018086,0x100f8086,0x01", # Network
"0x00000000,0x248b8086,0x02", # ATA
],
"sockets" => 2,
},
{
"model" => "Tyan S2510",
"ids" => [
"0x000c8086,0x12298086,0x08", # Network
"0x00000000,0x02111166,0x00", # ATA
"0x10001000,0x00201000,0x01", # SCSI
],
"sockets" => 2,
"socket-type" => "Intel-PGA370",
"dimms" => 4,
"memory-type" => "PC133 SDRAM ECC Registered",
"max-memory" => "4G",
},
{
"model" => "Dell GX620",
"ids" => [
"0x01ad1028,0x27df8086,0x01", # ATA
"0x01ad1028,0x27c[013]8086,0x01", # SATA
"0x01ad1028,0x167714e4,0x01", # Network
],
"sockets" => 1,
},
{
"model" => "Dell GX280",
"ids" => [
"0x01791028,0x266f8086,0x03", # ATA
"0x01791028,0x26518086,0x03", # SATA
"0x01791028,0x167714e4,0x01", # Network
],
"sockets" => 1,
},
{
"model" => "Dell Precision 360",
"ids" => [
"0x01561028,0x24d18086,0x02", # SATA
"0x01561028,0x24db8086,0x02", # ATA
],
"sockets" => 1,
"dimms" => 4,
"memory-type" => "DDR-400 ECC Unbuffered",
"max-memory" => "4G",
},
{
"model" => "Dell SX260",
"ids" => [
"0x01381028,0x24cb8086,0x01", # SATA
"0x01381028,0x100e8086,0x02", # Network
],
"sockets" => 1,
},
{
"model" => "Dell GX270",
"ids" => [
"0x01511028,0x24d18086,0x02", # SATA
"0x01511028,0x24db8086,0x02", # ATA
],
"sockets" => 1,
},
{
"model" => "Dell 530",
"ids" => [
"0x00d81028,0x244b8086,0x04", # ATA
"0x00d81028,0x920010b7,0x78", # Network
],
"sockets" => 1,
},
{
"model" => "Dell GX240",
"ids" => [
"0x010e1028,0x244b8086,0x12", # ATA
"0x00fe1028,0x920010b7,0x78", # Network
],
"sockets" => 1,
},
{
"model" => "HP DX2255",
"ids" => [
"0x3024103c,0x05711106,0x80", # ATA
"0x3024103c,0x813910ec,0x10", # Network
],
"sockets" => 1,
"dimms" => 2,
"memory-type" => "DDR2-667 non-ECC Unbuffered",
"max-memory" => "2G",
},
{
"model" => "HP DX2180",
"ids" => [
"0x301e103c,0x26518086,0x04", # SATA
"0x301e103c,0x813910ec,0x10", # Network
],
"sockets" => 1,
},
{
"model" => "HP D290",
"ids" => [
"0x301f103c,0x26518086,0x04", # SATA
],
"sockets" => 1,
},
{
"model" => "HP DX2280",
"ids" => [
"0x3022103c,0x27c[013]8086,0x01", # SATA
"0x3022103c,0x(8167|8169)10ec,0x10", # Network
],
"sockets" => 1,
},
{
"model" => "HP DX5150",
"ids" => [
"0x3009103c,0x43791002,0x00", # SATA
"0x3009103c,0x167714e4,0x20", # Network
],
"sockets" => 1,
},
{
"model" => "HP DC5800",
"ids" => [
"0x281e103c,0x10bd8086,0x02", # Network
],
"sockets" => 1,
"dimms" => 4,
"memory-type" => "DDR2-800 non-ECC Unbuffered",
"max-memory" => "8G",
},
{
"model" => "HP DC7600",
"ids" => [
"0x3011103c,0x160014e4,0x01", # Network
"0x3011103c,0x27c[013]8086,0x01", # SATA
],
"sockets" => 1,
},
{
"model" => "HP D510",
"ids" => [
"0x00b[89]0e11,0x24cb8086,0x01", # ATA
"0x00120e11,0x103b8086,0x81", # Network
],
"sockets" => 1,
},
{
"model" => "HP D530", # must come before HP DC5000
"ids" => [
"0x12bc103c,0x24d18086,0x02", # SATA
"0x12bc103c,0x24db8086,0x02", # ATA
"0x12bc103c,0x169614e4,0x03", # Network
],
"sockets" => 1,
},
{
"model" => "HP DC5000",
"ids" => [
"0x12bc103c,0x24db8086,0x02", # ATA
"0x12bc103c,0x169614e4,0x03", # Network
],
"sockets" => 1,
},
{
"model" => "HP DX6120",
"ids" => [
"0x300a103c,0x266f8086,0x03", # ATA
"0x300a103c,0x26518086,0x03", # SATA
"0x3005103c,0x167714e4,0x01", # Network
],
"sockets" => 1,
},
{
"model" => "HP DC7100",
"ids" => [
"0x3005103c,0x26518086,0x03", # SATA
"0x3005103c,0x167714e4,0x01", # Network
],
"sockets" => 1,
},
{
# http://h18000.www1.hp.com/products/quickspecs/12145_ca/12145_ca.pdf
"model" => "HP DC5100",
"ids" => [
"0x300[cd]103c,0x26518086,0x03", # SATA
"0x300[56]103c,0x167714e4,0x01", # Network
],
"sockets" => 1,
},
{
"model" => "HP DC5700",
"ids" => [
"0x2808103c,0x28208086,0x02", # SATA
"0x2808103c,0x28258086,0x02", # SATA
"0x2808103c,0x167b14e4,0x02", # Network
],
"sockets" => 1,
},
{
"model" => "Quanta QSSC-295MB",
"ids" => [
"0x00008086,0x10bd8086,0x02", # Network
"0x8954152d,0x292[02]8086,0x02", # SATA
"0x8954152d,0x29268086,0x02", # SATA
],
"sockets" => 2,
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Registered",
"max-memory" => "48G",
"max-ranks" => 12,
},
{
"model" => "eSlim SU4-1320", # Quanta S47 board
"ugly-model" => "Quanta S47",
"ids" => [
"0x8959152d,0x167814e4,0xa3", # Network
"0x8959152d,0x292[02]8086,0x02", # SATA
],
"dimms" => 4,
"memory-type" => "DDR2-800 ECC Unbuffered",
"max-memory" => "8G",
"sockets" => 1,
},
{
"model" => "Quanta S45",
"ids" => [
"(0x00008086,0x10bd8086,0x02|0x00008086,0x108b8086,0x03)", # Network
"0x8954152d,0x292[02]8086,0x02", # SATA
],
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Registered",
"max-memory" => "48G",
"max-ranks" => 12,
"sockets" => 2,
},
{
"model" => "Dell DCS S45",
"ids" => [
"(0x00008086,0x10bd8086,0x02|0x00008086,0x108b8086,0x03)", # Network
"0x2[89]2[02]8086,0x2[89]2[02]8086,0x02", # SATA
],
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Registered",
"max-memory" => "48G",
"max-ranks" => 12,
"sockets" => 2,
},
{
"model" => "Dell DCS S29S-SAS",
"ugly-model" => "Dell (F1CH|DCS Platform)",
"ids" => [
"0x80868086,0x25d48086,0xb1", # Chipset
"0x894b152d,0x00561000,0x02", # SAS
"0x8949152d,0x10968086,0x01", # Network
],
"sockets" => 2,
},
{
"model" => "Dell DCS S29S",
"ugly-model" => "Dell (F1CH|DCS Platform)",
"ids" => [
"0x80868086,0x25d48086,0xb1", # Chipset
"0x8949152d,0x268[012]8086,0x09", # SATA
"0x8949152d,0x10968086,0x01", # Network
],
"sockets" => 2,
},
{
"model" => "Dell DCS S29R",
"ugly-model" => "Dell BlackfordESB2",
"ids" => [
"0x8949152d,0x25d48086,0xb1", # Chipset
"0x8949152d,0x268[012]8086,0x09", # SATA
"0x8949152d,0x10968086,0x01", # Network
],
"sockets" => 2,
},
{
"model" => "Dell DCS S58R-SAS", # must come before Dell DCS S58R
"ugly-model" => "(Intel|Dell) BlackfordESB2",
"ids" => [
"0x894b152d,0x25d88086,0xb1", # Chipset
"0x894b152d,0x00561000,0x02", # SAS
"0x8949152d,0x10968086,0x01", # Network
],
"sockets" => 2,
},
{
"model" => "Dell DCS S58R",
"ugly-model" => "(Intel|Dell) BlackfordESB2",
"ids" => [
"0x894b152d,0x25d88086,0xb1", # Chipset
"0x894b152d,0x268[012]8086,0x09", # SATA
"0x8949152d,0x10968086,0x01", # Network
],
"sockets" => 2,
},
{
"model" => "Dell DCS S58S-SAS", # must come before Dell DCS S58S
"ugly-model" => "Quanta S58A?",
"ids" => [
"0x80868086,0x25d88086,0xb1", # Chipset
"0x894b152d,0x00561000,0x02", # SAS
"0x8949152d,0x10968086,0x01", # Network
],
"sockets" => 2,
},
{
"model" => "Dell DCS S58S",
"ugly-model" => "Quanta S58A?",
"ids" => [
"0x80868086,0x25d88086,0xb1", # Chipset
"0x(894b|8950)152d,0x268[012]8086,0x09", # SATA
"0x8949152d,0x10968086,0x01", # Network
],
"sockets" => 2,
},
{
"model" => "Inventec 5220",
"ids" => [
"0x003a1170,0x10968086,0x01", # Network
"0x003a1170,0x268[012]8086,0x09", # SATA
],
"dimms" => 8,
"memory-type" => "DDR2 ECC Fully Buffered",
"max-memory" => "32G",
"sockets" => 2,
},
{
"model" => "Inventec Seabream",
"ids" => [
"0x00231170,0x(268[012]|269e)8086,0x09", # ATA/SATA
"0x00231170,0x10968086,0x01", # Network
],
"sockets" => 2,
"ymodel-type" => "J",
},
{
"model" => "Inventec IR1250",
"ids" => [
"0x00221170,0x27df8086,0x01", # ATA
"0x00221170,0x165914e4,0x11", # Network
],
"sockets" => 1,
},
{
"model" => "Inventec IR2100",
"ids" => [
"0x000c1170,0x47521002,0x27", # VGA
"0x165914e4,0x165914e4,0x11", # Network
],
"sockets" => 2,
},
{
"model" => "Inventec IR2300",
"ugly-model" => "Inventec Tuna",
"ids" => [
"0x00161170,0x005310de,0xa2", # ATA
"0x165914e4,0x165914e4,0x11", # Network
],
"sockets" => 2,
},
{
"model" => "Inventec IR2350",
"ids" => [
"0x00171170,0x005310de,0xa2", # ATA
"0x165914e4,0x165914e4,0x11", # Network
],
"sockets" => 2,
},
{
"model" => "Inventec IR2400",
"ids" => [
"0x00261170,0x037f10de,0xa3",
"0x00261170,0x037310de,0xa3",
],
"sockets" => 2, # Socket F
},
{
"model" => "Supermicro X8DTN",
"ids" => [
"0x10a715d9,0x10a78086,0x02", # Network
"0x2[89]2[02]8086,0x2[89]2[02]8086,0x02", # SATA
"0x515e1002,0x515e1002,0x02", # VGA
],
"sockets" => 2,
"dimms" => 18,
"memory-type" => "DDR3",
},
{
"model" => "Supermicro X5DP8",
"ids" => [
"0x348015d9,0x248b8086,0x02", # ATA
"0x005e9005,0x801d9005,0x10", # SCSI
"0x10118086,0x10108086,0x01", # Network
],
"sockets" => 2,
"dimms" => 8,
"memory-type" => "DDR-266 ECC Registered",
"max-memory" => "16G",
},
{
"model" => "Supermicro P4DP6",
"ids" => [
"0x348015d9,0x248b8086,0x02", # ATA
"0x900515d9,0x00cf9005,0x01", # SCSI
"0x10508086,0x12298086,0x0d", # Network
],
"sockets" => 2,
},
{
"model" => "Supermicro PDSBM",
"ids" => [
"0xb58015d9,0x27c[013]8086,0x01", # SATA
"0x109a15d9,0x109a8086,0x00", # Network
],
"sockets" => 1,
"dimms" => 2,
"memory-type" => "DDR2-667 non-ECC Unbuffered",
"max-memory" => "4G",
},
{
"model" => "Supermicro X7SBL",
"ids" => [
"0x109a15d9,0x109a8086,0x00", # Network
"0xd88015d9,0x292[02]8086,0x02", # SATA
],
"sockets" => 1,
"dimms" => 4,
"memory-type" => "DDR2-800 ECC Registered",
"max-memory" => "8G",
"sata-ports" => 6,
"form-factor" => "Micro ATX",
},
{
"model" => "Supermicro X7DBP",
"ids" => [
"0x838015d9,0x269e8086,0x09", # ATA
"0x(0000|1096)15d9,0x10968086,0x01", # Network
],
"sockets" => 2,
"socket-type" => "Intel-LGA771",
"dimms" => 8,
"memory-type" => "DDR2-667 ECC Fully Buffered",
"max-memory" => "32G",
"sata-ports" => 6,
"lan-ports" => 2,
"serial-ports" => 2,
"PCI-X" => 2,
"PCI-E x8" => 2,
"form-factor" => "41.25cm x 28.52cm",
},
{
"model" => "Supermicro X7DCA-L",
"ids" => [
"0x109a15d9,0x109a8086,0x00", # Network
"0xdc8015d9,0x292[02]8086,0x02", # SATA
],
"sockets" => 2,
"socket-type" => "Intel-LGA771",
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Registered",
"max-memory" => "48G",
"sata-ports" => 6,
"form-factor" => "Micro ATX",
},
{
"model" => "Supermicro X7DCL-3", # needs to come before X7DCL-i
"ids" => [
"0xa48015d9,0x005[89]1000,0x08", # SAS
"0xa48015d9,0x292[02]8086,0x02", # SATA
"0x108c15d9,0x108c8086,0x03", # Netwwork
],
"sockets" => 2,
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Registered",
"max-memory" => "32G",
},
{
"model" => "Supermicro X7DCL-i",
"ugly-model" => '^Supermicro X7DCL$',
"ids" => [
"0xa48015d9,0x292[02]8086,0x02", # SATA
"0x108c15d9,0x108c8086,0x03", # Netwwork
],
"sockets" => 2,
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Registered",
"max-memory" => "32G",
},
{
"model" => "Supermicro X7DAL",
"ids" => [
"0x948015d9,0x25c08086,0x13", # Chipset
"0x(0000|1096)15d9,0x10968086,0x01", # Network
"0x948015d9,0x268[012]8086,0x09", # SATA
],
"sockets" => 2,
},
{
"model" => "Supermicro B7DBE",
"ids" => [
"0xb08015d9,0x268[012]8086,0x09", # SATA IDE|AHCI|RAID
],
"sockets" => 2,
},
{
"model" => "Supermicro X7DBU",
"ids" => [
# have some showing up as 0x868015d9,0x26818086,0x09, e.g. fe35.yosup.re1.yahoo.com
# looks like mistake, so ignore for now
"0x978[01]15d9,0x268[012]8086,0x09", # SATA IDE|AHCI|RAID
"0x(0000|1096)15d9,0x10968086,0x01", # Network
],
"sockets" => 2,
},
{
"model" => "Supermicro X7DVL-L",
"ids" => [
"0xb28015d9,0x25d48086,0xb1", # Chipset
"0x(0000|1096)15d9,0x10968086,0x01", # Network
"0xb28015d9,0x268[012]8086,0x09", # SATA IDE|AHCI|RAID
"0xb28015d9,0x002018ca,0x00", # VGA
],
"sockets" => 2,
"dimms" => 4,
"memory-type" => "DDR2-667 ECC Fully Buffered",
"max-memory" => "16G",
"sata-ports" => 4,
},
{
"model" => "Supermicro X7DVL-E",
"ids" => [
"0x868015d9,0x25d48086,0xb1", # Chipset
"0x(0000|1096)15d9,0x10968086,0x01", # Network
"0x868015d9,0x268[012]8086,0x09", # SATA IDE|AHCI|RAID
"0x868015d9,0x515e1002,0x02", # VGA
],
"sockets" => 2,
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Fully Buffered",
"max-memory" => "16G",
"sata-ports" => 6,
},
{
"model" => "Supermicro X7DBR-3 SAS",
"ids" => [
"0x928015d9,0x25d88086,0xb1", # Chipset
"0x(0000|1096)15d9,0x10968086,0x01", # Network
"0x928015d9,0x041e9005,0x09", # SAS
],
"sockets" => 2,
},
{
"model" => "Supermicro X7DBR-3 SATA",
"ids" => [
"0x928015d9,0x25d88086,0xb1", # Chipset
"0x(0000|1096)15d9,0x10968086,0x01", # Network
"0x928015d9,0x268[012]8086,0x09", # SATA
],
"sockets" => 2,
},
{
"model" => "Supermicro X7DBi+",
"ids" => [
"0xb18015d9,0x269e8086,0x09", # ATA
],
"sockets" => 2,
"dimms" => 16,
"memory-type" => "DDR2-667 ECC Fully Buffered",
"max-memory" => "64G",
"sata-ports" => 6,
},
{
"model" => "Supermicro X7DBR",
"ids" => [
"0x848015d9,0x268[012]8086,0x09", # SATA
],
"sockets" => 2,
"dimms" => 16,
"memory-type" => "DDR2-667 ECC Fully Buffered",
},
{
"model" => "Supermicro X7DB8",
"ids" => [
"0x808015d9,0x25d88086,0x92", # Chipset
"0x808015d9,0x269b8086,0x09", # SMBus
"0x(0000|1096)15d9,0x10968086,0x01", # Network
"0x808015d9,0x268[012]8086,0x09", # SATA
],
"sockets" => 2,
},
{
"model" => "Supermicro X7DB8",
"ids" => [
"0x808015d9,0x25d88086,0xb1", # Chipset
"0x808015d9,0x269b8086,0x09", # SMBus
"0x(0000|1096)15d9,0x10968086,0x01", # Network
"0x808015d9,0x269e8086,0x09", # ATA
],
"sockets" => 2,
},
{
"model" => "IBM dx340",
"ids" => [
"0x03251014,0x268[012]8086,0x09", # SATA
"0x82171043,0x10968086,0x01", # Network
],
"sockets" => 2,
},
{
"model" => "IBM x3850 M2",
"ids" => [
"0x03811014,0x27df8086,0x01", # ATA
"0x037c1014,0x163914e4,0x01", # Network
"0x03661014,0x00621000,0x03", # SAS
],
"sockets" => 4,
"dimms" => 32,
"memory-type" => "DDR2-533 ECC Registered",
"max-memory" => "256G",
"chipset" => "IBM X4",
},
{
"model" => "IBM x3550",
"ids" => [
"0x02dd1014,0x268[012]8086,0x09", # SATA
"0x03421014,0x164c14e4,0x11", # Network
],
"sockets" => 2,
},
{
"model" => "IBM eServer 306m",
"ids" => [
"0x02fd1014,0x27c[013]8086,0x01", # SATA
"0x02c61014,0x165914e4,0x11", # Network
],
"sockets" => 1,
},
{
"model" => "Sun Fire X2100",
"ids" => [
"0x5348108e,0x005410de,0xf3",
"0x5348108e,0x005710de,0xa3",
],
"sockets" => 1,
},
{
"model" => "Sun Fire V20z",
"ids" => [
"0x001017c2,0x74691022,0x03", # ATA
"0x001017c2,0x16..14e4,0x0.", # Network
"0x001017c2,0x00301000,0x0.", # SCSI, revs 0x07, 0x08
],
"sockets" => 2,
},
{
"model" => "Sun Fire V40z",
"ids" => [
"0x002017c2,0x74691022,0x03", # ATA
"0x002017c2,0x16a714e4,0x02", # Network
"0x002017c2,0x00301000,0x0.", # SCSI, revs 0x07, 0x08
],
"sockets" => 4,
},
{
"model" => "Asus K8N-DRE",
"ids" => [
"0x81491043,0x165914e4,0x.1", # revs 0x11, 0x21
"0x81621043,0x005510de,0xf3",
],
"sockets" => 2,
},
{
"model" => "Arima HDAMA-I SATA", # before HDAMA-I
"ids" => [
"0x164814e4,0x164814e4,0x10",
"0x3016161f,0x74691022,0x03",
"0x61141095,0x31141095,0x02",
],
"sockets" => 2,
},
{
"model" => "Arima HDAMA-I",
"ids" => [
"0x164814e4,0x164814e4,0x10",
"0x3016161f,0x74691022,0x03",
],
"sockets" => 2,
},
{
"model" => "Arima HDAMA SATA", # before HDAMA
"ids" => [
"0x000c14e4,0x16a614e4,0x02",
"0x3016161f,0x74691022,0x03",
"0x61141095,0x31141095,0x02",
],
"sockets" => 2,
},
{
"model" => "Arima HDAMA", # before HDAMA
"ids" => [
"0x000c14e4,0x16a614e4,0x02",
"0x3016161f,0x74691022,0x03",
],
"sockets" => 2,
},
{
"model" => "Dell PE1550",
"ugly-model" => "Dell Cleared System/1000",
"ids" => [
"0x00da1028,0x12298086,0x08", # Network
],
"sockets" => 2,
},
{
"model" => "Dell PE2550",
"ids" => [
"0x00d11028,0x164414e4,0x(10|12)", # Network
],
"sockets" => 2,
},
{
"model" => "Dell PE2450",
"ids" => [
"0x009b1028,0x12298086,0x08", # Network
"0x00a61028,0x00cf9005,0x01", # SCSI
],
"sockets" => 2,
},
{
"model" => "Dell PE1650",
"ids" => [
"0x810b1028,0x02121166,0x93",
],
"sockets" => 2,
},
{
"model" => "Dell PE2650",
"ids" => [
"0x01211028,0x164514e4,0x15", # network
],
"sockets" => 2,
},
{
"model" => "Dell PE2650",
"ids" => [
"0x01211028,0x16a714e4,0x02", # network
],
"sockets" => 2,
},
{
"model" => "Dell PE750",
"ids" => [
"0x01651028,0x25a38086,0x02",
],
"sockets" => 1,
},
{
"model" => "Dell PE1750",
"ids" => [
"0x014a1028,0x02121166,0x93",
],
"sockets" => 2,
},
{
"model" => "Dell SC1435",
"ids" => [
"0x01eb1028,0x024b1166,0x00",
],
"sockets" => 2,
"ymodel-type" => "J",
},
{
"model" => "Dell R200",
"ids" => [
"0x023c1028,0x165914e4,0x21", # network
],
"sockets" => 1,
"dimms" => 4,
"memory-type" => "DDR2-800 ECC Unbuffered",
"max-memory" => "8G",
},
{
"model" => "Dell R300",
"ids" => [
"0x020f1028,0x165a14e4,0x00", # network
],
"sockets" => 1,
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Unbuffered",
"max-memory" => "24G",
},
{
"model" => "Dell PE860",
"ids" => [
"0x01e61028,0x27788086,0x00",
],
"sockets" => 1,
},
{
"model" => "Dell PE850",
"ids" => [
"0x01b61028,0x27788086,0x00",
],
"sockets" => 1,
"ymodel-type" => "F",
},
{
"model" => "Dell PE1850",
"ids" => [
"0x016c1028,0x51591002,0x00", # VGA
],
"sockets" => 2,
},
{
"model" => "Dell PE1955",
"ids" => [
"0x01bb1028,0x16ac14e4,0x12", # Network
"0x1f081028,0x00541000,0x01", # SAS
],
"sockets" => 2,
},
{
"model" => "Dell PE1855",
"ids" => [
"0x018a1028,0x51591002,0x00", # VGA
],
"sockets" => 2,
},
{
"model" => "Dell PE2850",
"ids" => [
"0x016d1028,0x51591002,0x00", # VGA
],
"sockets" => 2,
},
{
"model" => "Dell PE6850",
"ids" => [
"0x01701028,0x164814e4,0x10", # Network
],
"sockets" => 4,
},
{
"model" => "Dell R900",
"ids" => [
"0x80868086,0x36008086,0x..", # Chipset
"0x01f01028,0x164c14e4,0x12", # Network
],
"sockets" => 4,
},
{
"model" => "Dell PE6950",
"ids" => [
"0x01ea1028,0x02141166,0x00",
"0x01ea1028,0x164c14e4,0x12", # Network
],
"sockets" => 4,
},
{
"model" => "Dell PE1950 III",
"ugly-model" => "Dell PowerEdge 1950",
"ids" => [
"0x1f101028,0x00581000,0x08", # SAS
"0x01b31028,0x164c14e4,0x1.", # Network - revs 0x11, 0x12
],
"sockets" => 2,
},
{
"model" => "Dell PE1950",
"ids" => [
"0x01b31028,0x164c14e4,0x1.", # Network - revs 0x11, 0x12
],
"sockets" => 2,
},
{
"model" => "Dell PE2970",
"ids" => [
"0x02051028,0x164c14e4,0x1.",
"0x02051028,0x024b1166,0x00",
],
"sockets" => 2,
},
{
"model" => "Dell PE2950",
"ids" => [
"0x01b21028,0x164c14e4,0x1.", # Network - revs 0x11, 0x12
],
"sockets" => 2,
"ymodel-type" => "M",
},
{
"model" => "Dell 1600SC",
"ids" => [
"0x01351028,0x100e8086,0x02", # Network
"0x41351028,0x02121166,0x93", # ATA
],
"sockets" => 2,
},
{
"model" => "Dell SC1425",
"ids" => [
"0x019a1028,0x51591002,0x00", # VGA
],
"sockets" => 2,
},
{
"model" => "HP DL365 G1",
"ids" => [
"0x7038103c,0x164c14e4,0x1.", # network
"0x320b103c,0x02141166,0x00", # ata
],
"model-match" => "DL365",
"sockets" => 2,
},
{
"model" => "HP DL385 G2",
"ids" => [
"0x7038103c,0x164c14e4,0x1.", # network
"0x320b103c,0x02141166,0x00", # ata
],
"model-match" => "DL385",
"sockets" => 2,
},
{
"model" => "HP DL365 G1/DL385 G2",
"ids" => [
"0x7038103c,0x164c14e4,0x1.", # network
"0x320b103c,0x02141166,0x00", # ata
],
"sockets" => 2,
},
{
"model" => "HP BL480c G1", # needs to go before DL380 G5
"ids" => [
"0x703b103c,0x16ac14e4,0x12", # Network
"0x703c103c,0x167914e4,0xa3", # Network
"0x31fd103c,0x25d88086,0x(93|b1)", # chipset
],
"sockets" => 2,
"dimms" => 12,
"memory-type" => "DDR2 ECC Fully Buffered",
"max-memory" => "48G",
},
{
"model" => "HP DL120 G5",
"ids" => [
"0x........,0x29f08086,0x..", # Chipset
"0x31f4103c,0x292[02]8086,0x02", # SATA
"0x7051103c,0x165a14e4,0x00", # Network
],
"sockets" => 1,
"dimms" => 4,
},
{
"model" => "HP DL160 G5",
"ids" => [
"0x........,0x40038086,0x..", # Chipset
"0x7051103c,0x165a14e4,0x00", # Network
# SAS version hides the following:
# "0x31fe103c,0x269e8086,0x09", # ATA
# "0x31f6103c,0x268[012]8086,0x09", # SATA
],
"sockets" => 2,
"dimms" => 8,
"memory-type" => "DDR2-800 ECC Fully Buffered",
"max-memory" => "64G",
},
{
"model" => "HP DL180 G5", # must come before HP SE1101
"ugly-model" => "HP ProLiant ML150 G5",
"ids" => [
"0x........,0x65c08086,0x80", # Chipset
"0x7051103c,0x165a14e4,0x00", # Network
"0x00000000,0x65e38086,0x80", # PCI - needed to distinguish from HP SE1101
],
"sockets" => 2,
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Registered",
"max-memory" => "32G",
"max-ranks" => 8,
},
{
"model" => "HP SE1101",
"ids" => [
"0x........,0x65c08086,0x80", # Chipset
"0x7051103c,0x165a14e4,0x00", # Network
],
"sockets" => 2,
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Registered",
"max-memory" => "32G",
"max-ranks" => 8,
},
{
"model" => "HP SB600c", # needs to go before DL380 G5
"ids" => [
"0x31fd103c,0x25d88086,0x(93|b1)", # chipset
"0x000000(00|40),0x26908086,0x09",
"0x3211103c,0x3238103c,0x00", # CISS
"0x703b103c,0x16ac14e4,0x12", # Network
],
"sockets" => 2,
"dimms" => 8,
"memory-type" => "DDR2 ECC Fully Buffered",
"max-memory" => "32G",
},
{
"model" => "HP BL260c G5",
"ids" => [
"0x703c103c,0x167914e4,0xa3", # Network
"0x31fe103c,0x292[02]8086,0x02", # SATA
],
"sockets" => 2,
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Registered",
"max-memory" => "16G",
},
{
"model" => "HP DL380 G5", # needs to go before DL360 G5
"ids" => [
"0x31fd103c,0x25d88086,0x(93|b1)", # chipset
"0x000000(00|40),0x26908086,0x09",
],
"sockets" => 2,
},
{
"model" => "HP BL460c G1", # needs to go before DL360 G5
"ids" => [
"0x703b103c,0x16ac14e4,0x12", # Network
"0x31fd103c,0x25d88086,0x(93|b1)", # chipset
],
"sockets" => 2,
"dimms" => 8,
"memory-type" => "DDR2 ECC Fully Buffered",
"max-memory" => "32G",
},
{
"model" => "HP DL360 G5",
"ids" => [
"0x31fd103c,0x25d88086,0x(93|b1)",
],
"sockets" => 2,
},
{
"model" => "HP DL380 G4",
"ids" => [
"0x32010e11,0x24db8086,0x02",
],
"sockets" => 2,
},
{
"model" => "HP DL360 G4p",
"ids" => [
"0x32000e11,0x35908086,0x0c",
"0x32010e11,0x25a28086,0x02",
],
"model-match" => "G4p",
"sockets" => 2,
},
{
"model" => "HP DL360 G4",
"ids" => [
"0x32000e11,0x35908086,0x0c",
"0x32010e11,0x25a28086,0x02",
],
"model-match" => "G4",
"sockets" => 2,
},
{
"model" => "HP DL360 G4/G4p", # only diff is 4 vs. 6 dimms
"ids" => [
"0x32000e11,0x35908086,0x0c",
"0x32010e11,0x25a28086,0x02",
],
"sockets" => 2,
},
{
"model" => "HP DL360 G4",
"ids" => [
"0x32000e11,0x35908086,0x0a",
"0x32010e11,0x25a28086,0x02",
],
"sockets" => 2,
},
{
"model" => "Intel S7000FC4UR",
"ugly-model" => "Intel MP",
"ids" => [
"0x34cc8086,0x515e1002,0x02", # VGA
"0x34cc8086,0x268[012]8086,0x09", # SATA
],
"sockets" => 4,
"dimms" => 32,
"memory-type" => "DDR2-667 ECC Fully Buffered",
"max-memory" => "256G",
},
{
"model" => "HP DL580 G5",
"ids" => [
"0x31f2103c,0x36008086,0x01", # Chipset
"0x31fe103c,0x269e8086,0x09", # ATA
"0x7038103c,0x164c14e4,0x1.", # Network
],
"sockets" => 4,
},
{
"model" => "HP DL580 G4",
"ids" => [
"0x3201103c,0x24db8086,0x02", # ATA
"0x1709103c,0x164a14e4,0x02", # Network
],
"sockets" => 4,
},
{
"model" => "Compaq ML530 G2", # needs to come before DL580 G2
"ids" => [
"0x00000000,0x00111166,0x22", # Chipset
"0xa2fe0e11,0xa0f70e11,0x14", # PCI
"0xf6200e11,0x00c09005,0x01", # SCSI
"0xb1340e11,0x12298086,0x08", # Network
],
"sockets" => 2,
},
{
"model" => "Compaq DL580 G2",
"ids" => [
"0x00000000,0x00111166,0x22", # Chipset
"0xa2fe0e11,0xa0f70e11,0x14", # PCI
],
"sockets" => 4,
},
{
"model" => "Compaq ML570", # needs to go before DL380 G2
"ids" => [
"0xa2f90e11,0xa0f70e11,0x12", # PCI
"0xb1430e11,0x000a1000,0x02", # SCSI
],
"sockets" => 4,
},
{
"model" => "Compaq ML370 G2", # identical to 380g2
"ids" => [
"0xa2f90e11,0xa0f70e11,0x12", # PCI
],
"model-match" => "ML370",
"sockets" => 2,
},
{
"model" => "Compaq DL380 G2",
"ids" => [
"0xa2f90e11,0xa0f70e11,0x12", # PCI
],
"sockets" => 2,
},
{
"model" => "HP DL180", # needs to go before DL360 G3
"ids" => [
"0x00cb0e11,0x16a714e4,0x02", # Network
"0x31fe103c,0x269e8086,0x09", # ATA
"0x31f6103c,0x268[012]8086,0x09", # SATA
],
"sockets" => 2,
},
{
"model" => "HP DL380 G3", # needs to go before DL360 G3
"ids" => [
"0x00cb0e11,0x16a714e4,0x02", # Network
"0xa2fe0e11,0xa0f70e11,0x14", # PCI
],
"sockets" => 2,
},
{
"model" => "HP DL560 G1", # identical to 360g3
"ids" => [
"0x00cb0e11,0x16a714e4,0x02", # Network
"0x40800e11,0xb1780e11,0x01", # ciss
],
"model-match" => "DL560",
"sockets" => 4,
},
{
"model" => "HP DL360 G3", # identical to 560g1
"ids" => [
"0x00cb0e11,0x16a714e4,0x02", # Network
"0x40800e11,0xb1780e11,0x01", # ciss
],
"sockets" => 2,
},
{
"model" => "Compaq DL360 G2",
"ids" => [
"0x00850e11,0x164514e4,0x15", # Network
],
"sockets" => 2,
},
{
"model" => "HP DL320 G5", # could also be a HP DL320s
"ids" => [
"0x31fe103c,0x27df8086,0x01", # ATA
"0x7039103c,0x166814e4,0xa3", # Network
],
"sockets" => 1,
"dimms" => 4,
"memory-type" => "DDR2-667 ECC Unbuffered",
"max-memory" => "8G",
},
{
"model" => "HP DL320 G3",
"ids" => [
"0x32000e11,0x25888086,0x05",
"0x32010e11,0x26528086,0x03",
],
"sockets" => 1,
},
{
"model" => "HP DL320 G2",
"ids" => [
"0x00bb0e11,0x16a614e4,0x02",
],
"sockets" => 1,
},
{
"model" => "Compaq DL360",
"ids" => [
"0xb1340e11,0x12298086,0x08", # Network
"0x....0e11,0x00..1000,0x02", # SCSI
"0xb0f30e11,0xa0f00e11,0x00", # Advanced System Management Controller
],
"sockets" => 2,
},
{
"model" => "Compaq DL320",
"ids" => [
"0xb1340e11,0x12298086,0x08", # Network
"0x00000000,0x02111166,0x00", # ATA
"0x001e0e11,0x47521002,0x27", # VGA
],
"sockets" => 1,
},
{
"model" => "HP DL140 G2",
"ids" => [
"0x3208103c,0x24d[1b]8086,0x02", # SATA/ATA
"0x1659....,0x165914e4,0x11", # Network
],
"sockets" => 2,
},
{
"model" => "HP DL140 G3",
"ids" => [
"0x25c08086,0x25c08086,0x..", # Chipset
"0x31fe103c,0x269b8086,0x09", # SMBus
"0x3260103c,0x165914e4,0x11", # Network
],
"sockets" => 2,
},
{
"model" => "HP DL145 G3",
"ids" => [
"0x703e103c,0x167814e4,0xa3", # Network
"0x320b103c,0x02141166,0x00", # ATA
],
"sockets" => 2,
},
{
"model" => "HP DL185 G5",
"ids" => [
"0x320b103c,0x02141166,0x00", # SATA
"0x310f103c,0x164814e4,0x10", # Network
],
"sockets" => 2,
"dimms" => 8,
"memory-type" => "DDR2-667 ECC Registered",
"max-memory" => "32G",
"max-ranks" => 8,
},
{
"model" => "HP DL145 G2",
"ids" => [
"0x3209103c,0x165914e4,0x11",
],
"sockets" => 2,
},
{
"model" => "HP DL145 G1",
"ids" => [
"0x36c01022,0x74691022,0x03", # ATA
],
"sockets" => 2,
},
{
"model" => "HP DL585 G2",
"ids" => [
"0x1709103c,0x164a14e4,0x02",
"0x31f8103c,0x005310de,0xa3",
],
"sockets" => 4,
},
{
"model" => "HP DL585 G1",
"ids" => [
"0x32040e11,0x74691022,0x03",
"0x40800e11,0xb1780e11,0x01", # ciss
],
"sockets" => 4,
},
{
"model" => "HP DL385 G1",
"ids" => [
"0x32040e11,0x74691022,0x03",
"0x40910e11,0x00460e11,0x01",
],
"sockets" => 2,
},
{
"model" => "HP DL140",
"ids" => [
"0x001e0e11,0x47521002,0x27",
"0x164814e4,0x164814e4,0x02",
],
"sockets" => 2,
},
{
"model" => "Supermicro PDSMi",
"ids" => [
"0x109a15d9,0x109a8086,0x00", # Network
"0x798015d9,0x27c[013]8086,0x01", # SATA
],
"sockets" => 1,
},
{
"model" => "Supermicro PDSML",
"ids" => [
"0x109a15d9,0x109a8086,0x00", # Network
"0x858015d9,0x27c[013]8086,0x01", # SATA
],
"sockets" => 1,
"dimms" => 4,
"memory-type" => "DDR2-667 ECC Unbuffered",
"max-memory" => "8G",
},
{
"model" => "Supermicro X6DLP",
"ids" => [
"0x109a15d9,0x109a8086,0x00", # Network
"0x108c15d9,0x108c8086,0x03",
"0x698015d9,0x25a38086,0x02",
],
"sockets" => 2,
},
{
"model" => "Supermicro X7DCT",
"ids" => [
"0x108c15d9,0x108c8086,0x03", # Netwwork
"0xde8015d9,0x515e1002,0x02", # VGA
],
"sockets" => 2,
"socket-type" => "Intel-LGA771",
"dimms" => 6,
"memory-type" => "DDR2-667 ECC Registered",
"max-memory" => "48G",
"sata-ports" => 4,
"lan-ports" => 2,
"serial-ports" => 1,
"PCI-e x16" => 1,
"form-factor" => "41.66cm x 16.51cm",
},
{
"model" => "Intel S3000PT",
"ids" => [
"0x349[ab]8086,0x27c[013]8086,0x01", # SATA
"0x349b8086,0x108b8086,0x03",
],
"sockets" => 1,
},
{
"model" => "Intel S5000PAL",
"ids" => [
"0x346[cd]8086,0x25d88086,0xb1",
],
"sockets" => 2,
},
{
"model" => "Intel S5400SF",
"ids" => [
"0x34d48086,0x268[012]8086,0x09", # SATA
"0x34d48086,0x10968086,0x01", # Network
],
"sockets" => 2,
"dimms" => 16,
"memory-type" => "DDR2-667 ECC Fully Buffered",
"max-memory" => "64G",
},
{
"model" => "Intel S5000XSL",
"ids" => [
"0x347a8086,0x268[012]8086,0x09", # SATA
],
"sockets" => 2,
},
{
"model" => "Intel S5000VSA",
"ids" => [
"0x34848086,0x10968086,0x01", # Network
],
"sockets" => 2,
},
{
"model" => "Intel S5000PSL",
"ids" => [
"0x34768086,0x25d88086,0x(92|b1)",
],
"sockets" => 2,
},
{
"model" => "Intel S5000PSL-SAS",
"ids" => [
"0x34788086,0x25d88086,0xb1",
],
"sockets" => 2,
},
{ # with scsi
"model" => "Intel SE7520JR2S", # needs to go before SE7520JR2
"ids" => [
"0x10798086,0x10798086,0x03",
"0x34358086,0x00301000,0x08",
],
"sockets" => 2,
},
{
"model" => "Intel SE7520JR2",
"ids" => [
"0x10798086,0x10798086,0x03",
],
"sockets" => 2,
},
{
"model" => "Intel SE7520BB2",
"ugly-model" => "Intel SE7520BB2..?",
"ids" => [
"0x347e8086,0x10768086,0x05", # Network
],
"sockets" => 2,
"ymodel-type" => "J",
},
{ # with scsi
"model" => "Intel SE7520BD2S", # needs to go before SE7520BD2
"ids" => [
"0x34398086,0x10768086,0x05", # Network
"0x34628086,0x00301000,0xc1",
],
"sockets" => 2,
},
{ # with sata
"model" => "Intel SE7520BD2D", # needs to go before SE7520BD2
"ids" => [
"0x34398086,0x10768086,0x05", # Network
"0x34398086,0x24d18086,0x02",
],
"sockets" => 2,
},
{
"model" => "Intel SE7520BD2",
"ids" => [
"0x34398086,0x10768086,0x05", # Network
],
"sockets" => 2,
},
{
"model" => "Intel SE7320VP2",
"ids" => [
"0x34448086,0x10768086,0x05", # Network
],
"sockets" => 2,
},
{
"model" => "Intel SE7320VP2", # 2nd version of SE7320VP2
"ids" => [
"0x34508086,0x10768086,0x05", # Network
],
"sockets" => 2,
},
{
"model" => "Intel SE7500WV2", # scsi version of SE7500WV2A
"ids" => [
"0x34158086,0x25408086,0x03",
],
"sockets" => 2,
},
{
"model" => "Intel SE7500WV2A",
"ids" => [
"0x34168086,0x25408086,0x03",
],
"sockets" => 2,
},
{ # with scsi
"model" => "Intel SE7501WV2S", # needs to go before SE7501WV2
"ids" => [
"0x341a8086,0x254c8086,0x01",
"0x341a8086,0x801f9005,0x03",
],
"sockets" => 2,
},
{ # we had some SE7501WV2S without scsi ids
"model" => "Intel SE7501WV2",
"ids" => [
"0x341a8086,0x254c8086,0x01",
],
"sockets" => 2,
},
{
"model" => "Intel SE7501WV2A",
"ids" => [
"0x341b8086,0x254c8086,0x01",
],
"sockets" => 2,
},
{
"model" => "Intel SE7501CW2",
"ids" => [
"0x34258086,0x248b8086,0x02",
],
"sockets" => 2,
},
{
"model" => "Intel SE7500CW2",
"ids" => [
"0x34198086,0x248b8086,0x02",
],
"sockets" => 2,
},
{
"model" => "Intel SE7501BR2",
"ids" => [
"0x34188086,0x254c8086,0x01",
],
"sockets" => 2,
},
{
"model" => "Intel S875WP1",
"ids" => [
"0x34288086,0x24d18086,0x02",
],
"sockets" => 1,
},
{
"model" => "Intel CA810E",
"ids" => [
"0x43328086,0x71258086,0x03",
],
"sockets" => 1,
},
{
"model" => "Intel TR440BX",
"ids" => [
"0x71908086,0x71928086,0x03", # Chipset
"0x30008086,0x12298086,0x08", # Network
"0x00000000,0x71118086,0x01", # ATA
],
"sockets" => 1,
},
{
"model" => "Intel L440GX+",
"ids" => [
"0x00000000,0x71a08086,0x00",
"0x(00539004|080f9005|ffff9005),0x005f9005,0x00",
"0x00bc1013,0x00bc1013,0x23",
],
"sockets" => 2,
},
{
"model" => "Intel N440BX",
"ids" => [
"0x00000000,0x71928086,0x..",
"0x........,0x000f1000,0x37",
"0x00088086,0x12298086,0x05",
"0x00000000,0x71118086,0x01",
"0x........,0x00bc1013,0x23",
],
"sockets" => 2,
},
{
"model" => "Intel S845WD1",
"ids" => [
"0x57448086,0x244b8086,0x05",
],
"sockets" => 1,
},
{
"model" => "Intel SCB20-S", # SCSI version
"ids" => [
"0x340f8086,0x12298086,0x0d",
"0x340f8086,0x02121166,0x92",
],
"sockets" => 2,
},
{
"model" => "Intel SCB20-A",
"ids" => [
"0x34108086,0x12298086,0x0d",
"0x34108086,0x02121166,0x92",
],
"sockets" => 2,
},
{
"model" => "Dell PE6650",
"ids" => [
"0x01091028,0x164414e4,0x14", # network
],
"sockets" => 4,
},
{
"model" => "Compaq 6400R",
"ids" => [
"0xb0dd0e11,0x12298086,0x05", # network
],
"sockets" => 4,
},
# Laptops
{
"model" => "Dell Latitude D610",
"ids" => [
"0x01821028,0x26538086,0x03", # SATA
"0x01821028,0x167714e4,0x01", # Network
"0x27228086,0x42208086,0x05", # Wireless
],
"sockets" => 1,
"dimms" => 2,
"memory-type" => "DDR2-533 non-ECC Unbuffered",
"max-memory" => "2G",
},
{
"model" => "HP NC6220",
"ids" => [
"0x0944103c,0x266f8086,0x03", # ATA
"0x0944103c,0x167d14e4,0x11", # Network
"0x12f6103c,0x42208086,0x05", # Wireless
],
"sockets" => 1,
"dimms" => 2,
"memory-type" => "DDR2-533 non-ECC Unbuffered",
"max-memory" => "2G",
},
{
"model" => "HP NC6400",
"ids" => [
"0x30ad103c,0x27df8086,0x01", # ATA
"0x30ad103c,0x16fd14e4,0x21", # Network
"0x135[bc]103c,0x42228086,0x02", # Wireless
],
"sockets" => 1,
"dimms" => 2,
"memory-type" => "DDR2-667 non-ECC Unbuffered",
"max-memory" => "4G",
},
);
my(%hostid_synonyms);
my(%hostid_to_pci);
my(%hostid_to_driver);
my(%linux_driver_map) = (
"lsi" => "mpt",
"3w" => "twe",
);
sub sig_warn {
my($err) = @_;
$err = "$zero: perl-warn: $err";
$perl_warn .= $err;
warn $err;
}
sub sig_die {
my($err) = @_;
$err = "$zero: perl-die: $err";
$perl_warn .= $err;
email('', '');
die $err;
}
$SIG{'__WARN__'} = 'sig_warn';
$SIG{'__DIE__'} = 'sig_die';
sub watchdog {
die "watchdog expired; something is taking too long";
}
sub usage {
print "usage:\t$zero [-dhnv] [-o output-file]\n";
print "\t-d show debugging information\n";
print "\t-h show usage\n";
print "\t-n don't break output lines\n";
print "\t-v show version\n";
print "\t-o write output to a file\n";
}
sub round {
my($number) = @_;
return int($number + 0.5);
}
sub cmp_devs {
my($aa, $bb) = ($a, $b);
$aa = $hostid_to_pci{$aa} if ($hostid_to_pci{$aa});
$bb = $hostid_to_pci{$bb} if ($hostid_to_pci{$bb});
my($atype, $anum) = ($aa =~ /^(.*?)(\d*)$/);
my($btype, $bnum) = ($bb =~ /^(.*?)(\d*)$/);
return ($atype cmp $btype || $anum <=> $bnum);
}
sub parse_enable {
my($string, $more_yes, $more_no) = @_;
my($yes) = "yes|on|enabled|1";
my($no) = "no|off|disabled|0";
$yes .= "|$more_yes" if $more_yes;
$no .= "|$more_no" if $more_no;
if ($string =~ /^($yes)$/i) {
return 1;
} elsif ($string =~ /^($no)$/i) {
return 0;
} else {
return;
}
}
sub parse_value {
my($string) = @_;
if ($string =~ /^(\d+)/) {
return $1;
}
return $string;
}
sub parse_bytes {
my($string, $factor) = @_;
my($result) = 0;
my(%exp) = (
"K" => 1,
"KB" => 1,
"M" => 2,
"MB" => 2,
"G" => 3,
"GB" => 3,
"T" => 4,
"TB" => 4,
);
if ($string =~ /^\s*([\d\.]+)\s*(K|KB|M|MB|G|GB|T|TB)\s*$/i) {
$result = $1 * (($factor || 1000) ** $exp{uc($2)});
}
}
sub parse_rpm {
my($string) = @_;
my($result) = "";
my(@rpms) = (4500, 5400, 7200, 10000, 15000);
my($low) = 0;
my($high);
foreach $high (@rpms) {
if ($string <= $high) {
if ($high < 10000) {
$result = sprintf("%3.1fK", $high / 1000);
} else {
$result = sprintf("%2dK", $high / 1000);
}
last;
}
}
return $result;
}
sub parse_volume_status {
my($string) = @_;
my($result);
if ($string =~ /^(OK|Optimal)$/i) {
$result = "ok";
} elsif ($string =~ /^(Degraded)$/i) {
$result = "degraded";
} elsif ($string =~ /^(Failed|INTERM RECOVERY|Interim Recovery Mode|BROKEN)$/i) {
$result = "failed";
} else {
$result = $string;
}
return $result;
}
sub parse_drive_status {
my($string) = @_;
my($result);
if ($string =~ /^(OK|Ready)/i) {
$result = "ok";
} elsif ($string =~ /^(Online)/i) {
$result = "online";
} elsif ($string =~ /^(Offline)/i) {
$result = "offline";
} elsif ($string =~ /^(Failed)/i) {
$result = "failed";
} elsif ($string =~ /^(Rebuild)/i) {
$result = "rebuilding";
} else {
$result = $string;
}
return $result;
}
sub parse_drive_interface {
my($string) = @_;
my($result) = $string;
if ($string =~ /Parallel SCSI/) {
$result = "SCSI";
} elsif ($string =~ /SAS/) {
$result = "SAS";
}
return $result;
}
sub parse_drive_speed {
my($string) = @_;
my($result) = "";
if ($string =~ /320/) {
$result = "U320";
} elsif ($string =~ /SATA 1\.5 Gb\/s/) {
$result = "SATA-150";
} elsif ($string =~ /SATA 3\.0 Gb\/s/) {
$result = "SATA-300";
}
return $result;
}
sub canon_raid {
my($raid) = @_;
return unless (defined $raid);
$raid =~ s/RAID 6 \(ADG\)/RAID ADG/;
$raid =~ s/volume//i;
$raid =~ s/[^a-z0-9]+$//i; # nuke garbage from the end
$raid =~ s/raid\s+raid/raid/ig;
$raid =~ s/SINGLE/JBOD/i;
$raid =~ s/RAID Simple/JBOD/i;
$raid =~ s/^\s+//;
$raid =~ s/\s+$//;
$raid =~ s/\-/ /g;
$raid =~ s/raid(.+)/RAID $1/i;
# /proc/driver/cciss/cciss0
$raid =~ s/1\(1\+0/10/;
$raid =~ s/1\(0\+1/10/;
# hpacucli
$raid =~ s/1\+0/10/;
$raid =~ s/0\+1/10/;
# aac
$raid =~ s/0\/1/10/;
$raid =~ s/\s+/-/g;
return $raid;
}
sub canon_cpu_vendor {
my($vendor) = @_;
if ($vendor =~ /Intel|Pentium|Xeon|Celeron/i) {
$vendor = 'Intel';
} elsif ($vendor =~ /AMD/i) {
$vendor = 'AMD';
} elsif ($vendor =~ /^I/i) {
$vendor = 'Intel';
}
return $vendor;
}
sub canon_drive {
my($model) = @_;
$model =~ s/^\s+//;
$model =~ s/\s+$//;
$model =~ s/[\W_]+/-/ig;
$model =~ s/^\-+//;
$model =~ s/\-+$//;
return $model;
}
sub canon_memory {
my($model) = @_;
if ($model =~ /^0x/ || (length($model) > 18 && $model =~ /^[0-9a-z]+$/i)) {
$model =~ s/^0x0*//;
$model =~ s/(..)/sprintf("%c", hex($1))/ge;
}
$model =~ s/\s+/ /g;
$model =~ s/^\s+//;
$model =~ s/\s+$//;
return $model;
}
sub clean_white {
my($string) = @_;
$string =~ s/\s+/ /g;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
sub clean_pci_model {
my($model) = @_;
$model =~ s/\(was:.*\)//i; # freebsd
$model =~ s/\(rev .*\)$//; # linux
$model =~ s/PCI Express/PCI-E/i;
$model =~ s/(Gigabit) Ethernet( Controller( \(Copper\))?)?/$1/i;
$model =~ s/(Gigabit) Network Connection/$1/i;
$model =~ s/\b(Corporation|Corp\.?|Inc|Co\.|Ltd\.|Technologies Inc|Technology Group Ltd\.|Semiconductor Co\.\,)//ig;
$model =~ s/\s+(Controller|Adapter)$//i;
return clean_white($model);
}
sub print_bytes {
my($number, $factor, $int, $round_limit) = @_;
my(@suffix) = ('', 'K', 'M', 'G', 'T', 'P', 'E');
my($i) = 0;
$factor = 1000 unless $factor;
$round_limit = 10 unless $round_limit;
# keep going until we're below 1000, otherwise can end up with 1020MB
# given that we round to one decimal, 1001/1024 will round to 1.0, i.e. we avoid 0.98 type results
while ($number >= 1000) {
$number = $number / $factor;
$i++;
}
my($result);
if ($number >= $round_limit) {
$result = sprintf("%.0f%sB", $number, $suffix[$i]);
} elsif ($number) {
$result = sprintf("%3.1f%sB", $number, $suffix[$i]);
$result =~ s/\.0// if ($int);
} else {
$result = sprintf("0B");
}
return $result;
}
sub cpuid {
my($vendor, $cpuid) = @_;
$vendor = canon_cpu_vendor($vendor);
my($family, $model, $stepping, $ext_model, $ext_family);
$stepping = $cpuid & 0xf;
$model = ($cpuid >> 4) & 0xf;
$family = ($cpuid >> 8) & 0xf;
$ext_model = ($cpuid >> 16) & 0xf;
$ext_family = ($cpuid >> 20) & 0xff;
$family += $ext_family;
$model += ($ext_model << 4);
return "$vendor-$family,$model,$stepping";
}
sub init_dmesg {
my($in) = 'DMESG';
my($line);
if (-r $dmesg_file) {
open($in, "< $dmesg_file") || warn("open: $dmesg_file");
while ($line = <$in>) {
$dmesg_buf .= $line;
}
close($in);
} else {
$dmesg_buf = `$dmesg_prog`;
}
}
my($pci_all) = "";
my($guess_system) = "Unknown";
my($system_model_index);
sub guess_system {
my($init) = @_;
my($system) = "";
my($buf) = $dmesg_buf;
my($i) = 0;
my($model);
foreach $model (@system_models) {
my($guess) = $model->{'model'};
my($id);
my($match) = 1;
foreach $id (@{$model->{'ids'}}) {
if (!($pci_all =~ /<$id>/)) {
$match = 0;
last;
}
}
if ($match && defined $system_models[$i]{'model-match'}) {
$match = 0 unless ($init =~ /$system_models[$i]{'model-match'}/);
}
if ($match) {
$system = $guess;
$guess_system = $guess;
$system_model_index = $i;
last;
}
$i++;
}
if ($guess_system eq "Unknown" && $< == 0) {
$debug .= "Debug-System:\t$guess_system\n";
}
return $system if ($system);
if ($buf =~ /ServerWorks ROSB4 ATA33/ && $buf =~ /fxp1:/) {
if ($buf =~ /CMD 649 ATA100/ && $buf =~ /Mach64-GR/) {
$system = "Compaq ProLiant DL320?";
} elsif (($buf =~ /sym1:/ || $buf =~ /ida0:/) && $buf =~ /Mach64-GV/) {
$system = "Compaq ProLiant DL360?";
} elsif ($buf =~ /Compaq Smart Array 5i/ && $buf =~ /Mach64-GR/) {
$system = "Compaq ProLiant DL380 G2?";
}
} elsif ($buf =~ /ServerWorks CSB5 ATA100/ && $buf =~ /bge1:/ && $buf =~ /Mach64-GR/ && $buf =~ /Compaq Smart Array 5i/) {
if ($buf =~ /Broadcom BCM5701/) {
$system = "Compaq ProLiant DL360 G2?";
} elsif ($buf =~ /Broadcom BCM5703/) {
if ($buf =~ /pci6/ && $buf =~ /pci7/) {
$system = "Compaq ProLiant DL380 G3?";
} else {
$system = "HP ProLiant DL360 G3?";
}
}
} elsif ($buf =~ /Broadcom BCM5702/ && $buf =~ /bge1:/ && $buf =~ /Mach64-GR/) {
if ($buf =~ /CMD 649 ATA100/) {
$system = "HP ProLiant DL320 G2?";
}
} elsif ($buf =~ /HP Smart Array 6i/ && $buf =~ /bge1:/ && $buf =~ /Mach64-GR/) {
if ($buf =~ /Intel 6300ESB ATA100/) {
$system = "HP ProLiant DL360 G4?";
} elsif ($buf =~ /Intel ICH5 ATA100/) {
$system = "HP ProLiant DL380 G4?";
}
}
return ($system || "Unknown");
}
my(%interfaces);
my(%pci_map);
my(%pci_to_driver);
my(%irq_to_pci);
my(%irq_to_driver);
my(%scsi_to_driver);
my($ndrives) = 0;
my($drive_id) = 1;
my(%volumes);
my(%drives);
my(%props);
my(%logical_to_os);
my(%controller_volumes);
sub grok_proc_scsi {
my($file) = 'FILE';
my($line);
return unless ($os_type eq "linux");
if (-e $proc_scsi) {
my($letter) = 'a';
my($dev, $channel, $id, $lun, $model, $vendor, $vendor_model);
$need_arcconf++ if (-e "/proc/scsi/aacraid");
open($file, "< $proc_scsi") || warn("open: $proc_scsi: $!");
$debug_storage .= ">> $proc_scsi\n";
while ($line = <$file>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^Host:\s+(\S+)\s+Channel:\s+(\S+)\s+Id:\s+(\S+)\s+Lun:\s+(\S+)/) {
($dev, $channel, $id, $lun) = ($1, $2, $3, $4);
} elsif ($line =~ /^Host: (\S+)/) {
$dev = $1;
} elsif ($line =~ /^\s*Vendor:\s*(.*)Model:\s*(.*\S)\s*Rev:/) {
($vendor, $model) = ($1, $2);
$vendor_model = "$vendor $model";
$need_megacli++ if ($vendor_model =~ /$perc_names/); # no /i so that PepperCo doesn't match
$need_megarc++ if ($vendor_model =~ /MegaRAID/);
$need_twcli++ if ($vendor_model =~ /(3ware|AMCC)/);
} elsif ($line =~ /^\s*Type:\s*Direct-Access/) {
my($vol) = "sd" . $letter++;
my($device) = vol_to_hostid($vol) || $dev;
$volumes{$vol}++;
if ($model =~ /(raid\d+)/i) {
$props{$vol}{raid} = $1;
} else {
$props{$vol}{raid} = "JBOD";
}
if ($vendor =~ /^(PepperC|SMSC)/) {
$props{$vol}{hidden} = 1;
}
$props{$vol}{device} = $device if ($device);
$drives{$vol}{$drive_id}++;
$props{drives}{$drive_id}{model} = canon_drive($vendor_model);
$props{drives}{$drive_id}{volume} = $vol;
smartctl($vol, "/dev/$vol", $vendor, $drive_id);
hdparm($vol, "/dev/$vol", $drive_id);
$drive_id++;
$ndrives++;
if (defined($dev) && defined($channel)) {
if ($vendor_model =~ /MegaRAID/) {
my($logical) = sprintf("%s-%d-%d-%d", $dev, $channel, $id, $lun);
$logical_to_os{'megaraid'}{$logical} = $vol;
} elsif ($vendor_model =~ /$perc_names/) {
my($logical) = sprintf("%s-%d-%d-%d", $dev, $channel, $id, $lun);
$logical_to_os{'perc'}{$logical} = $vol;
} elsif ($vendor_model =~ /(3ware|AMCC)/i) {
my($logical) = sprintf("c%d-u%d", ($dev =~ /^scsi(\d+)/), $id);
$logical_to_os{'tw'}{$logical} = $vol;
} else {
$logical_to_os{'other'}{$model} = $vol;
}
}
undef $dev;
undef $channel;
undef $id;
undef $lun;
}
}
close($file);
}
}
# need to parse /sys/bus/pci/drivers/cciss/ to get pci-id to match with controller
sub grok_proc_cciss {
my($dir) = 'DIR';
my($file) = 'FILE';
my($line);
return unless ($os_type eq "linux" && -d $proc_cciss);
$need_hpacucli++;
opendir($dir, $proc_cciss) || warn("opendir: $proc_cciss: $!");
my(@dirs) = readdir($dir);
closedir($dir);
my(@dirs2);
if (-d $sys_cciss) {
opendir($dir, $sys_cciss) || warn("opendir: $sys_cciss: $!");
@dirs2 = readdir($dir);
closedir($dir);
}
$debug_storage .= ">> $proc_cciss\n";
my($ent, $ent2);
foreach $ent (@dirs) {
if ($ent =~ /^cciss\d+$/) {
open($file, "< $proc_cciss/$ent") || warn("open: $proc_cciss/$ent: $!");
$debug_storage .= ">>> $proc_cciss/$ent\n";
while ($line = <$file>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /firmware version: (\S+)/i) {
$props{$ent}{'firmware'} = $1;
} elsif ($line =~ /^(cciss\/c\d+d\d+):\s+([\d\.]+)GB\s+(\S+.*)\s*$/) {
my($vol) = $1;
$volumes{$vol}++;
$props{$vol}{raid} = $3;
$props{$vol}{device} = $ent;
$controller_volumes{$ent}{$vol}++;
foreach $ent2 (@dirs2) {
if ($ent2 =~ /^[0-9a-f]{4}:(.*)/i) {
# not sure when this was added and why. it only seems to screw things up
# commenting out the next line on 20080329, the other two were commented out long ago
# $props{$vol}{device} = $1;
# $other_devices{'Disk-Control'}{$dev} = "$dev: $model";
# $cleanup{'Disk-Control'}{$num}++;
}
}
}
}
close($file);
}
}
}
sub ccdconfig {
my($in) = 'CCD';
my($line);
my($result) = 0;
system("which ccdconfig > /dev/null 2>&1");
return $result if ($?);
open($in, "ccdconfig -g 2> /dev/null |") || warn "exec ccdconfig: $!";
$debug_storage .= ">> ccdconfig -g\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
$result = 1;
my($vol, $ileave, $flags, @parts) = split(' ', $line);
if ($flags =~ /MIRROR/) {
$props{$vol}{raid} = "RAID-1";
} else {
$props{$vol}{raid} = "RAID-0";
$props{$vol}{stripe} = $ileave * 512;
}
my($model) = "";
my($sep) = "partitions: ";
my($part);
foreach $part (@parts) {
$part =~ s,/dev/,,;
$model .= "$sep$part";
$sep = ", ";
}
$volumes{$vol}++;
$drives{$vol}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $vol;
$drive_id++;
$ndrives++;
}
close($in);
return $result;
}
sub grok_mdstat {
my($file) = 'FILE';
my($line);
my($vol, $raid, $rest);
return unless ($os_type eq "linux");
if (-e $proc_mdstat) {
open($file, "< $proc_mdstat") || warn("open: $proc_mdstat: $!");
$debug_storage .= ">> $proc_mdstat\n";
while ($line = <$file>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^(md\d+).*(raid\d+)\s+(.*)/) {
($vol, $raid, $rest) = ($1, $2, $3);
$props{$vol}{raid} = $raid;
my($dev);
my($model) = "";
my($sep) = "partitions: ";
my($part, %parts);
foreach $dev (split(' ', $rest)) {
if ($dev =~ /^(.*)\[(\d+)\]/) {
$parts{$2} = $1;
}
$dev =~ s/\[(\d+)\]//;
$dev =~ s/\d+$//;
$props{$dev}{inmd}++;
}
foreach $part (sort keys %parts) {
$model .= "$sep$parts{$part}";
$sep = ", ";
}
$drives{$vol}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $vol;
$drive_id++;
$ndrives++;
} elsif ($line =~ /(\S+)\s+chunks/) {
$props{$vol}{stripe} = parse_bytes($1, 1024);
}
}
}
}
sub grok_proc_partitions {
my($file) = 'FILE';
my($line);
return unless ($os_type eq "linux");
if (-e $proc_partitions) {
open($file, "< $proc_partitions") || warn("open: $proc_partitions: $!");
$debug_storage .= ">> $proc_partitions\n";
while ($line = <$file>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+([hs]d[a-z]+)(\s+|$)/) {
my($blocks) = $3;
my($vol) = $4;
$volumes{$vol}++;
$props{$vol}{bytes} = $blocks * 1024;
} elsif ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+((cciss|ida)\/c\d+d\d+)(\s+|$)/) {
my($blocks) = $3;
my($vol) = $4;
$volumes{$vol}++;
$props{$vol}{bytes} = $blocks * 1024;
$need_hpacucli++;
} elsif ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(rd\/c\d+d\d+)(\s+|$)/) {
my($blocks) = $3;
my($vol) = $4;
$volumes{$vol}++;
$props{$vol}{bytes} = $blocks * 1024;
$need_rd++;
} elsif ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(md\d+)(\s+|$)/) {
my($blocks) = $3;
my($vol) = $4;
$volumes{$vol}++;
$props{$vol}{bytes} = $blocks * 1024;
$need_mdstat++;
} elsif ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(lvm\S+)(\s+|$)/) {
$need_lvm++;
} elsif ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(dm-\d+)(\s+|$)/) {
$need_lvm++;
}
}
close($file);
}
}
sub grok_proc_ide {
my($dir) = 'DIR';
return unless ($os_type eq "linux" && -d $proc_ide);
opendir($dir, $proc_ide) || warn("opendir: $proc_ide: $!");
my(@dirs1) = readdir($dir);
closedir($dir);
my($ent1);
foreach $ent1 (@dirs1) {
if ($ent1 =~ /^ide\d+$/ && -d "$proc_ide/$ent1") {
opendir($dir, "$proc_ide/$ent1") || warn("opendir: $proc_ide/$ent1: $!");
my(@dirs2) = readdir($dir);
closedir($dir);
my($ent2);
foreach $ent2 (@dirs2) {
if ($ent2 =~ /^hd([a-z])$/ && -d "$proc_ide/$ent1/$ent2") {
my($letter) = $1;
my($vol) = $ent2;
my($media, $model, $blocks, $cache);
chomp($media = `cat $proc_ide/$ent1/$vol/media 2> /dev/null`);
next if ($media =~ /(cdrom|unknown)/i);
chomp($model = `cat $proc_ide/$ent1/$vol/model 2> /dev/null`);
chomp($blocks = `cat $proc_ide/$ent1/$vol/capacity 2> /dev/null`);
chomp($cache = `cat $proc_ide/$ent1/$vol/cache 2> /dev/null`);
$cache *= 1024 if ($cache);
$model = canon_drive($model);
$volumes{$vol}++;
$props{$vol}{raid} = "JBOD";
$props{$vol}{bytes} = $blocks * 512;
$props{$vol}{device} = $ent1;
$props{$vol}{ms} = ((ord($letter) - ord('a')) % 2) ? "slave" : "master";
$drives{$vol}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{size} = $blocks * 512;
$props{drives}{$drive_id}{cache_size} = $cache;
$props{drives}{$drive_id}{volume} = $vol;
# override with hdparm info if we have it
smartctl($vol, "/dev/$vol", "ATA", $drive_id);
hdparm($vol, "/dev/$vol", $drive_id);
$drive_id++;
$ndrives++;
}
}
}
}
}
sub pci_to_driver {
my($root) = "/sys/bus/pci/drivers";
my($dir) = 'DIR';
my($driver);
if (-d $root) {
opendir($dir, "$root") || warn("opendir: $root: $!");
my(@dirs) = readdir($dir);
closedir($dir);
foreach $driver (sort @dirs) {
next if ($driver =~ /^\.+$/);
opendir($dir, "$root/$driver") || warn("opendir: $root/$driver: $!");
my(@files) = readdir($dir);
closedir($dir);
my($file);
my($count) = 0;
foreach $file (sort @files) {
if ($file =~ /^0000:(.*)/) {
my($pci) = $1;
$pci_to_driver{$pci} = lc($driver);
$pci_to_driver{$pci} =~ s/\s+/_/g;
$pci_to_driver{$pci} .= "-" if ($driver =~ /\d$/);
$pci_to_driver{$pci} .= $count++;
}
}
}
}
}
sub pci_to_hostid {
my($pci) = @_;
my($root) = "/sys/bus/pci/devices";
my($dir) = 'DIR';
my($file) = 'FILE';
my(@dirs1);
my($hostid);
my($full_pci) = $pci;
$full_pci = "0000:$full_pci" unless (-d "$root/$full_pci");
if (-d "$root/$full_pci") {
opendir($dir, "$root/$full_pci") || warn("opendir: $root/$full_pci: $!");
my(@dirs1) = readdir($dir);
closedir($dir);
my($ent1);
foreach $ent1 (sort @dirs1) {
if ($ent1 =~ /^host\d+$/) {
if ($hostid) {
$hostid_synonyms{$ent1} = $hostid;
} else {
$hostid = $ent1;
}
$hostid_to_pci{$ent1} = $pci;
if ($pci_to_driver{$pci}) {
$hostid_to_driver{$ent1} = $pci_to_driver{$pci};
} elsif (-e "/sys/class/scsi_host/$ent1/proc_name") {
my($driver) = `cat "/sys/class/scsi_host/$ent1/proc_name"`;
chomp($driver);
$driver = $linux_driver_map{$driver} || $driver;
$driver .= $1 if ($ent1 =~ /(\d+)$/);
$hostid_to_driver{$ent1} = $pci_to_driver{$pci} = $driver;
}
}
}
}
return $hostid;
}
sub vol_to_hostid {
my($vol) = @_;
my($root) = "/sys/block";
if (-l "$root/$vol/device") {
my($link) = readlink("$root/$vol/device");
if ($link =~ /\/(host\d+)\//) {
return $hostid_synonyms{$1} || $1;
}
}
return;
}
my(%ioports_map);
my(%iomem_map);
my(%interrupts_map);
my(%irq_count);
sub grok_proc_ioports {
my($file) = 'FILE';
my($line);
return unless ($os_type eq "linux");
if (-e $proc_interrupts) {
my($class) = 0;
my($in) = "LSPCI";
open($in, "$lspci -vn 2> /dev/null |") || warn("exec: $lspci: $!");
while ($line = <$in>) {
if ($line =~ /^([0-9a-f\.\:]+)\s+(Class\s+)?([0-9a-f]+):/i) {
$class = "0x$3";
}
if ($line =~ /irq\s+(\d+)/i) {
$irq_count{$1}++;
$irq_count{"$1,$class"}++;
}
}
close($in);
open($file, "< $proc_interrupts") || warn("open: $proc_interrupts: $!");
while ($line = <$file>) {
if ($line =~ /^\s*(\d+).*\s+(\S+)$/) {
$interrupts_map{$1} = lc($2) if ($irq_count{$1} && $irq_count{$1} == 1);
}
}
close($file);
}
if (-e $proc_ioports) {
open($file, "< $proc_ioports") || warn("open: $proc_ioports: $!");
while ($line = <$file>) {
if ($line =~ /^\s*([0-9a-f]+)-([0-9a-f]+)\s+:\s+(\w+)/) {
$ioports_map{$1} = lc($3);
}
}
close($file);
}
if (-e $proc_iomem) {
open($file, "< $proc_iomem") || warn("open: $proc_iomem: $!");
while ($line = <$file>) {
if ($line =~ /^\s*([0-9a-f]+)-([0-9a-f]+)\s+:\s+(\w+)/) {
$iomem_map{$1} = lc($3);
}
}
close($file);
}
}
my(%iomem_to_pci);
sub grok_lspci {
my($in) = "LSPCI";
my($line);
my(%driver_count);
my(%model);
if ($os_type eq "linux") {
open($in, "$lspci 2> /dev/null |") || warn("exec: $lspci: $!");
while ($line = <$in>) {
chomp($line);
if ($line =~ /^([0-9a-f:\.]+) ([^:]+):(.*)/i) {
my($pci, $class, $model) = ($1, $2, $3);
if ($model =~ s/: Unknown device [0-9a-f]+$//i) {
$model .= " $class";
}
$model{$pci} = clean_pci_model($model);
}
}
close($in);
open($in, "$lspci -vn 2> /dev/null |") || warn("exec: $lspci: $!");
$line = <$in>;
my($first) = 1;
my($pci, $class, $chip, $card, $rev, $irq, $irq_class);
while (1) {
$debug_lspci .= $line;
if (eof($in) || $line =~ /^\S+/) {
if (!$first) {
my($model) = $model{$pci} || 'Unknown';
if ($chipsets{"$chip,$rev"}) {
$other_devices{'Chipset'}{"$chip,$rev"} = $chipsets{"$chip,$rev"};
} elsif ($chipsets{$chip}) {
$other_devices{'Chipset'}{$chip} = $chipsets{$chip};
}
if ($pci_devices{'storage'}{"$card,$chip,$rev"}) {
my($dev) = pci_to_hostid($pci) || $pci;
$other_devices{'Disk-Control'}{$dev} = "$dev: " . $pci_devices{'storage'}{"$card,$chip,$rev"};
} elsif ($pci_devices{'storage'}{"$card,$chip"}) {
my($dev) = pci_to_hostid($pci) || $pci;
$other_devices{'Disk-Control'}{$dev} = "$dev: " . $pci_devices{'storage'}{"$card,$chip"};
} elsif ($pci_devices{'storage'}{"0x????????,$chip"}) {
my($dev) = pci_to_hostid($pci) || $pci;
$debug .= "Debug-Disk-Control:\t$dev: $card,$chip,$rev - $model\n";
$other_devices{'Disk-Control'}{$dev} = "$dev: " . $pci_devices{'storage'}{"0x????????,$chip"};
} elsif ($pci_devices{'network'}{"$card,$chip,$rev"}) {
$other_devices{'Network'}{$pci} = "$pci: " . $pci_devices{'network'}{"$card,$chip,$rev"};
} elsif ($pci_devices{'network'}{"0x????????,$chip,$rev"}) {
$debug .= "Debug-Network:\t$pci: $card,$chip,$rev - $model\n";
$other_devices{'Network'}{$pci} = "$pci: " . $pci_devices{'network'}{"0x????????,$chip,$rev"};
} elsif ($pci_devices{'network'}{"0x????????,$chip,0x??"}) {
$debug .= "Debug-Network:\t$pci: $card,$chip,$rev - $model\n";
$other_devices{'Network'}{$pci} = "$pci: " . $pci_devices{'network'}{"0x????????,$chip,0x??"};
} elsif ($pci_devices{'other'}{"$card,$chip,$rev"}) {
$other_devices{$pci_devices{'other'}{"$card,$chip,$rev"}{type}}{"$card,$chip"} = $pci_devices{'other'}{"$card,$chip,$rev"}{model};
} elsif ($pci_classes{$class}) {
my($dev) = pci_to_hostid($pci) || $pci;
$debug .= "Debug-" . $pci_classes{$class} . ":\t$dev: $card,$chip,$rev - $model\n";
$other_devices{$pci_classes{$class}}{$dev} = "$dev: $model";
}
$pci_map{$pci} = "$card,$chip,$rev";
$pci_all .= "<$card,$chip,$rev>";
$sig_pci .= "$card,$chip,$rev\t$model\n";
}
if ($line =~ /^([0-9a-f\.\:]+)\s+(Class\s+)?([0-9a-f]+):\s+([0-9a-f]+):([0-9a-f]+)( \(rev ([0-9a-f]+)\))?/i) {
($pci, $class, $chip, $card, $rev, $irq, $irq_class) = ($1, "0x$3", "0x$5$4", "0x00000000", $7 ? "0x$7" : "0x00", 0, 0);
$pci =~ s/^0000://;
$first = 0;
}
} elsif ($line =~ /^\sFlags:.*IRQ\s+(\d+)/i) {
if ($irq_count{$1} && $irq_count{$1} == 1) {
$irq = $1;
$irq_to_pci{$irq} = $pci;
}
if ($irq_count{"$1,$class"} && $irq_count{"$1,$class"} == 1) {
$irq_class = "$1,$class";
$irq_to_pci{$irq_class} = $pci;
}
} elsif ($line =~ /^\s*I\/O ports at ([0-9a-f]+)/i) {
my($addr) = $1;
unless ($pci_to_driver{$pci}) {
my($networks) = "e100|e1000|eepro100|tg3|bnx2|bcm5700|forcedeth|pcnet32|sky2";
my($match) = "^(lsi|aic79xx|qla2300|cciss|sata_nv|sata_sil|3w|3ware|3w-9xxx|libata|(ide|ioc)\\d+|$networks)\$";
my($driver);
if ($ioports_map{$addr} && $ioports_map{$addr} =~ /$match/) {
$driver = $ioports_map{$addr};
} elsif ($irq && $interrupts_map{$irq} && $interrupts_map{$irq} =~ /$match/) {
# use only on last resort, shared interrupts makes this often wrong
$driver = $interrupts_map{$irq};
}
if ($driver) {
$driver = $linux_driver_map{$driver} || $driver;
if ($driver =~ /^((ide|ioc)\d+|$networks)$/) {
$pci_to_driver{$pci} = $driver;
} else {
$driver_count{$driver}++;
$pci_to_driver{$pci} = $driver;
$pci_to_driver{$pci} .= "-" if ($driver =~ /\d$/);
$pci_to_driver{$pci} .= ($driver_count{$driver} - 1);
}
}
}
if ($pci_to_driver{$pci}) {
$irq_to_driver{$irq_class} = $pci_to_driver{$pci} if ($irq_class);
$irq_to_driver{$irq} = $pci_to_driver{$pci} if ($irq);
}
} elsif ($line =~ /^\s*Memory at ([0-9a-f]+)/i) {
my($addr) = $1;
unless ($pci_to_driver{$pci}) {
my($networks) = "e100|e1000|eepro100|tg3|bnx2|bcm5700|forcedeth|pcnet32|sky2";
my($match) = "^(megaraid|megasas|aic7xxx|$networks)\$";
my($driver);
$iomem_to_pci{$addr} = $pci;
if ($iomem_map{$addr} && $iomem_map{$addr} =~ /$match/) {
$driver = $iomem_map{$addr};
} elsif ($irq && $interrupts_map{$irq} && $interrupts_map{$irq} =~ /$match/) {
# use only on last resort, shared interrupts makes this often wrong
$driver = $interrupts_map{$irq};
}
if ($driver) {
$driver = $linux_driver_map{$driver} || $driver;
if ($driver =~ /^($networks)$/) {
$pci_to_driver{$pci} = $driver;
} else {
$driver_count{$driver}++;
$pci_to_driver{$pci} = $driver;
$pci_to_driver{$pci} .= "-" if ($driver =~ /\d$/);
$pci_to_driver{$pci} .= ($driver_count{$driver} - 1);
}
}
}
if ($pci_to_driver{$pci}) {
$irq_to_driver{$irq_class} = $pci_to_driver{$pci} if ($irq_class);
$irq_to_driver{$irq} = $pci_to_driver{$pci} if ($irq);
}
} elsif ($line =~ /^\s*Subsystem: ([0-9a-f]+):([0-9a-f]+)/i) {
$card = "0x$2$1";
}
last if eof($in);
$line = <$in>;
}
close($in);
}
}
sub grok_pciconf {
my($in) = "PCICONF";
my($line);
my($dev, $class, $card, $chip, $rev);
my($model);
my(%vendor, %model);
my(@lines, $lines);
system("which $pciconf > /dev/null 2>&1");
return if ($?);
open($in, "$pciconf -lv 2> /dev/null |") || warn("exec: $pciconf: $!");
if (eof($in)) {
close($in);
open($in, "$pciconf -l 2> /dev/null |") || warn("exec: $pciconf: $!");
}
while ($line = <$in>) {
$debug_pciconf .= $line;
push(@lines, $line);
if ($line =~ /^(\S+)\@.*class=(\S+).*card=(\S+).*chip=(\S+).*rev=(\S+)/) {
($dev, $class, $card, $chip, $rev) = ($1, $2, $3, $4, $5);
} elsif ($line =~ /^\s+vendor\s+=\s+'(.*)'$/) {
$vendor{$dev} = clean_pci_model($1);
} elsif ($line =~ /^\s+device\s+=\s+'(.*)'$/) {
$model{$dev} = clean_pci_model($1);
}
}
close($in);
foreach $line (@lines) {
if ($line =~ /^(\S+)\@.*class=(\S+).*card=(\S+).*chip=(\S+).*rev=(\S+)/) {
($dev, $class, $card, $chip, $rev) = ($1, $2, $3, $4, $5);
$class =~ s/..$//;
if ($sysctl_dev{$dev} && $sysctl_dev{$dev}{'xmodel'}) {
$model = $sysctl_dev{$dev}{'xmodel'};
} elsif ($vendor{$dev} && $model{$dev}) {
$model = "$vendor{$dev} $model{$dev}";
} else {
$model = 'unknown';
}
$pci_all .= "<$card,$chip,$rev>";
$sig_pci .= "$card,$chip,$rev\t$model\n";
if ($chipsets{"$chip,$rev"}) {
$other_devices{'Chipset'}{"$chip,$rev"} = $chipsets{"$chip,$rev"};
} elsif ($chipsets{$chip}) {
$other_devices{'Chipset'}{$chip} = $chipsets{$chip};
}
if ($dev =~ /^(atapci|ciss|amr|ahc|ahd|asr|aac|aacch|mpt|sym|twe|twa|asr|mfi|ida)\d+/ ) {
$need_cissutil++ if ($1 eq "ciss");
$need_megarc++ if ($1 eq "amr");
$need_mfiutil++ if ($1 eq "mfi");
$need_mptutil++ if ($1 eq "mpt");
$need_arcconf++ if ($1 eq "aac");
$need_twcli++ if ($1 eq "twe" || $1 eq "twa");
if (!$pci_devices{'storage'}{"$card,$chip,$rev"} && !$pci_devices{'storage'}{"$card,$chip"}) {
$debug .= "Debug-Disk-Control:\t$dev: $model, $card,$chip,$rev\n";
$card = "0x????????";
}
if ($pci_devices{'storage'}{"$card,$chip,$rev"}) {
$other_devices{'Disk-Control'}{$dev} = "$dev: " . $pci_devices{'storage'}{"$card,$chip,$rev"};
} elsif ($pci_devices{'storage'}{"$card,$chip"}) {
$other_devices{'Disk-Control'}{$dev} = "$dev: " . $pci_devices{'storage'}{"$card,$chip"};
} else {
$other_devices{'Disk-Control'}{$dev} = "$dev: $model";
}
} elsif ($dev =~ /^($freebsd_net_devs)/) {
$interfaces{$dev}{'model'} = $model unless ($model eq 'unknown' && $interfaces{$dev}{'model'});
if (!$pci_devices{'network'}{"$card,$chip,$rev"}) {
$debug .= "Debug-Network:\t$dev: ";
$debug .= "$interfaces{$dev}{'model'}, " if ($interfaces{$dev}{'model'});
$debug .= "$card,$chip,$rev\n";
$card = "0x????????";
}
if (!$pci_devices{'network'}{"$card,$chip,$rev"}) {
$rev = "0x??";
}
if ($pci_devices{'network'}{"$card,$chip,$rev"}) {
$interfaces{$dev}{'model'} = $pci_devices{'network'}{"$card,$chip,$rev"};
}
} elsif ($pci_devices{'storage'}{"$card,$chip,$rev"}) {
$other_devices{'Disk-Control'}{$dev} = "$dev: " . $pci_devices{'storage'}{"$card,$chip,$rev"};
} elsif ($pci_devices{'storage'}{"$card,$chip"}) {
$other_devices{'Disk-Control'}{$dev} = "$dev: " . $pci_devices{'storage'}{"$card,$chip"};
} elsif ($pci_devices{'network'}{"$card,$chip,$rev"}) {
$other_devices{'Network'}{$dev} = "$dev: " . $pci_devices{'network'}{"$card,$chip,$rev"};
} elsif ($pci_devices{'other'}{"$card,$chip,$rev"}) {
$other_devices{$pci_devices{'other'}{"$card,$chip,$rev"}{type}}{"$card,$chip"} = $pci_devices{'other'}{"$card,$chip,$rev"}{model};
} elsif ($pci_classes{$class}) {
$other_devices{$pci_classes{$class}}{$dev} = "$dev: $model";
$debug .= "Debug-" . $pci_classes{$class} . ":\t$dev: $model, $card,$chip,$rev\n";
}
}
}
}
sub hdparm {
my($vol, $device, $id) = @_;
my($result) = 0;
my($in) = 'HDPARM';
my($line);
system("which hdparm > /dev/null 2>&1");
return $result if ($?);
# only use hdparm for /dev/hdx and /dev/sdx devices
return $result if ($device !~ /^\/dev\/(sd|hd)[a-z]+$/);
open($in, "hdparm -iI $device 2> /dev/null |") || warn("hdparm: $!");
$debug_storage .= ">> hdparm -iI $device\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
$line =~ s/\s*$//;
if ($line =~ /Model=([^,]+)/i || $line =~ /Model Number:\s*(.*)/i) {
$props{drives}{$id}{model} = canon_drive($1);
$result = 1;
}
if ($line =~ /SerialNo=([^,]+)/i || $line =~ /Serial Number:\s*(.*)/i) {
$props{drives}{$id}{serial} = $1;
}
if ($line =~ /FwRev=([^,]+)/i || $line =~ /Firmware Revision:\s*(.*)/i) {
$props{drives}{$id}{firmware} = $1;
}
if ($line =~ /^\s*Used: (\S+)/) {
$props{drives}{$id}{interface} = parse_protocol($1);
}
if ($line =~ /^\s*Likely used: (\d+)/) {
$props{drives}{$id}{interface} = parse_protocol("ATA-$1");
}
if ($line =~ /LBAsects=(((\d+)))/i || $line =~ /LBA(48)?\s*user addressable sectors( =|:)\s*(\d+)/i) {
$props{drives}{$id}{size} = $3 * 512;
}
if ($line =~ /BuffSize=([^,]+)/i) {
$props{drives}{$id}{cache_size} = parse_bytes($1, 1024);
}
if ($line =~ /WriteCache=([^,]+)/i) {
$props{drives}{$id}{wcache_enable} = parse_enable($1);
}
if ($line =~ /^\s*(\*?)\s*Write cache\s*$/i) {
$props{drives}{$id}{wcache_support} = 1;
$props{drives}{$id}{wcache_enable} = parse_enable($1, '\*', '');
}
if ($line =~ /^\s*(\*?)\s*Look-ahead\s*$/i) {
$props{drives}{$id}{readahead_support} = 1;
$props{drives}{$id}{readahead_enable} = parse_enable($1, '\*', '');
}
if ($line =~ /^\s*(\*?)\s*Device-initiated interface power management\s*$/i) {
$props{drives}{$id}{dipm_support} = 1;
$props{drives}{$id}{dipm_enable} = parse_enable($1, '\*', '');
}
if ($line =~ /^\s*(\*?)\s*Host-initiated interface power management\s*$/i) {
$props{drives}{$id}{hipm_support} = 1;
$props{drives}{$id}{hipm_enable} = parse_enable($1, '\*', '');
}
if ($line =~ /^\s*(\*?)\s*Native Command Queueing \(NCQ\)\s*$/i) {
$props{drives}{$id}{ncq_support} = 1;
$props{drives}{$id}{ncq_enable} = parse_enable($1, '\*', '');
}
if ($line =~ /Queue depth: (\d+)/i) {
$props{drives}{$id}{ncq_depth} = $1;
}
if ($line =~ /^\s*(\*?)\s*SMART feature set\s*$/i) {
$props{drives}{$id}{smart_support} = 1;
$props{drives}{$id}{smart_enable} = parse_enable($1, '\*', '');
}
if ($line =~ /^\s*(\*?)\s*Automatic Acoustic Management feature set\s*$/i) {
$props{drives}{$id}{aam_support} = 1;
$props{drives}{$id}{aam_enable} = parse_enable($1, '\*', '');
}
if ($line =~ /Recommended acoustic management value: (\d+), current value: (\d+)/i) {
$props{drives}{$id}{aam_value} = $2;
}
if ($line =~ /^\s*(\*?)\s*Power Management feature set\s*$/i) {
$props{drives}{$id}{pm_support} = 1;
$props{drives}{$id}{pm_enable} = parse_enable($1, '\*', '');
}
if ($line =~ /^\s*(\*?)\s*Advanced Power Management feature set\s*$/i) {
$props{drives}{$id}{apm_support} = 1;
$props{drives}{$id}{apm_enable} = parse_enable($1, '\*', '');
}
if ($line =~ /Advanced power management level: (\d+)/i) {
$props{drives}{$id}{apm_value} = $1;
}
if ($line =~ /^\s*(\*)\s*(SATA-I signaling)/i) {
$props{drives}{$id}{interface} = parse_protocol($2);
}
if ($line =~ /^\s*(\*)\s*(SATA-II signaling)/i) {
$props{drives}{$id}{interface} = parse_protocol($2);
}
if ($line =~ /Logical Unit WWN Device Identifier:\s*(\S+)/i) {
$props{drives}{$id}{wwn} = "0x$1";
}
}
close($in);
return $result;
}
sub smartctl {
my($vol, $device, $vendor, $id) = @_;
my($result) = 0;
my($line);
my($in) = 'SMARTCTL';
my($dev_opt) = ($vendor =~ /^ATA\s*$/) ? '-d ata' : '';
system("which smartctl > /dev/null 2>&1");
return $result if ($?);
# orginally used "smartctl -a" here. this causes some PE2950 RHEL boxes to hang/crash
# e.g. test164.data.corp.sp1.yahoo.com, kr2-ymon-001.ysm.kr2.yahoo.com, s200.del.re1.yahoo.net
# need to be very careful here. "smartctl -i" does appear to be safe for all types, but
# for now we'll be conservative and just use this for ATA drives, which is why we
# starting using this in the first place. before we use for anything else, need to
# be careful.
#
# 20080824 - enabling for all types now. as stated earlier does appear safe
open($in, "smartctl -i $dev_opt $device 2> /dev/null |") || warn "exec smartctl: $!";
$debug_storage .= ">> smartctl -i $dev_opt $device\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^Device Model:\s*(.*)/) {
$props{drives}{$id}{model} = canon_drive($1);
} elsif ($line =~ /^Serial Number:\s*(.*)/) {
$props{drives}{$id}{serial} = $1;
} elsif ($line =~ /^Firmware Version:\s*(.*)/) {
$props{drives}{$id}{firmware} = $1;
} elsif ($line =~ /^User Capacity:\s*([\d,]+)\s+bytes/) {
my($size) = $1;
$size =~ s/,//g;
$props{drives}{$id}{size} = int($size);
} elsif ($line =~ /^SMART support is: Available/) {
$props{drives}{$id}{smart_support} = 1;
} elsif ($line =~ /^SMART support is: Enabled/) {
$props{drives}{$id}{smart_enable} = 1;
}
$result = 1;
}
close($in);
return $result;
}
# new lshal - 0.5.11rc2 on fedora9
# - info.bus seems to have gone away, only used now for usb?
# - linux.sysfs_path_device is gone
sub grok_lshal {
my($in) = "LSHAL";
my($line);
my(%hal, $udi);
my(%cleanup);
open($in, "$lshal 2> /dev/null |") || warn("exec: $lshal: $!");
while ($line = <$in>) {
$debug_lshal .= $line;
chomp($line);
if ($line =~ /^udi = \'([^\']*)\'/) {
$udi = $1;
} elsif ($line =~ /^\s+(\S+)\s+=\s+\'([^\']*)\'/) {
$hal{$udi}{$1} = $2;
} elsif ($line =~ /^\s+(\S+)\s+=\s+(\S+)/) {
$hal{$udi}{$1} = $2;
}
}
close($in);
foreach $udi (keys %hal) {
if ($hal{$udi}{'pci.product_id'}) {
my($num) = substr($hal{$udi}{'linux.sysfs_path'}, -7);
my($id) = $pci_map{$num};
if ($hal{$udi}{'net.interface'}) {
my($model) = $other_devices{'Network'}{$num};
$model =~ s/^$num: //;
$interfaces{$hal{$udi}{'net.interface'}}{'model'} = $model;
$cleanup{'Network'}{$num}++;
$success{'grok_lshal_network'}++;
}
$need_arcconf++ if ($hal{$udi}{'pci.vendor'} && $hal{$udi}{'pci.vendor'} eq 'Adaptec' && $hal{$udi}{'pci.product'} =~ /AAC/);
} elsif (($hal{$udi}{'info.subsystem'} && $hal{$udi}{'info.subsystem'} eq 'ide') || ($hal{$udi}{'info.bus'} && $hal{$udi}{'info.bus'} eq 'ide_host')) {
my($num, $dev);
if ($hal{$udi}{'info.subsystem'} && $hal{$udi}{'info.subsystem'} eq 'ide') {
# new lshal - 0.5.11rc2
($num, $dev) = ($hal{$udi}{'linux.sysfs_path'} =~ /(.{7})\/(ide\d+)\//);
} else {
# legacy lshal
($num, $dev) = ($hal{$udi}{'ide_host.linux.sysfs_path'} =~ /(.{7})\/([^\/]+)$/);
}
if ($num =~ /^[0-9a-f:\.]+$/) {
# guard against case - linux.sysfs_path = '/sys/devices/ide0/0.0'
# which happens with lshal 0.5.11rc2 and ide == compatible in bios
my($model) = $other_devices{'Disk-Control'}{$num};
$dev =~ s/^.*\///;
$model =~ s/^$num: //;
$other_devices{'Disk-Control'}{$dev} = "$dev: $model";
$cleanup{'Disk-Control'}{$num}++;
}
} elsif (($hal{$udi}{'info.subsystem'} && $hal{$udi}{'info.subsystem'} eq 'scsi_host') || ($hal{$udi}{'info.bus'} && $hal{$udi}{'info.bus'} eq 'scsi_host')) {
my($num, $dev);
if ($hal{$udi}{'info.subsystem'} && $hal{$udi}{'info.subsystem'} eq 'scsi_host') {
# new lshal - 0.5.11rc2
($num, $dev) = ($hal{$udi}{'linux.sysfs_path'} =~ /(.{7})\/([^\/]+)$/);
} else {
# legacy lshal
($num, $dev) = ($hal{$udi}{'linux.sysfs_path_device'} =~ /(.{7})\/([^\/]+)$/);
}
unless ($hal{$udi}{'info.parent'} =~ /usb/) {
# check for synonyms for this hostid
$dev = pci_to_hostid($num) || $dev;
unless (defined $other_devices{'Disk-Control'}{$dev}) {
my($model) = $other_devices{'Disk-Control'}{$num};
$dev =~ s/^.*\///;
$model =~ s/^$num: //;
$other_devices{'Disk-Control'}{$dev} = "$dev: $model";
$cleanup{'Disk-Control'}{$num}++;
}
}
} elsif ($hal{$udi}{'storage.drive_type'} && $hal{$udi}{'storage.drive_type'} eq 'disk') {
my($devpath) = $hal{$udi}{'block.device'};
my($vol) = $devpath;
$vol =~ s/.*\///;
$volumes{$vol}++;
my($firmware, $serial, $model);
$firmware = $hal{$udi}{'storage.firmware_version'};
$serial = $hal{$udi}{'storage.serial'};
$model = canon_drive($hal{$udi}{'storage.model'});
if ($model =~ /(raid\d+)/i) {
$props{$vol}{raid} = $1;
} else {
$props{$vol}{raid} = "JBOD";
}
if ($hal{$udi}{'storage.bus'} eq 'ide') {
my($node) = $udi;
my($ms) = 'unknown';
while ($hal{$node}{'info.parent'}) {
$node = $hal{$node}{'info.parent'};
if ($hal{$node}{'info.product'}) {
if ($hal{$node}{'info.product'} =~ /IDE device \((slave|master)\)/) {
$ms = $1;
}
}
if ($hal{$node}{'linux.subsystem'} && $hal{$node}{'linux.subsystem'} eq 'ide') {
# new lshal - 0.5.11rc2 on fedora9
my($dev) = ($hal{$node}{'linux.sysfs_path'} =~ /\/(ide\d+)\//);
$props{$vol}{'device'} = $dev;
$props{$vol}{'ms'} = $ms if ($ms);
$success{'grok_lshal_ide'}++;
$drives{$vol}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $vol;
$props{drives}{$drive_id}{firmware} = $firmware;
$props{drives}{$drive_id}{serial} = $serial;
smartctl($vol, $devpath, $hal{$udi}{'storage.vendor'}, $drive_id);
hdparm($vol, $devpath, $drive_id);
$drive_id++;
$ndrives++;
last;
} elsif ($hal{$node}{'info.bus'} eq 'ide_host') {
# legacy lshal
my($dev) = ($hal{$node}{'ide_host.linux.sysfs_path'} =~ /\/([^\/]+)$/);
$props{$vol}{'device'} = $dev;
$props{$vol}{'ms'} = $ms if ($ms);
$success{'grok_lshal_ide'}++;
$drives{$vol}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $vol;
$props{drives}{$drive_id}{firmware} = $firmware;
$props{drives}{$drive_id}{serial} = $serial;
smartctl($vol, $devpath, $hal{$udi}{'storage.vendor'}, $drive_id);
hdparm($vol, $devpath, $drive_id);
$drive_id++;
$ndrives++;
last;
}
}
} elsif ($hal{$udi}{'storage.bus'} eq 'scsi') {
# good test case - feedb-beta.local.mud
my($node) = $udi;
my($extmodel) = $hal{$node}{'storage.vendor'} . ' ' . $hal{$node}{'storage.model'};
my($scsi_id, $channel, $id, $lun) = (0, 0, 0, 0);
$need_megacli++ if ($extmodel =~ /$perc_names/);
$need_megarc++ if ($extmodel =~ /MegaRAID/);
$need_twcli++ if ($extmodel =~ /(3ware|AMCC)/i);
if ($hal{$node}{'info.parent'} =~ /scsi_(\d+)_(\d+)_(\d+)_(\d+)/) {
($scsi_id, $channel, $id, $lun) = ($1, $2, $3, $4);
} elsif ($hal{$node}{'info.parent'} =~ /scsi_host_scsi_device/) {
my($parent) = $hal{$node}{'info.parent'};
($scsi_id, $channel, $id, $lun) = ($hal{$parent}{'scsi.host'}, $hal{$parent}{'scsi.bus'}, $hal{$parent}{'scsi.target'}, $hal{$parent}{'scsi.lun'});
}
if ($extmodel =~ /MegaRAID/) {
my($logical) = sprintf("scsi%d-%d-%d-%d", $scsi_id, 0, $id, 0);
$logical_to_os{'megaraid'}{$logical} = $vol;
} elsif ($extmodel =~ /$perc_names/) {
my($logical) = sprintf("scsi%d-%d-%d-%d", $scsi_id, 0, $id, 0);
$logical_to_os{'perc'}{$logical} = $vol;
} elsif ($extmodel =~ /(3ware|AMCC)/i) {
my($logical) = sprintf("c%d-u%d", $scsi_id, $id);
$logical_to_os{'tw'}{$logical} = $vol;
} else {
$logical_to_os{'other'}{$hal{$node}{'storage.model'}} = $vol;
}
while ($hal{$node}{'info.parent'}) {
if (($hal{$node}{'info.bus'} && $hal{$node}{'info.bus'} eq 'scsi_host') ||
($hal{$node}{'info.category'} && $hal{$node}{'info.category'} eq 'scsi_host')) {
my($dev) = ($hal{$node}{'linux.sysfs_path'} =~ /\/([^\/]+)$/);
$props{$vol}{'device'} = $dev;
$success{'grok_lshal_scsi'}++;
$drives{$vol}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $vol;
smartctl($vol, $devpath, $hal{$udi}{'storage.vendor'}, $drive_id);
hdparm($vol, $devpath, $drive_id);
$drive_id++;
$ndrives++;
last;
}
$node = $hal{$node}{'info.parent'};
}
}
}
}
my($type, $num);
foreach $type (keys %cleanup) {
foreach $num (keys %{$cleanup{$type}}) {
delete $other_devices{$type}{$num};
}
}
}
my(%lvm_logical_to_physical);
sub lvdisplay {
my($in) = 'LVM';
my($line);
my($result) = 0;
my($lv) = "unknown";
my($lv_count) = 0;
my($lv_size) = 0;
my($vol) = "unknown";
my($model) = "unknown";
my($sep) = '';
my($looking) = 0;
system("which lvdisplay > /dev/null 2>&1");
return $result if ($?);
$debug_storage .= ">> lvm\n";
open($in, "lvdisplay -m 2> /dev/null |") || warn "exec lvdisplay: $!";
$debug_storage .= ">>> lvdisply -m\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
$result = 1;
if ($line =~ /^Synopsis:/) {
$result = 0;
last;
}
if ($line =~ /LV Name\s+(\S+)/) {
$lv = $1;
$lv =~ s,^/dev/,,;
$lv =~ s,/,-,g;
$vol = "dm$lv_count";
$lv_count++;
} elsif ($line =~ /LV Size\s+(.*)/) {
$lv_size = parse_bytes($1, 1000);
} elsif ($line =~ /Type\s+striped/) {
$ndrives++;
$volumes{$vol}++;
$props{$vol}{bytes} = $lv_size;
$props{$vol}{raid} = "RAID 1";
$sep = "partitions: ";
$model = '';
$looking++;
} elsif ($line =~ /Stripe size\s+(.*)/) {
$props{$vol}{stripe} = parse_bytes($1, 1024);
} elsif ($line =~ /Physical volume\s+(\S+)/) {
my($dev) = $1;
$lvm_logical_to_physical{$lv} = $dev;
$dev =~ s,^/dev/,,;
$model .= "$sep$dev";
$sep = ", ";
} elsif ($line =~ /^\s*$/) {
if ($looking) {
$drives{$vol}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $vol;
$drive_id++;
$lvm_logical_to_physical{$lv} = $vol;
}
$looking = 0;
}
}
close($in);
if (!$result) {
my($volumes);
open($in, "lvscan 2> /dev/null |") || warn "exec lvscan: $!";
$debug_storage .= ">>> lvscan\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /ACTIVE\s*\"(\S+)\"/) {
$volumes .= " $1";
}
}
close($in);
if ($volumes) {
my($next) = 0;
open($in, "lvdisplay -v $volumes 2> /dev/null |") || warn "exec lvdisplay: $!";
$debug_storage .= ">>> lvdisplay -v $volumes\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /LV Name\s+(\S+)/) {
$lv = $1;
}
if ($next) {
if ($line =~ /^\s+(\S+)/) {
$lvm_logical_to_physical{$lv} = $1;
}
$next = 0;
}
if ($line =~ /^\s*PV Name/) {
$next = 1;
}
}
close($in);
}
}
return $result;
}
sub df {
my($in) = 'DF';
my($line);
my($result) = 0;
system("which df > /dev/null 2>&1");
return $result if ($?);
if ($os_type eq "linux") {
open($in, "df -P -k -l 2> /dev/null |") || warn "exec df: $!";
$debug_storage .= ">> df -P -k -l\n";
} else {
open($in, "df -k -t ufs 2> /dev/null |") || warn "exec df: $!";
$debug_storage .= ">> df -k -t ufs\n";
}
$line = <$in>;
$debug_storage .= $line;
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
$result++;
my($vol, $size, $used, $avail, @rest) = split(' ', $line);
next unless ($vol =~ m,^/dev/,);
if ($vol =~ m,^/dev/mapper/(.*),) {
$vol = $lvm_logical_to_physical{$1} || $vol;
}
$vol = $lvm_logical_to_physical{$vol} || $vol;
$vol =~ s,^/dev/,,;
if ($os_type eq "linux") {
if ($vol =~ m,^[hs]d,) {
$vol =~ s,\d+$,,;
} else {
$vol =~ s,p\d+$,,;
}
} else {
$vol =~ s,s\d+[a-e]$,,; # e.g. /dev/ad0s1e
$vol =~ s,(\d+)[a-e]$,$1,; # e.g. /dev/ad0e
$vol =~ s,p\d+$,,; # e.g. /dev/mfid0p4
$need_ccdconfig++ if ($vol =~ /^ccd/);
}
$props{$vol}{df}{size} += $size * 1024;
$props{$vol}{df}{used} += $used;
$props{$vol}{df}{avail} += $avail;
}
close($in);
return $result;
}
sub other_devices {
my($line);
my($type, $device);
my(@chipsets);
my($out, @out);
foreach $type (sort keys %other_devices) {
foreach $device (sort cmp_devs keys %{$other_devices{$type}}) {
if ($type eq 'Chipset') {
push(@chipsets, $other_devices{$type}{$device});
next;
}
$out = '';
$out .= "$type:\t";
$out .= "\t" if (length($type) < 7);
my($description) = $other_devices{$type}{$device};
my($dev) = $device;
if ($hostid_to_pci{$dev}) {
$dev = $hostid_to_pci{$dev};
}
if ($dev =~ /^[0-9a-f:\.]+$/) {
my($new) = $pci_to_driver{$dev} || pci_to_hostid($dev);
if ($new) {
if ($type eq 'Network') {
$description =~ s/^$device/$device ($new)/;
} else {
$description =~ s/^$device/$new/;
$dev = $new;
}
}
}
$out .= $description;
if ($type eq 'Disk-Control') {
if ($props{$dev}{'package'}) {
if ($props{$dev}{'firmware'}) {
$out .= ", Package $props{$dev}{'package'}";
} else {
$out .= ", FW $props{$dev}{'package'}";
}
}
if ($props{$dev}{'firmware'}) {
$out .= ", FW $props{$dev}{'firmware'}";
}
if ($props{$dev}{'bios'}) {
$out .= ", BIOS $props{$dev}{'bios'}";
}
if ($props{$dev}{'cache-status'} || $props{$dev}{'cache-size'}) {
$out .= ", Cache";
$out .= " $props{$dev}{'cache-status'}" if $props{$dev}{'cache-status'};
if ($props{$dev}{'cache-size'}) {
$out .= ' ' . print_bytes($props{$dev}{'cache-size'}, 1024, 1);
} elsif (defined $props{$dev}{'cache-read'}) {
$out .= ' ' . print_bytes($props{$dev}{'cache-read'}, 1024, 1);
$out .= '/' . print_bytes($props{$dev}{'cache-write'}, 1024, 1);
$out .= ' (R/W)';
}
}
if ($props{$dev}{'bbu'}) {
$out .= ", BBU";
}
}
push(@out, $out);
}
}
foreach $out (sort cmp_other_devices @out) {
$output .= $out . "\n";
}
if (@chipsets) {
my($chipset, $pretty, $vendor, $last);
foreach $chipset (sort @chipsets) {
$chipset =~ s/^(NB|SB|IB): //;
($vendor) = ($chipset =~ /^(\S+)\s+/);
if ($last && $vendor eq $last) {
$chipset =~ s/^$vendor\s+//;
$pretty .= ", " if $pretty;
} else {
$pretty .= "; " if $pretty;
}
$pretty .= $chipset;
$last = $vendor;
}
$output .= "Chipset:\t$pretty\n";
} elsif ($system_model_index && defined $system_models[$system_model_index]{chipset}) {
$output .= "Chipset:\t$system_models[$system_model_index]{chipset}\n";
} else {
$debug .= "Debug-Chipset:\tUnknown\n";
}
}
sub cmp_other_devices {
my($atype, $anum) = ($a =~ /^[^:]*:\s*([^:]*?)(\d*)/);
my($btype, $bnum) = ($b =~ /^[^:]*:\s*([^:]*?)(\d*)/);
if ($anum && $bnum) {
return ($atype cmp $btype || $anum <=> $bnum);
} else {
return ($atype cmp $btype)
}
}
sub dmesg_disks {
my($line);
my(%disks, $disk);
my($result, $sep);
foreach $line (split(/\n/, $dmesg_buf)) {
if ($line =~ /^((mfid|twed|idad|da|ad|wd|sd)\d+):/) {
$disks{$1}++;
}
}
$sep = "";
$result = "";
foreach $disk (sort { $a cmp $b } keys %disks) {
$result .= "$sep$disk";
$sep = " ";
}
return $result;
}
my(%dmesg);
sub grok_dmesg {
my($line);
foreach $line (split(/\n/, $dmesg_buf)) {
chomp($line);
$line =~ s/\(R\)//g;
if ($line =~ /^CPU:\s+([^\(]*).*\(([\d\.]+-MHz)/i) {
my($family, $speed) = ($1, $2);
$family =~ s/\bCPU.*//;
$family =~ s/\s+$//;
$speed =~ s/-//g;
$dmesg{proc}{family} = $family;
$dmesg{proc}{speed} = $speed;
if ($family =~ /amd/i) {
$dmesg{proc}{vendor} = "AMD";
} elsif ($family =~ /intel/i || $family =~ /xeon/i || $family =~ /pentium/i) {
$dmesg{proc}{vendor} = "Intel";
}
} elsif ($line =~ /^\s*Features\s*=\s*0x([0-9a-f]+)/i) {
$dmesg{proc}{features} = $1;
} elsif ($line =~ /Origin\s*=\s*"(\S+)".*Id\s*=\s*0x([0-9a-f]+).*Stepping\s*=\s*(\S+)/i) {
$dmesg{proc}{origin} = $1;
$dmesg{proc}{cpuid} = $2;
$dmesg{proc}{stepping} = $3;
} elsif ($line =~ /^((atapci|mfi|mpt|ahc|ahd|asr|aac|aacch|sym|ida|twe|twa)\d+): <([^>]*)>.*device/) {
$need_mfiutil++ if ($2 eq "mfi");
$need_mptutil++ if ($2 eq "mpt");
$need_twcli++ if ($2 eq "twe" || $2 eq "twa");
$other_devices{"Disk-Control"}{$1} = "$1: $3";
$other_devices{"Disk-Control"}{$1} =~ s/\s+controller\b.*//i;
} elsif ($line =~ /^(($freebsd_net_devs)\d+): <([^>]*)>.*device/) {
$interfaces{$1}{'model'} = $3;
$interfaces{$1}{'model'} =~ s/\s*(Ethernet|Network|,).*//;
} elsif ($line =~ /^ciss\d+/) {
$need_cissutil++;
if ($line =~ /^(ciss\d+): <([^>]*)>.*port.*device/) {
$other_devices{"Disk-Control"}{$1} = "$1: $2";
} elsif ($line =~ /^(ciss\d+):\s+firmware\s+([\d\.]+)/) {
$props{$1}{'firmware'} = $2;
}
} elsif ($line =~ /^amr\d+/) {
$need_megarc++;
if ($line =~ /^(amr\d+): <([^>]*)>.*Firmware\s+([^,]+),.*BIOS\s+([^,]+)/) {
$other_devices{"Disk-Control"}{$1} = "$1: $2";
$props{$1}{'firmware'} = $3;
$props{$1}{'bios'} = $4;
}
}
}
}
my(%procs);
sub parse_proc {
my($in, $section, $handle) = @_;
my($line);
my($socket) = ++$procs{sockets};
my($ignore) = 1;
my($key);
while ($line = <$in>) {
$debug_dmidecode .= $line;
chomp($line);
$line =~ s/\s+$//;
last if ($line =~ /^(handle.*)?$/i);
$line =~ s/$clean_smbios_regex//i;
if ($handle) {
if ($line =~ /^\t(\S[^:]+):\s*(.*)/) {
$key = $1;
$dmi{$handle}{'key'}{$1} = $2;
} elsif ($line =~ /^\t\t(.*)/) {
$dmi{$handle}{'key'}{$key} .= "\t$1";
}
}
if ($line =~ /^\s*Type:\s+(CPU|Central Processor)/i) {
$ignore = 0;
} elsif ($line =~ /^\s*Socket Designation:\s+(Slot-2)/i) {
$ignore = 0
} elsif ($line =~ /^\s*current (cpu )?speed:\s+(.*)$/i) {
my($speed) = $2;
$speed =~ s/\s+//g;
$procs{$socket}{speed} = ($speed eq "0MHz") ? 0 : $speed;
} elsif ($line =~ /^\s*(external )?clock:\s+(.*)$/i) {
my($clock) = $2;
$clock =~ s/\s+//g;
$procs{$socket}{clock} = ($clock eq "0MHz") ? 0 : $clock;
} elsif ($line =~ /^\s*family:\s+(.*)$/i) {
$procs{$socket}{family} = $1;
} elsif ($line =~ /^\s*manufacturer:\s+(.*)$/i) {
$procs{$socket}{vendor} = $1;
} elsif ($line =~ /^\s*cpu present:\s+(.*)$/i) {
$procs{$socket}{status} = ($1 =~ /yes/i);
} elsif ($line =~ /^\s*id:\s+(.*)$/i) {
my($id) = lc($1);
if ($id =~ / /) {
# from dmidecode
$id = join('', reverse(split(' ', $id))) if ($id =~ / /);
}
$id =~ s/^0x//;
$procs{$socket}{cpuid} = substr($id, -8);
$procs{$socket}{features} = substr($id, 0 ,8);
} elsif ($line =~ /^\s*status:\s+(.*)$/i) {
$procs{$socket}{status} = ($1 =~ /\bpopulated\b/i);
} elsif ($line =~ /^\s*(L\d+ Cache Handle):\s+(.*)$/) {
$procs{$socket}{$1} = $2;
}
}
if ($ignore) {
$procs{sockets}--;
delete $procs{$socket};
}
}
$smbios{'Memory'}{'Count'} = 0;
sub parse_memory {
my($in, $section, $sub, $handle) = @_;
my($count) = $smbios{$section}{'Count'} + 1;
my($line);
my($ignore) = 0;
my($speed) = 0;
my($size) = 0;
my($manufacturer) = 0;
my($part) = 0;
my($type) = 0;
my($key);
if ($sub eq "Device") {
# override previous Module entries
if (!$smbios{$section}{$sub} && $count > 1) {
while ($count) {
delete $smbios{$section}{$count};
$count--;
}
$count = 1;
}
$smbios{$section}{$sub}++;
} elsif ($smbios{$section}{'Device'}) {
# ignore if we've already parsed Device entries
$ignore = 1;
}
while ($line = <$in>) {
$debug_dmidecode .= $line;
chomp($line);
$line =~ s/\s+$//;
last if ($line =~ /^(handle.*)?$/i);
$line =~ s/$clean_smbios_regex//i;
if ($handle) {
if ($line =~ /^\t(\S[^:]+):\s*(.*)/) {
$key = $1;
$dmi{$handle}{'key'}{$1} = $2;
} elsif ($line =~ /^\t\t(.*)/) {
$dmi{$handle}{'key'}{$key} .= "\t$1";
}
}
if ($line =~ /^\s*(current )?speed:\s+((\d+).*)/i) {
$speed = ($3 == 0 || $3 > 10000) ? 0 : $2;
$speed =~ s/\([\d\.]+ ns\)//;
$speed =~ s/\s+//g;
} elsif ($line =~ /^\s*(installed )?size:\s+([^\(]*)/i) {
$size = $2;
} elsif ($line =~ /^\s*(memory\s+)?type:\s+(.*)$/i) {
$type = $2;
$ignore = 1 if ($type eq "Flash");
} elsif ($line =~ /^\s*manufacturer:\s+(.*)$/i) {
$manufacturer = $1;
} elsif ($line =~ /^\s*part\s+number:\s+(.*)$/i) {
$part = canon_memory($1);
} elsif ($line =~ /^\s*form factor: (chip|tsop)/i) {
$ignore = 1;
}
}
if (!$ignore) {
$smbios{$section}{'Count'} = $count;
$smbios{$section}{$count}{'Speed'} = $speed;
$smbios{$section}{$count}{'Size'} = $size;
$smbios{$section}{$count}{'Type'} = $type;
$smbios{$section}{$count}{'Manufacturer'} = $manufacturer;
$smbios{$section}{$count}{'Part Number'} = $part;
}
}
sub parse_bios {
my($in, $section, $handle) = @_;
my($count) = ++$smbios{$section}{'Count'};
my($line);
my($key);
while ($line = <$in>) {
$debug_dmidecode .= $line;
chomp($line);
$line =~ s/\s+$//;
last if ($line =~ /^(handle.*)?$/i);
$line =~ s/$clean_smbios_regex//i;
if ($handle) {
if ($line =~ /^\t(\S[^:]+):\s*(.*)/) {
$key = $1;
$dmi{$handle}{'key'}{$1} = $2;
} elsif ($line =~ /^\t\t(.*)/) {
$dmi{$handle}{'key'}{$key} .= "\t$1";
}
}
if ($line =~ /^\s*vendor:\s+(\S+.*)$/i) {
$smbios{$section}{$count}{'Vendor'} = $1;
} elsif ($line =~ /^\s*version:\s+(\S+.*)$/i) {
my($version) = $1;
$version =~ s/BIOS Version(:)?\s+//i;
$version =~ s/\-\[(.*)\]\-/$1/;
$version =~ s/^'(.*)'$/$1/;
$version = clean_white($version);
if ($version =~ s/\s+(BIOS )?Date(:)?\s+(\S+.*)//i) {
$smbios{$section}{$count}{'Release Date'} = $3;
}
$smbios{$section}{$count}{'Version'} = $version;
} elsif ($line =~ /^\s*release date:\s+(\S+.*)$/i) {
$smbios{$section}{$count}{'Release Date'} = $1;
}
}
}
sub parse_system {
my($in, $section, $handle) = @_;
my($count) = ++$smbios{$section}{'Count'};
my($line);
my($key);
while ($line = <$in>) {
$debug_dmidecode .= $line;
chomp($line);
$line =~ s/\s+$//;
last if ($line =~ /^(handle.*)?$/i);
$line =~ s/$clean_smbios_regex//i;
if ($handle) {
if ($line =~ /^\t(\S[^:]+):\s*(.*)/) {
$key = $1;
$dmi{$handle}{'key'}{$1} = $2;
} elsif ($line =~ /^\t\t(.*)/) {
$dmi{$handle}{'key'}{$key} .= "\t$1";
}
}
if ($line =~ /^\s*product( name)?:\s+(.*)$/i) {
$smbios{$section}{$count}{'Product Name'} = $2;
} elsif ($line =~ /^\s*manufacturer:\s+(.*)$/i) {
$smbios{$section}{$count}{'Manufacturer'} = $1;
}
}
}
my(%interface_to_driver);
sub grok_network {
my($in) = "IFCONFIG";
my($line);
my($int);
open($in, "ifconfig -a |") || warn("exec: ifconfig: $!");
$debug_network .= ">> ifconfig -a\n";
if ($os_type eq "freebsd") {
while ($line = <$in>) {
$debug_network .= $line;
chomp($line);
if ($line =~ /^(\w+):/) {
$int = $1;
}
if ($line =~ /^\s*media:\s*(Ethernet)?\s*(.*)/) {
my($media) = $2;
$media =~ s/status.*//;
$media =~ s/autoselect//;
$media =~ s/[\(\)]//g;
$media =~ s/\s+/ /g;
$media =~ s/^\s+//;
$media =~ s/\s+$//;
$interfaces{$int}{media} = $media;
} elsif ($line =~ /^\s*ether\s*(\S*)/) {
$interfaces{$int}{mac} = $1;
}
if ($line =~ /\bstatus:\s*(.*)/) {
$interfaces{$int}{status} = $1;
}
}
} elsif ($os_type eq "linux") {
my($pci) = 0;
my($debug_network_2) = '';
while ($line = <$in>) {
$debug_network .= $line;
chomp($line);
if ($line =~ /^(\w+)\s+Link.*HWaddr\s+(\S+)/) {
$int = $1;
$interfaces{$int}{mac} = lc($2);
my($eth) = "ETHTOOL";
my($eline);
my($speed, $duplex) = ("", "");
open($eth, "$ethtool $int 2> /dev/null |") || warn("exec: $ethtool: $!");
$debug_network_2 .= ">> $ethtool $int\n";
while ($eline = <$eth>) {
$debug_network_2 .= $eline;
chomp($eline);
if ($eline =~ /Link detected:\s*(\S+)/) {
# 2.6 kernels only?
# comment out for now 20080201, found a case (mc1020.mail.re1, op951002.inktomisearch.com) running rhel4u6 that
# shows link detected when there is no link. ifconfig doesn't show RUNNING in this
# case, so maybe ifconfig is more accurate. if this is still commented out some
# months from now, this should all be nuked.
# $interfaces{$int}{status} = ($1 eq "yes") ? "active" : "no carrier";
# in order to keep output the same (i.e. no carrier when no link as root), set
# to no carrier as default and let ifconfig decide
$interfaces{$int}{status} = "no carrier" unless ($interfaces{$int}{status} && $interfaces{$int}{status} eq "active");
} elsif ($eline =~ /Speed:\s*(\S+)/) {
$speed = $1;
} elsif ($eline =~ /Duplex:\s*(\S+)/) {
$duplex = lc($1);
}
}
$interfaces{$int}{media} = $speed;
$interfaces{$int}{media} .= " <$duplex-duplex>" if ($duplex);
close($eth);
my($driver) = $int;
open($eth, "$ethtool -i $int 2> /dev/null |") || warn("exec: $ethtool: $!");
$debug_network_2 .= ">> $ethtool -i $int\n";
while ($eline = <$eth>) {
$debug_network_2 .= $eline;
chomp($eline);
if ($eline =~ /driver:\s+(\S+)/) {
$interface_to_driver{$int} = $1;
} elsif ($eline =~ /bus-info:\s+(\S+)/) {
$pci = $1;
}
}
close($eth);
if (!$pci) {
if (-l "/sys/class/net/$int/driver") {
$interface_to_driver{$int} = readlink("/sys/class/net/$int/driver");
$interface_to_driver{$int} =~ s/.*\///;
}
if (-l "/sys/class/net/$int/device") {
$pci = readlink("/sys/class/net/$int/device");
$pci =~ s/.*\///;
}
}
}
if (defined $int && $line =~ /RUNNING/) {
# needed for 2.4 kernels which don't have "Link detected" above
$interfaces{$int}{status} = "active";
}
if (!$pci && defined $int && $line =~ /Interrupt:(\d+)/i) {
$pci = $irq_to_pci{"$1,0x0200"} if ($irq_to_pci{"$1,0x0200"});
}
if (!$pci && defined $int && $line =~ /Memory:([0-9a-f]+)/i) {
$pci = $iomem_to_pci{$1} if ($iomem_to_pci{$1});
}
if ($line =~ /^\s*$/) {
if ($int) {
if (!$pci) {
if ($dmesg_buf =~ /\b$int:.*probe: addr 0x([0-9a-f]+)*/im) {
$pci = $iomem_to_pci{$1} if ($iomem_to_pci{$1});
}
}
if (!$interface_to_driver{$int}) {
if ($pci && $pci_to_driver{$pci}) {
$interface_to_driver{$int} = $pci_to_driver{$pci};
} elsif ($dmesg_buf =~ /^(\S+):.*\b$int:.*link is up/im) {
$interface_to_driver{$int} = $1;
}
}
if ($pci) {
$pci =~ s/^0000://;
if ($other_devices{'Network'}{$pci}) {
my($model) = $other_devices{'Network'}{$pci};
$model =~ s/^$pci: //;
$interfaces{$int}{'model'} = $model;
delete $other_devices{'Network'}{$pci};
}
}
}
undef $int;
$pci = 0;
}
}
$debug_network .= $debug_network_2;
}
close($in);
}
sub cpuinfo {
my($in) = 'CPUINFO';
my($line);
# prefer data from smbinfo if available
return unless (-r $cpuinfo);
my($family, $model, $stepping, $vendor_id, $model_name, $flags, $speed, $cores, $threads);
my(%physical_id, %core_id);
my($n) = 0;
open($in, "< $cpuinfo") || warn "open: $cpuinfo: $!";
while ($line = <$in>) {
$debug_cpuinfo .= $line;
chomp($line);
if ($line =~ /^cpu family\s*:\s*(\d+)/i) {
$family = $1;
} elsif ($line =~ /^model\s*:\s*(\d+)/i) {
$model = $1;
} elsif ($line =~ /^stepping\s*:\s*(\d+)/i) {
$stepping = $1;
} elsif ($line =~ /^vendor_id\s*:\s*(.*)/i) {
$vendor_id = $1;
} elsif ($line =~ /^model name\s*:\s*(.*)/i) {
$model_name = $1;
} elsif ($line =~ /^cpu MHz\s*:\s*(.*)/i) {
$speed = $1;
} elsif ($line =~ /^physical id\s*:\s*(.*)/i) {
$physical_id{$1}++;
} elsif ($line =~ /^core id\s*:\s*(.*)/i) {
$core_id{$1}++;
} elsif ($line =~ /^flags\s*:\s*(.*)/i) {
$flags = $1;
} elsif ($line =~ /^cpu cores\s*:\s*(.*)/i) {
$cores = $1;
} elsif ($line =~ /^\s*$/) {
if ($family && $model) {
$n++;
unless ($procs{$n}{cpuid}) {
if ($vendor_id =~ /AMD/i && $family >= 15) {
$procs{$n}{cpuid} = sprintf("%x", (($family - 15) << 20) | (($model >> 4) << 16) | (15 << 8) | (($model & 0xf) << 4) | $stepping);
} else {
$procs{$n}{cpuid} = sprintf("%x", ($family << 8) | ($model << 4) | $stepping);
}
}
$procs{$n}{vendor} = $vendor_id;
$procs{$n}{family} = $model_name;
$procs{$n}{speed} = $speed;
$procs{$n}{flags} = $flags;
# don't set {status} since we don't know if this is a socket
}
}
}
# $cpu_cores how many physical cores per socket for this particular cpuid, lookup table
# $cpu_threads how many logical cores per socket for this particular cpuid, lookup table
# $cores how many cores per chip does cpuinfo think
# $procs{threads} how many logical cores for overall system, kernel sees but may be disabled
# $procs{active_threads} how many logical cores for overall system that are enabled
# $procs{cores} how many physical cores for overall system, some may be disabled in bios/kernel
# $procs{active_cores} how many physical cores for overall system that are enabled
# $procs{sockets} how many sockets for overall system, might not be populated with chip
my($id) = cpuid($procs{1}{vendor}, hex($procs{1}{cpuid}));
my($cpu_info, $cpu_cores, $cpu_threads, $cpu_gen) = ('', 0, 0, 0);
if ($cpu_models{$id}) {
$model_name = canon_cpu_model($model_name);
if (ref($cpu_models{$id}[0]) eq "ARRAY") {
my($try);
foreach $try (@{$cpu_models{$id}}) {
($cpu_info, $cpu_cores, $cpu_threads, $cpu_gen) = @{$try->[1]};
last if ($model_name =~ /$try->[0]/i);
}
} else {
($cpu_info, $cpu_cores, $cpu_threads, $cpu_gen) = @{$cpu_models{$id}};
}
}
if ($cpu_cores) {
if ($cores && $cores != $cpu_cores) {
$debug .= sprintf("Debug-Cores:\t%d (cpuinfo) != %d (lookup)\n", $cores, $cpu_cores);
}
$cores = $cpu_cores;
}
if (!$cores) {
if ($model_name =~ /opteron/i && $flags =~ /\bht\b/i) {
# older kernels don't have the "cpu cores" field, so guess that ht == 2
$cores = 2;
}
}
my($htt) = 0;
if (defined $procs{1}{features}) {
my($features) = $procs{1}{features};
$htt = (hex($features) >> $feature_htt_bit) & 0x0001;
} else {
$htt = ($flags =~ /\bht\b/i);
}
if ($cpu_threads) {
# don't know of a way to actually test to see if hyperthreads are enabled.
# so this will be wrong if hyperthreading is disabled in bios, in particular
# this is a problem with old dl320 g2's that probably don't have bios support,
# so cpu is HT capable but no way for system to run in that mode. this one is
# easy to fix because cpu count is one. need to use dmidecode for this.
# well, at least on old kernels, some seem not to show HT in flags, which i
# guess means kernel doesn't support it. so let's at least get that case right.
# actually absense of HT does not imply kernel doesn't support it. e.g.
# tp-ms-db1.search.sp1 is running 2.4.21-32.ELsmp, supports HT but doesn't show in cpuinfo
if ($htt) {
$threads = $cpu_threads;
}
}
# $n is now number of threads
# this we're sure about, cpuinfo always gets this right
$procs{threads} = $n;
$procs{active_threads} = $n;
my(@keys) = keys %core_id;
if ($#keys > -1) {
$n = $#keys + 1;
} else {
if ($n > 1 && $threads) {
$n = $n / $threads;
}
}
# $n is now number of cores
$procs{cores} = $n;
$procs{active_cores} = $n;
if ($n > 1 && $cores) {
$n = $n / $cores;
}
# $n is now number of chips
@keys = keys %physical_id;
$procs{chips} = $#keys + 1;
}
sub mptutil {
my($result) = 0;
my($in) = 'MPT';
my($line);
my($dev);
my($adapter, @adapters);
my($vol);
system("which $mptutil > /dev/null 2>&1");
return $result if ($?);
$have_mptutil = 1;
$debug_storage .= ">> $mptutil\n";
open($in, "$mptutil show adapter 2> /dev/null |") || warn "exec $mptutil: $!";
$debug_storage .= ">>> $mptutil show adapter\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^(mpt(\d+))\s+Adapter/) {
$adapter = $2;
$dev = $1;
push(@adapters, $adapter);
$got_mptutil = 1;
$result = 1;
} elsif ($line =~ /^\s*battery backup: (.*)/i) {
$props{$dev}{'bbu'} = ($1 eq "present");
} elsif ($line =~ /^\s*onboard memory: (.*)/i) {
$props{$dev}{'cache-size'} = parse_bytes($1, 1024);
}
}
close($in);
open($in, "$mptutil show drives 2> /dev/null |") || warn "exec $mptutil: $!";
$debug_storage .= ">>> $mptutil show drives\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^(mpt\d+) physical drives:/i) {
$vol = "$1-spares";
} elsif ($line =~ /\b(SPARE|UNCONFIGURED)\b.*<([^>]+)>/) {
my($model) = canon_drive($2);
$props{$vol}{raid} = "JBOD";
$drives{$vol}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $vol;
$drive_id++;
$volumes{$vol}++;
$ndrives++;
}
}
close($in);
foreach $adapter (@adapters) {
my($array);
my(%array_to_vol);
my($dev) = "mpt$adapter";
open($in, "$mptutil -u $adapter show firmware 2> /dev/null |") || warn "exec $mptutil: $!";
$debug_storage .= ">>> $mptutil -u $adapter show firmware\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^BIOS\s+(\S+)/) {
$props{$dev}{'bios'} = $1;
} elsif ($line =~ /^APP\s+(\S+)/) {
$props{$dev}{'firmware'} = $1;
}
}
close($in);
open($in, "$mptutil -u $adapter show config 2> /dev/null |") || warn "exec $mptutil: $!";
$debug_storage .= ">>> $mptutil -u $adapter show config\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^\s*volume (da)?(\d+) \(([^\)]*)\) (\S+) (\S+) (\S+)/) {
$vol = "da$2";
delete $drives{$vol};
$props{$vol}{bytes} = parse_bytes($3, 1024);
$props{$vol}{raid} = $4;
my($stripe, $status) = ($5, $6);
if ($stripe =~ /^\d+/) {
$props{$vol}{stripe} = parse_bytes($stripe, 1024);
$props{$vol}{status} = parse_volume_status($status);
} else {
$props{$vol}{status} = parse_volume_status($stripe);
}
} elsif ($line =~ /^\s*dedicated spare/) {
$vol = '';
} elsif ($line =~ /^\s*array (\d+)\s*$/) {
if ($vol) {
$array_to_vol{$1} = $vol;
}
}
}
close($in);
open($in, "$mptutil -u $adapter show config 2> /dev/null |") || warn "exec $mptutil: $!";
while ($line = <$in>) {
chomp($line);
if ($line =~ /^\s*volume (da)?(\d+)/) {
$vol = "da$2";
} elsif ($line =~ /^\s*spare (\d+) \([^\)]*\) ([^<]+) <([^>]+)> (\S+)/) {
my($status) = $2;
my($model) = canon_drive($3) || "Unknown";
my($spares) = "$dev-spares";
$drives{$spares}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{interface} = $4;
$props{drives}{$drive_id}{volume} = $spares;
$drive_id++;
$volumes{$spares}++;
$props{$spares}{raid} = "JBOD";
$ndrives++;
if ($status ne "ONLINE") {
$props{$spares}{failed}++;
}
} elsif ($line =~ /^\s*drive (da)?(\d+) \([^\)]*\) ([^<]+) <([^>]+)> (\S+)/) {
my($status) = $3;
my($model) = canon_drive($4) || "Unknown";
if ($1) {
$vol = "da$2";
delete $drives{$vol}; # nuke camcontrol info
}
$drives{$vol}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{interface} = $5;
$props{drives}{$drive_id}{status} = parse_drive_status($status);
$props{drives}{$drive_id}{volume} = $vol;
$drive_id++;
$volumes{$vol}++;
$ndrives++;
if ($status eq "REBUILD") {
$props{$vol}{rebuild}++;
} elsif ($status eq "MISSING") {
$props{$vol}{missing}++;
} elsif ($status ne "ONLINE") {
# e.g. OFFLINE, FAILED
$props{$vol}{failed}++;
}
}
}
close($in);
}
}
sub mfiutil {
my($result) = 0;
my($in) = 'MFI';
my($line);
my($dev);
my($adapter, @adapters);
my($vol);
my($try);
# MegaCli docs at:
# http://www.lsilogic.com/files/docs/techdocs/storage_stand_prod/sas/mr_sas_sw_ug.pdf
system("which $mfiutil > /dev/null 2>&1");
return $result if ($?);
$have_mfiutil = 1;
$debug_storage .= ">> $mfiutil\n";
$try = 0;
while (1) {
open($in, "$mfiutil -u $try show adapter 2> /dev/null |") || warn "exec $mfiutil: $!";
$debug_storage .= ">>> $mfiutil -u $try show adapter\n";
my($found) = 0;
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^(mfi(\d+))\s+Adapter/) {
$adapter = $2;
$dev = $1;
push(@adapters, $adapter);
$got_mfiutil = 1;
$result = 1;
$found = 1;
} elsif ($line =~ /^\s*firmware: (.*)/i) {
$props{$dev}{'package'} = $1;
} elsif ($line =~ /^\s*battery backup: (.*)/i) {
$props{$dev}{'bbu'} = ($1 eq "present");
} elsif ($line =~ /^\s*onboard memory: (.*)/i) {
$props{$dev}{'cache-size'} = parse_bytes($1, 1024);
}
}
close($in);
last if !$found;
$try++;
}
foreach $adapter (@adapters) {
my($array);
my(%array_to_vol);
my($dev) = "mfi$adapter";
open($in, "$mfiutil -u $adapter show drives 2> /dev/null |") || warn "exec $mfiutil: $!";
$debug_storage .= ">>> $mfiutil -u $adapter show drives\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^(mfi\d+) physical drives:/i) {
$vol = "$1-spares";
} elsif ($line =~ /\b(SPARE|UNCONFIGURED)\b.*<([^>]+)>/) {
my($model) = canon_drive($2) || "Unknown";
$props{$vol}{raid} = "JBOD";
$drives{$vol}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $vol;
$drive_id++;
$volumes{$vol}++;
$ndrives++;
}
}
close($in);
open($in, "$mfiutil -u $adapter show firmware 2> /dev/null |") || warn "exec $mfiutil: $!";
$debug_storage .= ">>> $mfiutil -u $adapter show firmware\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^BIOS\s+(\S+)/) {
$props{$dev}{'bios'} = $1;
} elsif ($line =~ /^APP\s+(\S+)/) {
$props{$dev}{'firmware'} = $1;
}
}
close($in);
open($in, "$mfiutil -u $adapter show config 2> /dev/null |") || warn "exec $mfiutil: $!";
$debug_storage .= ">>> $mfiutil -u $adapter show config\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^\s*volume (mfid)?(\d+) \(([^\)]*)\) (\S+) (\S+) (\S+)/) {
$vol = "mfid$2";
delete $drives{$vol};
$props{$vol}{bytes} = parse_bytes($3, 1024);
$props{$vol}{raid} = $4;
my($stripe, $status) = ($5, $6);
if ($stripe =~ /^\d+/) {
$props{$vol}{stripe} = parse_bytes($stripe, 1024);
$props{$vol}{status} = parse_volume_status($status);
} else {
$props{$vol}{status} = parse_volume_status($stripe);
}
} elsif ($line =~ /^\s*dedicated spare/) {
$vol = '';
} elsif ($line =~ /^\s*array (\d+)\s*$/) {
if ($vol) {
$array_to_vol{$1} = $vol;
}
}
}
close($in);
open($in, "$mfiutil -u $adapter show config 2> /dev/null |") || warn "exec $mfiutil: $!";
while ($line = <$in>) {
chomp($line);
if ($line =~ /^\s*array (\d+) of (\d+) drives/) {
$array = $1;
$vol = $array_to_vol{$array};
} elsif ($line =~ /^\s*drive (\d+) \([^\)]*\) ([^<]+) <([^>]+)> (\S+)/) {
my($status) = $2;
my($model) = canon_drive($3) || "Unknown";
$drives{$vol}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{interface} = $4;
$props{drives}{$drive_id}{status} = parse_drive_status($status);
$props{drives}{$drive_id}{volume} = $vol;
$drive_id++;
$volumes{$vol}++;
$ndrives++;
if ($status eq "REBUILD") {
$props{$vol}{rebuild}++;
} elsif ($status eq "MISSING") {
$props{$vol}{missing}++;
} elsif ($status ne "ONLINE") {
# e.g. OFFLINE, FAILED
$props{$vol}{failed}++;
}
} elsif ($line =~ /^\s*volume/) {
last;
}
}
close($in);
}
}
sub omreport {
my($omreport) = 'omreport';
my($result) = 0;
my($line);
my($controller, %controllers);
my($device);
my(%seen);
my(%count);
return 1 if ($got_omreport);
system("which $omreport > /dev/null 2>&1");
return $result if ($?);
$have_omreport = 1;
$debug_storage .= ">> $omreport\n";
$count{'megaraid'} = 0;
$count{'megaraid_sas'} = 0;
open($in, "$omreport storage controller 2> /dev/null |") || warn "exec $omreport: $!";
$debug_storage .= ">>> $omreport storage controller\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^\s*$/) {
$device = "unknown";
} elsif ($line =~ /^ID\s*:\s*(\d+)\s*$/) {
$controller = $1;
$got_omreport = 1;
$result = 1;
} elsif ($line =~ /^Name\s*:\s*(.*)/) {
my($name) = $1;
if ($name =~ /PERC [34]/) {
$device = 'megaraid' . $count{'megaraid'}++;
$controllers{$controller} = $device;
} elsif ($name =~ /PERC/) {
$device = 'megaraid_sas' . $count{'megaraid_sas'}++;
$controllers{$controller} = $device;
}
} elsif ($line =~ /^Firmware Version\s*:\s*(.*)/) {
# don't use this if megarc already set firmware version
$props{$device}{'package'} = $1 unless ($props{$device}{'firmware'});
} elsif ($line =~ /^Cache Memory Size\s*:\s*(.*)/) {
$props{$device}{'cache-size'} = parse_bytes($1, 1024);
}
}
close($in);
foreach $controller (keys %controllers) {
$device = $controllers{$controller};
open($in, "$omreport storage battery controller=$controller 2> /dev/null |") || warn "exec $omreport: $!";
$debug_storage .= ">>> $omreport storage battery controller=$controller\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^Status\s*:\s*(\S+)/) {
$props{$device}{'bbu'} = ($1 eq "Ok");
}
}
close($in);
my($volume, $name, $raid, $bytes, $stripe, $virtual) = (0, 0, 0, 0, 0, 0);
my(%virtuals);
open($in, "$omreport storage vdisk controller=$controller 2> /dev/null |") || warn "exec $omreport: $!";
$debug_storage .= ">>> $omreport storage vdisk controller=$controller\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^ID\s*:\s*(\d+)/) {
$virtual = $1;
} elsif ($line =~ /^Layout\s*:\s*(\S+)/) {
$raid = canon_raid($1);
} elsif ($line =~ /^Name\s*:\s*(.*)/) {
$name = $1;
} elsif ($line =~ /^Size\s*:\s*.*\((\d+) bytes\)/) {
$bytes = $1;
} elsif ($line =~ /^Device Name\s*:\s*(\S+)/) {
$volume = $1;
$volume =~ s/^\/dev\///;
} elsif ($line =~ /^Stripe Element Size\s*:\s*(.*)/) {
$stripe = parse_bytes($1, 1024);
} elsif ($line =~ /^\s*$/) {
if ($name) {
$volume = "$device-l$virtual" unless $volume;
$virtuals{$virtual} = $volume;
$volumes{$volume}++;
$props{$volume}{bytes} = $bytes;
$props{$volume}{raid} = $raid;
$props{$volume}{stripe} = $stripe;
# remove info we got from /proc/scsi/scsi
delete $drives{$volume} unless $seen{$volume}++;
($volume, $name, $raid, $bytes, $stripe, $virtual) = (0, 0, 0, 0, 0, 0);
}
}
}
close($in);
foreach $virtual (keys %virtuals) {
$volume = $virtuals{$virtual};
my($have_size) = $props{$volume}{bytes};
my($state);
my($vendor, $model, $serial, $firmware, $year, $week, $day, $wwn) = ('', '', '', '', '', '', '', '');
open($in, "$omreport storage adisk controller=$controller vdisk=$virtual 2> /dev/null |") || warn "exec $omreport: $!";
$debug_storage .= ">>> $omreport storage adisk controller=$controller vdisk=$virtual\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^State\s*:\s*(.*)/) {
$state = $1;
$props{$volume}{failed}++ if ($1 ne 'Online');
} elsif ($line =~ /^Hot Spare\s*:\s*(.*)/) {
$props{$volume}{spare}++ if ($1 eq 'Yes');
} elsif ($line =~ /^Product ID\s*:\s*(.*)/) {
$model = $1;
} elsif ($line =~ /^Serial No\.\s*:\s*(.*)/) {
$serial = $1;
} elsif ($line =~ /^Revision\s*:\s*(.*)/) {
$firmware = $1;
} elsif ($line =~ /^Vendor ID\s*:\s*(.*)/) {
$vendor = $1;
} elsif ($line =~ /^Manufacture Day\s*:\s*(.*)/) {
$day = $1;
} elsif ($line =~ /^Manufacture Week\s*:\s*(.*)/) {
$week = $1;
} elsif ($line =~ /^Manufacture Year\s*:\s*(.*)/) {
$year = $1;
} elsif ($line =~ /^SAS Address\s*:\s*(.*)/) {
$wwn = $1;
} elsif ($line =~ /^Capacity\s*:\s*.*\((\d+) bytes\)/) {
$bytes = $1;
$props{$volume}{bytes} += $bytes unless ($have_size);
} elsif ($line =~ /^\s*$/) {
if ($model) {
$model = canon_drive("$vendor-$model");
$ndrives++;
$drives{$volume}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $volume;
$props{drives}{$drive_id}{serial} = $serial;
$props{drives}{$drive_id}{firmware} = $firmware;
$props{drives}{$drive_id}{wwn} = $wwn;
$props{drives}{$drive_id}{size} = $bytes;
$props{drives}{$drive_id}{date} = sprintf("%04d%02d%02d", $year, $week, $day) if ($year && $week && $day);
$drive_id++;
}
($model, $vendor) = ('', '');
}
}
close($in);
}
}
return $result;
}
sub arcconf {
my($result) = 0;
my($line);
my($controller, @controllers);
my($volume);
my(%mapping);
system("which $arcconf > /dev/null 2>&1");
return $result if ($?);
$have_arcconf = 1;
$debug_storage .= ">> $arcconf\n";
open($in, "$arcconf getversion 2> /dev/null |") || warn "exec $arcconf: $!";
$debug_storage .= ">>> $arcconf getversion\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^Controller #(\d+)/) {
push(@controllers, int($1));
$got_arcconf++;
$result++;
}
}
close($in);
foreach $controller (@controllers) {
open($in, "$arcconf getconfig $controller 2> /dev/null |") || warn "exec $arcconf: $!";
$debug_storage .= ">>> $arcconf getconfig $controller\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
last if ($line =~ /^Logical device information/);
}
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
last if ($line =~ /^Physical Device information/);
if ($line =~ /Logical device number (\d+)/) {
# hopefully gets overwritten by "logical device name"
$volume = "aac-c$controller-l$1";
} elsif ($line =~ /Logical device name.*: (.*)/) {
my($logical) = $1;
# if only one vol, map it
my(@keys) = keys %{$logical_to_os{'other'}};
if ($#keys == 0) {
$logical = $keys[0];
}
if ($logical_to_os{'other'}{$logical}) {
$volume = $logical_to_os{'other'}{$logical};
# remove info we got from /proc/scsi/scsi
delete $drives{$volume};
}
} elsif ($line =~ /RAID level.*: (.*)/) {
$props{$volume}{raid} = "RAID $1";
} elsif ($line =~ /Status of logical device.*: (.*)/) {
$props{$volume}{status} = parse_volume_status($1);
} elsif ($line =~ /Size.*: (.*)/) {
$props{$volume}{bytes} = parse_bytes($1, 1024);
} elsif ($line =~ /Stripe-unit size.*: (.*)/) {
$props{$volume}{stripe} = parse_bytes($1, 1024);
} elsif ($line =~ /Read-cache mode.*: (\S+)/) {
$props{$volume}{rcache_enable} = parse_enable($1);
} elsif ($line =~ /Write-cache mode.*: (\S+)/) {
$props{$volume}{wcache_enable} = parse_enable($1);
} elsif ($line =~ /Segment \d+.*: .*\((\d+),(\d+)\)/) {
my($channel, $device) = ($1, $2);
$mapping{"$channel,$device"} = $volume;
}
}
my($vendor, $model, $hide, $state, $channel);
my($id) = 0;
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^\s*Device is (.*)/) {
my($type) = $1;
if ($type =~ /Hard drive/) {
$hide = 0;
$id = $drive_id;
} else {
$hide = 1;
$id = 0;
}
} elsif ($line =~ /Channel #(\d+)/) {
$channel = $1;
} elsif ($line =~ /^\s*State\s+: (.*)/) {
$state = $1;
$props{drives}{$id}{status} = parse_drive_status($1);
} elsif ($line =~ /^\s*Reported Channel,Device\s+: (.*)/) {
if ($mapping{$1}) {
$volume = $mapping{$1};
} else {
$volume = "aac-c$controller-spares";
$props{$volume}{raid} = "JBOD";
}
} elsif ($line =~ /^\s*Firmware\s+: (.*)/) {
$props{drives}{$id}{firmware} = $1;
} elsif ($line =~ /^\s*Serial number\s+: (.*)/) {
$props{drives}{$id}{serial} = $1;
} elsif ($line =~ /^\s*Size\s+: (.*)/) {
$props{drives}{$id}{size} = parse_bytes($1, 1024);
} elsif ($line =~ /^\s*Write Cache\s+: (.*)/) {
$props{drives}{$id}{wcache_enable} = parse_enable($1);
} elsif ($line =~ /^\s*S\.M\.A\.R\.T\.\s+: (.*)/) {
$props{drives}{$id}{smart_enable} = parse_enable($1);
} elsif ($line =~ /^\s*Transfer Speed\s+: (.*)/) {
$props{drives}{$id}{speed} = parse_drive_speed($1);
} elsif ($line =~ /^\s*Vendor\s+: (.*)/) {
$vendor = $1;
} elsif ($line =~ /^\s*Model\s+: (.*)/) {
$model = canon_drive("$vendor$1");
if (!$hide) {
$ndrives++;
$drives{$volume}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $volume;
$drive_id++;
$volumes{$volume}++;
if ($state eq "Rebuilding") {
$props{$volume}{rebuild}++;
} elsif ($state ne "Online" && $state ne "Ready") {
$props{$volume}{failed}++;
}
}
}
}
close($in);
}
return $result;
}
sub megacli {
my($adapter, @adapters);
my($result) = 0;
my($line);
my($volume) = "NA";
my(%seen);
my($driver) = 'megaraid_sas';
# MegaCli docs at:
# http://www.lsilogic.com/files/docs/techdocs/storage_stand_prod/sas/mr_sas_sw_ug.pdf
my($megacli) = 'MegaCli';
system("which $megacli > /dev/null 2>&1");
if ($?) {
$megacli = 'MegaCli64';
system("which $megacli > /dev/null 2>&1");
if ($?) {
$megacli = 'megacli';
system("which $megacli > /dev/null 2>&1");
return $result if ($?);
}
}
$have_megacli = 1;
$debug_storage .= ">> $megacli\n";
open($in, "$megacli -AdpAllInfo -aAll 2> /dev/null |") || warn "exec $megacli: $!";
$debug_storage .= ">>> $megacli -AdpAllInfo -aAll\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^Adapter\s+\#(\d+)/) {
$adapter = int($1);
push(@adapters, $adapter);
$got_megacli = 1;
$result = 1;
} elsif ($line =~ /^FW Package Build\s*:\s+(\S+)/i) {
$props{"$driver$adapter"}{'package'} = $1;
} elsif ($line =~ /^FW Version\s*:\s+(\S+)/i) {
$props{"$driver$adapter"}{'firmware'} = $1;
} elsif ($line =~ /^BIOS Version\s*:\s+(\S+)/i) {
$props{"$driver$adapter"}{'bios'} = $1;
} elsif ($line =~ /^Serial No\s*:\s+(\S+)/i) {
$props{"$driver$adapter"}{'serial'} = $1;
}
}
close($in);
foreach $adapter (@adapters) {
# if only one volume, wiring is easy
my($default_volume) = '';
if (defined $controller_volumes{"$driver$adapter"}) {
my(@keys) = keys %{$controller_volumes{"$driver$adapter"}};
if ($#keys == 0) {
$default_volume = $keys[0];
delete $drives{$default_volume}; # nuke camcontrol info
}
}
my($state, $wwn, $raw) = ('', '');
open($in, "$megacli -cfgDsply -a$adapter 2> /dev/null |") || warn "exec $megacli: $!";
$debug_storage .= ">>> $megacli -cfgDsply -a$adapter\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^BBU: Present/i) {
$props{"$driver$adapter"}{'bbu'} = 1;
} elsif ($line =~ /^Memory: (.*)/i) {
$props{"$driver$adapter"}{'cache-size'} = parse_bytes($1, 1024);
} elsif ($line =~ /^DISK GROUPS: (\d+)/) {
$volume = "$driver$adapter-spares";
$props{$volume}{raid} = "JBOD";
$volume = ($default_volume || "$driver$adapter-vol$1");
# make some guesses here for linux on adapter, channel, lun
my($logical) = sprintf("scsi%d-%d-%d-%d", $adapter, 0, $1, 0);
if (defined $logical_to_os{'perc'}{$logical}) {
$volume = $logical_to_os{'perc'}{$logical};
# remove info we got from /proc/scsi/scsi
delete $drives{$volume} unless $seen{$volume}++;
} else {
# if only one vol, map it
my(@keys) = keys %{$logical_to_os{'perc'}};
if ($#keys == 0) {
$volume = $logical_to_os{'perc'}{$keys[0]};
# remove info we got from /proc/scsi/scsi
delete $drives{$volume} unless $seen{$volume}++;
}
}
$volumes{$volume}++;
} elsif ($line =~ /^RAID Level: Primary-(\d+)/) {
$props{$volume}{raid} = "RAID $1";
} elsif ($line =~ /^State:\s*(\S+)/) {
$props{$volume}{status} = parse_volume_status($1);
} elsif ($line =~ /^Size:\s*(\S+)/) {
$props{$volume}{bytes} = parse_bytes($1, 1024);
} elsif ($line =~ /^Raw Size:\s*(\S+)/) {
$raw = parse_bytes($1, 1024);
} elsif ($line =~ /^Stripe Size:\s*(\S+)/) {
$props{$volume}{stripe} = parse_bytes($1, 1024);
} elsif ($line =~ /^Firmware state:\s+(\S+)/) {
$state = $1;
} elsif ($line =~ /^SAS Address\(0\):\s*(\S+)/) {
$wwn = $1;
} elsif ($line =~ /^Inquiry Data:\s+(\S+)\s+(\S+)\s+(\S+)(\s+(\S+))?/) {
my($model, $serial);
if ($4) {
$model = canon_drive("$1-$2-$3");
$serial = $5;
} else {
$model = canon_drive("$1-$2");
$serial = $3;
}
$ndrives++;
$drives{$volume}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $volume;
$props{drives}{$drive_id}{serial} = $serial;
$props{drives}{$drive_id}{wwn} = $wwn;
$props{drives}{$drive_id}{size} = $raw;
$props{drives}{$drive_id}{status} = parse_drive_status($state);
$drive_id++;
$volumes{$volume}++;
if ($state eq "FAILED") {
$props{$volume}{failed}++;
}
}
}
close($in);
}
return $result;
}
sub megarc {
my(%megadrives);
my($adapter, @adapters);
my($result) = 0;
my($line);
my($volume) = "NA";
my(%seen);
my($driver) = ($os_type eq 'linux') ? 'megaraid' : 'amr';
system("which $megarc > /dev/null 2>&1");
return $result if ($?);
$have_megarc = 1;
$debug_storage .= ">> $megarc\n";
open($in, "$megarc -AllAdpInfo -noLog 2> /dev/null |") || warn "exec $megarc: $!";
$debug_storage .= ">>> $megarc -AllAdpInfo\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
last if ($line =~ /^\s*AdapterNo/);
}
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
$got_megarc = 1;
$result = 1;
if ($line =~ /^\s*(\d+)/) {
push(@adapters, int($1));
} else {
last;
}
}
close($in);
foreach $adapter (@adapters) {
unless ($os_type eq "freebsd" && $os_date < 20070130) {
# armd bug in early freebsd kernels causes data corruption for this query, so don't do it.
open($in, "$megarc -ctlrInfo -a$adapter -noLog 2> /dev/null |") || warn "exec $megarc: $!";
$debug_storage .= ">>> $megarc -ctlrInfo -a$adapter\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /Firmware Version : (\S+)/i) {
$props{"$driver$adapter"}{'firmware'} = $1;
}
if ($line =~ /BIOS Version : (\S+)/i) {
$props{"$driver$adapter"}{'bios'} = $1;
}
if ($line =~ /DRAM : (\S+)/i) {
$props{"$driver$adapter"}{'cache-size'} = parse_bytes($1, 1024);
}
}
close($in);
}
# if only one volume, wiring is easy
my($default_volume) = '';
if (defined $controller_volumes{"$driver$adapter"}) {
my(@keys) = keys %{$controller_volumes{"$driver$adapter"}};
if ($#keys == 0) {
$default_volume = $keys[0];
delete $drives{$default_volume}; # nuke camcontrol info
}
}
open($in, "$megarc -ldInfo -Lall -a$adapter -noLog 2> /dev/null |") || warn "exec $megarc: $!";
$debug_storage .= ">>> $megarc -ldInfo -Lall -a$adapter\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /Logical Drive\s*:\s*(\d+)\s*\(\s*Adapter:\s*(\d+)\s*\)/) {
$volume = "$driver$adapter-spares";
$props{$volume}{raid} = "JBOD";
$volume = ($default_volume || "$driver$adapter-vol$1");
# make some guesses here for linux on adapter, channel, lun
my($logical) = sprintf("scsi%d-%d-%d-%d", $adapter, 0, $1, 0);
if (defined $logical_to_os{'megaraid'}{$logical}) {
$volume = $logical_to_os{'megaraid'}{$logical};
# remove info we got from /proc/scsi/scsi
delete $drives{$volume} unless $seen{$volume}++;
} else {
# if only one vol, map it
my(@keys) = keys %{$logical_to_os{'megaraid'}};
if ($#keys == 0) {
$volume = $logical_to_os{'megaraid'}{$keys[0]};
# remove info we got from /proc/scsi/scsi
delete $drives{$volume} unless $seen{$volume}++;
}
}
$volumes{$volume}++;
}
if ($line =~ /RaidLevel\s*:\s*(\S+)/) {
$props{$volume}{raid} = "RAID $1";
}
if ($line =~ /StripSz\s*:\s*(\S+)/) {
$props{$volume}{stripe} = parse_bytes($1, 1024);
}
if ($line =~ /Cache\s*:\s*(\S+)/) {
$props{$volume}{cachepolicy} = $1; # CachedIO, DirectIO
}
if ($line =~ /WrPolicy\s*:\s*(\S+)/) {
$props{$volume}{wrpolicy} = $1; # WriteBack, ?
}
if ($line =~ /RdAhead\s*:\s*(\S+)/) {
$props{$volume}{rdahead} = $1; # Yes, No
}
if ($line =~ /^\s*(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s*$/) {
my($status) = $5;
my($drive) = sprintf("%d-%d-%d", $adapter, int($1), int($2));
$megadrives{$drive}{vol} = $volume;
if ($status eq "FAILED") {
$props{$volume}{failed}++;
} elsif ($status eq "RBLD") {
$props{$volume}{rebuild}++;
}
}
}
close($in);
open($in, "$megarc -phys -idAll -chAll -a$adapter -noLog 2> /dev/null |") || warn "exec $megarc: $!";
$debug_storage .= ">>> $megarc -phys -idAll -chAll -a$adapter\n";
my($type, $rev);
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^\s*Adapter\s+(\d+),\s+Channel\s+(\d+),\s+Target ID\s+(\d+)/) {
my($drive) = sprintf("%d-%d-%d", int($1), int($2), int($3));
$volume = $megadrives{$drive}{vol} || "$driver$adapter-spares";
}
if ($line =~ /Type\s*:\s+(\S+)/) {
$type = lc($1);
}
if ($line =~ /Revision\s*:\s*(\S+)/) {
$rev = $1;
}
if ($line =~ /Product\s*:\s+(\S+)/ && $type eq "disk") {
my($model) = canon_drive($1);
$ndrives++;
$drives{$volume}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $volume;
$props{drives}{$drive_id}{firmware} = $rev;
$drive_id++;
$volumes{$volume}++;
}
}
close($in);
}
return $result;
}
sub mptable {
my($in) = 'MPTABLE';
my($line);
my($result) = 0;
system("which $mptable > /dev/null 2>&1");
return $result if ($?);
open($in, "$mptable 2> /dev/null |") || warn "exec $mptable: $!";
while ($line = <$in>) {
last if ($line =~ /^Processors:/);
}
while ($line = <$in>) {
last if ($line =~ /^[-= ]*$/);
$result = 1;
$procs{mptable}++;
if (!$procs{$procs{mptable}}{cpuid}) {
my(@cols) = split(' ', $line);
my($family, $model, $step, $flags) = @cols[$#cols-3 .. $#cols];
if ($family == 6 && $model == 2 && $step == 1) {
# appears to be the only bug with mptable, otherwise seems reliable
# e.g. uds1.ads.cnb.yahoo.com, p24.chat.dcn.yahoo.com, mailsrv.bangalore.corp.yahoo.com
# and it's not just 6b1 that it gets wrong
# so ignore it here, hopefully get it from dmesg
} else {
$procs{$procs{mptable}}{cpuid} = sprintf("0x%x%x%x", $family, $model, $step);
}
$flags =~ s/^0x//;
$procs{$procs{mptable}}{features} = $flags;
}
}
close($in);
return $result;
}
sub twcli {
my($in) = 'TWCLI';
my($line);
my($controller, %controllers);
my(%units, %ports);
my($version) = 0;
my($result) = 0;
my(%seen);
system("which $twcli > /dev/null 2>&1");
return $result if ($?);
$have_twcli = 1;
$debug_storage .= ">> $twcli\n";
open($in, "$twcli info 2> /dev/null |") || warn "exec $twcli: $!";
$debug_storage .= ">>> $twcli info\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
last if ($line =~ /^---------/);
}
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
last if ($line =~ /^\s*$/);
if ($line =~ /^Controller\s+(\d+):\s+(\S+)/) {
$controllers{"c$1"} = $2;
$version = 1;
} elsif ($line =~ /^(c\d+)\s+(\S+)/) {
$controllers{$1} = $2;
$version = 2;
}
}
close($in);
foreach $controller (keys %controllers) {
my(%header);
$got_twcli++;
$result++;
open($in, "$twcli info $controller |") || warn "exec $twcli: $!";
$debug_storage .= ">>> $twcli info $controller\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
my(@cols) = split(' ', $line);
if ($line =~ /^Unit/) {
my($i);
for ($i=0; $i <= $#cols; $i++) {
$header{$cols[$i]} = $i;
}
} elsif ($line =~ /^u(\d+)/ || $line =~ /^\s*unit\s+(\d+)/i) {
my($unit) = "u$1";
my($volume);
my($type) = ($version == 1) ? $cols[2] : $cols[1];
my($size) = ($version == 1) ? "$cols[5] $cols[6]" : "$cols[$header{'Size(GB)'}] GB";
my($stripe) = parse_bytes(($version == 1) ? $cols[4] : $cols[$header{'Stripe'}], 1024);
if ($type eq "SPARE") {
$volume = "tw-$controller-spares";
$props{$volume}{raid} = "JBOD";
} else {
$volume = "$controller-$unit";
if (defined $logical_to_os{'tw'}{$volume}) {
$volume = $logical_to_os{'tw'}{$volume};
# remove info we got from /proc/scsi/scsi
delete $drives{$volume} unless $seen{$volume}++;
} else {
# if only one vol, map it
my(@keys) = keys %{$logical_to_os{'tw'}};
if ($#keys == 0) {
$volume = $logical_to_os{'tw'}{$keys[0]};
# remove info we got from /proc/scsi/scsi
delete $drives{$volume} unless $seen{$volume}++;
}
}
$props{$volume}{raid} = $type;
$props{$volume}{bytes} = parse_bytes($size, 1024);
}
$props{$volume}{stripe} = $stripe;
$volumes{$volume}++;
$units{$unit}{volume} = $volume;
# update 3ware controller model if we have enough data
my($device) = $props{$volume}{device};
if ($controllers{$controller} && $device) {
if (defined $other_devices{'Disk-Control'}{$device}) {
$other_devices{'Disk-Control'}{$device} =~ s/(7xxx\/8xxx|9xxx)/$controllers{$controller}/;
}
}
} elsif ($line =~ /^p(\d+)/ || $line =~ /^\s*port\s+(\d+)/i) {
my($port) = "p$1";
my($unit) = "unknown";
next if ($line =~ /NOT.PRESENT/);
if ($version == 1) {
if ($line =~ /unit\s+(\d+)/i) {
$unit = "u$1";
} elsif ($line =~ /\(NO UNIT\)/) {
$unit = "free";
}
} else {
$unit = $cols[2];
}
my($volume);
if (defined($units{$unit}) && $units{$unit}{volume}) {
$volume = $units{$unit}{volume};
} else {
if ($unit eq "-") {
$volume = "tw-$controller-free";
} else {
$volume = "tw-$controller-$unit";
}
$volumes{$volume}++;
$props{$volume}{raid} = "JBOD";
}
$props{$volume}{failed}++ if ($line =~ /DEGRADED/);
$ports{$controller}{$port} = $volume;
}
}
close($in);
if ($version == 1) {
my($unit);
foreach $unit (keys %units) {
my($volume) = $units{$unit}{volume};
open($in, "$twcli info $controller $unit |") || warn "exec $twcli: $!";
$debug_storage .= ">>> $twcli info $controller $unit\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^Unit Type:\s+(.*)/) {
$props{$volume}{raid} = $1;
} elsif ($line =~ /^Size:.*\((\d+)\s+blocks\)/) {
$props{$volume}{bytes} = $1 * 512;
} elsif ($line =~ /^Stripe Size:\s*(\S+)/) {
$props{$volume}{stripe} = parse_bytes($1, 1024);
}
}
close($in);
}
}
my($port);
foreach $port (keys %{$ports{$controller}}) {
open($in, "$twcli info $controller $port model |") || warn "exec $twcli: $!";
$debug_storage .= ">>> $twcli info $controller $port model\n";
$line = <$in>;
$debug_storage .= $line;
chomp($line);
$line =~ s/^.*model\s*=\s*//i;
my($model) = canon_drive($line);
my($volume) = $ports{$controller}{$port};
$drives{$volume}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $volume;
$drive_id++;
close($in);
}
}
return $result;
}
sub smbinfo {
my($in) = "IN";
my($line);
my($result) = 0;
# smbinfo obsoletes smbiosinfo
system("which $smbinfo > /dev/null 2>&1");
if ($?) {
system("which $smbiosinfo > /dev/null 2>&1");
return $result if ($?);
open($in, "$smbiosinfo -l 2> /dev/null |") || warn "exec $smbiosinfo: $!";
} elsif (-t STDIN) {
open($in, "$smbinfo -l 2> /dev/null |") || warn "exec $smbinfo: $!";
} else {
# older versions of smbinfo don't work when stdin is not a tty, e.g. from cron
# closing stdin works for some older versions, however ancient versions will stil break
open($in, "$smbinfo -l <&- 2> /dev/null |") || warn "exec $smbinfo: $!";
}
if (!eof($in)) {
$line = <$in>;
$result = 1;
my($comp);
if ($line =~ /^SMBIOS version/) {
$line = <$in>;
while (!eof($in)) {
$debug_dmidecode .= $line;
if ($line =~ /^(\S.*):/) {
$comp = $1;
parse_bios($in, 'BIOS', 0) if ($comp eq "BIOS Information");
parse_system($in, 'Base Board', 0) if ($comp eq "Base Board Information");
parse_system($in, 'System', 0) if ($comp eq "System Information");
parse_proc($in, 'Processor', 0) if ($comp eq "Processor Information");
parse_memory($in, 'Memory', 'Device', 0) if ($comp eq "Memory Device");
}
$line = <$in>;
}
} else {
while (!eof($in)) {
$debug_dmidecode .= $line;
if ($line =~ /^\[\S+\s+([^\]]+)\]/) {
$comp = $1;
parse_bios($in, 'BIOS', 0) if ($comp eq "BIOS");
parse_system($in, 'Base Board', 0) if ($comp eq "Base Board");
parse_system($in, 'System', 0) if ($comp eq "System");
parse_proc($in, 'Processor', 0) if ($comp eq "Processor");
parse_memory($in, 'Memory', 'Device', 0) if ($comp eq "Memory Device");
}
$line = <$in>;
}
}
}
return $result;
}
sub dmidecode {
my($in) = 'DMIDECODE';
my($line);
my($result) = 0;
my($version) = 0;
my($section, $count, $attribute, $value, $sep);
my($handle) = 0;
my($type) = 0;
my($key);
system("which $dmidecode > /dev/null 2>&1");
return $result if ($?);
open($in, "$dmidecode 2> /dev/null |") || warn("exec $dmidecode: $!");
while ($line = <$in>) {
$debug_dmidecode .= $line;
$line =~ s/\s+$//;
if ($handle) {
if ($line =~ /^(\S+.*)/) {
$dmi{$handle}{'name'} = $1;
} elsif ($line =~ /^\t(\S[^:]+):\s*(.*)/) {
$key = $1;
$dmi{$handle}{'key'}{$1} = $2;
} elsif ($line =~ /^\t\t(.*)/) {
$dmi{$handle}{'key'}{$key} .= "\t$1";
}
}
if ($line =~ /^Handle (\S+), DMI type (\d+)/) {
$handle = $1;
$type = $2;
$dmi{$handle}{'type'} = $type;
$version = 1;
} elsif ($line =~ /^\t?(System|Base Board)( Information)?( Block)?$/) {
$result = 1;
parse_system($in, $1, $handle);
$handle = 0;
} elsif ($line =~ /^\t?(BIOS)( Information)( Block)?$/) {
parse_bios($in, $1, $handle);
$handle = 0;
} elsif ($line =~ /^\t?(Memory) (Device|Module Information)$/) {
parse_memory($in, $1, $2, $handle);
$handle = 0;
} elsif ($line =~ /^\t?(Processor)( Information)?$/) {
parse_proc($in, $1, $handle);
$handle = 0;
} elsif ($line =~ /^checksum failed/) {
last;
} elsif ($line =~ /^\s*$/) {
$handle = 0;
}
}
close($in);
return $result;
}
sub hpacucli {
my($in) = 'HPACUCLI';
my($line);
my($slot, %slots, %logicals, %physicals, %arrays);
system("which $hpacucli > /dev/null 2>&1");
return if ($?);
$have_hpacucli = 1;
return if system("$hpacucli version > /dev/null 2>&1");
$debug_storage .= ">> $hpacucli\n";
open($in, "$hpacucli controller all show 2> /dev/null |") || warn "exec $hpacucli: $!";
$debug_storage .= ">>> $hpacucli controller all show\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /in\s+slot\s+(\d+)/i) {
$slots{$1}++;
$got_hpacucli = 1;
}
}
close($in);
my($count) = 0;
foreach $slot (keys %slots) {
my($dev) = "cciss$count";
my($total_cache_size) = 0;
my($ratio) = 0;
open($in, "$hpacucli controller slot=$slot show |") || warn "exec $hpacucli: $!";
$debug_storage .= ">>> $hpacucli controller slot=$slot show\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^\s*Read Cache Size: (.*)/i) {
$props{$dev}{'cache-read'} = parse_bytes($1, 1024);
} elsif ($line =~ /^\s*Write Cache Size: (.*)/i) {
$props{$dev}{'cache-write'} = parse_bytes($1, 1024);
} elsif ($line =~ /^\s*Total Cache Size: (.*)/i) {
$total_cache_size = parse_bytes($1, 1024);
} elsif ($line =~ /^\s*Accelerator Ratio: (\d+)/i) {
$ratio = $1;
} elsif ($line =~ /^\s*Battery Pack Count: (\d+)/i) {
$props{$dev}{'BBU'} = 1 if ($1);
} elsif ($line =~ /^\s*Firmware Version: (.*)/i) {
$props{$dev}{'firmware'} = $1;
} elsif ($line =~ /^\s*Hardware Revision: (.*)/i) {
$props{$dev}{'revision'} = $1;
} elsif ($line =~ /^\s*Serial Number: (.*)/i) {
$props{$dev}{'serial'} = $1;
} elsif ($line =~ /^\s*Cache Status: (.*)/i) {
$props{$dev}{'cache-status'} = ($1 eq 'OK') ? 'on' : 'off';
}
}
close($in);
if ($total_cache_size) {
$props{$dev}{'cache-read'} = ($ratio / 100) * $total_cache_size;
$props{$dev}{'cache-write'} = ((100 - $ratio) / 100) * $total_cache_size;
}
my(%ids, $id);
my($array) = "NA";
open($in, "$hpacucli controller slot=$slot logicaldrive all show |") || warn "exec $hpacucli: $!";
$debug_storage .= ">>> $hpacucli controller slot=$slot logicaldrive all show\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /array\s+(\S+)/i) {
$array = $1;
} elsif ($line =~ /logicaldrive\s+(\d+)\s+\(([^,]*),([^,]*)/) {
$ids{$1} = $array;
}
}
close($in);
foreach $id (keys %ids) {
my($volume, $array, $raid, $size, $stripe, $cache_enable, $status, $uid) = ("ciss-s$slot-$ids{$id}-l$id", $ids{$id}, 0, 0, 0, 'NA', '');
open($in, "$hpacucli controller slot=$slot logicaldrive $id show |") || warn "exec $hpacucli: $!";
$debug_storage .= ">>> $hpacucli controller slot=$slot logicaldrive $id show\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^\s*array\s+(\S+)/) {
$array = $1;
} elsif ($line =~ /^\s*Size:\s+(.*)/) {
$size = parse_bytes($1, 1024);
} elsif ($line =~ /^\s*Fault Tolerance:\s+(.*)/) {
$raid = canon_raid("RAID $1");
} elsif ($line =~ /^\s*Array Accelerator:\s+(.*)/) {
$cache_enable = parse_enable($1);
} elsif ($line =~ /^\s*Stripe Size:\s+(.*)/) {
$stripe = parse_bytes($1, 1024);
} elsif ($line =~ /^\s*Status:\s+(.*)/) {
$status = parse_volume_status($1);
} elsif ($line =~ /^\s*UID:\s+(.*)/) {
$uid = $1;
} elsif ($line =~ /^\s*Disk Name:\s+(\S+)/) {
if ($1 ne 'Unknown') {
$volume = $1;
$volume =~ s/^\/dev\///;
}
}
}
close($in);
$volumes{$volume}++;
$logicals{$slot}{$array}{$id} = $volume;
$props{$volume}{bytes} = $size if ($size);
$props{$volume}{raid} = $raid if ($raid);
$props{$volume}{stripe} = $stripe if ($stripe);
$props{$volume}{status} = $status if ($status);
$props{$volume}{cache_enable} = $cache_enable;
$props{$volume}{uid} = $uid;
$arrays{$slot}{$array}++;
}
$array = "NA";
open($in, "$hpacucli controller slot=$slot physicaldrive all show |") || warn "exec $hpacucli: $!";
$debug_storage .= ">>> $hpacucli controller slot=$slot physicaldrive all show\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /array\s+(\S+)/i) {
$array = $1;
} elsif ($line =~ /physicaldrive\s+(\S+)/) {
$physicals{$slot}{$array}{$1}++;
}
}
close($in);
foreach $array (keys %{$arrays{$slot}}) {
my($volume);
my(@keys) = keys %{$logicals{$slot}{$array}};
if ($#keys == 0) {
# if only one logical in the array, then logical == array
# so set the volume to the logical, otherwise we'll have an anonymous array volume
$volume = $logicals{$slot}{$array}{$keys[0]};
} else {
# create anonymoums array volume
$volume = "ciss-s$slot-$array";
$volumes{$volume}++;
$props{$volume}{raid} = "JBOD";
$props{$volume}{bytes} = 0;
}
my($have_size) = $props{$volume}{bytes};
my($drive);
foreach $drive (keys %{$physicals{$slot}{$array}}) {
my($size, $rpm, $speed, $interface, $status, $firmware, $serial) = (0, "", "", "", "", "", "");
my($model) = "unknown";
open($in, "$hpacucli controller slot=$slot physicaldrive $drive show |") || warn "exec $hpacucli: $!";
$debug_storage .= ">>> $hpacucli controller slot=$slot physicaldrive $drive show\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /Size:\s+(.*)/i) {
$size = parse_bytes($1, 1000);
} elsif ($line =~ /Rotational Speed:\s+(.*)/i) {
$rpm = parse_rpm($1);
} elsif ($line =~ /Transfer Speed:\s+(.*)/i) {
$speed = parse_drive_speed($1);
} elsif ($line =~ /Status:\s+(.*)/i) {
$status = parse_drive_status($1);
} elsif ($line =~ /Interface Type:\s+(.*)/i) {
$interface = parse_drive_interface($1);
} elsif ($line =~ /Serial Number:\s+(.*)/i) {
$serial = $1;
} elsif ($line =~ /Firmware Revision:\s+(.*)/i) {
$firmware = $1;
} elsif ($line =~ /Model:\s+(.*)/i) {
$model = canon_drive($1);
}
}
close($in);
if ($status eq "Failed") {
$props{$volume}{failed}++;
}
if ($model eq "unknown") {
$model = "Unknown";
$model .= " " . print_bytes($size, 1000, 0) if ($size);
$model .= " $rpm" if ($rpm);
$model .= " $interface" if ($interface);
$model .= " $speed" if ($speed);
}
$drives{$volume}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $volume;
$props{drives}{$drive_id}{firmware} = $firmware if ($firmware);
$props{drives}{$drive_id}{serial} = $serial if ($serial);
$props{drives}{$drive_id}{rpm} = $rpm if ($rpm);
$props{drives}{$drive_id}{size} = $size if ($size);
$props{drives}{$drive_id}{speed} = $speed if ($speed);
$props{drives}{$drive_id}{interface} = $interface if ($interface);
$props{drives}{$drive_id}{status} = $status if ($status);
$drive_id++;
$props{$volume}{bytes} += $size unless ($have_size);
}
}
$count++;
}
}
sub cissutil {
my(%cissdrives);
my($device, $dev);
my(%failed);
system("which $cissutil > /dev/null 2>&1");
return if ($?);
$have_cissutil = 1;
$debug_storage .= ">> $cissutil\n";
foreach $device (split(' ', `/bin/ls /dev/ciss[0-9]* 2> /dev/null`)) {
$dev = $device;
$dev =~ s,^/dev/ciss,,;
my($volume) = "NA";
my(@controllers);
my($controller) = 0;
# if only one volume, wiring is easy
my($default_volume) = '';
if (defined $controller_volumes{"ciss$dev"}) {
my(@keys) = keys %{$controller_volumes{"ciss$dev"}};
if ($#keys == 0) {
$default_volume = $keys[0];
delete $drives{$default_volume}; # nuke camcontrol info
}
}
open($in, "$cissutil -c $device -d 2> /dev/null |") || warn "exec on \"$cissutil -c $device -d\" failed";
$debug_storage .= ">>> $cissutil -c $device -d\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^controller\s+(\d+)\s*(\((.*)\))?/) {
$controller = $1;
my($type) = $3;
if ($type && !$other_devices{"Disk-Control"}{"ciss$dev"}) {
$type =~ s/\s+/ /g;
$type =~ s/^\s*//;
$type =~ s/\s*$//;
$other_devices{"Disk-Control"}{"ciss$dev"} = "ciss$dev: $type";
}
} elsif ($line =~ /^running firmware\s+([\d\.]+)/i) {
$props{"ciss$dev"}{"firmware"} = $1;
} elsif ($line =~ /^cache is:\s+(.*)/i) {
$props{"ciss$dev"}{'cache-status'} = ($1 =~ /enable/i) ? 'on' : 'off';
} elsif ($line =~ /^write cache size = (.*)/i) {
$props{"ciss$dev"}{'cache-write'} = parse_bytes($1, 1024);
} elsif ($line =~ /^read cache size = (.*)/i) {
$props{"ciss$dev"}{'cache-read'} = parse_bytes($1, 1024);
} elsif ($line =~ /^logical drives:\s+(\d+)/) {
push(@controllers, $controller);
} elsif ($line =~ /^(da\d+)\s*$/) {
$volume = $1;
delete $drives{$volume}; # nuke camcontrol info
$volumes{$volume}++;
} elsif ($line =~ /^vol(\d+)\s*$/) {
$volume = ($default_volume || "ciss$dev-c$controller-l$1");
$volumes{$volume}++;
} elsif ($line =~ /^(vol(\d+))?\s+blocks\s+available\s+(\S+)/) {
$volume = ($default_volume || "ciss$dev-c$controller-l$2") if $1;
$volumes{$volume}++;
$props{$volume}{bytes} = $3 * 512;
} elsif ($line =~ /^(vol(\d+))?\s+fault\s+tolerance\s+(\S+)/) {
$volume = ($default_volume || "ciss$dev-c$controller-l$2") if $1;
$props{$volume}{raid} = $3;
} elsif ($line =~ /^(vol(\d+))?\s+status\s+(.*)/) {
$volume = ($default_volume || "ciss$dev-c$controller-l$2") if $1;
$props{$volume}{status} = parse_volume_status($3);
} elsif ($line =~ /^(vol(\d+))?\s+stripe\s+size\s+(\S+)/) {
$volume = ($default_volume || "ciss$dev-c$controller-l$2") if $1;
$props{$volume}{stripe} = parse_bytes($3, 1024);
} elsif ($line =~ /^(vol(\d+))?\s+failed\s+drives\s+\(([^\)]+)\)/) {
$volume = ($default_volume || "ciss$dev-c$controller-l$2") if $1;
my($failed) = $3;
$failed =~ s/\bnone\b//g;
my(@failed) = split(/,/, $failed);
$props{$volume}{failed} = $#failed + 1;
%failed = map { $_ => 1 } @failed;
} elsif ($line =~ /^vol(\d+)\s+.*\s+(drives|spares)\s+\(([^\)]+)\)/) {
$volume = ($default_volume || "ciss$dev-c$controller-l$1");
my($drive);
foreach $drive (split(/,/, $3)) {
$cissdrives{"$dev-$controller-$drive"} = $volume;
}
}
}
close($in);
foreach $controller (@controllers) {
my($id) = 0;
$volume = "ciss$dev-c$controller-NA";
open($in, "$cissutil -c $device --controller $controller --drives 2> /dev/null |") || warn "exec on $cissutil failed";
$debug_storage .= ">>> $cissutil -c $device --controller $controller --drives\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
$got_cissutil = 1;
if ($line =~ /^\((b\d+t\d+) -> (da\d+)/) {
$volume = $2;
$ndrives++;
$id = $drive_id++;
$props{drives}{$id}{status} = parse_drive_status("failed") if ($failed{$1});
} elsif ($line =~ /^\(b\d+t\d+ -> free/) {
$volume = "ciss$dev-c$controller-NA";
$volumes{$volume}++;
$ndrives++;
$id = $drive_id++;
} elsif ($line =~ /^\((b(\d+)t(\d+))\)/) {
my($full, $bus, $target) = ($1, $2, $3);
if ($cissdrives{"$dev-$controller-$full"}) {
$volume = $cissdrives{"$dev-$controller-$full"};
} else {
$volume = "ciss$dev-c$controller-NA";
$volumes{$volume}++;
}
$ndrives++;
$id = $drive_id++;
} elsif ($line =~ /^\(b\d+t\d+ -> vol(\d+)/) {
$volume = ($default_volume || "ciss$dev-c$controller-l$1");
$ndrives++;
$id = $drive_id++;
} elsif ($line =~ /^\s+model\s+(.*)/) {
my(@model) = split(' ', $1);
my($model);
if ($model[0] eq "Unknown" || $model[0] eq "ATA") {
$model = canon_drive("$model[1],$model[2]");
$props{drives}{$id}{serial} = $model[3];
$props{drives}{$id}{firmware} = $model[4];
} else {
$model = canon_drive("$model[0],$model[1]");
$props{drives}{$id}{serial} = $model[2];
$props{drives}{$id}{firmware} = $model[3];
}
$drives{$volume}{$id}++;
$props{drives}{$id}{model} = $model;
$props{drives}{$id}{volume} = $volume;
} elsif ($line =~ /^\s+configured:\s+(\d+)/) {
$props{$volume}{free}++ unless ($1);
} elsif ($line =~ /^\s+configured_spare:\s+(\d+)/) {
$props{$volume}{spare}++ if ($1);
} elsif ($line =~ /^\s+cache_currently_enabled:\s+(\d+)/) {
$props{drives}{$id}{wcache_enable} = $1;
} elsif ($line =~ /^\s+rpm:\s+(\d+)/) {
$props{drives}{$id}{rpm} = $1;
} elsif ($line =~ /^\s+size\s+(.*)/) {
$props{drives}{$id}{size} = parse_bytes($1, 1024);
} elsif ($line =~ /^\s+SMART:\s+(.*)/) {
$props{drives}{$id}{smart_support} = parse_enable($1);
} elsif ($line =~ /^\s+SMART_errors_enabled:\s+(.*)/) {
$props{drives}{$id}{smart_enable} = parse_enable($1);
} elsif ($line =~ /^\s+drive_present:\s+(.*)/) {
if ($1) {
$props{drives}{$id}{status} = parse_drive_status("online") unless (defined($props{drives}{$id}{status}));
} else {
$props{drives}{$id}{status} = parse_drive_status("offline");
}
}
}
close($in);
}
}
}
sub camcontrol {
my($dev);
system("which $camcontrol > /dev/null 2>&1");
return if ($?);
open($in, "$camcontrol devlist -v 2> /dev/null |") || warn "exec $camcontrol: $!";
$debug_storage .= ">> $camcontrol devlist -v\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /^\<(\S+)\s+(\S+)/) {
if ($1 eq "COMPAQ") {
$want_cissutil++;
} elsif ($1 eq "PE/PV") {
$want_megarc++;
}
}
if ($line =~ /^scbus[-\d]+\s+on\s+(\S+)\s+bus\s+\d+/) {
$dev = $1;
}
if ($line =~ /\b(da\d+)\b/) {
my($volume) = $1;
if ($line =~ /^\<([^>]*)/) {
my($id) = canon_drive($1);
$ndrives++;
$volumes{$volume}++;
$drives{$volume}{$drive_id}++;
$props{drives}{$drive_id}{model} = $id;
$props{drives}{$drive_id}{volume} = $volume;
$drive_id++;
if ($dev) {
$props{$volume}{device} = $dev;
$controller_volumes{$dev}{$volume}++;
}
if ($line =~ /(raid\s*\S+)/i) {
$props{$volume}{raid} = $1;
} else {
$props{$volume}{raid} = "JBOD";
}
if ($dmesg_buf =~ /^$volume:.*?(\d+) (512 byte )?sectors/m) {
$props{$volume}{bytes} = $1 * 512;
}
}
}
}
close($in);
}
sub grok_sysctl_dev {
my($in) = 'IN';
my($line);
my($dev, $key, $val);
open($in, "sysctl dev |") || warn("sysctl: $!");
while ($line = <$in>) {
$debug_sysctl_dev .= $line;
chomp($line);
if ($line =~ /^dev\.([^\.]+)\.(\d+)\.\%?([^\:]+)\:\s+(.*)/) {
($dev, $key, $val) = ($1 . $2, $3, $4);
$sysctl_dev{$dev}{$key} = $val;
}
}
foreach $dev (keys %sysctl_dev) {
my($model) = $sysctl_dev{$dev}{desc};
$model =~ s/\(R\)//g if $model;
if ($dev =~ /^(atapci|mfi|mpt|ahc|ahd|asr|aac|aacch|sym|ida|ciss|amr)\d+$/) {
$model =~ s/\s+controller\b.*//i;
$other_devices{'Disk-Control'}{$dev} = "$dev: $model";
$sysctl_dev{$dev}{'xmodel'} = $model;
} elsif ($dev =~ /^(ata|amrd|mfid)\d+$/) {
$props{$dev}{device} = $sysctl_dev{$dev}{parent};
} elsif ($dev =~ /^($freebsd_net_devs)\d+$/) {
if ($1 eq "msk") {
$interface_to_driver{$dev} = $sysctl_dev{$dev}{parent};
}
$model =~ s/\s*(Ethernet|Network|,).*//;
$interfaces{$dev}{'model'} = $model;
$sysctl_dev{$dev}{'xmodel'} = $model;
} else {
$sysctl_dev{$dev}{'xmodel'} = $model;
}
}
}
sub parse_protocol {
my($proto) = @_;
my($result);
if ($proto eq "Serial ATA v1.0" || $proto eq "SATA-I signaling") {
$result = "SATA-1.0";
} elsif ($proto eq "Serial ATA II" || $proto eq "SATA-II signaling") {
$result = "SATA-2.0";
} elsif ($proto =~ /ATA\/ATAPI revision\s+(\d+)/i) {
$result = "ATA-$1";
} else {
$result = $proto;
$result =~ s/ATA\/ATAPI/ATA/;
}
return $result;
}
sub atacontrol {
my($in, $id, $disk) = @_;
my($line);
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /device (ad\d+):/) {
$disk = $1;
} elsif ($line =~ /^device model\s+(.*)/) {
my($model) = canon_drive($1);
$ndrives++;
$volumes{$disk}++;
$drives{$disk}{$id}++;
$props{drives}{$id}{model} = $model;
$props{drives}{$id}{volume} = $disk;
$drive_id++;
$props{$disk}{raid} = "JBOD";
} elsif ($line =~ /^lba(48)? (not )?supported\s+(\d+) sectors/) {
my($size) = $3 * 512;
$props{drives}{$id}{size} = $size;
if (!$props{$disk}{bytes} || $size > $props{$disk}{bytes}) {
$props{$disk}{bytes} = $size;
}
} elsif ($line =~ /^Protocol\s+(.*)/) {
$props{drives}{$id}{interface} = parse_protocol($1);
} elsif ($line =~ /^(ATA\/ATAPI revision\s*\d+)/) {
$props{drives}{$id}{interface} = parse_protocol($1);
} elsif ($line =~ /^serial number\s+(.*)/) {
$props{drives}{$id}{serial} = $1;
} elsif ($line =~ /^firmware revision\s+(.*)/) {
$props{drives}{$id}{firmware} = $1;
} elsif ($line =~ /^read ahead\s+(\S+)\s+(\S+)/) {
$props{drives}{$id}{readahead_support} = parse_enable($1);
$props{drives}{$id}{readahead_enable} = parse_enable($2);
} elsif ($line =~ /^write cache\s+(\S+)\s+(\S+)/) {
$props{drives}{$id}{wcache_support} = parse_enable($1);
$props{drives}{$id}{wcache_enable} = parse_enable($2);
} elsif ($line =~ /^SMART\s+(\S+)\s+(\S+)/) {
$props{drives}{$id}{smart_support} = parse_enable($1);
$props{drives}{$id}{smart_enable} = parse_enable($2);
} elsif ($line =~ /^power management\s+(\S+)\s+(\S+)/) {
$props{drives}{$id}{pm_support} = parse_enable($1);
$props{drives}{$id}{pm_enable} = parse_enable($2);
} elsif ($line =~ /^advanced power management\s+(\S+)\s+(\S+)(\s+(\S+))?/) {
$props{drives}{$id}{apm_support} = parse_enable($1);
$props{drives}{$id}{apm_enable} = parse_enable($2);
$props{drives}{$id}{apm_value} = parse_value($4) if ($3);
} elsif ($line =~ /^automatic acoustic management\s+(\S+)\s+(\S+)(\s+(\S+))?/) {
$props{drives}{$id}{aam_support} = parse_enable($1);
$props{drives}{$id}{aam_enable} = parse_enable($2);
$props{drives}{$id}{aam_value} = parse_value($4) if ($3);
} elsif ($line =~ /^Native Command Queuing \(NCQ\)\s+(\S+)\s+(\S+)(\s+(\S+))?/) {
$props{drives}{$id}{ncq_support} = parse_enable($1);
$props{drives}{$id}{ncq_enable} = parse_enable($2, '', '-');
$props{drives}{$id}{ncq_depth} = parse_value($4) if ($3);
}
}
}
sub freebsd_disks_unknown {
my($sysctl) = `sysctl -n kern.disks 2> /dev/null` || dmesg_disks();
chomp($sysctl);
my($disk);
foreach $disk (split(' ', $sysctl)) {
next if ($disk =~ /^(md|cd)\d+$/);
next if ($drives{$disk});
$ndrives++;
$volumes{$disk}++;
$drives{$disk}{$drive_id}++;
$props{drives}{$drive_id}{model} = "Unknown";
$props{drives}{$drive_id}{volume} = $disk;
$drive_id++;
}
}
sub freebsd_disks {
my($ac_works) = 1;
# do this before things like cissutil, megarc (let them override this with more detailed info)
camcontrol();
my($which);
chomp($which = `which $atacontrol` || 0);
if ($?) {
$ac_works = 0;
} else {
if (($yroot || $jailed) && $os_version < 500000000 && $parent_os !~ /^4/) {
# 4.x atacontrol hangs on a 6.x kernel
if (`file $which` =~ /FreeBSD 4/) {
$ac_works = 0;
}
}
}
$debug_storage .= ">> $atacontrol\n";
if ($ac_works) {
# this works with freebsd 4
my($i, $j);
for ($i=0; $i<4; $i++) {
for ($j=0; $j<2; $j++) {
open($in, "$atacontrol cap $i $j 2> /dev/null |") || warn "exec on $atacontrol failed";
$debug_storage .= ">>> $atacontrol cap $i $j\n";
atacontrol($in, $drive_id, "ata-$i,$j");
close($in);
}
}
}
my($grep) = "GREP";
my($gline);
my($sysctl) = `sysctl -n kern.disks 2> /dev/null` || dmesg_disks();
chomp($sysctl);
my($disk);
foreach $disk (split(' ', $sysctl)) {
next if ($disk =~ /^(md|cd)\d+$/);
next if ($drives{$disk});
if ($ac_works) {
# this works with freebsd 6+
open($in, "$atacontrol cap $disk 2> /dev/null |") || warn "exec $atacontrol: $!";
$debug_storage .= ">>> $atacontrol cap $disk\n";
atacontrol($in, $drive_id, $disk);
close($in);
next if ($drives{$disk});
if ($disk =~ /^ar\d+$/) {
my($model) = "";
my($sep) = "partitions: ";
open($in, "$atacontrol status $disk 2> /dev/null |") || warn "exec $atacontrol: $!";
$debug_storage .= ">>> $atacontrol status $disk\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /(RAID\d+).*subdisks: (.*) status:/) {
my($raid, $subs) = ($1, $2);
my($sub);
foreach $sub (split(' ', $subs)) {
$model .= "$sep$sub";
$sep = ", ";
}
$props{$disk}{raid} = $raid;
} elsif ($line =~ /(RAID\d+)( stripesize=(\d+))? status:\s*(\S+)/) {
my($raid, $stripe, $status) = ($1, $3, $4);
$props{$disk}{raid} = $raid;
$props{$disk}{stripe} = $stripe * 512 if $stripe;
$props{$disk}{status} = parse_volume_status($status);
} elsif ($line =~ /^\s*(\d+)\s+(ad\d+)\s+ONLINE/) {
$model .= "$sep$2";
$sep = ", ";
} elsif ($line =~ /^\s*(\d+)\s+\-+\s+MISSING/) {
$model .= "${sep}down";
$sep = ", ";
}
}
if ($model) {
$ndrives++;
$volumes{$disk}++;
$drives{$disk}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $disk;
$drive_id++;
if ($dmesg_buf =~ /^$disk: (\d+)MB/m) {
$props{$disk}{bytes} = $1 * 1024 * 1024;
}
}
}
next if ($drives{$disk});
}
foreach $gline (split(/\n/, $dmesg_buf)) {
if ($gline =~ /(\s*\d+\s+READY\s+)?\(?\b$disk\)?: ((\d+)MB\s*)?\<([^\>]*)\>(\s+on\s+(\S+))?/i && !$volumes{$disk}) {
my($size) = $3;
my($model) = canon_drive($4);
my($dev) = $6;
if (defined($sysctl_dev{$disk})) {
# on freebsd 6.x model/dev should be more accurate from sysctl
$model = canon_drive($sysctl_dev{$disk}{desc});
$dev = $sysctl_dev{$disk}{parent};
}
$ndrives++;
$volumes{$disk}++;
$drives{$disk}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $disk;
$drive_id++;
if ($size) {
$props{$disk}{bytes} = $size * 1024 * 1024;
}
if ($gline =~ /\b(raid\s*\S+)/i) {
$props{$disk}{raid} = $1;
} else {
$props{$disk}{raid} = "JBOD";
}
if ($dev) {
$props{$disk}{device} = $dev;
$controller_volumes{$dev}{$disk}++;
if ($dev =~ /^twe(\d+)/) {
my($ctrl) = $1;
if ($gline =~ /\b$disk: <Unit (\d+)/) {
$logical_to_os{'tw'}{"c$ctrl-u$1"} = $disk;
}
}
}
} elsif ($gline =~ /^$disk:.*?(\d+) (512 byte )?sectors/) {
$props{$disk}{bytes} = $1 * 512;
if ($gline =~ /(raid\s*\S+)/i) {
$props{$disk}{raid} = $1;
}
}
}
next if ($drives{$disk});
# on freebsd 6.x the following should work. do this after dmesg check as it should have more info.
if (defined($sysctl_dev{$disk})) {
my($model) = canon_drive($sysctl_dev{$disk}{desc});
my($dev) = $sysctl_dev{$disk}{parent};
$ndrives++;
$volumes{$disk}++;
$drives{$disk}{$drive_id}++;
$props{drives}{$drive_id}{model} = $model;
$props{drives}{$drive_id}{volume} = $disk;
$drive_id++;
$props{$disk}{device} = $dev;
$controller_volumes{$dev}{$disk}++;
}
}
if ($ac_works) {
# wire ATA drives
my($channel);
open($in, "$atacontrol list 2> /dev/null |") || warn "exec on $atacontrol failed";
$debug_storage .= ">>> $atacontrol list\n";
while ($line = <$in>) {
$debug_storage .= $line;
chomp($line);
if ($line =~ /ATA\s+channel\s+(\d+)/i) {
$channel = $1;
} elsif ($line =~ /^\s*(master|slave):\s*(ad\d+)/i) {
$props{$2}{channel} = "ata$channel";
$props{$2}{ms} = lc($1);
}
}
close($in);
}
# wire from dmesg if we haven't done it yet
foreach $gline (split(/\n/, $dmesg_buf)) {
if ($gline =~ /^(ad\d+):.*\s+at\s+(\S+)-(slave|master)/i) {
if (!defined($props{$1}{channel})) {
$props{$1}{channel} = $2;
$props{$1}{ms} = $3;
}
} elsif ($gline =~ /^(ata\d+):.*\s+on\s+(ata\S+)/i) {
$props{$1}{device} = $2 unless $props{$1}{device};
}
}
}
# this should probably be elsewhere, but do it last for now so that we always use this if we have it.
# should be very accurate. certainly more than dmesg output which can get garbled.
sub freebsd_disk_ioctls {
my($disk);
my($sysctl) = `sysctl -n kern.disks 2> /dev/null` || dmesg_disks();
chomp($sysctl);
foreach $disk (split(' ', $sysctl)) {
my($dev) = "/dev/$disk";
if (-e $dev && open($in, $dev)) {
my($status);
my($bytes);
if ($os_version >= 600000000) {
$bytes = pack("I2", 0, 0);
$status = ioctl($in, 0x40086481, $bytes);
if ($status) {
my(@bytes) = unpack("I2", $bytes);
$props{$disk}{bytes} = $bytes[0] + $bytes[1] * 4*1024*1024*1024;
}
} elsif ($os_version < 500000000) {
my($rdev) = (stat($dev))[6];
my($offset) = round(148 + (16 * ($rdev & 0x07)));
$bytes = pack("C276", 0);
$status = ioctl($in, 0x41146465, $bytes);
if ($status) {
my(@bytes) = unpack("C${offset}I", $bytes);
$props{$disk}{bytes} = $bytes[-1] * 512;
}
}
close($in);
}
}
}
my(%grub);
sub grok_grub {
my($conf);
if (-e $grub) {
$conf = `cat $grub 2> /dev/null`;
if ($conf =~ /vmlinuz-$os_version\s.*maxcpus=(\d+)/m) {
$grub{'maxcpus'} = $1;
}
}
}
sub grok_os {
$os = "";
$os_up = 0;
chomp($os = `uname -s`);
$os_type = lc($os);
chomp($os .= " " . `uname -r`);
chomp($os .= " " . `uname -m`);
if ($os_type eq "freebsd") {
my($config);
chomp($config = `uname -v`);
$config =~ s/.*\///;
$config =~ s/\s+$//;
$os .= " " . $config;
chomp($os_version = `uname -r`);
if ($os_version =~ /^(\d+)\.\d+-.*(-(\d+))?$/) {
# $2 is null if stock FreeBSD
$os_date = $2 ? $3 : "00000000";
$os_version = "$1$os_date";
}
chomp($jailed = `sysctl -n security.jail.jailed 2> /dev/null` || -e "/var/run/yroot-jail.pid" || 0);
chomp($parent_os = `sysctl -n kern.osrelease 2> /dev/null` || 0);
if ($jailed) {
my($host, $key);
chomp($host = `cat /.yroot_host 2> /dev/null` || 0);
chomp($key = `cat /etc/ssh/ssh_host_key.pub 2> /dev/null` || 0);
if ($host) {
$jailer = $host;
} elsif ($key =~ /\@(\S+)/) {
$jailer = $1;
}
}
my($smp);
# check to see if the sysctl name exists in 4.x or check value in 6.x
chomp($smp = `sysctl -N machdep.smp_active 2> /dev/null` || `sysctl -n kern.smp.active 2> /dev/null` || 0);
$os_up = 1 unless ($smp);
} elsif ($os_type eq "linux") {
chomp($os_version = `uname -r`);
if (-e "/etc/redhat-release") {
# http://kbase.redhat.com/faq/FAQ_43_4422.shtm
chomp($os_distro = `cat /etc/redhat-release`);
$os_distro =~ s/Red Hat Enterprise Linux/RHEL/;
$os_distro =~ s/\s+release\s+/ /;
$os_distro =~ s/\(.*Update (\d+)\)/U$1/;
} elsif (-e "/etc/debian_version") {
chomp($os_distro = `cat /etc/debian_version`);
$os_distro = "Debian $os_distro";
} elsif (-e "/etc/gentoo-release") {
chomp($os_distro = `cat /etc/gentoo-release`);
$os_distro =~ s/\s+Base System version\s+/ /;
}
if ($os_distro) {
$os = "$os_distro, $os";
}
}
if (-l "/.yroot") {
my($link) = readlink("/.yroot");
$link =~ s,^.*/var/yroots/,,;
$yroot = $link;
}
}
sub scsi_to_device {
my($dev) = @_;
if ($dev =~ /^scsi(\d+)$/) {
my($id) = $1;
if ($dmesg_buf =~ /\bscsi\(?$id\)?\s*:.*IRQ[:= ]\s*(\d+)/im) {
$dev = $irq_to_driver{$1} if ($irq_to_driver{$1});
}
}
return $dev;
}
sub cmp_disks {
my($atype, $anum) = ($a =~ /^(.*?)(\d*)$/);
my($btype, $bnum) = ($b =~ /^(.*?)(\d*)$/);
if ($os_type eq "linux" && $atype =~ /^sd/ && $btype =~ /^sd/) {
return (length($atype) cmp length($btype) || $atype cmp $btype);
} else {
return ($atype cmp $btype || $anum <=> $bnum);
}
}
sub print_disks {
my($volume);
foreach $volume (sort cmp_disks keys %volumes) {
next if ($volume =~ /^ata-/);
next unless ($drives{$volume} || $props{$volume}{bytes});
next if ($props{$volume}{hidden});
next if ($volume =~ /^ar\d+$/ && !defined($props{$volume}{df}));
my($out) = "$volume";
my($out_dev) = "";
if ($props{$volume}{channel}) {
my($channel) = $props{$volume}{channel};
my($dev) = $props{$channel}{device};
if ($dev) {
$dev = $pci_to_driver{$dev} || $hostid_to_driver{$dev} || $dev;
$dev = scsi_to_device($dev);
$out_dev .= "$dev:";
}
$out_dev .= "$props{$volume}{channel}-" . substr($props{$volume}{ms}, 0, 1);
} elsif ($props{$volume}{device}) {
my($dev) = $props{$volume}{device};
$dev = $pci_to_driver{$dev} || $hostid_to_driver{$dev} || $dev;
$dev = scsi_to_device($dev);
$out_dev .= $dev;
$out_dev .= "-" . substr($props{$volume}{'ms'}, 0, 1) if $props{$volume}{'ms'};
} elsif ($dmesg_buf =~ /^$volume at (\S+)/m) {
$out_dev .= $1;
} elsif ($dmesg_buf =~ /^$volume: <.*> on (\S+)/m) {
$out_dev .= $1;
}
next if ($out_dev =~ /^umass/);
$out .= " ($out_dev)" if ($out_dev);
$out .= ":";
if ($props{$volume}{bytes}) {
$out .= " " . print_bytes($props{$volume}{bytes}, 1000, 0);
} elsif ($props{$volume}{df}{size}) {
$out .= " " . print_bytes($props{$volume}{df}{size}, 1000, 0);
}
$out .= sprintf(" (%d%%)", $props{$volume}{df}{used} * 100 / ($props{$volume}{df}{used} + $props{$volume}{df}{avail})) if (($props{$volume}{df}{used} || $props{$volume}{df}{avail}) && !defined($props{$volume}{inmd}));
my($raid) = canon_raid($props{$volume}{raid});
$out .= " $raid" if ($raid);
# this output is meant for debugger, will hopefully use it later in real output
# $out .= sprintf(" (stripe %s)", print_bytes($props{$volume}{stripe}, 1024, 1)) if ($props{$volume}{stripe});
if ($props{$volume}{spare} || $props{$volume}{free} || $props{$volume}{failed} || $props{$volume}{rebuild} || $props{$volume}{missing}) {
$out .= " (";
my($sep) = "";
if ($props{$volume}{spare}) {
$out .= "$sep$props{$volume}{spare} spare";
$sep .= ", ";
}
if ($props{$volume}{free}) {
$out .= "$sep$props{$volume}{free} free";
$sep .= ", ";
}
if ($props{$volume}{failed}) {
$out .= "$sep$props{$volume}{failed} failed";
$sep .= ", ";
}
if ($props{$volume}{rebuild}) {
$out .= "$sep$props{$volume}{rebuild} rebuild";
$sep .= ", ";
}
if ($props{$volume}{missing}) {
$out .= "$sep$props{$volume}{rebuild} missing";
$sep .= ", ";
}
$out .= ")";
}
$output .= "Disk:\t\t";
$output .= $out;
my($key);
my(%pretty);
foreach $key (keys %{$drives{$volume}}) {
my($try);
my($found) = 0;
my($model) = $props{drives}{$key}{model};
# sort by length to find longest match, e.g. some drives just differ in suffix
foreach $try (sort { length($b) <=> length($a) } keys %drive_models) {
if ($model =~ /$try/i) {
$pretty{$drive_models{$try}}++;
$found++;
last;
}
}
if (!$found) {
unless ($model =~ /^($ignore_disk_models)/i) {
$debug .= "Debug-Disk:\t$model\n";
}
if ($model =~ /^((COMPAQ|HP)-)?(BD|BF|DD|DF|DG|DH|FB|FJ)([0-9]{3})([0-9A-Z]{5})/ || $model =~ /^((ATA)-)?(GB)([0-9]{4})([0-9A-Z]{5})/) {
my($type, $size, $seq) = ($3, $4, $5);
my($str);
$size =~ s/^0+//;
$str = $size . "GB ";
if ($type eq "BD") {
$str .= "10K ";
$str .= "U320 " if (hex($seq) >= 0x85A24);
} elsif ($type eq "BF") {
$str .= "15K ";
$str .= "U320 " if (hex($seq) >= 0x87B54);
} elsif ($type eq "DD") {
$str .= "10K SAS ";
} elsif ($type eq "DF") {
$str .= "15K SAS ";
} elsif ($type eq "DG") {
$str .= "10K SAS 2.5\" ";
} elsif ($type eq "DH") {
$str .= "15K SAS 2.5\" ";
} elsif ($type eq "FB") {
$str .= "7.2K SATA/150 ";
} elsif ($type eq "FJ") {
$str .= "5.4K SATA/150 ";
} elsif ($type eq "GB") {
$str .= "7.2K SATA/300 ";
}
$str .= "HP";
$pretty{$str}++;
$found++;
}
}
if (!$found) {
$pretty{$model}++;
}
}
my($sep) = " == ";
foreach $key (sort { $pretty{$b} <=> $pretty{$a} || length($b) <=> length($a) } keys %pretty) {
if ($volume =~ /^(md|ccd|ar|dm)\d+/) {
$output .= "$sep$key";
} else {
$output .= "$sep$pretty{$key} x $key";
}
if ($opts{'n'}) {
$sep = ", ";
} else {
$sep = sprintf("\n\t\t%*s", length($out) + 4, " ");
}
}
$output .= "\n";
}
}
my($sent_email) = 0;
sub email {
my($old, $new) = @_;
my($out) = 'OUT';
return if ($sent_email);
open($out, "| sendmail $email") || warn("exec sendmail: $!");
print $out "To: $email\n";
print $out "From: hwconfig\@yahoo-inc.com\n";
print $out "Subject: hwconfig";
print $out " diff" if ($old ne $new);
print $out " for $hostname\n";
print $out "\n";
print $out $output;
print $out "Version:\t$version\n";
print $out "\n$debug" unless ($opts{'d'});
print $out "Debug-System:\t$guess_system\n" unless ($debug =~ /^Debug-System/m);
print $out "\n", $stderr, "\n" if ($stderr);
print $out "\n", $old, "\n" if ($old);
print $out "\n> perl warnings\n", $perl_warn if ($perl_warn);
print $out "\n> pciconf\n", $sig_pci, "\n", $debug_pciconf if ($debug_pciconf);
print $out "\n> lspci\n", $sig_pci, "\n", $debug_lspci if ($debug_lspci);
print $out "\n> lshal\n", $debug_lshal if ($debug_lshal);
print $out "\n> sysctl dev\n", $debug_sysctl_dev if ($debug_sysctl_dev);
print $out "\n> dmidecode\n", $debug_dmidecode if ($debug_dmidecode);
print $out "\n> cpuinfo\n", $debug_cpuinfo if ($debug_cpuinfo);
print $out "\n> meminfo\n", $debug_meminfo if ($debug_meminfo);
print $out "\n> storage\n", $debug_storage if ($debug_storage);
print $out "\n> network\n", $debug_network if ($debug_network);
print $out "\n.\n";
close($out);
$sent_email++;
}
# Main
$zero = $0;
$zero =~ s,.*/,,;
getopts('h?dmnvo:', \%opts);
if ($opts{'v'}) {
print "$version\n";
exit(0);
}
if ($opts{'h'} || $opts{'?'}) {
usage();
exit(0);
}
if ($<) {
$stderr .= "$zero: warning: run as root for more detailed and accurate data\n";
}
$SIG{'ALRM'} = 'watchdog';
alarm($timeout);
if ($opts{'o'}) {
# avoid infinite reboot by bailing if it looks like last run at reboot didn't complete
if (-e $lock) {
# avoid case where stray lock file permanently disables boot run
# worst case we end up with a single crash after a reboot
unlink($lock);
die "$zero: lock file '$lock' already exists, bailing out";
}
system("touch $lock");
}
grok_os();
grok_grub();
init_dmesg();
grok_dmesg();
if ($os_type eq 'freebsd') {
grok_sysctl_dev() if ($os_version >= 600000000);
grok_pciconf();
} elsif ($os_type eq "linux") {
pci_to_driver();
grok_proc_ioports();
grok_lspci();
grok_lshal();
}
# YYYY - need to nuke all dmi work if it fails, i.e. clear %smbios and %procs
dmidecode() || smbinfo();
mptable();
my($bios);
if ($smbios{'BIOS'}{1}{'Vendor'}) {
my($vendor, $version, $date) = ($smbios{'BIOS'}{1}{'Vendor'}, $smbios{'BIOS'}{1}{'Version'}, $smbios{'BIOS'}{1}{'Release Date'});
$bios = $vendor;
$bios =~ s/(Award|Dell|Intel|Phoenix).*/$1/;
$bios =~ s/American Megatrends.*/AMI/;
$bios =~ s/Hewlett.*/HP/;
$bios =~ s/\s+/_/g;
if ($version) {
$version =~ s/\s+/_/g;
$bios .= " $version";
}
if ($date) {
$date =~ s/\s+/_/g;
$bios .= " $date";
}
}
sub clean_system {
my($str) = @_;
$str =~ s/[^ -~]//g;
$str =~ s/[\.\,]/ /gi;
$str =~ s/\b(Server|Board|Mainboard|Microtower|Microsystems|Inc|Computer|Corp|Corporation|Technology|Co|Ltd|Manufacturer)\b/ /gi;
$str =~ s/Small Form Factor//i;
$str =~ s/\bInc\b/ /gi;
$str =~ s/Rackable Systems/Rackable/ig;
$str =~ s/Hewlett-Packard/HP/i;
$str =~ s/Enterprise Server Division//;
$str =~ s/TYAN High-End Dual AMD Opteron//;
$str =~ s/IBM System x iDataPlex/IBM iDataPlex/;
$str =~ s/Dual AMD Opteron//;
$str =~ s/TYAN/Tyan/g;
$str =~ s/GIGABYTE/Gigabyte/g;
$str =~ s/DELL/Dell/g;
$str =~ s/MICRO-STAR INTERNATIONAL/MSI/ig;
$str =~ s/ASUSTeK/Asus/ig;
$str =~ s/DELUXE/Deluxe/g;
$str =~ s/RIOWORKS/Arima/g;
$str =~ s/A Sanmina-SCI Company//g;
$str =~ s/NEWISYS/Newisys/g;
$str =~ s/InventecESC/Inventec/g;
$str =~ s/((HP|Sun|VMware|IBM|Tyan|Dell)\s+)+/$2 /i;
$str =~ s/HP Compaq/HP/i;
$str =~ s/\b(uT|CMT|SFF|MT)(\([^\)]+\))?/$1/;
$str =~ s/\((TM|R)\)//g;
$str =~ s/DL140 00h/DL140 G1/i;
$str =~ s/\-?\[[^\]]+\]\-?/ /;
$str =~ s/\([^\)]+\)/ /;
$str = clean_white($str);
return $str;
}
my($system) = 'Unknown';
my($base_board);
my($sys);
if ($smbios{'Base Board'}{1}{'Manufacturer'} && $smbios{'Base Board'}{1}{'Product Name'}) {
$base_board = clean_system("$smbios{'Base Board'}{1}{'Manufacturer'} $smbios{'Base Board'}{1}{'Product Name'}");
}
if ($smbios{'System'}{1}{'Manufacturer'} && $smbios{'System'}{1}{'Product Name'}) {
$system = "$smbios{'System'}{1}{'Manufacturer'} $smbios{'System'}{1}{'Product Name'}";
} elsif ($base_board) {
$system = $base_board;
}
my($guess) = guess_system($system);
$system = $guess if ($system eq 'Unknown');
if ($system eq "Unknown") {
$system = $smbios{'System'}{1}{'Product Name'} || $smbios{'System'}{1}{'Manufacturer'} || $smbios{'Base Board'}{1}{'Product Name'} || $smbios{'Base Board'}{1}{'Manufacturer'} || $system;
}
$system = clean_system($system);
if (defined($system_model_index)) {
my($ugly) = $system_models[$system_model_index]{'ugly-model'};
if ($ugly && $system =~ /^$ugly$/) {
$system = $system_models[$system_model_index]{'model'};
}
}
$sys = $system;
$sys =~ s/poweredge\s+(\d+)/PE$1/i;
$sys =~ s/poweredge\s*//i;
$sys =~ s/proliant\s*//i;
$sys = clean_white($sys);
my($procs, $processors);
sub canon_cpu_model {
my($model) = @_;
$model =~ s/\@.*//;
$model =~ s/[\d\.]+(MHz|GHz)//i;
$model =~ s/\((TM|R|quarter-micron|coppermine|katmai)\)/ /ig;
$model =~ s/\b(cpu(\s+family|\s+-\s+s)?|processor|genuine|intel|amd)\b/ /ig;
$model =~ s/dual[\-\s]+core\s+opteron/Opteron/ig;
$model =~ s/XEON/Xeon/g;
$model =~ s/\s+/ /g;
$model =~ s/\s+$//;
$model =~ s/^\s+//;
$model =~ s/\/.*//;
return $model;
}
sub grok_procs {
if ($os_type eq "linux") {
cpuinfo();
}
my($proc_id) = 1;
my($index);
for ($index=1; $index < 1025; $index++) {
if ($procs{$index} && $procs{$index}{status}) {
$proc_id = $index;
last;
}
}
if (!$procs{$proc_id}{vendor}) {
$procs{$proc_id}{vendor} = $dmesg{proc}{vendor};
}
if (!$procs{$proc_id}{family}) {
$procs{$proc_id}{family} = $dmesg{proc}{family};
}
if (!$procs{$proc_id}{speed}) {
if ($dmesg{proc}{speed}) {
$procs{$proc_id}{speed} = $dmesg{proc}{speed};
} else {
my($tsc) = `sysctl -n machdep.tsc_freq 2> /dev/null`;
if ($tsc) {
chomp($tsc);
$procs{$proc_id}{speed} = sprintf("%4.2fMHz", $tsc / 1000000) if ($tsc);
}
}
}
my($vendor, $model);
my($speed) = 0;
if ($os_type eq "freebsd") {
chomp($model = `sysctl -n hw.model 2> /dev/null`);
}
if (!$model) {
if ($procs{$proc_id}{family}) {
$model = $procs{$proc_id}{family};
} elsif ($vendor) {
$model = $vendor;
} else {
$model = "unknown";
}
}
$vendor = canon_cpu_vendor($procs{$proc_id}{vendor} || $model);
if ($model =~ /([\d\.]+)(MHz|GHz)/) {
$speed = round($1 * (($2 eq "GHz") ? 1000 : 1));
}
$model = canon_cpu_model($model);
if (!$model) {
if ($vendor) {
$model = $vendor;
} else {
$model = "uknown";
}
}
my($cpuid) = hex($procs{$proc_id}{cpuid} || $dmesg{proc}{cpuid} || "0");
my($id) = cpuid($vendor, $cpuid);
my($cpu_info, $cpu_cores, $cpu_threads, $cpu_gen) = ('', 0, 0, 0);
if ($cpu_models{$id}) {
if (ref($cpu_models{$id}[0]) eq "ARRAY") {
my($match) = "$model $speed";
my($try);
foreach $try (@{$cpu_models{$id}}) {
($cpu_info, $cpu_cores, $cpu_threads, $cpu_gen) = @{$try->[1]};
last if ($match =~ /$try->[0]/i);
}
} else {
($cpu_info, $cpu_cores, $cpu_threads, $cpu_gen) = @{$cpu_models{$id}};
}
}
$procs{gen} = $cpu_gen;
if ($cpu_info && defined($procs{$proc_id}{'L2 Cache Handle'})) {
my($handle) = $procs{$proc_id}{'L2 Cache Handle'};
if (defined($dmi{$handle}) && defined($dmi{$handle}{'key'}{'Installed Size'})) {
my($pretty) = print_bytes(parse_bytes($dmi{$handle}{'key'}{'Installed Size'}, 1024), 1024, 1);
$cpu_info =~ s/L2: (\S+)/L2: $pretty/;
}
}
if ($cpu_info && defined($procs{$proc_id}{'L3 Cache Handle'})) {
my($handle) = $procs{$proc_id}{'L3 Cache Handle'};
if (defined($dmi{$handle}) && defined($dmi{$handle}{'key'}{'Installed Size'})) {
my($pretty) = print_bytes(parse_bytes($dmi{$handle}{'key'}{'Installed Size'}, 1024), 1024, 1);
$cpu_info =~ s/L3: (\S+)/L3: $pretty/;
}
}
my($hyper) = "UNKNOWN";
if ($os_type eq "linux") {
if ($cpu_cores == 0) {
# lookup failed, so guess from what's active in cpuinfo
if ($procs{threads} && $procs{cores}) {
$cpu_cores = $procs{cores};
$cpu_threads = ceil($procs{threads} / $procs{cores});
} else {
$cpu_cores = 1;
$cpu_threads = 1;
}
}
if ($procs{1} && $procs{1}{flags} =~ /\bht\b/i) {
$hyper = "YES_ON";
} elsif ($procs{threads} > $procs{cores}) {
# cpu flags not working with Atom procs and dmidecode 2.9
$hyper = "YES_ON";
} else {
$hyper = "NO";
}
} elsif ($os_type eq "freebsd") {
if ($cpu_cores == 0) {
# lookup failed, no way to tell in freebsd, so set to 1
$cpu_cores = 1;
$cpu_threads = 1;
}
chomp($procs{active_threads} = `sysctl -n hw.ncpu`);
$procs{threads} = $procs{active_threads};
my($sysctl, $allowed, $halt);
chomp($sysctl = `sysctl -n machdep.hyperthreading_allowed 2> /dev/null`);
if ($?) {
$allowed = -1;
} elsif ($sysctl) {
$allowed = 1;
} else {
$allowed = 0;
}
chomp($sysctl = `sysctl -n machdep.hlt_logical_cpus 2> /dev/null`);
if ($?) {
$halt = -1;
} elsif ($sysctl) {
$halt = 1;
} else {
$halt = 0;
}
if ($halt == -1) {
if ($procs{active_threads} == 1) {
# if we have a UP kernel, have to grok dmesg looking for HTT feature
if ($allowed != -1) {
$debug .= "Debug-HT:\tmachdep.hlt_logical_cpus missing\n";
}
if ($dmesg_buf =~ /^\s*Features=.*\bHTT\b/m) {
$hyper = "YES_UP";
} else {
$hyper = "NO";
}
} else {
# we have old SMP kernel without machdep.hlt_logical_cpus
if ($dmesg_buf =~ /^\s*Features=/m && $dmesg_buf !~ /^\s*Features=.*\bHTT\b/m) {
$hyper = "NO";
} else {
# can't tell at this point, leave as UNKNOWN
}
}
} elsif ($halt == 1) {
$hyper = "YES_OFF";
} elsif ($halt == 0) {
if ($allowed == -1) {
if ($os_version >= 600000000) {
$hyper = "NO";
} else {
$hyper = "YES_ON";
}
} elsif ($allowed == 1) {
$hyper = "YES_ON";
} elsif ($allowed == 0) {
$hyper = "YES_OFF";
}
}
# figure out how many threads are really enabled
chomp($sysctl = `sysctl -n machdep.hlt_cpus 2> /dev/null`);
if ($?) {
if ($procs{active_threads} > 1) {
if ($hyper eq "YES_OFF") {
if ($halt == 1) {
$procs{active_threads} = $procs{active_threads} / ($cpu_threads * $cpu_cores);
} elsif ($halt == 0) {
$procs{active_threads} = $procs{active_threads} / $cpu_threads;
}
}
}
} elsif ($sysctl) {
my($mask) = $sysctl;
my($n) = $procs{active_threads};
while ($n) {
$procs{active_threads}-- if ($mask & 1);
$mask = $mask >> 1;
$n--;
}
}
}
# cpus will report HT even if they don't have it, e.g. dual/quad-core
if ($cpu_threads == 1) {
$hyper = "NO";
} elsif ($hyper eq "NO") {
$debug .= "Debug-HT:\tmissing HT detect\n" unless ($os_up);
}
if (!$speed && $procs{$proc_id}{speed} && $procs{$proc_id}{speed} =~ /^([\d\.]+)(MHz)?$/i) {
$speed = $1;
}
if ($speed >= 1000) {
$speed = sprintf("%4.2fGHz", $speed / 1000);
} elsif ($speed >= 100) {
$speed = sprintf("%.0fMHz", $speed);
} elsif ($speed > 0) {
$speed = sprintf("%4.2fMHz", $speed);
}
# fix bogus opteron models from HP - http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?objectID=c00606132
if ($model =~ /Opteron 852/ && $speed =~ /2\.40GHz/i) {
$model = "Opteron 880";
} elsif ($model =~ /Opteron 850/ && $speed =~ /2\.20GHz/i) {
$model = "Opteron 875";
}
# fix bogus FSB speeds
if ($procs{$proc_id}{clock} && $cpu_info) {
if ($cpu_info =~ /Prestonia/ && $procs{$proc_id}{clock} eq "133MHz") {
# for HP DL140 with Prestonia Bs
$procs{$proc_id}{clock} = "533MHz";
$cpu_info =~ s/Prestonia/Prestonia B/;
} elsif ($cpu_info =~ /Sossaman/ && $procs{$proc_id}{clock} eq "167MHz") {
# for Intel SE7520BB2 with Sossaman
$procs{$proc_id}{clock} = "667MHz";
}
}
# how many sockets does this particular system have (assuming we are correct on system type)
# to be looked up in system property defintion table
my($sockets) = 0;
if (defined($system_model_index)) {
$sockets = $system_models[$system_model_index]{sockets};
} else {
if ($procs{sockets}) {
# got data from smbinfo
$sockets = $procs{sockets};
} else {
# need to guess the number of sockets
if ($procs{mptable}) {
$sockets = $procs{mptable};
} else {
$sockets = $procs{threads};
}
if ($cpu_threads && ($hyper eq "YES_OFF" || $hyper eq "YES_ON")) {
# if HT is supported, ncpu should be 2x number of sockets
$sockets = ceil($sockets / $cpu_threads);
}
if ($cpu_cores) {
$sockets = ceil($sockets / $cpu_cores);
}
$sockets = 1 if ($sockets < 1);
}
}
if (!$procs{sockets} || $procs{sockets} != $sockets) {
if ($procs{sockets}) {
# only warn if we got bad info from smbios
$debug .= sprintf("Debug-Sockets:\t(smbios=%d) != (lookup=%d) ==> setting sockets=%d\n", $procs{sockets}, $sockets, $sockets);
}
# we figured out sockets above, use it
$procs{sockets} = $sockets;
# our best guess, make it look like smbios thought we had these minimum number of active cpus
my($i);
for ($i=0; $i < ceil($procs{active_threads} / $cpu_cores / $cpu_threads); $i++) {
$procs{$i+1}{status} = 1;
}
}
# how many active chips do we have in the system
my($chips) = 0;
my($proc);
foreach $proc (keys %procs) {
$chips++ if $procs{$proc}{status};
}
# does /proc/cpuinfo agree?
if ($procs{chips} && $procs{chips} != $chips) {
# if not, let's go with /proc/cpuinfo
$debug .= sprintf("Debug-Chips:\t(smbios=%d) != (cpuinfo=%d) ==> setting chips=%d\n", $chips, $procs{chips}, $procs{chips});
$chips = $procs{chips};
}
if (!$cpu_info && $cpu_cores == 1) {
# we don't know this cpu from cpuid, so guess at number of cores
$cpu_cores = ceil($procs{active_threads} / $cpu_threads);
$cpu_cores = ceil($cpu_cores / $chips) if ($chips);
}
# fixup chips and sockets
if ($procs{sockets} && ($chips > $procs{sockets})) {
# fix cases that are clearly broken
# e.g. Tyan S2865 with Opteron 180 dual-core reports 2 sockets in smbios
$debug .= sprintf("Debug-Sockets:\t(chips=%d) > (smbios=%d) ==> setting chips=%d\n", $chips, $procs{sockets}, $procs{sockets});
$chips = $procs{sockets};
}
# was using active_threads here before, but we really want just threads which should be accurate
if ($procs{threads} > $chips * $cpu_cores * $cpu_threads) {
# most likely smbios said we had fewer chips
# or we didn't have smbios so we guessed at one chip
$debug .= sprintf("Debug-Chips:\t(threads=%d) > (chips=%d * cpu_cores=%d * cpu_threads=%d) ==> setting chips=%d\n", $procs{threads}, $chips, $cpu_cores, $cpu_threads, ceil($procs{threads} / $cpu_cores / $cpu_threads));
$chips = ceil($procs{threads} / $cpu_cores / $cpu_threads);
if ($procs{sockets} < $chips) {
$procs{sockets} = $chips;
}
} elsif ($procs{threads} < $chips * $cpu_cores * $cpu_threads) {
if ($cpu_threads > 1 && $procs{threads} <= $chips * $cpu_cores) {
if ($hyper ne "YES_OFF") {
# deal with case where HT is turned off in BIOS
$hyper = "YES_MISSING";
}
} else {
if ($procs{threads} == 1) {
# should mean we have UP kernel running
$debug .= sprintf("Debug-Threads:\t(threads=%d) < (chips=%d * cpu_cores=%d * cpu_threads=%d) ==> running UP kernel?\n", $procs{threads}, $chips, $cpu_cores, $cpu_threads);
} elsif (defined($grub{'maxcpus'})) {
# maxcpus is limited in grub.conf
$debug .= sprintf("Debug-Threads:\t(threads=%d) < (chips=%d * cpu_cores=%d * cpu_threads=%d) ==> maxcpus=%d limited in $grub\n", $procs{threads}, $chips, $cpu_cores, $cpu_threads, $grub{'maxcpus'});
} else {
# we'll assume cores/threads are accurate, chips is not
$debug .= sprintf("Debug-Threads:\t(threads=%d) < (chips=%d * cpu_cores=%d * cpu_threads=%d) ==> setting chips=%d\n", $procs{threads}, $chips, $cpu_cores, $cpu_threads, ceil($procs{threads} / $cpu_cores / $cpu_threads));
$chips = ceil($procs{threads} / $cpu_cores / $cpu_threads);
if ($procs{sockets} < $chips) {
$procs{sockets} = $chips;
}
}
}
}
$procs{cores} = $chips * $cpu_cores;
$procs{threads} = $chips * $cpu_cores * $cpu_threads;
if ($procs{cores} > $procs{active_threads}) {
$procs{active_cores} = $procs{active_threads};
} else {
$procs{active_cores} = $procs{cores};
}
# sanity check on cores/threads
if ($procs{active_threads} > $procs{threads}) {
$debug .= sprintf("Debug-Threads-Active:\t(active_threads=%d) > (threads=%d)\n", $procs{active_threads}, $procs{threads});
}
if ($procs{active_cores} > $procs{cores}) {
$debug .= sprintf("Debug-Cores-Active:\t(active_cores=%d) > (cores=%d)\n", $procs{active_cores}, $procs{cores});
}
if ($procs{sockets} && ($procs{cores} > $procs{sockets} * $cpu_cores)) {
$debug .= sprintf("Debug-Cores:\t(cores=%d) > (sockets=%d * cpu_cores=%d)\n", $procs{cores}, $procs{sockets}, $cpu_cores);
}
if ($procs{sockets} && ($procs{threads} > $procs{sockets} * $cpu_cores * $cpu_threads)) {
$debug .= sprintf("Debug-Threads:\t(threads=%d) > (sockets=%d * cpu_cores=%d * cpu_threads=%d)\n", $procs{threads}, $procs{sockets}, $cpu_cores, $cpu_threads);
}
if ($procs{cores} != $chips * $cpu_cores) {
$debug .= sprintf("Debug-Cores:\t(cores=%d) != (chips=%d * cpu_cores=%d)\n", $procs{cores}, $chips, $cpu_cores);
}
# ready for results
$procs = "$chips x $model";
$procs .= " $speed" if ($speed);
if ($chips >= $procs{sockets}) {
$processors = "$chips x $model";
} else {
$processors = "$chips (of $procs{sockets}) x $model";
}
$processors .= " $speed" if ($speed);
$processors .= " $procs{$proc_id}{clock} FSB" if ($procs{$proc_id}{clock});
my($open, $close) = (" (", "");
if ($hyper =~ /^YES/ && $vendor ne "AMD") {
$processors .= $open . "HT ";
$open = ", ";
$close = ")";
if ($hyper eq "YES_ON") {
$processors .= "enabled";
} elsif ($hyper eq "YES_OFF") {
$processors .= "disabled";
} elsif ($hyper eq "YES_MISSING" || $hyper eq "YES_UP") {
$processors .= "missing";
}
}
if ($procs{cores} > $chips || $procs{active_cores} < $procs{cores}) {
if ($procs{active_cores} < $procs{cores}) {
$processors .= $open . "$procs{active_cores}/$procs{cores} cores";
} else {
$processors .= $open . "$procs{active_cores} cores";
}
$open = ", ";
$close = ")";
if ($procs{threads} && $procs{threads} > $procs{cores}) {
if ($procs{active_threads} < $procs{threads}) {
$processors .= $open . "$procs{active_threads}/$procs{threads} threads";
} else {
$processors .= $open . "$procs{active_threads} threads";
}
}
} elsif ($procs{threads} > $chips) {
if ($procs{active_threads} < $procs{threads}) {
$processors .= $open . "$procs{active_threads}/$procs{threads} threads";
} else {
$processors .= $open . "$procs{active_threads} threads";
}
$open = ", ";
$close = ")";
}
$processors .= $close;
if ($cpu_info) {
$processors .= " - $cpu_info" if ($cpu_info);
} elsif ($cpuid) {
$debug .= "Debug-Processors:\t$id\n";
}
# my($features) = $procs{$proc_id}{features} || $dmesg{proc}{features};
# if ($features) {
# $processors .= " (features = $features)";
# } elsif ($procs{$proc_id}{flags}) {
# $processors .= " (flags = $procs{$proc_id}{flags})";
# }
}
sub memory {
my($mem, $memory) = ("", "");
my($total) = 0;
if (-r $meminfo) {
my($in) = "MEMINFO";
my($line);
open($in, "< $meminfo") || warn "open: $meminfo: $!";
while ($line = <$in>) {
$debug_meminfo .= $line;
chomp($line);
if ($line =~ /^Mem:\s*(\d+)/i) {
$total = $1;
} elsif ($line =~ /^MemTotal:\s*(\d+)\s*kB/i) {
$total = $1 * 1024 unless $total;
}
}
close($in);
} else {
# first check with dmesg
if ($dmesg_buf =~ /^Physical memory chunk/m) {
my($line);
my($match) = 0;
foreach $line (split(/\n/, $dmesg_buf)) {
if ($line =~ /^Physical memory chunk/) {
$match = 1;
} elsif ($match) {
if ($line =~ /(\d+) bytes/) {
$total += $1;
} else {
last;
}
}
}
} elsif ($dmesg_buf =~ /^avail memory = (\d+)/m) {
$total = $1;
}
# now let's see what sysctl hw.* has to say
my($arch, $pae, $pages, $pagesize, $physmem);
chomp($arch = `sysctl -n hw.machine_arch 2> /dev/null` || 0);
chomp($pae = `sysctl -n kern.features.pae 2> /dev/null` || 0);
chomp($pages = `sysctl -n hw.maxmem 2> /dev/null` || `sysctl -n hw.availpages 2> /dev/null` || 0);
chomp($pagesize = `sysctl -n hw.pagesize 2> /dev/null` || 0);
chomp($physmem = `sysctl -n hw.physmem 2> /dev/null` || 0);
my($try) = 0;
if ($pae && !$total) {
# hw.physmem seems to be accurate, but is only 32-bit int, so can't use in case of pae
# however pages method seems to over estimate, so only use it if we don't have something from dmesg
$try = $pages * $pagesize;
}
if (!$try) {
$try = $physmem;
}
# prefer hw.physmem if we have it, but prefer dmesg if we resort to hw.maxmmem
$total = $try if ($try > $total);
}
$mem = print_bytes($total, 1024, 1, 100); # probably shouldn't force int=1 here, but didn't have .0 in legacy
$total = $total / 1024 / 1024;
if ($smbios{'Memory'}{'Count'}) {
my($sum) = 0;
my($i);
my($device, %device);
my($key);
my($sep) = "";
my($speed) = 0;
my($type);
for ($i=1; $i <= $smbios{'Memory'}{'Count'}; $i++) {
my($size) = $smbios{'Memory'}{$i}{'Size'};
if ($size =~ /(\d+)(MB)?/i) {
$size = $1 * 1024 * 1024;
# only use type/speed info if socket is populated
$type = $smbios{'Memory'}{$i}{'Type'} if ($smbios{'Memory'}{$i}{'Type'});
$speed = $smbios{'Memory'}{$i}{'Speed'} if ($smbios{'Memory'}{$i}{'Speed'});
} else {
$size = 0;
}
$sum += $size;
$key = "$size,";
$key .= $smbios{'Memory'}{$i}{'Part Number'} if ($smbios{'Memory'}{$i}{'Part Number'});
$device{$key}++;
}
$mem .= " / " if ($mem && $sum);
$mem .= print_bytes($sum, 1024, 1) if ($sum);
if ($speed) {
if ($speed eq "133MHz" && $system =~ /140 G3/) {
$speed = "533MHz";
}
}
if ($mem) {
$mem .= " $speed" if ($speed);
$mem .= " $type" if ($type && $type ne "Unknown" && $type ne "DRAM");
my(%pretty);
foreach $key (keys %device) {
my($size, $part) = ($key =~ /^(.*?),(.*)/);
my($try);
my($found) = 0;
if ($part) {
foreach $try (keys %memory_models) {
if ($part =~ /^$try$/i) {
my($pretty_key) = "$size," . $memory_models{$try};
$pretty{$pretty_key} += $device{$key};
$found++;
last;
}
}
if (!$found) {
$debug .= "Debug-Memory:\t$part\n";
}
}
if (!$found) {
$pretty{"$size,"} += $device{$key};
}
}
$sep = "";
# sort by memory size first, then number of dimms, then length of description
foreach $key (sort { (split(/,/,$b))[0] <=> (split(/,/,$a))[0] || $pretty{$b} <=> $pretty{$a} || length($b) <=> length($a) } keys %pretty) {
my($size, $model) = ($key =~ /^(.*?),(.*)/);
if ($size) {
$size = print_bytes($size, 1024, 1);
} else {
$size = "empty";
}
$memory .= "$sep$pretty{$key} x $size";
$memory .= " - $model" if ($model);
$sep = ", ";
}
}
}
return ($mem, $memory, $total);
}
grok_procs();
my($mem, $memory, $meg) = memory();
if ($os_type eq 'freebsd') {
freebsd_disks();
} elsif ($os_type eq 'linux') {
grok_proc_ide() unless $success{'grok_lshal_ide'};
grok_proc_scsi() unless $success{'grok_lshal_scsi'};
grok_proc_cciss();
grok_proc_partitions();
grok_mdstat() if ($need_mdstat);
}
if ($need_hpacucli || $want_hpacucli) {
hpacucli();
}
if ($need_twcli || $want_twcli) {
twcli();
}
if ($need_mptutil || $want_mptutil) {
mptutil();
}
if ($need_mfiutil || $want_mfiutil) {
mfiutil();
}
if ($need_megarc || $want_megarc) {
megarc() || omreport();
}
if ($need_megacli || $want_megacli) {
megacli() || omreport();
}
if ($need_cissutil || $want_cissutil) {
cissutil();
}
if ($need_arcconf || $want_arcconf) {
arcconf() || omreport();
}
if ($os_type eq 'freebsd') {
freebsd_disks_unknown();
freebsd_disk_ioctls();
}
my($ymodel) = '';
if ($system_model_index && defined $system_models[$system_model_index]{'ymodel-type'}) {
$ymodel = sprintf("%s%d%d%d", $system_models[$system_model_index]{'ymodel-type'}, $procs{gen} || 1, log($procs{cores})/log(2), log(($meg/1024)+0.5)/log(2));
}
$output .= "Summary:\t";
#$output .= "$ymodel - " if ($ymodel);
$output .= "$sys, $procs, $mem\n";
$output .= "System:\t\t$system";
$output .= " ($base_board)" if ($base_board && $base_board ne $system && !defined($smbios{'Base Board'}{2}));
$output .= "\nProcessors:\t$processors\n";
if (length($memory) > 70 && !$opts{'n'}) {
my($sep) = sprintf("\n\t\t%*s", length($mem) + 4, " ");
$memory =~ s/, /$sep/g;
}
$output .= "Memory:\t\t$mem";
$output .= " == $memory" if ($memory);
$output .= "\n";
lvdisplay() if ($need_lvm);
df();
ccdconfig() if ($need_ccdconfig);
print_disks();
# need this before other_devices()
grok_network();
other_devices();
my($interface);
foreach $interface (sort cmp_devs keys %interfaces) {
next if ($interface =~ /^(vlan|bond|dummy|vmnet|sw|irda|venet|veth|xenbr|virbr|cipsec|wmaster|mskc|pan)\d+$/);
my($driver) = $interface_to_driver{$interface};
$output .= "Network:\t$interface";
$output .= " ($driver)" if ($driver);
$output .= ": ";
if ($driver && $interfaces{$driver} && $interfaces{$driver}{model}) {
# only example of this is msk0 (interface) -> mskc0 (pci-device/driver)
$output .= $interfaces{$driver}{model} . ", ";
} elsif ($interfaces{$interface}{model}) {
$output .= $interfaces{$interface}{model} . ", ";
}
$output .= $interfaces{$interface}{mac} if ($interfaces{$interface}{mac});
if (defined($interfaces{$interface}{status})) {
if ($interfaces{$interface}{status} eq "active") {
$output .= ", $interfaces{$interface}{media}" if ($interfaces{$interface}{media});
} else {
$output .= ", $interfaces{$interface}{status}";
}
}
$output .= "\n";
}
if ($os) {
$output .= "OS:\t\t$os";
if ($os =~ /amd64|x86_64/) {
$output .= ", 64-bit";
} else {
$output .= ", 32-bit";
}
$output .= "\n";
}
$output .= "BIOS:\t\t$bios\n" if ($bios);
if ($os_type eq "linux") {
chomp($hostname = `hostname -f`);
} else {
chomp($hostname = `hostname`);
}
if ($hostname) {
$output .= "Hostname:\t$hostname";
my($pre, $post) = (" (", "");
if ($jailed) {
$output .= $pre . "jailed";
$output .= " on $jailer" if ($jailer);
$pre = ", ";
$post = ")";
}
if ($yroot) {
$output .= $pre . "yroot $yroot";
$pre = ", ";
$post = ")";
}
$output .= $post . "\n";
}
$output .= "\n$debug" if ($opts{'d'} && $debug);
if ($need_cissutil && !$got_cissutil) {
$stderr .= "$zero: warning: could not run $cissutil";
$stderr .= "; please yinst $cissutil" unless ($have_cissutil);
$stderr .= "\n";
}
if ($need_megarc && !$got_megarc && !$got_omreport) {
$stderr .= "$zero: warning: could not run $megarc";
$stderr .= "; please yinst $megarc" unless ($have_megarc);
$stderr .= "\n";
}
if ($need_megacli && !$got_megacli && !$got_omreport) {
$stderr .= "$zero: warning: could not run MegaCli";
$stderr .= "; please yinst megacli" unless ($have_megacli);
$stderr .= "\n";
}
if ($need_mfiutil && !$got_mfiutil) {
$stderr .= "$zero: warning: could not run $mfiutil";
$stderr .= "; please yinst $mfiutil" unless ($have_mfiutil);
$stderr .= "\n";
}
if ($need_mptutil && !$got_mptutil) {
$stderr .= "$zero: warning: could not run $mptutil";
$stderr .= "; please yinst $mptutil" unless ($have_mptutil);
$stderr .= "\n";
}
if ($need_hpacucli && !$got_hpacucli) {
$stderr .= "$zero: warning: could not run $hpacucli";
$stderr .= "; please yinst ports/$hpacucli" unless ($have_hpacucli);
$stderr .= "\n";
}
if ($need_twcli && !$got_twcli) {
$stderr .= "$zero: warning: could not run $twcli";
$stderr .= "; please yinst $twcli" unless ($have_twcli);
$stderr .= "\n";
}
if ($need_arcconf && !$got_arcconf && !$got_omreport) {
$stderr .= "$zero: warning: could not run $arcconf";
$stderr .= "\n";
}
if ($opts{'o'}) {
my($out) = 'OUT';
open($out, "> $opts{'o'}") || warn("open: $opts{'o'}: $!");
print STDERR $stderr if ($stderr);
print $out $output;
close($out);
if (($debug || $perl_warn) && !$jailed) {
my($old, $new) = ("", "");
my($tmp) = $opts{'o'};
$tmp =~ s/^.*\///;
$tmp = "/var/tmp/$tmp";
if (-e $tmp) {
$old = `cat $tmp`;
# nuke disk usage and hostnames for diff
$old =~ s/(\s*\d+)\%//gm;
$old =~ s/^Hostname:.*//m;
$new = $output;
$new =~ s/(\s*\d+)\%//gm;
$new =~ s/^Hostname:.*//m;
}
if (! -e $tmp || $old ne $new) {
email($old, $new);
open($out, "> $tmp") || warn("open: $tmp: $!");
print $out $output;
close($out);
}
}
unlink($lock);
} else {
print STDERR $stderr if ($stderr);
print $output;
}
if ($opts{'m'}) {
email('', '');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment