#!/usr/bin/perl -w # copy from below and modified. so, refer to the below code # https://github.com/smilejay/shell/blob/master/sh2012/hwconfig use strict; use English qw(-no_match_vars); use Getopt::Long; use IO::File; use DirHandle; # IO::Dir doesn't work with perl v5.005_03 use Fcntl qw(:flock); use POSIX qw(ceil setsid); # constants my($PATH) = "/etc/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin:/home/opt:/opt/MegaRAID/MegaCli:/usr/StorMan"; my($version) = '1.0.0'; my($xml_version) = '1.0.0'; my($timeout) = 600; my($email) = 'tmr_sysinfo@nobody.nobody'; my($rcsid) = '$Header: tmr_sysinfo,v 1.0 $'; my($smbinfo) = 'smbinfo'; my($smbiosinfo) = 'smbiosinfo'; my($mptable) = 'mptable'; my($pciconf) = 'pciconf'; my($megarc) = 'megarc'; my($mfiutil) = 'mfiutil'; my($mptutil) = 'mptutil'; my($mptstatus) = 'mpt-status'; my($cissutil) = 'cissutil'; my($camcontrol) = 'camcontrol'; my($atacontrol) = 'atacontrol'; my($feature_htt_bit) = 28; 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($linux_mpt_drivers) = 'mptbase|mptspi|mptsas'; my($freebsd_net_devs) = 'nfe|mxge|bge|em|fxp|xl|rl|nve|dc|bce|myk|msk|lnc|le|igb'; my($freebsd_block_devs) = 'atapci|mfi|mpt|mps|mpu|ahc|ahd|asr|aac|aacch|sym|ida|ciss|amr|twe|twa|ahci'; my($freebsd_disk_names) = 'sd|wd|da|ad|mfid|amrd|twed|idad|ada'; my($perc_names) = 'PERC|ServeRAID-MR10M|ServeRAID-MR10k|SROMBSASFC|ROMBSASMR|MegaRAID SAS|8704EM2|8708EM2'; my($lock) = '/var/tmp/tmr_sysinfo-boot.lock'; my($fh_lock); my($cpuid_vmware) = 0; 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_linuxmpt, $want_linuxmpt) = (0, 0); my($need_linuxmpt2, $want_linuxmpt2) = (0, 0); my($have_mptstatus, $got_mptstatus) = (0, 0); my($have_lsiutil, $got_lsiutil) = (0, 0); my($have_sas2ircu, $got_sas2ircu) = (0, 0); my($need_fio, $want_fio, $have_fio, $got_fio) = (0, 0, 0, 0); my($got_lshal, $got_sysblock) = (0, 0); my($need_mdstat) = 0; my($need_lvm) = 0; my($need_ccdconfig) = 0; my($need_rd) = 0; my($xml_top) = {}; my($xml_handle) = 1; my(%handle_to_xml); my($xml); my(%pci_to_handle); my(%hide_dev); my($command) = ''; my($dmesg_buf) = ''; my($output) = ''; my(%output); my($stderr_buf) = ''; my($stdout); my($perl_warn) = ''; my($phone_home) = 0; my($debug) = ''; my($raw_source) = ''; my($debug_pciconf) = ''; my($debug_lspci) = ''; my($debug_lshal) = ''; my($debug_sysctl_dev) = ''; my($debug_ipmi) = ''; my($debug_dmidecode) = ''; my($debug_storage) = ''; my($debug_network) = ''; my($debug_cpuinfo) = ''; my($debug_cpuid) = ''; my($debug_mptable) = ''; my($debug_memory) = ''; my($debug_virt) = ''; my($debug_lock) = ''; my($debug_kernel_config) = ''; my($sig_pci) = ''; my($os, $os_type, $os_date, $os_version, $os_version_pretty, $os_up, $os_distro, $custom_distro, $parent_os); my($jailed, $jailer) = (0, ''); my($hypervisor) = ''; my($cpu_bits) = 0; my($zero); my($hostname) = ''; my(%opts); my(%other_devices); my(%smbios); my(%dmi); my(%ipmi); my(%sysctl_dev); my(%sysctl_dev_raw); my(%possible_raid_vols); my(%interfaces); my(%pci_map); my(%pci_to_driver_raw); my(%pci_to_driver); my(%driver_to_pci); my(%irq_to_pci); my(%irq_to_all_pci); my(%irq_to_driver); my($ndrives) = 0; my($drive_id) = 1; my(%volumes); my(%drives); my(%props); my(%cpus); my(%logical_to_os); my(%controller_volumes); my(%hostid_synonyms); my(%hostid_to_pci); my(%hostid_to_driver); my(%pci_to_hostid); my($pci_all) = ""; my($guess_system) = "Unknown"; my($system_model_index); my(%ioports_map); my(%iomem_map); my(%interrupts_map); my(%irq_count); my(%dmesg); my(%partition_to_logical); my(%iomem_to_pci); my(%dev_to_pci); # freebsd mapping of devs (e.g. bge0, atapci0) to pci bus info my(%lvm_logical_to_physical); my(%procs); my(%interface_to_driver); my(%driver_version); my(%ioc_to_driver); my(%kernel); my(%debug_seen); my($procs, $processors); my($sent_email) = 0; my($clean_smbios_regex) = '(^|\s)(\(null\)|N\/A|_?To Be Filled( By O\.E\.M\.)?_?|NOT SUPPORT|Not Specified|Unspecified|empty||System Name|System Manufacturer|NO DIMM|No Module Installed|MemUndefined|None|Other|Unknown||ModulePartNumber\d+|Manufacturer\d+|SerNum\d+|AssetTagNum\d+|(A1_)?PartNum\d+|FFFFFFFF+|00000000+|\.\.\.\.\.\.*)(\s|$)'; 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|QEMU-HARDDISK|(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|iDRAC-Virtual-Floppy|AMI-Virtual-Floppy|VIRTUALFLOPPY|Logical-Disk-\d+|MegaRAID-SAS|MegaRAID-8704EM2|LSI-MR9260|HITACHI-DF600F'; my($ignore_scsi_models) = 'PepperC|SMSC|AMI.*Virtual Floppy|AVOCENT.*vmDisk|Virtual Device-FD'; my($ignore_networks) = 'vlan|bond|dummy|vmnet|sw|irda|venet|veth|xenbr|virbr|cipsec|wmaster|mskc|pan|yvmbr|yvmho|yvmnat|gre'; my(%chipset_types) = ( 'NB' => 'Northbridge', 'SB' => 'Southbridge', 'IB' => 'Integrated', ); 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,0x??" => "SB: Intel 82801DB (ICH4)", "0x24c08086,0x01" => "SB: Intel 82801DB step=A1 (ICH4)", "0x24c08086,0x02" => "SB: Intel 82801DB step=B0 (ICH4)", "0x24d08086" => "SB: Intel 82801E (ICH5)", # two steppings A2/A3, both with same rev 0x02 "0x25a18086,0x??" => "SB: Intel 6300ESB (ESB)", "0x25a18086,0x00" => "SB: Intel 6300ESB step=A0 (ESB)", "0x25a18086,0x01" => "SB: Intel 6300ESB step=A1/A2 (ESB)", "0x25a18086,0x02" => "SB: Intel 6300ESB step=A3 (ESB)", "0x26408086,0x??" => "SB: Intel 82801FB/FR (ICH6/R)", "0x26408086,0x03" => "SB: Intel 82801FB/FR step=B1 (ICH6/R)", "0x26408086,0x04" => "SB: Intel 82801FB/FR step=B2 (ICH6/R)", "0x26408086,0x05" => "SB: Intel 82801FB/FR step=C0 (ICH6/R)", "0x26418086,0x??" => "SB: Intel 82801FBM (ICH6M)", "0x26418086,0x03" => "SB: Intel 82801FBM step=B1 (ICH6M)", # HP NC6220 "0x26418086,0x04" => "SB: Intel 82801FBM step=B2 (ICH6M)", "0x26428086" => "SB: Intel 82801FW (ICH6W)", "0x26708086,0x??" => "SB: Intel 631xESB/632xESB (ESB2)", "0x26708086,0x00" => "IB: Intel 3100 step=A0 (Whitmore Lake)", "0x26708086,0x01" => "IB: Intel 3100 step=A1 (Whitmore Lake)", "0x26708086,0x08" => "SB: Intel 631xESB/632xESB step=A0 (ESB2)", "0x26708086,0x09" => "SB: Intel 631xESB/632xESB step=A1 (ESB2)", "0x27b08086" => "SB: Intel 82801GDH (ICH7DH)", "0x27b88086,0x??" => "SB: Intel 82801GB/GR (ICH7/R)", "0x27b88086,0x01" => "SB: Intel 82801GB/GR step=A1 (ICH7/R)", "0x27b98086,0x??" => "SB: Intel 82801GBM (ICH7M)", "0x27b98086,0x01" => "SB: Intel 82801GBM step=A1 (ICH7M)", "0x27b98086,0x02" => "SB: Intel 82801GBM step=B0 (ICH7M)", "0x27bd8086,0x??" => "SB: Intel 82801GHM (ICH7MDH)", "0x27bd8086,0x01" => "SB: Intel 82801GHM step=A1 (ICH7MDH)", "0x27bd8086,0x02" => "SB: Intel 82801GHM step=B0 (ICH7MDH)", "0x28108086,0x??" => "SB: Intel 82801HB/HR (ICH8/R)", "0x28108086,0x02" => "SB: Intel 82801HB/HR step=B0 (ICH8/R)", "0x28118086,0x??" => "SB: Intel 82801HEM (ICH8M-E)", "0x28118086,0x02" => "SB: Intel 82801HEM step=B0 (ICH8M-E)", "0x28118086,0x03" => "SB: Intel 82801HEM step=B1 (ICH8M-E)", # HP 6910p "0x28118086,0x04" => "SB: Intel 82801HEM step=B2 (ICH8M-E)", "0x28128086,0x??" => "SB: Intel 82801HH (ICH8DH)", "0x28128086,0x02" => "SB: Intel 82801HH step=B0 (ICH8DH)", "0x28148086,0x??" => "SB: Intel 82801HO (ICH8DO)", "0x28148086,0x02" => "SB: Intel 82801HO step=B0 (ICH8DO)", "0x28158086,0x??" => "SB: Intel 82801HBM (ICH8M)", "0x28158086,0x02" => "SB: Intel 82801HBM step=B0 (ICH8M)", "0x28158086,0x03" => "SB: Intel 82801HBM step=B1 (ICH8M)", # MSI GM965 "0x28158086,0x04" => "SB: Intel 82801HBM step=B2 (ICH8M)", "0x29128086,0x??" => "SB: Intel 82801IH (ICH9H)", # Home: +AHCI -RAID "0x29128086,0x02" => "SB: Intel 82801IH step=A2 (ICH9H)", # Home: +AHCI -RAID "0x29148086,0x??" => "SB: Intel 82801IO (ICH9O)", # Office: +AHCI +RAID "0x29148086,0x02" => "SB: Intel 82801IO step=A2 (ICH9O)", # Office: +AHCI +RAID "0x29168086,0x??" => "SB: Intel 82801IR (ICH9R)", # Raid: +AHCI +RAID "0x29168086,0x02" => "SB: Intel 82801IR step=A2 (ICH9R)", # Raid: +AHCI +RAID "0x29178086,0x??" => "SB: Intel 82801IBM (ICH9M)", # Base Moble: "0x29178086,0x02" => "SB: Intel 82801IBM step=A2 (ICH9M)", "0x29178086,0x03" => "SB: Intel 82801IBM step=A3 (ICH9M)", "0x29188086,0x??" => "SB: Intel 82801IB (ICH9)", # Base: -AHCI -RAID "0x29188086,0x02" => "SB: Intel 82801IB step=A2 (ICH9)", # Base: -AHCI -RAID "0x29198086,0x??" => "SB: Intel 82801IEM (ICH9M-E)", # Enhanced Moble: "0x29198086,0x02" => "SB: Intel 82801IEM step=A2 (ICH9M-E)", "0x29198086,0x03" => "SB: Intel 82801IEM step=A3 (ICH9M-E)", "0x3a148086,0x??" => "SB: Intel 82801JDO (ICH10DO)", "0x3a148086,0x02" => "SB: Intel 82801JDO step=B0 (ICH10DO)", "0x3a168086,0x??" => "SB: Intel 82801JIR (ICH10R)", # Raid: "0x3a168086,0x00" => "SB: Intel 82801JIR step=A0 (ICH10R)", # Raid: "0x3a188086,0x??" => "SB: Intel 82801JIB (ICH10)", # Base: "0x3a188086,0x00" => "SB: Intel 82801JIB step=A0 (ICH10)", # Base: "0x3a1a8086,0x??" => "SB: Intel 82801JD (ICH10D)", "0x3a1a8086,0x02" => "SB: Intel 82801JD step=B0 (ICH10D)", # not traditional south "0x3b028086,0x??" => "SB: Intel P55 PCH (Ibex Peak)", "0x3b028086,0x05" => "SB: Intel P55 PCH step=B2 (Ibex Peak)", # Gigabyte P55M-UD2 "0x3b028086,0x06" => "SB: Intel P55 PCH step=B3 (Ibex Peak)", "0x3b068086,0x??" => "SB: Intel H55 PCH (Ibex Peak)", "0x3b068086,0x06" => "SB: Intel H55 PCH step=B3 (Ibex Peak)", # MSI H55M-P31 "0x3b088086,0x??" => "SB: Intel H57 PCH (Ibex Peak)", "0x3b088086,0x06" => "SB: Intel H57 PCH step=B3 (Ibex Peak)", "0x3b0a8086,0x??" => "SB: Intel Q57 PCH (Ibex Peak)", "0x3b0a8086,0x06" => "SB: Intel Q57 PCH step=B3 (Ibex Peak)", "0x3b128086,0x??" => "SB: Intel 3400 PCH (Ibex Peak)", "0x3b128086,0x05" => "SB: Intel 3400 PCH step=B2 (Ibex Peak)", # SM X8SIL "0x3b148086,0x??" => "SB: Intel 3420 PCH (Ibex Peak)", "0x3b148086,0x05" => "SB: Intel 3420 PCH step=B2 (Ibex Peak)", # SM X8SIE "0x3b148086,0x06" => "SB: Intel 3420 PCH step=B3 (Ibex Peak)", "0x3b168086,0x??" => "SB: Intel 3450 PCH (Ibex Peak)", "0x3b168086,0x06" => "SB: Intel 3450 PCH step=B3 (Ibex Peak)", "0x1c468086,0x??" => "SB: Intel P67 PCH2 (Cougar Point)", "0x1c468086,0x04" => "SB: Intel P67 PCH2 step=B2 (Cougar Point)", "0x1c4a8086,0x??" => "SB: Intel H67 PCH2 (Cougar Point)", "0x1c4a8086,0x04" => "SB: Intel H67 PCH2 step=B2 (Cougar Point)", # Asus P8H67-M "0x1c528086,0x??" => "SB: Intel C202 PCH2 (Cougar Point)", "0x1c528086,0x04" => "SB: Intel C202 PCH2 step=B2 (Cougar Point)", "0x1c548086,0x??" => "SB: Intel C204 PCH2 (Cougar Point)", "0x1c548086,0x04" => "SB: Intel C204 PCH2 step=B2 (Cougar Point)", # DL120 G7 "0x1c568086,0x??" => "SB: Intel C206 PCH2 (Cougar Point)", "0x1c568086,0x04" => "SB: Intel C206 PCH2 step=B2 (Cougar Point)", # 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,0x??" => "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,0x??" => "NB: Intel E7230 (Mukilteo)", "0x27788086,0x00" => "NB: Intel E7230 (Mukilteo)", # PE850, DL320 G4, Intel S3000PT, DL320 G5, IR1250 "0x27788086,0xc0" => "NB: Intel 3000 step=A0 (Mukilteo 2)", # SM PDSML "0x25408086,0x??" => "NB: Intel E7500 (Plumas)", "0x25408086,0x02" => "NB: Intel E7500 step=A2 (Plumas)", # SM P4DP6 "0x25408086,0x03" => "NB: Intel E7500 step=A3 (Plumas)", # SM P4DP6, Tyan i7500 (S2722) "0x254c8086,0x??" => "NB: Intel E7501 (Plumas)", "0x254c8086,0x01" => "NB: Intel E7501 step=A1 (Plumas)", # Intel SE7501CW2 "0x35908086,0x??" => "NB: Intel E7520 (Lindenhurst)", # PE2850, DL360 G4, DL380 G4 "0x35908086,0x09" => "NB: Intel E7520 step=C1 (Lindenhurst)", "0x35908086,0x0a" => "NB: Intel E7520 step=C2 (Lindenhurst)", "0x35908086,0x0c" => "NB: Intel E7520 step=C4 (Lindenhurst)", "0x35928086,0x??" => "NB: Intel E7320 (Lindenhurst VS)", "0x35928086,0x09" => "NB: Intel E7320 step=C1 (Lindenhurst VS)", "0x35928086,0x0a" => "NB: Intel E7320 step=C2 (Lindenhurst VS)", "0x35928086,0x0c" => "NB: Intel E7320 step=C4 (Lindenhurst VS)", # Intel SE7320VP2 "0x26008086,0x??" => "NB: Intel E8500 (Twin Castle)", "0x26008086,0x10" => "NB: Intel E8500 step=B0 (Twin Castle)", # PE6850, DL580 G4 "0x26008086,0x11" => "NB: Intel E8500 step=B1 (Twin Castle)", "0x26008086,0x12" => "NB: Intel E8500 step=B2 (Twin Castle)", "0x25c08086,0x??" => "NB: Intel 5000X (Greencreek)", # PE2950, PE1950, DL140 G3, SM X7DAL "0x25c08086,0x12" => "NB: Intel 5000X step=B2 (Greencreek)", "0x25c08086,0x13" => "NB: Intel 5000X step=B3 (Greencreek)", "0x25c08086,0x30" => "NB: Intel 5000X step=G0 (Greencreek)", "0x25c08086,0x31" => "NB: Intel 5000X step=G1 (Greencreek)", "0x25d08086,0x??" => "NB: Intel 5000Z (Blackford)", "0x25d08086,0x93" => "NB: Intel 5000Z step=B3 (Blackford)", "0x25d48086,0x??" => "NB: Intel 5000V (Blackford VS)", # SM X7DVL-E, X7DVL-L, DL180 "0x25d48086,0x92" => "NB: Intel 5000V step=B2 (Blackford VS)", "0x25d48086,0x93" => "NB: Intel 5000V step=B3 (Blackford VS)", "0x25d48086,0xb1" => "NB: Intel 5000V step=G1 (Blackford VS)", "0x25d88086,0x??" => "NB: Intel 5000P (Blackford)", # Intel S5000PSL, PE1955, SM X7DBU, SM X7DBi+ "0x25d88086,0x92" => "NB: Intel 5000P step=B2 (Blackford)", "0x25d88086,0x93" => "NB: Intel 5000P step=B3 (Blackford)", "0x25d88086,0xb1" => "NB: Intel 5000P step=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 "0x2e108086,0x??" => "NB: Intel Q43/Q45 (Eaglelake)", "0x2e108086,0x02" => "NB: Intel Q43/Q45 step=A2 (Eaglelake)", "0x2e108086,0x03" => "NB: Intel Q43/Q45 step=A3 (Eaglelake)", # HP 6000 "0x2e208086,0x??" => "NB: Intel G43/G45/P43/P45 (Eaglelake)", "0x2e208086,0x02" => "NB: Intel G43/G45/P43/P45 step=A2 (Eaglelake)", # Gigabyte EP45-DS3R "0x2e208086,0x03" => "NB: Intel G43/G45/P43/P45 step=A3 (Eaglelake)", "0x2e308086,0x??" => "NB: Intel G41 (Eaglelake)", "0x2e308086,0x02" => "NB: Intel G41 step=A2 (Eaglelake)", "0x2e308086,0x03" => "NB: Intel G41 step=A3 (Eaglelake)", "0x65c08086,0x??" => "NB: Intel 5100 (San Clemente)", "0x65c08086,0x80" => "NB: Intel 5100 step=A0 (San Clemente)", # DL180 G5 "0x65c08086,0x90" => "NB: Intel 5100 step=B0 (San Clemente)", # Dell R300, SM X7DCL, SM X7DCA-L, HP BL260c G5 "0x40018086,0x??" => "NB: Intel 5400A (Seaburg)", "0x40018086,0x20" => "NB: Intel 5400A step=C0 (Seaburg)", "0x40038086,0x??" => "NB: Intel 5400B (Seaburg)", "0x40038086,0x20" => "NB: Intel 5400B step=C0 (Seaburg)", # Intel S5400SF, DL160 G5 "0x36008086,0x??" => "NB: Intel 7300 (Clarksboro)", "0x36008086,0x01" => "NB: Intel 7300 step=A1 (Clarksboro)", # DL580 G5, Intel S7000FC4UR "0x34008086,0x12" => "NB: Intel 5500 step=B2 (Tylersburg)", # SM X8DTN (pre-prod), SM X8STi "0x34038086,0x??" => "NB: Intel 5500 IOH-24D (Tylersburg)", "0x34038086,0x13" => "NB: Intel 5500 IOH-24D step=B3 (Tylersburg)", # Intel S5500WB, Dell M610, DCS XS23, SM X8DTL, DL320 G6 "0x34038086,0x22" => "NB: Intel 5500 IOH-24D step=C2 (Tylersburg)", # Dell C2100, C1100 "0x34058086,0x??" => "NB: Intel X58 (Tylersburg)", "0x34058086,0x12" => "NB: Intel X58 step=B2 (Tylersburg)", # Gigabyte EX58-UD3R "0x34058086,0x13" => "NB: Intel X58 step=B3 (Tylersburg)", "0x34058086,0x22" => "NB: Intel X58 step=C2 (Tylersburg)", "0x34068086,0x??" => "NB: Intel 5520 IOH-36D (Tylersburg)", "0x34068086,0x13" => "NB: Intel 5520 IOH-36D step=B3 (Tylersburg)", # Dell R710, Dell R610, DL180 G6, DL160 G6 "0x34068086,0x22" => "NB: Intel 5520 IOH-36D step=C2 (Tylersburg)", # SM X8DTT, Cisco UCS C200 M2 "0x34078086,0x??" => "NB: Intel 7500 (Boxboro-EX)", "0x34078086,0x22" => "NB: Intel 7500 step=B2 (Boxboro-EX)", # Dell R810 # 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 "0x5a121002" => "NB: AMD SR5670", # DL165 G7, Dell R815 "0x438d1002" => "SB: ATI SB600", # HP DC5750 "0x439d1002" => "SB: ATI SB700", # Dell R815, HP DC5850, DL165 G7 "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 "0x036410de" => "SB: nVIDIA MCP55 Pro", # IR2400, SM H8DMU # "0x036910de" => "SB: nVIDIA nForce Professional 3600", # IR2400 # replace with MCP55 "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 "0x06861106" => "SB: VIA VT82C686", # south - Asus CUV4X "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,0x??" => "NB: Intel 945 (Calistoga)", "0x27a08086,0x03" => "NB: Intel 945 step=A3 (Calistoga)", # NC6400 "0x2a008086,0x??" => "NB: Intel 965 (Crestline)", "0x2a008086,0x0c" => "NB: Intel 965 step=C0 (Crestline)", # HP 6910p, MSI GM965, AOpen i965GMt-LA "0x2a408086,0x??" => "NB: Intel Mobile 4 Series (Cantiga)", "0x2a408086,0x07" => "NB: Intel Mobile 4 Series step=B3 (Cantiga)", # Dell Latitude Z600, Dell Latitude E4300, HP 6930p "0x2a408086,0x09" => "NB: Intel Mobile 4 Series step=A1 (Cantiga)", ); my(%pci_classes) = ( # pciutils-2.2.4/lib/header.h # http://pci-ids.ucw.cz/read/PD "0x0100" => { 'type' => "Disk-Control", # SCSI 'required' => 1, }, "0x0101" => { 'type' => "Disk-Control", # IDE 'required' => 1, }, "0x0104" => { 'type' => "Disk-Control", # RAID 'required' => 1, }, "0x0105" => { 'type' => "Disk-Control", # ATA 'required' => 1, }, "0x0106" => { 'type' => "Disk-Control", # SATA 'required' => 1, }, "0x0107" => { 'type' => "Disk-Control", # SAS 'required' => 1, }, "0x0180" => { 'type' => "Disk-Control", # Other 'required' => 1, }, "0x0200" => { 'type' => "Network", # Ethernet 'required' => 1, }, "0x0280" => { 'type' => "Network", # Other (e.g. wireless) 'required' => 1, }, "0x0300" => { 'type' => "Graphics", # Display VGA 'required' => 0, }, "0x0c04" => { 'type' => "Disk-Control", # FC 'required' => 1, }, "0x0c03" => { 'type' => "Disk-Control", # USB 'required' => 1, 'hide' => 1, }, "0x0c06" => { 'type' => "Network", # InfiniBand 'required' => 1, }, "0x1000" => { 'type' => "Crypto", # Crypt Network 'required' => 1, }, ); 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' => { "0x00000000,0x10001af4,0x00" => "Qumranet Virtio Paravirtualized NIC", # KVM guest "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-10GbE", # Adapter "0x00011425,0x00301425,0x00" => "Chelsio T310 10GbE", # Adapter "0x1740103c,0x01004040,0x42" => "HP NC375T/NetXen NX3031 Gigabit", # Quad-port 1G Adapter "0x705b103c,0x01004040,0x42" => "HP NC522SFP/NetXen NX3031 10GbE", # Dual-port 10G Adapter "0x00000000,0x0035100b,0x30" => "NatSemi DP83065 Gigabit", "0x14051186,0x31061106,0x8b" => "DLink DFE-530TX/VIA VT6105 10/100", "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 "0x13001186,0x813910ec,0x10" => "DLink DFE-538TX/RealTek 8100C 10/100", "0x00015853,0x813910ec,0x20" => "Xen QEMU/RealTek 8139 10/100", # Xen QEMU "0x11001af4,0x813910ec,0x20" => "Bochs/RealTek 8139 10/100", # Bochs "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 "0xe0001458,0x816810ec,0x03" => "Gigabyte/RealTek 8111D Gigabit", # Gigabyte EX58-UD3R "0x76361462,0x816810ec,0x03" => "MSI/RealTek 8111D Gigabit", # MSI H55M-P31 "0x84321043,0x816810ec,0x06" => "Asus/RealTek 8111E Gigabit", # Asus P8H67-M "0x3022103c,0x816910ec,0x10" => "HP/RealTek RTL8110SX Gigabit", # HP DX2280 "0x301f103c,0x816910ec,0x10" => "HP/RealTek RTL8110SX Gigabit", # HP D290 "0x905510b7,0x905510b7,0x30" => "3Com 3c905B-TX 10/100", # 3Com 3C905B Fast Etherlink XL "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 "0x????????,0x037310de,0xa3" => "nVIDIA MCP55 Gigabit", "0x00261170,0x037310de,0xa3" => "Inventec/nVIDIA MCP55 Gigabit", # IR2400 "0xb0031028,0x037310de,0xa3" => "Dell/nVIDIA MCP55 Gigabit", # DCS CS24-NV5 "0x191115d9,0x037310de,0xa3" => "Supermicro/nVIDIA MCP55 Gigabit", # SM H8DMU "0xcb8410de,0x037310de,0xa3" => "nVIDIA MCP55 Gigabit", # Tyan S2927 "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 "0x????????,0x163914e4,0x20" => "Broadcom BCM5709 Gigabit", "0x090614e4,0x163914e4,0x20" => "Broadcom BCM5709 Gigabit", # Adapter from Dell "0x190614e4,0x163914e4,0x20" => "Broadcom BCM5709 Gigabit", # Adapter from Dell "0x037c1014,0x163914e4,0x20" => "IBM/Broadcom BCM5709 Gigabit", # IBM x3850 M2 "0x02351028,0x163914e4,0x20" => "Dell/Broadcom BCM5709 Gigabit", # Dell R710 "0x02361028,0x163914e4,0x20" => "Dell/Broadcom BCM5709 Gigabit", # Dell R610 "0x02d41028,0x163914e4,0x20" => "Dell/Broadcom BCM5709 Gigabit", # Dell R810 "0x1f261028,0x163914e4,0x20" => "Dell/Broadcom BCM5709 Gigabit", # Dell R815 "0x7059103c,0x163914e4,0x20" => "HP NC382T/Broadcom BCM5709 Gigabit", "0x????????,0x163a14e4,0x20" => "Broadcom BCM5709S Gigabit", "0x02871028,0x163a14e4,0x20" => "Dell/Broadcom BCM5709S Gigabit", # Dell M610 "0x????????,0x163b14e4,0x20" => "Broadcom BCM5716 Gigabit", "0x028c1028,0x163b14e4,0x20" => "Dell/Broadcom BCM5716 Gigabit", # Dell R410 "0x02a51028,0x163b14e4,0x20" => "Dell/Broadcom BCM5716 Gigabit", # Dell R210 "0x02f11028,0x163b14e4,0x20" => "Dell/Broadcom BCM5716 Gigabit", # Dell R510 "0x04891028,0x163b14e4,0x20" => "Dell/Broadcom BCM5716 Gigabit", # Dell R515 "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 3C996-SX/Broadcom BCM5701 Gigabit-SX", # 3Com 3C996-SX "0x100610b7,0x164514e4,0x15" => "3Com 3C996B-T/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 "0x3070103c,0x164a14e4,0x02" => "HP NC380T/Broadcom BCM5706 Gigabit", # HP NC380T Adapter "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 "0x01851028,0x165914e4,0x01" => "Dell/Broadcom BCM5721 Gigabit", # Dell PE800 "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 "0x165914e4,0x165914e4,0x21" => "Broadcom BCM5721 Gigabit", # Adapter "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 "0x705d103c,0x165b14e4,0x10" => "HP NC107i/Broadcom BCM5723 Gigabit", # DL120 G6 "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, DL320 G6 "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 "0x3029103c,0x167a14e4,0x02" => "HP/Broadcom BCM5754 Gigabit", # HP DC5850 "0x2808103c,0x167b14e4,0x02" => "HP/Broadcom BCM5755 Gigabit", # HP DC5700 "0x280a103c,0x167b14e4,0x02" => "HP/Broadcom BCM5755 Gigabit", # HP DC5750 "0x0944103c,0x167d14e4,0x11" => "HP/Broadcom BCM5751M Gigabit", # HP NC6220 "0x000c103c,0x169614e4,0x03" => "HP/Broadcom BCM5782 Gigabit", # "0x12bc103c,0x169614e4,0x03" => "HP/Broadcom BCM5782 Gigabit", # HP DC5000, HP D530 "0x352c1462,0x169a14e4,0x02" => "MSI/Broadcom BCM5786 Gigabit", # HP DX7400 "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 "0x00cb0e11,0x16c714e4,0x10" => "HP NC7781/Broadcom BCM5703 Gigabit", # HP NC7781 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 "0x10038086,0x10018086,0x02" => "Intel 82543GC Gigabit 1000-SX", # Intel PRO/1000 F Server Adapter "0x004a0e11,0x10018086,0x02" => "HP NC6136/Intel 82543GC Gigabit 1000-SX", # 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 "0x11078086,0x10098086,0x02" => "Intel 82544EI Gigabit 1000-SX", # Intel PRO/1000 XF 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 "0x00000000,0x100e8086,0x03" => "Intel 82540EM Gigabit", # Xen HVM domU "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 "0x81b41033,0x10108086,0x01" => "NEC/Intel 82546EB Gigabit", # NEC Express5800/120Rf-2 (SE7501WV2) "0x3002107b,0x10108086,0x01" => "Gateway/Intel 82546EB Gigabit", # Gateway 955 "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 "0x01671028,0x10758086,0x00" => "Dell/Intel 82547GI Gigabit", # PE700 "0x10761458,0x10768086,0x00" => "Gigabyte/Intel 82541GI Gigabit", # Gigabyte GA-7A8DRH "0x01651028,0x10768086,0x00" => "Dell/Intel 82541GI Gigabit", # PE750 "0x019a1028,0x10768086,0x00" => "Dell/Intel 82541GI Gigabit", # SC1425 buggy version, should be rev 0x05 "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 82541PI Gigabit", # Intel S3000AH "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 "0x117a8086,0x10798086,0x03" => "Intel 82546GB Gigabit", # Intel PRO/1000 MT Server Adapter "0x118a8086,0x10798086,0x03" => "Intel 82546GB Gigabit", # Intel Server Adapter "0x117a15d9,0x10798086,0x03" => "Supermicro/Intel 82546GB Gigabit", # SM X6DHP "0x018a1028,0x107b8086,0x03" => "Dell/Intel 82546GB Gigabit", # PE1855 "0x10828086,0x107d8086,0x06" => "Intel 82572EI Gigabit", # Intel PRO/1000 PT Server Adapter "0x10848086,0x107d8086,0x06" => "Intel 82572EI Gigabit", # "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 "0x9565107b,0x10968086,0x01" => "Gateway/Intel 82563EB Gigabit", # ?? "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 "0x8954152d,0x109a8086,0x00" => "Quanta/Intel 82573L Gigabit", # Quanta S49 "0x00008086,0x109a8086,0x03" => "Intel 82573L Gigabit", # DCS S45 "0x10a48086,0x10a48086,0x06" => "Intel 82571EB Quad Gigabit", # PRO/1000 PT Quad Port Server Adapter "0x11a48086,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 "0x34de8086,0x10a78086,0x02" => "Intel 82575EB Gigabit", # Intel Urbanna "0x10a715d9,0x10a78086,0x02" => "Supermicro/Intel 82575EB Gigabit", # SM X8DTN, SM H8DMT "0x8964152d,0x10a78086,0x02" => "Quanta/Intel 82575EB Gigabit", # Quanta S44 "0x5352108e,0x10a78086,0x02" => "Sun/Intel 82575EB Gigabit", # Sun X2270 "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 "0x00000000,0x10b98086,0xff" => "Intel 82572EI Gigabit", # adapter "0x10bc8086,0x10bc8086,0x06" => "Intel 82571EB Quad Gigabit", # "0x11bc8086,0x10bc8086,0x06" => "Intel 82571EB Quad Gigabit", # PRO/1000 PT Quad Port LP Server 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 "0x8954152d,0x10bd8086,0x02" => "Quanta/Intel 82566DM-2 Gigabit", # Quanta S49 "0xa16f8086,0x10c78086,0x01" => "Intel 82598EB 10GbE SR", # 10-Gigabit XF SR Server Adapter "0x????????,0x10c98086,0x01" => "Intel 82576 Gigabit", "0x34ea8086,0x10c98086,0x01" => "Intel 82576 Gigabit", # Intel S5500WB "0xa03c8086,0x10c98086,0x01" => "Intel 82576 Gigabit", # ET Dual Port Server Adapter "0xa04c8086,0x10c98086,0x01" => "Intel 82576 Gigabit", "0x010015d9,0x10c98086,0x01" => "Supermicro/Intel 82576 Gigabit", # SM X8DTU "0x060015d9,0x10c98086,0x01" => "Supermicro/Intel 82576 Gigabit", # SM X8DTU "0x10c915d9,0x10c98086,0x01" => "Supermicro/Intel 82576 Gigabit", # SM X8DTN, SM X8DT3 "0x323f103c,0x10c98086,0x01" => "HP NC362i/Intel 82576 Gigabit", # DL160 G6, DL180 G6, HP SL170z G6 "0x00000000,0x10c98086,0x01" => "Intel 82576 Gigabit", # DCS CS24-TY, DL160 G6 "0x8975152d,0x10c98086,0x01" => "Intel 82576 Gigabit", # DCS S99, DCS1100 "0x897b152d,0x10c98086,0x01" => "Intel 82576 Gigabit", # Dell C2100, C1100 "0x004a1170,0x10c98086,0x01" => "Inventec/Intel 82576 Gigabit", # DCS XS23-TY "0x00461170,0x10c98086,0x01" => "Inventec/Intel 82576 Gigabit", # Inventec 5241 "0x00651137,0x10c98086,0x01" => "Cisco/Intel 82576 Gigabit", # Cisco UCS C200 M2 "0x8963152d,0x10cc8086,0x00" => "Quanta/Intel 82567LM-2 Gigabit", # Quanta QSSC-890 "0x83971033,0x10cc8086,0x00" => "NEC/Intel 82567LM-2 Gigabit", # NEC Express5800/iR120a-1E "0x00008086,0x10cd8086,0x00" => "Intel 82567LF-2 Gigabit", # DCS XS23 "0x????????,0x10d38086,0x00" => "Intel 82574L Gigabit", "0x00008086,0x10d38086,0x00" => "Intel 82574L Gigabit", # DCS XS23 "0x040d15d9,0x10d38086,0x00" => "Supermicro/Intel 82574L Gigabit", # SM X8SIE "0x060515d9,0x10d38086,0x00" => "Supermicro/Intel 82574L Gigabit", # SM X8SIL "0x10d315d9,0x10d38086,0x00" => "Supermicro/Intel 82574L Gigabit", # SM X8STi, SM X8DTL "0x83691043,0x10d38086,0x00" => "Asus/Intel 82574L Gigabit", # Asus Z8NA-D6 "0x83971033,0x10d38086,0x00" => "NEC/Intel 82574L Gigabit", # NEC Express5800/iR120a-1E "0x1785103c,0x10d38086,0x00" => "HP/Intel 82574L Gigabit", # DL120 G7 "0x145a8086,0x10d68086,0x02" => "Intel 82575GB Quad Gigabit", # VT Quad Port Server Adapter "0x3048103c,0x10de8086,0x02" => "HP/Intel 82567LM-3 Gigabit", # HP 6000 "0xa02b8086,0x10e88086,0x01" => "Intel 82576 Gigabit", # ET Quad Port Server Adapter "0xa02c8086,0x10e88086,0x01" => "Intel 82576 Gigabit", # ET Quad Port Server Adapter "0x????????,0x10f58086,0x03" => "Intel 82567LM Gigabit", "0x024d1028,0x10f58086,0x03" => "Dell/Intel 82567LM Gigabit", # Dell Latitude E4300 "0x02c81028,0x10f58086,0x03" => "Dell/Intel 82567LM Gigabit", # Dell Latitude Z600 "0x30dc103c,0x10f58086,0x03" => "HP/Intel 82567LM Gigabit", # HP 6930p "0x7a118086,0x10fb8086,0x01" => "Intel 82599EB 10GbE", # Server Adapter X520-2 "0x000c8086,0x10fb8086,0x01" => "Intel 82599EB 10GbE", # 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", "0x00098086,0x12298086,0x04" => "Intel 82558 A 10/100", # adapter "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 "0xb01e0e11,0x12298086,0x05" => "Compaq NC3120/Intel 82558 B 10/100", "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 "0xb1630e11,0x12298086,0x08" => "Compaq NC3134/Intel 82559 C 10/100", # Compaq NC3134 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 "0x01a71028,0x27dc8086,0x01" => "Dell/Intel 82562GX (82801G ICH7) 10/100", # Dell Dimension 9100 "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 "0x13218086,0x42328086,0x00" => "Intel 5100AGN Wireless", # Dell Latitude Z600 "0x10118086,0x42368086,0x00" => "Intel 5300AGN Wireless", # HP 6930p "0x000c1028,0x431514e4,0x01" => "Dell/Broadcom BCM4312 BG Wireless", # Dell Latitude E4300 "0x00011028,0x432014e4,0x02" => "Dell/Broadcom BCM4306 BG Wireless", # infiniband "0x627415b3,0x627415b3,0x20" => "Mellanox MT25204 InfiniHost III", "0x627815b3,0x627815b3,0x20" => "Mellanox MT25208 InfiniHost III", "0x628215b3,0x628215b3,0x20" => "Mellanox MT25208 InfiniHost III", # iSCSI "0x01501077,0x30321077,0x00" => "QLogic QLE4060C Gigabit", "0x014f1077,0x40321077,0x00" => "QLogic QLE4060C iSCSI", "0x72119005,0x564a9005" => "Adaptec iSCSI ASA-7211", }, 'storage' => { "0x00000000,0x10011af4,0x00" => "Qumranet Virtio Paravirtualized Block Device", # KVM guest "0x94801b4b,0x94801b4b,0x03" => "Marvel 88SE9480 SAS/6 RAID", "0x10101aed,0x10001aed,0x01" => "Fusion-io 80GB SLC ioDrive", "0x10101aed,0x10031aed,0x01" => "Fusion-io 320GB MLC ioDrive", "0x10101aed,0x10051aed,0x01" => "Fusion-io 320GB MLC ioDrive", "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", "0x409a0e11,0x00460e11" => "HP Smart Array 641", "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 "0x3241103c,0x323a103c,0x01" => "HP Smart Array P212", "0x3243103c,0x323a103c,0x01" => "HP Smart Array P410", # DL180 G6 "0x3245103c,0x323a103c,0x01" => "HP Smart Array P410i", "0x3247103c,0x323a103c,0x01" => "HP Smart Array P411", "0x3249103c,0x323a103c,0x01" => "HP Smart Array P812", "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", "0x011b1028,0x000a1028,0x01" => "Dell PERC 3/Di", # PE1650 "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", # lsiutil/lsiutil.c "0x????????,0x00301000" => "LSILogic 1030 Ultra320", "0x00000000,0x00301000" => "LSILogic 1030 Ultra320", # VMware "0x10001000,0x00301000" => "LSILogic 1030 Ultra320", "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", "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", "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 "0x????????,0x00301000,0x01" => "LSILogic 1030 B0 Ultra320", "0x197615ad,0x00301000,0x01" => "LSILogic 1030 B0 Ultra320", # VMware "0x????????,0x00301000,0x07" => "LSILogic 1030 B2 Ultra320", "0x10001000,0x00301000,0x07" => "LSILogic 1030 B2 Ultra320", # Tyan S4882 "0x014a1028,0x00301000,0x07" => "Dell PE1750/LSILogic 1030 B2 Ultra320", "0x10401028,0x00301000,0x07" => "Dell/LSILogic 1030 B2 Ultra320", "0x00da0e11,0x00301000,0x07" => "HP/LSILogic 1030 B2 Ultra320", # DL145 G1 "0x00f40e11,0x00301000,0x07" => "HP/LSILogic 1030 B2 Ultra320", # DL140 G2 "0x????????,0x00301000,0x08" => "LSILogic 1030 C0 Ultra320", "0x10101000,0x00301000,0x08" => "LSILogic 1030 C0 Ultra320", # Tyan S4881 "0x002017c2,0x00301000,0x08" => "Newisys/LSILogic 1030 C0 Ultra320", # V40z "0x00da0e11,0x00301000,0x08" => "HP/LSILogic 1030 C0 Ultra320", # DL380 G4 "0x????????,0x00301000,0xc1" => "LSILogic 1020A A1 Ultra320", "0x50c01000,0x00301000,0xc1" => "LSILogic 1020A A1 Ultra320", "0x10001000,0x00301000,0xc1" => "LSILogic 1020A A1 Ultra320", "0x10051000,0x04131000" => "MegaRAID SAS 8300XLP", "0x????????,0x00501000,0x02" => "LSILogic SAS 1064", "0x10001000,0x00501000,0x02" => "LSILogic SAS 1064", "0x3228103c,0x00541000,0x00" => "HP/LSILogic SAS 1068", # DL140 G3 "0x????????,0x00541000,0x01" => "LSILogic SAS 1068", "0x1f041028,0x00541000,0x01" => "Dell/LSILogic SAS 5/E", # adapter "0x1f061028,0x00541000,0x01" => "Dell/LSILogic SAS 5/i", # PE2950, PE1950 "0x1f081028,0x00541000,0x01" => "Dell/LSILogic SAS 5/iR", # PE1955 "0x1f091028,0x00541000,0x01" => "Dell/LSILogic SAS 5/iR", # PE860, SC1435 "0x3228103c,0x00541000,0x01" => "HP/LSILogic SAS 1068", # DL140 G3 "0x83361033,0x00541000,0x01" => "NEC/LSILogic SAS 1068", # NEC Express5800/120Rg-1 "0x????????,0x00561000,0x02" => "LSILogic SAS 1064E B1", "0x10001000,0x00561000,0x02" => "LSILogic SAS 1064E B1", "0x34798086,0x00561000,0x02" => "Intel/LSILogic SAS 1064E B1", # Intel S5000PSL "0x894b152d,0x00561000,0x02" => "Quanta/LSILogic SAS 1064E B1", # Quanta S45, Quanta S47 "0x????????,0x00561000,0x04" => "LSILogic SAS 1064E B2", "0x10001000,0x00561000,0x04" => "LSILogic SAS 1064E B2", "0x346c8086,0x00561000,0x04" => "Intel/LSILogic SAS 1064E B2", # Dell S5400SF "0x34788086,0x00561000,0x04" => "Intel/LSILogic SAS 1064E B2", # Dell S5000PSL-SAS "0x????????,0x00561000,0x08" => "LSILogic SAS 1064E B3", "0x10001000,0x00561000,0x08" => "LSILogic SAS 1064E B3", "0x322b103c,0x00561000,0x08" => "HP/LSILogic SAS 1064E B3", # DL160 G5 "0x30911000,0x00561000,0x08" => "LSILogic SAS 1064E B3", "0x896d152d,0x00561000,0x08" => "Quanta/LSILogic SAS 1064E B3", # Cisco UCS C200 M2 "0x????????,0x00581000" => "LSILogic SAS 1068E", "0x10001000,0x00581000,0x04" => "LSILogic SAS 1068E B2", # Tyan S5397 (onboard) "0x538310f1,0x00581000,0x04" => "Tyan/LSILogic SAS 1068E B2", # Tyan S5383 "0x10001000,0x00581000,0x08" => "LSILogic SAS 1068E B3", "0x31401000,0x00581000,0x08" => "LSILogic SAS 1068E B3", # Dell S45 "0x1f0e1028,0x00581000,0x08" => "Dell/LSILogic SAS 6/iR (1068E B3)", # Dell R200 (card) "0x1f0f1028,0x00581000,0x08" => "Dell/LSILogic SAS 6/iR (1068E B3)", # Dell R410 "0x1f101028,0x00581000,0x08" => "Dell/LSILogic SAS 6/iR (1068E B3)", # Dell PE1950 (integrated) "0xa38015d9,0x00581000,0x08" => "Supermicro/LSILogic SAS 1068E B3", # SM X7DCT (add-on card?) "0xa48015d9,0x00581000,0x08" => "Supermicro/LSILogic SAS 1068E B3", # SM X7DCL-3 "0x000115d9,0x00581000,0x08" => "Supermicro/LSILogic SAS 1068E B3", # SM X8DT3 "0x000615d9,0x00581000,0x08" => "Supermicro/LSILogic SAS 1068E B3", # SM X8DTL "0xa18015d9,0x00581000,0x08" => "Supermicro/LSILogic SAS 1068E B3", # OCZ Z-Drive p84 PCI-Express SSD "0x3229103c,0x00581000,0x08" => "HP/LSILogic SAS 1068E B3", # DL160 G5 "0x10001170,0x00581000,0x08" => "Inventec/LSILogic SAS 1068E B3", # Dell XS23-TY3 "0xa18015d9,0x00591000,0x04" => "Supermicro/LSILogic 1068E B2 AOC-SAS-L4iR", # SM UIO "0x000115d9,0x00591000,0x08" => "Supermicro/LSILogic 1068E B3 AOC-SAS-L4iR", # SM X8DT3 "0x000415d9,0x00591000,0x08" => "Supermicro/LSILogic 1068E B3 AOC-SAS-L4iR", # SM X8STi "0xa48015d9,0x00591000,0x08" => "Supermicro/LSILogic 1068E B3 AOC-SAS-L4iR", # SM X7DCL-3 "0x????????,0x00601000,0x??" => "LSILogic MegaRAID SAS 1078", "0x34cc8086,0x00601000,0x03" => "Intel/LSILogic MegaRAID SAS 1078", # Intel Tigerton "0x002f1170,0x00601000,0x03" => "Inventec/LSILogic MegaRAID SAS 1078", # Inventec 5220 "0xc08015d9,0x00601000,0x03" => "Supermicro/LSILogic MegaRAID SAS 1078", "0x10131000,0x00601000,0x04" => "LSILogic MegaRAID SAS 1078", "0x10211000,0x00601000,0x04" => "LSILogic MegaRAID SAS 8704EM2", "0x35088086,0x00601000,0x04" => "Intel/LSILogic MegaRAID SAS 1078", # Quanta QSSC-98J "0x1f0a1028,0x00601000,0x04" => "Dell/LSILogic PERC 6/E", # DCS Adapter "0x1f0b1028,0x00601000,0x04" => "Dell/LSILogic PERC 6/i", # DCS Adapter "0x1f0c1028,0x00601000,0x04" => "Dell/LSILogic PERC 6/i", # PE2950 III, Dell R900 "0x1f0d1028,0x00601000,0x04" => "Dell/LSILogic PERC 6/i", # Dell M610 "0x1f111028,0x00601000,0x04" => "Dell/LSILogic CERC 6/i", # Dell M610 "0x03631014,0x00601000,0x04" => "IBM/LSILogic ServeRAID-MR10k", "0x03791014,0x00601000,0x04" => "IBM/LSILogic ServeRAID-MR10M", "0xc18015d9,0x00601000,0x04" => "Supermicro/LSILogic MegaRAID SAS 1078", "0x????????,0x00621000,0x03" => "LSILogic SAS 1078 C1", "0x03661014,0x00621000,0x03" => "IBM/LSILogic SAS 1078 C1", # IBM x3850 M2 "0x????????,0x00621000,0x04" => "LSILogic SAS 1078 C2", "0x03661014,0x00621000,0x04" => "IBM/LSILogic SAS 1078 C2", # IBM x3859 M2 "0x????????,0x00721000,0x02" => "LSILogic SAS2008 SAS-2", "0x00721000,0x00721000,0x02" => "LSILogic SAS2008 SAS-2", # SM UIO card "0x1f1d1028,0x00721000,0x02" => "Dell/LSILogic PERC H200", # Dell R410 adapter "0x897a152d,0x00721000,0x02" => "Quanta/LSILogic SAS2008 SAS-2", # Dell C2100 daughtercard "0x92611000,0x00791000,0x03" => "LSILogic MegaRAID SAS 9260-8i", # Adapter "0x1f161028,0x00791000,0x04" => "Dell/LSILogic PERC H700", # Dell R410 adapter "0x1f171028,0x00791000,0x04" => "Dell/LSILogic PERC H700", # Dell R810 integrated "0x1f161028,0x00791000,0x05" => "Dell/LSILogic PERC H700", # Dell R410 adapter "0x1f171028,0x00791000,0x05" => "Dell/LSILogic PERC H700", # Dell R515 "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 "0x808015d9,0x801d9005,0x10" => "Supermicro/Adaptec AIC-7902B Ultra320", # SM X7DB8 "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 "0x81b41033,0x801f9005,0x03" => "NEC/Adaptec AIC-7902 Ultra320", # NEC Express5800/120Rf-2 (SE7501WV2) "0x3002107b,0x801f9005,0x03" => "Gateway/Adaptec AIC-7902 Ultra320", # Gateway 955 "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 "0x02cc1014,0x809d9005,0x10" => "IBM/Adaptec AIC-7902B Ultra320 RAID", # IBM x346 "0x90059005,0x809f9005" => "Adaptec AIC-7902 Ultra320 RAID", "0x028e1014,0x02509005,0x07" => "IBM/Adaptec ServeRAID-7k Ultra320", # IBM x346 "0x02859005,0x02859005" => "Adaptec 2200S Ultra320 RAID", "0x02869005,0x02859005" => "Adaptec 2120S Ultra320 RAID", "0x02b69005,0x02859005,0x09" => "Adaptec RAID 5805 SAS", "0x02d19005,0x02859005,0x09" => "Adaptec RAID 5405 SAS", "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 "0x121217d3,0x168017d3,0x00" => "Areca ARC-1680 SAS RAID", "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", "0x100413c1,0x100413c1,0x01" => "3ware 9650SE 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", "0x????????,0x23121077,0x02" => "QLogic ISP2312 2G FC", "0x00091077,0x23121077,0x02" => "QLogic ISP2312 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", "0x01000e11,0x23121077,0x02" => "HP/QLogic ISP2312 2G FC", "0x01331077,0x24221077" => "QLogic ISP2422 4G FC", "0x01341077,0x24221077" => "QLogic ISP2422 4G FC", "0x01371077,0x24321077,0x02" => "QLogic ISP2432 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", "0x????????,0x25321077,0x02" => "QLogic ISP2532 8G FC", "0x015d1077,0x25321077,0x02" => "QLogic ISP2532 8G FC", "0x3263103c,0x25321077,0x02" => "HP/QLogic ISP2532 8G FC", "0x8471101e,0x12161077" => "QLogic ISP12160 Ultra160 RAID", # PE6650 "0x8493101e,0x12161077" => "QLogic ISP12160 Ultra160 RAID", # PE2650 "0xf0a510df,0xf0a510df" => "Emulex LP1050 2G FC", # Emulex Thor LightPulse "0xf0e510df,0xf0e510df,0x02" => "Emulex LPe1150-E 4G FC", "0x3281103c,0xf10010df,0x03" => "Emulex Saturn-X LP FC", "0xf90010df,0xf90010df" => "Emulex LP9000 2G FC", "0xfa0010df,0xfa0010df" => "Emulex LP10000 2G FC", # Emulex Thor-X LightPulse "0x00141657,0x00131657,0x01" => "Brocade 425/825 4G/8G FC", # PCI-E Dual Port Adapter "0xa48015d9,0x82131283" => "Supermicro/ITE IT8213F ATA/133", "0x82121043,0x612111ab,0xb1" => "Asus/Marvell 88SE6121 ATA/133 + SATA/300", # Asus P5Q-Deluxe "0xb0001458,0x2363197b,0x02" => "Gigabyte/JMicron JMB363 ATA/133 + SATA/300", # Gigabyte EX58-UD3R "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 "0x280a103c,0x438c1002,0x00" => "HP/ATI SB600 ATA/133", # HP DC5750 "0x2812103c,0x43801002,0x00" => "HP/ATI SB600 SATA/300", # HP DC5750 "0x04441028,0x43901002,0x00" => "Dell/ATI SB700 SATA/300", # Dell R815 "0x04891028,0x43901002,0x00" => "Dell/ATI SB700 SATA/300", # Dell R515 "0x3029103c,0x43901002,0x00" => "HP/ATI SB700 SATA/300", # HP DC5850 "0x43911002,0x43911002,0x00" => "ATI SB700 SATA/300 AHCI", # HP DL165 G7 "0x3338103c,0x439c1002,0x00" => "HP/ATI SB700 ATA/133", # HP DL165 G7 "0x04891028,0x439c1002,0x00" => "Dell/ATI SB700 ATA/133", # Dell R515 "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 "0x838f1043,0x04151106,0x00" => "Asus/VIA VT6415 ATA/150", # Asus P8H67-M "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 "0x34108086,0x4d30105a" => "Intel/Promise PDC20267 ATA/100", # Intel SCB20-A "0x4d68105a,0x4d68105a,0x02" => "Promise PDC20268 ATA/100", "0x6619105a,0x3373105a" => "Promise PDC20378 SATA/150", # Tyan S2880 "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 "0x25121095,0x35121095,0x01" => "SiI 3512 SATA/150 RAID", # Adapter "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 "0x02051028,0x024a1166,0x00" => "Dell/ServerWorks HT-1000 SATA/150", # 2970 "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", # "0x00015853,0x70108086,0x00" => "Xen QEMU/Intel 82371SB PIIX3 ATA/33", # Xen QEMU "0x11001af4,0x70108086,0x00" => "Bochs/Intel 82371SB PIIX3 ATA/33", # Bochs "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 "0x81b41033,0x248b8086,0x02" => "NEC/Intel 82801CA ICH3 ATA/100", # NEC Express5800/120Rf-2 (SE7501WV2) "0x3002107b,0x248b8086,0x02" => "Gateway/Intel 82801CA ICH3 ATA/100", # Gateway 955 "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 "0x02dd1014,0x24db8086,0x02" => "IBM/Intel ICH5 82801EB ATA/100", # IBM x346 "0x658015d9,0x24db8086,0x02" => "Supermicro/Intel ICH5 82801EB ATA/100", # SM X6DHP "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 "0x26528086,0x26528086,0x03" => "Intel ICH6R 82801FR SATA/150", # Dell PE800 "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 "0x01851028,0x266f8086,0x03" => "Dell/Intel ICH6 82801FB ATA/100", # Dell PE800 "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 "0x03811014,0x27c08086,0x01" => "IBM/Intel ICH7 82801GB SATA/300", # IBM x3850 M2 "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 "0xb58015d9,0x27c18086,0x01" => "Supermicro/Intel ICH7 82801GR SATA/300 AHCI", # SM PDSBM "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 "0x858115d9,0x27c38086,0x01" => "Supermicro/Intel ICH7 82801GB SATA/300 RAID", # SM PDSML "0x01a71028,0x27c38086,0x01" => "Dell/Intel ICH7 82801GB SATA/300 RAID", # Dell Dimension 9100 "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 "0x01a71028,0x27df8086,0x01" => "Dell/Intel ICH7 82801G ATA/100", # Dell Dimension 9100 "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-PRE "0xdc8015d9,0x28228086,0x02" => "Supermicro/Intel ICH8 82801H SATA/300 RAID", # SM X7DCA-L "0x8963152d,0x28228086,0x00" => "Quanta/Intel ICH8 82801H SATA/300 RAID", # Quanta QSSC-890 "0x8969152d,0x28228086,0x00" => "Quanta/Intel ICH8 82801H SATA/300 RAID", # Quanta QSSC-980J # ICH9 disguised as ICH8 "0xa48015d9,0x28228086,0x02" => "Supermicro/Intel ICH9 (ICH8) SATA/300 RAID", # SM X7DCL # PCH disguised as ICH8, search for 2822 in http://www.intel.com/Assets/PDF/datasheet/322169.pdf "0x????????,0x28228086,0x05" => "Intel PCH (ICH8) SATA/300 RAID", "0x3318103c,0x28228086,0x05" => "HP/Intel PCH (ICH8) SATA/300 RAID", # DL120 G6 "0x00471170,0x28228086,0x00" => "Inventec/Intel PCH (ICH8) SATA/300 RAID", # Dell XS23-TY3 "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", "0x30be103c,0x28298086,0x03" => "HP/Intel ICH8M 82801HBM SATA/300 AHCI", # HP 6910p "0x30c1103c,0x28298086,0x03" => "HP/Intel ICH8M 82801HBM SATA/300 AHCI", # HP 6910p "0x80301462,0x28298086,0x03" => "MSI/Intel ICH8M 82801HBM SATA/300 AHCI", # MSI GM965 "0x024d1028,0x282a8086,0x03" => "Dell/Intel ICH9M SATA/300 RAID", # Dell Latitude E4300, ICH9 uses same DID as ICH8 for RAID "0x????????,0x28508086,0x03" => "Intel ICH8M 82801HBM ATA/100", "0x30be103c,0x28508086,0x03" => "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, HP SE1101 "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 "0xf28015d9,0x29208086,0x02" => "Supermicro/Intel ICH9 82801I 4 Port SATA/300", # SM X8DTN-PRE "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 "0x02351028,0x29218086,0x02" => "Dell/Intel ICH9 82801IB 2 Port SATA/300", # Dell R710 "0x02361028,0x29218086,0x02" => "Dell/Intel ICH9 82801IB 2 Port SATA/300", # Dell R610 "0x73521462,0x29218086,0x02" => "MSI/Intel ICH9 82801IB 2 Port SATA/300", # HP DX7400 "0x????????,0x29228086,0x02" => "Intel ICH9 82801I 6 Port SATA/300 AHCI", "0x10001458,0x29228086,0x02" => "Gigabyte/Intel ICH9 82801I 6 Port SATA/300 AHCI", # Gigabyte R116 "0xdc8015d9,0x29228086,0x02" => "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-PRE "0xf28015d9,0x29228086,0x02" => "Intel ICH9 82801I 6 Port SATA/300 AHCI", # 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 "0x8964152d,0x29228086,0x02" => "Quanta/Intel ICH9 82801I 6 Port SATA/300 AHCI", # Quanta S44 "0x83661033,0x29228086,0x02" => "NEC/Intel ICH9 82801I 6 Port SATA/300 AHCI", # NEC Express5800/i120Ra-e1 "0xa48015d9,0x29228086,0x02" => "Supermicro/Intel ICH9 82801I 6 Port SATA/300 AHCI", # SM X7DCL "0x31f4103c,0x29228086,0x02" => "HP/Intel ICH9 82801I 6 Port SATA/300 AHCI", # HP SE1101 "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????????,0x29258086,0x02" => "Intel ICH9 82801IR 4 Port SATA/300 RAID", "0x31f4103c,0x29258086,0x02" => "HP/Intel ICH9 82801IR 4 Port SATA/300 RAID", # DL180 G5 "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, HP SE1101 "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 "0xf28015d9,0x29268086,0x02" => "Supermicro/Intel ICH9 82801I 2 Port SATA/300", # SM X8DTN-PRE "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 "0x73521462,0x29268086,0x02" => "MSI/Intel ICH9 82801I 2 Port SATA/300", # HP DX7400 "0x????????,0x29298086,0x03" => "Intel ICH9M SATA/300 AHCI", "0x02c81028,0x29298086,0x03" => "Dell/Intel ICH9M SATA/300 AHCI", # Dell Latitude Z600 "0x30dc103c,0x29298086,0x03" => "HP/Intel ICH9M SATA/300 AHCI", # HP 6930p "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 "0x01671028,0x25a38086,0x02" => "Dell/Intel 6300ESB SATA/150", # PE700 "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 "0x53808086,0x26808086,0x09" => "Intel 631xESB SATA/300", # Tyan S5383 "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 "0x32010e11,0x26808086,0x09" => "HP/Intel 631xESB SATA/300", # DL580 G5 "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 "0x9565107b,0x26808086,0x09" => "Gateway/Intel 631xESB SATA/300", # ?? "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 "0x003a1170,0x26818086,0x09" => "Inventec/Intel 631xESB SATA/300 AHCI", # Inventec 5220 "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 "0x34d58086,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 "0x003a1170,0x26828086,0x09" => "Inventec/Intel 631xESB SATA/300 RAID", # Inventec 5220 "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 "0x53808086,0x269e8086,0x09" => "Intel 631xESB ATA/133", # Tyan S5383 "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) "0x978015d9,0x269e8086,0x09" => "Supermicro/Intel 631xESB ATA/133", # SM X7DBU "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 "0x9565107b,0x269e8086,0x09" => "Gateway/Intel 631xESB ATA/133", # ?? "0x30c1103c,0x2a068086,0x0c" => "Intel PM965/GM965 PT IDER", # HP 6910p "0x30dc103c,0x2a468086,0x07" => "Intel Mobile 4 Series PT IDER", # HP 6930p "0x3048103c,0x2e168086,0x03" => "Intel 4 Series PT IDER", # HP 6000 "0x3048103c,0x3a008086,0x02" => "Intel ICH10 82801J 4 Port SATA/300", # HP 6000 "0x3048103c,0x3a028086,0x02" => "Intel ICH10 82801J 6 Port SATA/300 AHCI", # HP 6000 (corporate vs. consumer - 0x3a22) "0x3048103c,0x3a068086,0x02" => "Intel ICH10 82801J 2 Port SATA/300", # HP 6000 "0x????????,0x3a208086,0x00" => "Intel ICH10 82801J 4 Port SATA/300", "0x3a208086,0x3a208086,0x00" => "Intel ICH10 82801J 4 Port SATA/300", # DL170h G6 "0x34de8086,0x3a208086,0x00" => "Intel ICH10 82801J 4 Port SATA/300", # Intel Urbanna "0x34ea8086,0x3a208086,0x00" => "Intel ICH10 82801J 4 Port SATA/300", # Intel S5500WB "0xb0021458,0x3a208086,0x00" => "Gigabyte/Intel ICH10 82801J 4 Port SATA/300", # Gigabyte EP45-DS3R "0x330b103c,0x3a208086,0x00" => "HP/Intel ICH10 82801J 4 Port SATA/300", # DL180 G6, DL160 G6 "0x330d103c,0x3a208086,0x00" => "HP/Intel ICH10 82801J 4 Port SATA/300", # SE1120, DL320 G6 "0x8969152d,0x3a208086,0x00" => "Quanta/Intel ICH10 82801J 4 Port SATA/300", # DCS CS24-TY, DCS1100 "0x8975152d,0x3a208086,0x00" => "Quanta/Intel ICH10 82801J 4 Port SATA/300", # DCS CS24-TY "0x897a152d,0x3a208086,0x00" => "Quanta/Intel ICH10 82801J 4 Port SATA/300", # Dell C1100 "0x897b152d,0x3a208086,0x00" => "Quanta/Intel ICH10 82801J 4 Port SATA/300", # Dell C2100 "0x00461170,0x3a208086,0x00" => "Inventec/Intel ICH10 82801J 4 Port SATA/300", # Inventec 5241 "0x00471170,0x3a208086,0x00" => "Inventec/Intel ICH10 82801J 4 Port SATA/300", # DCS XS23 "0x000615d9,0x3a208086,0x00" => "Supermicro/Intel ICH10 82801J 4 Port SATA/300", # SM X8DTL "0x000915d9,0x3a208086,0x00" => "Supermicro/Intel ICH10 82801J 4 Port SATA/300", # SM X8STi "0x060015d9,0x3a208086,0x00" => "Supermicro/Intel ICH10 82801J 4 Port SATA/300", # SM X8DTU "0x10a715d9,0x3a208086,0x00" => "Supermicro/Intel ICH10 82801J 4 Port SATA/300", # SM X8DTN "0x000115d9,0x3a208086,0x00" => "Supermicro/Intel ICH10 82801J 4 Port SATA/300", # SM X8DT3 "0xa88015d9,0x3a208086,0x00" => "Supermicro/Intel ICH10 82801J 4 Port SATA/300", # SM X8DT3 "0x5352108e,0x3a208086,0x00" => "Sun/Intel ICH10 82801J 4 Port SATA/300", # Sun X2270 "0x83621043,0x3a208086,0x00" => "Asus/Intel ICH10 82801J 4 Port SATA/300", # Asus Z8NA-D6 "0x8975152d,0x3a208086,0x00" => "Quanta/Intel ICH10 82801J 4 Port SATA/300", # Dell S99 "0x028c1028,0x3a208086,0x00" => "Dell/Intel ICH10 82801J 4 Port SATA/300", # Dell R410 "0x02f11028,0x3a208086,0x00" => "Dell/Intel ICH10 82801J 4 Port SATA/300", # Dell R510 "0x02d41028,0x3a208086,0x00" => "Dell/Intel ICH10 82801J 4 Port SATA/300", # Dell R810 "0x83971033,0x3a208086,0x00" => "NEC/Intel ICH10 82801J 4 Port SATA/300", # NEC Express5800/iR120a-1E "0x01011137,0x3a208086,0x00" => "Cisco/Intel ICH10 82801J 4 Port SATA/300", # Cisco UCS C200 M2 "0x????????,0x3a228086,0x00" => "Intel ICH10 82801J 6 Port SATA/300 AHCI", "0x3a228086,0x3a228086,0x00" => "Intel ICH10 82801J 6 Port SATA/300 AHCI", # HP SL170z G6 "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 "0x3118103c,0x3a228086,0x00" => "HP/Intel ICH10 82801J 6 Port SATA/300 AHCI", # SE1170s "0x330b103c,0x3a228086,0x00" => "HP/Intel ICH10 82801J 6 Port SATA/300 AHCI", # DL180 G6, DL160 G6 "0x34ea8086,0x3a228086,0x00" => "Intel ICH10 82801J 6 Port SATA/300 AHCI", # Intel S5500WB "0x8969152d,0x3a228086,0x00" => "Quanta/Intel ICH10 82801J 6 Port SATA/300 AHCI", # DCS CS24-TY, DCS1100 "0x8975152d,0x3a228086,0x00" => "Quanta/Intel ICH10 82801J 6 Port SATA/300 AHCI", # DCS CS24-TY "0x897a152d,0x3a228086,0x00" => "Quanta/Intel ICH10 82801J 6 Port SATA/300 AHCI", # Dell C1100 "0x897b152d,0x3a228086,0x00" => "Quanta/Intel ICH10 82801J 6 Port SATA/300 AHCI", # Dell C2100 "0x8963152d,0x3a228086,0x00" => "Quanta/Intel ICH10 82801J 6 Port SATA/300 AHCI", # Quanta QSSC-890 "0x00461170,0x3a228086,0x00" => "Inventec/Intel ICH10 82801J 6 Port SATA/300 AHCI", # Inventec 5241 "0x00471170,0x3a228086,0x00" => "Inventec/Intel ICH10 82801J 6 Port SATA/300 AHCI", # DCS XS23 "0x000615d9,0x3a228086,0x00" => "Supermicro/Intel ICH10 82801J 6 Port SATA/300 AHCI", # SM X8DTL "0x000915d9,0x3a228086,0x00" => "Supermicro/Intel ICH10 82801J 6 Port SATA/300 AHCI", # SM X8STi "0x060015d9,0x3a228086,0x00" => "Supermicro/Intel ICH10 82801J 6 Port SATA/300 AHCI", # SM X8DTU "0x10a715d9,0x3a228086,0x00" => "Supermicro/Intel ICH10 82801J 6 Port SATA/300 AHCI", # SM X8DTN "0x000115d9,0x3a228086,0x00" => "Supermicro/Intel ICH10 82801J 6 Port SATA/300 AHCI", # SM X8DT3 "0xa88015d9,0x3a228086,0x00" => "Supermicro/Intel ICH10 82801J 6 Port SATA/300 AHCI", # SM X8DT3 "0x000715d9,0x3a228086,0x00" => "Supermicro/Intel ICH10 82801J 6 Port SATA/300 AHCI", # SM X8DTT "0x5352108e,0x3a228086,0x00" => "Sun/Intel ICH10 82801J 6 Port SATA/300 AHCI", # Sun X2270 "0x83621043,0x3a228086,0x00" => "Asus/Intel ICH10 82801J 6 Port SATA/300 AHCI", # Asus Z8NA-D6 "0x028c1028,0x3a228086,0x00" => "Dell/Intel ICH10 82801J 6 Port SATA/300 AHCI", # Dell R410 "0x02f11028,0x3a228086,0x00" => "Dell/Intel ICH10 82801J 6 Port SATA/300 AHCI", # Dell R510 "0x02d41028,0x3a228086,0x00" => "Dell/Intel ICH10 82801J 6 Port SATA/300 AHCI", # Dell R810 "0x????????,0x3a258086,0x00" => "Intel ICH10R 82801J SATA/300 RAID", "0x3118103c,0x3a258086,0x00" => "HP/Intel ICH10R 82801J SATA/300 RAID", # DL160 G6 "0x028c1028,0x3a258086,0x00" => "Dell/Intel ICH10R 82801J SATA/300 RAID", # Dell R410 "0x????????,0x3a268086,0x00" => "Intel ICH10 82801J 2 Port SATA/300", "0x34de8086,0x3a268086,0x00" => "Intel ICH10 82801J 2 Port SATA/300", # Intel Urbanna "0x34ea8086,0x3a268086,0x00" => "Intel ICH10 82801J 2 Port SATA/300", # Intel S5500WB "0xb0021458,0x3a268086,0x00" => "Gigabyte/Intel ICH10 82801J 2 Port SATA/300", # Gigabyte EP45-DS3R "0x330b103c,0x3a268086,0x00" => "HP/Intel ICH10 82801J 2 Port SATA/300", # DL180 G6, DL160 G6 "0x330d103c,0x3a268086,0x00" => "HP/Intel ICH10 82801J 2 Port SATA/300", # SE1120 "0x8969152d,0x3a268086,0x00" => "Quanta/Intel ICH10 82801J 2 Port SATA/300", # DCS CS24-TY, DCS1100 "0x8975152d,0x3a268086,0x00" => "Quanta/Intel ICH10 82801J 2 Port SATA/300", # DCS CS24-TY "0x897a152d,0x3a268086,0x00" => "Quanta/Intel ICH10 82801J 2 Port SATA/300", # Dell C1100 "0x897b152d,0x3a268086,0x00" => "Quanta/Intel ICH10 82801J 2 Port SATA/300", # Dell C2100 "0x00461170,0x3a268086,0x00" => "Inventec/Intel ICH10 82801J 2 Port SATA/300", # Inventec 5241 "0x00471170,0x3a268086,0x00" => "Inventec/Intel ICH10 82801J 2 Port SATA/300", # DCS XS23 "0x000615d9,0x3a268086,0x00" => "Supermicro/Intel ICH10 82801J 2 Port SATA/300", # SM X8DTL "0x000915d9,0x3a268086,0x00" => "Supermicro/Intel ICH10 82801J 2 Port SATA/300", # SM X8STi "0x060015d9,0x3a268086,0x00" => "Supermicro/Intel ICH10 82801J 2 Port SATA/300", # SM X8DTU "0x10a715d9,0x3a268086,0x00" => "Supermicro/Intel ICH10 82801J 2 Port SATA/300", # SM X8DTN "0x000115d9,0x3a268086,0x00" => "Supermicro/Intel ICH10 82801J 2 Port SATA/300", # SM X8DT3 "0xa88015d9,0x3a268086,0x00" => "Supermicro/Intel ICH10 82801J 2 Port SATA/300", # SM X8DT3 "0x5352108e,0x3a268086,0x00" => "Sun/Intel ICH10 82801J 2 Port SATA/300", # Sun X2270 "0x83621043,0x3a268086,0x00" => "Asus/Intel ICH10 82801J 2 Port SATA/300", # Asus Z8NA-D6 "0x8975152d,0x3a268086,0x00" => "Quanta/Intel ICH10 82801J 2 Port SATA/300", # Dell S99 "0x028c1028,0x3a268086,0x00" => "Dell/Intel ICH10 82801J 2 Port SATA/300", # Dell R410 "0x02f11028,0x3a268086,0x00" => "Dell/Intel ICH10 82801J 2 Port SATA/300", # Dell R510 "0x02d41028,0x3a268086,0x00" => "Dell/Intel ICH10 82801J 2 Port SATA/300", # Dell R810 "0x83971033,0x3a268086,0x00" => "NEC/Intel ICH10 82801J 2 Port SATA/300", # NEC Express5800/iR120a-1E "0x01011137,0x3a268086,0x00" => "Cisco/Intel ICH10 82801J 2 Port SATA/300", # Cisco UCS C200 M2 "0x????????,0x3b208086,0x05" => "Intel PCH 4 Port SATA/300", "0x040d15d9,0x3b208086,0x05" => "Supermicro/Intel PCH 4 Port SATA/300", # SM X8SIE "0x02a51028,0x3b208086,0x05" => "Supermicro/Intel PCH 4 Port SATA/300", # DELL R210 "0x3118103c,0x3b208086,0x05" => "HP/Intel PCH 4 Port SATA/300", # DL120 G6 "0x????????,0x3b218086,0x05" => "Intel PCH 2 Port SATA/300", "0x060515d9,0x3b218086,0x05" => "Supermicro/Intel PCH 2 Port SATA/300", # SM X8SIL "0x????????,0x3b228086,0x05" => "Intel PCH 6 Port SATA/300 AHCI", "0xb0051458,0x3b228086,0x05" => "Gigabyte/Intel PCH 6 Port SATA/300 AHCI", # Gigabyte P55M-UD2 "0x02a51028,0x3b228086,0x05" => "Dell/Intel PCH 6 Port SATA/300 AHCI", # Dell R210 "0x3318103c,0x3b228086,0x05" => "HP/Intel PCH 6 Port SATA/300 AHCI", # DL120 G6 "0x????????,0x3b228086,0x06" => "Intel PCH 6 Port SATA/300 AHCI", "0x76361462,0x3b228086,0x06" => "MSI/Intel PCH 6 Port SATA/300 AHCI", # MSI H55M-P31 "0x????????,0x3b258086,0x05" => "Intel PCH SATA/300 RAID", "0x3118103c,0x3b258086,0x05" => "HP/Intel PCH SATA/300 RAID", # DL120 G6 "0x????????,0x3b268086,0x05" => "Intel PCH 2 Port SATA/300", "0x040d15d9,0x3b268086,0x05" => "Supermicro/Intel PCH 2 Port SATA/300", # SM X8SIE "0x060515d9,0x3b268086,0x05" => "Supermicro/Intel PCH 2 Port SATA/300", # SM X8SIL "0x02a51028,0x3b268086,0x05" => "Supermicro/Intel PCH 2 Port SATA/300", # DELL R210 "0x3118103c,0x3b268086,0x05" => "HP/Intel PCH 2 Port SATA/300", # DL120 G6 "0x330d103c,0x1c028086,0x04" => "HP/Intel PCH2 6 Port SATA/300 AHCI", # DL120 G7 "0x844d1043,0x1c028086,0x04" => "Asus/Intel PCH2 6 Port SATA/300 AHCI", # Asus P8H67-M "0x????????,0x036e10de,0xa1" => "nVIDIA MCP55 ATA/133", "0x00261170,0x036e10de,0xa1" => "Inventec/nVIDIA MCP55 ATA/133", # IR2400 "0xb0031028,0x036e10de,0xa1" => "Dell/nVIDIA MCP55 ATA/133", # DCS CS24-NV5 "0x191115d9,0x036e10de,0xa1" => "Supermicro/nVIDIA MCP55 ATA/133", # SM H8DMU "0x241115d9,0x036e10de,0xa1" => "Supermicro/nVIDIA MCP55 ATA/133", # SM H8DMT "0xcb8410de,0x036e10de,0xa1" => "nVIDIA MCP55 ATA/133", # Tyan S2927 "0x????????,0x037f10de,0xa3" => "nVIDIA MCP55 SATA/300", "0x00261170,0x037f10de,0xa3" => "Inventec/nVIDIA MCP55 SATA/300", # IR2400 "0xb0031028,0x037f10de,0xa3" => "Dell/nVIDIA MCP55 SATA/300", # DCS CS24-NV5 "0x191115d9,0x037f10de,0xa3" => "Supermicro/nVIDIA MCP55 SATA/300", # SM H8DMU "0x241115d9,0x037f10de,0xa3" => "Supermicro/nVIDIA MCP55 SATA/300", # SM H8DMT "0xcb8410de,0x037f10de,0xa3" => "nVIDIA MCP55 SATA/300", # Tyan S2927 "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' => { "0x020d10de,0x014e10de,0xa2" => { "type" => "Graphics", "model" => "nVIDIA Quadro FX 540", "bus" => "PCIe x16" }, "0x032c10de,0x029e10de,0xa1" => { "type" => "Graphics", "model" => "nVIDIA Quadro FX 1500", "bus" => "PCIe x16" }, "0x055f10de,0x061a10de,0xa2" => { "type" => "Graphics", "model" => "nVIDIA Quadro FX 3700", "bus" => "PCIe 2.0 x16" }, "0x0001177d,0x0001177d,0x01" => { "type" => "Crypto", "model" => "Cavium Nitrox XL", "bus" => "PCI-X" }, # Nitrox PX Processor - markings == CN1620(proc) NHB(half-height) # CN1620-400-NHB-G device - http://www.cavium.com/acceleration_boards_PCIe.html # http://www.cavium.com/Table.html#NXAB "0x0001177d,0x0010177d,0x01" => { "type" => "Crypto", "model" => "Cavium Nitrox PX XL", "bus" => "PCIe x8" }, }, ); 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://support.amd.com/us/Processor_TechDocs/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' => ['Winchester D0, 64-bit, 90nm, L2: 512KB',1,1,0], # e.g. Athlon 64 3200+ 'AMD,15,33,0' => ['Egypt E1, 64-bit, dual-core, 90nm, L2: 2MB',2,1,0], # e.g. 875 (dual-core) 'AMD,15,33,2' => ['Italy E6, 64-bit, dual-core, 90nm, L2: 2MB',2,1,0], # e.g. 275 (dual-core) 'AMD,15,35,2' => ['Denmark E6, 64-bit, dual-core, 90nm, L2: 2MB',2,1,0], # e.g. 180 (dual-core) 'AMD,15,37,1' => ['Troy E4, 64-bit, 90nm, L2: 1MB',1,1,0], # stepping SH-E4, socket940 (not dual-core) 'AMD,15,65,2' => ['Santa Rosa F2, 64-bit, dual-core, 90nm, L2: 2MB',2,1,0], # e.g. 8220 SE 'AMD,15,65,3' => ['Santa Rosa F3, 64-bit, dual-core, 90nm, L2: 2MB',2,1,0], # e.g. 2220 'AMD,15,67,3' => ['Windsor F3, 64-bit, dual-core, 90nm, L2: 1MB',2,1,0], # e.g. Athlon 64 X2 Dual Core 3800+ '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' => ['Brisbane G1, 64-bit, dual-core, 65nm, L2: 1MB',2,1,0], # e.g. Athlon 64 X2 4000+ 'AMD,15,107,2' => ['Brisbane G2, 64-bit, dual-core, 65nm, L2: 1MB',2,1,0], # e.g. Athlon 64 X2 5200B 'AMD,16,2,3' => [ ['Phenom', ['Agena B3, 64-bit, quad-core, 65nm, L2: 2MB, L3: 2MB',4,1,0]], # e.g. Phenom 9850 ['Opteron', ['Barcelona B3, 64-bit, quad-core, 65nm, L2: 2MB, L3: 2MB',4,1,0]], # e.g. Opteron 2352 ], 'AMD,16,4,2' => [ ['Phenom II X3', ['Heka C2, 64-bit, triple-core, 45nm, L2: 2MB, L3: 6MB',3,1,3]], # e.g. Phenom II X3 720 ['Phenom II X4', ['Deneb C2, 64-bit, quad-core, 45nm, L2: 2MB, L3: 6MB',4,1,3]], # e.g. Phenom II X4 940 ['Opteron', ['Shanghai C2, 64-bit, quad-core, 45nm, L2: 2MB, L3: 6MB',4,1,3]], # e.g. Opteron 2372 ], 'AMD,16,8,0' => ['Istanbul D0, 64-bit, six-core, 45nm, L2: 3MB, L3: 6MB',6,1,3], 'AMD,16,8,1' => ['Lisbon D1, 64-bit, six-core, 45nm, L2: 3MB, L3: 6MB',6,1,3], 'AMD,16,9,1' => [ ['Opteron 61[67]', ['Magny-Cours D1, 64-bit, 12-core, 45nm, L2: 6MB, L3: 12MB',12,1,3]], ['Opteron 61[23]', ['Magny-Cours D1, 64-bit, 8-core, 45nm, L2: 6MB, L3: 12MB',8,1,3]], ], # 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,6' => ['Dothan B1, 90nm, L2: 2MB',1,1,0], # e.g. Pentium M 725 '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 E7310', ['Tigerton G0, 64-bit, quad-core, 65nm, L2: 4MB',4,1,2]], ['Xeon E73[23]0', ['Tigerton G0, 64-bit, quad-core, 65nm, L2: 6MB',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,15,13' => [ ['\bE1', ['Allendale M0, 64-bit, dual-core, 65nm, L2: 512KB',2,1,2]], # Celeron Desktop ['\bE2', ['Conroe M0, 64-bit, dual-core, 65nm, L2: 1MB',2,1,2]], # Pentium Desktop ['\bE4', ['Allendale M0, 64-bit, dual-core, 65nm, L2: 2MB',2,1,2]], # Core 2 Desktop ['\bE6', ['Conroe M0, 64-bit, dual-core, 65nm, L2: 2MB',2,1,2]], # Core 2 Desktop ['\bT1', ['Merom M0, 64-bit, dual-core, 65nm, L2: 1MB',2,1,2]], # Celeron Mobile ['\bT[23]', ['Merom M0, 64-bit, dual-core, 65nm, L2: 1MB',2,1,2]], # Pentium Mobile ['\bT[57]', ['Merom M0, 64-bit, dual-core, 65nm, L2: 2MB',2,1,2]], # Core 2 Mobile ['\bU7', ['Merom M0, 64-bit, dual-core, 65nm, L2: 2MB',2,1,2]], # Core 2 Mobile ULV ['default', ['Conroe M0, 64-bit, dual-core, 65nm, L2: 1MB',2,1,2]], ], 'Intel,6,22,1' => [ ['Celeron', ['Merom A1, 64-bit, 65nm, L2: 1M',1,1,2]], ], 'Intel,6,23,1' => ['Harpertown, 64-bit, quad-core, 45nm, L2: 12MB',4,1,3], # pre-prod 'Intel,6,23,4' => ['Harpertown, 64-bit, quad-core, 45nm, L2: 12MB',4,1,3], # pre-prod 'Intel,6,23,6' => [ ['Pentium E2', ['Wolfdale M0, 64-bit, dual-core, 45nm, L2: 1MB',2,1,3]], ['Pentium E5', ['Wolfdale M0, 64-bit, dual-core, 45nm, L2: 2MB',2,1,3]], ['Celeron', ['Penryn R0, 64-bit, dual-core, 45nm, L2: 1MB',2,1,3]], ['Core 2 Solo', ['Penryn R0, 64-bit, 45nm, L2: 3MB',1,1,3]], # CULV ['Core 2 Duo T6', ['Penryn R0, 64-bit, dual-core, 45nm, L2: 2MB',2,1,3]], # MV - medium voltage ['Core 2 Duo P[78]', ['Penryn M0, 64-bit, dual-core, 45nm, L2: 3MB',2,1,3]], # LV - low voltage ['Core 2 Duo T8', ['Penryn M0, 64-bit, dual-core, 45nm, L2: 3MB',2,1,3]], # MV ['Core 2 Duo SU9', ['Penryn M0, 64-bit, dual-core, 45nm, L2: 3MB',2,1,3]], # ULV - FCBGA6 ['Core 2 Duo S[LP]9', ['Penryn C0, 64-bit, dual-core, 45nm, L2: 6MB',2,1,3]], # LV, MV - FCBGA6 ['Core 2 Duo [PT]9', ['Penryn C0, 64-bit, dual-core, 45nm, L2: 6MB',2,1,3]], # LV, MV ['Core 2 Extreme X9', ['Penryn C0, 64-bit, dual-core, 45nm, L2: 6MB',2,1,3]], # SV - standard voltage ['Core 2 Quad Q9', ['Penryn C0, 64-bit, quad-core, 45nm, L2: 12MB',4,1,3]], # SV ['Core 2 Extreme QX9', ['Yorkfield C0, 64-bit, quad-core, 45nm, L2: 12MB',4,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 E31', ['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]], # LV, MV, SV ['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' => [ ['Xeon X33[23]0', ['Yorkfield M1, 64-bit, quad-core, 45nm, L2: 6MB',4,1,3]], ['Xeon X33', ['Yorkfield C1, 64-bit, quad-core, 45nm, L2: 12MB',4,1,3]], ['Quad Q8', ['Yorkfield M1, 64-bit, quad-core, 45nm, L2: 4MB',4,1,3]], ['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]], ['QX9', ['Yorkfield 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' => [ ['Celeron', ['Wolfdale R0, 64-bit, dual-core, 45nm, L2: 1MB',2,1,3]], ['Pentium E[23]', ['Wolfdale R0, 64-bit, dual-core, 45nm, L2: 1MB',2,1,3]], ['Pentium E[56]', ['Wolfdale R0, 64-bit, dual-core, 45nm, L2: 2MB',2,1,3]], ['Core 2 Duo E7', ['Wolfdale R0, 64-bit, dual-core, 45nm, L2: 3MB',2,1,3]], ['Core 2 Duo U9', ['Penryn R0, 64-bit, dual-core, 45nm, L2: 3MB',2,1,3]], # e.g. U9600 ['Core 2 Duo T9', ['Penryn R0, 64-bit, dual-core, 45nm, L2: 6MB',2,1,3]], # e.g. T9550 ['Core 2 Duo', ['Wolfdale E0, 64-bit, dual-core, 45nm, L2: 6MB',2,1,3]], ['Core 2 Quad Q8', ['Yorkfield R0, 64-bit, quad-core, 45nm, L2: 4MB',4,1,3]], ['Core 2 Quad Q9.5', ['Yorkfield E0, 64-bit, quad-core, 45nm, L2: 12MB',4,1,3]], ['Core 2 Quad Q9', ['Yorkfield R0, 64-bit, quad-core, 45nm, L2: 6MB',4,1,3]], ['Xeon [LE]31', ['Wolfdale E0, 64-bit, dual-core, 45nm, L2: 6MB',2,1,3]], ['Xeon [LE]33', ['Wolfdale E0, 64-bit, quad-core, 45nm, L2: 12MB',4,1,3]], ['Xeon X33[23]0', ['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' => ['Nehalem B0, 64-bit, 45nm, L3: 8MB',4,2,4], # pre-prod 'Intel,6,26,4' => [ ['Core i7', ['Bloomfield C0, 64-bit, quad-core, 45nm, L3: 8MB',4,2,4]], ['Xeon W350', ['Bloomfield C0, 64-bit, dual-core, 45nm, L3: 4MB',2,1,4]], ['Xeon W35', ['Bloomfield C0, 64-bit, quad-core, 45nm, L3: 8MB',4,2,4]], ['Xeon E5502', ['Gainestown C0, 64-bit, dual-core, 45nm, L3: 4MB',2,1,4]], ['Xeon [LE]550', ['Gainestown C0, 64-bit, quad-core, 45nm, L3: 4MB',4,1,4]], ['Xeon [LEXW]55', ['Gainestown C0, 64-bit, quad-core, 45nm, L3: 8MB',4,2,4]], ['Xeon', ['Gainestown C0, 64-bit, quad-core, 45nm, L3: 8MB',4,2,4]], ], 'Intel,6,26,5' => [ ['Core i7', ['Bloomfield D0, 64-bit, quad-core, 45nm, L3: 8MB',4,2,4]], ['Xeon W350', ['Bloomfield D0, 64-bit, dual-core, 45nm, L3: 4MB',2,1,4]], ['Xeon W35', ['Bloomfield D0, 64-bit, quad-core, 45nm, L3: 8MB',4,2,4]], ['Xeon E5502', ['Gainestown D0, 64-bit, dual-core, 45nm, L3: 4MB',2,1,4]], ['Xeon [LE]550', ['Gainestown D0, 64-bit, quad-core, 45nm, L3: 4MB',4,1,4]], ['Xeon [LEXW]55', ['Gainestown D0, 64-bit, quad-core, 45nm, L3: 8MB',4,2,4]], ['Xeon', ['Gainestown D0, 64-bit, quad-core, 45nm, L3: 8MB',4,2,4]], ], 'Intel,6,28,2' => [ ['Atom 230', ['Diamondville C0, 64-bit, 45nm, L2: 512KB',1,2,3]], ['Atom 330', ['Diamondville C0, 64-bit, dual-core, 45nm, L2: 1MB',2,2,3]], ['Atom N2', ['Diamondville C0, 45nm, L2: 512KB',1,2,3]], ['Atom Z5[01]0\b', ['Silverthorne C0, 45nm, L2: 512KB',1,1,3]], ['Atom Z\d\d\dP', ['Silverthorne C0, 64-bit, 45nm, L2: 512KB',1,2,3]], ['Atom Z', ['Silverthorne C0, 45nm, L2: 512KB',1,2,3]], ['Atom', ['Silverthorne C0, 45nm, L2: 512KB',1,2,3]], ], 'Intel,6,28,10' => [ ['Atom [DN]5', ['Pineview B0, 64-bit, dual-core, 45nm, L2: 1MB',2,2,3]], ['Atom [DN]4', ['Pineview A0, 64-bit, 45nm, L2: 512KB',1,2,3]], ], 'Intel,6,29,1' => [ ['Xeon [LE]74[0-4]', ['Dunnington A1, 64-bit, 4-core, 45nm, L3: 12MB',4,1,3]], ['Xeon [LEX]74', ['Dunnington A1, 64-bit, 6-core, 45nm, L3: 12MB',6,1,3]], ], 'Intel,6,30,5' => [ ['i7-720QM', ['Clarksfield B1, 64-bit, quad-core, 45nm, L3: 6MB',4,2,4]], ['i7-820QM', ['Clarksfield B1, 64-bit, quad-core, 45nm, L3: 8MB',4,2,4]], ['i7-920XM', ['Clarksfield B1, 64-bit, quad-core, 45nm, L3: 8MB',4,2,4]], ['Core i5', ['Lynnfield B1, 64-bit, quad-core, 45nm, L3: 8MB',4,1,4]], ['Core i7', ['Lynnfield B1, 64-bit, quad-core, 45nm, L3: 8MB',4,2,4]], ['Xeon X3430', ['Lynnfield B1, 64-bit, quad-core, 45nm, L3: 8MB',4,1,4]], ['Xeon [LX]3', ['Lynnfield B1, 64-bit, quad-core, 45nm, L3: 8MB',4,2,4]], ], 'Intel,6,37,2' => [ ['i3-...M', ['Arrandale C2, 64-bit, dual-core, 32nm, L3: 3MB',2,2,4]], # standard voltage, 35W ['i5-...M', ['Arrandale C2, 64-bit, dual-core, 32nm, L3: 3MB',2,2,4]], # standard voltage ['i5-...UM', ['Arrandale C2, 64-bit, dual-core, 32nm, L3: 3MB',2,2,4]], # ultra-low voltage, 18W ['i7-...[EM]', ['Arrandale C2, 64-bit, dual-core, 32nm, L3: 4MB',2,2,4]], # standard voltage ['i7-...L[EM]', ['Arrandale C2, 64-bit, dual-core, 32nm, L3: 4MB',2,2,4]], # low voltage, 25W ['i7-...U[EM]', ['Arrandale C2, 64-bit, dual-core, 32nm, L3: 4MB',2,2,4]], # ultra-low voltage ['Pentium', ['Clarkdale C2, 64-bit, dual-core, 32nm, L3: 3MB',2,1,4]], ['Core i3', ['Clarkdale C2, 64-bit, dual-core, 32nm, L3: 4MB',2,2,4]], ['Core i5', ['Clarkdale C2, 64-bit, dual-core, 32nm, L3: 4MB',2,2,4]], ], 'Intel,6,37,5' => [ ['i3-...[EM]', ['Arrandale K0, 64-bit, dual-core, 32nm, L3: 3MB',2,2,4]], # standard voltage, 35W ['i3-...UM', ['Arrandale K0, 64-bit, dual-core, 32nm, L3: 3MB',2,2,4]], # ultra-low voltage, 18W ['i5-...M', ['Arrandale K0, 64-bit, dual-core, 32nm, L3: 3MB',2,2,4]], # standard voltage ['i5-...UM', ['Arrandale K0, 64-bit, dual-core, 32nm, L3: 3MB',2,2,4]], # ultra-low voltage ['i7-...[EM]', ['Arrandale K0, 64-bit, dual-core, 32nm, L3: 4MB',2,2,4]], # standard voltage ['i7-...L[EM]', ['Arrandale K0, 64-bit, dual-core, 32nm, L3: 4MB',2,2,4]], # low voltage, 25W ['i7-...U[EM]', ['Arrandale K0, 64-bit, dual-core, 32nm, L3: 4MB',2,2,4]], # ultra-low voltage ['Celeron', ['Arrandale K0, 64-bit, dual-core, 32nm, L3: 2MB',2,1,4]], ['Pentium', ['Clarkdale K0, 64-bit, dual-core, 32nm, L3: 3MB',2,1,4]], ['Core i3', ['Clarkdale K0, 64-bit, dual-core, 32nm, L3: 4MB',2,2,4]], ['Core i5', ['Clarkdale K0, 64-bit, dual-core, 32nm, L3: 4MB',2,2,4]], ], 'Intel,6,42,5' => ['Sandy Bridge, 64-bit, 4-core, 32nm, L3: 8MB',4,2,5], # pre-prod 'Intel,6,42,6' => ['Sandy Bridge D1, 64-bit, 4-core, 32nm, L3: 8MB',4,2,5], # pre-prod 'Intel,6,42,7' => [ ['Core i7-27', ['Sandy Bridge D2, 64-bit, 4-core, 32nm, L3: 6MB',4,2,5]], ['Core i7', ['Sandy Bridge D2, 64-bit, 4-core, 32nm, L3: 8MB',4,2,5]], ['Core i5', ['Sandy Bridge D2, 64-bit, 4-core, 32nm, L3: 6MB',4,1,5]], ['Core i3', ['Sandy Bridge D2, 64-bit, 2-core, 32nm, L3: 3MB',2,2,5]], ['Pentium', ['Sandy Bridge D2, 64-bit, 2-core, 32nm, L3: 3MB',2,1,5]], ['Xeon E31220L', ['Sandy Bridge D2, 64-bit, 4-core, 32nm, L3: 3MB',2,2,5]], ['Xeon E3122', ['Sandy Bridge D2, 64-bit, 4-core, 32nm, L3: 8MB',4,1,5]], ['Xeon E3', ['Sandy Bridge D2, 64-bit, 4-core, 32nm, L3: 8MB',4,2,5]], ['Xeon', ['Sandy Bridge D2, 64-bit, 4-core, 32nm, L3: 8MB',4,2,5]], ], 'Intel,6,44,0' => ['Gulftown, 64-bit, six-core, 32nm, L3: 12MB',6,2,4], # pre-prod 'Intel,6,44,1' => [ # pre-prod ['Xeon W36.0', ['Gulftown, 64-bit, six-core, 32nm, L3: 12MB',6,2,4]], ['Xeon X56.0', ['Gulftown, 64-bit, six-core, 32nm, L3: 12MB',6,2,4]], ['Xeon L5640', ['Gulftown, 64-bit, six-core, 32nm, L3: 12MB',6,2,4]], ['Xeon [LEXW]56', ['Gulftown, 64-bit, quad-core, 32nm, L3: 12MB',4,2,4]], ], 'Intel,6,44,2' => [ ['Core i7', ['Gulftown B1, 64-bit, six-core, 32nm, L3: 12MB',6,2,4]], ['Xeon [LE]560.', ['Gulftown B1, 64-bit, quad-core, 32nm, L3: 12MB',4,1,4]], ['Xeon W36.0', ['Gulftown B1, 64-bit, six-core, 32nm, L3: 12MB',6,2,4]], ['Xeon X56.[05]', ['Gulftown B1, 64-bit, six-core, 32nm, L3: 12MB',6,2,4]], ['Xeon E56(45|49)', ['Gulftown B1, 64-bit, six-core, 32nm, L3: 12MB',6,2,4]], ['Xeon L56(38|40)', ['Gulftown B1, 64-bit, six-core, 32nm, L3: 12MB',6,2,4]], ['Xeon [LEX]56', ['Gulftown B1, 64-bit, quad-core, 32nm, L3: 12MB',4,2,4]], ], 'Intel,6,46,6' => [ ['Xeon X7542', ['Beckton D0, 64-bit, 6-core, 45nm, L3: 12MB',6,1,4]], ['Xeon E7520', ['Beckton D0, 64-bit, 4-core, 45nm, L3: 18MB',4,2,4]], ['Xeon [EL]75(30|40|45)', ['Beckton D0, 64-bit, 6-core, 45nm, L3: 12MB',6,2,4]], ['Xeon [XL]75(50|60|55)', ['Beckton D0, 64-bit, 8-core, 45nm, L3: 18MB',8,2,4]], ['Xeon E6510', ['Beckton D0, 64-bit, 4-core, 45nm, L3: 12MB',4,2,4]], ['Xeon E6540', ['Beckton D0, 64-bit, 6-core, 45nm, L3: 18MB',6,2,4]], ['Xeon X6550', ['Beckton D0, 64-bit, 8-core, 45nm, L3: 18MB',8,2,4]], ['Xeon', ['Beckton D0, 64-bit, 8-core, 45nm, L3: 18MB',8,2,4]], ], '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,1,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, no HT for celeron ['Pentium', ['Northwood D1, 130nm, L2: 512KB',1,2,0]], # P4, mixed bag on HT ['Xeon', ['Prestonia D1, 130nm, L2: 512KB',1,2,0]], # P4 Xeon DP ], 'Intel,15,3,3' => [ ['Celeron', ['Prescott C0, 90nm, L2: 256KB',1,1,0]], ['Pentium', ['Prescott C0, 64-bit, 90nm, L2: 1MB',1,2,0]], # P4, full HT support ], 'Intel,15,3,4' => [ ['Celeron (3.1|3.6|355)', ['Prescott D0, 64-bit, 90nm, L2: 256KB',1,1,0]], ['Celeron', ['Prescott D0, 90nm, L2: 256KB',1,1,0]], ['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 (3.1|3.6|355)', ['Prescott E0, 64-bit, 90nm, L2: 256KB',1,1,0]], ['Celeron', ['Prescott E0, 90nm, L2: 256KB',1,1,0]], ['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,2' => [ ['Celeron (3.1|3.6|355)', ['Prescott G0, 64-bit, 90nm, L2: 256KB',1,1,0]], ['Celeron', ['Prescott G0, 90nm, L2: 256KB',1,1,0]], ], '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' => [ ['Celeron (3.1|3.6|355)', ['Prescott G1, 64-bit, 90nm, L2: 256KB',1,1,0]], ['Celeron', ['Prescott G1, 90nm, L2: 256KB',1,1,0]], ['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 D', ['Presler B1, 64-bit, dual-core, 65nm, L2: 4MB',2,1,0]], # Pentium D ['Pentium', ['Cedar Mill B1, 64-bit, 65nm, L2: 2MB',1,2,0]], # Pentium 4 ], 'Intel,15,6,4' => [ ['Celeron', ['Cedar Mill C1, 64-bit, 65nm, L2: 512KB',1,1,0]], # Celeron ['Pentium D', ['Presler C1, 64-bit, dual-core, 65nm, L2: 4MB',2,1,0]], # Pentium D ['Pentium', ['Cedar Mill C1, 64-bit, 65nm, L2: 2MB',1,2,0]], # Pentium 4 ['Xeon', ['Dempsey C1, 64-bit, dual-core, 65nm, L2: 4MB',2,2,0]], # PD Xeon DP ], 'Intel,15,6,5' => [ ['Celeron', ['Cedar Mill D0, 64-bit, 65nm, L2: 512KB',1,1,0]], # Celeron ['Pentium D', ['Presler D0, 64-bit, dual-core, 65nm, L2: 4MB',2,1,0]], # Pentium D ['Pentium', ['Cedar Mill D0, 64-bit, 65nm, L2: 2MB',1,2,0]], # Pentium 4 ], 'Intel,15,6,8' => [ ['Xeon', ['Tulsa B0, 64-bit, dual-core, 65nm, L2: 4MB',2,2,0]], # PD Xeon MP ], ); my(%ipmi_vendor) = ( # http://svn.savannah.gnu.org/svn/freeipmi/trunk/libfreeipmi/include/freeipmi/spec/ipmi-iana-enterprise-numbers-spec.h 2 => 'IBM', 42 => 'Sun', 343 => 'Intel', 674 => 'Dell', 7244 => 'Quanta', 10368 => 'Fujitsu', 10437 => 'Peppercon', 10876 => 'Supermicro', 20569 => 'Inventec', 47488 => 'Supermicro', ); my(%jedec) = ( # http://www.jedec.org/download/search/jep106Y.pdf # http://www.jedec.org/download/search/jep106Z.pdf # http://www.jedec.org/sites/default/files/docs/JEP106AB.pdf '2C' => 'Micron', 'AD' => 'Hynix', 'BF' => 'SST', 'C1' => 'Infineon', 'CE' => 'Samsung', '7F40' => 'Viking', '7F4F' => 'Transcend', '7F61' => 'Wintec', '7F7A' => 'Apacer', '7F94' => 'Smart Modular', '7F98' => 'Kingston', '7FA8' => 'Simple Tech', '7F7F64' => 'MDT', '7F7F85' => 'Hypertec', '7F7F98' => 'Southland', '7F7F9E' => 'Corsair', '7F7FFE' => 'Elpida', '7F7F7F0B' => 'Nanya', '7F7F7F16' => 'Netlist', '7F7F7F83' => 'Buffalo', '7F7F7F8A' => 'Princeton', '7F7F7F7F08' => 'Silicon Mountain', '7F7F7F7F46' => 'Legacy', '7F7F7F7F43' => 'Ramaxel', '7F7F7F7FCB' => 'A-DATA', '7F7F7F7FCD' => 'G.Skill', '7F7F7F7F7F51' => 'Qimonda', '7F7F7F7F7F57' => 'Aeneon', '7F7F7F7F7FE3' => 'Kreton', '7F7F7F7F7F3E' => 'PQI', '7F7F7F7F7F9B' => 'Crucial', '7F7F7F7F7FF7' => 'Avant', '7F7F7F7F7F7F34' => 'Super Talent', ); my(%vendor_to_jedec) = ( 'C1494E46494E454F' => 'C1', # C1 + INFINEO. some parts report this, e.g. 72D128521GR7B ); my(%tmr_sysinfo_err) = ( '10001' => { # GB0250C8045, GB0500C8046, GB0750C8047, GB0250EAFJF, GB0500EAFJH, GB0750EAFJK, GB1000EAFJL 'type' => 'drive-firmware', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/HardwareIssuesHpDriveFirmware', 'tiny' => '', }, '10002' => { # ST3500320AS, ST3500620AS, ST3500820AS, ST3640330AS, ST3640530AS, ST3750330AS, ST3750630AS, ST31000340AS 'type' => 'drive-firmware', 'url' => 'http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207951&NewLang=en', 'tiny' => '', }, '10003' => { # ST3250310NS, ST3500320NS, ST3750330NS, ST31000340NS 'type' => 'drive-firmware', 'url' => 'http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207963&NewLang=en', 'tiny' => '', }, '10004' => { # ST31000340SV, ST3750330SV, ST3500320SV, ST3320410SV 'type' => 'drive-firmware', 'url' => 'http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=208451&NewLang=en', 'tiny' => '', }, '10005' => { # ST31500341AS, ST31000333AS, ST3640323AS, ST3640623AS, ST3320613AS, ST3320813AS, ST3160813AS 'type' => 'drive-firmware', 'url' => 'http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207957&NewLang=en', 'tiny' => '', }, '10006' => { # STM3500320AS, STM3750330AS, STM31000340AS 'type' => 'drive-firmware', 'url' => 'http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207969&NewLang=en', 'tiny' => '', }, '10007' => { # STM31000334AS, STM3640323AS, STM3320614AS, STM3160813AS 'type' => 'drive-firmware', 'url' => 'http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207975&NewLang=en', 'tiny' => '', }, '10008' => { # freebsd scsi tcq_depth set too low 'type' => 'volume-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/HardwareIssuesTcqDepth', 'tiny' => '', }, '10009' => { # linux cpufreq/scaling_governor not set correctly 'type' => 'cpu-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/HardwareIssuesCpuScalingGovernor', 'tiny' => '', }, '10010' => { # linux sata controller configured in legacy IDE mode 'type' => 'driver-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/LinuxLegacyIDE', 'tiny' => '', }, '10011' => { # linux sata controller configured in non-AHCI mode 'type' => 'driver-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/LinuxNonAHCI', 'tiny' => '', }, '10012' => { # battery on disk controller bbu has failed 'type' => 'disk-controller', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/DiskControllerBBU', 'tiny' => '', }, '10013' => { # battery on disk controller bbu is missing 'type' => 'disk-controller', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/DiskControllerBBU', 'tiny' => '', }, '10014' => { # failed or failing drive in volume 'type' => 'disk-status', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/DiskFail', 'tiny' => '', }, '10015' => { # cpu config 'type' => 'cpu-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/KernelConfigLimitCPU', 'tiny' => '', }, '10016' => { # cpu config 'type' => 'cpu-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/KernelBootLimitCPU', 'tiny' => '', }, '10017' => { # network running half-duplex 'type' => 'network-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/NetworkHalfDuplex', 'tiny' => '', }, '10018' => { # running 32-bit OS on 64-bit hardware 'type' => 'os-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/32bitOn64bit', 'tiny' => '', }, '10019' => { # write cache disabled on volume 'type' => 'volume-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/VolumeWriteCacheDisabled', 'tiny' => '', }, '10020' => { # drive write cache disabled on volume 'type' => 'volume-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/VolumeDiskWriteCacheDisabled', 'tiny' => '', }, '10021' => { # write cache disabled on drive 'type' => 'drive-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/DiskWriteCacheDisabled', 'tiny' => '', }, '10022' => { # write cache disabled on controller 'type' => 'disk-controller', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/DiskControllerWriteCacheDisabled', 'tiny' => '', }, '10023' => { # disk write cache disabled on controller 'type' => 'disk-controller', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/DiskControllerDiskWriteCacheDisabled', 'tiny' => '', }, '10024' => { # volume is degraded 'type' => 'volume-status', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/VolumeStatusDegraded', 'tiny' => '', }, '10025' => { # volume has failed 'type' => 'volume-status', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/VolumeStatusFailed', 'tiny' => '', }, '10026' => { # memory config 'type' => 'memory-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/KernelBootLimitMemory', 'tiny' => '', }, '10027' => { # memory config 'type' => 'memory-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/MemoryPopulationOrder', 'tiny' => '', }, '10028' => { # memory config 'type' => 'memory-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/MemoryChannelBalance', 'tiny' => '', }, '10029' => { # memory config 'type' => 'memory-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/MemoryBalancePerSocket', 'tiny' => '', }, '10030' => { # linux cpufreq/scaling_governor set to userspace without cpuspeed daemon enabled 'type' => 'cpu-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/HardwareIssuesCpuScalingGovernor', 'tiny' => '', }, '10031' => { # SpeedStep disabled in BIOS 'type' => 'cpu-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/SpeedStepDisabledByBIOS', 'tiny' => '', }, '10032' => { # cpu steppings don't match 'type' => 'cpu-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/CPUSteppingsMismatch', 'tiny' => '', }, '10033' => { # cpuspeed service not enabled 'type' => 'cpu-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/CpuspeedServiceDisabled', 'tiny' => '', }, '10034' => { # cpu models don't match 'type' => 'cpu-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/CPUModelsMismatch', 'tiny' => '', }, '10035' => { # some cpus are offline # this should be superceded by 10015 or 10016 'type' => 'cpu-config', 'url' => 'http://github.com/euriion/TomorrowWorks/sysinfo/guide/CPUOffline', 'tiny' => '', }, ); 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/ # http://www.datasheetarchive.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", "GR2DF4GBX4QM667Q2R" => "4GB 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", "512E40K3R24" => "512MB PC2-3200 Itaucom DDR2-400 ECC Registered CL3", "M0840038" => "2GB PC2-4200 PQI DDR2-533 Unbuffered CL3", # Avant "F7251P625667F" => "4GB PC2-5300 Avant DDR2-667 ECC Registered CL5 2Rx4", "F7256R53E5667F" => "2GB PC2-5300 Avant DDR2-667 ECC Registered CL5 2Rx4", "F7251R62E5667F" => "4GB PC2-5300 Avant DDR2-667 ECC Registered CL5 2Rx4", "7251B62E5667F" => "4GB PC2-5300 Avant DDR2-667 ECC Fully Buffered", # HP "HP497157-B88-ELDW" => "2GB PC3-10600 HP/Kingston DDR3-1333 Unbuffered CL9", "140134-031" => "256MB PC133 HP SDRAM Unbuffered CL3", "127006-041" => "512MB PC133 HP/Micron SDRAM ECC Registered CL3 1Rx4", "HPQ00-21183-723SCU" => "2GB PC-2700 HP/Simple Tech DDR-333 ECC Registered CL2.5 2Rx4", "HPQFB-2GD18-667MEA" => "4GB PC2-5300 HP/Simple Tech DDR2-667 ECC Fully Buffered CL5", "HPQFB-2GD18-667EC2" => "4GB PC2-5300 HP/Simple Tech DDR2-667 ECC Fully Buffered CL5", # GOODRAM "GR667F272D4L5/2G" => "2GB PC2-5300 GOODRAM DDR2-667 ECC Fully Buffered CL5 2R", # Southland "40002038-81" => "2GB PC2-3200 Southland DDR2-400 ECC Registered CL3 2R", # TwinMOS "M2SAOA8AHXAG081MA-" => "1GB PC-3200 TwinMOS DDR-400 Unbuffered CL3 2Rx8", # Apacer "75.A72A6.G01" => "2GB PC2-5300 Apacer DDR2-667 ECC Registered CL5 2Rx4", # Ramaxel "RML1040HB38D6F-533" => "512MB PC2-4200 Ramaxel DDR2-533 Unbuffered CL4 1Rx4", "RML1040HC38D6F-533" => "512MB PC2-4200 Ramaxel DDR2-533 Unbuffered CL4", "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", "RML1320EJ38D7W-667" => "1GB PC2-5300 Ramaxel DDR2-667 Unbuffered CL5", "RML1520EC48D7W-800" => "1GB PC2-6400 Ramaxel DDR2-800 Unbuffered CL6", "RML1520EF48D7W-800" => "1GB PC2-6400 Ramaxel DDR2-800 Unbuffered CL6", "RML1320EF48D8W-800" => "2GB PC2-6400 Ramaxel DDR2-800 Unbuffered CL6", # Transcend # http://www.transcendusa.com/Support/Search/index.asp "TS32MLD64V4F" => "256MB PC-3200 Transcend DDR-400 Unbuffered CL2.5 1Rx8", "TS64MLD64V4F" => "512MB PC-3200 Transcend DDR-400 Unbuffered CL2.5 2Rx8", "TS128MLD64V3J" => "1GB PC-2700 Transcend DDR-333 Unbuffered CL2.5 2Rx8", "TS128MLD64V4J" => "1GB PC-3200 Transcend DDR-400 Unbuffered CL3 2Rx8", "TS64MLQ64V4J" => "512MB PC2-3200 Transcend DDR2-400 Unbuffered CL3 1Rx8", "TS64MLQ64V5J" => "512MB PC2-4200 Transcend DDR2-533 Unbuffered CL4 1Rx8", "TS256MLQ64V6U" => "2GB PC2-5300 Transcend DDR2-667 Unbuffered CL5 2Rx8", "TS256MLQ64V8U" => "2GB PC2-6400 Transcend DDR2-800 Unbuffered CL6 2Rx8", "JM388Q643A-5" => "1GB PC2-4200 Transcend DDR2-533 Unbuffered CL4 2Rx8", "JM388Q643A-6" => "1GB PC2-5300 Transcend DDR2-667 Unbuffered CL5 2Rx8", "JM667QLJ-1G" => "1GB PC2-5300 Transcend DDR2-667 Unbuffered CL5 2Rx8", "JM667QLU-2G" => "2GB PC2-5300 Transcend DDR2-667 Unbuffered CL5 2Rx8", "TS512MQR72V4T" => "4GB PC2-3200 Transcend DDR2-400 ECC Registered CL3 1Rx4", "JM1333KLU-2G" => "2GB PC3-10600 Transcend DDR3-1333 Unbuffered CL9 2Rx8", # Aeneon "AET660UD00-30DB97X" => "512MB PC2-5300 Aeneon DDR2-667 Unbuffered CL5 1Rx8", "AET760UD00-370A98X" => "1GB PC2-4200 Aeneon DDR2-533 Unbuffered CL4 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 # Crucial "CT12864AA667.M8FJ2" => "1GB PC2-5300 Crucial DDR2-667 Unbuffered CL5", # 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", "DG992G-NAB" => "2GB PC2-5300 Kingston DDR2-667 ECC Registered CL5 2R", "KC6844-ELG37" => "1GB PC2-4200 Kingston DDR2-533 ECC Unbuffered CL4 2Rx8", "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", "9905315-062.A00LF" => "1GB PC2-4200 Kingston DDR2-533 Unbuffered CL4", # KTD-DM8400A/1G "9905316-005.A04LF" => "1GB PC2-5300 Kingston DDR2-667 Unbuffered CL5 2Rx8", # KVR667D2N5/1G "9905315-106.A00LF" => "1GB PC2-6400 Kingston DDR2-800 Unbuffered CL6", "9905316-131.A01LF" => "1GB PC2-6400 Kingston DDR2-800 Unbuffered CL6", "9905321-008.A00LF" => "2GB PC2-4200 Kingston DDR2-533 ECC Unbuffered CL4 2Rx8", # KVR533D2E4K2/4G "9905316-132.A01LF" => "2GB PC2-6400 Kingston DDR2-800 Unbuffered CL6", "DGM431NABINTD1F" => "2GB PC2-5300 Kingston DDR2-667 ECC Fully Buffered CL5 2R", "9905458-009.A00LF" => "2GB PC3-10600 Kingston DDR3-1333 Unbuffered CL9", "9905458-010.A00LF" => "2GB PC3-10600 Kingston DDR3-1333 Unbuffered CL9", "9905458-012.A00LF" => "2GB PC3-10600 Kingston DDR3-1333 Unbuffered CL9", "9905403-011.A03LF" => "2GB PC3-10600 Kingston DDR3-1333 Unbuffered CL9 2Rx8", # KVR1333D3N9/2G "9905471-001.A00LF" => "2GB PC3-10600 Kingston DDR3-1333 Unbuffered CL9", "9965426-024.A00LF" => "2GB PC3-10600 Kingston DDR3-1333 ECC Registered CL9 2Rx8", "9965426-039.A00LF" => "4GB PC3-10600 Kingston DDR3-1333 ECC Registered CL9", "9965447-028.A00LF" => "4GB PC3-10600 Kingston DDR3-1333 ECC Registered CL9", "9965447-030.A00LF" => "4GB PC3-10600 Kingston DDR3-1333 ECC Registered CL9", "9965447-034.A00LF" => "4GB PC3-10600 Kingston DDR3-1333 ECC Registered CL9", "9965447-056.A00LF" => "4GB PC3-10600 Kingston DDR3-1333 ECC Registered CL9", "9965426-037.A00LF" => "4GB PC3-10600 Kingston DDR3-1333 ECC Registered CL9 2Rx8", # KVR1333D3D8R9S/4GHB "9965447-042.A00LF" => "4GB PC3-8500 Kingston DDR3-1066 ECC Registered CL7", # 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 Tech DDR2-400 ECC Registered CL3 1R", "S1024R3NN2QK-I" => "1GB PC2-5300 Simple Tech 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 "HYS64D32009GU-7.5" => "256MB PC-2100 Infineon DDR-266 Unbuffered CL2.5", "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", "72D64300[GHE]BR6C" => "512MB PC-2700 Infineon DDR-333 ECC Registered CL2.5 1Rx4", "72D128521[GHE]R7B" => "1GB PC-2100 Infineon DDR-266 ECC Registered CL2 2Rx4", "72D128300[GHE]BR6B" => "1GB PC-2700 Infineon DDR-333 ECC Registered CL2.5 1Rx4", "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", "72T64000[EH]R5." => "512MB 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", "72T256220[EH]R3.7." => "2GB PC2-4200 Infineon DDR2-533 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", "72T512920[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 # ||------- Product variations # |-------- 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", "64T128020[EH]U2.5.." => "1GB PC2-6400 Infineon DDR2-800 Unbuffered CL6 2Rx8", "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", "64T256020[EH]U2.5.." => "2GB PC2-6400 Infineon DDR2-800 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", # DDR3 # http://www.qimonda.com/computing-dram/ddr3/unbuffered.html "IMSH2GE13A1F1CT10F" => "2GB PC3-8500 Qimonda DDR3-1066 ECC Unbuffered CL7 2Rx8", "IMSH2GP13A1F1C-10F" => "2GB PC3-8500 Qimonda DDR3-1066 ECC Registered CL7 2Rx8", # ^ ^^^ ^ # | ||| |--- 10F=PC3-8500 CL7 # | |||---------- 2=4x, 3=8x, 4=16x # | ||----------- 0=1R, 1=2R # | |------------ E=UDIMM ECC, S=SODIMM, U=UDIMM, P=Reg ECC # |-------------- 51=512MB, 1G=1GB, 2G=2GB, 4G=4GB, 8G=8GB # http://www.qimonda.com/download.jsp?ref=/qis_docs/Downloads%20Computing/DDR3_SDRAM_Comp%20%26%20Mod.pdf # 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", "16VDDT3264AG-265.." => "256MB PC-2100 Micron DDR-266 Unbuffered CL2.5 2Rx8", "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", "16VDDT6464AG-335.." => "512MB PC-2700 Micron DDR-333 Unbuffered CL2.5 2Rx8", "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", "18HTF25672PY-667.." => "2GB PC2-5300 Micron DDR2-667 ECC Registered CL5 1Rx4", "36HTF25672Y-40E.." => "2GB PC2-3200 Micron DDR2-400 ECC Registered CL3 2Rx4", # Non-Parity "36HTF25672Y-53E.." => "2GB PC2-4200 Micron DDR2-533 ECC Registered CL3 2Rx4", "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 "36HTF51272PZ-667.." => "4GB PC2-5300 Micron DDR2-667 ECC Registered CL5 2Rx4", # Parity "36HTS1G72PY-667.." => "8GB PC2-5300 Micron DDR2-667 ECC Registered CL5 2Rx4 DDP", # Parity DDP "9HTF3272AY-40E.." => "256MB PC2-3200 Micron DDR2-400 Unbuffered CL3 1Rx8", "4HTF3264AY-53E.." => "256MB PC2-4200 Micron DDR2-533 Unbuffered CL4 1Rx16", "8HTF6464AY-53E.." => "512MB PC2-4200 Micron DDR2-533 Unbuffered CL4 1Rx8", "8HTF6464AY-667.." => "512MB PC2-5300 Micron DDR2-667 Unbuffered CL5 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", "8HTF12864AZ-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", "16HTF25664AY-667.." => "2GB PC2-5300 Micron DDR2-667 Unbuffered CL5 2Rx8", "18HTF25672AY-667.." => "2GB PC2-5300 Micron DDR2-667 ECC Unbuffered CL5 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", "9HTF6472FY-667...." => "512MB PC2-5300 Micron DDR2-667 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", "18HF25672FD667...." => "2GB PC2-5300 Micron DDR2-667 ECC Fully Buffered CL5 2Rx8", "36HTF25672F667...." => "2GB PC2-5300 Micron DDR2-667 ECC Fully Buffered CL5 2Rx4", "36HTF51272F667...." => "4GB PC2-5300 Micron DDR2-667 ECC Fully Buffered CL5 2Rx4", "36HF51272FZ667...." => "4GB PC2-5300 Micron DDR2-667 ECC Fully Buffered CL5 2Rx4", "36HTF51272F80E...." => "4GB PC2-6400 Micron DDR2-800 ECC Fully Buffered CL6 2Rx4", # http://download.micron.com/pdf/numbering/numsdrammod.pdf "16JTF25664AZ-1G4..?" => "2GB PC3-10600 Micron DDR3-1333 Unbuffered CL9 2Rx8", "16JTF25664AY-1G4.." => "2GB PC3-10600 Micron DDR3-1333 Unbuffered CL9 2Rx8", "18JSF25672AY-1G4.." => "2GB PC3-10600 Micron DDR3-1333 ECC Unbuffered CL9 2Rx8", "18JSF25672AZ-1G1.." => "2GB PC3-8500 Micron DDR3-1066 ECC Unbuffered CL9 2Rx8", "18JSF25672AZ-1G4.." => "2GB PC3-10600 Micron DDR3-1333 ECC Unbuffered CL9 2Rx8", "18JSF25672PDZ1G4.." => "2GB PC3-10600 Micron DDR3-1333 ECC Registered CL9 2Rx8", "36JSZF51272PY1G1.." => "4GB PC3-8500 Micron DDR3-1066 ECC Registered CL7 2Rx4", # MT36JSZF51272PY-1G1D1 "36JSZF51272PZ1G1.." => "4GB PC3-8500 Micron DDR3-1066 ECC Registered CL7 2Rx4", # MT36JSZF51272PZ-1G1F1 "36JSZF51272PD1G1.." => "4GB PC3-8500 Micron DDR3-1066 ECC Registered CL7 4Rx8", # MT36JSZF51272PDY-1G1D1 "36JSZF51272DZ1G1.." => "4GB PC3-8500 Micron DDR3-1066 ECC Registered CL7 4Rx8", # MT36JSZF51272PDZ-1G1F1 "36JSZF51272PY1G4.." => "4GB PC3-10600 Micron DDR3-1333 ECC Registered CL9 2Rx4", # MT36JSZF51272PY-1G4D1 "36JSZF51272PZ1G4.." => "4GB PC3-10600 Micron DDR3-1333 ECC Registered CL9 2Rx4", # MT36JSZF51272PZ-1G4F1 "36JSZF1G72PZ-1G4.." => "8GB PC3-10600 Micron DDR3-1333 ECC Registered CL9 2Rx4", # MT36JSZF1G72PZ-1G4D1 # 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 # http://www.hynix.com/inc/pdfDownload.jsp?path=/upload/products/gl/products/dram/down/DDR2MODULE.pdf # P == lead-free, M == 36 chips? "71V32635HCT8-H" => "256MB PC133 Hynix SDRAM Unbuffered CL3 2Rx8", # 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://www.netlistinc.com/technology_products.aspx?sm=pr "NLD127R21203F-D32K" => "1GB PC2-3200 Netlist DDR2-400 ECC Registered CL3 1Rx4", "NLD257R21203F-D32K" => "2GB PC2-3200 Netlist DDR2-400 ECC Registered CL3 2Rx4", "NLD257R22503F-D32K" => "2GB PC2-3200 Netlist DDR2-400 ECC Registered CL3 1Rx4", "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", "NLD517R22503F-D32K" => "4GB PC2-3200 Netlist DDR2-400 ECC Registered CL3", "NLD517R2250BF-D32K" => "4GB PC2-3200 Netlist DDR2-400 ECC Registered CL3", # http://www.smartm.com/product/productCat.cfm?productCatID=1 # http://www.smartupgradeconfigurator.com/config/ # http://www.smartupgradeconfigurator.com/ext/ind/docs_ds.asp?SMID=244 "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", "SM5643285D8N6CHHAH" => "256MB PC-2100 Smart DDR-266 Unbuffered CL2.5", "SG2567UDR212852HC" => "2GB PC2-5300 Smart DDR2-667 ECC Unbuffered CL5 2Rx8", "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", "SB2567RDR212835IA" => "2GB PC2-3200 Smart DDR2-400 ECC Registered CL3 2R", "SB572564FG8E6DBIAH" => "2GB PC2-3200 Smart DDR2-400 ECC Registered", "SG572124FG8P6IL" => "4GB PC2-5300 Smart DDR2-667 ECC Registered CL5 2Rx4", "SG5127RDR225652HC" => "4GB PC2-5300 Smart DDR2-667 ECC Registered CL5 2Rx4", "SG572124FG8P6ILHCH" => "4GB PC2-5300 Smart DDR2-667 ECC Registered CL5 2Rx4", "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", "SG5SE84N2G1BDDJHCH" => "4GB PC2-5300 Smart DDR2-667 ECC Fully Buffered CL5", "SG5127FBD12852HCDL" => "4GB PC2-5300 Smart DDR2-667 ECC Fully Buffered CL5 4Rx8", "SG5127FB212852HCDM" => "4GB PC2-5300 Smart DDR2-667 ECC Fully Buffered CL5 4Rx8", "SG572568FH8P6PH" => "2GB PC3-8500 Micron DDR3-1066 ECC Registered", ); 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 # we have same issue with Fujitsu as we do with Hitachi drives, see below for comments # so, need to also use truncated versions where not ambiguous. that's what the # optional final char is about in all of the models below. ########### MHS2-A family "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", ########### MHV2-A families "MHV2040AS" => "40GB 5.4K ATA/100 2.5\" Fujitsu ED Mobile MHV2-AS 8MB", "MHV2060AS" => "60GB 5.4K ATA/100 2.5\" Fujitsu ED Mobile MHV2-AS 8MB", "MHV2080AS" => "80GB 5.4K ATA/100 2.5\" Fujitsu ED Mobile MHV2-AS 8MB", # http://www.fujitsu.com/global/services/computing/storage/hdd/archive/mhv2040ah-mhv2120ah.html "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", # http://www.fujitsu.com/global/services/computing/storage/hdd/archive/mhv2040at-mhv2120at.html "MHV2040AT" => "40GB 4.2K ATA/100 2.5\" Fujitsu Mobile MHV2-AT 2MB", "MHV2060AT" => "60GB 4.2K ATA/100 2.5\" Fujitsu Mobile MHV2-AT 8MB", "MHV2080AT" => "80GB 4.2K ATA/100 2.5\" Fujitsu Mobile MHV2-AT 8MB", "MHV2100AT" => "100GB 4.2K ATA/100 2.5\" Fujitsu Mobile MHV2-AT 8MB", "MHV2120AT" => "120GB 4.2K ATA/100 2.5\" Fujitsu Mobile MHV2-AT 8MB", # these are ambiguous "MHV2040A" => "40GB ATA/100 2.5\" Fujitsu Mobile MHV2-A", "MHV2060A" => "60GB ATA/100 2.5\" Fujitsu Mobile MHV2-A 8MB", "MHV2080A" => "80GB ATA/100 2.5\" Fujitsu Mobile MHV2-A 8MB", "MHV2100A" => "100GB ATA/100 2.5\" Fujitsu Mobile MHV2-A 8MB", "MHV2120A" => "120GB ATA/100 2.5\" Fujitsu Mobile MHV2-A 8MB", ########### MHY2-B families "MHY2040BH" => "40GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-BH 8MB", "MHY2060BH" => "60GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-BH 8MB", "MHY2080BH" => "80GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-BH 8MB", "MHY2100BH" => "100GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-BH 8MB", "MHY2120BH" => "120GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-BH 8MB", "MHY2160BH" => "160GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-BH 8MB", "MHY2200BH" => "200GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-BH 8MB", "MHY2250BH" => "250GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-BH 8MB", "MHY2040BS" => "40GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHY2-BS 8MB", "MHY2060BS" => "60GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHY2-BS 8MB", "MHY2080BS" => "80GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHY2-BS 8MB", "MHY2100BS" => "100GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHY2-BS 8MB", "MHY2120BS" => "120GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHY2-BS 8MB", "MHY2160BS" => "160GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHY2-BS 8MB", "MHY2200BS" => "200GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHY2-BS 8MB", # these are ambiguous "MHY2040B" => "40GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-B 8MB", "MHY2060B" => "60GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-B 8MB", "MHY2080B" => "80GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-B 8MB", "MHY2100B" => "100GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-B 8MB", "MHY2120B" => "120GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-B 8MB", "MHY2160B" => "160GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-B 8MB", "MHY2200B" => "200GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHY2-B 8MB", ########### MHV2-B families "MHV2040BS" => "40GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHV2-BS 8MB", "MHV2060BS" => "60GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHV2-BS 8MB", "MHV2080BS" => "80GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHV2-BS 8MB", "MHV2040BH" => "40GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHV2-BH 8MB", "MHV2060BH" => "60GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHV2-BH 8MB", "MHV2080BH" => "80GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHV2-BH 8MB", "MHV2100BH" => "100GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHV2-BH 8MB", "MHV2120BH" => "120GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHV2-BH 8MB", "MHV2160BT" => "160GB 4.2K SATA/150 2.5\" Fujitsu Mobile MHV2-BT 8MB", "MHV2200BT" => "220GB 4.2K SATA/150 2.5\" Fujitsu Mobile MHV2-BT 8MB", # these are ambiguous "MHV2040B" => "40GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHV2-B 8MB", "MHV2060B" => "60GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHV2-B 8MB", "MHV2080B" => "80GB 5.4K SATA/150 2.5\" Fujitsu Mobile MHV2-B 8MB", ########### MHW2-B families # http://www.fujitsu.com/global/services/computing/storage/hdd/archive/mhw2040bh-mhw2160bh.html "MHW2040BH" => "40GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHW2-BH 8MB", "MHW2060BH" => "60GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHW2-BH 8MB", "MHW2080BH" => "80GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHW2-BH 8MB", "MHW2100BH" => "100GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHW2-BH 8MB", "MHW2120BH" => "120GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHW2-BH 8MB", "MHW2160BH" => "160GB 5.4K SATA/150 2.5\" Fujitsu ED Mobile MHW2-BH 8MB", # http://www.fujitsu.com/global/services/computing/storage/hdd/archive/mhw2080bj-mhw2160bj-2.html "MHW2080BJ" => "60GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHW2-BJ 8MB", "MHW2120BJ" => "120GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHW2-BJ 8MB", "MHW2160BJ" => "120GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHW2-BJ 8MB", # http://www.fujitsu.com/downloads/COMP/fcpa/hdd/mhw2xxxbk_datasheet.pdf "MHW2060BK" => "60GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHW2-BK 8MB", "MHW2080BK" => "80GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHW2-BK 8MB", "MHW2120BK" => "120GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHW2-BK 8MB", # these are ambiguous "MHW2060B" => "60GB SATA 2.5\" Fujitsu ED Mobile MHW2-B 8MB", "MHW2080B" => "80GB SATA 2.5\" Fujitsu ED Mobile MHW2-B 8MB", "MHW2120B" => "120GB SATA 2.5\" Fujitsu ED Mobile MHW2-B 8MB", "MHW2160B" => "160GB SATA 2.5\" Fujitsu ED Mobile MHW2-B 8MB", ########### MHZ2-B families # http://www.fujitsu.com/global/services/computing/storage/hdd/mhdd/mhz2040bh-mhz2320bh.html "MHZ2040BH" => "40GB 5.4K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BH 8MB", "MHZ2080BH" => "80GB 5.4K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BH 8MB", "MHZ2120BH" => "120GB 5.4K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BH 8MB", "MHZ2160BH" => "160GB 5.4K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BH 8MB", "MHZ2200BH" => "200GB 5.4K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BH 8MB", "MHZ2250BH" => "250GB 5.4K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BH 8MB", "MHZ2320BH" => "320GB 5.4K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BH 8MB", # http://www.fujitsu.com/global/services/computing/storage/hdd/mhdd/mhz2080bj-mhz2320bj.html "MHZ2080BJ" => "80GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BJ 16MB", "MHZ2120BJ" => "120GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BJ 16MB", "MHZ2160BJ" => "160GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BJ 16MB", "MHZ2200BJ" => "200GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BJ 16MB", "MHZ2250BJ" => "250GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BJ 16MB", "MHZ2320BJ" => "320GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BJ 16MB", # http://www.fujitsu.com/downloads/COMP/fcpa/hdd/mhz2xxxbk_datasheet.pdf "MHZ2080BK" => "80GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BK 16MB", "MHZ2120BK" => "120GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BK 16MB", "MHZ2160BK" => "160GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BK 16MB", "MHZ2250BK" => "250GB 7.2K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BK 16MB", # http://www.fujitsu.com/global/services/computing/storage/hdd/mhdd/mhz2120bs-mhz2250bs.html "MHZ2120BS" => "120GB 5.4K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BS 8MB", "MHZ2250BS" => "250GB 5.4K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BS 8MB", # http://www.fujitsu.com/global/services/computing/storage/hdd/mhdd/mhz2080bj-mhz2320bj.html "MHZ2400BT" => "400GB 4.2K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BT 8MB", "MHZ2400BT" => "500GB 4.2K SATA/300 2.5\" Fujitsu ED Mobile MHZ2-BT 8MB", # these are ambiguous "MHZ2080B" => "80GB SATA/300 2.5\" Fujitsu ED Mobile MHZ2-B", "MHZ2120B" => "120GB SATA/300 2.5\" Fujitsu ED Mobile MHZ2-B", "MHZ2160B" => "160GB SATA/300 2.5\" Fujitsu ED Mobile MHZ2-B", "MHZ2200B" => "200GB SATA/300 2.5\" Fujitsu ED Mobile MHZ2-B", "MHZ2250B" => "250GB SATA/300 2.5\" Fujitsu ED Mobile MHZ2-B", "MHZ2320B" => "320GB SATA/300 2.5\" Fujitsu ED Mobile MHZ2-B", ################################################################################ # 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", "HD083GJ" => "80GB 7.2K SATA/300 Samsung SpinPoint F1 DT 8MB", "HD161GJ" => "160GB 7.2K SATA/300 Samsung SpinPoint F1 DT 8MB", "HD162GJ" => "160GB 7.2K SATA/300 Samsung SpinPoint F1 DT 16MB", "HD251HJ" => "250GB 7.2K SATA/300 Samsung SpinPoint F1 DT 8MB", "HD252HJ" => "250GB 7.2K SATA/300 Samsung SpinPoint F1 DT 16MB", "HD321HJ" => "320GB 7.2K SATA/300 Samsung SpinPoint F1 DT 8MB", "HD322HJ" => "320GB 7.2K SATA/300 Samsung SpinPoint F1 DT 16MB", "HD501IJ" => "500GB 7.2K SATA/300 Samsung SpinPoint F1 DT 8MB", "HD502IJ" => "500GB 7.2K SATA/300 Samsung SpinPoint F1 DT 16MB", "HD642JJ" => "640GB 7.2K SATA/300 Samsung SpinPoint F1 DT 16MB", "HD753LJ" => "750GB 7.2K SATA/300 Samsung SpinPoint F1 DT 32MB", "HD103UJ" => "1TB 7.2K SATA/300 Samsung SpinPoint F1 DT 32MB", # need more info on these models "HE160HJ" => "160GB 7.2K SATA/300 Samsung 8MB", "HE161HJ" => "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", "HE642JJ" => "640GB 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", "HD252HI" => "250GB 5.4K SATA/300 Samsung EcoGreen F1 DT 16MB", "HD322HI" => "320GB 5.4K SATA/300 Samsung EcoGreen F1 DT 16MB", "HD502JI" => "500GB 5.4K SATA/300 Samsung EcoGreen F1 DT 16MB", "HD642JI" => "640GB 5.4K SATA/300 Samsung EcoGreen F1 DT 16MB", "HD753LI" => "750GB 5.4K SATA/300 Samsung EcoGreen F1 DT 32MB", "HD103UI" => "1TB 5.4K SATA/300 Samsung EcoGreen F1 DT 32MB", "HD502HI" => "500GB 5.4K SATA/300 Samsung EcoGreen F2 16MB", "HD102SI" => "1TB 5.4K SATA/300 Samsung EcoGreen F2 16MB", "HD103SI" => "1TB 5.4K SATA/300 Samsung EcoGreen F2 32MB", "HD153UI" => "1.5TB 5.4K SATA/300 Samsung EcoGreen F2 16MB", "HD154UI" => "1.5TB 5.4K SATA/300 Samsung EcoGreen F2 32MB", "HD164GJ" => "160GB 7.2K SATA/300 Samsung SpinPoint F3 8MB", "HD163GJ" => "160GB 7.2K SATA/300 Samsung SpinPoint F3 16MB", "HD254GJ" => "250GB 7.2K SATA/300 Samsung SpinPoint F3 8MB", "HD253GJ" => "250GB 7.2K SATA/300 Samsung SpinPoint F3 16MB", "HD324HJ" => "320GB 7.2K SATA/300 Samsung SpinPoint F3 8MB", "HD323HJ" => "320GB 7.2K SATA/300 Samsung SpinPoint F3 16MB", "HD502HJ" => "500GB 7.2K SATA/300 Samsung SpinPoint F3 16MB", "HD754JJ" => "750GB 7.2K SATA/300 Samsung SpinPoint F3 32MB", "HD103SJ" => "1TB 7.2K SATA/300 Samsung SpinPoint F3 32MB", "HE253GJ" => "250GB 7.2K SATA/300 Samsung SpinPoint F3R 16MB", "HE502HJ" => "500GB 7.2K SATA/300 Samsung SpinPoint F3R 16MB", "HE754JJ" => "750GB 7.2K SATA/300 Samsung SpinPoint F3R 32MB", "HE103SJ" => "1TB 7.2K SATA/300 Samsung SpinPoint F3R 32MB", "HD253GI" => "250GB 7.2K SATA/300 Samsung EcoGreen F3 16MB", "HD324HI" => "320GB 7.2K SATA/300 Samsung EcoGreen F3 16MB", "HD503HI" => "500GB 7.2K SATA/300 Samsung EcoGreen F3 16MB", "HD754JI" => "750GB 7.2K SATA/300 Samsung EcoGreen F3 32MB", "HD105SI" => "1TB 7.2K SATA/300 Samsung EcoGreen F3 32MB", "HD153WI" => "1.5TB 7.2K SATA/300 Samsung EcoGreen F3 EG 32MB", "HD203WI" => "2TB 7.2K SATA/300 Samsung EcoGreen F3 EG 32MB", "HD165GJ" => "160GB 7.2K SATA/300 Samsung Spinpoint F4 8MB", "HD166GJ" => "160GB 7.2K SATA/300 Samsung Spinpoint F4 16MB", "HD255GJ" => "250GB 7.2K SATA/300 Samsung Spinpoint F4 8MB", "HD256GJ" => "250GB 7.2K SATA/300 Samsung Spinpoint F4 16MB", "HD322GJ" => "320GB 7.2K SATA/300 Samsung Spinpoint F4 16MB", "HD204UI" => "2TB 7.2K SATA/300 Samsung Spinpoint F4 EG 32MB", "HM121HI" => "120GB 5.4K SATA/150 2.5\" Samsung Spinpoint M5 8MB", "HM160HI" => "160GB 5.4K SATA/150 2.5\" Samsung Spinpoint M5 8MB", "HM250JI" => "250GB 5.4K SATA/150 2.5\" Samsung Spinpoint M5 8MB", "HM251JI" => "250GB 5.4K SATA/150 2.5\" Samsung Spinpoint M6 8MB", "HM320JI" => "320GB 5.4K SATA/150 2.5\" Samsung Spinpoint M6 8MB", "HM250II" => "250GB 5.4K SATA/300 2.5\" Samsung Spinpoint M7 8MB", "HM320HI" => "320GB 5.4K SATA/300 2.5\" Samsung Spinpoint M7 8MB", "HM320HI" => "400GB 5.4K SATA/300 2.5\" Samsung Spinpoint M7 8MB", "HM500JI" => "500GB 5.4K SATA/300 2.5\" Samsung Spinpoint M7 8MB", ################################################################################ # Western Digital # # 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", "WD1600AVJS" => "160GB 7.2K SATA/300 WD AV 8MB", "WD2500AVJS" => "250GB 7.2K SATA/300 WD AV 8MB", "WD3200AVJS" => "320GB 7.2K SATA/300 WD AV 8MB", "WD5000AVJS" => "500GB 7.2K SATA/300 WD AV 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", "WD6400AAKS" => "640GB 7.2K SATA/300 WD Caviar SE16 16MB", "WD7500AAKS" => "750GB 7.2K SATA/300 WD Caviar SE16 16MB", "WD5000AAVS" => "500GB 5.4K SATA/300 WD Caviar Green 8MB", "WD6400AAVS" => "640GB 5.4K SATA/300 WD Caviar Green 8MB", "WD7500AAVS" => "750GB 5.4K SATA/300 WD Caviar Green 8MB", "WD10EAVS" => "1TB 5.4K SATA/300 WD Caviar Green 8MB", "WD1600AVVS" => "160GB 5.4K SATA/300 WD AV-GP 8MB", "WD2500AVVS" => "250GB 5.4K SATA/300 WD AV-GP 8MB", "WD3200AVVS" => "320GB 5.4K SATA/300 WD AV-GP 8MB", "WD5000AVVS" => "500GB 5.4K SATA/300 WD AV-GP 8MB", "WD6400AVVS" => "640GB 5.4K SATA/300 WD AV-GP 8MB", "WD7500AVVS" => "750GB 5.4K SATA/300 WD AV-GP 8MB", "WD10EVVS" => "1TB 5.4K SATA/300 WD AV-GP 8MB", "WD5000AACS" => "500GB 5.4K SATA/300 WD Caviar Green 16MB", "WD6400AACS" => "640GB 5.4K SATA/300 WD Caviar Green 16MB", "WD7500AACS" => "750GB 5.4K SATA/300 WD Caviar Green 16MB", "WD10EACS" => "1TB 5.4K SATA/300 WD Caviar Green 16MB", "WD5000AADS" => "500GB 5.4K SATA/300 WD Caviar Green 32MB", "WD6400AADS" => "640GB 5.4K SATA/300 WD Caviar Green 32MB", "WD7500AADS" => "750GB 5.4K SATA/300 WD Caviar Green 32MB", "WD10EADS" => "1TB 5.4K SATA/300 WD Caviar Green 32MB", "WD15EADS" => "1.5TB 5.4K SATA/300 WD Caviar Green 32MB", "WD20EADS" => "2TB 5.4K SATA/300 WD Caviar Green 32MB", "WD6400AARS" => "640GB 5.4K SATA/300 WD Caviar Green 64MB", "WD8000AARS" => "800GB 5.4K SATA/300 WD Caviar Green 64MB", "WD10EARS" => "1TB 5.4K SATA/300 WD Caviar Green 64MB", "WD15EARS" => "1.5TB 5.4K SATA/300 WD Caviar Green 64MB", "WD20EARS" => "2TB 5.4K SATA/300 WD Caviar Green 64MB", "WD25EZRS" => "2.5TB 5.4K SATA/300 WD Caviar Green 64MB", "WD30EZRS" => "3TB 5.4K SATA/300 WD Caviar Green 64MB", "WD5000AVDS" => "500GB 5.4K SATA/300 WD AV-GP 32MB", "WD7500AVDS" => "750GB 5.4K SATA/300 WD AV-GP 32MB", "WD10EVDS" => "1TB 5.4K SATA/300 WD AV-GP 32MB", "WD15EVDS" => "1.5TB 5.4K SATA/300 WD AV-GP 32MB", "WD20EVDS" => "2TB 5.4K SATA/300 WD AV-GP 32MB", "WD5001AALS" => "500GB 7.2K SATA/300 WD Caviar Black 32MB", "WD6401AALS" => "640GB 7.2K SATA/300 WD Caviar Black 32MB", "WD7501AALS" => "750GB 7.2K SATA/300 WD Caviar Black 32MB", "WD1001FALS" => "1TB 7.2K SATA/300 WD Caviar Black 32MB", "WD1501FASS" => "1.5TB 7.2K SATA/300 WD Caviar Black 64MB", "WD2001FASS" => "2TB 7.2K SATA/300 WD Caviar Black 64MB", "WD1002FAEX" => "1TB 7.2K SATA/600 WD Caviar Black 64MB", # Mobile drives "WD400UE" => "40GB 5.4K ATA/100 2.5\" WD Scorpio 2MB", "WD600UE" => "60GB 5.4K ATA/100 2.5\" WD Scorpio 2MB", "WD800UE" => "80GB 5.4K ATA/100 2.5\" WD Scorpio 2MB", "WD1200UE" => "120GB 5.4K ATA/100 2.5\" WD Scorpio 2MB", # 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 5.4K SATA/300 WD RE2-GP 16MB", "WD7500AYPS" => "750GB 5.4K SATA/300 WD RE2-GP 16MB", "WD1000FYPS" => "1TB 5.4K SATA/300 WD RE2-GP 16MB", "WD2503ABYX" => "250GB 7.2K SATA/300 WD RE4 64MB", "WD5003ABYX" => "500GB 7.2K SATA/300 WD RE4 64MB", "WD1003FBYX" => "1TB 7.2K SATA/300 WD RE4 64MB", "WD1503FYYS" => "1.5TB 7.2K SATA/300 WD RE4 64MB", "WD2003FYYS" => "2TB 7.2K SATA/300 WD RE4 64MB", "WD1502FYPS" => "1.5TB 5.4K SATA/300 WD RE4-GP 64MB", "WD2002FYPS" => "2TB 5.4K SATA/300 WD RE4-GP 64MB", "WD3002FYPX" => "3TB 5.4K SATA/600 WD RE4-GP 64MB", "WD2003FYYG" => "2TB 7.2K SAS/3 WD RE4 64MB", # Unknown "WD1602ABKS" => "160GB 7.2K SATA/300 WD RE 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", "HUS154530VLS300" => "300GB 15K SAS/3 Hitachi Ultrastar 15K450 16MB", "HUS154545VLS300" => "450GB 15K SAS/3 Hitachi Ultrastar 15K450 16MB", "HUS156030VLS600" => "300GB 15K SAS/6 Hitachi Ultrastar 15K600 64MB", "HUS156045VLS600" => "450GB 15K SAS/6 Hitachi Ultrastar 15K600 64MB", "HUS156060VLS600" => "600GB 15K SAS/6 Hitachi Ultrastar 15K600 64MB", "HUS1573SBSUN72G" => "73GB 15K SAS/3 Sun/Hitachi Ultrastar", "HUS1514SBSUN146G" => "147GB 15K SAS/3 Sun/Hitachi Ultrastar", "HUS1530SBSUN300G" => "300GB 15K SAS/3 Sun/Hitachi Ultrastar", "HUC101473CSS300" => "73GB 10K SAS/3 2.5\" Hitachi Ultrastar C10K147", "HUC101414CSS300" => "147GB 10K SAS/3 2.5\" Hitachi Ultrastar C10K147", "HUC103014CSS600" => "147GB 10K SAS/6 2.5\" Hitachi Ultrastar C10K300", "HUC103030CSS600" => "300GB 10K SAS/6 2.5\" Hitachi Ultrastar C10K300", "HUC151473CSS600" => "73GB 15K SAS/6 2.5\" Hitachi Ultrastar C15K147", "HUC151414CSS600" => "147GB 15K SAS/6 2.5\" Hitachi Ultrastar C15K147", "CBRBA073C3ETS0" => "73GB 10K SAS/3 2.5\" IBM/Hitachi Ultrastar C10K147", "CBRBA146C3ETS0" => "147GB 10K SAS/3 2.5\" IBM/Hitachi Ultrastar C10K147", # HUC101414CSS300 "IBM-ESXS-PYH146C3-ETS10FN" => "147GB 10K U320 IBM/Hitachi", # sn=V5XGEPNA "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", # we have a problem with Hitachi drives. they report the model as something like: # Model Number: Hitachi HDP725025GLA380 # instead of: # Model Number: ST3250620NS # which means when they're behind something like an mpt controller, which prepends ATA, # we only get 8 chars of the real model (a total of 20 char scsi model). on latest # linux, this is okay at least with mpt because hdparm knows how to tunnel through and # talk directly to the drive. however, with mfi or mpt on freebsd we don't have the # pass through support, so we get these truncated models. in some cases these numbers # are unique enough, but not always. in those cases, we simply can't tell. # # so, in cases where first 8 are unique, don't require the rest. only need to worry about sata. # some examples: # ATA-Hitachi-HUA72101A9N1 (last 4 digits are firmware) # ATA-Hitachi-HDP72502 # # this problem exists with others, e.g. Intel SSDs, but so far only hitachi is widespread. # luckily seagate doesn't do this. not sure about the others. looks like Maxtor has # the same issue, although just those post Seagate merger (i.e. models starting with STM). # # update as of 20101023 # drive matching now deals with this issue automatically by looking for ambiguous matches. # if only diff is drive size, we can deal with that. if there's more than drive size # diff, then will need to use regex still. for now nuking most of the regex in models # below. "HDS728040PLAT20" => "40GB 7.2K ATA/133 Hitachi Deskstar 7K80", "HDS728080PLAT20" => "80GB 7.2K ATA/133 Hitachi Deskstar 7K80", "HDS728040PLA320" => "40GB 7.2K SATA/300 Hitachi Deskstar 7K80", "HDS728080PLA380" => "80GB 7.2K SATA/300 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", "HTS545012B9A300" => "120GB 5.4K SATA/300 2.5\" Hitachi Travelstar 5K500.B 8MB", "HTS545016B9A300" => "160GB 5.4K SATA/300 2.5\" Hitachi Travelstar 5K500.B 8MB", "HTS545025B9A300" => "250GB 5.4K SATA/300 2.5\" Hitachi Travelstar 5K500.B 8MB", "HTS545032B9A300" => "320GB 5.4K SATA/300 2.5\" Hitachi Travelstar 5K500.B 8MB", "HTS545040B9A300" => "400GB 5.4K SATA/300 2.5\" Hitachi Travelstar 5K500.B 8MB", "HTS545050B9A300" => "500GB 5.4K SATA/300 2.5\" Hitachi Travelstar 5K500.B 8MB", "HTE545016B9A300" => "160GB 5.4K SATA/300 2.5\" Hitachi Travelstar E5K500.B 8MB", "HTE545025B9A300" => "250GB 5.4K SATA/300 2.5\" Hitachi Travelstar E5K500.B 8MB", "HTE545032B9A300" => "320GB 5.4K SATA/300 2.5\" Hitachi Travelstar E5K500.B 8MB", "HTE545050B9A300" => "500GB 5.4K SATA/300 2.5\" Hitachi Travelstar E5K500.B 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", "HTS722080K9SA00" => "80GB 7.2K SATA/150 2.5\" Hitachi Travelstar 7K200 16MB", "HTS722010K9SA00" => "100GB 7.2K SATA/150 2.5\" Hitachi Travelstar 7K200 16MB", "HTS722012K9SA00" => "120GB 7.2K SATA/150 2.5\" Hitachi Travelstar 7K200 16MB", "HTS722016K9SA00" => "160GB 7.2K SATA/150 2.5\" Hitachi Travelstar 7K200 16MB", "HTS722020K9SA00" => "200GB 7.2K SATA/150 2.5\" Hitachi Travelstar 7K200 16MB", "HTS722080K9A300" => "80GB 7.2K SATA/300 2.5\" Hitachi Travelstar 7K200 16MB", "HTS722010K9A300" => "100GB 7.2K SATA/300 2.5\" Hitachi Travelstar 7K200 16MB", "HTS722012K9A300" => "120GB 7.2K SATA/300 2.5\" Hitachi Travelstar 7K200 16MB", "HTS722016K9A300" => "160GB 7.2K SATA/300 2.5\" Hitachi Travelstar 7K200 16MB", "HTS722020K9A300" => "200GB 7.2K SATA/300 2.5\" Hitachi Travelstar 7K200 16MB", "HTS72208" => "80GB 7.2K SATA 2.5\" Hitachi Travelstar 7K200 16MB", "HTS72201" => "%B 7.2K SATA 2.5\" Hitachi Travelstar 7K200 16MB", "HTS72202" => "200GB 7.2K SATA 2.5\" Hitachi Travelstar 7K200 16MB", "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", "HDP72503" => "320GB 7.2K SATA/300 Hitachi Deskstar P7K500", "HDP725040GLA380" => "400GB 7.2K SATA/300 Hitachi Deskstar P7K500 8MB", "HDP725040GLA360" => "400GB 7.2K SATA/300 Hitachi Deskstar P7K500 16MB", "HDP72504" => "400GB 7.2K SATA/300 Hitachi Deskstar P7K500", "HDP725050GLA380" => "500GB 7.2K SATA/300 Hitachi Deskstar P7K500 8MB", "HDP725050GLA360" => "500GB 7.2K SATA/300 Hitachi Deskstar P7K500 16MB", "HDP72505" => "500GB 7.2K SATA/300 Hitachi Deskstar P7K500", "HDT722516DLA380" => "160GB 7.2K SATA/300 Hitachi Deskstar T7K250 8MB", "HDT722525DLA380" => "250GB 7.2K SATA/300 Hitachi Deskstar T7K250 8MB", "HDT725025VLA380" => "250GB 7.2K SATA/300 Hitachi Deskstar T7K500 8MB", "HDT725025VLA360" => "250GB 7.2K SATA/300 Hitachi Deskstar T7K500 16MB", "HDT72502" => "250GB 7.2K SATA/300 Hitachi Deskstar T7K500", "HDT725032VLA380" => "320GB 7.2K SATA/300 Hitachi Deskstar T7K500 8MB", "HDT725032VLA360" => "320GB 7.2K SATA/300 Hitachi Deskstar T7K500 16MB", "HDT72503" => "320GB 7.2K SATA/300 Hitachi Deskstar T7K500", "HDT725040VLA380" => "400GB 7.2K SATA/300 Hitachi Deskstar T7K500 8MB", "HDT725040VLA360" => "400GB 7.2K SATA/300 Hitachi Deskstar T7K500 16MB", "HDT72504" => "400GB 7.2K SATA/300 Hitachi Deskstar T7K500", "HDT725050VLA380" => "500GB 7.2K SATA/300 Hitachi Deskstar T7K500 8MB", "HDT725050VLA360" => "500GB 7.2K SATA/300 Hitachi Deskstar T7K500 16MB", "HDT72505" => "500GB 7.2K SATA/300 Hitachi Deskstar T7K500", "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 16MB", "HDT721050SLA360" => "500GB 7.2K SATA/300 Hitachi Deskstar 7K1000.B 16MB", "HDT721064SLA360" => "640GB 7.2K SATA/300 Hitachi Deskstar 7K1000.B 16MB", "HDT721075SLA360" => "750GB 7.2K SATA/300 Hitachi Deskstar 7K1000.B 16MB", "HDT721010SLA360" => "1TB 7.2K SATA/300 Hitachi Deskstar 7K1000.B 16MB", "HDT72101" => "%B 7.2K SATA/300 Hitachi Deskstar 7K1000.B", "HDS721016CLA382" => "160GB 7.2K SATA/300 Hitachi Deskstar 7K1000.C 8MB", "HDS721025CLA382" => "250GB 7.2K SATA/300 Hitachi Deskstar 7K1000.C 8MB", "HDS721032CLA362" => "320GB 7.2K SATA/300 Hitachi Deskstar 7K1000.C 16MB", "HDS721050CLA362" => "500GB 7.2K SATA/300 Hitachi Deskstar 7K1000.C 16MB", "HDS721064CLA332" => "640GB 7.2K SATA/300 Hitachi Deskstar 7K1000.C 32MB", "HDS721075CLA332" => "750GB 7.2K SATA/300 Hitachi Deskstar 7K1000.C 32MB", "HDS721010CLA332" => "1TB 7.2K SATA/300 Hitachi Deskstar 7K1000.C 32MB", "HDS721075KLA330" => "750GB 7.2K SATA/300 Hitachi Deskstar 7K1000 32MB", "HDS721010KLA330" => "1TB 7.2K SATA/300 Hitachi Deskstar 7K1000 32MB", "HDS72107" => "750GB 7.2K SATA/300 Hitachi Deskstar 7K1000(.C) 32MB", "HDS72101" => "%B 7.2K SATA/300 Hitachi Deskstar 7K1000(.C) 32MB", "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", "HDS722020ALA330" => "2TB 7.2K SATA/300 Hitachi Deskstar 7K2000 32MB", "HUA721050KLA330" => "500GB 7.2K SATA/300 Hitachi Ultrastar A7K1000 32MB", "HUA721075KLA330" => "750GB 7.2K SATA/300 Hitachi Ultrastar A7K1000 32MB", "HUA721010KLA330" => "1TB 7.2K SATA/300 Hitachi Ultrastar A7K1000 32MB", "HUA722050CLA330" => "500GB 7.2K SATA/300 Hitachi Ultrastar A7K2000 32MB", "HUA722010CLA330" => "1TB 7.2K SATA/300 Hitachi Ultrastar A7K2000 32MB", "HUA722020ALA330" => "2TB 7.2K SATA/300 Hitachi Ultrastar A7K2000 32MB", "HUA723020ALA640" => "2TB 7.2K SATA/600 Hitachi Ultrastar A7K3000 64MB", "HUA723030ALA640" => "3TB 7.2K SATA/600 Hitachi Ultrastar A7K3000 64MB", "HUS723020ALS640" => "2TB 7.2K SAS/6 Hitachi Ultrastar A7K3000 64MB", "HUS723030ALS640" => "3TB 7.2K SAS/6 Hitachi Ultrastar A7K3000 64MB", ################################################################################ # IBM "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", ################################################################################ # Seagate "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", "ST3146356SS" => "146GB 15K SAS/3 Seagate 15K.6", "ST3300656SS" => "300GB 15K SAS/3 Seagate 15K.6", "ST3450856SS" => "450GB 15K SAS/3 Seagate 15K.6", "ST3300657SS" => "300GB 15K SAS/6 Seagate 15K.7", "ST3450857SS" => "450GB 15K SAS/6 Seagate 15K.7", "ST3600057SS" => "600GB 15K SAS/6 Seagate 15K.7", "ST3400755SS" => "400GB 10K SAS/3 Seagate Cheetah NS", "ST3450802SS" => "450GB 10K SAS/6 Seagate Cheetah NS.2", "ST3600002SS" => "600GB 10K SAS/6 Seagate Cheetah NS.2", "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", "ST3400320AS" => "400GB 7.2K SATA/300 Seagate 7200.10 32MB", "ST3500830AS" => "500GB 7.2K SATA/300 Seagate 7200.10 8MB", "ST3500630AS" => "500GB 7.2K SATA/300 Seagate 7200.10 16MB", "ST3500330AS" => "500GB 7.2K SATA/300 Seagate 7200.10 32MB", "ST3750840AS" => "750GB 7.2K SATA/300 Seagate 7200.10 8MB", "ST3750640AS" => "750GB 7.2K SATA/300 Seagate 7200.10 16MB", "ST3750340AS" => "750GB 7.2K SATA/300 Seagate 7200.10 32MB", "ST3160813AS" => { 'pretty' => "160GB 7.2K SATA/300 Seagate 7200.11 8MB", 'firmware-advisory' => { 'yerr' => '10005', 'firmware' => '!CC', 'severity' => 0, }, }, "ST3320813AS" => { 'pretty' => "320GB 7.2K SATA/300 Seagate 7200.11 8MB", 'firmware-advisory' => { 'yerr' => '10005', 'firmware' => '!CC', 'severity' => 0, }, }, "ST3320613AS" => { 'pretty' => "320GB 7.2K SATA/300 Seagate 7200.11 16MB", 'firmware-advisory' => { 'yerr' => '10005', 'firmware' => '!CC', 'severity' => 0, }, }, "ST3360320AS" => "360GB 7.2K SATA/300 Seagate 7200.11 32MB", "ST3500820AS" => { 'pretty' => "500GB 7.2K SATA/300 Seagate 7200.11 8MB", 'firmware-advisory' => { 'yerr' => '10002', 'firmware' => 'AD14|SD1[5-9]|SD81', 'severity' => 0, }, }, "ST3500620AS" => { 'pretty' => "500GB 7.2K SATA/300 Seagate 7200.11 16MB", 'firmware-advisory' => { 'yerr' => '10002', 'firmware' => 'AD14|SD1[5-9]|SD81', 'severity' => 0, }, }, "ST3500320AS" => { 'pretty' => "500GB 7.2K SATA/300 Seagate 7200.11 32MB", 'firmware-advisory' => { 'yerr' => '10002', 'firmware' => 'AD14|SD1[5-9]|SD81', 'severity' => 0, }, }, "ST3640623AS" => { 'pretty' => "640GB 7.2K SATA/300 Seagate 7200.11 16MB", 'firmware-advisory' => { 'yerr' => '10005', 'firmware' => '!CC', 'severity' => 0, }, }, "ST3640323AS" => { 'pretty' => "640GB 7.2K SATA/300 Seagate 7200.11 32MB", 'firmware-advisory' => { 'yerr' => '10005', 'firmware' => '!CC', 'severity' => 0, }, }, "ST3640630AS" => { 'pretty' => "640GB 7.2K SATA/300 Seagate 7200.11 16MB", 'firmware-advisory' => { 'yerr' => '10002', 'firmware' => 'AD14|SD1[5-9]|SD81', 'severity' => 0, }, }, "ST3640330AS" => { 'pretty' => "640GB 7.2K SATA/300 Seagate 7200.11 32MB", 'firmware-advisory' => { 'yerr' => '10002', 'firmware' => 'AD14|SD1[5-9]|SD81', 'severity' => 0, }, }, "ST3750630AS" => { 'pretty' => "750GB 7.2K SATA/300 Seagate 7200.11 16MB", 'firmware-advisory' => { 'yerr' => '10002', 'firmware' => 'AD14|SD1[5-9]|SD81', 'severity' => 0, }, }, "ST3750330AS" => { 'pretty' => "750GB 7.2K SATA/300 Seagate 7200.11 32MB", 'firmware-advisory' => { 'yerr' => '10002', 'firmware' => 'AD14|SD1[5-9]|SD81', 'severity' => 0, }, }, "ST31000333AS" => { 'pretty' => "1TB 7.2K SATA/300 Seagate 7200.11 32MB", 'firmware-advisory' => { 'yerr' => '10005', 'firmware' => '!CC', 'severity' => 0, }, }, "ST31000340AS" => { 'pretty' => "1TB 7.2K SATA/300 Seagate 7200.11 32MB", 'firmware-advisory' => { 'yerr' => '10002', 'firmware' => 'AD14|SD1[5-9]|SD81', 'severity' => 0, }, }, "ST31500341AS" => { 'pretty' => "1.5TB 7.2K SATA/300 Seagate 7200.11 32MB", 'firmware-advisory' => { 'yerr' => '10005', 'firmware' => '!CC', 'severity' => 0, }, }, "ST3160318AS" => "160GB 7.2K SATA/300 Seagate 7200.12 8MB", "ST3250318AS" => "250GB 7.2K SATA/300 Seagate 7200.12 8MB", "ST3250311AS" => "250GB 7.2K SATA/300 Seagate 7200.12 8MB", "ST3320418AS" => "320GB 7.2K SATA/300 Seagate 7200.12 16MB", "ST3500418AS" => "500GB 7.2K SATA/300 Seagate 7200.12 16MB", "ST3500410AS" => "500GB 7.2K SATA/300 Seagate 7200.12 16MB", "ST3750528AS" => "750GB 7.2K SATA/300 Seagate 7200.12 32MB", "ST3750523AS" => "750GB 7.2K SATA/300 Seagate 7200.12 32MB", "ST31000528AS" => "1TB 7.2K SATA/300 Seagate 7200.12 32MB", "ST31000523AS" => "1TB 7.2K SATA/300 Seagate 7200.12 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" => { 'pretty' => "250GB 7.2K SATA/300 Seagate SV35.3 8MB", }, "ST3500320SV" => { 'pretty' => "500GB 7.2K SATA/300 Seagate SV35.3 32MB", 'firmware-advisory' => { 'yerr' => '10004', 'firmware' => 'SV16', 'severity' => 0, }, }, "ST3750330SV" => { 'pretty' => "750GB 7.2K SATA/300 Seagate SV35.3 32MB", 'firmware-advisory' => { 'yerr' => '10004', 'firmware' => 'SV16', 'severity' => 0, }, }, "ST31000340SV" => { 'pretty' => "1TB 7.2K SATA/300 Seagate SV35.3 32MB", 'firmware-advisory' => { 'yerr' => '10004', 'firmware' => 'SV16', 'severity' => 0, }, }, "ST3320410SV" => { 'pretty' => "320GB 7.2K SATA/300 Seagate SV35.4 16MB", 'firmware-advisory' => { 'yerr' => '10004', 'firmware' => 'CV11', 'severity' => 0, }, }, "ST3250310NS" => { 'pretty' => "250GB 7.2K SATA/300 Seagate Barracuda ES.2 32MB", 'firmware-advisory' => { 'yerr' => '10003', 'firmware' => 'SN[01][1-5]', 'severity' => 0, }, }, "ST3500320NS" => { 'pretty' => "500GB 7.2K SATA/300 Seagate Barracuda ES.2 32MB", 'firmware-advisory' => { 'yerr' => '10003', 'firmware' => 'SN[01][1-5]', 'severity' => 0, }, }, "ST3750330NS" => { 'pretty' => "750GB 7.2K SATA/300 Seagate Barracuda ES.2 32MB", 'firmware-advisory' => { 'yerr' => '10003', 'firmware' => 'SN[01][1-5]', 'severity' => 0, }, }, "ST31000340NS" => { 'pretty' => "1TB 7.2K SATA/300 Seagate Barracuda ES.2 32MB", 'firmware-advisory' => { 'yerr' => '10003', 'firmware' => 'SN[01][1-5]', 'severity' => 0, }, }, "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", "ST31000520AS" => "1TB 5.9K SATA/300 Seagate Barracuda LP 32MB", "ST31500541AS" => "1.5TB 5.9K SATA/300 Seagate Barracuda LP 32MB", "ST32000542AS" => "2TB 5.9K SATA/300 Seagate Barracuda LP 32MB", "ST3250311SV" => "250GB 7.2K SATA/300 Seagate SV35.5 8MB", "ST3500410SV" => "500GB 7.2K SATA/300 Seagate SV35.5 16MB", "ST31000525SV" => "1TB 7.2K SATA/300 Seagate SV35.5 32MB", "ST32000644SV" => "2TB 7.2K SATA/300 Seagate SV35.5 32MB", # from powerpoint "ST3500514NS" => "500GB 7.2K SATA/300 Seagate Constellation ES 32MB", "ST31000524NS" => "1TB 7.2K SATA/300 Seagate Constellation ES 32MB", "ST32000544NS" => "2TB 7.2K SATA/300 Seagate Constellation ES 32MB", # real sample "ST32000644NS" => "2TB 7.2K SATA/300 Seagate Constellation ES 64MB", # ^^ ^^ # || |-- AS=desktop, NS=enterprise SATA, SS=enterprise SAS # ||----- 4 platter # |------ 2^6 == 64MB cache "ST3500414SS" => "500GB 7.2K SAS/6 Seagate Constellation ES 16MB", "ST31000424SS" => "1TB 7.2K SAS/6 Seagate Constellation ES 16MB", "ST32000444SS" => "2TB 7.2K SAS/6 Seagate Constellation ES 16MB", "ST33000650SS" => "3TB 7.2K SAS/6 Seagate Constellation ES.2 64MB", "ST33000650NS" => "3TB 7.2K SATA/600 Seagate Constellation ES.2 64MB", "ST32000641AS" => "2TB 7.2K SATA/600 Seagate Barracuda XT 64MB", "ST33000651AS" => "3TB 7.2K SATA/600 Seagate Barracuda XT 64MB", # 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", "ST9120315AS" => "120GB 5.4K SATA/300 2.5\" Seagate Momentus 5400.6 8MB", "ST9250315AS" => "250GB 5.4K SATA/300 2.5\" Seagate Momentus 5400.6 8MB", "ST9500325AS" => "500GB 5.4K SATA/300 2.5\" Seagate Momentus 5400.6 8MB", "ST96023AS" => "60GB 7.2K SATA/150 2.5\" Seagate Momentus 7200.1 8MB", "ST980825AS" => "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", "ST9160414AS" => "160GB 7.2K SATA/300 2.5\" Seagate Momentus 7200 FDE 16MB", "ST9320424AS" => "320GB 7.2K SATA/300 2.5\" Seagate Momentus 7200 FDE 16MB", "ST9120410AS" => "120GB 7.2K SATA/300 2.5\" Seagate Momentus 7200.4 16MB", "ST9160412AS" => "160GB 7.2K SATA/300 2.5\" Seagate Momentus 7200.4 16MB", "ST9250410AS" => "250GB 7.2K SATA/300 2.5\" Seagate Momentus 7200.4 16MB", "ST9320423AS" => "320GB 7.2K SATA/300 2.5\" Seagate Momentus 7200.4 16MB", "ST9500420AS" => "500GB 7.2K SATA/300 2.5\" Seagate Momentus 7200.4 16MB", "ST92505610AS" => "250GB 7.2K Hybrid SATA/300 2.5\" Seagate Momentus XT 32MB", "ST93205620AS" => "320GB 7.2K Hybrid SATA/300 2.5\" Seagate Momentus XT 32MB", "ST95005620AS" => "500GB 7.2K Hybrid SATA/300 2.5\" Seagate Momentus XT 32MB", "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", "ST973402SS" => "73GB 10K SAS/3 2.5\" Seagate Savvio 10K.2 16MB", "ST9146802SS" => "146GB 10K SAS/3 2.5\" Seagate Savvio 10K.2 16MB", "ST936751SS" => "37GB 15K SAS/3 2.5\" Seagate Savvio 15K 16MB", "ST973451SS" => "73GB 15K SAS/3 2.5\" Seagate Savvio 15K 16MB", "ST9146803SS" => "146GB 10K SAS/6 2.5\" Seagate Savvio 10K.3 16MB", "ST9146703SS" => "146GB 10K SAS/6 2.5\" Seagate Savvio 10K.3 16MB", # SED "ST9300603SS" => "300GB 10K SAS/6 2.5\" Seagate Savvio 10K.3 16MB", "ST9300503SS" => "300GB 10K SAS/6 2.5\" Seagate Savvio 10K.3 16MB", # SED "ST9450404SS" => "450GB 10K SAS/6 2.5\" Seagate Savvio 10K.4 16MB", "ST9450304SS" => "450GB 10K SAS/6 2.5\" Seagate Savvio 10K.4 16MB", # SED "ST9600204SS" => "600GB 10K SAS/6 2.5\" Seagate Savvio 10K.4 16MB", "ST9600104SS" => "600GB 10K SAS/6 2.5\" Seagate Savvio 10K.4 16MB", # SED "ST9300605SS" => "300GB 10K SAS/6 2.5\" Seagate Savvio 10K.4 64MB", "ST9300505SS" => "300GB 10K SAS/6 2.5\" Seagate Savvio 10K.4 64MB", # SED "ST9450405SS" => "450GB 10K SAS/6 2.5\" Seagate Savvio 10K.4 64MB", "ST9450305SS" => "450GB 10K SAS/6 2.5\" Seagate Savvio 10K.4 64MB", # SED "ST9600205SS" => "600GB 10K SAS/6 2.5\" Seagate Savvio 10K.4 64MB", "ST9600105SS" => "600GB 10K SAS/6 2.5\" Seagate Savvio 10K.4 64MB", # SED "ST9900805SS" => "900GB 10K SAS/6 2.5\" Seagate Savvio 10K.4 64MB", "ST9900705SS" => "900GB 10K SAS/6 2.5\" Seagate Savvio 10K.4 64MB", # SED "ST973452SS" => "73GB 15K SAS/6 2.5\" Seagate Savvio 15K.2 16MB", "ST973352SS" => "73GB 15K SAS/6 2.5\" Seagate Savvio 15K.2 16MB", # SED "ST9146852SS" => "146GB 15K SAS/6 2.5\" Seagate Savvio 15K.2 16MB", "ST9146752SS" => "146GB 15K SAS/6 2.5\" Seagate Savvio 15K.2 16MB", # SED "ST9146853SS" => "146GB 15K SAS/6 2.5\" Seagate Savvio 15K.3 64MB", "ST9146753SS" => "146GB 15K SAS/6 2.5\" Seagate Savvio 15K.3 64MB", # SED "ST9300653SS" => "300GB 15K SAS/6 2.5\" Seagate Savvio 15K.3 64MB", "ST9300553SS" => "300GB 15K SAS/6 2.5\" Seagate Savvio 15K.3 64MB", # SED "ST9160511NS" => "160GB 7.2K SATA/300 2.5\" Seagate Constellation 32MB", "ST9500530NS" => "500GB 7.2K SATA/300 2.5\" Seagate Constellation 32MB", "ST9250610NS" => "250GB 7.2K SATA/600 2.5\" Seagate Constellation.2 64MB", "ST9250611NS" => "250GB 7.2K SATA/600 2.5\" Seagate Constellation.2 64MB", # SED "ST9500620NS" => "500GB 7.2K SATA/600 2.5\" Seagate Constellation.2 64MB", "ST9500621NS" => "500GB 7.2K SATA/600 2.5\" Seagate Constellation.2 64MB", # SED "ST91000640NS" => "1TB 7.2K SATA/600 2.5\" Seagate Constellation.2 64MB", "ST91000641NS" => "1TB 7.2K SATA/600 2.5\" Seagate Constellation.2 64MB", # SED "ST9500430SS" => "500GB 7.2K SAS/6 2.5\" Seagate Constellation 16MB", "ST9500431SS" => "500GB 7.2K SAS/6 2.5\" Seagate Constellation 16MB", # SED "ST9250610SS" => "250GB 7.2K SAS/6 2.5\" Seagate Constellation.2 64MB", "ST9250611SS" => "250GB 7.2K SAS/6 2.5\" Seagate Constellation.2 64MB", # SED "ST9500620SS" => "500GB 7.2K SAS/6 2.5\" Seagate Constellation.2 64MB", "ST9500621SS" => "500GB 7.2K SAS/6 2.5\" Seagate Constellation.2 64MB", # SED "ST91000640SS" => "1TB 7.2K SAS/6 2.5\" Seagate Constellation.2 64MB", "ST91000641SS" => "1TB 7.2K SAS/6 2.5\" Seagate Constellation.2 64MB", # SED ################################################################################ # Fujitsu "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", # NC=SCA-2, NP=68-pin-wide "MAP3367(NC|NP)" => "36GB 10K U320 Fujitsu MAP", "MAP3735(NC|NP)" => "73GB 10K U320 Fujitsu MAP", "MAP3147(NC|NP)" => "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", "MBD2147RC" => "147GB 10K SAS/6 2.5\" Fujitsu MBD 16MB", "MBD2300RC" => "300GB 10K SAS/6 2.5\" Fujitsu MBD 16MB", "MBE2073RC" => "73GB 15K SAS/6 2.5\" Fujitsu MBE 16MB", "MBE2147RC" => "147GB 15K SAS/6 2.5\" Fujitsu MBE 16MB", "MBF2300RC" => "300GB 10K SAS/6 2.5\" Fujitsu MBF 16MB", "MBF2450RC" => "450GB 10K SAS/6 2.5\" Fujitsu MBF 16MB", "MBF2600RC" => "600GB 10K SAS/6 2.5\" Fujitsu MBF 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 U160 Compaq/Seagate 36ES", "BD03664553" => "36GB 10K U160 Compaq/Seagate 36ES", # ST336706LC "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", # sn=J492NWBK, seagate-PN=8J147J00415F1 "BD3008A4B6" => "300GB 10K U320 Compaq", "BD0728A4C4" => "72GB 10K U320 Compaq/Seagate 10K.7", # related to BD0729A4C7, sn=3KT33AD6, seagate-PN=9X3006, ST373207LC, firm=HPB4 "BD1468A4C5" => "146GB 10K U320 Compaq/Seagate 10K.7", "BD3008A4C6" => "300GB 10K U320 Compaq/Seagate 10K.7", "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", "BD0729A4B7" => "72GB 10K U320 Compaq", # sn=J20K3YYK, seagate-PN=8J073L00216F1 "BD1469A4B8" => "146GB 10K U320 Compaq", "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 U320 Compaq", "BF0728683C" => "72GB 15K U320 Compaq", "BF14686842" => "146GB 15K U320 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", "BF0368B269" => "36GB 15K U320 Compaq/Seagate 15K.5", "BF0728B26A" => "72GB 15K U320 Compaq/Seagate 15K.5", "BF1468B26B" => "146GB 15K U320 Compaq/Seagate 15K.5", "BF3008B26C" => "300GB 15K U320 Compaq/Seagate 15K.5", # sn=3LM5700N, Seagate-PN=9Z1006-623, ST3300655LC "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 "DF072A4940" => "72GB 15K SAS/3 HP/Hitachi Ultrastar 15K300", "DF146A4941" => "146GB 15K SAS/3 HP/Hitachi Ultrastar 15K300", # HUS153014VLS300, firmware HPD3 "DF300A4950" => "300GB 15K SAS/3 HP/Hitachi Ultrastar 15K300", # HUS153030VLS300, firmware HPD3 "DF036A8B55" => "36GB 15K SAS/3 HP/Seagate 15K.4", "DF072A8B56" => "72GB 15K SAS/3 HP/Seagate 15K.4", # ST373454SS, firmware HPD7 "DF146A8B57" => "146GB 15K SAS/3 HP/Seagate 15K.4", "DF036A9843" => "36GB 15K SAS/3 HP/Fujitsu MAX", "DF072A9844" => "72GB 15K SAS/3 HP/Fujitsu MAX", # MAX3073RC, firmware HPD0 "DF146A9845" => "146GB 15K SAS/3 HP/Fujitsu MAX", "DF036ABAA7" => "36GB 15K SAS/3 HP/Seagate 15K.5", "DF072ABAA8" => "72GB 15K SAS/3 HP/Seagate 15K.5", "DF146ABAA9" => "146GB 15K SAS/3 HP/Seagate 15K.5", "DF300ABAAA" => "300GB 15K SAS/3 HP/Seagate 15K.5", # ST3300655SS, firmware HPD5 "DF072BABUD" => "72GB 15K SAS/3 HP/Hitachi Ultrastar 15K300", # HUS153073VLS300 "DF146BABUE" => "146GB 15K SAS/3 HP/Hitachi Ultrastar 15K300", # HUS153014VLS300, firmware HPD5 "DF300BABUF" => "300GB 15K SAS/3 HP/Hitachi Ultrastar 15K300", "DF072BAFDT" => "72GB 15K SAS/3 HP/Fujitsu MBA", # MBA3300RC "DF146BAFDU" => "146GB 15K SAS/3 HP/Fujitsu MBA", "DF300BAFDV" => "300GB 15K SAS/3 HP/Fujitsu MBA", # sn=BJ04P8A017TU0843 "DF072BB6BC" => "72GB 15K SAS/3 HP/Seagate 15K.5", "DF146BB6C2" => "146GB 15K SAS/3 HP/Seagate 15K.5", # ST3146855SS, firmware HPD7 "DF300BB6C3" => "300GB 15K SAS/3 HP/Seagate 15K.5", "DF0146B8052" => "146GB 15K SAS/3 HP/Seagate 15K.6", "DF0300B8053" => "300GB 15K SAS/3 HP/Seagate 15K.6", # ST3300656SS "DF0450B8054" => "450GB 15K SAS/3 HP/Seagate 15K.6", # ST3450856SS, sn=3QQ045TV00009846S0YL "DF0300BAERF" => "300GB 15K SAS/3 HP/Hitachi Ultrastar 15K450", # HUS154530VLS300 "DF0450BAERH" => "450GB 15K SAS/3 HP/Hitachi Ultrastar 15K450", "EF0300FARMU" => "300GB 15K SAS/6 HP/Seagate 15K.7", # sn=3SJ05DSW000090119UY8, seagate-sn=3SJ05DSW, seagate-pn=9FL066-501 "EF0450FARMV" => "450GB 15K SAS/6 HP/Seagate 15K.7", # sn=3SK06B9C00009023SG6P, seagate-sn=3SK06B9C, seagate-pn=9FM066-506 "EF0600FARNA" => "600GB 15K SAS/6 HP/Seagate 15K.7", # sn=6SL03WDX0000M1206481, seagate-sn=6SL03WDX, seagate-pn=9FN066-502 "EF0300FATFD" => "300GB 15K SAS/6 HP/Hitachi Ultrastar 15K600", # HUS156030VLS60 "EF0450FATFE" => "450GB 15K SAS/6 HP/Hitachi Ultrastar 15K600", "EF0600FATFF" => "600GB 15K SAS/6 HP/Hitachi Ultrastar 15K600", "DG072A4951" => "72GB 10K SAS 2.5\" HP/Hitachi Ultrastar C10K147", # HUC101473CSS300, sn=P2V9VK0A, firm=HPD4 "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" => "72GB 10K SAS 2.5\" HP/Seagate Savvio 10K.2 16MB", # ST973402SS "DG146ABAB4" => "146GB 10K SAS 2.5\" HP/Seagate Savvio 10K.2 16MB", "DG072BAAJA" => "72GB 10K SAS 2.5\" HP/Hitachi Ultrastar C10K147", "DG146BAAJB" => "147GB 10K SAS 2.5\" HP/Hitachi Ultrastar C10K147", # HUC101414CSS300 "DG072BABCE" => "72GB 10K SAS 2.5\" HP/Fujitsu MBB 16MB", "DG146BABCF" => "146GB 10K SAS 2.5\" HP/Fujitsu MBB 16MB", # MBB2147RC "DG072BB975" => "72GB 10K SAS 2.5\" HP/Seagate Savvio 10K.2 16MB", "DG146BB976" => "146GB 10K SAS 2.5\" HP/Seagate Savvio 10K.2 16MB", # ST9146802SS "DG0146BAHZP" => "146GB 10K SAS/6 2.5\" HP/Seagate Savvio 10K.3 16MB", "DG0300BAHZQ" => "300GB 10K SAS/6 2.5\" HP/Seagate Savvio 10K.3 16MB", # related to DG0300BALVP "DG0072BALVL" => "72GB 10K SAS/6 2.5\" HP/Seagate Savvio 10K.3 16MB", # ST9146803SS#72, HPD3 "DG0146BALVN" => "146GB 10K SAS/6 2.5\" HP/Seagate Savvio 10K.3 16MB", "DG0300BALVP" => "300GB 10K SAS/6 2.5\" HP/Seagate Savvio 10K.3 16MB", # ST9300603SS, HPD2 "DG0146BARTP" => "146GB 10K SAS/6 2.5\" HP/Fujitsu MBD 16MB", # sn=D0A2P97052WP0930, firm=HPD0, fujitsu-sn=D0A2P97052WP "DG0300BARTQ" => "300GB 10K SAS/6 2.5\" HP/Fujitsu MBD 16MB", "DG0146FAMWL" => "146GB 10K SAS/6 2.5\" HP/Seagate Savvio 10K.3 16MB", # sn=3SD1FVSP00009009JB59, firm=HPDC, ST9146803SS "DG0300FAMWN" => "300GB 10K SAS/6 2.5\" HP/Seagate Savvio 10K.3 16MB", "DG0146FARVU" => "146GB 10K SAS/6 2.5\" HP/Hitachi Ultrastar C10K300", # sn=PCWB8GAE, firm=HPD5, guess hitachi based on sn "DG0300FARVV" => "300GB 10K SAS/6 2.5\" HP/Hitachi Ultrastar C10K300", "EG0146FARTR" => "146GB 10K SAS/6 2.5\" HP/Fujitsu MBD 16MB", # dual port, sn=D2A1PA102V381004, firm=HPD5, fujitsu-sn=D2A1PA102V38 "EG0300FARTT" => "300GB 10K SAS/6 2.5\" HP/Fujitsu MBD 16MB", "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 "DH0036BALWK" => "36GB 15K SAS/6 2.5\" HP/Seagate Savvio 15K.2 16MB", "DH0072BALWL" => "72GB 15K SAS/6 2.5\" HP/Seagate Savvio 15K.2 16MB", "DH0146BALWN" => "146GB 15K SAS/6 2.5\" HP/Seagate Savvio 15K.2 16MB", # ST9146852SS, firmware HPD0 "DH0072FAQRD" => "72GB 15K SAS/6 2.5\" HP/Seagate Savvio 15K.2 16MB", # dual-port "DH0146FAQRE" => "146GB 15K SAS/6 2.5\" HP/Seagate Savvio 15K.2 16MB", # ST9146852SS, firmware HPDB # SATA # serial number lookup # http://support.seagate.com/customer/warranty_validation.jsp (need to get model number right, so make good guess) # http://websupport.wdc.com/warranty/serialinput.asp?custtype=end&requesttype=warranty&lang=en # http://www.hitachigst.com/portal/site/en/support/warranty/ # https://hdd.fcpa.fujitsu.com/myapps/admin/jsp/webrma/addRequest1NoLogin.jsp # 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 Barracuda 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" => { # ST3250310NS 'pretty' => '250GB 7.2K SATA/150 HP/Seagate Barracuda ES.2 32MB', 'firmware-advisory' => { 'yerr' => '10001', 'firmware' => 'HPG[1-5]', 'severity' => 0, }, }, "GB0500C8046" => { # serial: 9QM10Y2H, seagate part: 9CA154-783 'pretty' => '500GB 7.2K SATA/150 HP/Seagate Barracuda ES.2 32MB', 'firmware-advisory' => { 'yerr' => '10001', 'firmware' => 'HPG[1-5]', 'severity' => 0, }, }, "GB0750C8047" => { 'pretty' => '750GB 7.2K SATA/150 HP/Seagate Barracuda ES.2 32MB', 'firmware-advisory' => { 'yerr' => '10001', 'firmware' => 'HPG[1-5]', 'severity' => 0, }, }, "GB0160CAABV" => "160GB 7.2K SATA/300 HP", "GB0160EAFJE" => "160GB 7.2K SATA/300 HP/Seagate 7200.10", # ST3160815AS "GB0250EAFJF" => { 'pretty' => '250GB 7.2K SATA/300 HP/Seagate Barracuda ES.2 32MB', 'firmware-advisory' => { 'yerr' => '10001', 'firmware' => 'HPG[1-5]', 'severity' => 0, }, }, "GB0500EAFJH" => { 'pretty' => '500GB 7.2K SATA/300 HP/Seagate Barracuda ES.2 32MB', 'firmware-advisory' => { 'yerr' => '10001', 'firmware' => 'HPG[1-5]', 'severity' => 0, }, }, "GB0750EAFJK" => { 'pretty' => '750GB 7.2K SATA/300 HP/Seagate Barracuda ES.2 32MB', 'firmware-advisory' => { 'yerr' => '10001', 'firmware' => 'HPG[1-5]', 'severity' => 0, }, }, "GB1000EAFJL" => { # ST31000340NS 'pretty' => '1TB 7.2K SATA/300 HP/Seagate Barracuda ES.2 32MB', 'firmware-advisory' => { 'yerr' => '10001', 'firmware' => 'HPG[1-5]', 'severity' => 0, }, }, "VB0250EAVER" => "250GB 7.2K SATA/300 HP/Seagate Barracuda", # sn=9VMPG909 "GB0250EAFYK" => "250GB 7.2K SATA/300 HP/WD RE3 16MB", # WD2502ABYS "GB0500EAFYL" => "500GB 7.2K SATA/300 HP/WD RE3 16MB", "GB0750EAMYB" => "750GB 7.2K SATA/300 HP/WD RE3 32MB", "GB1000EAMYC" => "1TB 7.2K SATA/300 HP/WD RE3 32MB", # WD1002FBYS, HPG1 "MB0500CBEPQ" => "500GB 7.2K SATA/300 HP/Seagate Constellation ES 32MB", # sn=9WJ07V88, seagate-pn=9JW152-290, ST3500514NS "MB0500EAMZD" => "500GB 7.2K SATA/300 HP/Seagate Constellation ES 32MB", "MB1000EAMZE" => "1TB 7.2K SATA/300 HP/Seagate Constellation ES 32MB", "MB2000EAMZF" => "2TB 7.2K SATA/300 HP/Seagate Constellation ES 64MB", # sn=9WK08JQY, ST32000644NS "MB2000EAZNL" => "2TB 7.2K SATA/300 HP/WD RE4 64MB", # sn=WMAY00040218 matches WD2003FYYS sn=WMAY00028700 "MB0500EBNCR" => "500GB 7.2K SATA/300 HP/WD", # sn=WMAYP0543102, wd_pn=WDMH5003-70WER "MB1000FAMYU" => "1TB 7.2K SAS/3 HP/Seagate Constellation ES 16MB", # sn=9WK07H21, seagate-pn=9JX244-501, ST31000424SS "MB2000FAMYV" => "2TB 7.2K SAS/3 HP/Seagate Constellation ES 16MB", "DB7500BABFE" => "750GB 7.2K SAS/3 HP/Seagate Barracuda ES.2 16MB", "DB1000BABFF" => "1TB 7.2K SAS/3 HP/Seagate Barracuda ES.2 16MB", # sn=9QJ5PCVK00009012D89V, seagate-pn=9EF248-583, ST31000640SS ################################################################################ # Maxtor # "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", "ATLAS10K4-146" => "146GB 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", "ATLAS15K2-036SAS" => "36GB 15K SAS Maxtor Atlas 15K II", "ATLAS15K2-073SAS" => "73GB 15K SAS Maxtor Atlas 15K II", "ATLAS15K2-146SAS" => "146GB 15K SAS 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", # we have same issue with Seagate/Maxtor as we do with Hitachi drives, see Hitachi for comments # so, need to also use truncated versions where not ambiguous. only need to deal with SATA. "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", "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", # either DiamondMax 20 or 21 "STM316021" => "160GB 7.2K SATA/300 Maxtor DiamondMax 2MB", "STM3160813AS" => { 'pretty' => "160GB 7.2K SATA/300 Maxtor DiamondMax 22 8MB", 'firmware-advisory' => { 'yerr' => '10007', 'firmware' => '.', 'severity' => 0, }, }, "STM3320614AS" => { 'pretty' => "320GB 7.2K SATA/300 Maxtor DiamondMax 22 16MB", 'firmware-advisory' => { 'yerr' => '10007', 'firmware' => '.', 'severity' => 0, }, }, "STM3500320AS" => { 'pretty' => "500GB 7.2K SATA/300 Maxtor DiamondMax 22 32MB", 'firmware-advisory' => { 'yerr' => '10006', 'firmware' => 'MX15', 'severity' => 0, }, }, "STM3640323AS" => { 'pretty' => "640GB 7.2K SATA/300 Maxtor DiamondMax 22 32MB", 'firmware-advisory' => { 'yerr' => '10007', 'firmware' => '.', 'severity' => 0, }, }, "STM3750330AS" => { 'pretty' => "750GB 7.2K SATA/300 Maxtor DiamondMax 22 32MB", 'firmware-advisory' => { 'yerr' => '10006', 'firmware' => 'MX15', 'severity' => 0, }, }, "STM31000334AS" => { 'pretty' => "1TB 7.2K SATA/300 Maxtor DiamondMax 22 32MB", 'firmware-advisory' => { 'yerr' => '10007', 'firmware' => '.', 'severity' => 0, }, }, "STM31000333AS" => { 'pretty' => "1TB 7.2K SATA/300 Maxtor DiamondMax 22 32MB", 'firmware-advisory' => { 'yerr' => '10006', 'firmware' => 'MX15', 'severity' => 0, }, }, "STM31000340AS" => { 'pretty' => "1TB 7.2K SATA/300 Maxtor DiamondMax 22 32MB", 'firmware-advisory' => { 'yerr' => '10006', 'firmware' => 'MX15', 'severity' => 0, }, }, # one of the previous three "STM310003" => "1TB 7.2K SATA/300 Maxtor DiamondMax 22 32MB", "STM3160318AS" => "160GB 7.2K SATA/300 Maxtor DiamondMax 23 8MB", "STM3250318AS" => "250GB 7.2K SATA/300 Maxtor DiamondMax 23 8MB", "STM3320418AS" => "320GB 7.2K SATA/300 Maxtor DiamondMax 23 16MB", "STM3500418AS" => "500GB 7.2K SATA/300 Maxtor DiamondMax 23 16MB", "STM3750528AS" => "750GB 7.2K SATA/300 Maxtor DiamondMax 23 32MB", "STM31000528AS" => "1TB 7.2K SATA/300 Maxtor DiamondMax 23 32MB", "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 # http://download.micron.com/pdf/numbering/numssd.pdf # issues with truncated model names for intel; see hitachi sata drives for details "SSDSA2MH080G1G[CN]" => "80GB SSD SATA/300 2.5\" Intel X25-M MLC", "SSDSA2MH160G1G[CN]" => "160GB SSD SATA/300 2.5\" Intel X25-M MLC", "SSDSA2SH032G1G[CN]" => "32GB SSD SATA/300 2.5\" Intel X25-E SLC", "SSDSA2SH064G1G[CN]" => "64GB SSD SATA/300 2.5\" Intel X25-E SLC", "SSDSA2M080G2G[CN]" => "80GB SSD SATA/300 2.5\" Intel X25-M G2 MLC", "SSDSA2M160G2G[CN]" => "160GB SSD SATA/300 2.5\" Intel X25-M G2 MLC", # http://www.samsung.com/global/business/semiconductor/productList.do?fmly_id=161 "MCBQE25G5MPQ" => "25GB SSD SATA/300 2.5\" Samsung SSD SS415 SLC", "MCCOE50G5MPQ" => "50GB SSD SATA/300 2.5\" Samsung SSD SS415 SLC", "MCBQE32G5MPQ" => "32GB SSD SATA/300 2.5\" Samsung SSD SS410 SLC", "MCCOE64G5MPQ" => "64GB SSD SATA/300 2.5\" Samsung SSD SS410 SLC", "MCB4E50G5MXP-0VB" => "50GB SSD SATA/300 2.5\" Samsung SS805 SLC", "MCB4E60G5MXP-0VB" => "60GB SSD SATA/300 2.5\" Samsung SS805 SLC", "MCCOE50G5MXP-0VB" => "50GB SSD SATA/300 2.5\" Samsung SS805 SLC", "MCCOE1HG5MXP-0VB" => "100GB SSD SATA/300 2.5\" Samsung SS805 SLC", "MCCOE1H5MXP-0VB" => "100GB SSD SATA/300 2.5\" Samsung SS805 SLC", # same as above? maybe sample "MCCOEA2G5MXP-0VB" => "120GB SSD SATA/300 2.5\" Samsung SS805 SLC", "MMCRE64G5MXP-0VB" => "64GB SSD SATA/300 2.5\" Samsung PM800 MLC", "MMCRE28G5MXP-0VB" => "128GB SSD SATA/300 2.5\" Samsung PM800 MLC", "MMDOE56G5MXP-0VB" => "256GB SSD SATA/300 2.5\" Samsung PM800 MLC", "SAMSUNG-SSD-PB22-JS3-FDE-TM-64GB" => "64GB SSD SATA/300 1.8\" Samsung PB22-JS3 MLC", "SAMSUNG-SSD-PB22-JS3-FDE-TM-128GB" => "128GB SSD SATA/300 1.8\" Samsung PB22-JS3 MLC", "SAMSUNG-SSD-PB22-JS3-FDE-TM-256GB" => "256GB SSD SATA/300 2.5\" Samsung PB22-JS3 MLC", "MK0060EAVDR" => "60GB SSD SATA/300 2.5\" HP/Samsung SS805 SLC", # MCB4E60G5MXP-0VB "MK0120EAVDT" => "120GB SSD SATA/300 2.5\" HP/Samsung SS805 SLC", "Axiom-Mobile-Signature" => "%B SSD SATA/300 2.5\" Axiom Signature MLC", "OCZ-Z-Drive-P84" => "%B SSD SATA/300 OCZ Z-Drive p84 MLC", "OCZ-VERTEX" => "%B SSD SATA/300 2.5\" OCZ Vertex MLC", "OCZ-ONYX" => "%B SSD SATA/300 2.5\" OCZ Onyx MLC", "DENCSTE351M11-0050" => "50GB SSD SATA/300 OCZ Deneva MLC", "DENCSTE351M11-0100" => "100GB SSD SATA/300 OCZ Deneva MLC", "DENCSTE351M11-0120" => "120GB SSD SATA/300 OCZ Deneva MLC", "DENCSTE351M11-0200" => "200GB SSD SATA/300 OCZ Deneva MLC", "DENCSTE351M11-0240" => "240GB SSD SATA/300 OCZ Deneva MLC", "DENCSTE351M10-0400" => "400GB SSD SATA/300 OCZ Deneva MLC", "DENCSTE351M10-0480" => "480GB SSD SATA/300 OCZ Deneva MLC", "DENCSTE251M11-0050" => "50GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M11-0100" => "100GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M11-0120" => "120GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M11-0200" => "200GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M11-0240" => "240GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M10-0400" => "400GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M10-0480" => "480GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M21-0040" => "50GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M21-0050" => "50GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M21-0060" => "60GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M21-0100" => "100GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M21-0120" => "120GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M21-0200" => "200GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M21-0240" => "240GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M20-0400" => "400GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENCSTE251M20-0480" => "480GB SSD SATA/300 2.5\" OCZ Deneva MLC", "DENRSTE251M21-0050" => "50GB SSD SATA/300 2.5\" OCZ Deneva Reliability MLC", "DENRSTE251M21-0100" => "100GB SSD SATA/300 2.5\" OCZ Deneva Reliability MLC", "DENRSTE251M21-0200" => "200GB SSD SATA/300 2.5\" OCZ Deneva Reliability MLC", "DENRSTE251M20-0400" => "400GB SSD SATA/300 2.5\" OCZ Deneva Reliability MLC", "DENRSTE251M31-0050" => "50GB SSD SATA/300 2.5\" OCZ Deneva Reliability MLC", "DENRSTE251M31-0100" => "100GB SSD SATA/300 2.5\" OCZ Deneva Reliability MLC", "DENRSTE251M31-0200" => "200GB SSD SATA/300 2.5\" OCZ Deneva Reliability MLC", "DENRSTE251M30-0400" => "400GB SSD SATA/300 2.5\" OCZ Deneva Reliability MLC", "DENRSTE251E10-0050" => "50GB SSD SATA/300 2.5\" OCZ Deneva Reliability eMLC", "DENRSTE251E10-0100" => "100GB SSD SATA/300 2.5\" OCZ Deneva Reliability eMLC", "DENRSTE251E10-0200" => "200GB SSD SATA/300 2.5\" OCZ Deneva Reliability eMLC", "DENRSTE251E10-0400" => "400GB SSD SATA/300 2.5\" OCZ Deneva Reliability eMLC", "DENCSTE251S10-0050" => "50GB SSD SATA/300 2.5\" OCZ Deneva SLC", "DENRSTE251S10-0050" => "50GB SSD SATA/300 2.5\" OCZ Deneva Reliability SLC", "DENRSTE251S10-0100" => "100GB SSD SATA/300 2.5\" OCZ Deneva Reliability SLC", "DENRSTE251S10-0200" => "200GB SSD SATA/300 2.5\" OCZ Deneva Reliability SLC", "DENRSTE251S30-0050" => "50GB SSD SATA/300 2.5\" OCZ Deneva Reliability SLC", "DENRSTE251S30-0100" => "100GB SSD SATA/300 2.5\" OCZ Deneva Reliability SLC", "DENRSTE251S30-0200" => "200GB SSD SATA/300 2.5\" OCZ Deneva Reliability SLC", "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", "Z16IZD3B-100UC" => "100GB SSD SAS/3 STEC Zeus IOPS SSD SLC", "SSD-D0030S[CI]?-5000" => "30GB SSD SATA/300 2.5\" WD SiliconDrive III", "SSD-D0060S[CI]?-5000" => "60GB SSD SATA/300 2.5\" WD SiliconDrive III", "SSD-D0090S[CI]?-5000" => "90GB SSD SATA/300 2.5\" WD SiliconDrive III", "SSD-D0120S[CI]?-5000" => "120GB SSD SATA/300 2.5\" WD SiliconDrive III", "ST950011FS" => "50GB SSD SATA/300 2.5\" Seagate Pulsar SLC", "ST9100011FS" => "100GB SSD SATA/300 2.5\" Seagate Pulsar SLC", "ST9200011FS" => "200GB SSD SATA/300 2.5\" Seagate Pulsar SLC", "ST100FM0012" => "100GB SSD SATA/600 2.5\" Seagate Pulsar.2 MLC", "ST200FM0012" => "200GB SSD SATA/600 2.5\" Seagate Pulsar.2 MLC", "ST400FM0012" => "400GB SSD SATA/600 2.5\" Seagate Pulsar.2 MLC", "ST100FM0002" => "100GB SSD SAS/6 2.5\" Seagate Pulsar.2 MLC", "ST200FM0002" => "200GB SSD SAS/6 2.5\" Seagate Pulsar.2 MLC", "ST400FM0002" => "400GB SSD SAS/6 2.5\" Seagate Pulsar.2 MLC", "ST800FM0002" => "800GB SSD SAS/6 2.5\" Seagate Pulsar.2 MLC", "ST100FX0002" => "100GB SSD SAS/6 2.5\" Seagate Pulsar XT.2 SLC", "ST200FX0002" => "200GB SSD SAS/6 2.5\" Seagate Pulsar XT.2 SLC", "ST400FX0002" => "400GB SSD SAS/6 2.5\" Seagate Pulsar XT.2 SLC", "Pliant-LB150S" => "150GB SSD SAS/3 2.5\" Pliant Lightning LB SLC", "Pliant-LS150S" => "150GB SSD SAS/3 Pliant Lightning LS SLC", "Pliant-LS300S" => "300GB SSD SAS/3 Pliant Lightning LS SLC", "REALSSD-C300-2.5" => "%B SSD SATA/600 2.5\" Micron RealSSD C300 MLC", ); # memory configurations: # intel 5500 chipset: # http://h18006.www1.hp.com/products/quickspecs/13236_ca/13236_ca.HTML#Memory my(@system_models) = ( { "model" => "VMware", "ids" => [ "(0x20001022,0x20001022,0x10|0x075015ad,0x100f8086,0x01)", # Network ], "sockets" => 1, }, { "model" => "Supermicro X8SIL", "ids" => [ "0x060515d9,0x10d38086,0x00", # Network ], "form-factor" => "Micro ATX, 244mm x 244mm", "sockets" => 1, "socket-type" => "Intel-LGA1156 - Socket H", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => "4", "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => "2", "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "32 GB RDIMM; 16 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 4 GB UDIMM", "memory-max-ranks" => "16 RDIMM; 8 UDIMM", "memory-max-ranks-per-channel" => "8 RDIMM; 4 UDIMM", "memory-max-ranks-per-slot" => "4 RDIMM; 2 UDIMM", "sata-ports" => 4, "lan-ports" => 2, "serial-ports" => 1, "pci-e 2.0 x8/x8" => 2, "pci-e x4/x8" => 1, # x4 support in x8 slot "pci" => 1, "vga" => 1, "usb 2.0" => 5, "specs" => "http://www.supermicro.com/manuals/motherboard/3420/MNL-1130.pdf", }, { "model" => "Supermicro X8SIE", "ids" => [ "0x040d15d9,0x10d38086,0x00", # Network ], "form-factor" => "ATX, 305mm x 244mm", "sockets" => 1, "socket-type" => "Intel-LGA1156 - Socket H", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => "6", "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => "2", "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "32 GB RDIMM; 16 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 4 GB UDIMM", "memory-max-ranks" => "16 RDIMM; 8 UDIMM", "memory-max-ranks-per-channel" => "8 RDIMM; 4 UDIMM", "memory-max-ranks-per-slot" => "4 RDIMM; 2 UDIMM", "sata-ports" => 6, "lan-ports" => 2, "serial-ports" => 1, "pci-e 2.0 x16/x16" => 1, "pci-e x4/x8" => 1, # x4 support in x8 slot "pci" => 1, "vga" => 1, "usb 2.0a" => 8, "specs" => "http://www.supermicro.com/manuals/motherboard/3420/MNL-1144.pdf", }, { "model" => "Supermicro X8STi", "ids" => [ "0x10d315d9,0x10d38086,0x00", # Network "0x000915d9,0x3a2[026]8086,0x00", # SATA ], "form-factor" => "ATX, 305mm x 244mm", "sockets" => 1, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC Unbuffered", "memory-slots" => "6", "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => "3", "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "24 GB", "memory-max-size-per-slot" => "4 GB", "memory-max-ranks" => "24", "memory-max-ranks-per-channel" => "8", "memory-max-ranks-per-slot" => "4", "sata-ports" => 6, "lan-ports" => 2, "serial-ports" => 1, "pci" => 1, "pci-e x8" => 1, "pci-e x16" => 1, }, { "model" => "Inventec 5241", "ids" => [ "0x00461170,0x10c98086,0x01", # Network "0x00461170,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slot-type" => "DDR3 240-pin DIMM", "memory-slots" => 18, "memory-channels" => 6, "memory-per-socket" => 'Ch-[ABC],Ch-[DEF]', "memory-population-order" => 'Ch-[AD] DIMM0,Ch-[BE] DIMM0,Ch-[CF] DIMM0,Ch-[AD] DIMM1,Ch-[BE] DIMM1,Ch-[CF] DIMM1,Ch-[AD] DIMM2,Ch-[BE] DIMM2,Ch-[CF] DIMM2', }, { "model" => "Dell DCS XS23-TY", "ids" => [ "0x00008086,0x10cd8086,0x00", # Network "0x00471170,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slot-type" => "DDR3 240-pin DIMM", "memory-slots" => 9, }, { "model" => "Dell DCS XS23-TY3", "ids" => [ "0x(00000000|004a1170),0x10c98086,0x01", # Network "0x00471170,(0x3a2[026]8086|0x28228086),0x00", # SATA ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slot-type" => "DDR3 240-pin DIMM", "memory-slots" => 12, "memory-channels" => 6, "memory-per-socket" => 'CPU0,CPU1', "memory-population-order" => '(01|07),(03|09),(05|11),(02|08),(04|10),(06|12)', "bios-spec" => 'xs23-ty3', }, { "model" => "Cisco UCS C200 M2", "ugly-model" => "Cisco R200-1120402W", "ids" => [ "0x01011137,0x34068086,0x22", # Chipset "0x00651137,0x10c98086,0x01", # Network ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 12, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "96 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 24, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => '[ABC][12],[DEF][12]', "memory-population-order" => '[AD]1,[BE]1,[CF]1,[AD]2,[BE]2,[CF]2', }, { # very similar to Cisco C200 above # uses C2 stepping of chipset "model" => "Quanta QSSC-98J C2", "ids" => [ "0x8969152d,0x34068086,0x22", # Chipset "0x00000000,0x10c98086,0x01", # Network ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 12, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "96 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 24, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => '[ABC][12],[DEF][12]', "memory-population-order" => '[AD]1,[BE]1,[CF]1,[AD]2,[BE]2,[CF]2', "specs" => "http://www.qsscit.com/upfiles/QSSC-980_User%20Manual.pdf", }, { # very close to DCS CS24-TY, see below "model" => "Quanta QSSC-98J", "ids" => [ "0x8969152d,0x34068086,0x13", # Chipset "0x00000000,0x10c98086,0x01", # Network "0x00008086,0x10d38086,0x00", # Network - mgmt port ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 12, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "96 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 24, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => '[ABC][12],[DEF][12]', "memory-population-order" => '[AD]1,[BE]1,[CF]1,[AD]2,[BE]2,[CF]2', "specs" => "http://www.qsscit.com/upfiles/QSSC-980_User%20Manual.pdf", }, { "model" => "Quanta QSSC-890", "ids" => [ "0x8963152d,0x10cc8086,0x00", # Network ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 6, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "48 GB RDIMM; 12 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 24, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => '[ABC]1,[DEF]1', "memory-population-order" => '[AD]1,[BE]1,[CF]1', "specs" => "http://www.qsscit.com/upfiles/QSSC-890%20User%20Manual.pdf", }, { # these next few are all very close # this is rename of Dell DCS CS24-TY, with new chipset rev? "model" => "Dell DCS1100", "model-match" => "DCS1100", "ids" => [ "0x8969152d,0x34038086,0x22", # Chipset "0x8975152d,0x10c98086,0x01", # Network "0x8969152d,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 18, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "144 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 48, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => 'DIMM [ABC],DIMM [DEF]', "memory-population-order" => '[AD]0,[BE]0,[CF]0,[AD]1,[BE]1,[CF]1,[AD]2,[BE]2,[CF]2', "chassis" => '1U', "bios-spec" => 'cs24-ty-2', }, { "model" => "Dell C1100", "model-match" => "C1100", "ids" => [ "0x897a152d,0x34038086,0x22", # Chipset "0x897b152d,0x10c98086,0x01", # Network "0x897a152d,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 18, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "144 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 48, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => 'DIMM [ABC],DIMM [DEF]', "memory-population-order" => '[AD]0,[BE]0,[CF]0,[AD]1,[BE]1,[CF]1,[AD]2,[BE]2,[CF]2', "chassis" => '1U', "bios-spec" => 'c2100', "specs" => 'http://support.dell.com/support/edocs/systems/cp_pe_c1100/en/HOM/HTML/index.htm', }, { "model" => "Dell C2100", "model-match" => "C2100", "ids" => [ "0x897b152d,0x34038086,0x22", # Chipset "0x897b152d,0x10c98086,0x01", # Network "0x897b152d,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 18, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "144 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 48, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => 'DIMM [ABC],DIMM [DEF]', "memory-population-order" => '[AD]0,[BE]0,[CF]0,[AD]1,[BE]1,[CF]1,[AD]2,[BE]2,[CF]2', "chassis" => '2U', "bios-spec" => 'c2100', "specs" => 'http://support.dell.com/support/edocs/systems/cp_pe_c2100/en/HOM/HTML/index.htm', }, { "model" => "Dell DCS CS24-TY", # new version "ids" => [ "0x8969152d,0x34038086,0x22", # Chipset "0x8975152d,0x10c98086,0x01", # Network "0x8969152d,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 18, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "144 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 48, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => 'DIMM [ABC],DIMM [DEF]', "memory-population-order" => '[AD]0,[BE]0,[CF]0,[AD]1,[BE]1,[CF]1,[AD]2,[BE]2,[CF]2', "chassis" => '1U', "bios-spec" => 'cs24-ty-2', }, { # previously called Dell DCS S99 "model" => "Dell DCS CS24-TY", "ugly-model" => "Dell S99", # 0x8975 used for S99, 0x8969 later for CS24-TY "ids" => [ "0x(8969|8975)152d,0x34038086,0x13", # Chipset "0x(00000000|8975152d),0x10c98086,0x01", # Network "0x(8969|8975)152d,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 18, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "144 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 48, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => 'DIMM [ABC],DIMM [DEF]', "memory-population-order" => '[AD]0,[BE]0,[CF]0,[AD]1,[BE]1,[CF]1,[AD]2,[BE]2,[CF]2', "chassis" => '1U', "bios-spec" => 'cs24-ty-1', }, { "model" => "Supermicro X8DTU", "ids" => [ "0x(0100|0600)15d9,0x10c98086,0x01", # Network "0x060015d9,0x3a2[026]8086,0x00", # SATA ], "form-factor" => "307mm x 332mm", "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC Unbuffered, DDR3 ECC Registered", "memory-slots" => "12", "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => "6", "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "96 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => "48", "memory-max-ranks-per-channel" => "8", "memory-max-ranks-per-slot" => "4", "memory-per-socket" => 'P0,P1', "memory-population-order" => '1A,2A,3A,1B,2B,3B', "sata-ports" => 6, "lan-ports" => 2, "serial-ports" => 1, "pci-e 2.0 x16/x16" => 1, "uio" => 1, "specs" => "http://www.supermicro.com/products/motherboard/QPI/5500/X8DTU.cfm", }, { "model" => "Supermicro X8DTL-i", "ids" => [ "0x10d315d9,0x10d38086,0x00", # Network "0x000615d9,0x3a2[026]8086,0x00", # SATA ], "form-factor" => "ATX, 305mm x 254mm", "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC Unbuffered, DDR3 ECC Registered", "memory-slots" => "6", "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => "6", "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "24 GB", "memory-max-size-per-slot" => "4 GB", "memory-max-ranks" => "24", "memory-max-ranks-per-channel" => "4", "memory-max-ranks-per-slot" => "4", "memory-per-socket" => 'P0,P1', "memory-population-order" => '1A,2A,3A', "sata-ports" => 6, "lan-ports" => 2, "serial-ports" => 1, "pci-e 2.0 x8/x16" => 1, # x8 support in x16 slot "pci-e 2.0 x8/x8" => 1, "pci-e 2.0 x4/x8" => 1, # x4 support in x8 slot "pci-e x4/x8" => 1, "pci" => 2, "specs" => "http://www.supermicro.com/products/motherboard/QPI/5500/X8DTL-i.cfm", }, { "model" => "Intel S5500WB", "ids" => [ "0x34ea8086,0x10c98086,0x01", # Network ], "form-factor" => "Extended ATX, 305mm x 330mm", "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC Unbuffered, DDR3 ECC Registered", "memory-slots" => "8", "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => "3", "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "64 GB", "memory-max-size-per-slot" => "8 GB", "memory-max-ranks" => "24", "memory-max-ranks-per-channel" => "8", "memory-max-ranks-per-slot" => "4", "sata-ports" => 6, "lan-ports" => 2, "serial-ports" => 1, "pci-e x8" => 1, "pci-e x16" => 1, }, { "model" => "Intel Urbanna", "ids" => [ "0x34de8086,0x10a78086,0x02", # Network "0x34de8086,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, "dimms" => 12, "memory-type" => "DDR3-1066 ECC Unbuffered", "memory-form" => "240pin DDR3", }, { "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[026]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,0x3a2[026]8086,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 P55M-UD2", "ids" => [ "0xe0001458,0x816810ec,0x03", # Network "0xb0051458,0x3b2[026]8086,0x05", # SATA "0xb0001458,0x2363197b,0x02", # ATA + SATA ], "sockets" => 1, "socket-type" => "Intel-LGA1156 - Socket H", "dimms" => 4, "memory-type" => "DDR3-1333 non-ECC Unbuffered", "max-memory" => "16G", "sata-ports" => 7, "ata-ports" => 1, "lan-ports" => 1, "pci-e 2.0 x16/x16" => 1, "pci-e x4/x16" => 1, # x4 support in x16 slot "pci" => 2, "specs" => "http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ClassValue=Motherboard&ProductID=3165&ProductName=GA-P55M-UD2", }, { "model" => "Gigabyte EX58-UD3R", "ids" => [ "0xe0001458,0x816810ec,0x03", # Network "0xb0051458,0x3a2[026]8086,0x00", # SATA "0xb0001458,0x2363197b,0x02", # ATA + SATA ], "sockets" => 1, "socket-type" => "Intel-LGA1366", "dimms" => 4, "memory-type" => "DDR3-1333 non-ECC Unbuffered", "max-memory" => "16G", "sata-ports" => 8, "ata-ports" => 1, "pci-e x16" => 2, "pci-e x4" => 1, "pci-e x1" => 2, "pci" => 2, "specs" => "http://www.gigabyte.com.tw/Products/Motherboard/Products_Overview.aspx?ClassValue=Motherboard&ProductID=2989&ProductName=GA-EX58-UD3R", }, { "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" => [ "0xb00[25]1458,0x3a2[026]8086,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", 'specs' => 'http://www.tyan.com/product_board_detail.aspx?pid=560', }, { "model" => "Tyan S5376", "ids" => [ "0x521110f1,0x108b8086,0x03", # Network "0x537610f1,0x292[026]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 PE800", "ids" => [ "0x01851028,0x266f8086,0x03", # ATA "0x26528086,0x26528086,0x03", # SATA "0x01851028,0x165914e4,0x01", # Network ], "sockets" => 1, "socket-type" => "Intel-LGA775", "dimms" => 4, "memory-type" => "DDR-533 ECC Unbuffered", "max-memory" => "4G", "sata-ports" => 6, "PCI-X" => 2, "PCI-E x1" => 2, "PCI" => 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 6000 Pro", "ids" => [ "0x3048103c,0x3a0[026]8086,0x02", # SATA "0x3048103c,0x10de8086,0x02", # Network ], "sockets" => 1, "dimms" => 4, "memory-type" => "DDR3-1066 non-ECC Unbuffered", "max-memory" => "16G", }, { "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 DX7400", "ids" => [ "0x352c1462,0x169a14e4,0x02", # Network "0x73521462,0x29218086,0x02", # SATA ], "sockets" => 1, }, { "model" => "HP DC5800", "ids" => [ "0x281e103c,0x10bd8086,0x02", # Network ], "sockets" => 1, "dimms" => 4, "memory-type" => "DDR2-800 non-ECC Unbuffered", "max-memory" => "8G", "broken-ahci" => 1, }, { "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, "socket-type" => "Intel-PGA478", "memory-type" => "DDR Unbuffered", "memory-slots" => "4", "memory-slot-type" => "DDR 184-pin DIMM", "memory-min-speed" => "266 Mhz", "memory-max-speed" => "400 Mhz", "memory-max-size" => "4 GB", "memory-max-size-per-slot" => "1 GB", "memory-max-ranks" => "8", "memory-max-ranks-per-slot" => "2", }, { "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, }, { "model" => "HP DC5100", "ids" => [ "0x300[cd]103c,0x26518086,0x03", # SATA "0x300[56]103c,0x167714e4,0x01", # Network ], "sockets" => 1, "specs" => 'http://h18000.www1.hp.com/products/quickspecs/12145_ca/12145_ca.pdf', }, { "model" => "HP DC5700", "ids" => [ "0x2808103c,0x28208086,0x02", # SATA "0x2808103c,0x28258086,0x02", # SATA "0x2808103c,0x167b14e4,0x02", # Network ], "sockets" => 1, "socket-type" => "Intel-LGA775 - Socket T", "memory-type" => "DDR2 non-ECC Unbuffered", "memory-slots" => "4", "memory-slot-type" => "DDR2 240-pin DIMM", "memory-channels" => "2", "memory-min-speed" => "533 Mhz", "memory-max-speed" => "800 Mhz", "memory-max-size" => "8 GB", "memory-max-size-per-slot" => "2 GB", "memory-max-ranks" => "8", "memory-max-ranks-per-channel" => "4", "memory-max-ranks-per-slot" => "2", }, { "model" => "HP DC5750", "ids" => [ "0x2812103c,0x43801002,0x00", # SATA "0x280a103c,0x167b14e4,0x02", # Network ], "sockets" => 1, }, { "model" => "eSlim SU7-2154", # Quanta S98 board "ugly-model" => "Quanta QSSC-980J/QR1-980J", "ids" => [ "0x00000000,0x10c98086,0x01", # Network "0x8969152d,0x28228086,0x00", # SATA ], "sockets" => 2, }, { "model" => "eSlim SU4-1320", # Quanta S47 board "ugly-model" => "Quanta S47", "ids" => [ "0x8959152d,0x167814e4,0xa3", # Network "0x8959152d,0x292[026]8086,0x02", # SATA ], "dimms" => 4, "memory-type" => "DDR2-800 ECC Unbuffered", "max-memory" => "8G", "sockets" => 1, }, { "model" => "Quanta S44", "ids" => [ "0x8964152d,0x10a78086,0x02", # Network "0x8964152d,0x292[026]8086,0x02", # SATA ], "dimms" => 6, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "48G", "max-ranks" => 12, "sockets" => 2, }, { "model" => "Tyan S2927", "ids" => [ "0xcb8410de,0x037310de,0xa3", # Network "0xcb8410de,0x037f10de,0xa3", # SATA ], "sockets" => 2, "socket-type" => "AMD-LGA1207 - Socket F", "dimms" => 8, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "32G", "sata-ports" => 6, "lan-ports" => 2, }, { "model" => "Supermicro H8DMU", "ids" => [ "0x191115d9,0x037310de,0xa3", # Network "0x191115d9,0x037f10de,0xa3", # SATA ], "sockets" => 2, "socket-type" => "AMD-LGA1207 - Socket F", "dimms" => 16, "memory-type" => "DDR2-800 ECC Registered", "max-memory" => "128G", "sata-ports" => 6, "lan-ports" => 2, }, { "model" => "Supermicro H8DMT", "ids" => [ "0x10a715d9,0x10a78086,0x02", # Network "0x241115d9,0x037f10de,0xa3", # SATA ], "sockets" => 2, "socket-type" => "AMD-LGA1207 - Socket F", "dimms" => 8, "memory-type" => "DDR2-800 ECC Registered", "max-memory" => "64G", "sata-ports" => 4, "lan-ports" => 2, }, { "model" => "Dell DCS CS24-NV5", "ids" => [ "0xb0031028,0x037310de,0xa3", # Network "0xb0031028,0x037f10de,0xa3", # SATA ], "sockets" => 2, "socket-type" => "AMD-LGA1207 - Socket F", "dimms" => 16, }, { "model" => "Quanta S49", "ids" => [ "0x8954152d,0x109a8086,0x00", # Network "0x8954152d,0x10bd8086,0x02", # Network "0x8954152d,0x292[026]8086,0x02", # SATA ], "dimms" => 6, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "48G", "max-ranks" => 12, "sockets" => 2, }, # next two are identical { "model" => "Rackable S45", "model-match" => 'Rackable', "base-board" => "Quanta QSSC-295MB", "ids" => [ "0x8954152d,0x65c08086,0x90", # Chipset "0x00008086,0x10bd8086,0x02", # Network "0x8954152d,0x292[026]8086,0x02", # SATA ], "sockets" => 2, "dimms" => 6, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "48G", "max-ranks" => 12, }, { "model" => "Quanta S45", "base-board" => "Quanta QSSC-295MB", "ids" => [ "0x8954152d,0x65c08086,0x90", # Chipset "0x00008086,0x10bd8086,0x02", # Network "0x8954152d,0x292[026]8086,0x02", # SATA ], "sockets" => 2, "dimms" => 6, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "48G", "max-ranks" => 12, }, { # previously called Dell DCS S45 "model" => "Dell DCS CS24-SC SAS", # needs to be before FS12-SC "ids" => [ "0x8960152d,0x65c08086,0x90", # Chipset "0x........,0x(65f7|65fa)8086,0x90", # x8 port 2-3 | x16 port 4-7 (doesn't seem to be in FS12, but wouldn't count on it) "0x00008086,(0x10bd8086,0x02|0x108b8086,0x03)", # Network "0x894b152d,0x00561000,0x02", # SAS ], "dimms" => 6, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "48G", "max-ranks" => 12, "sockets" => 2, "bios-spec" => "cs24-sc", }, { # previously called Dell DCS S45 "model" => "Dell DCS CS24-SC", # needs to be before FS12-SC "ids" => [ "0x8960152d,0x65c08086,0x90", # Chipset "0x........,0x(65f7|65fa)8086,0x90", # x8 port 2-3 | x16 port 4-7 (doesn't seem to be in FS12, but wouldn't count on it) "0x00008086,(0x10bd8086,0x02|0x108b8086,0x03)", # Network ], "dimms" => 6, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "48G", "max-ranks" => 12, "sockets" => 2, "bios-spec" => "cs24-sc", }, { "model" => "Dell DCS FS12-SC", "ids" => [ "0x8960152d,0x65c08086,0x90", # Chipset "0x00008086,(0x10bd8086,0x02|0x108b8086,0x03)", # Network ], "dimms" => 6, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "48G", "max-ranks" => 12, "sockets" => 2, "bios-spec" => "cs24-sc", }, { "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)|Dell DCS F1D", "ids" => [ "0x894b152d,0x25d88086,0xb1", # Chipset "0x894b152d,0x00561000,0x02", # SAS "0x8949152d,0x10968086,0x01", # Network ], "sockets" => 2, }, { "model" => "Dell DCS S58R", "ugly-model" => "((Intel|Dell) BlackfordESB2)|Dell DCS F1D", "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, }, { "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 X8DTT", "ids" => [ "0x10d315d9,0x10d38086,0x00", # Network "0x000715d9,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, "socket-type" => "Intel-LGA1366", "dimms" => 12, "memory-type" => "DDR3", "memory-channels" => 6, "memory-per-socket" => 'P1,P2', "memory-population-order" => '1A,2A,3A,1B,2B,3B', }, { "model" => "Supermicro X8DT3", "ids" => [ "0x10c915d9,0x10c98086,0x01", # Network "0x(a880|0001)15d9,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, "socket-type" => "Intel-LGA1366", "dimms" => 12, "memory-type" => "DDR3", "memory-channels" => 6, "memory-per-socket" => 'NODE0,NODE1', "memory-population-order" => '1A,2A,3A,1B,2B,3B', }, { "model" => "Supermicro X8DTN", "ids" => [ "0x10c915d9,0x10c98086,0x01", # Network "0x10a715d9,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, "socket-type" => "Intel-LGA1366", "dimms" => 18, "memory-type" => "DDR3", }, { "model" => "Supermicro X8DTN-PRE", "ids" => [ "0x10a715d9,0x10a78086,0x02", # Network "0x2[89]2[02]8086,0x2[89]2[026]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[026]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)(8086|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,0x2[89]2[026]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,0x29168086,0x02", # Chipset "0xa48015d9,0x005[89]1000,0x08", # SAS "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,0x29168086,0x02", # Chipset "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,0x25d88086,0xb1 # looks like mistake, so ignore for now # these 8680 ones look like X7DVL-E, but with X7DBU chipset, strange "0x978[01]15d9,0x25d88086,0xb1", # chipset "0x(0000|1096)15d9,0x10968086,0x01", # Network ], "sockets" => 2, }, { "model" => "Supermicro X7DVL-L", "ugly-model" => '^Supermicro X7DVL$', "ids" => [ "0xb28015d9,0x25d48086,0xb1", # Chipset "0x(0000|1096)15d9,0x10968086,0x01", # Network "0xb28015d9,0x268[012]8086,0x09", # SATA IDE|AHCI|RAID ], "sockets" => 2, "dimms" => 4, "memory-type" => "DDR2-667 ECC Fully Buffered", "max-memory" => "16G", "sata-ports" => 4, "PCI-E x8" => 1, "PCI" => 1, }, { "model" => "Supermicro X7DVL-E", "ugly-model" => '^Supermicro X7DVL$', "ids" => [ "0x868015d9,0x25d48086,0x(93|b1)", # Chipset "0x(0000|1096)15d9,0x10968086,0x01", # Network "0x868015d9,0x268[012]8086,0x09", # SATA IDE|AHCI|RAID ], "sockets" => 2, "dimms" => 6, "memory-type" => "DDR2-667 ECC Fully Buffered", "max-memory" => "16G", "sata-ports" => 6, "PCI-E x8" => 1, "PCI-E x4" => 1, "PCI-X" => 2, "PCI" => 2, }, { "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,0x(27c0|27df)8086,0x01", # SATA | ATA "0x037c1014,0x163914e4,0x(01|20)", # Network ], "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 X2270", "ids" => [ "0x5352108e,0x10a78086,0x02", # Network "0x5352108e,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, }, { "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" => [ "0x011b1028,0x10088086,0x02", # Network ], "sockets" => 2, }, { "model" => "Dell PE2650", "ids" => [ "0x01211028,0x164514e4,0x15", # network ], "sockets" => 2, }, { "model" => "Dell PE2650", "ids" => [ "0x01211028,0x16a714e4,0x02", # network ], "sockets" => 2, }, { "model" => "Dell PE700", "ids" => [ "0x01671028,0x25a38086,0x02", # SATA ], "sockets" => 1, }, { "model" => "Dell PE750", "ids" => [ "0x01651028,0x25a38086,0x02", # SATA ], "sockets" => 1, }, { "model" => "Dell PE1750", "ids" => [ "0x014a1028,0x02121166,0x93", ], "sockets" => 2, }, { "model" => "Dell SC1435", "ids" => [ "0x01eb1028,0x024b1166,0x00", ], "sockets" => 2, }, { "model" => "Dell M610", "ids" => [ "0x02871028,0x163a14e4,0x20", # Network ], "sockets" => 2, "dimms" => 12, "specs" => "http://www.dell.com/content/products/productdetails.aspx/server-poweredge-m610?c=us&cs=555&l=en&s=biz", }, { "model" => "Dell R210", "ids" => [ "0x02a51028,0x163b14e4,0x20", # Network ], "sockets" => 1, "dimms" => 4, "memory-type" => "DDR3-1333 ECC Registered", "bios-spec" => "r210", "specs" => 'http://support.dell.com/support/edocs/systems/per210/en/HOM/HTML/index.htm', }, { "model" => "Dell R410", "ids" => [ "0x028c1028,0x163b14e4,0x20", # Network ], "sockets" => 2, "dimms" => 8, "memory-type" => "DDR3-1333 ECC Registered", "memory-channels" => 6, "memory-per-socket" => 'A,B', "memory-population-order" => '1,2,3,4', "broken-ahci" => { "bad-before" => "20101022", }, "bios-spec" => "r410", "specs" => 'http://support.dell.com/support/edocs/systems/per410/en/HOM/HTML/index.htm', }, { "model" => "Dell R510", "ids" => [ "0x02f11028,0x163b14e4,0x20", # Network ], "sockets" => 2, "dimms" => 8, "memory-type" => "DDR3-1333 ECC Registered", "memory-channels" => 6, "memory-per-socket" => 'A,B', "memory-population-order" => '1,2,3,4', "bios-spec" => "r410", "specs" => 'http://support.dell.com/support/edocs/systems/per510/en/HOM/HTML/index.htm', }, { "model" => "Dell R610", "ids" => [ "0x02361028,0x163914e4,0x20", # Network ], "sockets" => 2, "dimms" => 12, "memory-type" => "DDR3-1066 ECC Registered", "memory-channels" => 6, "memory-per-socket" => 'A,B', "memory-population-order" => '1,2,3,4,5,6', "bios-spec" => "r410", "specs" => 'http://support.dell.com/support/edocs/systems/per610/en/HOM/HTML/index.htm', }, { "model" => "Dell R710", "ids" => [ "0x02351028,0x163914e4,0x20", # Network ], "sockets" => 2, "dimms" => 18, "memory-type" => "DDR3-1066 ECC Registered", "memory-channels" => 6, "memory-per-socket" => 'A,B', "memory-population-order" => '1,2,3,4,5,6,7,8,9', "chassis" => '2U', "bios-spec" => "r410", "specs" => 'http://support.dell.com/support/edocs/systems/per710/en/HOM/HTML/index.htm', }, { "model" => "Dell R815", "ids" => [ "0x1f261028,0x163914e4,0x20", # Network ], "socket-type" => "AMD-LGA1974 - Socket G34", "sockets" => 4, "dimms" => 32, "memory-type" => "DDR3-1066 ECC Registered", "specs" => 'http://support.dell.com/support/edocs/systems/per815/en/HOM/HTML/index.htm', }, { "model" => "Dell R810", "ids" => [ "0x02d41028,0x163914e4,0x20", # Network ], "socket-type" => "Intel-LGA1567 - Socket LS", "sockets" => 4, "dimms" => 32, "memory-type" => "DDR3-1066 ECC Registered", "specs" => 'http://support.dell.com/support/edocs/systems/per810/en/HOM/HTML/index.htm', }, { "model" => "Dell R200", "ids" => [ "0x023c1028,0x165914e4,0x21", # network ], "sockets" => 1, "dimms" => 4, "memory-type" => "DDR2-800 ECC Unbuffered", "max-memory" => "8G", "broken-ahci" => 1, }, { "model" => "Dell R300", "ids" => [ "0x020f1028,0x165a14e4,0x00", # network ], "sockets" => 1, "dimms" => 6, "memory-type" => "DDR2-667 ECC Unbuffered", "max-memory" => "24G", "broken-ahci" => 1, }, { "model" => "Dell PE860", "ids" => [ "0x01e61028,0x27788086,0x00", ], "sockets" => 1, "bios-spec" => "pe860", }, { "model" => "Dell PE850", "ids" => [ "0x01b61028,0x27788086,0x00", ], "sockets" => 1, "bios-spec" => "pe850", }, { "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" => [ "(0x1f0c1028,0x00601000,0x04|0x1f101028,0x00581000,0x08)", # switch from SAS/PERC 5 to 6 "0x01b31028,0x164c14e4,0x12", ], "sockets" => 2, "bios-spec" => "pe1950", }, { "model" => "Dell PE1950 II", "ugly-model" => "Dell PowerEdge 1950", "ids" => [ "0x01b31028,0x164c14e4,0x12", # mirror what we do with PE2950, not verified ], "sockets" => 2, "bios-spec" => "pe1950", }, { "model" => "Dell PE1950", "ids" => [ "0x01b31028,0x164c14e4,0x11", ], "sockets" => 2, "bios-spec" => "pe1950", }, { "model" => "Dell PE2970", "ids" => [ "0x02051028,0x164c14e4,0x1.", "0x02051028,0x024[ab]1166,0x00", # ATA ], "sockets" => 2, }, { "model" => "Dell PE2950 III", "ugly-model" => "Dell PowerEdge 2950", "ids" => [ "0x1f0c1028,0x00601000,0x04", # RAID switch from PERC 5 to PERC 6 "0x01b21028,0x164c14e4,0x12", ], "sockets" => 2, "bios-spec" => "pe1950", }, { "model" => "Dell PE2950 II", "ugly-model" => "Dell PowerEdge 2950", "ids" => [ "0x01b21028,0x164c14e4,0x12", # is 0x12 really version II? ], "sockets" => 2, "bios-spec" => "pe1950", }, { "model" => "Dell PE2950", "ids" => [ "0x01b21028,0x164c14e4,0x11", ], "sockets" => 2, "bios-spec" => "pe1950", }, { "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 DL120 G7", "ids" => [ "0x1785103c,0x10d38086,0x00", # Network "0x330e103c,0x0533102b,0x00", # VGA ], "sockets" => 1, "socket-type" => "Intel-LGA1155 - Socket H2", "memory-slots" => 4, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 2, }, { "model" => "HP DL120 G6", "ids" => [ "0x(3118|3318)103c,0x3b148086,0x05", # Chipset "0x705d103c,0x165b14e4,0x10", # Network ], "sockets" => 1, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 6, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 2, "memory-min-speed" => "1066 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "16 GB RDIMM; 16 GB UDIMM", "memory-max-size-per-slot" => "4 GB RDIMM; 4 GB UDIMM", "memory-max-ranks" => 16, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-population-order" => '3,6,2,5,1,4', "bios-spec" => 'dl120g6', "specs" => 'http://h18004.www1.hp.com/products/quickspecs/13504_na/13504_na.html', }, { "model" => "HP DL120 G5", "ids" => [ "0x........,0x29f08086,0x..", # Chipset "0x31f4103c,0x292[026]8086,0x02", # SATA "0x7051103c,0x165a14e4,0x00", # Network ], "sockets" => 1, "dimms" => 4, }, { "model" => "HP DL160 G5p", "ids" => [ "0x........,0x40038086,0x..", # Chipset "0x7051103c,0x165a14e4,0x00", # Network ], "sockets" => 2, "dimms" => 16, "memory-type" => "DDR2-800 ECC Fully Buffered", "max-memory" => "128G", "PCI-E 2.0 x16" => 2, "model-match" => "G5p", "bios-spec" => "dl160g5", "specs" => 'http://h18000.www1.hp.com/products/quickspecs/13138_na/13138_na.HTML', }, { "model" => "HP DL160 G5", "ids" => [ "0x........,0x40038086,0x..", # Chipset "0x7051103c,0x165a14e4,0x00", # Network ], "sockets" => 2, "dimms" => 8, "memory-type" => "DDR2-800 ECC Fully Buffered", "max-memory" => "64G", "PCI-E 2.0 x16" => 2, "model-match" => "G5", "bios-spec" => "dl160g5", "specs" => 'http://h18000.www1.hp.com/products/quickspecs/12902_na/12902_na.HTML', }, { "model" => "HP DL160 G5/G5p", "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", "PCI-E 2.0 x16" => 2, "bios-spec" => "dl160g5", "specs" => 'http://h18000.www1.hp.com/products/quickspecs/12902_na/12902_na.HTML', }, { "model" => "HP SE1220", # very similar to DL160/180 G6, must come before "ids" => [ "0x330b103c,0x34068086,0x13", # Chipset "0x323f103c,0x10c98086,0x01", # Network "0x31fb103c,0x515e1002,0x02", # VGA ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 12, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "192 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "16 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 48, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => 'PROC 1,PROC 2', "memory-population-order" => '2$,4$,6$,1$,3$,5$', "chassis" => '2U', }, { "model" => "HP SE1120", # very similar to DL160 G6, must come before "ids" => [ "0x330b103c,0x34068086,0x13", # Chipset "0x330b103c,0x34118086,0x13", # PCI-E Root Port 10; missing from DL180 G6? "0x323f103c,0x10c98086,0x01", # Network "0x330d103c,0x3a2[026]8086,0x00", # SATA; diff from DL160 G6 ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 12, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "96 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 48, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, }, { "model" => "HP DL160 G6", # very similar to DL180 G6, must come before "ids" => [ "0x330b103c,0x34068086,0x13", # Chipset "0x(00000000|330b103c),0x34118086,0x13",# PCI-E Root Port 10; missing from DL180 G6? "0x(00000000|323f103c),0x10c98086,0x01",# Network ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 18, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "192 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "16 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 48, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => 'PROC 1,PROC 2', "memory-population-order" => '3A:0,6B:1,9C:2,2D:0,5E:1,8F:2,1G:0,4H:1,7I:2', "memory-imbalances" => '0,0,1;0,1,1;1,1,2;0,2,2;1,2,2;2,2,3;2,3,3', "lan-ports" => 2, "serial-ports" => 1, "PCI-E 2.0 x16" => 1, "PCI-E 2.0 x4/x8" => 1, # x4 support in x8 slot "bios-spec" => "dl160g6", "specs" => 'http://h18004.www1.hp.com/products/quickspecs/13247_na/13247_na.html', }, { # used to be called SL170h (pre-prod?) "model" => "HP SL170z G6", # very similar to DL180 G6, needs to come before that "ids" => [ "0x330b103c,0x34068086,0x13", # Chipset "0x323f103c,0x10c98086,0x01", # Network "0x3a2[02]8086,0x3a2[026]8086,0x00", # SATA ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 16, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "128 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 48, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => 'PROC 1,PROC 2', "memory-population-order" => '8A,5B,2C,7D,4E,1F,6G,3H', "memory-imbalances" => '0,0,1;0,1,1;1,1,2;0,2,2;1,2,2;2,2,3', "lan-ports" => 2, "serial-ports" => 1, "PCI-E 2.0 x16 LP" => 1, '3.5" drive bays NHP' => 6, "specs" => 'http://h18004.www1.hp.com/products/quickspecs/13332_na/13332_na.html', }, { "model" => "HP SE1170s", # very similar to DL180 G6, needs to come before that "ids" => [ "0x330b103c,0x34068086,0x13", # Chipset "0x323f103c,0x10c98086,0x01", # Network "0x31fa103c,0x0522102b,0x02", # VGA ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 16, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "192 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "16 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 48, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => 'PROC 1,PROC 2', "memory-population-order" => '8A:0,5B:1,2C:2,7D:0,4E:1,1F:2,6G:0,3H:1', "chassis" => '2U', }, { "model" => "HP DL180 G6", "ids" => [ "0x330b103c,0x34068086,0x13", # Chipset "0x(00000000|323f103c),0x10c98086,0x01",# Network ], "sockets" => 2, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 12, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 6, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "96 GB RDIMM; 24 GB UDIMM", "memory-max-size-per-slot" => "8 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 48, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => 'PROC 1,PROC 2', "memory-population-order" => '2A,4B,6C,1D,3E,5F', "memory-imbalances" => '0,0,1;0,1,1;1,1,2;0,2,2;1,2,2', "lan-ports" => 2, "serial-ports" => 1, "PCI-E x16" => 1, "PCI-E x8" => 2, "PCI-X" => 2, '3.5" drive bays HP' => 14, '2.5" drive bays HP' => 25, "bios-spec" => "dl160g6", "specs" => 'http://h18004.www1.hp.com/products/quickspecs/13248_na/13248_na.html', }, { "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, "bios-spec" => "dl180g5", }, { "model" => "HP SE1101", "ids" => [ "0x........,0x65c08086,0x80", # Chipset - San Clemente A0 "0x7051103c,0x165a14e4,0x00", # Network ], "sockets" => 2, "dimms" => 6, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "32G", "max-ranks" => 8, "bios-spec" => "se1101", }, { "model" => "HP SE1102", "ids" => [ "0x........,0x65c08086,0x90", # Chipset - San Clemente B0 "0x7051103c,0x165a14e4,0x00", # Network ], "sockets" => 2, "dimms" => 6, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "48G", "max-ranks" => 12, "bios-spec" => "se1102,se1101", }, { "model" => "HP BL260c G5", "ids" => [ "0x703c103c,0x167914e4,0xa3", # Network "0x31fe103c,0x292[026]8086,0x02", # SATA ], "sockets" => 2, "dimms" => 6, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "16G", }, { "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 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 DL380 G5", # needs to go before DL360 G5 "ids" => [ "0x31fd103c,0x25d88086,0x(93|b1|b5)", # 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 "(0x32010e11,0x26808086,0x09|0x31fe103c,0x269e8086,0x09)", # SATA | 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 G6", "ids" => [ "0x703e103c,0x167814e4,0xa3", # Network "0x330b103c,0x34038086,0x13", # Chipset "0x31fb103c,0x515e1002,0x02", # VGA ], "sockets" => 1, "socket-type" => "Intel-LGA1366 - Socket B", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 9, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 3, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "96 GB RDIMM; 12 GB UDIMM", "memory-max-size-per-slot" => "16 GB RDIMM; 2 GB UDIMM", "memory-max-ranks" => 24, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => 'PROC 1', "memory-population-order" => '3A,6B,9C,2D,5E,8F,1G,4H,7I', "memory-imbalances" => '0,0,1;0,1,1;1,1,2;0,2,2;1,2,2;2,2,3;2,3,3', "lan-ports" => 2, "serial-ports" => 1, "PCI-E x16" => 2, '3.5" drive bays HP' => 4, "specs" => 'http://h18004.www1.hp.com/products/quickspecs/13344_na/13344_na.html', }, { "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 ], "bios-spec" => "dl140g3", "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" => "64G", "max-ranks" => 8, "model-match" => 'DL185', }, { "model" => "HP DL165 G5", "ids" => [ "0x320b103c,0x02141166,0x00", # SATA "0x310f103c,0x164814e4,0x10", # Network ], "sockets" => 2, "dimms" => 8, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "64G", "max-ranks" => 8, "model-match" => 'DL165 G5', }, { "model" => "HP DL165 G6", "ids" => [ "0x320b103c,0x02141166,0x00", # SATA "0x310f103c,0x164814e4,0x10", # Network ], "sockets" => 2, "dimms" => 8, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "64G", "max-ranks" => 8, "model-match" => 'DL165 G6', "specs" => 'http://h18004.www1.hp.com/products/quickspecs/13367_na/13367_na.html', }, { "model" => "HP DL165/DL185 G5/G6", "ids" => [ "0x320b103c,0x02141166,0x00", # SATA "0x310f103c,0x164814e4,0x10", # Network ], "sockets" => 2, "dimms" => 8, "memory-type" => "DDR2-667 ECC Registered", "max-memory" => "64G", "max-ranks" => 8, }, { "model" => "HP DL165 G7", "ids" => [ "0x3322103c,0x5a121002,0x02", # Chipset "0x323f103c,0x10c98086,0x01", # Network ], "sockets" => 2, "socket-type" => "AMD-LGA1974 - Socket G34", "memory-type" => "DDR3 ECC RDIMM; DDR3 ECC UDIMM", "memory-slots" => 24, "memory-slot-type" => "DDR3 240-pin DIMM", "memory-channels" => 8, "memory-min-speed" => "800 Mhz", "memory-max-speed" => "1333 Mhz", "memory-max-size" => "256 GB RDIMM; 64 GB UDIMM", "memory-max-size-per-slot" => "16 GB RDIMM; 4 GB UDIMM", "memory-max-ranks" => 64, "memory-max-ranks-per-channel" => 8, "memory-max-ranks-per-slot" => 4, "memory-per-socket" => 'PROC 1,PROC 2', "memory-population-order" => '1$:0,7$:3,4$:2,10$:4,3$:0,9$:3,6$:2,12$:4,2$:0,8$:3,5$:2,11$:4', "chipset" => "NB=AMD SR5670, SB=AMD SP5100", "specs" => "http://h18004.www1.hp.com/products/quickspecs/13602_na/13602_na.html", }, { "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 "0x858[01]15d9,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" => "Dell DCS CS23-SH", # needs to be before S5400SF, same spec "model-match" => 'CS23-SH', "ids" => [ "0x34d[45]8086,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 S5400SF", "ids" => [ "0x34d[45]8086,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", "ugly-model" => "Intel MP", "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, }, { # 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 ], "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(%bios_dates) = ( 'dl160g6' => { 20091015 => 'dl160g6,dl160g6+1', 0 => 'dl160g6', }, ); my(%bios_versions) = ( 'cs24-sc' => { '^S45_3A[0-1]\d$' => 'cs24-sc-1', # S45_3A01, S45_3A07, S45_3A09, S45_3A10 '^S45_3A[2-9]\d$' => 'cs24-sc-2', # S45_3A20 }, 'xs23-ty3' => { '^1\.0[1-6]$' => 'xs23-ty3-1', # tested on 1.04, 1.08 '^1\.0[7-8]$' => 'xs23-ty3-2', # tested on 1.04, 1.08 '^1\.\d\d.\d\d$' => 'xs23-ty3-3', # tested on 1.37.99, 1.44.00 }, ); my(%bios_check_sum) = ( 'check_sum_1' => { 'default' => { 'start' => 0x10, 'end' => 0x2d, 'hi' => 0x2e, 'lo' => 0x2f, 'type' => 'sum', }, 'pe850' => 'default', 'pe860' => 'default', 'r210' => 'default', 'r410' => 'default', 'dl160g6' => 'default', 'dl160g5' => 'default', 'dl180g5' => 'default', 'pe1950' => 'default', 'se1101' => 'default', 'cs24-sc-1' => 'default', 'cs24-sc-2' => 'default', 'c2100' => 'default', 'cs24-ty-1' => 'default', 'cs24-ty-2' => 'default', 'xs23-ty3-1' => 'default', 'xs23-ty3-2' => 'default', 'xs23-ty3-3' => 'default', 'dl140g3' => 'default', }, 'check_sum_2' => { 'pe1950' => { 'start' => 0xc0, 'end' => 0xdd, 'hi' => 0xde, 'lo' => 0xdf, 'type' => 'sum', }, 'pe850' => 'pe1950', 'pe860' => 'pe1950', 'r210' => 'pe1950', 'r410' => 'pe1950', 'dl160g6' => { 'start' => 0x00, 'end' => 0x00,, 'hi' => 0x3e, 'lo' => 0x3f, 'type' => 'sum', }, 'se1101' => { 'start' => 0x00, 'end' => 0x00,, 'hi' => 0x3e, 'lo' => 0x3f, 'type' => 'sum', }, 'cs24-sc-1' => 'se1101', 'cs24-sc-2' => 'se1101', 'c2100' => 'se1101', 'cs24-ty-1' => 'se1101', 'cs24-ty-2' => 'se1101', 'xs23-ty3-1' => 'se1101', 'xs23-ty3-2' => 'se1101', 'xs23-ty3-3' => 'se1101', 'dl140g3' => { 'start' => 0x00, 'end' => 0x00,, 'hi' => 0x40, 'lo' => 0x47, 'type' => 'sum', }, }, 'check_sum_3' => { 'pe1950' => { 'start' => 0x5C, 'end' => 0x65, 'lo' => 0x66, 'type' => 'sum', # no hi byte, just low }, 'pe850' => 'pe1950', 'pe860' => 'pe1950', 'r210' => 'pe1950', 'r410' => 'pe1950', }, 'check_sum_4' => { 'pe1950' => { 'start' => 0x50, 'end' => 0x5B, 'hi' => 0x6D, 'lo' => 0x6E, 'type' => 'negative-sum', # 0x10000 - sum }, 'pe850' => 'pe1950', 'pe860' => 'pe1950', 'r210' => 'pe1950', 'r410' => 'pe1950', }, ); my(%bios_spec) = ( 'asset_tag' => { 'pe1950' => { 'address' => 0x5C, 'length' => 10, 'type' => 'string', 'values' => 'clean_white($val)', }, 'pe850' => 'pe1950', 'pe860' => 'pe1950', 'r210' => 'pe1950', 'r410' => 'pe1950', }, 'sas_controller' => { 'pe1950' => { 'address' => 0x11, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'sata_controller' => { 'pe850' => { 'address' => 0xCC, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'pe860' => 'pe850', 'pe1950' => { 'address' => 0xCB, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g5' => { 'address' => 0x5B, 'mask' => 0xC0, 'values' => { 0 => 'disabled', 1 => 'compatible', 2 => 'enhanced', }, }, 'dl180g5' => { 'address' => 0x9C, 'mask' => 0xC0, 'values' => { 0 => 'disabled', 1 => 'compatible', 2 => 'enhanced', }, }, 'xs23-ty3-3' => { 'address' => 0xB5, 'mask' => 0xC0, 'values' => { 0 => 'disabled', 1 => 'compatible', 2 => 'enhanced', }, }, 'cs24-ty-2' => { 'address' => 0xD0, 'mask' => 0xC0, 'values' => { 0 => 'disabled', 1 => 'compatible', 2 => 'enhanced', }, }, 'c2100' => 'cs24-ty-2', 'dl140g3' => { 'address' => 0xEF, 'mask' => 0x80, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-2' => { 'address' => 0xA3, 'mask' => 0x0C, 'values' => { 0 => 'disabled', 1 => 'compatible', 2 => 'enhanced', }, }, }, 'sata_mode' => { 'dl120g6' => { 'address' => 0xA5, 'mask' => 0x03, 'values' => { 0 => 'ide', 1 => 'ahci', 2 => 'raid', 3 => 'disabled', }, }, 'dl160g6' => { 'address' => 0x7E, 'mask' => 0x07, 'values' => { 0 => 'disabled', 1 => 'ide', 2 => 'raid', 3 => 'ahci', }, }, 'dl140g3' => { 'address' => 0xF0, 'mask' => 0x1C, 'values' => { 0 => 'ide-compatible', 2 => 'ide-enhanced', 6 => 'ahci', 7 => 'raid', }, }, 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xAD, 'mask' => 0x30, 'values' => { 0 => 'ide', 1 => 'raid', 2 => 'ahci', }, }, 'xs23-ty3-3' => { 'address' => 0xB6, 'mask' => 0x03, 'values' => { 0 => 'ide', 1 => 'raid', 2 => 'ahci', }, }, 'cs24-sc-1' => { 'address' => 0x99, 'mask' => 0x30, 'values' => { 0 => 'ide', 1 => 'raid', 2 => 'ahci', }, }, 'cs24-sc-2' => { 'address' => 0xA3, 'mask' => 0x30, 'values' => { 0 => 'ide', 1 => 'raid', 2 => 'ahci', }, }, 'cs24-ty-1' => { 'address' => 0xC5, 'mask' => 0x30, 'values' => { 0 => 'ide', 1 => 'raid', 2 => 'ahci', }, }, 'cs24-ty-2' => { 'address' => 0xD1, 'mask' => 0x03, 'values' => { 0 => 'ide', 1 => 'raid', 2 => 'ahci', }, }, 'c2100' => 'cs24-ty-2', 'dl160g5' => { 'address' => 0x78, 'mask' => 0xC0, 'values' => { 0 => 'ide', 1 => 'raid', 2 => 'ahci', }, }, 'dl180g5' => { 'address' => 0x9D, 'mask' => 0x03, 'values' => { 0 => 'ide', 1 => 'raid', 2 => 'ahci', }, }, 'r210' => { 'address' => 0xCB, 'mask' => 0x03, 'values' => { 0 => 'disabled', 1 => 'ide', 2 => 'ahci', 3 => 'raid', }, }, 'r410' => { 'address' => 0xCB, 'mask' => 0x03, 'values' => { 0 => 'disabled', 1 => 'ide', 2 => 'raid', }, }, }, 'mch_channel_mode' => { 'se1101' => { 'address' => 0x80, 'mask' => 0x03, 'values' => { 0 => 'sequential', 1 => 'interleaved', 2 => 'single', }, }, 'dl180g5' => { 'address' => 0x80, 'mask' => 0x03, 'values' => { 0 => 'sequential', 1 => 'interleaved', 2 => 'single', }, }, }, 'memory_mode' => { 'cs24-sc-1' => { 'address' => 0x80, 'mask' => 0x03, 'values' => { 0 => 'sequential', 1 => 'interleaved', 2 => 'mirrored', 3 => 'single', }, }, 'cs24-sc-2' => 'cs24-sc-1', 'dl140g3' => { 'address' => 0x90, 'mask' => 0x03, 'values' => { 0 => 'sequential', 1 => 'interleaved', 2 => 'mirrored', 3 => 'single', }, }, }, 'branch_0_sparing' => { 'dl140g3' => { 'address' => 0x90, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'branch_1_sparing' => { 'dl140g3' => { 'address' => 0x90, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'memory_interleaving' => { 'dl120g6' => { 'address' => 0x1B, 'mask' => 0xA0, 'values' => { 0 => 'channel', 1 => 'disabled', 4 => 'full', }, }, 'dl160g6+1' => { 'address' => 0xD4, 'mask' => 0x03, 'values' => { 0 => 'full', 1 => 'channel', 2 => 'disabled', 3 => 'disabled', # not documented in xml, but setup shows disabled, and see this in the wild }, }, 'r410' => { 'address' => 0xD0, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'channel_interleaving' => { 'xs23-ty3-3' => { 'address' => 0xD2, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'rank_interleaving' => { 'xs23-ty3-3' => { 'address' => 0xD2, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'node_interleaving' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0x81, 'mask' => 0x80, 'values' => { 0 => 'enabled', # numa off 1 => 'disabled', # numa on }, }, 'xs23-ty3-3' => { 'address' => 0x81, 'mask' => 0xC0, 'values' => { 0 => 'enabled', # numa off 1 => 'disabled', # numa on }, }, 'c2100' => 'cs24-ty-2', 'cs24-ty-2' => { 'address' => 0x81, 'mask' => 0xC0, 'values' => { 0 => 'enabled', # numa off 1 => 'disabled', # numa on }, }, 'cs24-ty-1' => { 'address' => 0x81, 'mask' => 0xC0, 'values' => { 0 => 'enabled', # non-numa os 1 => 'disabled' , # numa os 2 => 'disabled;slit=sles11', # numa for sles-11 - check the SLIT values }, }, 'dl160g6' => { 'address' => 0xD1, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'r410' => { 'address' => 0xD0, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'intel_c1e' => { 'dl120g6' => { 'address' => 0xA1, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g6' => { 'address' => 0x9D, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl140g3' => { 'address' => 0x24, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g5' => { 'address' => 0x9A, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'r410' => { 'address' => 0xC5, 'mask' => 0x04, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, }, 'intel_cstate_c3' => { 'cs24-ty-2' => { 'address' => 0xD5, 'mask' => 0xC0, 'values' => { 0 => 'disabled', 1 => 'acpi-c2', 2 => 'acpi-c3', }, }, 'c2100' => 'cs24-ty-2', }, 'intel_cstate_c6' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0x82, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'xs23-ty3-3' => { 'address' => 0xD3, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-2' => { 'address' => 0xEB, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', }, 'intel_cstate' => { 'xs23-ty3-3' => { 'address' => 0xD3, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', 'cs24-ty-2' => { 'address' => 0xEB, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-1' => { 'address' => 0xDE, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g6' => { 'address' => 0xA4, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'r210' => 'r410', 'r410' => { 'address' => 0xC7, 'mask' => 0x20, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, }, 'intel_cstate_limit' => { 'dl160g6' => { 'address' => 0x83, 'mask' => 0x07, 'values' => { 0 => 'auto', 1 => 'c1', 2 => 'c3', 3 => 'c6', 4 => 'c7', }, }, }, 'cpu_multiplier' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0x53, 'mask' => 0x3E, 'values' => '($val == 31) ? "max" : $val', }, 'xs23-ty3-3' => { 'address' => 0x52, 'mask' => 0x3E, 'values' => '($val == 31) ? "max" : $val', }, }, 'turbo_mode' => { 'xs23-ty3-3' => { 'address' => 0xD3, 'mask' => 0x08, 'values' => { 0 => 'traditional', 1 => 'power_optimized', }, }, }, 'intel_turbo' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xCB, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'xs23-ty3-3' => { 'address' => 0xD3, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-1' => { 'address' => 0xDE, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-2' => { 'address' => 0xEB, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', 'dl120g6' => { 'address' => 0xA1, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g6' => { 'address' => 0xA4, 'mask' => 0x10, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'r210' => 'r410', 'r410' => { 'address' => 0xC7, 'mask' => 0x02, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, }, 'serial_console_port' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xCD, 'mask' => 0x10, 'values' => { 0 => 'com1', 1 => 'com2', }, }, 'xs23-ty3-3' => { 'address' => 0xC0, 'mask' => 0x0C, 'values' => { 0 => 'com1', 1 => 'com2', }, }, 'cs24-sc-1' => { 'address' => 0xA6, 'mask' => 0xC0, 'values' => { 0 => 'com1', 1 => 'com2', }, }, 'cs24-sc-2' => 'cs24-sc-1', 'cs24-ty-1' => { 'address' => 0xCA, 'mask' => 0x30, 'values' => { 0 => 'com1', 1 => 'com2', }, }, 'cs24-ty-2' => { 'address' => 0xD7, 'mask' => 0x03, 'values' => { 0 => 'com1', 1 => 'com2', }, }, 'c2100' => 'cs24-ty-2', 'pe1950' => { 'address' => 0x54, 'mask' => 0x01, 'values' => { 0 => 'com1', 1 => 'com2', }, }, 'r410' => 'pe1950', 'r210' => 'pe1950', }, 'serial_console' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xCD, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'xs23-ty3-3' => { 'address' => 0xD5, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-1' => { 'address' => 0xA5, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-2' => 'cs24-sc-1', 'cs24-ty-1' => { 'address' => 0xDB, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-2' => { 'address' => 0xE7, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', 'dl140g3' => { 'address' => 0x5F, 'mask' => 0x80, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl180g5' => { 'address' => 0xAE, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl120g6' => { 'address' => 0x61, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g6' => { 'address' => 0xA5, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'pe850' => { 'address' => 0x53, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'pe860' => 'pe850', 'pe1950' => { 'address' => 0x54, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'r410' => 'pe1950', 'r210' => 'pe1950', }, 'serial_speed' => { 'pe850' => { 'address' => 0x53, 'mask' => 0x18, 'values' => { 0 => 115200, 1 => 57600, 2 => 19200, 3 => 9600, }, }, 'pe860' => 'pe850', 'pe1950' => { 'address' => 0x54, 'mask' => 0x30, 'values' => { 0 => 115200, 1 => 57600, 2 => 19200, 3 => 9600, }, }, 'r210' => 'pe1950', 'r410' => 'pe1950', 'dl160g5' => { 'address' => 0x8A, 'mask' => 0x07, 'values' => { 0 => 115200, 1 => 57600, 2 => 19200, 3 => 9600, }, }, 'dl140g3' => { 'address' => 0x60, 'mask' => 0x0E, 'values' => { 3 => 9600, 4 => 19200, 5 => 38400, 6 => 57600, 7 => 115200, }, }, 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xA7, 'mask' => 0x38, 'values' => { 0 => 115200, 1 => 57600, 2 => 38400, 3 => 19200, 4 => 9600, }, }, 'xs23-ty3-3' => { 'address' => 0xAA, 'mask' => 0x07, 'values' => { 0 => 115200, 1 => 57600, 2 => 38400, 3 => 19200, 4 => 9600, }, }, 'dl180g5' => { 'address' => 0x91, 'mask' => 0x07, 'values' => { 0 => 115200, 1 => 57600, 2 => 38400, 3 => 19200, 4 => 9600, }, }, 'cs24-sc-1' => { 'address' => 0xA5, 'mask' => 0x1C, 'values' => { 0 => 115200, 1 => 57600, 2 => 38400, 3 => 19200, 4 => 9600, }, }, 'cs24-sc-2' => 'cs24-sc-1', 'cs24-ty-1' => { 'address' => 0xBA, 'mask' => 0x07, 'values' => { 0 => 115200, 1 => 57600, 2 => 38400, 3 => 19200, 4 => 9600, }, }, 'cs24-ty-2' => { 'address' => 0xC7, 'mask' => 0x07, 'values' => { 0 => 115200, 1 => 57600, 2 => 38400, 3 => 19200, 4 => 9600, }, }, 'c2100' => 'cs24-ty-2', 'dl120g6' => { 'address' => 0x61, 'mask' => 0x70, 'values' => { 3 => 9600, 4 => 19200, 5 => 38400, 6 => 57600, 7 => 115200, }, }, 'dl160g6' => { 'address' => 0x83, 'mask' => 0x38, 'values' => { 0 => 115200, 1 => 57600, 3 => 19200, 4 => 9600, }, }, }, 'serial_term' => { 'pe850' => { 'address' => 0x53, 'mask' => 0x02, 'values' => { 0 => 'ansi', 1 => 'vt100', }, }, 'pe860' => 'pe850', 'r210' => 'r410', 'r410' => { 'address' => 0x54, 'mask' => 0x04, 'values' => { 0 => 'ansi', 1 => 'vt100', }, }, 'dl140g3' => { 'address' => 0x60, 'mask' => 0x70, 'values' => { 0 => 'vt100', 1 => 'vt100-8bit', 2 => 'ansi-7bit', 3 => 'ansi', 4 => 'vt100+', 5 => 'vt-utf8', 6 => 'ascii', }, }, 'dl160g5' => { 'address' => 0x96, 'mask' => 0xC0, 'values' => { 0 => 'ansi', 1 => 'vt100', 2 => 'vt-utf8', }, }, 'dl180g5' => { 'address' => 0x9F, 'mask' => 0x0C, 'values' => { 0 => 'ansi', 1 => 'vt100', 2 => 'vt-utf8', }, }, 'cs24-sc-1' => { 'address' => 0xA6, 'mask' => 0x0C, 'values' => { 0 => 'ansi', 1 => 'vt100', 2 => 'vt-utf8', }, }, 'cs24-sc-2' => 'cs24-sc-1', 'cs24-ty-1' => { 'address' => 0xC8, 'mask' => 0x30, 'values' => { 0 => 'ansi', 1 => 'vt100', 2 => 'vt-utf8', }, }, 'cs24-ty-2' => { 'address' => 0xD4, 'mask' => 0x03, 'values' => { 0 => 'ansi', 1 => 'vt100', 2 => 'vt-utf8', }, }, 'c2100' => 'cs24-ty-2', 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xB4, 'mask' => 0x03, 'values' => { 0 => 'ansi', 1 => 'vt100', 2 => 'vt-utf8', }, }, 'xs23-ty3-3' => { 'address' => 0xB9, 'mask' => 0x03, 'values' => { 0 => 'ansi', 1 => 'vt100', 2 => 'vt-utf8', }, }, 'dl160g6' => { 'address' => 0x90, 'mask' => 0x30, 'values' => { 0 => 'ansi', 1 => 'vt100', 2 => 'vt-utf8', }, }, }, 'intel_vt' => { 'cs24-ty-1' => { 'address' => 0xD6, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-2' => { 'address' => 0xE2, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xC3, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'xs23-ty3-3' => { 'address' => 0xC9, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl120g6' => { 'address' => 0x2A, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g6' => { 'address' => 0x9E, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl140g3' => { 'address' => 0x6F, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g5' => { 'address' => 0x9B, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-1' => { 'address' => 0xA8, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-2' => { 'address' => 0xB3, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'se1101' => { 'address' => 0xAA, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl180g5' => { 'address' => 0xAA, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'pe860' => { 'address' => 0xC3, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'pe1950' => { 'address' => 0xC6, 'mask' => 0x40, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'r410' => 'pe1950', 'r210' => 'pe1950', }, 'sr_iov' => { 'xs23-ty3-3' => { 'address' => 0xD0, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', 'cs24-ty-2' => { 'address' => 0xEA, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-1' => { 'address' => 0xDD, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'intel_vt_d_coherency' => { 'xs23-ty3-3' => { 'address' => 0xD4, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'intel_vt_d' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xCC, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'xs23-ty3-3' => { 'address' => 0xD4, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', 'cs24-ty-2' => { 'address' => 0xEC, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-1' => { 'address' => 0xDF, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl120g6' => { 'address' => 0xD0, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g6' => { 'address' => 0xA4, 'mask' => 0x80, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, }, 'active_cores' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0x52, 'mask' => 0x03, 'values' => { 0 => 'all', 1 => 1, 2 => 2, }, }, 'xs23-ty3-3' => { 'address' => 0x53, 'mask' => 0x07, 'values' => { 0 => 'all', 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, }, }, 'c2100' => 'cs24-ty-1', 'cs24-ty-2' => 'cs24-ty-1', 'cs24-ty-1' => { 'address' => 0x53, 'mask' => 0x03, 'values' => { 0 => 'all', 1 => 'one', 2 => 'half', }, }, 'dl120g6' => { 'address' => 0x13, 'mask' => 0x03, 'values' => { 0 => 'all', 1 => 'one', 2 => 'half', }, }, 'dl160g6' => { 'address' => 0x53, 'mask' => 0x03, 'values' => { 0 => 'all', 1 => 'one', 2 => 'half', }, }, 'dl180g5' => { 'address' => 0x52, 'mask' => 0x01, 'values' => { 0 => 'one', 1 => 'all', }, }, 'r210' => 'r410', 'r410' => { 'address' => 0xC7, 'mask' => 0x0C, 'values' => { 0 => 'all', 1 => 'one', 2 => 'half', }, }, 'pe1950' => { 'address' => 0xC7, 'mask' => 0x04, 'values' => { 0 => 'all', 1 => 'half', }, }, 'se1101' => { 'address' => 0x52, 'mask' => 0x01, 'values' => { 0 => 'half', 1 => 'all', }, }, 'cs24-sc-1' => { 'address' => 0x52, 'mask' => 0x01, 'values' => { 0 => 'half', 1 => 'all', }, }, }, 'intel_ioat2' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0x80, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'xs23-ty3-3' => { 'address' => 0x80, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'intel_ioat' => { 'pe1950' => { 'address' => 0xC0, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'r410' => 'pe1950', }, 'intel_ht' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0x52, 'mask' => 0x04, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'xs23-ty3-3' => { 'address' => 0x53, 'mask' => 0x08, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'c2100' => 'cs24-ty-1', 'cs24-ty-2' => 'cs24-ty-1', 'cs24-ty-1' => { 'address' => 0x53, 'mask' => 0x04, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'dl160g6' => { 'address' => 0x1D, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g6' => { 'address' => 0x53, 'mask' => 0x04, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'dl140g3' => { 'address' => 0x1B, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'r210' => 'r410', 'r410' => { 'address' => 0xC6, 'mask' => 0x01, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, }, 'sata_dwc' => { 'dl120g6' => { 'address' => 0x22, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g6' => { 'address' => 0xA9, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g5' => { 'address' => 0x9A, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl180g5' => { 'address' => 0x14, 'mask' => 0x04, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'se1101' => { 'address' => 0x14, 'mask' => 0x04, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, }, 'bmc_nic' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0x5F, 'mask' => 0x08, 'values' => { 0 => 'shared', 1 => 'dedicated', }, }, 'xs23-ty3-3' => { 'address' => 0x5F, 'mask' => 0x04, 'values' => { 0 => 'shared', 1 => 'dedicated', }, }, 'dl120g6' => { 'address' => 0xAD, 'mask' => 0x10, 'values' => { 0 => 'dedicated', 1 => 'shared', }, }, }, 'power_recovery_mode' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xB5, 'mask' => 0xC0, 'values' => { 0 => 'immediate', # this bit is also addr=0xCE,mask=0x04 1 => 'random', 2 => 'custom', }, }, 'xs23-ty3-3' => { 'address' => 0xD6, 'mask' => 0x60, 'values' => { 0 => 'immediate', 1 => 'random', 2 => 'custom', }, }, 'cs24-ty-2' => { 'address' => 0xD5, 'mask' => 0x0C, 'values' => { 0 => 'immediate', 1 => 'random', 2 => 'custom', }, }, }, 'power_recovery_delay' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xD3, 'mask' => 0xFF, 'values' => '$val', }, 'xs23-ty3-3' => { 'address' => 0xD8, 'mask' => 0xFF, 'values' => '$val', }, 'cs24-ty-2' => { 'address' => 0x56, 'mask' => 0xFF, 'values' => '$val', }, }, 'power_loss' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xAD, # also changes addr=0xB6,mask=0x03 'mask' => 0x03, 'values' => { 0 => 'off', 1 => 'on', 2 => 'last', }, }, 'xs23-ty3-3' => { 'address' => 0xB5, # also changes addr=0xC2,mask=0x03 'mask' => 0x30, 'values' => { 0 => 'off', 1 => 'on', 2 => 'last', }, }, 'cs24-ty-1' => { 'address' => 0xA6, 'mask' => 0x30, 'values' => { 0 => 'off', 1 => 'on', 2 => 'last', }, }, 'cs24-ty-2' => { 'address' => 0xA6, 'mask' => 0x30, 'values' => { 0 => 'off', 1 => 'on', 2 => 'last', }, }, 'c2100' => 'cs24-ty-2', 'dl160g6' => { 'address' => 0x8B, 'mask' => 0x30, 'values' => { 0 => 'off', 1 => 'on', 2 => 'last', }, }, 'cs24-sc-1' => { 'address' => 0xA6, 'mask' => 0x30, 'values' => { 0 => 'off', 1 => 'on', 2 => 'last', }, }, 'cs24-sc-2' => 'cs24-sc-1', 'se1101' => { 'address' => 0x9C, 'mask' => 0xC0, 'values' => { 0 => 'off', 1 => 'on', 2 => 'last', }, }, 'dl180g5' => { 'address' => 0x9C, 'mask' => 0x30, 'values' => { 0 => 'off', 1 => 'on', 2 => 'last', }, }, 'pe850' => { 'address' => 0xC8, 'mask' => 0x03, 'values' => { 0 => 'last', 1 => 'on', 2 => 'off', }, }, 'pe860' => 'pe850', 'pe1950' => { 'address' => 0xC5, 'mask' => 0x30, 'values' => { 0 => 'last', 1 => 'on', 2 => 'off', }, }, 'r410' => 'pe1950', }, 'power_management' => { 'xs23-ty3-1' => { 'address' => 0x78, # also changes addr=0x5F,mask=0x30 'mask' => 0x03, 'values' => { 0 => 'disabled', # max performance 1 => 'os-dbpm', 2 => 'sys-dbpm', # DAPC 3 => 'node-manager', # intel node manager }, }, 'xs23-ty3-2' => 'xs23-ty3-3', # normally tracks -1, this time it's -3 'xs23-ty3-3' => { 'address' => 0xDA, # also changes addr=0xC1,mask=0x30 'mask' => 0x03, 'values' => { 0 => 'disabled', # max performance 1 => 'os-dbpm', 2 => 'sys-dbpm', # DAPC 3 => 'node-manager', # intel node manager }, }, 'c2100' => { 'address' => 0x80, 'mask' => 0x30, 'values' => { 0 => 'disabled', # max performance 1 => 'os-dbpm', 2 => 'sys-dbpm', # DAPC 3 => 'node-manager', # intel node manager }, }, }, 'intel_speed_step' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xCB, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'xs23-ty3-3' => { 'address' => 0xD3, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => { 'address' => 0xD5, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-1' => { 'address' => 0xCA, 'mask' => 0x03, 'values' => { 0 => 'disabled', 1 => 'os-dbpm', 2 => 'sys-dbpm', # DAPC }, }, 'cs24-ty-2' => { 'address' => 0xD5, 'mask' => 0x30, 'values' => { 0 => 'disabled', 1 => 'os-dbpm', 2 => 'sys-dbpm', # DAPC }, }, 'dl120g6' => { 'address' => 0xA1, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g6' => { 'address' => 0xA4, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g5' => { 'address' => 0xA0, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl180g5' => { 'address' => 0xB2, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'pe1950' => { 'address' => 0xC7, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'pe850' => 'pe1950', 'pe860' => 'pe1950', 'r410' => { 'address' => 0xCF, 'mask' => 0x0C, 'values' => { 0 => 'max', 1 => 'min', 2 => 'os-dbpm', 3 => 'sys-dbpm', }, }, 'se1101' => { 'address' => 0xB4, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-1' => { 'address' => 0xB0, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-2' => { 'address' => 0xBB, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'fan_speed' => { 'dl160g5' => { 'address' => 0x90, 'mask' => 0xF0, 'values' => { 0 => 'standard', 1 => 'low', }, }, }, 'fan_power' => { 'r410' => { 'address' => 0xCF, 'mask' => 0x80, 'values' => { 0 => 'max', 1 => 'min', }, }, }, 'low_power_memory' => { 'cs24-sc-1' => { 'address' => 0x80, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-2' => 'cs24-sc-1', 'pe1950' => { 'address' => 0x26, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'hw_prefetcher' => { # http://lonesysadmin.net/2009/07/06/disabling-the-hardware-prefetcher-on-dell-r900s/ 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xC2, 'mask' => 0x80, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'xs23-ty3-3' => { 'address' => 0xC9, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-1' => { 'address' => 0xD5, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-2' => { 'address' => 0xE1, 'mask' => 0x80, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', 'dl120g6' => { 'address' => 0x13, 'mask' => 0x04, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'dl160g6' => { 'address' => 0x9D, 'mask' => 0x80, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g5' => { 'address' => 0x9A, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'se1101' => { 'address' => 0xA9, 'mask' => 0x80, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-1' => { 'address' => 0xA8, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-2' => { 'address' => 0xB2, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl180g5' => { 'address' => 0xA9, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'pe1950' => { 'address' => 0xC6, 'mask' => 0x08, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'pe860' => 'pe1950', 'r410' => 'pe1950', }, 'acl_prefetch' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xC3, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'xs23-ty3-3' => { 'address' => 0xC9, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-1' => { 'address' => 0xD5, 'mask' => 0x80, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-2' => { 'address' => 0xE2, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', 'dl120g6' => { 'address' => 0x13, 'mask' => 0x08, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'dl160g6' => { 'address' => 0x9E, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl140g3' => { 'address' => 0x11, 'mask' => 0x80, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'dl160g5' => { 'address' => 0x9A, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl180g5' => { 'address' => 0xA9, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-1' => { 'address' => 0xA8, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-2' => { 'address' => 0xB2, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'se1101' => { 'address' => 0xAA, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'pe1950' => { 'address' => 0xC6, 'mask' => 0x04, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'r410' => 'pe1950', 'pe860' => 'pe1950', }, 'dcu_prefetcher' => { # http://bizsupport1.austin.hp.com/bizsupport/TechSupport/Document.jsp?lang=en&cc=us&taskId=110&prodSeriesId=3884082&prodTypeId=15351&prodSeriesId=3884082&objectID=c02207408 'dl160g6' => { 'address' => 0xA9, 'mask' => 0x08, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, }, 'l1_data_prefetcher' => { 'cs24-ty-2' => { 'address' => 0xF8, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'data_reuse' => { 'cs24-ty-2' => { 'address' => 0xF8, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g6' => { 'address' => 0xA9, 'mask' => 0x10, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, }, 'demand_scrubbing' => { 'dl160g6' => { 'address' => 0x82, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'patrol_scrubbing' => { 'dl160g6' => { 'address' => 0x82, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'mem_turbo' => { 'c2100' => 'cs24-ty-1', 'cs24-ty-2' => 'cs24-ty-1', 'cs24-ty-1' => { 'address' => 0xF1, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'mem_frequency' => { 'c2100' => 'cs24-ty-1', 'cs24-ty-2' => 'cs24-ty-1', 'cs24-ty-1' => { 'address' => 0x80, 'mask' => 0xE0, 'values' => { 0 => 'auto', 1 => '800', 2 => '1066', 3 => '1333', }, }, 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0x80, 'mask' => 0xE0, 'values' => { 0 => 'auto', 1 => '800', 2 => '1066', 3 => '1333', }, }, 'xs23-ty3-3' => { 'address' => 0x80, 'mask' => 0xE0, 'values' => { 0 => 'auto', 1 => '800', 2 => '1066', 3 => '1333', }, }, 'dl120g6' => { 'address' => 0x1B, 'mask' => 0x06, 'values' => { 0 => 'max', 1 => '800', 2 => '1066', 3 => '1333', }, }, 'dl160g6' => { 'address' => 0x80, 'mask' => 0xE0, 'values' => { 0 => 'auto', 1 => '800', 2 => '1066', 3 => '1333', }, }, 'r410' => { 'address' => 0xCF, 'mask' => 0x70, 'values' => { 0 => 'max', 1 => '1333', 2 => '1066', 3 => '800', 4 => 'min', }, }, }, 'qpi_links_speed' => { 'cs24-ty-1' => { 'address' => 0x80, 'mask' => 0x01, 'values' => { 0 => 'slow', # forces qpi_frequency to 4.8 1 => 'full', }, }, 'cs24-ty-2' => { 'address' => 0x80, 'mask' => 0x01, 'values' => { 0 => 'slow', # forces qpi_frequency to 4.8 1 => 'full', }, }, 'dl160g6' => { 'address' => 0x80, 'mask' => 0x01, 'values' => { 0 => 'slow', 1 => 'full', }, }, }, 'qpi_frequency' => { 'c2100' => 'cs24-ty-2', 'cs24-ty-2' => { 'address' => 0x80, 'mask' => 0x0E, 'values' => { 0 => 'auto', 1 => '4.800GT', 2 => '5.866GT', 3 => '6.400GT', }, }, 'cs24-ty-1' => { 'address' => 0x80, 'mask' => 0x0E, 'values' => { 0 => 'auto', 1 => '4.800GT', 2 => '5.866GT', 3 => '6.400GT', }, }, 'dl160g6' => { 'address' => 0x80, 'mask' => 0x0E, 'values' => { 0 => 'auto', 1 => '4.800GT', 2 => '5.866GT', 3 => '6.400GT', }, }, }, 'qpi_optimization' => { 'cs24-ty-2' => { # called "QPI Bandwidth Priority" 'address' => 0xF9, 'mask' => 0x08, 'values' => { 0 => 'compute', 1 => 'io', }, }, 'dl160g6' => { 'address' => 0xC0, 'mask' => 0x60, 'values' => { 0 => 'balanced', 1 => 'memory', 2 => 'advanced', }, }, }, 'sas_sata_rate' => { 'dl160g6' => { 'address' => 0xC1, 'mask' => 0x60, 'values' => { 0 => 'auto', 1 => '3Gb', 2 => '1.5Gb', }, }, }, 'channel_0_rank_sparing' => { 'cs24-sc-1' => { 'address' => 0x84, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'channel_1_rank_sparing' => { 'cs24-sc-1' => { 'address' => 0x88, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'redundant_memory' => { 'pe1950' => { 'address' => 0xC9, 'mask' => 0x03, 'values' => { 0 => 'disabled', 1 => 'spare', 2 => 'mirrored', }, }, }, 'amp' => { # advanced memory protection 'r410' => { 'address' => 0xC9, 'mask' => 0x03, 'values' => { 0 => 'independent', 2 => 'mirrored', 3 => 'lockstep', }, }, 'c2100' => 'cs24-ty-1', 'cs24-ty-2' => 'cs24-ty-1', 'cs24-ty-1' => { 'address' => 0x81, 'mask' => 0x03, 'values' => { 0 => 'independent', 1 => 'mirrored', 2 => 'lockstep', }, }, 'dl160g6' => { 'address' => 0x81, 'mask' => 0x03, 'values' => { 0 => 'independent', 1 => 'mirrored', 2 => 'lockstep', }, }, }, 'mem_throttling_closed_loop' => { 'c2100' => 'cs24-ty-1', 'cs24-ty-2' => 'cs24-ty-1', 'cs24-ty-1' => { 'address' => 0x91, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'mem_throttling_open_loop' => { 'c2100' => 'cs24-ty-1', 'cs24-ty-2' => 'cs24-ty-1', 'cs24-ty-1' => { 'address' => 0x91, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'intel_me' => { # Manageability Engine 'c2100' => 'cs24-ty-2', 'cs24-ty-2' => { 'address' => 0xED, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-1' => { 'address' => 0xE0, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'aspm' => { # active state power management 'cs24-ty-1' => { 'address' => 0xE0, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-2' => { 'address' => 0xED, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', 'dl120g6' => { 'address' => 0x60, 'mask' => 0x60, 'values' => { 0 => 'disabled', 1 => 'l0', 2 => 'l1', 3 => 'both', }, }, 'dl160g6' => { 'address' => 0xA4, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'se1102' => { 'address' => 0xB4, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'pci_express' => { 'dl120g6' => { 'address' => 0x21, 'mask' => 0x80, 'values' => { 0 => 'gen_2', 1 => 'gen_1', }, }, 'dl160g6' => { 'address' => 0xA5, 'mask' => 0x08, 'values' => { 0 => 'gen_2', # PCIe 2.0 1 => 'gen_1', # PCIe 1.0 }, }, }, 'mps' => { 'cs24-ty-1' => { 'address' => 0xE0, 'mask' => 0x04, 'values' => { 0 => '1.1', 1 => '1.4', }, }, 'cs24-ty-2' => { 'address' => 0xED, 'mask' => 0x08, 'values' => { 0 => '1.1', 1 => '1.4', }, }, 'cs24-sc-1' => { 'address' => 0xB0, 'mask' => 0x20, 'values' => { 0 => '1.1', 1 => '1.4', }, }, 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xCC, 'mask' => 0x80, 'values' => { 0 => '1.1', 1 => '1.4', }, }, 'xs23-ty3-3' => { 'address' => 0xD4, 'mask' => 0x80, 'values' => { 0 => '1.1', 1 => '1.4', }, }, }, 'nx_bit' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xC3, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'xs23-ty3-3' => { 'address' => 0xC9, 'mask' => 0x80, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', 'cs24-ty-2' => { 'address' => 0xE2, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-1' => { 'address' => 0xD6, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g6' => { 'address' => 0x9E, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl140g3' => { 'address' => 0x11, 'mask' => 0x01, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'r210' => 'r410', 'r410' => { 'address' => 0xC7, 'mask' => 0x10, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'pe1950' => { 'address' => 0xC7, 'mask' => 0x02, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'cs24-sc-1' => { 'address' => 0xA8, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-2' => { 'address' => 0xB3, 'mask' => 0x04, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'snoop_filter' => { 'pe1950' => { 'address' => 0xC0, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl140g3' => { 'address' => 0xF1, 'mask' => 0x40, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, }, 'power_efficiency' => { 'se1102' => { 'address' => 0xB9, 'mask' => 0x03, 'values' => { 0 => 'efficiency', 1 => 'performance', 2 => 'custom', }, }, 'dl160g6' => { 'address' => 0x8A, 'mask' => 0x0C, 'values' => { 0 => 'efficiency', 1 => 'performance', 2 => 'custom', }, }, 'dl120g6' => { 'address' => 0xAE, 'mask' => 0x60, 'values' => { 0 => 'efficiency', 1 => 'performance', 2 => 'custom', }, }, }, 'summary_screen' => { 'dl140g3' => { 'address' => 0x59, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'quiet_boot' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xC1, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'xs23-ty3-3' => { 'address' => 0xC7, 'mask' => 0x40, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-1' => { 'address' => 0xD4, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-2' => { 'address' => 0xE0, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', 'cs24-sc-1' => { 'address' => 0xA3, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-2' => { 'address' => 0xB1, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g6' => { 'address' => 0x9C, 'mask' => 0x10, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'quick_boot' => { 'xs23-ty3-2' => 'xs23-ty3-1', 'xs23-ty3-1' => { 'address' => 0xC1, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'xs23-ty3-3' => { 'address' => 0xC7, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-1' => { 'address' => 0xD3, 'mask' => 0x80, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-ty-2' => { 'address' => 0xE0, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'c2100' => 'cs24-ty-2', 'dl160g6' => { 'address' => 0x87, 'mask' => 0x0C, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl160g5' => { 'address' => 0xA6, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl180g5' => { 'address' => 0xA7, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-1' => { 'address' => 0xA3, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-2' => { 'address' => 0xB0, 'mask' => 0x80, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'se1101' => { 'address' => 0xA8, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'dl140g3' => { 'address' => 0x25, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'nmi_button' => { 'pe860' => { 'address' => 0xC0, 'mask' => 0x02, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'r410' => { 'address' => 0xC3, 'mask' => 0x02, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'pe1950' => { 'address' => 0x11, 'mask' => 0x04, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, }, 'memory_test' => { 'pe1950' => { 'address' => 0x11, 'mask' => 0x04, 'values' => { 0 => 'enabled', 1 => 'disabled', }, }, 'r210' => 'pe1950', 'r410' => 'pe1950', 'pe850' => 'pe1950', 'pe860' => 'pe1950', 'dl120g6' => { 'address' => 0x2B, 'mask' => 0x0C, 'values' => { 0 => 'normal', 2 => 'none', }, }, 'dl140g3' => { 'address' => 0x25, 'mask' => 0xC0, 'values' => { 0 => 'normal', 1 => 'zero', 2 => 'none', }, }, }, 'event_logging' => { 'cs24-ty-2' => { 'address' => 0xEF, 'mask' => 0x01, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-1' => { 'address' => 0xB1, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'ecc_event_logging' => { 'cs24-ty-2' => { 'address' => 0xE9, 'mask' => 0x20, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, 'cs24-sc-1' => { 'address' => 0xAF, 'mask' => 0x08, 'values' => { 0 => 'disabled', 1 => 'enabled', }, }, }, 'serr_condition' => { 'dl140g3' => { 'address' => 0xD9, 'mask' => 0x60, 'values' => { 0 => 'none', 1 => 'single', 2 => 'multi', 3 => 'both', }, }, }, ); my(%linux_driver_map) = ( "lsi" => "mpt", "3w" => "twe", ); my %redhat_release = ( # http://kbase.redhat.com/faq/docs/DOC-3079 "2.6.32-71" => "RHEL Server 6", # ?? "2.6.18-238" => "RHEL Server 5.6", # ?? "2.6.18-194" => "RHEL Server 5.5", "2.6.18-164" => "RHEL Server 5.4", "2.6.18-128" => "RHEL Server 5.3", "2.6.18-92" => "RHEL Server 5.2", "2.6.18-53" => "RHEL Server 5.1", "2.6.18-8" => "RHEL Server 5", "2.6.9-89" => "RHEL AS 4 U8", "2.6.9-78" => "RHEL AS 4 U7", "2.6.9-67" => "RHEL AS 4 U6", "2.6.9-55" => "RHEL AS 4 U5", "2.6.9-42" => "RHEL AS 4 U4", "2.6.9-34" => "RHEL AS 4 U3", "2.6.9-22" => "RHEL AS 4 U2", "2.6.9-11" => "RHEL AS 4 U1", "2.6.9-5" => "RHEL AS 4", "2.4.21-50" => "RHEL AS 3 U9", "2.4.21-47" => "RHEL AS 3 U8", "2.4.21-40" => "RHEL AS 3 U7", "2.4.21-37" => "RHEL AS 3 U6", "2.4.21-32" => "RHEL AS 3 U5", "2.4.21-27" => "RHEL AS 3 U4", "2.4.21-20" => "RHEL AS 3 U3", "2.4.21-15" => "RHEL AS 3 U2", "2.4.21-9" => "RHEL AS 3 U1", "2.4.21-4" => "RHEL AS 3", ); sub sig_warn { my($err) = @_; my($hush) = 0; $hush++ if ($err =~ s/^hush:\s+// || $err =~ /^Use of uninitialized/); $err = "$zero: perl-warn: $err"; my($stack) = Carp::longmess($err); $perl_warn .= $stack; if ($opts{'d'}) { $stderr_buf .= $stack; } elsif (!$hush) { $stderr_buf .= $err; } } sub sig_die { my($err) = @_; $err = "$zero: perl-die: $err"; my($stack) = Carp::longmess($err); $perl_warn .= $stack; if ($opts{'d'}) { $stderr_buf .= $stack; die $stack; } else { $stderr_buf .= $err; die $err; } } $SIG{'__WARN__'} = 'sig_warn'; $SIG{'__DIE__'} = 'sig_die'; $xml_top->{execution}->{begin} = time; sub watchdog { # in case we're in an eval, reset the alarm alarm($timeout); die("watchdog expired; something is taking too long (> ${timeout}s)"); } sub usage { print "usage: $zero [-cCdhnv] [-t timeout] [-e file] [-r file] [-x file] [-o file]\n"; print "\t-b boot mode: run in background\n"; print "\t-c force use of ansi colors\n"; print "\t-C don't use ansi colors\n"; print "\t-d show debugging information\n"; print "\t-e write errors to file (- for stderr)\n"; print "\t-h show usage\n"; print "\t-n don't break output lines\n"; print "\t-N don't write files to /var/run\n"; print "\t-o write output to file (- for stdout)\n"; print "\t-r write raw source to file (- for stdout)\n"; print "\t-t abort after timeout seconds (default $timeout)\n"; print "\t-v verbose output\n"; print "\t-V show version\n"; print "\t-x write xml to file (- for stdout)\n"; print "version: $version, XML: $xml_version\n"; } sub internal_warn { my($str) = @_; warn('hush: ' . $str); } sub user_warn { my($level, $tmr_sysinfo_err, $str, $ref) = @_; $stderr_buf .= $zero .': ' . (($level < 100) ? 'warning' : 'error') . ': '; $stderr_buf .= $str; $stderr_buf .= "; see $tmr_sysinfo_err{$tmr_sysinfo_err}{tiny}" if $tmr_sysinfo_err; $stderr_buf .= "\n"; if ($ref) { if (ref($ref) eq 'HASH') { push(@{$ref->{warning}}, $xml_handle); } elsif ($handle_to_xml{$ref}) { push(@{$handle_to_xml{$ref}->{warning}}, $xml_handle); } } $xml = {}; $xml->{severity} = $level; $xml->{message} = $str; if ($tmr_sysinfo_err) { $xml->{code} = $tmr_sysinfo_err; $xml->{type} = $tmr_sysinfo_err{$tmr_sysinfo_err}{type}; $xml->{url} = $tmr_sysinfo_err{$tmr_sysinfo_err}{url}; $xml->{tiny} = $tmr_sysinfo_err{$tmr_sysinfo_err}{tiny}; } $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{execution}->{warning}}, $xml); $xml->{handle} = $xml_handle++; } sub trace { my($cmd) = @_; if ($opts{'trace'}) { print $cmd, "\n"; } } sub daemonize { chdir('/') || warn("chdir: $!"); open(STDIN, '< /dev/null') || warn("open: stdin: $!"); open(STDOUT, '> /dev/null') || warn("open: stdout: $!"); my($pid) = fork(); if (defined $pid) { exit if $pid; setsid() || warn("setsid: $!"); open(STDERR, '>&STDOUT') || warn("dup: stdout: $!"); } else { warn("fork: $!"); } } sub round { my($number) = @_; return int($number + 0.5); } sub bighex { # hex() only works cleanly on 32-bit numbers; will either fail on 32-bit systems or warn about non-portable. # this adds support for > 32 bit numbers. # note that perl usually supports only 53-bit ints, so beyond that, you'll lose precision my($str) = @_; my($result) = 0; my($exp) = 0; $str =~ s/^0x//; while ($str) { $result += hex(substr($str, -8)) * (2**$exp); $str = substr($str, 0, -8); $exp += 32; } return $result; } sub cmp_drives { my($aa, $bb) = ($a, $b); my($a_hid) = $props{drives}{$aa}{hidden} || 0; my($b_hid) = $props{drives}{$bb}{hidden} || 0; return ($a_hid <=> $b_hid) || cmp_disks($props{drives}{$aa}{volume}, $props{drives}{$bb}{volume}); } sub cmp_disks { my($adisk, $bdisk) = @_; # put undefs at the end $adisk = 'zzz' unless (defined $adisk); $bdisk = 'zzz' unless (defined $bdisk); # e.g. pass0, amr2-spares, mfid5, hda, sda, mpt0-b0-t1, ciss-s5-B-l2, cciss/c0d0, tw-c0-free, megaraid0-vol1 # make ints work with cmp by expanding them $adisk =~ s/(\d+)/sprintf("%05d", $1)/eg; $bdisk =~ s/(\d+)/sprintf("%05d", $1)/eg; # force pass devices to be last, usually ignored anyway $adisk =~ s/^pass/zzpass/; $bdisk =~ s/^pass/zzpass/; if ($os_type eq "linux" && $adisk =~ /^sd/ && $bdisk =~ /^sd/) { return (length($adisk) cmp length($bdisk) || $adisk cmp $bdisk); } else { return ($adisk cmp $bdisk); } } 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 cmp_cpus { my($aa, $bb) = ($a, $b); if (defined $cpus{cpus}{$aa}{apic_id} && defined $cpus{cpus}{$bb}{apic_id}) { return ($cpus{cpus}{$aa}{apic_id} <=> $cpus{cpus}{$bb}{apic_id}); } else { return ($aa cmp $bb); } } sub cmp_caches { my($aa, $bb) = ($a, $b); if ($aa =~ /^(.*_.*)_(\d+)/) { my($pri_a, $sec_a) = ($1, $2); if ($bb =~ /^(.*_.*)_(\d+)/) { my($pri_b, $sec_b) = ($1, $2); return ($pri_a cmp $pri_b || $sec_a <=> $sec_b); } } return ($aa cmp $bb); } sub parse_enable { my($string, $more_yes, $more_no) = @_; my($yes) = '1|yes|on|ok|true|enabled|enabled \(write-back\)'; my($no) = '0|no|off|false|disabled|temporarily disabled|permanently disabled|not supported|not\s*configured|disabled \(write-through\)'; my($unknown) = 'unknown'; $yes .= "|$more_yes" if $more_yes; $no .= "|$more_no" if $more_no; { # hpacucli $string =~ s/^ATTR_VALUE_CACHE_STATUS_//; $string =~ s/_/ /g; } if ($string =~ /^($yes)$/i) { return 1; } elsif ($string =~ /^($unknown)$/i) { return -1; } elsif ($string =~ /^($no)$/i || $string eq '') { return 0; } else { internal_warn("unknown enable value `$string'"); return; } } sub parse_value { my($string) = @_; if ($string =~ /^(\d+)/) { return $1; } return $string; } sub parse_patrol_mode { my($string) = @_; my($result) = ''; if ($string =~ /auto/i) { $result = 'auto'; } elsif ($string =~ /manual/i) { $result = 'manual'; } elsif ($string =~ /disable/i) { $result = 'off'; } else { internal_warn("unknown patrol mode `$string'"); } return $result; } sub parse_seconds { my($string) = @_; my($result) = ''; if ($string =~ /^\s*(\d+)\s*hours?\s*$/) { $result = $1 * 3600; } elsif ($string =~ /^\s*(\d+)\s*minutes?\s*$/) { $result = $1 * 60; } elsif ($string =~ /^\s*(\d+)\s*seconds?\s*$/) { $result = $1; } elsif ($string =~ /^\s*(\d+)\s*$/) { $result = $1; } elsif ($string eq 'Continuous') { $result = 0; } else { internal_warn("unknown time value `$string'"); } return $result; } sub parse_date { my($string) = @_; my($result) = ''; if ($string =~ m{^(\d+)/(\d+)/(\d+)$}) { $result = sprintf("%04d%02d%02d", $3, $1, $2); } else { internal_warn("unknown date value `$string'"); } return $result; } sub parse_bytes { my($string, $factor) = @_; my($result); my(%exp) = ( "B" => 0, "K" => 1, "KB" => 1, "M" => 2, "MB" => 2, "G" => 3, "GB" => 3, "T" => 4, "TB" => 4, "P" => 5, "PB" => 5, "E" => 6, "EB" => 6, ); $string =~ s/bytes/B/ig; if ($string =~ /^\s*([\d\.]+)\s*(B|K|KB|M|MB|G|GB|T|TB|P|PB|E|EB)\s*$/i) { $result = int($1 * (($factor || 1000) ** $exp{uc($2)})); } return $result; } sub parse_rpm { # a few common meaningless values we see: 20000 (mpt logical vols), 28897 (umass) # for these, just best to return null my($string) = @_; my($result) = ""; my(@rpms) = (4500, 5400, 7200, 10000, 15000); my($low) = 0; if ($string =~ /non-rotating/) { return 0; } my($rpm) = int($string); return 0 unless ($rpm); foreach my $high (@rpms) { # allow for 10% slopage in reported number if ($rpm <= ($high * 1.1)) { $result = $high; last; } } return $result; } sub print_rpm { my($string) = @_; my($result) = 0; my($rpm) = parse_rpm($string); if ($rpm) { if ($rpm < 10000) { $result = sprintf("%3.1fK", $rpm / 1000); } else { $result = sprintf("%2dK", $rpm / 1000); } } return $result; } sub parse_network_speed { my($string) = @_; my($result); if ($string eq '10baseT/UTP') { $result = '10Mb/s'; } elsif ($string eq '100baseTX') { $result = '100Mb/s'; } elsif ($string eq '1000Mb/s' || $string eq '1000baseTX') { $result = '1Gb/s'; } elsif ($string eq '10000Mb/s' || $string eq '10000baseTX') { $result = '10Gb/s'; } else { $result = $string; } return $result; } sub parse_ps_status { my($string) = @_; if ($string =~ /not present/i) { return 'missing'; } elsif ($string =~ /present/i) { return 'present'; } else { internal_warn("unknown PS status `$string'"); return 'failed'; } } sub parse_bbu_status { my($string) = @_; if ($string =~ /^(Present|Ok|Non-Critical|Optimal)$/i) { return 'ok'; } elsif ($string =~ /^(Recharging)/i) { return 'recharging'; } elsif ($string =~ /^(Missing|Absent|Not Installed|Not Present(\/Discharged)?)$/i) { return 'missing'; } elsif ($string =~ /^(Failed( \(Replace Batteries\))?|Critical|dead)$/i) { return 'failed'; } else { internal_warn("unknown BBU status `$string'"); return 'failed'; } } sub parse_read_ahead_policy { my($string) = @_; my($result); if ($string =~ /^(adaptive|ReadAdaptive)$/i) { $result = "adaptive"; } elsif ($string =~ /^(always|ReadAhead)$/i) { $result = "always"; } elsif ($string =~ /^(No|none|ReadAheadNone)$/i) { $result = "none"; } else { $result = $string; internal_warn("unknown cache policy `$string'"); } return $result; } sub parse_drive_form { my($string) = @_; my($result); if ($string =~ /3.5 inch/i) { $result = "3.5 inch"; } elsif ($string =~ /2.5 inch/i) { $result = "2.5 inch"; } elsif ($string =~ /1.8 inch/i) { $result = "1.8 inch"; } else { $result = $string; internal_warn("unknown drive form `$string'"); } return $result; } sub parse_drive_cache { my($string) = @_; my($result); if ($string =~ /^(enabled)$/i) { $result = "enabled"; } elsif ($string =~ /^(disabled)$/i) { $result = "disabled"; } elsif ($string =~ /^(default|Disk's Default)$/i) { $result = "default"; } else { $result = $string; internal_warn("unknown cache policy `$string'"); } return $result; } sub parse_cache_policy { my($string) = @_; my($result); if ($string =~ /(write-back|WriteBack)/i) { $result = "write-back"; } elsif ($string =~ /(write-through|WriteThrough|WriteThru)/i) { $result = "write-through"; } elsif ($string =~ /^(none|not supported)$/i) { $result = "none"; } else { $result = $string; internal_warn("unknown cache policy `$string'"); } return $result; } sub parse_volume_status { my($string) = @_; my($result); # probably need three fields, e.g. status=enabled|online|offline, state=optimal|degraded, operation=resync if ($string =~ /^(OK|Optimal|Ready|READY RECOVERY|optimal, enabled|Okay|OKY|clean|active|dirty)$/i) { $result = "ok"; } elsif ($string =~ /^(REBUILD-PAUSED|INTERM RECOVERY|Interim Recovery Mode|Degraded|Partially Degraded|Ready for Rebuild|degraded, enabled|DGD|clean, degraded|active, degraded)$/i) { $result = "degraded"; } elsif ($string =~ /^(RECOVERING|Recovering.*complete|degraded, enabled, resync in progress|Synchronize|active, resyncing|clean, resyncing)$/i) { $result = "rebuilding"; } elsif ($string =~ /^(EXPANDING)$/i) { $result = "expanding"; } elsif ($string =~ /^(Transforming.*complete)$/i) { $result = "transforming"; # e.g. hpacucli when you add new drives to exisiting logical } elsif ($string =~ /^(verifying)$/i) { $result = "verifying"; } elsif ($string =~ /^(Background Initialization|Initializing|INIT)$/i) { $result = "initializing"; } elsif ($string =~ /^(Offline|Failed|BROKEN|failed, enabled|FLD|INOPERABLE)$/i) { $result = "failed"; } elsif ($string =~ /^(Missing|MIS)$/i) { $result = "missing"; } elsif ($string =~ /^(Online|ONL)$/i) { $result = "online"; } else { $result = $string; internal_warn("unknown volume status `$string'"); } return $result; } sub parse_drive_status { my($string) = @_; my($result); # # this needs work. failed spare? failed free drive? # prob need type and status # role = active, spare, free # status = ok, failed, missing, rebuilding, failing # if ($string =~ /^(OK|Ready|RDY)/i) { # generic ok status, ideally would know more detail: online, spare, free $result = "ok"; } elsif ($string =~ /^(Online|Optimal|ONL|OPT|Online, Spun Up)/i) { # online and active part of volume, i.e. not spare, free $result = "online"; } elsif ($string =~ /^(missing|removed|MIS)/i) { # no drive detected $result = "missing"; } elsif ($string =~ /^(Offline)/i) { # not sure?? $result = "offline"; } elsif ($string =~ /^(Failed|NOT COMPATIBLE|DEGRADED|Unconfigured\(bad\)|DEVICE-ERROR|FLD|DGD)/i) { # drive is present with errors $result = "failed"; } elsif ($string =~ /^(Predictive Failure|SMART-FAILURE)/i) { # drive is online and active, but marked as failing $result = "failing"; } elsif ($string =~ /^(verifying)/i) { # drive is present, being verified # not sure this makes much sense for a drive, happens with tw_cli $result = "verifying"; } elsif ($string =~ /^(Rebuild|RBLD)/i) { # drive is present, part of degraded volume and rebuilding $result = "rebuilding"; } elsif ($string =~ /^(out of sync|OSY)/i) { # drive is ok and part of logical, but out of sync with rest of logical $result = "stale"; } elsif ($string =~ /^(spare|Hotspare|Hot Spare|HSP)/i) { # drive is ok, marked as spare $result = "spare"; } elsif ($string =~ /^(free|Unconfigured\(good\)|Unconfigured\(good\), Spun Up)/i) { # drive is ok, but currently not marked as any function, i.e. not spare, online $result = "free"; } elsif ($string =~ /^(not supported)/i) { # hpacucli will return this at times, not consistent so looks a timeout $result = "unknown"; } elsif ($string =~ /^(Unsupported)/i) { # omreport has shown this for what megacli says is a failed drive $result = "unknown"; } else { $result = $string; internal_warn("unknown drive status `$string'"); } return $result; } sub parse_drive_interface { my($string) = @_; my($result) = $string; if ($string =~ /\bSAS\b/) { $result = "SAS"; } elsif ($string =~ /\bSATA\b/) { $result = "SATA"; } elsif ($string =~ /\bATA\b/) { $result = "ATA"; } elsif ($string =~ /\b(SCSI|U320|U160|Ultra2|Ultra)\b/) { $result = "SCSI"; } elsif ($string =~ /unknown/i) { $result = "unknown"; } elsif ($string) { internal_warn("unknown drive interface `$string'"); } return $result; } sub parse_drive_speed { my($string) = @_; my($result) = ""; if (!defined $string) { $result = 0; } elsif ($string =~ /U320|Ultra320|\b320\b.*MB\/s/i) { $result = 320 * 1024 * 1024; } elsif ($string =~ /U160|Ultra160|\b160\b.*MB\/s/i) { $result = 160 * 1024 * 1024; } elsif ($string =~ /\b80\b.*MB\/s/i) { $result = 80 * 1024 * 1024; } elsif ($string =~ /\b40\b.*MB\/s/i) { $result = 40 * 1024 * 1024; } elsif ($string =~ /\b20\b.*MB\/s/i) { $result = 20 * 1024 * 1024; } elsif ($string =~ /\b10\b.*MB\/s/i) { $result = 10 * 1024 * 1024; # hpacucli reports this for failed drives } elsif ($string =~ /(SATA 1\.5 Gb\/s|1\.5GBPS|1\.5Gb\/s)/i) { $result = 150 * 1024 * 1024; } elsif ($string =~ /((SATA|SAS) 3\.0 Gb\/s|3\.0GBPS|3\.0Gb\/s)/i) { $result = 300 * 1024 * 1024; } elsif ($string =~ /((SATA|SAS) 6\.0 Gb\/s|6\.0GBPS|6\.0Gb\/s)/i) { $result = 600 * 1024 * 1024; } elsif ($string =~ /SATA(\d+)/i) { $result = $1 * 1024 * 1024; } elsif ($string =~ /UDMA(\d\d+)/i) { $result = $1 * 1024 * 1024; } elsif ($string eq 'WDMA2') { $result = 16 * 1024 * 1024; } elsif ($string =~ /\b([1-9]\d*)\b.*MB\/s/i) { $result = $1 * 1024 * 1024; } elsif ($string =~ /^(Unknown)/) { $result = 0; } elsif ($string =~ /(Failed)/) { $result = 0; } elsif ($string) { internal_warn("unknown drive speed `$string'"); $result = 0; } return $result; } sub canon_pci { my($str) = @_; my($result) = ''; if ($str =~ /(([0-9a-h]{2}h:?){4})/) { my @ids = map { hex(substr($_, 0, -1)) } split(/:/, $str); shift @ids; my $last = pop @ids; $result = join(':', map { sprintf("%02x", $_) } @ids); $result .= sprintf(".%1x", $last); } else { $result = $str; } return $result; } sub canon_raid { my($raid) = @_; return unless (defined $raid); $raid =~ s/\bIME\b/RAID 1E/; $raid =~ s/\bIM\b/RAID 1/; $raid =~ s/\bIS\b/RAID 0/; $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; $raid .= '-?' if ($raid eq 'RAID'); 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-f]+$/i)) { $model =~ s/^0x0*//; $model =~ s/(..)/sprintf("%c", hex($1))/ge; $model =~ s/[^ -~]//g; } $model =~ s/\s+/ /g; $model =~ s/^\s+//; $model =~ s/\s+$//; return $model; } sub highlight { my($str) = @_; $str =~ s/^/\033[31m/gm; $str =~ s/$/\033[0m/gm; return $str; } sub clean_white { my($string) = @_; $string =~ s/\s+/ /g; $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; } 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/\bdual[\-\s]+core\b//ig; # might be too agressive, do we need this distinction? $model =~ s/XEON/Xeon/g; $model =~ s/\s+/ /g; $model =~ s/\s+$//; $model =~ s/^\s+//; $model =~ s/\/.*//; return $model; } sub clean_pci_model { my($model) = @_; $model =~ s/\(was:.*\)//i; # freebsd $model =~ s/\(rev .*\)$//; # linux $model =~ s/PCI Express/PCIe/i; $model =~ s/(Gigabit) Ethernet( Controller( \(Copper\))?)?/$1/i; $model =~ s/(Gigabit) Network Connection/$1/i; $model =~ s/Fibre Channel Host Adapter/FC HBA/i; $model =~ s/\b(Corporation|Corp\.?|Inc|Co\.|Ltd\.|Technologies|Technology Group Ltd\.|Semiconductor Co\.\,)//ig; $model =~ s/\s+(Controller|Adapter)\s*$//i; return clean_white($model); } sub clean_system { my($str) = @_; $str =~ s/[^ -~]//g; $str =~ s/[\.\,]/ /gi; $str =~ s/\b(Server|Board|Mainboard|Microtower|Microsystems|Inc|Computer|Corp|Corporation|Coporation|Technology|Technologies|Co|Ltd|Manufacturer)\b/ /gi; $str =~ s/Small Form Factor//i; $str =~ s/American Megatrends/AMI/; $str =~ s/Award Software/Award/; $str =~ s/Rackable Systems/Rackable/ig; $str =~ s/Cisco Systems/Cisco/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/HUAWEI/Huawei/g; $str =~ s/DELL/Dell/g; $str =~ s/VMware Virtual Platform/VMware/; $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 Compaq/HP/i; $str =~ s/(HP|Sun|VMware|IBM|Tyan|Dell)\s+\1/$1/i; $str =~ s/Sun FIRE\b/Sun Fire/; $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; } sub decode_jedec { my($input) = @_; my($jedec) = ''; my($name); if (!$vendor_to_jedec{init}) { foreach my $key (keys %jedec) { $vendor_to_jedec{uc($jedec{$key})} = $key; } $vendor_to_jedec{init}++; } $input =~ s/^jedec id://i; $name = $input; $input = uc($input); # first, check to see if we got a vendor name if ($vendor_to_jedec{$input}) { $jedec = $vendor_to_jedec{$input}; } else { # if not, assume jedec code $input =~ s/\s+//g; $input =~ s/(00|FF)+$//; $input =~ s/^0X//; if ($input =~ /^((7F)*[0-9A-F]{2})$/) { $jedec = $1; } elsif ($input =~ /^(80|01|02|83|04|85|86)([0-9A-F]{2})/) { # this format allows for three jedecs: module + amb + chip $jedec = ('7F' x (hex($1) & 0xf)) . $2; } elsif ($input =~ /^([0-9A-F]{2})(80|01|02|83|04|85|86)/) { $jedec = ('7F' x (hex($2) & 0xf)) . $1; } elsif ($input =~ /^([0-9A-F]{2})(7F)/) { $jedec = "$2$1"; } } if ($jedec) { if ($jedec{$jedec}) { $name = $jedec{$jedec}; } else { $name = ''; } } return ($jedec, $name); } sub print_rate { my($number, $factor, $int, $round_limit) = @_; my(@suffix) = ('', 'K', 'M', 'G', 'T', 'P', 'E'); my($i) = 0; $factor = 1024 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 (round($number) >= 1000) { $number = $number / $factor; $i++; } my($result); if ($number >= $round_limit) { $result = sprintf("%.0f%sB/s", $number, $suffix[$i]); } elsif ($number) { $result = sprintf("%3.1f%sB/s", $number, $suffix[$i]); $result =~ s/\.0// if ($int); } else { $result = sprintf("0B/s"); } return $result; } sub print_bytes { my($number, $factor, $int, $round_limit, $suffix) = @_; my(@suffix) = ('', 'K', 'M', 'G', 'T', 'P', 'E'); my($i) = 0; $factor = 1000 unless $factor; $round_limit = 10 unless defined $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 (round($number) >= 1000) { $number = $number / $factor; $i++; last if ($suffix && $suffix eq $suffix[$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 decode_cpuid { my($vendor, $cpuid_hex) = @_; $vendor = canon_cpu_vendor($vendor); my($family, $model, $stepping, $ext_model, $ext_family); my($cpuid) = hex($cpuid_hex || 0); $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); if ($cpuid_vmware) { return ($vendor, $family, $model, 'VMware'); } else { return ($vendor, $family, $model, $stepping); } } sub init_dmesg { my $fh = new IO::File; my $line; my $dmesg_file; my $remote = 0; trace('dmesg'); my $dmesg = `dmesg`; # fallback to saved disk version if needed if ($os_type eq 'freebsd') { $dmesg_file = '/var/run/dmesg.boot'; system("df -t ufs $dmesg_file 2> /dev/null | grep -v ^Filesystem > /dev/null 2>&1"); $remote = ($CHILD_ERROR) ? 1 : 0; } else { $dmesg_file = '/var/log/dmesg'; system("df -l $dmesg_file 2> /dev/null | grep -v ^Filesystem > /dev/null 2>&1"); $remote = ($CHILD_ERROR) ? 1 : 0; } # if dmesg output looks complete or we don't have local disk version, use dmesg if ($dmesg =~ /^Copyright.*The FreeBSD Project/ || $dmesg =~ /^(Linux version|Bootdata ok)/ || $remote) { $dmesg_buf = $dmesg; } else { $fh->open("< $dmesg_file") || warn("open: $dmesg_file"); while ($line = <$fh>) { $dmesg_buf .= $line; } $fh->close; } } sub guess_system { my($init) = @_; my($system) = ""; my($buf) = $dmesg_buf; my($i) = 0; foreach my $model (@system_models) { my($guess) = $model->{'model'}; my($match) = 1; foreach my $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') && ($init =~ /VMware/i)) { $guess_system = $system = 'VMware'; } if (($guess_system eq 'Unknown') && ($init =~ /Xen HVM domU/i)) { $guess_system = $system = 'Xen HVM domU'; } if ($guess_system eq "Unknown" && $UID == 0) { $debug .= "Debug-System:\t$guess_system\n"; } return ($system || "Unknown"); } sub parse_model_for_raid { my($model) = @_; my($raid); if ($model =~ /\b(raid[\s\-]*(1E|ADG|[0156]+)(volume)?)\b/i) { $raid = $1; } elsif ($model =~ /(LSI.*IM|Mirror)/) { $raid = "RAID-1"; } elsif ($model =~ /(Stripe)/) { $raid = "RAID-0"; } else { $raid = ""; } return $raid; } sub grok_proc_scsi { my($fh) = new IO::File; my($line); return unless ($os_type eq "linux"); if (-e $proc_scsi) { my($letter) = 'a'; my($dev, $channel, $id, $lun, $model, $vendor, $rev, $vendor_model); $need_arcconf++ if (-e "/proc/scsi/aacraid"); $fh->open("< $proc_scsi") || warn("open: $proc_scsi: $!"); $debug_storage .= ">> $proc_scsi\n"; while ($line = <$fh>) { $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*Rev:\s*(.*)/) { ($vendor, $model, $rev) = ($1, $2 || 'Unknown', $3); $vendor_model = "$vendor $model"; } elsif ($line =~ /^\s*Type:\s*Direct-Access/) { my($vol) = "sd" . $letter++; my($device) = vol_to_hostid($vol) || $dev; my($driver) = $hostid_to_driver{$device} || scsi_to_device($device) || ''; # skip the case where lshal has already filled in this info if (!$got_lshal && !$got_sysblock) { $volumes{$vol}++; $props{volumes}{$vol}{raid} = parse_model_for_raid($vendor_model); $props{volumes}{$vol}{device} = $device if ($device); $props{volumes}{$vol}{source}{procscsi} = 1; $drives{$vol}{$drive_id}++; $props{drives}{$drive_id}{type} = 'scsi-volume'; $props{drives}{$drive_id}{model} = canon_drive($vendor_model); $props{drives}{$drive_id}{firmware} = $rev; $props{drives}{$drive_id}{volume} = $vol; $props{drives}{$drive_id}{size} = $props{volumes}{$vol}{bytes}; if ($vendor_model =~ /^($ignore_scsi_models)/) { $props{volumes}{$vol}{hidden} = 1; $props{drives}{$drive_id}{hidden} = 1; } smartctl($vol, "/dev/$vol", $vendor, $drive_id); hdparm($vol, "/dev/$vol", $drive_id); if ($hypervisor =~ /ESX/ && $os_version < 206000000) { # scsi info not accurate on ESX service console # hopefully we have better from smartctl $vendor_model = $props{drives}{$drive_id}{model}; } $drive_id++; $ndrives++; if (defined($dev) && defined($channel)) { my($logical) = sprintf("%s-%d-%d-%d", $dev, $channel, $id, $lun); my($logical_channel) = sprintf("%s-%d", $dev, $channel); $logical_to_os{all}{dev}{$logical} = $vol; $logical_to_os{all}{channel}{$logical_channel}++; if ($vendor_model =~ /$perc_names/ || $driver =~ /megaraid_sas/) { $logical_to_os{perc}{dev}{$logical} = $vol; $logical_to_os{perc}{channel}{$logical_channel}++; } elsif ($vendor_model =~ /MegaRAID/ || $driver =~ /megaraid/) { $logical_to_os{megaraid}{dev}{$logical} = $vol; $logical_to_os{megaraid}{channel}{$logical_channel}++; } elsif ($vendor_model =~ /LSILOGIC/ || $driver =~ /(mptsas|mptspi)/) { $logical_to_os{lsi}{dev}{$logical} = $vol; $logical_to_os{lsi}{channel}{$logical_channel}++; } elsif ($vendor_model =~ /(3ware|AMCC)/ || $driver =~ /3w/) { $logical = sprintf("c%d-u%d", ($dev =~ /^scsi(\d+)/), $id); $logical_to_os{tw}{dev}{$logical} = $vol; $logical_to_os{tw}{channel}{$logical_channel}++; } else { $logical_to_os{other}{dev}{$model} = $vol; $logical_to_os{other}{channel}{$logical_channel}++; } } undef $dev; undef $channel; undef $id; undef $lun; } if ($vendor_model =~ /$perc_names/) { # no /i so that PepperC doesn't match PERC $need_megacli++; } elsif ($vendor_model =~ /MegaRAID/) { $need_megarc++; $want_megacli++; } elsif ($vendor_model =~ /LSILOGIC/) { $need_linuxmpt++; } elsif ($vendor_model =~ /(3ware|AMCC)/) { $need_twcli++; } if ($driver =~ /($linux_mpt_drivers)/ && $vendor_model !~ /VMware/) { $want_linuxmpt++; $need_linuxmpt++ if ($vendor_model =~ /(LSILOGIC|VIRTUAL)/); } elsif ($driver =~ /mpt2sas/) { $need_linuxmpt2++; } elsif ($driver =~ /megaraid_sas/) { $need_megacli++; } elsif ($driver =~ /megaraid/) { $need_megarc++; } elsif ($driver =~ /3w/) { $need_twcli++; } elsif ($driver =~ /aacraid/) { $need_arcconf++; } } } $fh->close; } } sub grok_proc_cciss { my($dd) = new DirHandle; my($fh) = new IO::File; my($line); return unless ($os_type eq "linux" && -d $proc_cciss); $need_hpacucli++; $dd->open($proc_cciss) || warn("opendir: $proc_cciss: $!"); my(@dirs1) = $dd->read; $dd->close; my(@dirs2); if (-d $sys_cciss) { $dd->open($sys_cciss) || warn("opendir: $sys_cciss: $!"); @dirs2 = $dd->read; $dd->close; } $debug_storage .= ">> $proc_cciss\n"; foreach my $ent (@dirs1) { if ($ent =~ /^cciss\d+$/) { $fh->open("< $proc_cciss/$ent") || warn("open: $proc_cciss/$ent: $!"); $debug_storage .= ">>> $proc_cciss/$ent\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /firmware version: (\S+)/i) { $props{controllers}{$ent}{'firmware'} = $1; } elsif ($line =~ /^(cciss\/c\d+d\d+):\s+([\d\.]+GB)\s+(\S+.*)\s*$/) { my($vol, $bytes, $raid) = ($1, $2, $3); $bytes = parse_bytes($bytes, 1000); $raid = canon_raid($raid); $volumes{$vol}++; $props{volumes}{$vol}{raid} = $3; $props{volumes}{$vol}{device} = $ent; $controller_volumes{$ent}{$vol}++; $logical_to_os{ciss}{dev}{$vol} = $vol; block_register($vol, { 'bytes' => $bytes, 'raid' => $raid, 'driver' => 'cciss', 'controller' => $ent, }); foreach my $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{volumes}{$vol}{device} = $1; # $other_devices{'Disk-Control'}{$dev} = "$dev: $model"; # $cleanup{'Disk-Control'}{$num}++; } } } } $fh->close; } } } sub ccdconfig { my($fh) = new IO::File; my($line); my($result) = 0; system("which ccdconfig > /dev/null 2>&1"); return $result if ($CHILD_ERROR); my($cmd) = 'ccdconfig -g'; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec $cmd: $!"; $debug_storage .= ">> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); $result = 1; my($vol, $ileave, $flags, @parts) = split(' ', $line); if ($flags =~ /MIRROR/) { $props{volumes}{$vol}{raid} = "SW-RAID-1"; } else { $props{volumes}{$vol}{raid} = "SW-RAID-0"; $props{volumes}{$vol}{stripe} = $ileave * 512; } my($model) = ""; my($sep) = "partitions: "; foreach my $part (@parts) { $part =~ s{/dev/}{}; $model .= "$sep$part"; $sep = ", "; } $volumes{$vol}++; $drives{$vol}{$drive_id}++; $props{drives}{$drive_id}{type} = 'lv-ccd'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{volume} = $vol; $drive_id++; $ndrives++; } $fh->close; return $result; } sub mdadm { my($fh) = new IO::File; my($line); my($result) = 0; my(%md); system("which mdadm > /dev/null 2>&1"); return $result if ($CHILD_ERROR); my($cmd) = 'mdadm --detail --scan'; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec $cmd: $!"; $debug_storage .= ">> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^ARRAY (\S+)/) { $md{$1}++; $result++; } } $fh->close; foreach my $md (keys %md) { my($vol) = $md; $vol =~ s{^/dev/}{}; $props{volumes}{$vol}{driver} = 'md'; my(%parts); my($raid_devices, $total_devices, $failed_devices, $spare_devices); $cmd = "mdadm --detail $md"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec $cmd: $!"; $debug_storage .= ">> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^\s*Raid Level\s*:\s*(.*)/) { $props{volumes}{$vol}{raid} = canon_raid("SW-$1"); } elsif ($line =~ /^\s*Array Size\s*:\s*(\d+)/) { $props{volumes}{$vol}{bytes} = $1 * 1024; } elsif ($line =~ /^\s*Raid Devices\s*:\s*(\d+)/) { $raid_devices = $1; } elsif ($line =~ /^\s*Total Devices\s*:\s*(\d+)/) { $total_devices = $1; } elsif ($line =~ /^\s*Failed Devices\s*:\s*(\d+)/) { $failed_devices = $1; } elsif ($line =~ /^\s*Spare Devices\s*:\s*(\d+)/) { $spare_devices = $1; } elsif ($line =~ /^\s*Chunk Size\s*:\s*(.*)/) { $props{volumes}{$vol}{stripe} = parse_bytes($1, 1024); } elsif ($line =~ /^\s*Layout\s*:\s*(.*)/) { $props{volumes}{$vol}{raid_layout} = $1; } elsif ($line =~ /^\s*State\s*:\s*(.*)/) { # clean # active # same as clean, but with pending sync # clean, degraded # active, degraded $props{volumes}{$vol}{status} = parse_volume_status($1); } elsif ($line =~ /^\s*UUID\s*:\s*(.*)/) { $props{volumes}{$vol}{uuid} = $1; } elsif ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(.*?)\s*(\/dev\/\S+)?$/) { my($number, $major, $minor, $raid, $state, $dev) = ($1, $2, $3, $4, $5, $6); if ($dev) { $dev =~ s{^/dev/}{}; $parts{$number} = $dev; $partition_to_logical{$dev} = $vol; } } } $fh->close; my($model) = ''; my($sep) = 'partitions: '; foreach my $part (sort { cmp_disks($parts{$a}, $parts{$b}) } keys %parts) { $model .= "$sep$parts{$part}"; $sep = ", "; } $drives{$vol}{$drive_id}++; $props{drives}{$drive_id}{type} = 'lv-md'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{volume} = $vol; $drive_id++; $ndrives++; $failed_devices += ($raid_devices + $spare_devices - $total_devices); $props{volumes}{$vol}{failed} = $failed_devices if $failed_devices; $props{volumes}{$vol}{spare} = $spare_devices if $spare_devices; } return $result; } sub mdstat { my($fh) = new IO::File; my($line); my($vol, $raid, $rest); return unless ($os_type eq "linux"); if (-e $proc_mdstat) { $fh->open("< $proc_mdstat") || warn("open: $proc_mdstat: $!"); $debug_storage .= ">> $proc_mdstat\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^(md\d+).*(raid\d+)\s+(.*)/) { ($vol, $raid, $rest) = ($1, $2, $3); $props{volumes}{$vol}{raid} = canon_raid("SW-$raid"); $props{volumes}{$vol}{driver} = 'md'; my($model) = ""; my($sep) = "partitions: "; my(%parts); foreach my $dev (split(' ', $rest)) { if ($dev =~ /^(.*)\[(\d+)\](\((\w+)\))?/) { my($name, $num, $status) = ($1, $2, $4); $parts{$num} = $name; $partition_to_logical{$name} = $vol; if (defined $status && $status =~ /F/) { $props{volumes}{$vol}{failed}++; $props{volumes}{$vol}{status} = parse_volume_status('degraded'); } } $dev =~ s/\[(\d+)\]//; $dev =~ s/\d+$//; } my($count) = 0; foreach my $part (sort { cmp_disks($parts{$a}, $parts{$b}) } keys %parts) { $model .= "$sep$parts{$part}"; $sep = ", "; $count++; } if ($count > 2 && $props{volumes}{$vol}{raid} eq 'SW-RAID-1') { $props{volumes}{$vol}{raid} = 'SW-RAID-10'; } $drives{$vol}{$drive_id}++; $props{drives}{$drive_id}{type} = 'lv-md'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{volume} = $vol; $drive_id++; $ndrives++; } elsif ($line =~ /(\S+)\s+chunk/) { $props{volumes}{$vol}{stripe} = parse_bytes($1, 1024); } } $fh->close; } } sub grok_proc_partitions { my($fh) = new IO::File; my($line); return unless ($os_type eq "linux"); if (-e $proc_partitions) { $fh->open("< $proc_partitions") || warn("open: $proc_partitions: $!"); $debug_storage .= ">> $proc_partitions\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+((h|s|xv|v)d[a-z]+)(\d+)?(\s+|$)/) { my($blocks, $vol, $part) = ($3, $4, $6); if (defined $part) { $props{partitions}{$vol}{$part}{bytes} = $blocks * 1024; } else { $volumes{$vol}++; $props{volumes}{$vol}{bytes} = $blocks * 1024; $possible_raid_vols{$vol}++ if ($vol =~ /^sd/); } } elsif ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+((cciss|ida)\/c\d+d\d+)(p\d+)?(\s+|$)/) { my($blocks, $vol, $part) = ($3, $4, $6); if (defined $part) { $props{partitions}{$vol}{$part}{bytes} = $blocks * 1024; } else { $volumes{$vol}++; $props{volumes}{$vol}{bytes} = $blocks * 1024; $need_hpacucli++; $possible_raid_vols{$vol}++; } } elsif ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(rd\/c\d+d\d+)(p\d+)?(\s+|$)/) { my($blocks, $vol, $part) = ($3, $4, $5); if (defined $part) { $props{partitions}{$vol}{$part}{bytes} = $blocks * 1024; } else { $volumes{$vol}++; $props{volumes}{$vol}{bytes} = $blocks * 1024; $need_rd++; $possible_raid_vols{$vol}++; } } elsif ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(md\d+)(\s+|$)/) { my($blocks) = $3; my($vol) = $4; $volumes{$vol}++; $props{volumes}{$vol}{bytes} = $blocks * 1024; $need_mdstat++; } elsif ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(fio[a-z]+)(\d+)(\s+|$)/) { my($blocks, $vol, $part) = ($3, $4, $5); if (defined $part) { $props{partitions}{$vol}{$part}{bytes} = $blocks * 1024; } else { $volumes{$vol}++; $props{volumes}{$vol}{bytes} = $blocks * 1024; $need_fio++; } } 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++; } } $fh->close; } } sub grok_swap { my($fh) = new IO::File; my($proc) = '/proc/swaps'; my($line); if ($os_type eq 'linux') { if (-e $proc) { $fh->open("< $proc") || warn("open: $proc: $!"); $debug_storage .= ">> $proc\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ m{^/dev/(\S+)}) { $partition_to_logical{$1} = 'swap'; } } $fh->close; } } } sub grok_proc_ide { my($dd) = new DirHandle; return unless ($os_type eq "linux" && -d $proc_ide); $dd->open($proc_ide) || warn("opendir: $proc_ide: $!"); my(@dirs1) = $dd->read; $dd->close; foreach my $ent1 (@dirs1) { if ($ent1 =~ /^ide\d+$/ && -d "$proc_ide/$ent1") { $dd->open("$proc_ide/$ent1") || warn("opendir: $proc_ide/$ent1: $!"); my(@dirs2) = $dd->read; $dd->close; foreach my $ent2 (@dirs2) { if ($ent2 =~ /^hd([a-z])$/ && -d "$proc_ide/$ent1/$ent2") { my($letter) = $1; my($vol) = $ent2; next if (defined $props{volumes}{$vol}{source}{lshal}); 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{volumes}{$vol}{raid} = "JBOD"; $props{volumes}{$vol}{bytes} = $blocks * 512; $props{volumes}{$vol}{device} = $ent1; $props{volumes}{$vol}{ms} = ((ord($letter) - ord('a')) % 2) ? "slave" : "master"; $drives{$vol}{$drive_id}++; $props{drives}{$drive_id}{type} = 'ide-disk'; $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($dd) = new DirHandle; if (-d $root) { $dd->open($root) || warn("opendir: $root: $!"); my(@dirs) = $dd->read; $dd->close; foreach my $driver (sort @dirs) { next if ($driver =~ /^\.+$/); next if ($driver eq 'Delkin/ASKA/Workbit Cardbus IDE'); # e.g. lapg9005.inktomisearch.com, kp901125.inktomisearch.com $dd->open("$root/$driver") || warn("opendir: $root/$driver: $!"); my(@files) = $dd->read; $dd->close; my($count) = 0; foreach my $file (sort @files) { if ($file =~ /^0000:(.*)/) { my($pci) = $1; $pci_to_driver_raw{$pci} = $driver; $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++; $driver_to_pci{$pci_to_driver{$pci}} = $pci; # may not have devices connected, so just say we want these, not need if ($driver =~ /($linux_mpt_drivers)/) { $want_linuxmpt++; } elsif ($driver =~ /megaraid_sas/) { $want_megacli++; } elsif ($driver =~ /megaraid/) { $want_megarc++; } elsif ($driver =~ /3w/) { $want_twcli++; } elsif ($driver =~ /aacraid/) { $want_arcconf++; } } } } } } sub device_to_driver { my($dev) = @_; my($driver) = $pci_to_driver{$dev} || $hostid_to_driver{$dev} || $dev; $driver = scsi_to_device($driver); return $driver; } sub sys_scsi_host { my($result) = 0; my($dd) = new DirHandle; my($root) = '/sys/class/scsi_host'; return $result if (! -d $root); $dd->open($root) || warn "opendir: $root: $!"; my(@hosts) = grep(/^host\d+$/, $dd->read); $dd->close; foreach my $host (sort @hosts) { my($link) = readlink("$root/$host/device"); my($pci); if ($link =~ m{/devices/pci[^/]+/0000:([^/]+)}) { $pci = $1; $hostid_to_pci{$host} = $pci; if ($pci_to_hostid{$pci}) { $hostid_synonyms{$host} = $pci_to_hostid{$pci}; } else { $pci_to_hostid{$pci} = $host; } $result++; } if ($pci && $pci_to_driver{$pci}) { $hostid_to_driver{$host} = $pci_to_driver{$pci}; } elsif (-e "$root/$host/proc_name") { my $driver = `cat $root/$host/proc_name 2> /dev/null`; chomp($driver); $driver = $linux_driver_map{$driver} || $driver; $driver .= $1 if ($host =~ /(\d+)$/); $hostid_to_driver{$host} = $driver; $pci_to_driver{$pci} = $driver if ($pci); } } return $result; } sub pci_to_hostid { my($pci) = @_; my($root) = "/sys/bus/pci/devices"; my($dd) = new DirHandle; my($hostid); my($full_pci) = $pci; return $pci_to_hostid{$pci} if ($pci_to_hostid{$pci}); # rest should be dead code $full_pci = "0000:$full_pci" unless (-d "$root/$full_pci"); if (-d "$root/$full_pci") { $dd->open("$root/$full_pci") || warn("opendir: $root/$full_pci: $!"); my(@dirs) = $dd->read; $dd->close; foreach my $ent1 (sort @dirs) { 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" 2> /dev/null`; 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; } sub grok_proc_ioports { my($fh) = new IO::File; my($line); return unless ($os_type eq "linux"); if (-e $proc_interrupts) { my($class) = 0; my($cmd) = "$lspci -vn"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn("exec: $cmd: $!"); while ($line = <$fh>) { 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"}++; } } $fh->close; $fh->open("< $proc_interrupts") || warn("open: $proc_interrupts: $!"); while ($line = <$fh>) { if ($line =~ /^\s*(\d+).*\s+(\S+)$/) { $interrupts_map{$1} = lc($2) if ($irq_count{$1} && $irq_count{$1} == 1); } } $fh->close; } if (-e $proc_ioports) { $fh->open("< $proc_ioports") || warn("open: $proc_ioports: $!"); while ($line = <$fh>) { if ($line =~ /^\s*([0-9a-f]+)-([0-9a-f]+)\s+:\s+(\w+)/) { $ioports_map{$1} = lc($3); } } $fh->close; } if (-e $proc_iomem) { $fh->open("< $proc_iomem") || warn("open: $proc_iomem: $!"); while ($line = <$fh>) { if ($line =~ /^\s*([0-9a-f]+)-([0-9a-f]+)\s+:\s+(\w+)/) { $iomem_map{$1} = lc($3); } } $fh->close; } } sub grok_lspci { my($fh) = new IO::File; my($line); my(%driver_count); my(%model); my($cmd) = $lspci; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn("exec: $cmd: $!"); if ($fh->eof) { # have seen this happen with Xen $fh->close; return 0; } while ($line = <$fh>) { 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); } } $fh->close; $cmd = "$lspci -vn"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn("exec: $cmd: $!"); $debug_lspci = ">> $cmd\n"; $line = <$fh>; my($first) = 1; my($pci, $class, $chip, $card, $rev, $vendor_id, $product_id, $irq, $irq_class); while (1) { $debug_lspci .= $line; if ($fh->eof|| $line =~ /^\S+/) { if (!$first) { my($model) = $model{$pci} || 'Unknown'; $pci_map{$pci} = "$card,$chip,$rev"; $pci_all .= "<$card,$chip,$rev>"; $sig_pci .= "$card,$chip,$rev\t$model\n"; if ($chipsets{"$chip,$rev"}) { $other_devices{'Chipset'}{"$chip,$rev"}{model} = $chipsets{"$chip,$rev"}; $other_devices{'Chipset'}{"$chip,$rev"}{pci} = $pci; } elsif ($chipsets{"$chip,0x??"}) { $other_devices{'Chipset'}{"$chip,0x??"}{model} = $chipsets{"$chip,0x??"}; $other_devices{'Chipset'}{"$chip,0x??"}{pci} = $pci; $debug .= "Debug-Chipset:\t$chip,$rev - $model\n"; } elsif ($chipsets{$chip}) { $other_devices{'Chipset'}{$chip}{model} = $chipsets{$chip}; $other_devices{'Chipset'}{$chip}{pci} = $pci; } if ($pci_devices{'storage'}{"$card,$chip,$rev"}) { my($dev) = pci_to_hostid($pci) || $pci; $model = $pci_devices{'storage'}{"$card,$chip,$rev"}; $other_devices{'Disk-Control'}{$dev} = "$dev: $model"; } elsif ($pci_devices{'storage'}{"$card,$chip"}) { my($dev) = pci_to_hostid($pci) || $pci; $model = $pci_devices{'storage'}{"$card,$chip"}; $other_devices{'Disk-Control'}{$dev} = "$dev: $model"; } elsif ($pci_devices{'storage'}{"0x????????,$chip,$rev"}) { my($dev) = pci_to_hostid($pci) || $pci; $debug .= "Debug-Disk-Control:\t$dev: $card,$chip,$rev - $model\n"; $model = $pci_devices{'storage'}{"0x????????,$chip,$rev"}; $other_devices{'Disk-Control'}{$dev} = "$dev: $model"; } elsif ($pci_devices{'storage'}{"0x????????,$chip"}) { my($dev) = pci_to_hostid($pci) || $pci; $debug .= "Debug-Disk-Control:\t$dev: $card,$chip,$rev - $model\n"; $model = $pci_devices{'storage'}{"0x????????,$chip"}; $other_devices{'Disk-Control'}{$dev} = "$dev: $model"; } elsif ($pci_devices{'network'}{"$card,$chip,$rev"}) { $model = $pci_devices{'network'}{"$card,$chip,$rev"}; $other_devices{'Network'}{$pci} = "$pci: $model"; } elsif ($pci_devices{'network'}{"0x????????,$chip,$rev"}) { $debug .= "Debug-Network:\t$pci: $card,$chip,$rev - $model\n"; $model = $pci_devices{'network'}{"0x????????,$chip,$rev"}; $other_devices{'Network'}{$pci} = "$pci: $model"; } elsif ($pci_devices{'network'}{"0x????????,$chip,0x??"}) { $debug .= "Debug-Network:\t$pci: $card,$chip,$rev - $model\n"; $model = $pci_devices{'network'}{"0x????????,$chip,0x??"}; $other_devices{'Network'}{$pci} = "$pci: $model"; } elsif ($pci_devices{'other'}{"$card,$chip,$rev"}) { $model = $pci_devices{'other'}{"$card,$chip,$rev"}{model}; $other_devices{$pci_devices{'other'}{"$card,$chip,$rev"}{type}}{"$card,$chip"} = $model; } elsif ($pci_classes{$class} && $pci_classes{$class}{required}) { my($dev) = pci_to_hostid($pci) || $pci; $other_devices{$pci_classes{$class}{type}}{$dev} = "$dev: $model"; if (!$pci_classes{$class}{hide}) { $debug .= "Debug-" . $pci_classes{$class}{type} . ":\t$dev: $card,$chip,$rev - $model\n"; } } if ($pci_classes{$class}{hide}) { my($dev) = pci_to_hostid($pci) || $pci; $hide_dev{$dev}++; } set($xml, 'model', $model); set($xml, 'hostid', pci_to_hostid($pci)); if ($pci_to_driver_raw{$pci} || $pci_to_driver{$pci}) { $xml->{driver} = {}; set($xml->{driver}, 'name', $pci_to_driver_raw{$pci} || $pci_to_driver{$pci}); if ($pci_to_driver_raw{$pci} && $driver_version{$pci_to_driver_raw{$pci}}) { set($xml->{driver}, 'version', $driver_version{$pci_to_driver_raw{$pci}}); } } } 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, $vendor_id, $product_id, $chip, $card, $rev, $irq, $irq_class) = ($1, "0x$3", "0x$4", "0x$5", "0x$5$4", "0x00000000", $7 ? "0x$7" : "0x00", 0, 0); $pci =~ s/^0000://; $first = 0; $xml = {}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{pci}->{device}}, $xml); $pci_to_handle{$pci} = $xml->{handle} = $xml_handle++; $xml->{pci} = $pci; $xml->{class} = $class; $xml->{vendor_id} = $vendor_id; $xml->{product_id} = $product_id; $xml->{rev} = $rev; } } elsif ($line =~ /^\sFlags:.*IRQ\s+(\d+)/i) { $xml->{irq} = $1; $irq_to_all_pci{$1}{$pci}++; 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; if (!$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) { $pci_to_driver_raw{$pci} = $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; if (!$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) { $pci_to_driver_raw{$pci} = $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"; $xml->{subsys_vendor_id} = "0x$1"; $xml->{subsys_product_id} = "0x$2"; } last if $fh->eof; $line = <$fh>; } $fh->close; } sub grok_pciconf { my($fh) = new IO::File; my($dev, $pci, $class, $card, $chip, $rev); my($model); my(%vendor, %model); my(@lines); system("which $pciconf > /dev/null 2>&1"); return if ($CHILD_ERROR); my($cmd) = "$pciconf -lv"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn("exec: $cmd: $!"); $debug_pciconf = ">> $cmd\n"; if ($fh->eof) { $fh->close; $cmd = "$pciconf -l"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn("exec: $cmd: $!"); $debug_pciconf = ">> $cmd\n"; } while (my $line = <$fh>) { $debug_pciconf .= $line; push(@lines, $line); if ($line =~ /^(\S+)\@(\S+).*class=(\S+).*card=(\S+).*chip=(\S+).*rev=(\S+)/) { ($dev, $pci, $class, $card, $chip, $rev) = ($1, $2, $3, $4, $5, $6); } elsif ($line =~ /^\s+vendor\s+=\s+'(.*)'$/) { $vendor{$dev} = clean_pci_model($1); } elsif ($line =~ /^\s+device\s+=\s+'(.*)'$/) { $model{$dev} = clean_pci_model($1); } } $fh->close; foreach my $line (@lines) { if ($line =~ /^(\S+)\@(\S+).*class=(\S+).*card=(\S+).*chip=(\S+).*rev=(\S+)/) { ($dev, $pci, $class, $card, $chip, $rev) = ($1, $2, $3, $4, $5, $6); if ($pci =~ /pci(\d+):(\d+):(\d+)/) { $pci = sprintf("%02x:%02x:%x", $1, $2, $3); } $class =~ s/..$//; $xml = {}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{pci}->{device}}, $xml); $pci_to_handle{$pci} = $xml->{handle} = $xml_handle++; $xml->{class} = $class; if ($chip =~ /^0x(.{4})(.{4})$/) { $xml->{product_id} = "0x$1"; $xml->{vendor_id} = "0x$2"; } if ($card =~ /^0x(.{4})(.{4})$/) { $xml->{subsys_product_id} = "0x$1"; $xml->{subsys_vendor_id} = "0x$2"; } $xml->{rev} = $rev; $xml->{driver}->{name} = $dev; $xml->{pci} = $pci; $dev_to_pci{$dev} = $pci; 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"}{model} = $chipsets{"$chip,$rev"}; $other_devices{'Chipset'}{"$chip,$rev"}{pci} = $pci; } elsif ($chipsets{"$chip,0x??"}) { $other_devices{'Chipset'}{"$chip,0x??"}{model} = $chipsets{"$chip,0x??"}; $other_devices{'Chipset'}{"$chip,0x??"}{pci} = $pci; $debug .= "Debug-Chipset:\t$chip,$rev - $model\n"; } elsif ($chipsets{$chip}) { $other_devices{'Chipset'}{$chip}{model} = $chipsets{$chip}; $other_devices{'Chipset'}{$chip}{pci} = $pci; } if ($pci_classes{$class}{type} && $pci_classes{$class}{type} eq 'Disk-Control') { my($type) = $dev; $type =~ s/\d+$//; $need_cissutil++ if ($type eq 'ciss'); $need_megarc++ if ($type eq 'amr'); $need_mfiutil++ if ($type eq 'mfi'); $need_mptutil++ if ($type eq 'mpt'); $need_arcconf++ if ($type eq 'aac'); $need_twcli++ if ($type eq 'twe' || $type eq 'twa'); if (!$pci_devices{'storage'}{"$card,$chip,$rev"} && !$pci_devices{'storage'}{"$card,$chip"}) { if (!$pci_classes{$class}{hide}) { $debug .= "Debug-Disk-Control:\t$dev: $model, $card,$chip,$rev\n"; } $card = "0x????????"; } if ($pci_devices{'storage'}{"$card,$chip,$rev"}) { $model = $pci_devices{'storage'}{"$card,$chip,$rev"}; $other_devices{'Disk-Control'}{$dev} = "$dev: $model"; } elsif ($pci_devices{'storage'}{"$card,$chip"}) { $model = $pci_devices{'storage'}{"$card,$chip"}; $other_devices{'Disk-Control'}{$dev} = "$dev: $model"; } else { $other_devices{'Disk-Control'}{$dev} = "$dev: $model"; } } elsif ($pci_classes{$class}{type} && $pci_classes{$class}{type} eq 'Network') { $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"}) { $model = $pci_devices{'network'}{"$card,$chip,$rev"}; $interfaces{$dev}{'model'} = $model; } } elsif ($pci_devices{'other'}{"$card,$chip,$rev"}) { $model = $pci_devices{'other'}{"$card,$chip,$rev"}; $other_devices{$pci_devices{'other'}{"$card,$chip,$rev"}{type}}{"$card,$chip"} = $model; } elsif ($pci_classes{$class}{required}) { $other_devices{$pci_classes{$class}{type}}{$dev} = "$dev: $model"; if (!$pci_classes{$class}{hide}) { $debug .= "Debug-" . $pci_classes{$class}{type} . ":\t$dev: $model, $card,$chip,$rev\n"; } } if ($pci_classes{$class}{hide}) { $hide_dev{$dev}++; } $xml->{model} = $model; } } } sub hdparm { my($vol, $device, $id) = @_; my($result) = 0; my($fh) = new IO::File; my($line); system("which hdparm > /dev/null 2>&1"); return $result if ($CHILD_ERROR); # only use hdparm for /dev/hdx and /dev/sdx devices return $result if ($device !~ /^\/dev\/(sd|hd)[a-z]+$/); # stop using -g option here since we only used it for size info. and that # data is not always accurate, could either be in sectors or bytes (see below) my($cmd) = "hdparm -iI $device"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn("exec: $cmd: $!"); $debug_storage .= ">> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); $line =~ s/\s*$//; if ($line =~ /Model=([^,]+)/i || $line =~ /Model Number:\s*(.*)/i) { $props{drives}{$id}{type} = 'ata-disk'; $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 =~ /geometry.*sectors = (((\d+)))/i) { # this can either be in sectors or in bytes :-( # this mostly gets overwritten by LBA48 which always seems to be in sectors :-) # don't think there's anyway to tell so just go with most common case, # hopefully we'll get better data elsewhere $props{drives}{$id}{size} = $3; } if ($line =~ /LBAsects=(((\d+)))/i || $line =~ /LBA(48)?\s*user addressable sectors( =|:)\s*(\d+)/i) { $props{drives}{$id}{sectors} = $3; $props{drives}{$id}{size} = $3 * 512; } if ($line =~ /BuffSize=([^,]+)/i) { $props{drives}{$id}{cache_size} = parse_bytes($1, 1024); } if ($line =~ /cache\/buffer size\s*=\s*(\d+ KBytes)/) { $props{drives}{$id}{cache_size} = parse_bytes($1, 1024); } if ($line =~ /Logical\/Physical Sector size:\s+(\d+) bytes/) { $props{drives}{$id}{logical_sector} = $1; $props{drives}{$id}{physical_sector} = $1; } if ($line =~ /Logical\s+Sector size:\s+(\d+) bytes/) { $props{drives}{$id}{logical_sector} = $1; } if ($line =~ /Physical\s+Sector size:\s+(\d+) bytes/) { $props{drives}{$id}{physical_sector} = $1; } if ($line =~ /Form Factor: (.*)/) { $props{drives}{$id}{form} = parse_drive_form($1); } if ($line =~ /Nominal Media Rotation Rate: (\d+)/) { $props{drives}{$id}{rpm} = parse_rpm($1); } 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*Data Set Management TRIM supported\s*$/i) { $props{drives}{$id}{trim_support} = 1; $props{drives}{$id}{trim_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*(Gen\d+ signaling speed \(([^\)]+)\))/i) { # not sure when this format was introduced, but hdparm-9.12 uses it # assume the fastest one is last, so that we pick up top speed $props{drives}{$id}{speed} = parse_drive_speed($3); $props{drives}{$id}{interface} = parse_protocol($2); } if ($line =~ /Logical Unit WWN Device Identifier:\s*(\S+)/i) { $props{drives}{$id}{wwn} = "0x$1"; } if ($line =~ /^\s*Drive Supports :/) { # break here to avoid garbled model info for older OS last; } } $fh->close; return $result; } sub smartctl_parse { my($device, $dev_opt, $id) = @_; my($result) = 0; my($line); my($fh) = new IO::File; $dev_opt .= ' ' if $dev_opt; my($cmd) = "smartctl -i $dev_opt$device"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^Device Model:\s*(.*)/) { $props{drives}{$id}{type} = 'disk'; $props{drives}{$id}{model} = canon_drive($1); $result = 1; } elsif ($line =~ /^Device:\s*(.*)\s*Version:\s*(.*)/) { $props{drives}{$id}{type} = 'disk'; $props{drives}{$id}{model} = canon_drive($1); $props{drives}{$id}{firmware} = clean_white($2); $result = 1; } elsif ($line =~ /^Serial Number:\s*(.*)/i) { $props{drives}{$id}{serial} = clean_white($1); } elsif ($line =~ /^Firmware Version:\s*(.*)/) { $props{drives}{$id}{firmware} = clean_white($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; } elsif ($line =~ /^Device supports SMART and is Enabled/) { $props{drives}{$id}{smart_enable} = 1; } } $fh->close; return $result; } sub smartctl { my($vol, $device, $vendor, $id) = @_; my($result) = 0; my($dev_opt) = ($vendor =~ /^ATA\s*$/) ? '-d ata' : ''; system("which smartctl > /dev/null 2>&1"); return $result if ($CHILD_ERROR); # orginally used "smartctl -a" here. this causes some PE2950 RHEL boxes to hang/crash # 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 eval { # smartctl can be slow; eval wrap will cause it to die on alarm $result = smartctl_parse($device, $dev_opt, $id); if (!$result && $dev_opt) { # mptsas in linux doesn't work with -d ata $dev_opt = ''; $result = smartctl_parse($device, $dev_opt, $id); } }; 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($fh) = new IO::File; my($line); my(%hal); my(%cleanup); my($udi_key); my($cmd) = $lshal; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn("exec: $cmd: $!"); while ($line = <$fh>) { $debug_lshal .= $line; chomp($line); if ($line =~ /^udi = \'([^\']*)\'/) { $udi_key = $1; } elsif ($line =~ /^\s+(\S+)\s+=\s+\'([^\']*)\'/) { $hal{$udi_key}{$1} = $2; } elsif ($line =~ /^\s+(\S+)\s+=\s+(\S+)/) { $hal{$udi_key}{$1} = $2; } } $fh->close; foreach my $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}++; } $need_arcconf++ if ($hal{$udi}{'pci.vendor'} && $hal{$udi}{'pci.vendor'} eq 'Adaptec' && $hal{$udi}{'pci.product'} && $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 my($path) = $hal{$udi}{'linux.sysfs_path'}; if ($path =~ /pci[0-9a-f:\.]+\/(([0-9a-f:\.]{12})\/)?([0-9a-f:\.]{12}).*\/([^\/]+)$/) { ($num, $dev) = ($3, $4); } } 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'} || $hal{$udi}{'storage.revision'}; $serial = $hal{$udi}{'storage.serial'}; $model = canon_drive($hal{$udi}{'storage.model'}); $props{volumes}{$vol}{raid} = parse_model_for_raid($model); 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{volumes}{$vol}{'device'} = $dev; $props{volumes}{$vol}{'ms'} = $ms if ($ms); $props{volumes}{$vol}{source}{lshal} = 1; $got_lshal++; $drives{$vol}{$drive_id}++; $props{drives}{$drive_id}{type} = 'ide-disk'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{volume} = $vol; $props{drives}{$drive_id}{firmware} = $firmware; $props{drives}{$drive_id}{serial} = $serial; $props{drives}{$drive_id}{size} = $props{volumes}{$vol}{bytes}; 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{volumes}{$vol}{'device'} = $dev; $props{volumes}{$vol}{'ms'} = $ms if ($ms); $props{volumes}{$vol}{source}{lshal} = 1; $got_lshal++; $drives{$vol}{$drive_id}++; $props{drives}{$drive_id}{type} = 'ide-disk'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{volume} = $vol; $props{drives}{$drive_id}{firmware} = $firmware; $props{drives}{$drive_id}{serial} = $serial; $props{drives}{$drive_id}{size} = $props{volumes}{$vol}{bytes}; 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' || $hal{$udi}{'info.parent'} =~ /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); if ($extmodel =~ /$perc_names/) { # no /i so that PepperC doesn't match PERC $need_megacli++; } elsif ($extmodel =~ /MegaRAID/) { $need_megarc++; $want_megacli++; } elsif ($extmodel =~ /LSILOGIC/) { $need_linuxmpt++; } elsif ($extmodel =~ /(3ware|AMCC)/) { $need_twcli++; } if ($extmodel =~ /^($ignore_scsi_models)/) { $props{volumes}{$vol}{hidden} = 1; } $props{volumes}{$vol}{raid} = parse_model_for_raid($extmodel); 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'}); } my($logical) = sprintf("scsi%d-%d-%d-%d", $scsi_id, 0, $id, 0); my($logical_channel) = sprintf("scsi%d-%d", $scsi_id, 0); my($hostid) = vol_to_hostid($vol) || ''; my($driver) = $hostid_to_driver{$hostid} || ''; $logical_to_os{all}{dev}{$logical} = $vol; $logical_to_os{all}{channel}{$logical_channel}++; if ($extmodel =~ /$perc_names/ || $driver =~ /megaraid_sas/) { $logical_to_os{perc}{dev}{$logical} = $vol; $logical_to_os{perc}{channel}{$logical_channel}++; } elsif ($extmodel =~ /MegaRAID/ || $driver =~ /megaraid/) { $logical_to_os{megaraid}{dev}{$logical} = $vol; $logical_to_os{megaraid}{channel}{$logical_channel}++; } elsif ($extmodel =~ /LSILOGIC/ || $driver =~ /(mptsas|mptspi)/) { $logical_to_os{lsi}{dev}{$logical} = $vol; $logical_to_os{lsi}{channel}{$logical_channel}++; } elsif ($extmodel =~ /(3ware|AMCC)/ || $driver =~ /3w/) { $logical = sprintf("c%d-u%d", $scsi_id, $id); $logical_to_os{tw}{dev}{$logical} = $vol; $logical_to_os{tw}{channel}{$logical_channel}++; } else { $logical_to_os{other}{dev}{$hal{$node}{'storage.model'}} = $vol; $logical_to_os{other}{channel}{$logical_channel}++; } 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{volumes}{$vol}{'device'} = $dev; $props{volumes}{$vol}{source}{lshal} = 1; $got_lshal++; $drives{$vol}{$drive_id}++; $props{drives}{$drive_id}{type} = 'scsi-disk'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{volume} = $vol; $props{drives}{$drive_id}{size} = $props{volumes}{$vol}{bytes}; if ($extmodel =~ /^($ignore_scsi_models)/) { $props{drives}{$drive_id}{hidden} = 1; } smartctl($vol, $devpath, $hal{$udi}{'storage.vendor'}, $drive_id); hdparm($vol, $devpath, $drive_id); $drive_id++; $ndrives++; last; } $node = $hal{$node}{'info.parent'}; } } } } foreach my $type (keys %cleanup) { foreach my $num (keys %{$cleanup{$type}}) { delete $other_devices{$type}{$num}; } } } sub lvdisplay { my($fh) = new IO::File; 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 ($CHILD_ERROR); $debug_storage .= ">> lvm\n"; my($cmd) = 'lvdisplay -m'; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $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{volumes}{$vol}{bytes} = $lv_size; $props{volumes}{$vol}{raid} = "SW-RAID-0"; $sep = "partitions: "; $model = ''; $looking++; } elsif ($line =~ /Stripe size\s+(.*)/) { $props{volumes}{$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}{type} = 'lv-lvm'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{volume} = $vol; $drive_id++; $lvm_logical_to_physical{$lv} = $vol; } $looking = 0; } } $fh->close; if (!$result) { my($volumes); $cmd = 'lvscan'; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /ACTIVE\s*\"(\S+)\"/) { $volumes .= " $1"; } } $fh->close; if ($volumes) { my($next) = 0; $cmd = "lvdisplay -v $volumes"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $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; } } $fh->close; } } return $result; } sub df { my($fh) = new IO::File; my($line); my($result) = 0; my(%seen); system("which df > /dev/null 2>&1"); return $result if ($CHILD_ERROR); my($cmd); if ($os_type eq "linux") { $cmd = 'df -P -k -l'; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">> $cmd\n"; } else { $cmd = 'df -k -t ufs'; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">> $cmd\n"; } $line = <$fh> || ''; $debug_storage .= $line; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); $result++; my($vol, $size, $used, $avail, @rest) = split(' ', $line); next unless ($vol =~ m{^/dev/}); # bsd4 show a partition multiple times with df -t ufs # so only count each partition once to workaround this bug # manickam-dt-btr.ubcity.corp:~$ df -k # Filesystem 1K-blocks Used Avail Capacity Mounted on # /dev/ad5s1a 1014887 630489 303208 68% / # /dev/ad5s1e 70152614 19466422 45073983 30% /home # manickam-dt-btr.ubcity.corp:~$ df -k -t ufs # Filesystem 1K-blocks Used Avail Capacity Mounted on # /dev/ad5s1e 70152614 19466422 45073983 30% /home # /dev/ad5s1e 70152614 19466422 45073983 30% /home next if ($seen{$vol}++); 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 =~ /^((h|s|xv|v)d[a-z]+)(\d*)$/) { my($part) = $3; $vol = $1; if ($part ne '') { $props{partitions}{$vol}{$part}{df}{size} += $size * 1024; $props{partitions}{$vol}{$part}{df}{used} += $used; $props{partitions}{$vol}{$part}{df}{avail} += $avail; } } elsif ($vol =~ /(p\d+)$/) { my($part) = $1; $vol =~ s/p\d+$//; $props{partitions}{$vol}{$part}{df}{size} += $size * 1024; $props{partitions}{$vol}{$part}{df}{used} += $used; $props{partitions}{$vol}{$part}{df}{avail} += $avail; } } 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{volumes}{$vol}{df}{size} += $size * 1024; $props{volumes}{$vol}{df}{used} += $used; $props{volumes}{$vol}{df}{avail} += $avail; } $fh->close; return $result; } sub disk_usage { foreach my $vol (keys %{$props{volumes}}) { my($vol_size) = $props{volumes}{$vol}{bytes}; next unless $vol_size; # ignored volumes won't have sizes my($usage); my($total_usage, $denom) = (0, 0); if ($props{partitions}{$vol}) { foreach my $part (keys %{$props{partitions}{$vol}}) { my($partition) = $vol . $part; my($partition_size) = $props{partitions}{$vol}{$part}{bytes}; my($percentage) = $partition_size / $vol_size; if ($props{partitions}{$vol}{$part}{df} && $props{partitions}{$vol}{$part}{df}{size}) { $usage = $props{partitions}{$vol}{$part}{df}{used} / ($props{partitions}{$vol}{$part}{df}{used} + $props{partitions}{$vol}{$part}{df}{avail}); $total_usage += ($usage * $percentage); $denom += $percentage; } elsif ($partition_to_logical{$partition}) { my($logical) = $partition_to_logical{$partition}; while (defined $partition_to_logical{$logical}) { # deal with nested md devices, e.g. raid-10 $logical = $partition_to_logical{$logical}; } if ($logical eq 'swap') { $total_usage += (1.0 * $percentage); $denom += $percentage; } else { if ($props{volumes}{$logical}{df} && $props{volumes}{$logical}{df}{size}) { $usage = $props{volumes}{$logical}{df}{used} / ($props{volumes}{$logical}{df}{used} + $props{volumes}{$logical}{df}{avail}); $total_usage += ($usage * $percentage); $denom += $percentage; } } } else { # treat it as not used $total_usage += (0.0 * $percentage); $denom += $percentage; } } if ($denom) { $total_usage /= $denom; } } elsif ($partition_to_logical{$vol}) { # take care of case where drive is not split into partitions, but still part of an md my($logical) = $partition_to_logical{$vol}; if ($props{volumes}{$logical}{df} && $props{volumes}{$logical}{df}{size}) { $total_usage = $props{volumes}{$logical}{df}{used} / ($props{volumes}{$logical}{df}{used} + $props{volumes}{$logical}{df}{avail}); } } if ($total_usage) { $props{volumes}{$vol}{usage} = $total_usage; } elsif ($props{volumes}{$vol}{df} && $props{volumes}{$vol}{df}{used}) { $props{volumes}{$vol}{usage} = $props{volumes}{$vol}{df}{used} / ($props{volumes}{$vol}{df}{used} + $props{volumes}{$vol}{df}{avail}); } } } sub other_devices { my($result) = ''; my($line); my(@chipsets); my($out, @out); foreach my $type (sort keys %other_devices) { foreach my $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}; if (ref($description) eq 'HASH') { $description = $description->{model}; } my($dev) = $device; my($pci) = $dev_to_pci{$dev} || $hostid_to_pci{$dev} || ''; 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') { $description =~ s/^\S+:\s+//; $props{controllers}{$dev}{model} = $description; $props{controllers}{$dev}{pci} = $pci; if ($props{controllers}{$dev}{'package'}) { $out .= ", FW Package $props{controllers}{$dev}{'package'}"; } if ($props{controllers}{$dev}{'firmware'}) { $out .= ", FW $props{controllers}{$dev}{'firmware'}"; } if ($props{controllers}{$dev}{'mpi'}) { $out .= ", MPI $props{controllers}{$dev}{'mpi'}"; } if ($props{controllers}{$dev}{'bios'}) { $out .= ", BIOS $props{controllers}{$dev}{'bios'}"; } if (defined $props{controllers}{$dev}{cache} && ($props{controllers}{$dev}{cache}{status} || $props{controllers}{$dev}{cache}{size})) { $out .= ", Cache"; $out .= " $props{controllers}{$dev}{cache}{status}" if $props{controllers}{$dev}{cache}{status}; if (defined $props{controllers}{$dev}{read_cache} && defined $props{controllers}{$dev}{read_cache}{size}) { $out .= ' ' . print_bytes($props{controllers}{$dev}{read_cache}{size}, 1024, 1); $out .= '/' . print_bytes($props{controllers}{$dev}{write_cache}{size}, 1024, 1); $out .= ' (R/W)'; } elsif ($props{controllers}{$dev}{cache}{size}) { $out .= ' ' . print_bytes($props{controllers}{$dev}{cache}{size}, 1024, 1); } } if ($props{controllers}{$dev}{'bbu_status'}) { if ($props{controllers}{$dev}{'bbu_status'} ne 'missing') { $out .= ", BBU"; if ($props{controllers}{$dev}{'bbu_status'} eq 'failed') { $out .= " failed"; } } } } push(@out, $out) unless ($hide_dev{$device}); } } foreach my $line (sort cmp_other_devices @out) { $result .= $line . "\n"; } if (@chipsets) { my($last); my($pretty) = ''; foreach my $chipset (sort { $a->{model} cmp $b->{model} } @chipsets) { my($name) = $chipset->{model}; my($pci) = $chipset->{pci}; if ($name =~ /^(NB|SB|IB): (\S+)\s+(.*?)( step=(\S+))?(\s+\(([^\)]+)\))?$/) { my($bridge, $vendor, $model, $x1, $step, $x2, $code) = ($1, $2, $3, $4, $5, $6, $7); if ($last && $vendor eq $last) { $pretty .= ", " if $pretty; } else { $pretty .= "; " if $pretty; $pretty .= "$vendor "; } $pretty .= $model; $pretty .= " $step" if ($step); $pretty .= " ($code)" if ($code); $last = $vendor; $xml = {}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{chipsets}->{chipset}}, $xml); $xml->{handle} = $xml_handle++; $xml->{type} = $chipset_types{$bridge} || $bridge || ''; $xml->{vendor} = $vendor; $xml->{model} = $model; $xml->{stepping} = $step if ($step); $xml->{name} = $code if ($code); $xml->{pci} = $pci; $xml->{pci_handle} = $pci_to_handle{$pci}; } else { $pretty .= $name; } } $result .= "Chipset:\t$pretty\n"; $xml_top->{chipsets}->{summary} = $pretty; } elsif ($system_model_index && defined $system_models[$system_model_index]{chipset}) { my($name, $vendor, $model); $name = $system_models[$system_model_index]{chipset}; $result .= "Chipset:\t$name\n"; $xml_top->{chipsets}->{summary} = $name; $xml = {}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{chipsets}->{chipset}}, $xml); $xml->{handle} = $xml_handle++; ($vendor, $model) = ($name =~ /^(\S+)\s+(.*)/); $xml->{vendor} = $vendor; $xml->{model} = $model; } else { $debug .= "Debug-Chipset:\tUnknown\n"; } return $result; } 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(%disks); my($result, $sep); foreach my $line (split(/\n/, $dmesg_buf)) { if ($line =~ /^(($freebsd_disk_names)\d+):/) { $disks{$1}++; } } $sep = ""; $result = ""; foreach my $disk (sort { $a cmp $b } keys %disks) { $result .= "$sep$disk"; $sep = " "; } return $result; } sub grok_dmesg { foreach my $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_edx} = $1; $cpus{features_edx}{dmesg} = $1; } elsif ($line =~ /^\s*Features2\s*=\s*(0x[0-9a-f]+)/i) { $dmesg{proc}{features_ecx} = $1; $cpus{features_ecx}{dmesg} = $1; } elsif ($line =~ /^\s*AMD Features\s*=\s*(0x[0-9a-f]+)/i) { $dmesg{proc}{features_ext_edx} = $1; $cpus{features_ext_edx}{dmesg} = $1; } elsif ($line =~ /^\s*AMD Features2\s*=\s*(0x[0-9a-f]+)/i) { $dmesg{proc}{features_ext_ecx} = $1; $cpus{features_ext_ecx}{dmesg} = $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; $cpus{cpuid}{dmesg} = $2; } 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{controllers}{$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{controllers}{$1}{'firmware'} = $3; $props{controllers}{$1}{'bios'} = $4; } } elsif ($line =~ /^(($freebsd_block_devs)\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; } } } sub parse_proc { my($in, $section, $handle, $prefix) = @_; my($line); my($socket) = ++$procs{sockets}; my($ignore) = 1; my($key); while ($line = <$in>) { $debug_dmidecode .= $line; chomp($line); $line =~ s/\s+$//; $line =~ s/^${prefix}//; 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{proc}{$socket}{speed} = ($speed eq "0MHz") ? 0 : $speed; } elsif ($line =~ /^\s*(external )?clock:\s+(.*)$/i) { my($clock) = $2; $clock =~ s/\s+//g; $procs{proc}{$socket}{clock} = ($clock eq "0MHz") ? 0 : $clock; } elsif ($line =~ /^\s*family:\s+(.*)$/i) { $procs{proc}{$socket}{family} = $1; } elsif ($line =~ /^\s*manufacturer:\s+(.*)$/i) { $procs{proc}{$socket}{vendor} = $1; } elsif ($line =~ /^\s*version:\s+(.*)$/i) { # this data is useless, usually blank, don't use it $procs{proc}{$socket}{model} = clean_white($1); } elsif ($line =~ /^\s*cpu present:\s+(.*)$/i) { $procs{proc}{$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//; my($cpuid) = '0x' . substr($id, -8); my($edx) = '0x' . substr($id, 0 ,8); $procs{proc}{$socket}{cpuid} = $cpuid; $procs{proc}{$socket}{features_edx} = $edx; if (hex($cpuid) > 0) { $cpus{cpuid}{dmidecode} = $cpuid; $cpus{features_edx}{dmidecode} = $edx; } } elsif ($line =~ /^\s*status:\s+(.*)$/i) { $procs{proc}{$socket}{status} = ($1 =~ /\bpopulated\b/i); } elsif ($line =~ /^\s*(L\d+ Cache Handle):\s+(.*)$/) { $procs{proc}{$socket}{$1} = $2; } } if ($ignore) { $procs{sockets}--; delete $procs{proc}{$socket}; } elsif ($procs{proc}{$socket}{status} && $procs{proc}{$socket}{vendor} && $procs{proc}{$socket}{cpuid}) { my($step) = (decode_cpuid($procs{proc}{$socket}{vendor}, $procs{proc}{$socket}{cpuid}))[3]; $cpus{steppings}{$step}++; } } $smbios{'Memory'}{'Count'} = 0; sub parse_memory { my($in, $section, $sub, $handle, $prefix) = @_; my($count) = $smbios{$section}{'Count'} + 1; my($line); my($ignore) = 0; my($speed) = 0; my($size) = 0; my($manufacturer) = 0; my($part) = 0; my($serial) = 0; my($type) = 0; my($asset) = 0; my($locator) = 0; my($bank_locator) = 0; my($width) = 0; my($form) = 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+$//; $line =~ s/^${prefix}//; 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 =~ /Flash/i); } elsif ($line =~ /^\s*manufacturer:\s+(.*)$/i) { $manufacturer = $1; } elsif ($line =~ /^\s*total width:\s+(.*)$/i) { $width = $1; } elsif ($line =~ /^\s*asset tag:\s+(.*)$/i) { $asset = $1; } elsif ($line =~ /^\s*form factor:\s+(.*)$/i) { $form = $1; $ignore = 1 if ($form =~ /(chip|tsop)/i); } elsif ($line =~ /^\s*(device )?locator:\s+(.*)$/i) { $locator = $2; } elsif ($line =~ /^\s*bank locator:\s+(.*)$/i) { $bank_locator = $1; } elsif ($line =~ /^\s*part\s+number:\s+(.*)$/i) { $part = canon_memory($1); } elsif ($line =~ /^\s*serial\s+number:\s+(.*)$/i) { $serial = $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; $smbios{$section}{$count}{'serial'} = $serial; $smbios{$section}{$count}{'asset'} = $asset; $smbios{$section}{$count}{'locator'} = $locator; $smbios{$section}{$count}{'bank_locator'} = $bank_locator; $smbios{$section}{$count}{'width'} = $width; $smbios{$section}{$count}{'form'} = $form; } } sub parse_bios { my($in, $section, $handle, $prefix) = @_; my($count) = ++$smbios{$section}{'Count'}; my($line); my($key); while ($line = <$in>) { $debug_dmidecode .= $line; chomp($line); $line =~ s/\s+$//; $line =~ s/^${prefix}//; 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($ver) = $1; $ver =~ s/BIOS Version(:)?\s+//i; $ver =~ s/\-\[(.*)\]\-/$1/; $ver =~ s/^'(.*)'$/$1/; $ver = clean_white($ver); if ($ver =~ s/\s+(BIOS )?Date(:)?\s+(\S+.*)//i) { $smbios{$section}{$count}{'Release Date'} = $3; } $smbios{$section}{$count}{'Version'} = $ver; } elsif ($line =~ /^\s*BIOS Revision:\s+(.*)$/i) { $smbios{$section}{$count}{'Revision'} = $1; } elsif ($line =~ /^\s*Release Date:\s+(\S+.*)$/i) { $smbios{$section}{$count}{'Release Date'} = $1; } } } sub parse_system { my($in, $section, $handle, $prefix) = @_; my($count) = ++$smbios{$section}{'Count'}; my($line); my($key); while ($line = <$in>) { $debug_dmidecode .= $line; chomp($line); $line =~ s/\s+$//; $line =~ s/^${prefix}//; 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; } elsif ($line =~ /^\s*Version:\s+(.*)$/i) { $smbios{$section}{$count}{'Version'} = $1; } elsif ($line =~ /^\s*Revision:\s+(.*)$/i) { $smbios{$section}{$count}{'Revision'} = $1; } elsif ($line =~ /^\s*Serial Number:\s+(.*)$/i) { $smbios{$section}{$count}{'Serial Number'} = $1; } elsif ($line =~ /^\s*(SKU|Model Part) Number:\s+(.*)$/i) { $smbios{$section}{$count}{'Part Number'} = $2; } elsif ($line =~ /^\s*Family:\s+(.*)$/i) { $smbios{$section}{$count}{'Family'} = $1; } elsif ($line =~ /^\s*UUID:\s+(.*)$/i) { $smbios{$section}{$count}{'UUID'} = $1; } elsif ($line =~ /^\s*Asset Tag:\s+(.*)$/i) { $smbios{$section}{$count}{'Asset Tag'} = $1; } elsif ($line =~ /^\s*Type:\s+(.*)$/i) { $smbios{$section}{$count}{'Type'} = $1; } elsif ($line =~ /^\s*Height:\s+(.*)$/i) { $smbios{$section}{$count}{'Height'} = $1; } elsif ($line =~ /^\s*Location( In Chassis)?:\s+(.*)$/i) { $smbios{$section}{$count}{'Location'} = $2; } elsif ($line =~ /^\s*Status:\s+(.*)$/i) { $smbios{$section}{$count}{'Status'} = $1; } } } sub grok_network { my($fh) = new IO::File; my($line); my($int); my($result) = 0; system("which ifconfig > /dev/null 2>&1"); return $result if ($CHILD_ERROR); my($cmd) = 'ifconfig -a'; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn("exec: $cmd: $!"); $debug_network .= ">> $cmd\n"; if ($os_type eq "freebsd") { while ($line = <$fh>) { $debug_network .= $line; chomp($line); if ($line =~ /^(\w+):.*<(.*)>.*mtu (\d+)/) { $result++; $int = $1; $xml = {}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{network}->{interface}}, $xml); $interfaces{$int}{xml_handle} = $xml->{handle} = $xml_handle++; $xml->{name} = $int; $xml->{flags} = $2; $xml->{mtu} = $3; if ($dev_to_pci{$int}) { $xml->{pci} = $dev_to_pci{$int}; $xml->{pci_handle} = $pci_to_handle{$xml->{pci}}; } if ($dmesg_buf =~ /^$int:.*F\/W \(([^\)]+)/m) { # this works for bce $xml->{firmware} = $1; } # assume hidden for now $interfaces{$int}{hidden} = 1; } if ($line =~ /^\s*media:\s*(Ethernet)?\s*(.*)/) { my($media) = $2; $xml->{autoselect} = 1 if ($media =~ /autoselect/); if ($media =~ /\((.*)\)/) { # for case where active != requested, just go with the active setting $media = $1; } $interfaces{$int}{media} = ''; if ($media =~ /(\d+baseT\S+)/) { my $speed = parse_network_speed($1); $xml->{speed} = $speed; $interfaces{$int}{media} .= "$speed "; } if ($media =~ /(\w+)-duplex/) { $xml->{duplex} = $1; $interfaces{$int}{media} .= "<$1-duplex> "; } chop($interfaces{$int}{media}); # rest of $media is now obsolete 20100828 (interfaces{media} already set) $media =~ s/(\d+baseT\S+)/parse_network_speed($1)/e; $media =~ s/status.*//; # needed for < freebsd 4 $media =~ s/autoselect//; $media =~ s/[\(\)]//g; $media =~ s/\s+/ /g; $media =~ s/^\s+//; $media =~ s/\s+$//; } elsif ($line =~ /^\s*options=.*<(.*)>/) { $xml->{options} = $1; } elsif ($line =~ /^\s*ether\s*(\S*)/) { $interfaces{$int}{mac} = $1; $xml->{mac} = $1; # interfaces we care about should have mac; those that don't: lo0, tun0 $interfaces{$int}{hidden} = 0; } elsif ($line =~ /inet (\S+) netmask (\S+)( broadcast (\S+))?/) { my($ip) = {}; $handle_to_xml{$xml_handle} = $ip; push(@{$xml->{ip}}, $ip); $ip->{handle} = $xml_handle++; $ip->{address} = $1; $ip->{netmask} = $2; $ip->{broadcast} = $4 if ($3); } # same line as media: match above on < freebsd 4, so need separate if if ($line =~ /\bstatus:\s*(.*)/) { $interfaces{$int}{status} = $1; $xml->{status} = $1; } } } elsif ($os_type eq "linux") { my($pci) = 0; my($debug_network_2) = ''; while ($line = <$fh>) { $debug_network .= $line; chomp($line); if ($line =~ /^(\w+)\s+Link.*HWaddr\s+(\S+)/) { $result++; $int = $1; $interfaces{$int}{mac} = lc($2); $xml = {}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{network}->{interface}}, $xml); $interfaces{$int}{xml_handle} = $xml->{handle} = $xml_handle++; $xml->{name} = $int; $xml->{mac} = $interfaces{$int}{mac}; my($eth) = new IO::File; my($eline); my($speed, $duplex) = ("", ""); $cmd = "$ethtool $int"; trace($cmd); $eth->open("$cmd 2> /dev/null |") || warn("exec: $cmd: $!"); $debug_network_2 .= ">> $cmd\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 = parse_network_speed($1); } elsif ($eline =~ /Duplex:\s*(\S+)/) { $duplex = lc($1); } elsif ($eline =~ /^\s+Auto-negotiation: (\S+)/) { $xml->{autoselect} = 1 if ($1 eq 'on'); } } $eth->close; $interfaces{$int}{speed} = $speed; $interfaces{$int}{media} = $speed; if ($duplex) { $interfaces{$int}{duplex} = $duplex;; $interfaces{$int}{media} .= " <$duplex-duplex>"; } $cmd = "$ethtool -i $int"; trace($cmd); $eth->open("$cmd 2> /dev/null |") || warn("exec: $cmd: $!"); $debug_network_2 .= ">> $cmd\n"; while ($eline = <$eth>) { $debug_network_2 .= $eline; chomp($eline); if ($eline =~ /driver:\s+(\S+)/) { $interface_to_driver{$int} = $1; } elsif ($eline =~ /firmware-version:\s+(.*)/) { $xml->{firmware} = $1; } elsif ($eline =~ /bus-info:\s+(\S+)/) { $pci = $1; } } $eth->close; my(@options); $cmd = "$ethtool -k $int"; trace($cmd); $eth->open("$cmd 2> /dev/null |") || warn("exec: $cmd: $!"); $debug_network_2 .= ">> $cmd\n"; while ($eline = <$eth>) { $debug_network_2 .= $eline; chomp($eline); if ($eline =~ /rx-checksumming:\s+(\S+)/) { if (parse_enable($1)) { push(@options, 'RXCSUM'); } } elsif ($eline =~ /tx-checksumming:\s+(\S+)/) { if (parse_enable($1)) { push(@options, 'TXCSUM'); } } elsif ($eline =~ /tcp segmentation offload:\s+(\S+)/) { if (parse_enable($1)) { push(@options, 'TSO'); } } elsif ($eline =~ /udp fragmentation offload:\s+(\S+)/) { if (parse_enable($1)) { push(@options, 'UFO'); } } elsif ($eline =~ /udp large send offload:\s+(\S+)/) { if (parse_enable($1)) { push(@options, 'LSO'); } } elsif ($eline =~ /scatter-gather:\s+(\S+)/) { if (parse_enable($1)) { push(@options, 'SG'); } } } $eth->close; # mimic freebsd ifconfig output if (@options) { $xml->{options} = join(',', @options); } if (!$pci && -l "/sys/class/net/$int/device") { $pci = readlink("/sys/class/net/$int/device"); $pci =~ s/.*\///; } if (-l "/sys/class/net/$int/driver") { $interface_to_driver{$int} = readlink("/sys/class/net/$int/driver"); $interface_to_driver{$int} =~ s/.*\///; } elsif (-l "/sys/class/net/$int/device/driver") { $interface_to_driver{$int} = readlink("/sys/class/net/$int/device/driver"); $interface_to_driver{$int} =~ s/.*\///; } } if (defined $int) { if ($line =~ /inet addr:(\S+)\s+(Bcast:(\S+)\s+)?Mask:(\S+)/) { my($ip) = {}; $handle_to_xml{$xml_handle} = $ip; push(@{$xml->{ip}}, $ip); $ip->{handle} = $xml_handle++; $ip->{address} = $1; $ip->{netmask} = $4; $ip->{broadcast} = $3 if ($2); } elsif ($line =~ /^\s+(.*)MTU:(\d+)/) { my($flags) = $1; $xml->{mtu} = $2; $flags =~ s/\s+$//; $flags =~ s/\s+/,/g; $xml->{flags} = $flags; } if ($line =~ /RUNNING/) { # needed for 2.4 kernels which don't have "Link detected" above $interfaces{$int}{status} = "active"; } if (!$pci && $line =~ /Interrupt:(\d+)/i) { $pci = $irq_to_pci{"$1,0x0200"} if ($irq_to_pci{"$1,0x0200"}); } if (!$pci && $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}; $xml->{model} = $model; $xml->{pci} = $pci; $xml->{pci_handle} = $pci_to_handle{$pci}; } } $xml->{status} = $interfaces{$int}{status} || ''; if ($xml->{status} eq 'active') { $xml->{speed} = $interfaces{$int}{speed} || ''; $xml->{duplex} = $interfaces{$int}{duplex} || ''; } } undef $int; $pci = 0; } } $debug_network .= $debug_network_2; } $fh->close; return $result; } sub cpuinfo { my($fh) = new IO::File; my($line); # prefer data from smbinfo if available return unless (-r $cpuinfo); my($family, $model, $stepping, $vendor_id, $model_name, $flags, $speed, $cores, $siblings, $threads, $physical_id, $core_id); my(%physical_id, %core_id); my($cpu) = 'unknown'; my($n) = 0; $fh->open("< $cpuinfo") || warn "open: $cpuinfo: $!"; while ($line = <$fh>) { $debug_cpuinfo .= $line; chomp($line); if ($line =~ /^processor\s*:\s*(\d+)/i) { $cpu = "cpu$1"; } elsif ($line =~ /^cpuid level\s*:\s*(\d+)/i) { $cpus{cpus}{$cpu}{cpuid_level} = $1; } elsif ($line =~ /^cpu family\s*:\s*(\d+)/i) { $family = $1; $cpus{cpus}{$cpu}{family_id} = $1; } elsif ($line =~ /^model\s*:\s*(\d+)/i) { $model = $1; $cpus{cpus}{$cpu}{model_id} = $1; } elsif ($line =~ /^stepping\s*:\s*(\d+)/i) { $stepping = $1; $cpus{cpus}{$cpu}{stepping_id} = $1; $cpus{steppings}{$1}++; } elsif ($line =~ /^vendor_id\s*:\s*(.*)/i) { $vendor_id = $1; $cpus{cpus}{$cpu}{vendor_id} = $1; } elsif ($line =~ /^apicid\s*:\s*(.*)/i) { $cpus{cpus}{$cpu}{apic_id} = $1; } elsif ($line =~ /^model name\s*:\s*(.*)/i) { $model_name = clean_white($1); $cpus{cpus}{$cpu}{model} = $model_name; $cpus{models}{$model_name}++; } elsif ($line =~ /^cpu MHz\s*:\s*(.*)/i) { $speed = $1; $cpus{cpus}{$cpu}{speed} = int(1000000 * $1); } elsif ($line =~ /^physical id\s*:\s*(.*)/i) { $physical_id = $1; $cpus{cpus}{$cpu}{package_id} = $1; } elsif ($line =~ /^core id\s*:\s*(.*)/i) { $core_id = $1; $cpus{cpus}{$cpu}{core_id} = $1; } elsif ($line =~ /^flags\s*:\s*(.*)/i) { $flags = $1; } elsif ($line =~ /^address sizes\s*:\s*(\d+) bits physical, (\d+) bits virtual/i) { $cpus{cpus}{$cpu}{physical_address_bits} = $1; $cpus{cpus}{$cpu}{virtual_address_bits} = $2; } elsif ($line =~ /^cpu cores\s*:\s*(.*)/i) { $cores = $1; $cpus{cpus}{$cpu}{cores} = $1; } elsif ($line =~ /^siblings\s*:\s*(.*)/i) { $siblings = $1; $cpus{cpus}{$cpu}{threads} = $1; } elsif ($line =~ /^\s*$/) { if ($family && $model) { $n++; if (defined $physical_id) { $physical_id{$physical_id}++; if (defined $core_id) { $core_id{"$physical_id,$core_id"}++; } } my($ext_family) = 0; if ($family > 15) { $ext_family = $family - 15; $family = 15; } my($cpuid) = sprintf("0x%x", ($ext_family << 20) | (($model >> 4) << 16) | ($family << 8) | (($model & 0xf) << 4) | $stepping); $cpus{cpus}{$cpu}{cpuid} = $cpuid; $cpus{cpuid}{cpuinfo} = $cpuid; # don't override what dmidecode gave us $procs{proc}{$n}{cpuid} = $cpuid unless ($procs{proc}{$n}{cpuid}); $procs{proc}{$n}{vendor} = $vendor_id; $procs{proc}{$n}{family} = $model_name; $procs{proc}{$n}{speed} = $speed; $procs{proc}{$n}{flags} = $flags; # don't set {status} since we don't know if this is a socket } if (defined($physical_id) && defined($core_id)) { $cpus{packages}{$physical_id}{cores}{$core_id}{threads}{$cpu}++; } } } $fh->close; # $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) = join(',', decode_cpuid($procs{proc}{1}{vendor}, $procs{proc}{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") { foreach my $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:\tcpuinfo: %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{proc}{1}{features_edx}) { my($features) = hex($procs{proc}{1}{features_edx}); $htt = ($features >> $feature_htt_bit) & 0x0001; } else { $htt = ($flags =~ /\bht\b/i); } # this is now obsolete, will leave for now, but should be nuked - 20090201 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. # this is just a case where cpuinfo decoding is a bit stale wrt to rest of kernel. # which is why we should always show raw data (feature bits from ecx, edx) in addition # to showing decoded info. 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; # compute cores if ($n > 1 && $cpu_threads) { $n = ceil($n / $cpu_threads); } # $n is now number of active cores # although will be too high in case of HT missing # so use %core_id if possible my(@keys) = keys %core_id; if ($#keys > -1) { $procs{cores} = $#keys + 1; # %core_id is not always right, sanity check it if ($cpu_threads && ($procs{active_threads} > ($procs{cores} * $cpu_threads))) { $debug .= sprintf("Debug-Cores:\tcpuinfo: (active_threads=%d) > (cores=%d * cpu_threads=%d) ==> setting cores=%d\n", $procs{active_threads}, $procs{cores}, $cpu_threads, $n); $procs{cores} = $n; } } else { $procs{cores} = $n; } $procs{active_cores} = $procs{cores}; # compute chips if ($n > 1 && $cores) { $n = ceil($n / $cores); } # $n is now number of active chips # can't use this for procs{chips}, since we need total chips, not just active @keys = keys %physical_id; $procs{chips} = $#keys + 1; # if physical_id doesn't exist, chips will be 0, which is what we want, i.e. we don't know # without physical_id we have no way to guess at number of chips, we'll get it from sbmios } sub hide_drives { my($volume) = @_; foreach my $id (keys %{$drives{$volume}}) { $props{drives}{$id}{hidden} = 1; } } sub vol_to_drives { my($volume) = @_; my(@result); foreach my $id (keys %{$drives{$volume}}) { next if $props{drives}{$id}{hidden}; push(@result, $id); } return @result; } sub mptstatus { my($result) = 0; my($fh) = new IO::File; my($cmd); my($line); my($driver) = 'mptsas'; my(%seen); my(@controllers); my(%controller_to_vol); my($volume); system("which $mptstatus > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $have_mptstatus = 1; $debug_storage .= ">> $mptstatus\n"; # load mptctl if not already # this used to be done with the -i call below, but --autoload can cause failure system("$mptstatus --autoload > /dev/null 2>&1"); foreach my $key (keys %{$logical_to_os{lsi}{dev}}) { if ($key =~ /scsi(\d+)-(\d+)-(\d+)-(\d+)/) { push(@controllers, $3); $controller_to_vol{$3} = $logical_to_os{lsi}{dev}{$key}; } } foreach my $controller (@controllers) { $volume = $controller_to_vol{$controller}; $cmd = "$mptstatus -i $controller"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^ioc(\d+) vol_id (\d+) type (\S+), (\d+) phy, ([^,]+), state ([^,]+)/) { my($cid, $vid, $type, $phy, $size, $state) = ($1, $2, $3, $4, $5, $6); hide_drives($volume) unless $seen{$volume}++; $volumes{$volume}++; $props{volumes}{$volume}{raid} = canon_raid($type); $props{volumes}{$volume}{bytes} = parse_bytes($size, 1024); $props{volumes}{$volume}{status} = parse_volume_status($state); $got_mptstatus = 1; $result = 1; } elsif ($line =~ /^ioc(\d+) phy (\d+) scsi_id (\d+) (.{8} .{16}) (.{4}), ([^,]+), state (\S+)/) { $props{drives}{$drive_id}{volume} = $volume; $props{drives}{$drive_id}{type} = 'sas-volume'; $props{drives}{$drive_id}{model} = canon_drive($4); $props{drives}{$drive_id}{firmware} = $5; $props{drives}{$drive_id}{size} = parse_bytes($6, 1024); $props{drives}{$drive_id}{status} = parse_drive_status($7); $drives{$volume}{$drive_id}++; $drive_id++; $ndrives++; } } $fh->close; } return $result; } sub fio { # run fio-status # parse /proc/fusion/* $got_fio = 1; } sub mpt2 { sas2ircu(); } sub mpt { my($fh) = new IO::File; my($line); if (-e '/proc/mpt/summary') { $fh->open("< /proc/mpt/summary") || warn "open: /proc/mpt/summary: $!"; while ($line = <$fh>) { chomp($line); if ($line =~ /^(ioc\d+): (.*), FwRev=(\S+), Ports=\d+, MaxQ=(\d+), IRQ=(\d+)/) { my($ioc, $model, $fw, $maxq, $irq) = ($1, $2, $3, $4, $5); foreach my $pci (keys %{$irq_to_all_pci{$irq}}) { my($driver) = $pci_to_driver{$pci}; if ($driver && $driver =~ /mpt/) { $ioc_to_driver{$ioc} = $driver; $props{controllers}{$driver}{firmware} = sprintf("%d.%02d.%02d.%02d", hex(substr($fw, 0, 2)), hex(substr($fw, 2, 2)), hex(substr($fw, 4, 2)), hex(substr($fw, 6, 2))); } } } } $fh->close; } lsiutil() || mptstatus(); } # http://www.lsi.com/DistributionSystem/AssetDocument/SAS2_IR_User_Guide.pdf sub sas2ircu { my $result = 0; my $line; my %cids; my $dev; my $cmd; my $fh = new IO::File; $cmd = 'sas2ircu'; system("which $cmd > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $have_sas2ircu = 1; $debug_storage .= ">> $cmd\n"; $cmd = 'sas2ircu list'; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); last if ($line =~ /-------------/); } while ($line = <$fh>) { $debug_storage .= $line; chomp($line); last if ($line =~ /Completed Successfully/); if ($line =~ /\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/) { my $cid = $1; my $pci = canon_pci($5); $cids{$cid} = $pci_to_driver{$pci} || $pci; $got_sas2ircu++; } } $fh->close; foreach my $cid (keys %cids) { $dev = $cids{$cid}; $cmd = "sas2ircu $cid display"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); last if ($line =~ /^IR Volume information/i); if ($line =~ /^\s*BIOS version\s*: (.*)/i) { $props{controllers}{$dev}{'bios'} = $1; } elsif ($line =~ /^\s*Firmware version\s*: (.*)/i) { $props{controllers}{$dev}{'firmware'} = $1; } } my $volume; my %map; $volume = "$dev-spares"; $props{volumes}{$volume}{raid} = "JBOD"; my $vid; my $status; my $raid; my $bytes; my $ir_vol; my @phys; my %vid_to_volume; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); last if ($line =~ /^Physical device information/i); if ($line =~ /^((IR volume (\d+))|------------)/i) { my $next_ir_vol = $3; if (defined $ir_vol) { $volume = block_match({ 'size' => print_bytes($bytes, 1000, 1), 'raid' => $raid, 'controller' => $dev, 'sas_handle' => $vid, }); if ($volume) { # nuke what we already have hide_drives($volume); } else { $volume = "$dev-l$ir_vol"; } $vid_to_volume{$vid} = $volume; $volumes{$volume}++; $props{volumes}{$volume}{device} = $dev; $props{volumes}{$volume}{status} = $status; $props{volumes}{$volume}{raid} = $raid; $props{volumes}{$volume}{bytes} = $bytes; foreach my $phy (@phys) { if ($phy eq '0:0') { # drive is missing my($missing) = "$dev-missing"; $map{$phy} = $missing; $volumes{$missing}++; $props{volumes}{$missing}{device} = $dev; } else { $map{$phy} = $volume; } } undef @phys; } $ir_vol = $next_ir_vol; } elsif ($line =~ /^\s*Volume ID\s*: (\d+)/i) { $vid = $1; } elsif ($line =~ /^\s*Status of volume\s*: (.*) \((\S+)\)$/i) { $status = parse_volume_status($1); } elsif ($line =~ /^\s*RAID level\s*: (.*)/i) { $raid = canon_raid($1); } elsif ($line =~ /^\s*Size \(in MB\)\s*: (\d+)/i) { $bytes = parse_bytes("$1 MB", 1024); } elsif ($line =~ /^\s*PHY\[\d+\].* : (\d+):(\d+)$/) { push(@phys, "$1:$2"); } } my $device_type; my $enclosure; my $slot; my $state; my $size; my $vendor; my $model; my $firmware; my $serial; my $protocol; my $drive_type; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); last if ($line =~ /^Enclosure information/i); if ($line =~ /^Device is a (.*)/i) { $device_type = $1; } elsif ($line =~ /^\s*Enclosure #\s*: (\d+)/i) { $enclosure = $1; } elsif ($line =~ /^\s*Slot #\s*: (\d+)/i) { $slot = $1; } elsif ($line =~ /^\s*State\s*: (.*) \((\S+)\)$/i) { $state = $1; } elsif ($line =~ /^\s*Size \(in MB\).*: (\d+)\/(\d+)$/i) { $size = parse_bytes("$1 MB", 1024); } elsif ($line =~ /^\s*Manufacturer\s*: (.*)/i) { $vendor = $1; } elsif ($line =~ /^\s*Model Number\s*: (.*)/i) { $model = $1; } elsif ($line =~ /^\s*Firmware Revision\s*: (.*)/i) { $firmware = $1; } elsif ($line =~ /^\s*Serial No\s*: (.*)/i) { $serial = $1; } elsif ($line =~ /^\s*Protocol\s*: (.*)/i) { $protocol = $1; } elsif ($line =~ /^\s*Drive Type\s*: (.*)/i) { $drive_type = $1; if ($device_type eq 'Hard disk') { $status = parse_drive_status($state); if (defined $map{"$enclosure:$slot"}) { $volume = $map{"$enclosure:$slot"} } elsif ($status eq 'spare') { $volume = "$dev-spares"; } else { # JBOD device that we already have $volume = block_match({ 'vendor' => $vendor, 'model' => $model, 'firmware' => $firmware, 'serial' => $serial, 'controller' => $dev, 'size' => print_bytes($size, 1000, 1), }); if ($volume) { hide_drives($volume); } } if ($volume) { $volumes{$volume}++; $ndrives++; $drives{$volume}{$drive_id}++; $props{drives}{$drive_id}{volume} = $volume; $props{drives}{$drive_id}{status} = $status; $props{drives}{$drive_id}{size} = $size; $props{drives}{$drive_id}{model} = canon_drive("$vendor-$model"); $props{drives}{$drive_id}{firmware} = $firmware; $props{drives}{$drive_id}{serial} = $serial; $props{drives}{$drive_id}{protocol} = $protocol; $props{drives}{$drive_id}{type} = $drive_type; $props{drives}{$drive_id}{location} = "enclosure=$enclosure,slot=$slot"; $drive_id++; } } } } $fh->close; $cmd = "sas2ircu $cid status"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^\s*Volume ID\s*: (\d+)/i) { $vid = $1; $volume = $vid_to_volume{$vid}; } elsif ($line =~ /^\s*Current Operation\s*: (.*)/i) { my($op) = $1; if ($op eq 'Synchronize') { $props{volumes}{$volume}{status} = parse_volume_status($op); } } } $fh->close; } } # ftp://ftp.lsil.com/HostAdapterDrivers/linux/lsiutil/LSIUtil_UG.pdf # http://www.t13.org/Documents/UploadedDocuments/docs2007/D1699r4a-ATA8-ACS.pdf # todo # - get sas address for drives and device from option 70 # - get link speed from option 68 sub lsiutil { my($result) = 0; my($cmd) = 'lsiutil'; my($fh) = new IO::File; my($line); my(%ioc); my($host); my($vol); my(%phys_to_vol); my($phys, $bus, $target); my(%ata_drives); # assumes linux for %ioc presence return 0 unless ($os_type eq 'linux'); system("which $cmd > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $have_lsiutil = 1; $cmd = 'lsiutil'; trace($cmd); $fh->open("$cmd < /dev/null 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); last if ($line =~ /Port Name/); } while ($line = <$fh>) { $debug_storage .= $line; chomp($line); last if ($line =~ /^\s*$/); if ($line =~ /^\s*(\d+)\..*(ioc\d+)/) { $ioc{$1} = $2; } } $fh->close; foreach my $controller (keys %ioc) { my($driver) = $ioc_to_driver{$ioc{$controller}} || 0; $cmd = "lsiutil -p$controller 1 42 -a 1,2,0 21"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); # from menu 1 if ($line =~ /Firmware.*version is MPTFW-(\S+)/) { $props{controllers}{$driver}{firmware} = $1; } elsif ($line =~ /BIOS.*version is MPTBIOS-(\S+)/) { $props{controllers}{$driver}{bios} = $1; } # from menu 42 if ($line =~ /is SCSI host (\d+)/) { $host = $1; } # from menu 21 -> 1 if ($line =~ /^Volume (\d+) is Bus (\d+) Target (\d+), Type (\S+)/) { my($raid); ($bus, $target, $raid) = ($2, $3, $4); my($key) = "scsi$host-$bus-$target-0"; $vol = "mpt$host-b$bus-t$target"; if (defined $logical_to_os{all}{dev}{$key}) { $vol = $logical_to_os{all}{dev}{$key}; } else { # if only one lsi device, wire it my(@keys) = keys %{$logical_to_os{lsi}{dev}}; if ($#keys == 0) { $key = $keys[0]; $vol = $logical_to_os{lsi}{dev}{$key}; } } $volumes{$vol}++; $props{volumes}{$vol}{raid} = canon_raid($raid); # remove info we got from /proc/scsi/scsi hide_drives($vol); } elsif ($line =~ /^\s*Volume WWID:\s*(\S+)/) { $props{volumes}{$vol}{wwn} = $1; } elsif ($line =~ /^\s*Volume State:\s*(.*)/) { $props{volumes}{$vol}{status} = parse_volume_status($1); } elsif ($line =~ /^\s*Volume Settings:\s*(.*)/) { my($settings) = $1; foreach my $setting (split(/,\s*/, $settings)) { if ($setting =~ /write caching (\S+)/) { $props{volumes}{$vol}{drive_write_cache} = parse_drive_cache($1); } } } elsif ($line =~ /^\s*Volume Size (\d+ \S+)(, Stripe Size (\d+ \S+))?,/) { $props{volumes}{$vol}{bytes} = parse_bytes($1, 1024); $props{volumes}{$vol}{stripe} = parse_bytes($3, 1024) if ($3); } elsif ($line =~ /(Member (\d+)|Primary|Secondary) is PhysDisk (\d+)/) { $phys_to_vol{$3} = $vol; # from menu 21 -> 2 } elsif ($line =~ /^PhysDisk (\d+) is Bus (\d+) Target (\d+)/) { ($phys, $bus, $target) = ($1, $2, $3); $vol = $phys_to_vol{$phys}; } elsif ($line =~ /PhysDisk belongs to Hot Spare Pools:\s*(\d+)/) { $vol = "mpt$host-spares"; $volumes{$vol}++; } elsif ($line =~ /PhysDisk Size ([^,]+), Inquiry Data:\s*(.*)/) { my($size, $inquiry) = ($1, $2); my($firm) = substr($inquiry, -4); $inquiry = substr($inquiry, 0, -4); $props{drives}{$drive_id}{volume} = $vol; $props{drives}{$drive_id}{type} = 'scsi-disk'; $props{drives}{$drive_id}{model} = canon_drive($inquiry); $props{drives}{$drive_id}{firmware} = $firm; $props{drives}{$drive_id}{size} = parse_bytes($size, 1024); if ($inquiry =~ /^ATA/) { $ata_drives{$drive_id}{bus} = $bus; $ata_drives{$drive_id}{target} = $target; } $drives{$vol}{$drive_id}++; $drive_id++; $ndrives++; } elsif ($line =~ /PhysDisk State:\s*(\S.*)/) { $props{drives}{$drive_id}{status} = parse_drive_status($1); } $got_lsiutil = 1; $result = 1; } $fh->close; foreach my $id (keys %ata_drives) { $target = $ata_drives{$id}{target}; $cmd = "lsiutil -p$controller -a 10,$target,,0 20"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { last if ($line =~ /Identify Device Data returned/); } my($data) = ''; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^\s*\d+ : (([0-9a-f]{4} ){1,10})/) { $data .= $1; } } $fh->close; $data =~ s/\s+//g; $props{drives}{$id}{serial} = clean_white(pack("H*", substr($data, 10*4, 10*4))); $props{drives}{$id}{firmware} = clean_white(pack("H*", substr($data, 23*4, 4*4))); $props{drives}{$id}{model} = canon_drive(clean_white(pack("H*", substr($data, 27*4, 20*4)))); $props{drives}{$id}{type} = 'ata-disk'; my($hdparm) = ''; foreach my $i (0 .. 31) { foreach my $j (0 .. 7) { $hdparm .= substr($data, ($i*32) + ($j*4), 4); } chop($hdparm); $hdparm .= "\n"; } } } return $result; } sub mptutil { my($result) = 0; my($fh) = new IO::File; my($cmd); my($line); my($dev); my($str); my(@adapters); my(%vid_to_vol); my($vol); while ($dmesg_buf =~ /^(mpt\d+): (.*)/gm) { ($dev, $str) = ($1, $2); if ($str =~ /^F\/W Version=(.*)/) { $props{controllers}{$dev}{firmware} = $1; } elsif ($str =~ /^MPI Version=(.*)/) { $props{controllers}{$dev}{mpi} = $1; } } system("which $mptutil > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $have_mptutil = 1; $debug_storage .= ">> $mptutil\n"; $cmd = "$mptutil show adapter"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^(mpt(\d+))\s+Adapter/) { $dev = $1; push(@adapters, $2); $got_mptutil = 1; $result = 1; } elsif ($line =~ /^\s*battery backup: (.*)/i) { $props{controllers}{$dev}{'bbu'} = ($1 eq "present"); } elsif ($line =~ /^\s*onboard memory: (.*)/i) { $props{controllers}{$dev}{cache}{size} = parse_bytes($1, 1024); } } $fh->close; $cmd = "$mptutil show drives"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^(mpt\d+) physical drives:/i) { $vol = "$1-spares"; } elsif ($line =~ /\b(SPARE|UNCONFIGURED)\b.*<([^>]+) ([^>\s]+)> (\S+)/) { my($model, $firm, $int) = ($2, $3, $4); $model = canon_drive($model) || "Unknown"; $props{volumes}{$vol}{raid} = "JBOD"; $drives{$vol}{$drive_id}++; $props{drives}{$drive_id}{type} = 'scsi-disk'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{firmware} = $firm if ($firm); $props{drives}{$drive_id}{interface} = $int; $props{drives}{$drive_id}{volume} = $vol; $drive_id++; $volumes{$vol}++; $ndrives++; } } $fh->close; foreach my $adapter (@adapters) { my($array); my(%array_to_vol); $dev = "mpt$adapter"; $cmd = "$mptutil -u $adapter show firmware"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^BIOS\s+(\S+)/) { $props{controllers}{$dev}{'bios'} = $1; } elsif ($line =~ /^APP\s+(\S+)/) { $props{controllers}{$dev}{'firmware'} = $1; } } $fh->close; $cmd = "$mptutil -u $adapter show volumes"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^\s*((da)?(\d+))\s+\(([^\)]*)\)\s+(\S+)\s+(\S*)\s+(OPTIMAL|DEGRADED|FAILED|MISSING|VSTATE \S+)\s+(\S+)/) { my($vid, $da, $num, $size, $dwc) = ($1, $2, $3, parse_bytes($4, 1024), $8); if ($da) { $vol = $vid; } else { my($match) = block_match({ 'size' => print_bytes($size, 1000, 1), 'controller' => $dev, }); $vol = $match if ($match); } $vid_to_vol{$vid} = $vol; $props{volumes}{$vol}{drive_write_cache} = parse_drive_cache($dwc); } } $fh->close; $cmd = "$mptutil -u $adapter show config"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^\s*volume ((da)?(\d+)) \(([^\)]*)\) (\S+) (\S+) (\S+)/) { $vol = $vid_to_vol{$1} || "da$3"; hide_drives($vol); $props{volumes}{$vol}{bytes} = parse_bytes($4, 1024); $props{volumes}{$vol}{raid} = $5; my($stripe, $status) = ($6, $7); if ($stripe =~ /^\d+/) { $props{volumes}{$vol}{stripe} = parse_bytes($stripe, 1024); $props{volumes}{$vol}{status} = parse_volume_status($status); } else { $props{volumes}{$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; } } } $fh->close; $cmd = "$mptutil -u $adapter show config"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; while ($line = <$fh>) { chomp($line); if ($line =~ /^\s*volume ((da)?(\d+))/) { $vol = $vid_to_vol{$1} || "da$3"; } elsif ($line =~ /^\s*spare (\d+) \((.*)\) ([^<]+) <([^>]+) ([^>\s]+)> (\S+)/) { my($size, $status, $model, $firm, $int) = ($2, $3, $4, $5, $6); $model = canon_drive($model) || "Unknown"; my($spares) = "$dev-spares"; $drives{$spares}{$drive_id}++; $props{drives}{$drive_id}{type} = 'scsi-disk'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{size} = parse_bytes($size, 1024); $props{drives}{$drive_id}{firmware} = $firm if ($firm); $props{drives}{$drive_id}{interface} = $int; $props{drives}{$drive_id}{volume} = $spares; $drive_id++; $volumes{$spares}++; $props{volumes}{$spares}{raid} = "JBOD"; $ndrives++; if ($status ne "ONLINE") { $props{volumes}{$spares}{failed}++; } } elsif ($line =~ /^\s*drive (da)?(\d+) \((.*)\) ([^<]+) <([^>]+) ([^>\s]+)> (\S+)/) { my($da, $num, $size, $status, $model, $firm, $int) = ($1, $2, $3, $4, $5, $6, $7); $model = canon_drive($model) || "Unknown"; my($id) = 0; if ($da) { $vol = "da$num"; my(@drives) = vol_to_drives($vol); if ($#drives == 0) { $id = $drives[0]; } else { hide_drives($vol); } } if (!$id) { $id = $drive_id; $drive_id++; } $drives{$vol}{$id}++; $props{drives}{$id}{type} = 'scsi-disk'; $props{drives}{$id}{model} = $model; set_unless($props{drives}{$id}, 'size', parse_bytes($size, 1024)); # not accurate here $props{drives}{$id}{firmware} = $firm if ($firm); $props{drives}{$id}{interface} = $int; $props{drives}{$id}{status} = parse_drive_status($status); $props{drives}{$id}{volume} = $vol; $volumes{$vol}++; $ndrives++; if ($status eq "REBUILD") { $props{volumes}{$vol}{rebuild}++; } elsif ($status eq "MISSING") { $props{volumes}{$vol}{missing}++; } elsif ($status ne "ONLINE") { # e.g. OFFLINE, FAILED $props{volumes}{$vol}{failed}++; } } } $fh->close; } } sub mfiutil { my($result) = 0; my($fh) = new IO::File; my($cmd); my($line); my($dev); my(@adapters); my($vol, @vols); my($try); # MegaCli docs at: # http://www.lsi.com/DistributionSystem/AssetDocument/files/docs/techdocs/storage_stand_prod/sas/mr_sas_sw_ug.pdf system("which $mfiutil > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $have_mfiutil = 1; $debug_storage .= ">> $mfiutil\n"; $try = 0; while (1) { $cmd = "$mfiutil -u $try show adapter"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; my($found) = 0; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^(mfi(\d+))\s+Adapter/) { $dev = $1; push(@adapters, $2); $got_mfiutil = 1; $result = 1; $found = 1; } elsif ($line =~ /^\s*firmware: (.*)/i) { $props{controllers}{$dev}{'package'} = $1; } elsif ($line =~ /^\s*battery backup: (.*)/i) { $props{controllers}{$dev}{'bbu_status'} = parse_bbu_status($1); } elsif ($line =~ /^\s*onboard memory: (.*)/i) { $props{controllers}{$dev}{cache}{size} = parse_bytes($1, 1024); } } $fh->close; last if !$found; $try++; } foreach my $adapter (@adapters) { my($array); my(%array_to_vol); $dev = "mfi$adapter"; $cmd = "$mfiutil -u $adapter show battery"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /Serial Number: (.*)/) { $props{controllers}{$dev}{bbu_serial} = $1; } elsif ($line =~ /Manufacturer: (.*)/) { $props{controllers}{$dev}{bbu_manufacturer} = $1; } elsif ($line =~ /Manufacture Date: (.*)/) { $props{controllers}{$dev}{bbu_date} = parse_date($1); } elsif ($line =~ /Model: (.*)/) { $props{controllers}{$dev}{bbu_model} = $1; } elsif ($line =~ /Chemistry: (.*)/) { $props{controllers}{$dev}{bbu_chemistry} = $1; } elsif ($line =~ /Current Charge: (.*)/) { $props{controllers}{$dev}{bbu_charge} = $1; } } $fh->close; $cmd = "$mfiutil -u $adapter show patrol"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /Operation Mode: (.*)/) { $props{controllers}{$dev}{patrol_mode} = parse_patrol_mode($1); } elsif ($line =~ /Runs Start Every (\d+ seconds)/i) { $props{controllers}{$dev}{patrol_interval} = parse_seconds($1); } } $fh->close; $cmd = "$mfiutil -u $adapter show drives"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^(mfi\d+) physical drives:/i) { $vol = "$1-spares"; } elsif ($line =~ /\b(SPARE|UNCONFIGURED)\b.*<([^>]+) ([^>\s]+)> (\S+)/) { my($model, $firm, $int) = ($2, $3, $4); $model = canon_drive($model) || "Unknown"; $props{volumes}{$vol}{raid} = "JBOD"; $drives{$vol}{$drive_id}++; $props{drives}{$drive_id}{type} = 'scsi-disk'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{firmware} = $firm if ($firm); $props{drives}{$drive_id}{interface} = $int; $props{drives}{$drive_id}{volume} = $vol; $drive_id++; $volumes{$vol}++; $ndrives++; } } $fh->close; $cmd = "$mfiutil -u $adapter show firmware"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^BIOS\s+(\S+)/) { $props{controllers}{$dev}{'bios'} = $1; } elsif ($line =~ /^APP\s+(\S+)/) { $props{controllers}{$dev}{'firmware'} = $1; } } $fh->close; $cmd = "$mfiutil -u $adapter show config"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^\s*volume ((mfid)?(\d+)) \(([^\)]*)\) (\S+) (\S+) (\S+)/) { push(@vols, $1); $vol = "mfid$3"; hide_drives($vol); $props{volumes}{$vol}{bytes} = parse_bytes($4, 1024); $props{volumes}{$vol}{raid} = $5; my($stripe, $status) = ($6, $7); if ($stripe =~ /^\d+/) { $props{volumes}{$vol}{stripe} = parse_bytes($stripe, 1024); $props{volumes}{$vol}{status} = parse_volume_status($status); } else { $props{volumes}{$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; $props{volumes}{$vol}{spans}++; } } } $fh->close; $cmd = "$mfiutil -u $adapter show config"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; while ($line = <$fh>) { chomp($line); if ($line =~ /^\s*array (\d+) of (\d+) drives/) { $array = $1; $vol = $array_to_vol{$array}; } elsif ($line =~ /^\s*drive (\d+) \((.*)\) (\S+) <(.*?) (\S+)( serial=(\S+))?> (\S+)( enclosure (\d+), slot (\d+))?/) { my($size, $status, $model, $firm, $serial, $int, $enc, $slot) = ($2, $3, $4, $5, $7, $8, $10, $11); $model = canon_drive($model) || "Unknown"; $drives{$vol}{$drive_id}++; $props{drives}{$drive_id}{type} = 'scsi-disk'; $props{drives}{$drive_id}{size} = parse_bytes($size, 1024); $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{firmware} = $firm if (defined $firm); $props{drives}{$drive_id}{serial} = $serial if (defined $serial); $props{drives}{$drive_id}{interface} = $int; $props{drives}{$drive_id}{location} = "enclosure=$enc,slot=$slot" if (defined $enc); $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{volumes}{$vol}{rebuild}++; } elsif ($status eq "MISSING") { $props{volumes}{$vol}{missing}++; } elsif ($status ne "ONLINE") { # e.g. OFFLINE, FAILED $props{volumes}{$vol}{failed}++; } } elsif ($line =~ /^\s*volume/) { last; } } $fh->close; foreach my $vol (@vols) { $cmd = "$mfiutil -u $adapter cache $vol"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /I\/O caching: (.*)/) { my($caching) = $1; $props{volumes}{$vol}{read_cache}{enable} = 1 if ($caching =~ /reads/); $props{volumes}{$vol}{write_cache}{enable} = 1 if ($caching =~ /writes/); } elsif ($line =~ /write caching: (.*)/) { $props{volumes}{$vol}{write_cache}{policy} = parse_cache_policy($1); } elsif ($line =~ /read ahead: (.*)/) { $props{volumes}{$vol}{read_ahead} = parse_read_ahead_policy($1); } elsif ($line =~ /drive write cache: (.*)/) { $props{volumes}{$vol}{drive_write_cache} = parse_drive_cache($1); } elsif ($line =~ /Cache Disabled Due to Dead Battery/) { # this comes at end of output, ignore previous settings $props{volumes}{$vol}{read_cache}{enable} = 0; $props{volumes}{$vol}{write_cache}{enable} = 0; $props{volumes}{$vol}{read_ahead} = parse_read_ahead_policy('none'); $props{volumes}{$vol}{write_cache}{policy} = parse_cache_policy('write-through'); $props{controllers}{$dev}{'bbu_status'} = parse_bbu_status('dead'); } } $fh->close; } } } sub omreport { my($omreport) = 'omreport'; my($result) = 0; my($line); my(%controllers); my($device); my(%seen); my(%count); my($fh) = new IO::File; my($cmd); my($controller); return 1 if ($got_omreport); system("which $omreport > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $have_omreport = 1; $debug_storage .= ">> $omreport\n"; $count{megaraid} = 0; $count{megaraid_sas} = 0; $cmd = "$omreport storage controller"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^ID\s*:\s*(\d+)\s*$/) { $controller = $1; $got_omreport = 1; $device = "unknown"; $result = 1; } elsif ($line =~ /^Name\s*:\s*(.*)/) { my($name) = $1; if ($name =~ /PERC (4|3\/QC)/) { $device = 'megaraid' . $count{megaraid}++; $controllers{$controller} = $device; } elsif ($name =~ /PERC 3/) { $device = 'aacraid' . $count{aacraid}++; $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{controllers}{$device}{'package'} = $1 unless ($props{controllers}{$device}{'firmware'}); } elsif ($line =~ /^Cache Memory Size\s*:\s*(.*)/) { $props{controllers}{$device}{cache}{size} = parse_bytes($1, 1024); } } $fh->close; foreach my $controller (keys %controllers) { $device = $controllers{$controller}; $cmd = "$omreport storage battery controller=$controller"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^Status\s*:\s*(\S+)/) { $props{controllers}{$device}{'bbu_status'} = parse_bbu_status($1); } } $fh->close; my($status, $read_policy, $write_policy) = ('', '', ''); my($volume, $name, $raid, $bytes, $stripe, $virtual) = (0, 0, 0, 0, 0, 0); my(%virtuals); $cmd = "$omreport storage vdisk controller=$controller"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^ID\s*:\s*(\d+)/) { $virtual = $1; } elsif ($line =~ /^Layout\s*:\s*(.*)/) { $raid = canon_raid($1); } elsif ($line =~ /^State\s*:\s*(.*)/) { $status = parse_volume_status($1); } elsif ($line =~ /^Read Policy\s*:\s*(.*)/) { $read_policy = $1; } elsif ($line =~ /^Write Policy\s*:\s*(.*)/) { $write_policy = $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($2, 1024); } elsif ($line =~ /^\s*$/) { if ($name) { $volume = "$device-l$virtual" unless $volume; $virtuals{$virtual} = $volume; $volumes{$volume}++; $props{volumes}{$volume}{bytes} = $bytes; $props{volumes}{$volume}{raid} = $raid; $props{volumes}{$volume}{stripe} = $stripe; $props{volumes}{$volume}{status} = $status; $props{volumes}{$volume}{device} = $device; # remove info we got from /proc/scsi/scsi hide_drives($volume) unless $seen{$volume}++; ($volume, $name, $raid, $bytes, $stripe, $virtual) = (0, 0, 0, 0, 0, 0); } } } $fh->close; foreach my $virtual (keys %virtuals) { $volume = $virtuals{$virtual}; my($have_size) = $props{volumes}{$volume}{bytes}; my($vendor, $model, $serial, $firmware, $year, $week, $day, $wwn) = ('', '', '', '', '', '', '', ''); $cmd = "$omreport storage adisk controller=$controller vdisk=$virtual"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); $line =~ s/\s+$//; $line =~ s/\b(Not Available)\b//; if ($line =~ /^State\s*:\s*(.*)/) { $status = parse_drive_status($1); $props{volumes}{$volume}{failed}++ if ($status =~ /(failed|offline)/); } elsif ($line =~ /^Hot Spare\s*:\s*(.*)/) { $props{volumes}{$volume}{spare}++ if ($1 =~ /Yes|Dedicated/); } 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{volumes}{$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}{type} = 'scsi-disk'; $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}{status} = $status; $props{drives}{$drive_id}{wwn} = $wwn if ($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) = ('', ''); } } $fh->close; } } return $result; } sub arcconf { my($result) = 0; my($line); my(@controllers); my($volume); my(%mapping); my(%seen); my($driver) = "aacraid"; my($count) = 0; my($device); my($fh) = new IO::File; my($cmd); # arcconf docs at: # http://download.adaptec.com/pdfs/user_guides/Command_Line_Interface_for_Internal_RAID_Users_Guide_09_06.pdf # http://download.adaptec.com/pdfs/user_guides/CLI_v6_10_Users_Guide.pdf system("which $arcconf > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $have_arcconf = 1; $debug_storage .= ">> $arcconf\n"; $cmd = "$arcconf getversion"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^Controller #(\d+)/) { push(@controllers, int($1)); $got_arcconf++; $result++; } } $fh->close; foreach my $controller (@controllers) { $device = $driver . $count++; $cmd = "$arcconf getconfig $controller"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^\s*BIOS\s*:\s*(.*)/) { # seems to always match firmware, so ignore this #$props{controllers}{$device}{'bios'} = $1; } elsif ($line =~ /^\s*Firmware\s*:\s*(.*)/) { $props{controllers}{$device}{'firmware'} = $1; } elsif ($line =~ /^\s*Driver\s*:\s*(.*)/) { $props{controllers}{$device}{'driver'} = $1; } elsif ($line =~ /^\s*Controller Model\s*:\s*(.*)/) { $props{controllers}{$device}{'model'} = $1; } elsif ($line =~ /^\s*Controller Serial Number\s*:\s*(.*)/) { $props{controllers}{$device}{'serial'} = $1; } elsif ($line =~ /^\s*Installed memory\s*:\s*(.*)/) { $props{controllers}{$device}{cache}{size} = parse_bytes($1, 1024); } elsif ($line =~ /^\s*Copyback\s*:\s*(.*)/) { if (parse_enable($1)) { $props{controllers}{$device}{write_cache}{policy} = parse_cache_policy('write-back'); } else { $props{controllers}{$device}{write_cache}{policy} = parse_cache_policy('write-through'); } } elsif ($line =~ /^\s*Background consistency check\s*:\s*(.*)/) { $props{controllers}{$device}{patrol_mode} = parse_patrol_mode($1); } elsif ($line =~ /^\s*Status\s*:\s*(.*)/) { $props{controllers}{$device}{'bbu_status'} = parse_bbu_status($1); } last if ($line =~ /^Logical device information/); } while ($line = <$fh>) { $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 = "$device-l$1"; # our first attempt at volume guess, so use possible_raid_vols # when we have device name below, we have better shot my(@keys) = keys %possible_raid_vols; if ($#keys == 0) { $volume = $keys[0]; # remove earlier info hide_drives($volume); } } elsif ($line =~ /Logical device name.*: (.*)/) { my($logical) = $1; # if only one vol, map it my(@keys) = keys %{$logical_to_os{other}{dev}}; if ($#keys == 0) { $logical = $keys[0]; } if ($logical_to_os{other}{dev}{$logical}) { $volume = $logical_to_os{other}{dev}{$logical}; # remove info we got from /proc/scsi/scsi hide_drives($volume); } } elsif ($line =~ /RAID level.*: (.*)/) { $props{volumes}{$volume}{raid} = "RAID-$1"; } elsif ($line =~ /Status of logical device.*: (.*)/) { $props{volumes}{$volume}{status} = parse_volume_status($1); } elsif ($line =~ /Size.*: (.*)/) { $props{volumes}{$volume}{bytes} = parse_bytes($1, 1024); } elsif ($line =~ /Stripe-unit size.*: (.*)/) { $props{volumes}{$volume}{stripe} = parse_bytes($1, 1024); } elsif ($line =~ /MaxIQ cache setting\s*: (.*)/) { $props{volumes}{$volume}{maxiq_enable} = parse_enable($1); } elsif ($line =~ /Read-cache mode.*: (.*)/) { $props{volumes}{$volume}{rcache_enable} = parse_enable($1); } elsif ($line =~ /Write-cache mode.*: (.*)/) { $props{volumes}{$volume}{write_cache}{enable} = parse_enable($1); $props{volumes}{$volume}{write_cache}{policy} = parse_cache_policy($1); } elsif ($line =~ /(Group (\d+), )?Segment \d+.*: .*\((\d+),(\d+)\)/) { my($group, $channel, $id) = ($2, $3, $4); $mapping{"$channel,$id"} = $volume; $props{volumes}{$volume}{spans}++ if (defined($group) && !$seen{"group-$group"}++); } elsif ($line =~ /Stripe order \(Channel,Device\)\s*:\s*(.+)/) { my(@pairs) = split(' ', $1); foreach my $pair (@pairs) { my($channel, $id) = split(/,/, $pair); if (defined($channel) && defined($id)) { $mapping{"$channel,$id"} = $volume; } } } } my($vendor, $model, $state, $channel, $maxiq, $ncq); my($id) = 0; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^\s*Device #(\d+)/ || $line =~ /^\s*$/) { if ($id) { # process last drive if ($mapping{$channel}) { $volume = $mapping{$channel}; } elsif ($maxiq) { $volume = "$device-maxiq-cache"; $props{volumes}{$volume}{raid} = "JBOD"; } else { $volume = "$device-spares"; $props{volumes}{$volume}{raid} = "JBOD"; } $ndrives++; $drives{$volume}{$drive_id}++; $props{drives}{$id}{type} = 'scsi-disk'; $props{drives}{$id}{model} = $model; $props{drives}{$id}{volume} = $volume; if ($ncq) { $props{drives}{$id}{ncq_support} = $ncq; $props{drives}{$id}{ncq_enable} = $ncq; } $drive_id++; $volumes{$volume}++; if ($state =~ /Rebuild/) { $props{volumes}{$volume}{rebuild}++; } elsif ($state ne "Online" && $state ne "Ready") { $props{volumes}{$volume}{failed}++; } } $id = 0; } elsif ($line =~ /^\s*Device is (.*)/) { my($type) = $1; if ($type =~ /Hard drive/) { $id = $drive_id; } else { $id = 0; # not a real id, effectively /dev/null } } elsif ($line =~ /^\s*State\s+: (.*)/) { $state = $1; $props{drives}{$id}{status} = parse_drive_status($1); } elsif ($line =~ /^\s*Reported Channel,Device(\(T:L\))?\s+: (\d+,\d+)/) { $channel = $2; } elsif ($line =~ /^\s*Firmware\s+: (.*)/) { $props{drives}{$id}{firmware} = $1; } elsif ($line =~ /^\s*Serial number\s+: (.*)/) { $props{drives}{$id}{serial} = $1; } elsif ($line =~ /^\s*World-wide name\s+: (.*)/) { $props{drives}{$id}{wwn} = $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"); } elsif ($line =~ /^\s*MaxIQ Cache Assigned\s+: (.*)/) { $maxiq = parse_enable($1); } elsif ($line =~ /^\s*NCQ status\s+: (.*)/) { $ncq = parse_enable($1); } } $fh->close; } return $result; } sub megacli_pd { my($data, $volume, $ver) = @_; my($raw, $status, $wwn, $type, $enclosure, $slot, $device, $speed, $interface); if ($data =~ /^Raw Size\s*:.*\[0x(\S+) Sectors\]/im) { $raw = bighex($1) * 512; } elsif ($data =~ /^Raw Size\s*:\s*(\S+)/im) { $raw = parse_bytes($1, 1024); } $status = parse_drive_status($1) if ($data =~ /^Firmware state\s*:\s+(.*)/m); $wwn = $1 if ($data =~ /^SAS Address\(0\)\s*:\s*(\S+)/m); $type = $1 if ($data =~ /^PD Type\s*:\s*(\S+)/m); $enclosure = $1 if ($data =~ /^Enclosure Device ID\s*:\s*(\d+)/im); $slot = $1 if ($data =~ /^Slot Number\s*:\s*(\d+)/im); $device = $1 if ($data =~ /^Device Id\s*:\s*(\d+)/im); $speed = parse_drive_speed($1) if ($data =~ /^Device Speed\s*:\s*(.*)/im); $interface = parse_drive_interface($1) if ($data =~ /^PD Type\s*:\s*(.*)/im); if ($data =~ /^Inquiry Data\s*: (.*)/m) { my($inquiry) = $1; my(@inquiry) = split(' ', $inquiry); my($model, $serial, $firm); if ($ver gt '004000000' && $type eq 'SATA') { # megacli v4 uses this format for SATA, older versions don't have all of the data # Inquiry Data: GTF002PBGZKX6FHitachi HUA721010KLA330 GKAOA9N1 # Inquiry Data: CVEM8435019E080DGN INTEL SSDSA2MH080G1GN 045C8610 $serial = clean_white(substr($inquiry, 0, 20)); $model = canon_drive(substr($inquiry, 20, -8)); $firm = clean_white(substr($inquiry, -8)); } elsif ($#inquiry >= 2) { # these have all been verified to follow this format: # 1. Inquiry Data: SEAGATE ST3146855SS S5273LN3FDD8 # 2. Inquiry Data: ATA INTEL SSDSA2MH088610CVEM8435000K080DGN # 3. Inquiry Data: MAXTOR ATLAS10K5_073SASBP00J211CMGK A # 4. Inquiry Data: ATA Hitachi HUA72101A9N1 GTF002PBGZJYWF # 5. Inquiry Data: ATA Maxtor 6L080M0 1G10L20XPFJH # 6. Inquiry Data: FUJITSU MBA3147RC D306BJA3P8907KC2 # 7. Inquiry Data: HP DF0300B8053 HPD43QP1ENN1 # 8. Inquiry Data: HITACHI HUS153030VLS300 A4C2JHW5BY4C # 9. Inquiry Data: ATA ST3250620NS 3BKT # a. Inquiry Data: ATA STT_FTM56GX25H 1370P560127-QCIX-5069016 # b. Inquiry Data: ATA OCZ-VERTEX v1.101370ZI164032I7R946NKPV32 # c. Inquiry Data: ATA WDC WD800JD-75MS1E04 WD-WMAM9NK41406 # d. Inquiry Data: ATA WDC WD1002FBYS-10C06 WD-WMAWD-WMATV0541299 # e. Inquiry Data: ATA Hitachi HUA72202A28A JK1130YAH69RYT # ^^^^ # firm # ^^^^^^^^^^^^^^^^^^ # serial $model = canon_drive(substr($inquiry, 0, 24)); $firm = clean_white(substr($inquiry, 24, 4)); $serial = clean_white(substr($inquiry, 28)); $serial =~ s/\s+.*//; # cleanup case #3 } else { # only one example of this so far, just guessing here # 1. Inquiry Data: IBM-ESXSCBRBA146C3ETS0 NC495P4WM2B4ACBXSA495 $model = canon_drive($inquiry[0]); $serial = $inquiry[1]; } $ndrives++; $drives{$volume}{$drive_id}++; $props{drives}{$drive_id}{type} = 'scsi-disk'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{volume} = $volume; $props{drives}{$drive_id}{serial} = $serial; $props{drives}{$drive_id}{firmware} = $firm if ($firm); if ($type) { $props{drives}{$drive_id}{interface} = $type; } elsif ($inquiry =~ /^ATA/) { $props{drives}{$drive_id}{interface} = 'SATA'; } $props{drives}{$drive_id}{wwn} = $wwn; $props{drives}{$drive_id}{size} = $raw; $props{drives}{$drive_id}{status} = $status; $props{drives}{$drive_id}{speed} = $speed if ($speed); $props{drives}{$drive_id}{interface} = $interface if ($interface); my($location) = ''; $location .= "enclosure=$enclosure," if (defined $enclosure); $location .= "slot=$slot," if (defined $slot); $location .= "device=$device" if (defined $device); $location =~ s/,$//; $props{drives}{$drive_id}{location} = $location if ($location); $drive_id++; $volumes{$volume}++; $props{volumes}{$volume}{failed}++ if ($status =~ /(failed|offline)/); $props{volumes}{$volume}{spare}++ if ($status eq "spare"); $props{volumes}{$volume}{rebuild}++ if ($status eq "rebuilding"); } } sub megacli { my(@adapters); my($result) = 0; my($line); my($volume) = "NA"; my(%seen); my($driver) = 'megaraid_sas'; my($controller) = $driver; my($fh) = new IO::File; my($cmd); # MegaCli docs at: # http://www.lsi.com/DistributionSystem/AssetDocument/files/docs/techdocs/storage_stand_prod/sas/mr_sas_sw_ug.pdf # http://linux.dell.com/files/whitepapers/solaris/Managing_PERC6_0714.pdf # ftp://ftp.software.ibm.com/systems/support/system_x_pdf/ibm_doc_sraidmr_10.03_software-user-guide.pdf my($megacli) = 'MegaCli'; system("which $megacli > /dev/null 2>&1"); if ($CHILD_ERROR) { $megacli = 'MegaCli64'; system("which $megacli > /dev/null 2>&1"); if ($CHILD_ERROR) { $megacli = 'megacli'; system("which $megacli > /dev/null 2>&1"); return $result if ($CHILD_ERROR); } } $have_megacli = 1; $debug_storage .= ">> $megacli\n"; if (-d "/opt/lsi/pegasus/lib") { # some verions of megacli need these libs $megacli = "LD_LIBRARY_PATH=/opt/lsi/pegasus/lib $megacli"; } my($ver) = "000000000"; $line = `$megacli -v 2> /dev/null`; if ($line =~ /Ver (\d+)\.(\d+)\.(\d+)/) { $ver = sprintf("%03d%03d%03d", $1, $2, $3); } $debug_storage .= "version $ver\n"; my($last); my($section) = ''; $cmd = "$megacli -AdpAllInfo -aAll"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^Adapter\s+\#(\d+)/) { my $adapter = int($1); $controller = "$driver$adapter"; push(@adapters, $adapter); $got_megacli = 1; $result = 1; } elsif ($line =~ /^FW Package Build\s*:\s*(\S+)/i) { $props{controllers}{$controller}{'package'} = $1; } elsif ($line =~ /^FW Version\s*:\s*(\S+)/i) { $props{controllers}{$controller}{'firmware'} = $1; } elsif ($line =~ /^BIOS Version\s*:\s*(\S+)/i) { $props{controllers}{$controller}{'bios'} = $1; } elsif ($line =~ /^Serial No\s*:\s*(\S+)/i) { $props{controllers}{$controller}{'serial'} = $1; } elsif ($section eq 'HW Configuration' && $line =~ /^BBU\s*:\s*(.*)/i) { $props{controllers}{$controller}{'bbu_status'} = parse_bbu_status($1); } elsif ($line =~ /^\s*================\s*$/) { $section = clean_white($last); } $last = $line; } $fh->close; foreach my $adapter (@adapters) { $controller = "$driver$adapter"; # if only one volume, wiring is easy my($default_volume) = ''; if (defined $controller_volumes{$controller}) { my(@keys) = keys %{$controller_volumes{$controller}}; if ($#keys == 0) { $default_volume = $keys[0]; hide_drives($default_volume); } } my($id) = 0; my(%seen_device_ids, $device_id); $cmd = "$megacli -adpBBUcmd -a$adapter"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /Serial Number\s*:\s*(.*)/) { $props{controllers}{$controller}{bbu_serial} = $1; } elsif ($line =~ /BatteryType\s*:\s*(.*)/) { $props{controllers}{$controller}{bbu_type} = $1; } elsif ($line =~ /Device Name\s*:\s*(.*)/) { $props{controllers}{$controller}{bbu_model} = $1; } elsif ($line =~ /Manufacture Name\s*:\s*(.*)/) { $props{controllers}{$controller}{bbu_manufacturer} = $1; } elsif ($line =~ /Device Chemistry\s*:\s*(.*)/) { $props{controllers}{$controller}{bbu_chemistry} = $1; } elsif ($line =~ /Battery Pack Missing\s*:\s*(.*)/) { $props{controllers}{$controller}{bbu_status} = 'missing' if ($1 ne 'No'); } elsif ($line =~ /Battery Replacement required\s*:\s*(.*)/) { $props{controllers}{$controller}{bbu_status} = 'failed' if ($1 ne 'No'); } elsif ($line =~ /Relative State of Charge\s*:\s*(\d+) %/) { $props{controllers}{$controller}{bbu_charge} = "$1%"; } } $fh->close; $cmd = "$megacli -adpPR -info -a$adapter"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /Patrol Read Mode\s*:\s*(.*)/) { $props{controllers}{$controller}{patrol_mode} = parse_patrol_mode($1); } elsif ($line =~ /Patrol Read Execution Delay\s*:\s*(.*)/) { $props{controllers}{$controller}{patrol_interval} = parse_seconds($1); } } $fh->close; $cmd = "$megacli -cfgDsply -a$adapter"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^Memory\s*:\s*(.*)/i) { $props{controllers}{$controller}{cache}{size} = parse_bytes($1, 1024); } elsif ($line =~ /^Number of DISK GROUPS/i) { last; } } my($pd_buf) = ''; my($ld_buf) = ''; my($vds) = 0; my($disk_group); while ($line = <$fh>) { $debug_storage .= $line; $vds = $1 if ($line =~ /^Number of VDs\s*:\s(\d+)/); $disk_group = $1 if ($line =~ /^DISK GROUPS?\s*:\s*(\d+)/mi); if ($line =~ /^(Virtual|Physical) Disk\s*:/) { if ($ld_buf =~ /^Size\s*:/mi) { if ($ld_buf =~ /^Virtual (Disk|Drive)\s*:\s*(\d+)( \(Target Id: (\d+)\))?/mi) { $id = $4 if ($3); } elsif ($disk_group) { $id = $disk_group; } else { $id = 'NA' } my($bytes); $bytes = parse_bytes($1, 1024) if ($ld_buf =~ /^Size\s*:\s*(.*)/mi); $volume = $default_volume || "$controller-vol$id"; my($logical); my(@keys) = keys %{$logical_to_os{perc}{channel}}; if ($#keys == 0) { # if only one OS channel, use it $logical = sprintf("$keys[0]-%d-%d", $id, 0); } else { # make some guesses here for linux on adapter, channel, lun $logical = sprintf("scsi%d-%d-%d-%d", $adapter, 0, $id, 0); } if (defined $logical_to_os{perc}{dev}{$logical}) { $volume = $logical_to_os{perc}{dev}{$logical}; } else { # if only one vol, map it @keys = keys %{$logical_to_os{perc}{dev}}; if ($#keys == 0) { $volume = $logical_to_os{perc}{dev}{$keys[0]}; } } my($match) = block_match({ 'size' => print_bytes($bytes, 1000, 1), 'driver' => $driver, 'controller' => $controller, }); if ($match) { $volume = $match; } # remove info we got from /proc/scsi/scsi hide_drives($volume) unless $seen{$volume}++; $volumes{$volume}++; if ($ld_buf =~ /^RAID Level\s*:\s*Primary-(\d+)(.*Secondary-(\d+))?/mi) { # 0,0 = RAID0 # 1,0 = RAID1 # 5,0 = RAID5 # 1,3 = RAID10 # 5,3 = RAID50 $props{volumes}{$volume}{raid} = "RAID-$1" . (defined($3) && ($3 == 3) ? "0" : ""); } $props{volumes}{$volume}{spans} = $1 if ($ld_buf =~ /^Span Depth\s*:\s*(\d+)/mi); if ($ld_buf =~ /^Current Cache Policy\s*:\s*(.*)/mi) { my($write, $read_ahead, $direct, $bad) = split(/, /, $1); $props{volumes}{$volume}{write_cache}{policy} = parse_cache_policy($write); $props{volumes}{$volume}{read_ahead} = parse_read_ahead_policy($read_ahead); if ($direct eq 'Direct') { # Direct I/O. Specifies that reads are not buffered in cache memory. $props{volumes}{$volume}{read_cache}{enable} = 0; } elsif ($direct eq 'Cached') { # Cache I/O. Specifies that all reads are buffered in cache memory. $props{volumes}{$volume}{read_cache}{enable} = 1; } } $props{volumes}{$volume}{drive_write_cache} = parse_drive_cache($1) if ($ld_buf =~ /^Disk Cache Policy\s*:\s*(.*)/mi); $props{volumes}{$volume}{status} = parse_volume_status($1) if ($ld_buf =~ /^State\s*:\s*(.*)/mi); $props{volumes}{$volume}{stripe} = parse_bytes($1, 1024) if ($ld_buf =~ /^Stripe Size\s*:\s*(.*)/mi); $props{volumes}{$volume}{bytes} = $bytes; if ($vds > 1) { # we have multiple logical on one physical array $ndrives++; $drives{$volume}{$drive_id}++; $props{drives}{$drive_id}{volume} = $volume; $volume = "$controller-p$disk_group"; $props{drives}{$drive_id}{model} = $volume; $props{drives}{$drive_id}{no_debug} = 1; $volumes{$volume}++; $drive_id++; } } if ($line =~ /Physical/i) { # time to drop through to physical drives $pd_buf = $line; while ($line = <$fh>) { $debug_storage .= $line; last if ($line =~ /^\s*$/); $pd_buf .= $line; } megacli_pd($pd_buf, $volume, $ver); if ($pd_buf =~ /^Device Id\s*:\s*(\d+)/mi) { $seen_device_ids{$1}++; } } # start of next virtual drive $ld_buf = ''; } last if ($fh->eof); $ld_buf .= $line; } $fh->close; $volume = "$controller-free"; $props{volumes}{$volume}{raid} = "JBOD"; my($record) = 0; $pd_buf = ''; $cmd = "$megacli -PDList -a$adapter"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; $record = 1 if ($line =~ /^Enclosure Device/); $pd_buf .= $line if ($record);; $device_id = $1 if ($line =~ /Device Id: (\d+)/); if ($pd_buf && $line =~ /^\s*$/) { megacli_pd($pd_buf, $volume, $ver) unless ($seen_device_ids{$device_id}); $record = 0; $pd_buf = ''; } } $fh->close; } return $result; } sub megarc { my(%megadrives); my(@adapters); my($result) = 0; my($line); my($volume) = "NA"; my(%seen); my($driver) = ($os_type eq 'linux') ? 'megaraid' : 'amr'; my($fh) = new IO::File; my($cmd); # could use the following to get disk write cache settings: # megarc -psetcache -viewcache -a0 -ch0 -id0 # avoid for now because megarc is slow/flakey. freebsd can get this via camcontrol pass devs system("which $megarc > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $have_megarc = 1; $debug_storage .= ">> $megarc\n"; $cmd = "$megarc -AllAdpInfo -noLog"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); last if ($line =~ /^\s*AdapterNo/); } while ($line = <$fh>) { $debug_storage .= $line; chomp($line); $got_megarc = 1; $result = 1; if ($line =~ /^\s*(\d+)/) { push(@adapters, int($1)); } else { last; } } $fh->close; foreach my $adapter (@adapters) { my($controller) = "$driver$adapter"; 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. $cmd = "$megarc -ctlrInfo -a$adapter -noLog"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /Firmware Version : (\S+)/i) { $props{controllers}{$controller}{'firmware'} = $1; } if ($line =~ /BIOS Version : (\S+)/i) { $props{controllers}{$controller}{'bios'} = $1; } if ($line =~ /DRAM : (\S+)/i) { $props{controllers}{$controller}{cache}{size} = parse_bytes($1, 1024); } if ($line =~ /Board SN: (\S+)/i) { $props{controllers}{$controller}{'serial'} = $1; } } $fh->close; } # if only one volume, wiring is easy my($default_volume) = ''; if (defined $controller_volumes{$controller}) { my(@keys) = keys %{$controller_volumes{$controller}}; if ($#keys == 0) { $default_volume = $keys[0]; hide_drives($default_volume); } } $cmd = "$megarc -ldInfo -Lall -a$adapter -noLog"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /Logical Drive\s*:\s*(\d+)\s*\(\s*Adapter:\s*(\d+)\s*\)/) { my($id) = $1; $volume = "$controller-spares"; $props{volumes}{$volume}{raid} = "JBOD"; $volume = ($default_volume || "$controller-vol$1"); my($logical); my(@keys) = keys %{$logical_to_os{megaraid}{channel}}; if ($#keys == 0) { # if only one OS channel, use it $logical = sprintf("$keys[0]-%d-%d", $id, 0); } else { # make some guesses here for linux on adapter, channel, lun $logical = sprintf("scsi%d-%d-%d-%d", $adapter, 0, $id, 0); } if (defined $logical_to_os{megaraid}{dev}{$logical}) { $volume = $logical_to_os{megaraid}{dev}{$logical}; # remove info we got from /proc/scsi/scsi hide_drives($volume) unless $seen{$volume}++; } else { # if only one vol, map it @keys = keys %{$logical_to_os{megaraid}{dev}}; if ($#keys == 0) { $volume = $logical_to_os{megaraid}{dev}{$keys[0]}; # remove info we got from /proc/scsi/scsi hide_drives($volume) unless $seen{$volume}++; } } $volumes{$volume}++; $props{volumes}{$volume}{device} = $controller; } if ($line =~ /RaidLevel\s*:\s*(\S+)/) { $props{volumes}{$volume}{raid} = "RAID-$1"; } if ($line =~ /SpanDepth\s*:\s*(\d+)/) { $props{volumes}{$volume}{spans} = int($1); $props{volumes}{$volume}{raid} .= "0" if (int($1) > 1); } if ($line =~ /StripSz\s*:\s*(\S+)/) { $props{volumes}{$volume}{stripe} = parse_bytes($1, 1024); } if ($line =~ /Cache\s*:\s*(\S+)/) { my($direct) = $1; if ($direct eq 'DirectIO') { $props{volumes}{$volume}{read_cache}{enable} = 0; } elsif ($direct eq 'CachedIO') { $props{volumes}{$volume}{read_cache}{enable} = 1; } } if ($line =~ /WrPolicy\s*:\s*(\S+)/) { $props{volumes}{$volume}{write_cache}{policy} = parse_cache_policy($1); } if ($line =~ /RdAhead\s*:\s*(\S+)/) { $props{volumes}{$volume}{read_ahead} = parse_read_ahead_policy($1); } 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; $megadrives{$drive}{status} = parse_drive_status($status); if ($status eq "FAILED") { $props{volumes}{$volume}{failed}++; } elsif ($status eq "RBLD") { $props{volumes}{$volume}{rebuild}++; } } } $fh->close; $cmd = "$megarc -phys -idAll -chAll -a$adapter -noLog"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; my($type, $rev, $status); while ($line = <$fh>) { $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} || "$controller-spares"; $status = $megadrives{$drive}{status} || "spare"; $megadrives{$drive}{id} = $drive_id; } 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}{type} = 'scsi-disk'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{volume} = $volume; $props{drives}{$drive_id}{firmware} = $rev; $props{drives}{$drive_id}{status} = $status; $drive_id++; $volumes{$volume}++; $props{volumes}{$volume}{device} = $controller; } } $fh->close; $cmd = "$megarc -physdrvSerialInfo -idAll -chAll -a$adapter -noLog"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; my($id); while ($line = <$fh>) { $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)); $id = $megadrives{$drive}{id}; } if ($line =~ /PhysDrvSerial\#\s*:\s+(\w+)/ && defined($props{drives}{$id})) { $props{drives}{$id}{serial} = $1; } } $fh->close; } return $result; } sub mptable { my($fh) = new IO::File; my($cmd); my($line); my($result) = 0; system("which $mptable > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $cmd = "$mptable"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; while ($line = <$fh>) { $debug_mptable .= $line; chomp($line); last if ($line =~ /^Processors:/); } while ($line = <$fh>) { $debug_mptable .= $line; chomp($line); last if ($line =~ /^[-= ]*$/); $result = 1; $procs{mptable}++; my(@cols) = split(' ', $line); my($family, $model, $step, $flags) = @cols[$#cols-3 .. $#cols]; my($cpuid) = sprintf("0x%x%x%x", $family, $model, $step); $cpus{steppings}{$step}++; $cpus{cpuid}{mptable} = $cpuid; $cpus{features_edx}{mptable} = $flags; if (!$procs{proc}{$procs{mptable}}{cpuid}) { if ($family == 6 && $model == 2 && $step == 1) { # appears to be the only bug with mptable, otherwise seems reliable # and it's not just 6b1 that it gets wrong # so ignore it here, hopefully get it from dmesg } else { $procs{proc}{$procs{mptable}}{cpuid} = $cpuid; } $procs{proc}{$procs{mptable}}{features_edx} = $flags; } } $fh->close; return $result; } sub twcli { my($fh) = new IO::File; my($cmd); my($line); my(%controllers); my(%units, %ports); my($units) = 0; my($ver) = 0; my($result) = 0; my(%seen); system("which $twcli > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $have_twcli = 1; $debug_storage .= ">> $twcli\n"; $cmd = "$twcli info"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); last if ($line =~ /^---------/); } while ($line = <$fh>) { $debug_storage .= $line; chomp($line); last if ($line =~ /^\s*$/); if ($line =~ /^Controller\s+(\d+):\s+(\S+)/) { $controllers{"c$1"} = $2; $ver = 1; } elsif ($line =~ /^(c\d+)\s+(\S+)\s*(.*)/) { $controllers{$1} = $2; my(@cols) = split(' ', $3); if ($#cols >= 2) { $units = $cols[2]; } $ver = 2; } } $fh->close; foreach my $controller (keys %controllers) { my(%header); $got_twcli++; $result++; $cmd = "$twcli info $controller"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); my(@cols) = split(' ', $line); if ($line =~ /^Unit/) { foreach my $i (0 .. $#cols) { $header{$cols[$i]} = $i; } } elsif ($line =~ /^u(\d+)/ || $line =~ /^\s*unit\s+(\d+)/i) { my($unit) = "u$1"; my($volume); my($type) = ($ver == 1) ? $cols[2] : $cols[1]; my($status); $status = parse_volume_status($cols[$header{'Status'}]) if ($ver != 1); my($size) = ($ver == 1) ? "$cols[5] $cols[6]" : "$cols[$header{'Size(GB)'}] GB"; my($stripe) = parse_bytes(($ver == 1) ? $cols[4] : $cols[$header{'Stripe'}], 1024); if ($type eq "SPARE") { $volume = "tw-$controller-spares"; $props{volumes}{$volume}{raid} = "JBOD"; } else { $volume = "$controller-$unit"; if (defined $logical_to_os{tw}{dev}{$volume}) { $volume = $logical_to_os{tw}{dev}{$volume}; # remove info we got from /proc/scsi/scsi hide_drives($volume) unless $seen{$volume}++; } else { # if only one vol, and one unit, map it my(@keys) = keys %{$logical_to_os{tw}{dev}}; if ($#keys == 0 && $units < 2) { $volume = $logical_to_os{tw}{dev}{$keys[0]}; # remove info we got from /proc/scsi/scsi hide_drives($volume) unless $seen{$volume}++; } } $props{volumes}{$volume}{raid} = $type; $props{volumes}{$volume}{bytes} = parse_bytes($size, 1024); } $props{volumes}{$volume}{stripe} = $stripe; $props{volumes}{$volume}{status} = $status; $volumes{$volume}++; $units{$unit}{volume} = $volume; # update 3ware controller model if we have enough data my($found) = 0; my($device) = $props{volumes}{$volume}{device}; if ($controllers{$controller} && $device) { if (defined $other_devices{'Disk-Control'}{$device}) { $other_devices{'Disk-Control'}{$device} =~ s/(7xxx\/8xxx|9xxx)/$controllers{$controller}/; $found++; } } if (!$found) { my($save); foreach my $device (keys %{$other_devices{'Disk-Control'}}) { if ($other_devices{'Disk-Control'}{$device} =~ /(7xxx\/8xxx|9xxx)/) { $save = $device; $found++; } } if ($found == 1) { # if only one match $other_devices{'Disk-Control'}{$save} =~ 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 ($ver == 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 '-' || $unit eq 'u?') { $volume = "tw-$controller-free"; } else { $volume = "tw-$controller-$unit"; } $volumes{$volume}++; $props{volumes}{$volume}{raid} = "JBOD"; } $ports{$controller}{$port}{volume} = $volume; } } $fh->close; if ($ver == 1) { foreach my $unit (keys %units) { my($volume) = $units{$unit}{volume}; my($status); $cmd = "$twcli info $controller $unit"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^Unit Type:\s+(.*)/) { $props{volumes}{$volume}{raid} = $1; } elsif ($line =~ /^Size:.*\((\d+)\s+blocks\)/) { $props{volumes}{$volume}{bytes} = $1 * 512; } elsif ($line =~ /^Stripe Size:\s*(\S+)/) { $props{volumes}{$volume}{stripe} = parse_bytes($1, 1024); } elsif ($line =~ /^Status:\s*(\S+)/) { $props{volumes}{$volume}{status} = parse_volume_status($1); } elsif ($line =~ /CBOD: (\S+)/) { $status = parse_drive_status($1); } elsif ($line =~ /Physical Port: (\d+)/) { $ports{$controller}{"p$1"}{status} = $status; } } $fh->close; } } else { foreach my $unit (keys %units) { my($volume) = $units{$unit}{volume}; my($status); $cmd = "$twcli info $controller $unit"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^$unit-\d+\s+RAID/) { $props{volumes}{$volume}{spans}++; } } $fh->close; } } foreach my $port (keys %{$ports{$controller}}) { $props{drives}{$drive_id}{location} = "controller=$controller,port=$port"; if ($ver == 1) { $props{drives}{$drive_id}{status} = $ports{$controller}{$port}{status}; $cmd = "$twcli info $controller $port"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; } else { $cmd = "$twcli info $controller $port"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /^$port\s+(\S+)\s+(\S+)/) { if ($2 eq '-') { $props{drives}{$drive_id}{status} = parse_drive_status("free"); } else { $props{drives}{$drive_id}{status} = parse_drive_status($1); } } } $fh->close; $cmd = "$twcli /$controller/$port show model status serial firmware capacity"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; } while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /Model\s*[:=]\s*(.*)/i) { $props{drives}{$drive_id}{type} = 'ata-disk'; $props{drives}{$drive_id}{model} = canon_drive($1); } elsif ($line =~ /Status\s*[:=]\s*(.*)/i) { # ignore this status if set from above, always seems to be OK here. if (!defined($props{drives}{$drive_id}{status})) { $props{drives}{$drive_id}{status} = parse_drive_status($1); } } elsif ($line =~ /Serial\s*\#?\s*[:=]\s*(.*)/i) { $props{drives}{$drive_id}{serial} = $1; } elsif ($line =~ /(Firmware Version|FW)\s*[:=]\s*(.*)/i) { $props{drives}{$drive_id}{firmware} = $2; } elsif ($line =~ /(Capacity|Size)\s*[:=]\s*.*\((\d+) Blocks\)/i) { $props{drives}{$drive_id}{size} = $2 * 512; } } $fh->close; my($volume) = $ports{$controller}{$port}{volume}; $props{volumes}{$volume}{failed}++ if ($props{drives}{$drive_id}{status} eq "failed"); $props{volumes}{$volume}{failing}++ if ($props{drives}{$drive_id}{status} eq "failing"); $props{drives}{$drive_id}{volume} = $volume; $drives{$volume}{$drive_id}++; $drive_id++; } } return $result; } sub smbinfo { my($fh) = new IO::File; my($cmd); my($line); my($result) = 0; # smbinfo obsoletes smbiosinfo system("which $smbinfo > /dev/null 2>&1"); if ($CHILD_ERROR) { system("which $smbiosinfo > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $cmd = "$smbiosinfo -l"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; } elsif (-t STDIN) { $cmd = "$smbinfo -l"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; } 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 still break $cmd = "$smbinfo -l <&-"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; } if (!eof($fh)) { $line = <$fh>; $result = 1; my($comp); if ($line =~ /^SMBIOS version/) { $line = <$fh>; while (!eof($fh)) { $debug_dmidecode .= $line; if ($line =~ /^(\S.*):/) { $comp = $1; parse_bios($fh, 'BIOS', 0, '') if ($comp eq "BIOS Information"); parse_system($fh, 'Base Board', 0, '') if ($comp eq "Base Board Information"); parse_system($fh, 'System', 0, '') if ($comp eq "System Information"); parse_system($fh, 'Chassis', 0, '') if ($comp eq "Chassis Information"); parse_system($fh, 'System Power Supply', 0, '') if ($comp eq "System Power Supply"); parse_proc($fh, 'Processor', 0, '') if ($comp eq "Processor Information"); parse_memory($fh, 'Memory', 'Device', 0, '') if ($comp eq "Memory Device"); } $line = <$fh>; } } else { while (!eof($fh)) { $debug_dmidecode .= $line; if ($line =~ /^\[\S+\s+([^\]]+)\]/) { $comp = $1; parse_bios($fh, 'BIOS', 0, '') if ($comp eq "BIOS"); parse_system($fh, 'Base Board', 0, '') if ($comp eq "Base Board"); parse_system($fh, 'System', 0, '') if ($comp eq "System"); parse_system($fh, 'Chassis', 0, '') if ($comp eq "Chassis"); parse_system($fh, 'System Power Supply', 0, '') if ($comp eq "System Power Supply"); parse_proc($fh, 'Processor', 0, '') if ($comp eq "Processor"); parse_memory($fh, 'Memory', 'Device', 0, '') if ($comp eq "Memory Device"); } $line = <$fh>; } } } $fh->close; return $result; } sub ipmi { my($result); my($cmd); my($fh) = new IO::File; my($line); system("which ipmitool > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $cmd = "ipmitool mc info"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">> $cmd\n"; while ($line = <$fh>) { $debug_ipmi .= $line; if ($line =~ /^IPMI Version\s*:\s*(.*)/) { $ipmi{version} = $1; } elsif ($line =~ /^Device ID\s*:\s*(.*)/) { $ipmi{device}->{id} = $1; } elsif ($line =~ /^Device Revision\s*:\s*(.*)/) { $ipmi{device}->{revision} = $1; } elsif ($line =~ /^Firmware Revision\s*:\s*(.*)/) { $ipmi{device}->{firmware} = $1; } elsif ($line =~ /^Manufacturer ID\s*:\s*(\d+)/) { $ipmi{device}->{manufacturer}->{id} = $1; $ipmi{device}->{manufacturer}->{name} = $ipmi_vendor{$1} if ($ipmi_vendor{$1}); } elsif ($line =~ /^Product ID\s*:\s*(\d+)/) { $ipmi{device}->{product}->{id} = $1; } } $fh->close; $cmd = "ipmitool lan print"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">> $cmd\n"; while ($line = <$fh>) { $debug_ipmi .= $line; if ($line =~ /^IP Address\s*:\s*(.*)/) { $ipmi{lan}->{ip}->{address} = $1; } elsif ($line =~ /^Subnet Mask\s*:\s*(.*)/) { $ipmi{lan}->{ip}->{netmask} = $1; } elsif ($line =~ /^MAC Address\s*:\s*(.*)/) { $ipmi{lan}->{mac} = $1; } elsif ($line =~ /^Default Gateway IP\s*:\s*(.*)/) { $ipmi{lan}->{gateway} = $1; } } $fh->close; } sub dmidecode { my($fh) = new IO::File; my($cmd); my($line); my($result) = 0; my($section, $count, $sep); my($handle) = 0; my($prefix) = ''; my($key); system("which $dmidecode > /dev/null 2>&1"); return $result if ($CHILD_ERROR); $cmd = "$dmidecode"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; while ($line = <$fh>) { $debug_dmidecode .= $line; $line =~ s/\s+$//; $line =~ s/^${prefix}//; if ($line =~ /^Handle (\S+), DMI type (\d+)/) { $handle = $1; $dmi{$handle}{'type'} = $2; $prefix = ''; } elsif ($line =~ /^Handle (\S+)$/) { $handle = $1; $prefix = '\t'; } elsif ($line =~ /^DMI type (\d+)/) { $dmi{$handle}{'type'} = $1; } elsif ($line =~ /^(System|Base Board|Chassis|System Power Supply)( Information)?( Block)?$/) { $result = 1; parse_system($fh, $1, $handle, $prefix); $handle = 0; } elsif ($line =~ /^(BIOS)( Information)( Block)?$/) { parse_bios($fh, $1, $handle, $prefix); $handle = 0; } elsif ($line =~ /^(Memory) (Device|Module Information)$/) { parse_memory($fh, $1, $2, $handle, $prefix); $handle = 0; } elsif ($line =~ /^(Processor)( Information)?$/) { parse_proc($fh, $1, $handle, $prefix); $handle = 0; } elsif ($line =~ /^checksum failed/) { last; } elsif ($line =~ /^\s*$/) { $handle = 0; } elsif ($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"; } } } $fh->close; return $result; } sub hpacucli { my($fh) = new IO::File; my($cmd); my($line); my($slot, %slots, %logicals, %physicals, %arrays); my(%sns); my($running) = 'Another instance of hpacucli is running'; # http://docs.hp.com/en/9320/acu.pdf # http://bizsupport1.austin.hp.com/bc/docs/support/SupportManual/c02289065/c02289065.pdf system("which $hpacucli > /dev/null 2>&1"); return if ($CHILD_ERROR); $have_hpacucli = 1; $debug_storage .= ">> $hpacucli\n"; $cmd = "$hpacucli version"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; if ($line =~ /$running/) { $fh->close; sleep(1); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; next; } } $fh->close; $cmd = "$hpacucli controller all show"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /$running/) { $fh->close; sleep(1); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; next; } if ($line =~ /in\s+slot\s+(\d[0-9a-z]*)/i) { $slots{$1} = "slot"; } elsif ($line =~ /\(sn: (\w+)\)/) { $sns{$1}++; } } $fh->close; # assign slot ids if we didn't get them, e.g. # Smart Array P400 in Slot ATTR_VALUE_SLOT_UNKNOWN (sn: PAFGL0P9SX12IQ) $slot = 1; foreach my $sn (keys %sns) { while ($slots{$slot}) { $slot++; } $sns{$sn} = $slot; $slots{$slot} = $sn; } my($count) = 0; foreach my $slot (keys %slots) { my($controller) = ($slots{$slot} eq "slot") ? "slot=$slot" : "sn=$slots{$slot}"; my(%ids); my($array) = "NA"; my(%cid, $cid); $cmd = "$hpacucli controller $controller logicaldrive all show"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /$running/) { $fh->close; sleep(1); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; next; } $line =~ s/\s*$//; if ($line =~ /array\s+(\S+)/i) { $array = $1; } elsif ($line =~ /logicaldrive\s+(\d+)\s+\(([^,]*),([^,]*)/) { $ids{$1} = $array; } } $fh->close; foreach my $id (keys %ids) { my($volume, $raid, $size, $stripe, $cache_enable, $status, $uid) = ("ciss-s$slot-$ids{$id}-l$id", '', 0, 0, 0, '', ''); my(%mirror_group, $mirror_group_id); $array = $ids{$id}; # if only one vol, map it my(@keys) = keys %{$logical_to_os{ciss}{dev}}; if ($#keys == 0) { $volume = $logical_to_os{ciss}{dev}{$keys[0]}; } $cmd = "$hpacucli controller $controller logicaldrive $id show"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /$running/) { $fh->close; sleep(1); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; next; } $line =~ s/\s*$//; 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*Mirror Group (\d+):/) { $mirror_group_id = $1; } elsif ($line =~ /^\s*physicaldrive (\S+)/) { $mirror_group{$mirror_group_id}->{$1}++; } elsif ($line =~ /^\s*Disk Name:\s+(\S+)/) { if ($1 ne 'Unknown') { $volume = $1; $volume =~ s/^\/dev\///; if ($volume =~ /cciss\/c(\d+)d(\d+)/) { $cid = $1; $cid{$1} = $controller; } } } } $fh->close; my($match) = block_match({ # /sys/block always shows raid-1 as raid-10; so do same here to match 'raid' => ($raid eq 'RAID-1') ? 'RAID-10' : $raid, 'size' => print_bytes($size, 1000, 1), 'driver' => 'cciss', }); if ($match) { $volume = $match; } $volumes{$volume}++; $logicals{$slot}{$array}{$id} = $volume; $props{volumes}{$volume}{bytes} = $size if ($size); $props{volumes}{$volume}{raid} = $raid if ($raid); $props{volumes}{$volume}{stripe} = $stripe if ($stripe); $props{volumes}{$volume}{status} = $status if ($status); $props{volumes}{$volume}{uid} = $uid; $props{volumes}{$volume}{read_cache}{enable} = $cache_enable; $props{volumes}{$volume}{write_cache}{enable} = $cache_enable; if (defined $mirror_group{0}) { @keys = keys %{$mirror_group{0}}; $props{volumes}{$volume}{spans} = $#keys + 1; } $arrays{$slot}{$array}++; } # after we've parsed the logical drives, we hopefully have a 'disk name' to determine cciss device my($dev); if (defined $cid) { $dev = "cciss$cid"; } else { # if not, we'll just guess while (defined $cid{$count}) { $count++; } $dev = "cciss$count"; $count++; } $array = "NA"; $cmd = "$hpacucli controller $controller physicaldrive all show"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /$running/) { $fh->close; sleep(1); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; next; } $line =~ s/\s*$//; if ($line =~ /array\s+(\S+)/i) { $array = $1; } elsif ($line =~ /unassigned/) { $array = 'unused'; $arrays{$slot}{$array}++; } elsif ($line =~ /physicaldrive\s+(\S+)/) { $physicals{$slot}{$array}{$1}++; } } $fh->close; foreach my $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 if (defined $cid) { $volume = "ciss-c$cid-$array"; } else { $volume = "ciss-s$slot-$array"; } $volumes{$volume}++; $props{volumes}{$volume}{raid} = "JBOD"; $props{volumes}{$volume}{bytes} = 0; $props{volumes}{$volume}{device} = $dev; } my($have_size) = $props{volumes}{$volume}{bytes}; foreach my $drive (keys %{$physicals{$slot}{$array}}) { my($size, $rpm, $speed, $interface, $status, $firmware, $serial, $ncq_support, $ncq_enable, $type, $location) = (0, "", "", "", "", "", "", "", "", "", ""); my($model) = "Unknown"; $cmd = "$hpacucli controller $controller physicaldrive $drive show"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /$running/) { $fh->close; sleep(1); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; next; } $line =~ s/\s*$//; if ($line =~ /Size:\s+(.*)/i) { $size = parse_bytes($1, 1000); } elsif ($line =~ /Rotational Speed:\s+(.*)/i) { $rpm = $1; } elsif ($line =~ /Transfer Speed:\s+(.*)/i) { $speed = parse_drive_speed($1); } elsif ($line =~ /PHY Transfer Rate:\s+([^,]*)(, (.*))?/i) { $speed = parse_drive_speed($1) || parse_drive_speed($3); } elsif ($line =~ /SATA NCQ Capable:\s+(.*)/i) { $ncq_support = parse_enable($1); } elsif ($line =~ /SATA NCQ Enabled:\s+(.*)/i) { $ncq_enable = parse_enable($1); } elsif ($line =~ /Status:\s+(.*)/i) { $status = parse_drive_status($1); } elsif ($line =~ /Drive Type:\s+(.*)/i) { $type = $1; } elsif ($line =~ /Interface Type:\s+(.*)/i) { $interface = parse_drive_interface($1); } elsif ($line =~ /Serial Number:\s+(.*)/i) { $serial = clean_white($1); } elsif ($line =~ /Firmware Revision:\s+(.*)/i) { $firmware = $1; } elsif ($line =~ /Model:\s+(.*)/i) { $model = canon_drive($1); } } $fh->close; if ($status eq "failed") { $props{volumes}{$volume}{failed}++; } elsif ($status eq "failing") { $props{volumes}{$volume}{failing}++; } elsif ($type =~ /spare/i) { $props{volumes}{$volume}{spare}++; $status = "spare"; } $drives{$volume}{$drive_id}++; $props{drives}{$drive_id}{type} = 'scsi-disk'; $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); $props{drives}{$drive_id}{ncq_support} = $ncq_support; $props{drives}{$drive_id}{ncq_enable} = $ncq_enable; if ($drive =~ /^(\d+):(\d+)$/) { $props{drives}{$drive_id}{location} = "bus=$1,id=$2"; } elsif ($drive =~ /^(\d+\S):(\d+):(\d+)$/) { $props{drives}{$drive_id}{location} = "port=$1,box=$2,bay=$3"; } else { internal_warn("unknown drive location `$drive' in hpacucli"); } $drive_id++; $props{volumes}{$volume}{bytes} += $size unless ($have_size); } } my($cache_size, $cache_size_read, $cache_size_write, $cache_status, $ratio); $cmd = "$hpacucli controller $controller show"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /$running/) { $fh->close; sleep(1); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; next; } $line =~ s/\s*$//; if ($line =~ /^\s*Read Cache Size: (.*)/i) { $cache_size_read = parse_bytes($1, 1024); } elsif ($line =~ /^\s*Write Cache Size: (.*)/i) { $cache_size_write = parse_bytes($1, 1024); } elsif ($line =~ /^\s*Total Cache Size: (.*)/i) { $cache_size = parse_bytes($1, 1024); } elsif ($line =~ /^\s*Accelerator Ratio: (\d+)/i) { $ratio = $1; } elsif ($line =~ /^\s*Battery(\/Capacitor)?( Pack)? Count: (\d+)/i) { $props{controllers}{$dev}{'bbu_count'} = $3; if (!$3) { $props{controllers}{$dev}{'bbu_status'} = 'missing'; } } elsif ($line =~ /^\s*Battery(\/Capacitor)? Status: (.*)/i) { $props{controllers}{$dev}{'bbu_status'} = parse_bbu_status($2); } elsif ($line =~ /^\s*Firmware Version: (.*)/i) { $props{controllers}{$dev}{'firmware'} = $1; $got_hpacucli = 1; } elsif ($line =~ /^\s*Hardware Revision: Rev (.*)/i) { $props{controllers}{$dev}{'revision'} = $1; } elsif ($line =~ /^\s*Drive Write Cache: (.*)/i) { $props{controllers}{$dev}{'drive_write_cache'} = parse_enable($1); } elsif ($line =~ /^\s*Serial Number: (.*)/i) { $props{controllers}{$dev}{'serial'} = $1; } elsif ($line =~ /^\s*Cache Serial Number: (.*)/i) { $props{controllers}{$dev}{'cache_serial'} = $1; } elsif ($line =~ /^\s*Cache Status: (.*)/i) { $cache_status = parse_enable($1); } } $fh->close; if ($cache_size) { $props{controllers}{$dev}{cache}{size} = $cache_size; if (!defined $cache_size_read) { $cache_size_read = ($ratio / 100) * $cache_size; } if (!defined $cache_size_write) { $cache_size_write = ((100 - $ratio) / 100) * $cache_size; } } if (defined $cache_size_read) { $props{controllers}{$dev}{read_cache}{size} = $cache_size_read; } if (defined $cache_size_write) { $props{controllers}{$dev}{write_cache}{size} = $cache_size_write; } if ($cache_status) { $props{controllers}{$dev}{cache}{status} = 'on'; } else { $props{controllers}{$dev}{cache}{status} = 'off'; } if ($cache_status && $cache_size_read) { $props{controllers}{$dev}{read_cache}{enable} = 1; } else { $props{controllers}{$dev}{read_cache}{enable} = 0; } if ($cache_status && $cache_size_write) { $props{controllers}{$dev}{write_cache}{enable} = 1; $props{controllers}{$dev}{write_cache}{policy} = parse_cache_policy('write-back'); } else { $props{controllers}{$dev}{write_cache}{enable} = 0; $props{controllers}{$dev}{write_cache}{policy} = parse_cache_policy('write-through'); } } } sub hypervisor { my($system, $bios) = @_; my($hyper); my($guess) = ''; # first, are we a guest? if (-e '/sys/hypervisor/type') { my($type, $ver); chomp($type = `cat /sys/hypervisor/type 2> /dev/null` || ''); if ($type) { my($part); $guess = $type; chomp($part = `cat /sys/hypervisor/version/major 2> /dev/null` || ''); $guess .= " $part" if ($part); chomp($part = `cat /sys/hypervisor/version/minor 2> /dev/null` || ''); $guess .= ".$part" if ($part); chomp($part = `cat /sys/hypervisor/version/extra 2> /dev/null` || ''); $guess .= $part if ($part); } } $hyper = vmware($system, $bios, $guess); $hypervisor = $hyper if ($hyper); $hyper = xen($system, $bios, $guess); $hypervisor = $hyper if ($hyper); # second, are we a host? } sub xen { my($system, $bios, $guess) = @_; my($xen) = ''; my($dom0) = 0; my($domU) = 0; my($have) = 0; my($context) = ''; my($ver) = ''; if ($guess =~ /xen\s*(.*)/i) { $have++; $ver = $1; } if ($system =~ /Xen HVM/) { $have++; $context = 'HVM'; $domU++ if ($system =~ /domU/); if ($bios =~ /Xen ([0-9\.]+)/) { $ver = $1 unless ($ver); } } system("which xen-detect > /dev/null 2>&1"); if (!$CHILD_ERROR) { my($detect); chomp($detect = `xen-detect 2> /dev/null` || ''); if ($detect) { # Running in PV context on Xen v3.3. if ($detect =~ /(\S+) context/) { $have++; $context = $1; } if ($detect =~ /Xen v(.*)\.$/) { $ver = $1 unless ($ver); } } } if (-e '/proc/xen/capabilities') { my($caps); chomp($caps = `cat /proc/xen/capabilities 2> /dev/null` || ''); $have++; if ($caps =~ /control_d/) { $dom0++; } else { $domU++; } } if ($have) { my($dom) = $dom0 ? 'dom0' : 'domU'; $xen = 'Xen'; $xen .= " $ver" if ($ver); $xen .= " $context" if ($context); $xen .= " $dom"; $xml_top->{virtualization}->{host} = {}; $xml_top->{virtualization}->{host}->{type} = 'Xen'; $xml_top->{virtualization}->{host}->{version} = $ver if ($ver); $xml_top->{virtualization}->{self} = {}; $xml_top->{virtualization}->{self}->{type} = "Xen $dom"; $xml_top->{virtualization}->{self}->{context} = $context if ($context); } return $xen; } sub vmware { my($system, $bios, $guess) = @_; my($dir) = '/proc/vmware'; my($file); my($ver); my($vmware) = ''; my($fh) = new IO::File; my($line); # http://www.vmware.com/download/vi/ if (-d $dir) { $debug_virt .= ">> cat $dir/version\n"; $file = "$dir/version"; $fh->open("< $file") || warn "open: $file: $!"; while ($line = <$fh>) { $debug_virt .= $line; chomp($line); $ver = $line unless $ver; } $fh->close; } if ($ver) { $xml_top->{virtualization}->{host} = {}; $xml_top->{virtualization}->{self} = {}; $xml_top->{virtualization}->{host}->{type} = 'VMware'; if ($ver =~ /ESX/) { $xml_top->{virtualization}->{host}->{type} .= ' ESX' if ($ver =~ /ESX/); $xml_top->{virtualization}->{self}->{type} = 'VMware service console'; } if ($ver =~ /^(.*?)\b([0-9\.]+)\s+\[\S+\-(\d+)\]/) { my($name, $v, $build) = ($1, $2, $3); my($update) = 0; if ($v eq '3.5.0') { $v = '3.5'; if ($build > 123630) { $update = 4; } elsif ($build > 110268) { $update = 3; } elsif ($build > 82663) { $update = 2; } elsif ($build > 64607) { $update = 1; } } elsif ($v eq '3.0.2') { if ($build > 52542) { $update = 1; } } $xml_top->{virtualization}->{host}->{version} = $v; $xml_top->{virtualization}->{host}->{update} = $update if ($update); $xml_top->{virtualization}->{host}->{build} = $build; $ver = "$name $v"; $ver .= " Update $update" if ($update); $ver .= ", Build $build"; } else { $ver =~ s/\[.*//; } $vmware = clean_white($ver); } elsif ($system =~ /vmware/i) { $xml_top->{virtualization}->{host} = {}; $xml_top->{virtualization}->{self} = {}; $xml_top->{virtualization}->{host}->{type} = 'VMware'; $xml_top->{virtualization}->{self}->{type} = 'VMware'; $vmware = 'VMware'; } return $vmware; } sub cissutil { my($fh) = new IO::File; my($cmd); my(%cissdrives); my($dev); my(%failed); my($line); system("which $cissutil > /dev/null 2>&1"); return if ($CHILD_ERROR); $have_cissutil = 1; $debug_storage .= ">> $cissutil\n"; foreach my $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]; # nuke camcontrol info hide_drives($default_volume); } } $cmd = "$cissutil -c $device -d"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { last if ($line =~ /^(da|vol)\d+/); $debug_storage .= $line; chomp($line); if ($line =~ /^controller\s+(\d+)\s*(\((.*)\))?/) { $got_cissutil = 1; $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 =~ /^battery \d+: (.*)/i) { $props{controllers}{"ciss$dev"}{'bbu_status'} = parse_bbu_status($1); } elsif ($line =~ /^running firmware\s+([\d\.]+)/i) { $props{controllers}{"ciss$dev"}{'firmware'} = $1; } elsif ($line =~ /^cache is:\s+(.*)/i) { $props{controllers}{"ciss$dev"}{cache}{status} = ($1 =~ /enable/i) ? 'on' : 'off'; } elsif ($line =~ /^write cache size = (.*)/i) { my($size) = parse_bytes($1, 1024); $props{controllers}{"ciss$dev"}{write_cache}{size} = $size; if ($size) { $props{controllers}{"ciss$dev"}{write_cache}{policy} = parse_cache_policy('write-back'); } else { $props{controllers}{"ciss$dev"}{write_cache}{policy} = parse_cache_policy('write-through'); } } elsif ($line =~ /^read cache size = (.*)/i) { $props{controllers}{"ciss$dev"}{read_cache}{size} = parse_bytes($1, 1024); } elsif ($line =~ /^logical drives:\s+(\d+)/) { push(@controllers, $controller); } } my($bytes, $raid, $status, $stripe, $nfail) = (0, '', '', 0, 0); my($last); my(%disks); while ($line) { $debug_storage .= $line; chomp($line); if ($line =~ /^((da|vol)\d+)/ || $line =~ /^(\s*)$/) { my($vol) = $1; if ($last && $last ne $vol) { if ($last =~ /^da/) { $volume = $last; hide_drives($volume); } elsif ($default_volume) { $volume = $default_volume; } else { my($match) = block_match({ 'raid' => $raid, 'size' => print_bytes($bytes, 1000, 1), 'controller' => "ciss$dev", }); if ($match) { $volume = $match; hide_drives($volume); } elsif ($last =~ /(\d+)/) { $volume = "ciss$dev-c$controller-l$1"; } } $volumes{$volume}++; $props{volumes}{$volume}{bytes} = $bytes if ($bytes); $props{volumes}{$volume}{raid} = $raid if ($raid); $props{volumes}{$volume}{status} = $status if ($status); $props{volumes}{$volume}{stripe} = $stripe if ($stripe); $props{volumes}{$volume}{failed} = $nfail if ($nfail); foreach my $drive (keys %disks) { $cissdrives{"$dev-$controller-$drive"} = $volume; } ($bytes, $raid, $status, $stripe, $nfail) = (0, '', '', 0, 0); %disks = (); } $last = $vol; last unless $vol; } if ($line =~ /^(vol(\d+))?\s+blocks\s+available\s+(\S+)/) { $bytes = $3 * 512; } elsif ($line =~ /^(vol(\d+))?\s+fault\s+tolerance\s+(\S+)/) { $raid = canon_raid($3); } elsif ($line =~ /^(vol(\d+))?\s+status\s+(.*)/) { $status = parse_volume_status($3); } elsif ($line =~ /^(vol(\d+))?\s+stripe\s+size\s+(\S+)/) { $stripe = parse_bytes($3, 1024); } elsif ($line =~ /^(vol(\d+))?\s+failed\s+drives\s+\(([^\)]+)\)/) { my($failed) = $3; $failed =~ s/\bnone\b//g; my(@failed) = split(/,/, $failed); $nfail = $#failed + 1; %failed = map { $_ => 1 } @failed; } elsif ($line =~ /^(vol(\d+))?\s+.*\s+(drives|spares)\s+\(([^\)]+)\)/) { %disks = map { $_ => 1 } (split(/,/, $4)); } $line = <$fh>; } $fh->close; foreach my $controller (@controllers) { my($id) = 0; my($cissid); my($configured, $spare, $present); $volume = "ciss$dev-c$controller-NA"; $cmd = "$cissutil -c $device --controller $controller --drives"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($fh->eof || $line =~ /^\S/) { # we're at the end of previous drive, set status $got_cissutil = 1; if ($id) { if ($failed{$cissid}) { $props{drives}{$id}{status} = parse_drive_status("failed"); } elsif (!$present) { $props{drives}{$id}{status} = parse_drive_status("missing"); } elsif ($configured) { if ($spare) { $props{drives}{$id}{status} = parse_drive_status("spare"); } else { $props{drives}{$id}{status} = parse_drive_status("online"); } } else { $props{drives}{$id}{status} = parse_drive_status("free"); } } ($configured, $spare, $present) = (0, 0, 0); } if ($line =~ /^\((b\d+t\d+) -> (da\d+)/) { $cissid = $1; $volume = $2; $ndrives++; $id = $drive_id++; } elsif ($line =~ /^\((b\d+t\d+) -> free/) { $cissid = $1; $volume = "ciss$dev-c$controller-free"; $volumes{$volume}++; $ndrives++; $id = $drive_id++; } elsif ($line =~ /^\((b(\d+)t(\d+))\)/) { $cissid = $1; if ($cissdrives{"$dev-$controller-$cissid"}) { $volume = $cissdrives{"$dev-$controller-$cissid"}; } else { $volume = $default_volume || "ciss$dev-c$controller-NA"; $volumes{$volume}++; } $ndrives++; $id = $drive_id++; } elsif ($line =~ /^\((b\d+t\d+) -> vol(\d+)/) { $cissid = $1; if ($cissdrives{"$dev-$controller-$cissid"}) { $volume = $cissdrives{"$dev-$controller-$cissid"}; } else { $volume = $default_volume || "ciss$dev-c$controller-l$2"; $volumes{$volume}++; } $ndrives++; $id = $drive_id++; } elsif ($line =~ /^\s+model\s+(.*)/) { my(@model) = split(' ', $1); # good drives: # COMPAQ BF07285A36 3HW05BP4000073301VN3 HPB3 # COMPAQ BD146863B3 B8TD1SLM HPB6 # ATA SAMSUNG HD103UJ S1JMJ1NQ900048 1AA01116 # HP DF300BB6C3 3LM4JFY700009844SRCE HPDA # HP DF300BABUF J8W9SXGC HPD5 # ATA Maxtor 7Y250M0 Y69F74KE YAR511W0 # # failed drives: # COMPAQ BD14685A26 HPB7 if ($#model >= 2) { $props{drives}{$id}{firmware} = pop @model; if ($#model >= 2) { $props{drives}{$id}{serial} = pop @model; } # use at least first two as model $props{drives}{$id}{model} = canon_drive(join(',', @model)); $props{drives}{$id}{type} = 'scsi-disk'; } else { # e.g. failed drive shows up with empty model info $props{drives}{$id}{model} = 'Unknown'; $props{drives}{$id}{type} = 'scsi-disk'; } $props{drives}{$id}{volume} = $volume; $drives{$volume}{$id}++; } elsif ($line =~ /^\s+configured:\s+(\d+)/) { $configured = $1; $props{volumes}{$volume}{free}++ unless ($1); } elsif ($line =~ /^\s+configured_spare:\s+(\d+)/) { $spare = $1; $props{volumes}{$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+(.*)/) { $present = $1; } } $fh->close; } } } sub ata_identify_freebsd { my($id, $disk, $identify) = @_; foreach my $line (split(/\n/, $identify)) { if ($line =~ /^protocol\s+(.*)/i) { $props{drives}{$id}{protocol} = parse_protocol($1); } elsif ($line =~ /^(ATA\/ATAPI revision\s*\d+)/) { $props{drives}{$id}{interface} = parse_protocol($1); } elsif ($line =~ /^device model\s+(.*)/) { $props{drives}{$id}{model} = $1; } elsif ($line =~ /^firmware revision\s+(.*)/) { $props{drives}{$id}{firmware} = $1; } elsif ($line =~ /^serial number\s+(.*)/) { $props{drives}{$id}{serial} = $1; } elsif ($line =~ /^WWN\s+(.*)/) { $props{drives}{$id}{wwn} = $1; } elsif ($line =~ /^sector size\s+logical (\d+), physical (\d+)/) { $props{drives}{$id}{logical_sector} = $1; $props{drives}{$id}{physical_sector} = $2; } elsif ($line =~ /^lba(48)? (not )?supported\s+(\d+) sectors/i) { $props{drives}{$id}{sectors} = $3; my($size) = $3 * 512; $props{drives}{$id}{size} = $size; if (!$props{volumes}{$disk}{bytes} || $size > $props{volumes}{$disk}{bytes}) { $props{volumes}{$disk}{bytes} = $size; } } elsif ($line =~ /^media RPM\s+(\d+)/) { $props{drives}{$id}{rpm} = $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+(yes|no)(\s+(\d+) tags)?$/) { $props{drives}{$id}{ncq_support} = parse_enable($1); $props{drives}{$id}{ncq_enable} = parse_enable($1); $props{drives}{$id}{ncq_depth} = $3 if ($2); } 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); } elsif ($line =~ /^data set management \(TRIM\)\s+(\S+)/) { $props{drives}{$id}{trim_support} = parse_enable($1); $props{drives}{$id}{trim_enable} = parse_enable($1); } } } sub camcontrol { my($dev); my($channel); my(@ids); my($fh) = new IO::File; my($cmd); my($line); system("which $camcontrol > /dev/null 2>&1"); return if ($CHILD_ERROR); $debug_storage .= ">> $camcontrol\n"; $cmd = "$camcontrol devlist -v"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $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; undef $channel; if ($dev =~ /^ahcich\d+$/ && defined($sysctl_dev{$dev})) { $channel = $dev; $dev = $sysctl_dev{$dev}{parent}; } } if ($line =~ /\b(a?da\d+)\b/ || $line =~ /\b(pass\d+)\b/) { my($volume) = $1; if ($line =~ /^<([^>]*) (\S+)>/) { my($model) = canon_drive($1); my($rev) = $2; $ndrives++; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{firmware} = $rev; $props{drives}{$drive_id}{volume} = $volume; $props{volumes}{$volume}{raid} = parse_model_for_raid($model); if ($model =~ /^COMPAQ/) { block_register($volume, { 'raid' => $props{volumes}{$volume}{raid}, }); } if ($dev) { $props{drives}{$drive_id}{device} = $dev; } if ($volume =~ /^ada/) { $props{drives}{$drive_id}{type} = 'sata-disk'; } else { $props{drives}{$drive_id}{type} = 'scsi-disk'; } if ($volume =~ /^pass/) { $props{drives}{$drive_id}{hidden} = 1; } else { $volumes{$volume}++; $drives{$volume}{$drive_id}++; if ($dev) { $props{volumes}{$volume}{device} = $dev; if (defined $channel) { $props{volumes}{$volume}{channel} = $channel; } $controller_volumes{$dev}{$volume}++; block_register($volume, { 'controller' => $dev, }); } if ($dmesg_buf =~ /^$volume:.*?(\d+) (512 byte )?sectors/m) { my($bytes) = $1 * 512; $props{volumes}{$volume}{bytes} = $bytes; $props{drives}{$drive_id}{size} = $bytes; block_register($volume, { 'bytes' => $bytes, }); } } push(@ids, $drive_id); $drive_id++; } } } $fh->close; foreach my $id (@ids) { my($volume) = $props{drives}{$id}{volume}; if ($volume =~ /^ada/) { my($identify) = ''; $cmd = "$camcontrol identify $volume"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; $identify .= $line; } $fh->close; ata_identify_freebsd($id, $volume, $identify); } else { $cmd = "$camcontrol inquiry $volume"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; if ($line =~ /Serial Number\s*(.+?)\s*$/) { $props{drives}{$id}{serial} = $1; } if ($line =~ /([\d\.]+MB)\/s transfers/) { $props{drives}{$id}{speed} = parse_bytes($1, 1024); } if ($volume !~ /^pass/ && $line =~ /(Tagged|Command) Queueing Enabled/) { $props{drives}{$id}{tcq_support} = 1; $props{drives}{$id}{tcq_enable} = 1; } } $fh->close; $cmd = "$camcontrol modepage $volume -m 1"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; if ($line =~ /AWRE.*:\s*(\d+)/) { $props{drives}{$id}{awre} = $1; } elsif ($line =~ /ARRE.*:\s*(\d+)/) { $props{drives}{$id}{arre} = $1; } } $fh->close; $cmd = "$camcontrol modepage $volume -m 4"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; if ($line =~ /Medium Rotation Rate:\s*(\d+)/) { $props{drives}{$id}{rpm} = $1; } } $fh->close; # http://www.seagate.com/support/disc/manuals/scsi/89509a.pdf $cmd = "$camcontrol modepage $volume -m 8"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; if ($line =~ /WCE:\s*(\d+)/) { $props{drives}{$id}{wcache_support} = 1; $props{drives}{$id}{wcache_enable} = $1; } elsif ($line =~ /RCD:\s*(\d+)/) { $props{drives}{$id}{rcache_support} = 1; $props{drives}{$id}{rcache_enable} = $1 ? 0 : 1; } } $fh->close; # only works on 6.x $cmd = "$camcontrol readcap $volume"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; if ($line =~ /Last Block: (\d+), Block Length: (\d+)/) { my($bytes) = ($1 + 1) * $2; $props{drives}{$id}{size} = $bytes; block_register($volume, { 'bytes' => $bytes, }); } } $fh->close; # to get ata identify info # camcontrol cmd ada1 -a "EC 00 00 00 00 00 00 00 00 00 00 00" -i 512 - # if we wanted to get cache size from drive: # camcontrol cmd -n da -u 0 -v -c "3C 00 00 00 00 00 00 00 0e 00" -i 0xe "s1 i3 i1 i1 i1 i1 i1 i1 i1 i1 i1 i1" } if ($volume !~ /^pass/) { # tcq data for pass devices is meaningless $cmd = "$camcontrol tags $volume"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; if ($line =~ /device openings: (\d+)/) { $props{drives}{$id}{tcq_depth} = $1; } } $fh->close; } } } sub grok_sysctl_dev { my($fh) = new IO::File; my($cmd); my($line); $cmd = "sysctl dev"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || return 0; while ($line = <$fh>) { $debug_sysctl_dev .= $line; chomp($line); if ($line =~ /^dev\.([^\.]+)\.(\d+)\.\%?([^\:]+)\:\s+(.*)/) { my ($dev, $key, $val) = ($1 . $2, $3, $4); $sysctl_dev_raw{$1}{$2}{$3} = $4; $sysctl_dev{$dev}{$key} = $val; } } $fh->close; foreach my $dev (keys %sysctl_dev) { my($model) = $sysctl_dev{$dev}{desc}; $model =~ s/\(R\)//g if $model; if ($dev =~ /^($freebsd_block_devs)\d+$/) { $model =~ s/\s+controller\b.*//i; $other_devices{'Disk-Control'}{$dev} = "$dev: $model"; $sysctl_dev{$dev}{'xmodel'} = $model; } elsif ($dev =~ /^(ata|ahcich)\d+$/) { $props{channels}{$dev}{device} = $sysctl_dev{$dev}{parent}; } elsif ($dev =~ /^(amrd|mfid)\d+$/) { $props{volumes}{$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 =~ /(Gen1|SATA-I) signaling/) { $result = "SATA-1.0"; } elsif ($proto eq "Serial ATA II" || $proto =~ /(Gen2|SATA-II) signaling/) { $result = "SATA-2.0"; } elsif ($proto eq "Serial ATA III" || $proto =~ /(Gen3|SATA-III) signaling/) { $result = "SATA-3.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); my($identify) = ''; while ($line = <$in>) { $debug_storage .= $line; $identify .= $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}{type} = 'ata-disk'; $props{drives}{$id}{model} = $model; $props{drives}{$id}{volume} = $disk; $drive_id++; $props{volumes}{$disk}{raid} = "JBOD"; } } ata_identify_freebsd($id, $disk, $identify); } sub freebsd_disks_unknown { my $sysctl = `sysctl -n kern.disks 2> /dev/null` || dmesg_disks(); chomp($sysctl); foreach my $disk (split(' ', $sysctl)) { next if ($disk =~ /^(md|cd)\d+$/); next if ($drives{$disk}); $ndrives++; $volumes{$disk}++; $drives{$disk}{$drive_id}++; $props{drives}{$drive_id}{type} = 'unknown'; $props{drives}{$drive_id}{model} = "Unknown"; $props{drives}{$drive_id}{volume} = $disk; $drive_id++; } } sub freebsd_disks { my($system) = @_; my($ac_works) = 1; my($bad_ad_driver) = 0; my($fh) = new IO::File; my($cmd); my($line); my($id); # do this before things like cissutil, megarc (let them override this with more detailed info) camcontrol(); my($which); chomp($which = `which $atacontrol` || 0); if ($CHILD_ERROR) { $ac_works = 0; } if ($system =~ /DL140 G3/) { # running ac or sc on an ad device in a tight loop causes box to lockup # seen on 6.2-YAHOO-20070423, need to assume bad for all freebsd # have never seen this on other models $ac_works = 0; $bad_ad_driver = 1; } $debug_storage .= ">> $atacontrol\n"; if ($ac_works && ($os_version < 500000000)) { # this works with freebsd 4 foreach my $i (0 .. 3) { foreach my $j (0 .. 1) { $cmd = "$atacontrol cap $i $j"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; atacontrol($fh, $drive_id, "ata-$i,$j"); $fh->close; } } } my $sysctl = `sysctl -n kern.disks 2> /dev/null` || dmesg_disks(); chomp($sysctl); foreach my $disk (split(' ', $sysctl)) { next if ($disk =~ /^(md|cd)\d+$/); $possible_raid_vols{$disk}++; next if ($drives{$disk}); if ($ac_works) { $cmd = "$atacontrol mode $disk"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /current mode = (.*)/) { $props{drives}{$drive_id}{speed} = parse_drive_speed($1); } } $fh->close; # this works with freebsd 6+ $cmd = "$atacontrol cap $disk"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; atacontrol($fh, $drive_id, $disk); $fh->close; next if ($drives{$disk}); if ($disk =~ /^ar\d+$/) { my($model) = ""; my($sep) = "partitions: "; $cmd = "$atacontrol status $disk"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $debug_storage .= $line; chomp($line); if ($line =~ /(RAID\d+).*subdisks: (.*) status:/) { my($raid, $subs) = ($1, $2); foreach my $sub (split(' ', $subs)) { $model .= "$sep$sub"; $sep = ", "; } $props{volumes}{$disk}{raid} = "SW-$raid"; } elsif ($line =~ /(RAID\d+)( stripesize=(\d+))? status:\s*(\S+)/) { my($raid, $stripe, $status) = ($1, $3, $4); $props{volumes}{$disk}{raid} = "SW-$raid"; $props{volumes}{$disk}{stripe} = $stripe * 512 if $stripe; $props{volumes}{$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 = ", "; } } $fh->close; if ($model) { $ndrives++; $volumes{$disk}++; $drives{$disk}{$drive_id}++; $props{drives}{$drive_id}{type} = 'lv-ar'; $props{drives}{$drive_id}{model} = $model; $props{drives}{$drive_id}{volume} = $disk; $drive_id++; if ($dmesg_buf =~ /^$disk: (\d+)MB/m) { $props{volumes}{$disk}{bytes} = $1 * 1024 * 1024; } } } next if ($drives{$disk}); } foreach my $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}++; $id = $drive_id++; $drives{$disk}{$id}++; $props{drives}{$id}{type} = 'disk'; $props{drives}{$id}{model} = $model; $props{drives}{$id}{volume} = $disk; $props{volumes}{$disk}{raid} = parse_model_for_raid($model); if ($size) { $props{volumes}{$disk}{bytes} = $size * 1024 * 1024; $props{drives}{$id}{size} = $size * 1024 * 1024; } if ($dev) { $props{volumes}{$disk}{device} = $dev; $controller_volumes{$dev}{$disk}++; if ($dev =~ /^twe(\d+)/) { my($ctrl) = $1; if ($gline =~ /\b$disk: open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; $debug_storage .= ">>> $cmd\n"; while ($line = <$fh>) { $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{volumes}{$2}{channel} = "ata$channel"; $props{volumes}{$2}{ms} = lc($1); } } $fh->close; } # wire from dmesg if we haven't done it yet foreach my $gline (split(/\n/, $dmesg_buf)) { if ($gline =~ /^(ad\d+):.*\s+at\s+(\S+)-(slave|master)/i) { if (!defined($props{volumes}{$1}{channel})) { $props{volumes}{$1}{channel} = $2; $props{volumes}{$1}{ms} = $3; } } elsif ($gline =~ /^(ata\d+):.*\s+on\s+(ata\S+)/i) { $props{channels}{$1}{device} = $2 unless $props{channels}{$1}{device}; } elsif ($gline =~ /^(pass\d+) at (\S+) bus (\d+)/) { $props{volumes}{$1}{device} = $2; } } } # 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($fh) = new IO::File; my $sysctl = `sysctl -n kern.disks 2> /dev/null` || dmesg_disks(); chomp($sysctl); foreach my $disk (split(' ', $sysctl)) { my($dev) = "/dev/$disk"; if (-e $dev && $fh->open($dev)) { my($status); my($bytes); if ($os_version >= 600000000) { $bytes = pack("I2", 0, 0); # DIOCGMEDIASIZE $status = ioctl($fh, 0x40086481, $bytes); if ($status) { my(@bytes) = unpack("I2", $bytes); $props{volumes}{$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); # DIOCGDINFO $status = ioctl($fh, 0x41146465, $bytes); if ($status) { my(@bytes) = unpack("C${offset}I", $bytes); $props{volumes}{$disk}{bytes} = $bytes[-1] * 512; } } $fh->close; } } } sub grok_boot_options { my($options); if (-e "/proc/cmdline") { $options = `cat /proc/cmdline 2> /dev/null`; if ($options =~ /maxcpus=(\d+)/) { $kernel{boot}{max_cpus} = $1; } elsif ($options =~ /mem=(\S+)/) { $kernel{boot}{memory} = parse_bytes($1, 1024); } } elsif (-e "/boot/loader.conf.local") { $options = `cat /boot/loader.conf.local 2> /dev/null`; if ($options =~ /^\s*hw.physmem\s*=\s*"?(\S+)"?\s*(#.*)?$/m) { $kernel{boot}{memory} = parse_bytes($1, 1024); } } } sub parse_freebsd_config { my($kernel); chomp($kernel = `sysctl -n kern.bootfile 2> /dev/null` || ''); if (-r $kernel) { my($fh) = new IO::File; my($line) = ''; my($cmd) = "strings $kernel"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || warn "exec: $cmd: $!"; while ($line = <$fh>) { if ($line =~ /^START CONFIG FILE/) { # 4.x, 6.x while ($line = <$fh>) { last if ($line =~ /^END CONFIG FILE/); $line =~ s/^___//; $debug_kernel_config .= $line; } } elsif ($line =~ m{FreeBSD: src/sys/\S+/conf/}) { # 7.x $debug_kernel_config .= $line; while ($line = <$fh>) { last if ($line !~ /^\s*(#|device|options|makeoptions|cpu|ident)/); $debug_kernel_config .= $line; } } } $fh->close; } } sub parse_darwin_config { # to do } sub parse_linux_config { my($ver) = @_; my($fh) = new IO::File; my($line); my($config) = "/boot/config-$ver"; if (-r $config) { $fh->open("< $config") || warn("open: $config: $!"); while ($line = <$fh>) { $debug_kernel_config .= $line; chomp($line); $line =~ s/\s*\#.*//; next if ($line =~ /^\s*$/); $line =~ s/\s*$//; $line =~ s/\"([^\"]*)\"/$1/; if ($line =~ /^\s*(\S+)=(.*)/) { $kernel{config}{$1} = $2; } } $fh->close; } } 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($uname); chomp($uname = `uname -v`); $uname =~ s/.*\///; $uname =~ s/\s+$//; $os .= " " . $uname; chomp($os_version = `uname -r`); $os_version_pretty = $os_version; if ($os_version =~ /^(\d+)\.\d+-[^-]*(-(\d+))?$/) { # $2 is null if stock FreeBSD $os_date = $2 ? $3 : "00000000"; $os_version = "$1$os_date"; } parse_freebsd_config(); 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 "darwin") { print "Sorry! This script doesn't support Darwin and Mac OS X\n"; exit(1); } elsif ($os_type eq "linux") { chomp($os_version = `uname -r`); $os_version_pretty = $os_version; if ($os_version =~ /^((\d+)\.(\d+)\.(\d+)(-(\d+))?)/) { $os_version = sprintf("%d%02d%03d%03d", $2, $3, $4, $6 || 0); } if (-e "/etc/redhat-release") { # http://kbase.redhat.com/faq/FAQ_43_4422.shtm chomp($os_distro = `cat /etc/redhat-release 2> /dev/null`); $os_distro =~ s/Red Hat Linux Advanced Server/RHEL/; $os_distro =~ s/Red Hat Enterprise Linux/RHEL/; $os_distro =~ s/\s+release\s+/ /; $os_distro =~ s/\(.*Update (\d+)\)/U$1/; $os_distro =~ s/\s+\([^\)]+\)$// if ($os_distro =~ /RHEL/); } elsif (-e "/etc/debian_version") { chomp($os_distro = `cat /etc/debian_version 2> /dev/null`); $os_distro = "Debian $os_distro"; } elsif (-e "/etc/gentoo-release") { chomp($os_distro = `cat /etc/gentoo-release 2> /dev/null`); $os_distro =~ s/\s+Base System version\s+/ /; } if (-e "/etc/custom-release") { chomp($custom_distro = `fgrep -1 '[version]' /etc/custom-release | tail -1`); } if ($os_distro) { $os = "$os_distro, $os"; } if ($custom_distro) { $os = "YLinux $custom_distro, $os"; } parse_linux_config($os_version_pretty); if ($kernel{config}{CONFIG_NR_CPUS}) { $kernel{config}{max_cpus} = $kernel{config}{CONFIG_NR_CPUS}; } $os_up = 1 unless ($kernel{config}{CONFIG_SMP} && $kernel{config}{CONFIG_SMP} eq 'y'); } } 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 best_cpu { my($key) = @_; my($result); if ($os_type eq 'linux') { $result = $cpus{$key}{dev} || $cpus{$key}{dmidecode} || $cpus{$key}{cpuinfo}; } elsif ($os_type eq 'freebsd') { $result = $cpus{$key}{dmidecode} || $cpus{$key}{dmesg} || $cpus{$key}{mptable}; } elsif ($os_type eq 'darwin') { $result = $cpus{$key}{dmidecode} || $cpus{$key}{dmesg} || $cpus{$key}{mptable}; } return $result; } sub cpuid_features { my($features, $vendor, $ecx_in, $edx_in, $ext_ecx_in, $ext_edx_in) = @_; my($ecx) = hex($ecx_in || 0); my($edx) = hex($edx_in || 0); my($ext_ecx) = hex($ext_ecx_in || 0); my($ext_edx) = hex($ext_edx_in || 0); # prefer Intel naming over AMD for ecx and edx, opposite for ext_ecx and ext_edx # http://www.sandpile.org/ia32/cpuid.htm # http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=history;f=arch/x86/include/asm/cpufeature.h # http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=history;f=arch/x86/kernel/cpu/scattered.c if ($vendor =~ /Intel/) { # http://www.intel.com/Assets/PDF/appnote/241618.pdf # http://software.intel.com/file/28986 $features->{FPU}++ if (($edx >> 0) & 0x01); $features->{VME}++ if (($edx >> 1) & 0x01); $features->{DE}++ if (($edx >> 2) & 0x01); $features->{PSE}++ if (($edx >> 3) & 0x01); $features->{TSC}++ if (($edx >> 4) & 0x01); $features->{MSR}++ if (($edx >> 5) & 0x01); $features->{PAE}++ if (($edx >> 6) & 0x01); $features->{MCE}++ if (($edx >> 7) & 0x01); $features->{CX8}++ if (($edx >> 8) & 0x01); $features->{APIC}++ if (($edx >> 9) & 0x01); $features->{EDX10}++ if (($edx >> 10) & 0x01); $features->{SEP}++ if (($edx >> 11) & 0x01); $features->{MTRR}++ if (($edx >> 12) & 0x01); $features->{PGE}++ if (($edx >> 13) & 0x01); $features->{MCA}++ if (($edx >> 14) & 0x01); $features->{CMOV}++ if (($edx >> 15) & 0x01); $features->{PAT}++ if (($edx >> 16) & 0x01); $features->{PSE_36}++ if (($edx >> 17) & 0x01); $features->{PSN}++ if (($edx >> 18) & 0x01); $features->{CLFSH}++ if (($edx >> 19) & 0x01); $features->{EDX20}++ if (($edx >> 20) & 0x01); $features->{DS}++ if (($edx >> 21) & 0x01); $features->{ACPI}++ if (($edx >> 22) & 0x01); $features->{MMX}++ if (($edx >> 23) & 0x01); $features->{FXSR}++ if (($edx >> 24) & 0x01); $features->{SSE}++ if (($edx >> 25) & 0x01); $features->{SSE2}++ if (($edx >> 26) & 0x01); $features->{SS}++ if (($edx >> 27) & 0x01); $features->{HTT}++ if (($edx >> 28) & 0x01); $features->{TM}++ if (($edx >> 29) & 0x01); $features->{IA64}++ if (($edx >> 30) & 0x01); $features->{PBE}++ if (($edx >> 31) & 0x01); $features->{SSE3}++ if (($ecx >> 0) & 0x01); $features->{PCLMULQDQ}++ if (($ecx >> 1) & 0x01); $features->{DTES64}++ if (($ecx >> 2) & 0x01); $features->{MONITOR}++ if (($ecx >> 3) & 0x01); $features->{DS_CPL}++ if (($ecx >> 4) & 0x01); $features->{VMX}++ if (($ecx >> 5) & 0x01); $features->{SMX}++ if (($ecx >> 6) & 0x01); $features->{EIST}++ if (($ecx >> 7) & 0x01); $features->{TM2}++ if (($ecx >> 8) & 0x01); $features->{SSSE3}++ if (($ecx >> 9) & 0x01); $features->{CNXT_ID}++ if (($ecx >> 10) & 0x01); $features->{ECX11}++ if (($ecx >> 11) & 0x01); $features->{FMA}++ if (($ecx >> 12) & 0x01); $features->{CX16}++ if (($ecx >> 13) & 0x01); $features->{xTPR}++ if (($ecx >> 14) & 0x01); $features->{PDCM}++ if (($ecx >> 15) & 0x01); $features->{ECX16}++ if (($ecx >> 16) & 0x01); $features->{PCID}++ if (($ecx >> 17) & 0x01); $features->{DCA}++ if (($ecx >> 18) & 0x01); $features->{SSE4_1}++ if (($ecx >> 19) & 0x01); $features->{SSE4_2}++ if (($ecx >> 20) & 0x01); $features->{x2APIC}++ if (($ecx >> 21) & 0x01); $features->{MOVBE}++ if (($ecx >> 22) & 0x01); $features->{POPCNT}++ if (($ecx >> 23) & 0x01); $features->{TDT}++ if (($ecx >> 24) & 0x01); $features->{AES}++ if (($ecx >> 25) & 0x01); $features->{XSAVE}++ if (($ecx >> 26) & 0x01); $features->{OSXSAVE}++ if (($ecx >> 27) & 0x01); $features->{AVX}++ if (($ecx >> 28) & 0x01); $features->{F16C}++ if (($ecx >> 29) & 0x01); $features->{RDRND}++ if (($ecx >> 30) & 0x01); $features->{HYPER}++ if (($ecx >> 31) & 0x01); $features->{EXT_EDX0}++ if (($ext_edx >> 0) & 0x01); $features->{EXT_EDX1}++ if (($ext_edx >> 1) & 0x01); $features->{EXT_EDX2}++ if (($ext_edx >> 2) & 0x01); $features->{EXT_EDX3}++ if (($ext_edx >> 3) & 0x01); $features->{EXT_EDX4}++ if (($ext_edx >> 4) & 0x01); $features->{EXT_EDX5}++ if (($ext_edx >> 5) & 0x01); $features->{EXT_EDX6}++ if (($ext_edx >> 6) & 0x01); $features->{EXT_EDX7}++ if (($ext_edx >> 7) & 0x01); $features->{EXT_EDX8}++ if (($ext_edx >> 8) & 0x01); $features->{EXT_EDX9}++ if (($ext_edx >> 9) & 0x01); $features->{EXT_EDX10}++ if (($ext_edx >> 10) & 0x01); $features->{SYSCALL}++ if (($ext_edx >> 11) & 0x01); $features->{EXT_EDX12}++ if (($ext_edx >> 12) & 0x01); $features->{EXT_EDX13}++ if (($ext_edx >> 13) & 0x01); $features->{EXT_EDX14}++ if (($ext_edx >> 14) & 0x01); $features->{EXT_EDX15}++ if (($ext_edx >> 15) & 0x01); $features->{EXT_EDX16}++ if (($ext_edx >> 16) & 0x01); $features->{EXT_EDX17}++ if (($ext_edx >> 17) & 0x01); $features->{EXT_EDX18}++ if (($ext_edx >> 18) & 0x01); $features->{EXT_EDX19}++ if (($ext_edx >> 19) & 0x01); $features->{NX}++ if (($ext_edx >> 20) & 0x01); $features->{EXT_EDX21}++ if (($ext_edx >> 21) & 0x01); $features->{EXT_EDX22}++ if (($ext_edx >> 22) & 0x01); $features->{EXT_EDX23}++ if (($ext_edx >> 23) & 0x01); $features->{EXT_EDX24}++ if (($ext_edx >> 24) & 0x01); $features->{EXT_EDX25}++ if (($ext_edx >> 25) & 0x01); $features->{PDPE1GB}++ if (($ext_edx >> 26) & 0x01); $features->{RDTSCP}++ if (($ext_edx >> 27) & 0x01); $features->{EXT_EDX28}++ if (($ext_edx >> 28) & 0x01); $features->{LM}++ if (($ext_edx >> 29) & 0x01); $features->{EXT_EDX30}++ if (($ext_edx >> 30) & 0x01); $features->{EXT_EDX31}++ if (($ext_edx >> 31) & 0x01); $features->{LAHF}++ if (($ext_ecx >> 0) & 0x01); $features->{EXT_ECX1}++ if (($ext_ecx >> 1) & 0x01); $features->{EXT_ECX2}++ if (($ext_ecx >> 2) & 0x01); $features->{EXT_ECX3}++ if (($ext_ecx >> 3) & 0x01); $features->{EXT_ECX4}++ if (($ext_ecx >> 4) & 0x01); $features->{EXT_ECX5}++ if (($ext_ecx >> 5) & 0x01); $features->{EXT_ECX6}++ if (($ext_ecx >> 6) & 0x01); $features->{EXT_ECX7}++ if (($ext_ecx >> 7) & 0x01); $features->{EXT_ECX8}++ if (($ext_ecx >> 8) & 0x01); $features->{EXT_ECX9}++ if (($ext_ecx >> 9) & 0x01); $features->{EXT_ECX10}++ if (($ext_ecx >> 10) & 0x01); $features->{EXT_ECX11}++ if (($ext_ecx >> 11) & 0x01); $features->{EXT_ECX12}++ if (($ext_ecx >> 12) & 0x01); $features->{EXT_ECX13}++ if (($ext_ecx >> 13) & 0x01); $features->{EXT_ECX14}++ if (($ext_ecx >> 14) & 0x01); $features->{EXT_ECX15}++ if (($ext_ecx >> 15) & 0x01); $features->{EXT_ECX16}++ if (($ext_ecx >> 16) & 0x01); $features->{EXT_ECX17}++ if (($ext_ecx >> 17) & 0x01); $features->{EXT_ECX18}++ if (($ext_ecx >> 18) & 0x01); $features->{EXT_ECX19}++ if (($ext_ecx >> 19) & 0x01); $features->{EXT_ECX20}++ if (($ext_ecx >> 20) & 0x01); $features->{EXT_ECX21}++ if (($ext_ecx >> 21) & 0x01); $features->{EXT_ECX22}++ if (($ext_ecx >> 22) & 0x01); $features->{EXT_ECX23}++ if (($ext_ecx >> 23) & 0x01); $features->{EXT_ECX24}++ if (($ext_ecx >> 24) & 0x01); $features->{EXT_ECX25}++ if (($ext_ecx >> 25) & 0x01); $features->{EXT_ECX26}++ if (($ext_ecx >> 26) & 0x01); $features->{EXT_ECX27}++ if (($ext_ecx >> 27) & 0x01); $features->{EXT_ECX28}++ if (($ext_ecx >> 28) & 0x01); $features->{EXT_ECX29}++ if (($ext_ecx >> 29) & 0x01); $features->{EXT_ECX30}++ if (($ext_ecx >> 30) & 0x01); $features->{EXT_ECX31}++ if (($ext_ecx >> 31) & 0x01); } elsif ($vendor =~ /AMD/) { # http://support.amd.com/us/Processor_TechDocs/25481.pdf $features->{FPU}++ if (($edx >> 0) & 0x01); $features->{VME}++ if (($edx >> 1) & 0x01); $features->{DE}++ if (($edx >> 2) & 0x01); $features->{PSE}++ if (($edx >> 3) & 0x01); $features->{TSC}++ if (($edx >> 4) & 0x01); $features->{MSR}++ if (($edx >> 5) & 0x01); $features->{PAE}++ if (($edx >> 6) & 0x01); $features->{MCE}++ if (($edx >> 7) & 0x01); $features->{CX8}++ if (($edx >> 8) & 0x01); $features->{APIC}++ if (($edx >> 9) & 0x01); $features->{EDX10}++ if (($edx >> 10) & 0x01); $features->{SEP}++ if (($edx >> 11) & 0x01); $features->{MTRR}++ if (($edx >> 12) & 0x01); $features->{PGE}++ if (($edx >> 13) & 0x01); $features->{MCA}++ if (($edx >> 14) & 0x01); $features->{CMOV}++ if (($edx >> 15) & 0x01); $features->{PAT}++ if (($edx >> 16) & 0x01); $features->{PSE36}++ if (($edx >> 17) & 0x01); $features->{EDX18}++ if (($edx >> 18) & 0x01); $features->{CLFLUSH}++ if (($edx >> 19) & 0x01); $features->{EDX20}++ if (($edx >> 20) & 0x01); $features->{EDX21}++ if (($edx >> 21) & 0x01); $features->{EDX22}++ if (($edx >> 22) & 0x01); $features->{MMX}++ if (($edx >> 23) & 0x01); $features->{FXSR}++ if (($edx >> 24) & 0x01); $features->{SSE}++ if (($edx >> 25) & 0x01); $features->{SSE2}++ if (($edx >> 26) & 0x01); $features->{EDX27}++ if (($edx >> 27) & 0x01); $features->{HTT}++ if (($edx >> 28) & 0x01); $features->{EDX29}++ if (($edx >> 29) & 0x01); $features->{EDX30}++ if (($edx >> 30) & 0x01); $features->{EDX31}++ if (($edx >> 31) & 0x01); $features->{SSE3}++ if (($ecx >> 0) & 0x01); $features->{ECX1}++ if (($ecx >> 1) & 0x01); $features->{ECX2}++ if (($ecx >> 2) & 0x01); $features->{MONITOR}++ if (($ecx >> 3) & 0x01); $features->{ECX4}++ if (($ecx >> 4) & 0x01); $features->{ECX5}++ if (($ecx >> 5) & 0x01); $features->{ECX6}++ if (($ecx >> 6) & 0x01); $features->{ECX7}++ if (($ecx >> 7) & 0x01); $features->{ECX8}++ if (($ecx >> 8) & 0x01); $features->{SSSE3}++ if (($ecx >> 9) & 0x01); $features->{ECX10}++ if (($ecx >> 10) & 0x01); $features->{ECX11}++ if (($ecx >> 11) & 0x01); $features->{ECX12}++ if (($ecx >> 12) & 0x01); $features->{CX16}++ if (($ecx >> 13) & 0x01); $features->{ECX14}++ if (($ecx >> 14) & 0x01); $features->{ECX15}++ if (($ecx >> 15) & 0x01); $features->{ECX16}++ if (($ecx >> 16) & 0x01); $features->{ECX17}++ if (($ecx >> 17) & 0x01); $features->{ECX18}++ if (($ecx >> 18) & 0x01); $features->{SSE4_1}++ if (($ecx >> 19) & 0x01); $features->{ECX20}++ if (($ecx >> 20) & 0x01); $features->{ECX21}++ if (($ecx >> 21) & 0x01); $features->{ECX22}++ if (($ecx >> 22) & 0x01); $features->{POPCNT}++ if (($ecx >> 23) & 0x01); $features->{ECX24}++ if (($ecx >> 24) & 0x01); $features->{ECX25}++ if (($ecx >> 25) & 0x01); $features->{ECX26}++ if (($ecx >> 26) & 0x01); $features->{ECX27}++ if (($ecx >> 27) & 0x01); $features->{ECX28}++ if (($ecx >> 28) & 0x01); $features->{ECX29}++ if (($ecx >> 29) & 0x01); $features->{ECX30}++ if (($ecx >> 30) & 0x01); $features->{HYPER}++ if (($ecx >> 31) & 0x01); $features->{FPU}++ if (($ext_edx >> 0) & 0x01); $features->{VME}++ if (($ext_edx >> 1) & 0x01); $features->{DE}++ if (($ext_edx >> 2) & 0x01); $features->{PSE}++ if (($ext_edx >> 3) & 0x01); $features->{TSC}++ if (($ext_edx >> 4) & 0x01); $features->{MSR}++ if (($ext_edx >> 5) & 0x01); $features->{PAE}++ if (($ext_edx >> 6) & 0x01); $features->{MCE}++ if (($ext_edx >> 7) & 0x01); $features->{CX8}++ if (($ext_edx >> 8) & 0x01); $features->{APIC}++ if (($ext_edx >> 9) & 0x01); $features->{EXT_EDX10}++ if (($ext_edx >> 10) & 0x01); $features->{SYSCALL}++ if (($ext_edx >> 11) & 0x01); $features->{MTRR}++ if (($ext_edx >> 12) & 0x01); $features->{PGE}++ if (($ext_edx >> 13) & 0x01); $features->{MCA}++ if (($ext_edx >> 14) & 0x01); $features->{CMOV}++ if (($ext_edx >> 15) & 0x01); $features->{PAT}++ if (($ext_edx >> 16) & 0x01); $features->{PSE36}++ if (($ext_edx >> 17) & 0x01); $features->{EXT_EDX18}++ if (($ext_edx >> 18) & 0x01); $features->{EXT_EDX19}++ if (($ext_edx >> 19) & 0x01); $features->{NX}++ if (($ext_edx >> 20) & 0x01); $features->{EXT_EDX21}++ if (($ext_edx >> 21) & 0x01); $features->{MMXEXT}++ if (($ext_edx >> 22) & 0x01); $features->{MMX}++ if (($ext_edx >> 23) & 0x01); $features->{FXSR}++ if (($ext_edx >> 24) & 0x01); $features->{FXSR_OPT}++ if (($ext_edx >> 25) & 0x01); $features->{PDPE1GB}++ if (($ext_edx >> 26) & 0x01); $features->{RDTSCP}++ if (($ext_edx >> 27) & 0x01); $features->{EXT_EDX28}++ if (($ext_edx >> 28) & 0x01); $features->{LM}++ if (($ext_edx >> 29) & 0x01); $features->{'3DNOWEXT'}++ if (($ext_edx >> 30) & 0x01); $features->{'3DNOW'}++ if (($ext_edx >> 31) & 0x01); $features->{LAHF}++ if (($ext_ecx >> 0) & 0x01); $features->{CMP_LEGACY}++ if (($ext_ecx >> 1) & 0x01); $features->{SVM}++ if (($ext_ecx >> 2) & 0x01); $features->{EXTAPIC}++ if (($ext_ecx >> 3) & 0x01); $features->{ALTMOVCR8}++ if (($ext_ecx >> 4) & 0x01); $features->{ABM}++ if (($ext_ecx >> 5) & 0x01); $features->{SSE4A}++ if (($ext_ecx >> 6) & 0x01); $features->{MISALIGNSSE}++ if (($ext_ecx >> 7) & 0x01); $features->{'3DNOWPREFETCH'}++ if (($ext_ecx >> 8) & 0x01); $features->{OSVW}++ if (($ext_ecx >> 9) & 0x01); $features->{IBS}++ if (($ext_ecx >> 10) & 0x01); $features->{SSE5}++ if (($ext_ecx >> 11) & 0x01); $features->{SKINIT}++ if (($ext_ecx >> 12) & 0x01); $features->{WDT}++ if (($ext_ecx >> 13) & 0x01); $features->{EXT_ECX14}++ if (($ext_ecx >> 14) & 0x01); $features->{EXT_ECX15}++ if (($ext_ecx >> 15) & 0x01); $features->{EXT_ECX16}++ if (($ext_ecx >> 16) & 0x01); $features->{EXT_ECX17}++ if (($ext_ecx >> 17) & 0x01); $features->{EXT_ECX18}++ if (($ext_ecx >> 18) & 0x01); $features->{NODEID_MSR}++ if (($ext_ecx >> 19) & 0x01); $features->{EXT_ECX20}++ if (($ext_ecx >> 20) & 0x01); $features->{EXT_ECX21}++ if (($ext_ecx >> 21) & 0x01); $features->{EXT_ECX22}++ if (($ext_ecx >> 22) & 0x01); $features->{EXT_ECX23}++ if (($ext_ecx >> 23) & 0x01); $features->{EXT_ECX24}++ if (($ext_ecx >> 24) & 0x01); $features->{EXT_ECX25}++ if (($ext_ecx >> 25) & 0x01); $features->{EXT_ECX26}++ if (($ext_ecx >> 26) & 0x01); $features->{EXT_ECX27}++ if (($ext_ecx >> 27) & 0x01); $features->{EXT_ECX28}++ if (($ext_ecx >> 28) & 0x01); $features->{EXT_ECX29}++ if (($ext_ecx >> 29) & 0x01); $features->{EXT_ECX30}++ if (($ext_ecx >> 30) & 0x01); $features->{EXT_ECX31}++ if (($ext_ecx >> 31) & 0x01); } foreach my $key (sort keys %{$features}) { if ($key =~ /^(ECX|EDX|EXT_ECX|EXT_EDX)\d/ && !$debug_seen{$key}++) { $debug .= "Debug-CPU:\tunknown feature=$key: vendor=$vendor, ecx=$ecx_in, edx=$edx_in\n"; } } } sub features_to_string { my(@args) = @_; my(@keys, %seen); foreach my $hash (@args) { foreach my $key (keys %{$hash}) { push(@keys, $key) unless $seen{$key}++; } } return join(' ', sort @keys); } sub grok_procs { $xml = $xml_top->{cpus} = {}; # already have dmidecode and dmesg if ($os_type eq 'linux') { cpuinfo(); # so far /sys info seems very accurate, /proc/cpuinfo has been flakey in the past. # so allow sys_cpu to override previous data sys_cpu(); dev_cpu(); } elsif ($os_type eq 'freebsd') { mptable(); sysctl_cpu(); dev_cpu(); } my($proc_id) = 1; my($index) = 1; while ($procs{proc}{$index}) { if ($procs{proc}{$index}{status}) { $proc_id = $index; last; } $index++; } if (!$procs{proc}{$proc_id}{vendor}) { $procs{proc}{$proc_id}{vendor} = $dmesg{proc}{vendor}; } if (!$procs{proc}{$proc_id}{family}) { $procs{proc}{$proc_id}{family} = $dmesg{proc}{family}; } if (!$procs{proc}{$proc_id}{speed}) { if ($dmesg{proc}{speed}) { $procs{proc}{$proc_id}{speed} = $dmesg{proc}{speed}; } else { my $tsc = `sysctl -n machdep.tsc_freq 2> /dev/null`; if ($tsc) { chomp($tsc); $procs{proc}{$proc_id}{speed} = sprintf("%4.2fMHz", $tsc / 1000000) if ($tsc); } } } my($vendor, $raw_model, $model); my($speed) = 0; if ($os_type eq "freebsd") { chomp($raw_model = `sysctl -n hw.model 2> /dev/null`); $raw_model = clean_white($raw_model); } if (!$raw_model) { if ($procs{proc}{$proc_id}{family}) { $raw_model = $procs{proc}{$proc_id}{family}; } elsif ($vendor) { $raw_model = $vendor; } else { $raw_model = "unknown"; } } $vendor = canon_cpu_vendor($procs{proc}{$proc_id}{vendor} || $raw_model); if ($raw_model =~ /([\d\.]+)(MHz|GHz)/) { $speed = round($1 * (($2 eq "GHz") ? 1000 : 1)); } $model = canon_cpu_model($raw_model); if (!$model) { if ($vendor) { $model = $vendor; } else { $model = "uknown"; } } my($cpuid) = best_cpu('cpuid'); $cpuid = sprintf("0x%04x", hex($cpuid)) if (defined $cpuid); my($ecx) = best_cpu('features_ecx'); my($edx) = best_cpu('features_edx'); my($ext_ecx) = best_cpu('features_ext_ecx'); my($ext_edx) = best_cpu('features_ext_edx'); $ecx = sprintf("0x%08x", hex($ecx)) if (defined $ecx); $edx = sprintf("0x%08x", hex($edx)) if (defined $edx); $ext_ecx = sprintf("0x%08x", hex($ext_ecx)) if (defined $ext_ecx); $ext_edx = sprintf("0x%08x", hex($ext_edx)) if (defined $ext_edx); my(%features); cpuid_features(\%features, $vendor, $ecx, $edx, $ext_ecx, $ext_edx); my($features) = features_to_string(\%features); if ($ext_edx) { if ($features{LM}) { $cpu_bits = 64; } else { $cpu_bits = 32; } } my($id) = join(',', decode_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"; foreach my $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; $procs{model} = $model; foreach my $level ('L1', 'L2', 'L3') { if (defined($procs{proc}{$proc_id}{"$level Cache Handle"})) { my($handle) = $procs{proc}{$proc_id}{"$level Cache Handle"}; if (defined($dmi{$handle}) && defined($dmi{$handle}{'key'}{'Installed Size'})) { my($bytes) = parse_bytes($dmi{$handle}{'key'}{'Installed Size'}, 1024); if ($bytes) { $cpus{lc($level) . '_cache_size'} = $bytes; if ($cpu_info) { my($pretty) = print_bytes($bytes, 1024, 1); $cpu_info =~ s/$level: (\S+)/$level: $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} && $procs{chips}) { $cpu_cores = ceil($procs{cores} / $procs{chips}); $cpu_threads = ceil($procs{threads} / $procs{cores}); } else { $cpu_cores = 1; $cpu_threads = 1; } } if ($procs{proc}{1} && $procs{proc}{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 2> /dev/null`); if ($CHILD_ERROR || !$procs{active_threads}) { if ($CHILD_ERROR) { user_warn(1, 0, "sysctl does not work"); $phone_home++; } # sysctl not working, so try mptable, or default to 1 as last resort $procs{active_threads} = $procs{mptable} || 1; } $procs{threads} = $procs{active_threads}; my($sysctl, $allowed, $halt); chomp($sysctl = `sysctl -n machdep.hyperthreading_allowed 2> /dev/null`); if ($CHILD_ERROR) { $allowed = -1; } elsif ($sysctl) { $allowed = 1; } else { $allowed = 0; } chomp($sysctl = `sysctl -n machdep.hlt_logical_cpus 2> /dev/null`); if ($CHILD_ERROR) { $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 ($CHILD_ERROR) { 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}{$proc_id}{speed} && $procs{proc}{$proc_id}{speed} =~ /^([\d\.]+)(MHz)?$/i) { $speed = $1; } if (round($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}{$proc_id}{clock} && $cpu_info) { if ($cpu_info =~ /Prestonia/ && $procs{proc}{$proc_id}{clock} eq "133MHz") { # for HP DL140 with Prestonia Bs $procs{proc}{$proc_id}{clock} = "533MHz"; $cpu_info =~ s/Prestonia/Prestonia B/; } elsif ($cpu_info =~ /Sossaman/ && $procs{proc}{$proc_id}{clock} eq "167MHz") { # for Intel SE7520BB2 with Sossaman $procs{proc}{$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}; } elsif ($procs{threads}) { $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 # ignore thread count if we know HT is turned off, otherwise we underestimate active cpus foreach my $i (0 .. ceil($procs{active_threads} / $cpu_cores / ($hyper eq "YES_ON" ? $cpu_threads : 1))-1) { $procs{proc}{$i+1}{status} = 1; } } # how many active chips do we have in the system my($chips) = 0; foreach my $proc (keys %{$procs{proc}}) { $chips++ if $procs{proc}{$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) { # deal with this case after we know active_cores } else { if ($procs{threads} == 1) { # should mean we have UP kernel running if ($os_up) { # should we warn here? } else { $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 ($kernel{config}{max_cpus} && $kernel{config}{max_cpus} == $procs{threads}) { # maxcpus is limited by kernel config $debug .= sprintf("Debug-Threads:\t(threads=%d) < (chips=%d * cpu_cores=%d * cpu_threads=%d) ==> maxcpus=%d limited by kernel config\n", $procs{threads}, $chips, $cpu_cores, $cpu_threads, $kernel{config}{max_cpus}); } elsif ($kernel{boot}{max_cpus} && $kernel{boot}{max_cpus} == $procs{threads}) { # maxcpus is limited at boot $debug .= sprintf("Debug-Threads:\t(threads=%d) < (chips=%d * cpu_cores=%d * cpu_threads=%d) ==> maxcpus=%d limited at boot\n", $procs{threads}, $chips, $cpu_cores, $cpu_threads, $kernel{boot}{max_cpus}); } 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 (!defined($procs{active_cores})) { $procs{active_cores} = $procs{cores}; } if ($procs{active_cores} > $procs{active_threads}) { $procs{active_cores} = $procs{active_threads}; } elsif ($procs{active_cores} > $procs{cores}) { $procs{active_cores} = $procs{cores}; } if ($cpu_threads > 1 && $procs{active_threads} <= $procs{active_cores}) { if ($hyper ne "YES_OFF") { # deal with case where HT is turned off in BIOS $hyper = "YES_MISSING"; } } # 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_threads} > $procs{active_cores} * $cpu_threads) { $debug .= sprintf("Debug-Threads-Active:\t(active_threads=%d) > (active_cores=%d * cpu_threads=%d)\n", $procs{active_threads}, $procs{active_cores}, $cpu_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); } # cases we should warn about if ($procs{active_threads} < $procs{threads}) { if ($kernel{config}{max_cpus} && $kernel{config}{max_cpus} == $procs{active_threads}) { # maxcpus is limited by kernel config user_warn(1, 10015, "only $procs{active_threads} of $procs{threads} cpu threads active due to kernel config limit"); $phone_home++; } elsif ($kernel{boot}{max_cpus} && $kernel{boot}{max_cpus} == $procs{active_threads}) { # maxcpus is limited at boot user_warn(1, 10016, "only $procs{active_threads} of $procs{threads} cpu threads active due to kernel boot limit"); } } # 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); # dmidecode doesn't provide accurate FSB and it's going away anyway, so stop displaying it #$processors .= " $procs{proc}{$proc_id}{clock} FSB" if ($procs{proc}{$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 && !$cpuid_vmware) { $debug .= "Debug-Processors:\t$id\n"; } my($codename, $stepping, $bit, $cores, $process); if ($cpu_info =~ /^([^,]*?)(\s+(\S\S))?,( 64-bit,)?( (\S+)-core,)? (\d+nm),/) { ($codename, $stepping, $bit, $cores, $process) = ($1, $3, $4, $6, $7); if (!$cpu_bits) { $cpu_bits = $bit ? 64 : 32; } } $xml->{bits} = $cpu_bits if ($cpu_bits); $xml->{sockets} = $procs{sockets}; $xml->{sockets_populated} = $chips; if ($system_model_index) { my($src) = \%{$system_models[$system_model_index]}; $xml->{socket_type} = $src->{'socket-type'} || ''; } $xml->{cores} = $procs{cores}; $xml->{cores_active} = $procs{active_cores}; $xml->{threads} = $procs{threads}; $xml->{threads_active} = $procs{active_threads}; if ($hyper =~ /YES/) { $xml->{ht_support} = 1; $xml->{ht_enable} = ($hyper eq 'YES_ON') ? 1 : 0; $xml->{ht_bios_enable} = ($hyper eq 'YES_MISSING') ? 0 : 1; } else { $xml->{ht_support} = 0; } if (keys %{$cpus{topology}}) { foreach my $attr (keys %{$cpus{topology}}) { $xml->{$attr} = $cpus{topology}{$attr}; } } if (keys %{$cpus{caches}}) { foreach my $cache (sort cmp_caches keys %{$cpus{caches}}) { $xml = \%{$cpus{caches}{$cache}}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{cpus}->{cache}}, $xml); $xml->{handle} = $xml_handle++; } } if (keys %{$cpus{cpus}}) { foreach my $cpu (sort cmp_cpus keys %{$cpus{cpus}}) { $cpus{cpus}{$cpu}{bits} = $cpu_bits if ($cpu_bits); set_unless($cpus{cpus}{$cpu}, 'l1_cache_size', $cpus{l1_cache_size}); set_unless($cpus{cpus}{$cpu}, 'l2_cache_size', $cpus{l2_cache_size}); set_unless($cpus{cpus}{$cpu}, 'l3_cache_size', $cpus{l3_cache_size}); set_unless($cpus{cpus}{$cpu}, 'stepping', $stepping); set_unless($cpus{cpus}{$cpu}, 'codename', $codename); set_unless($cpus{cpus}{$cpu}, 'process', $process); set_unless($cpus{cpus}{$cpu}, 'vendor', $vendor); # dmidecode doesn't provide accurate FSB and it's going away anyway, so stop using it #set_unless($cpus{cpus}{$cpu}, 'fsb', $procs{proc}{$proc_id}{clock}); set_unless($cpus{cpus}{$cpu}, 'speed', $speed); set_unless($cpus{cpus}{$cpu}, 'model', $raw_model); set_unless($cpus{cpus}{$cpu}, 'cpuid', $cpuid); set_unless($cpus{cpus}{$cpu}, 'features_ecx', $ecx); set_unless($cpus{cpus}{$cpu}, 'features_ext_ecx', $ext_ecx); set_unless($cpus{cpus}{$cpu}, 'features_edx', $edx); set_unless($cpus{cpus}{$cpu}, 'features_ext_edx', $ext_edx); set_unless($cpus{cpus}{$cpu}, 'features_support', $features); if ($id =~ /^(.*),(\d+),(\d+),(\d+)$/) { my($id1, $id2, $id3) = ($2, $3, $4); set_unless($cpus{cpus}{$cpu}, 'family_id', $id1); set_unless($cpus{cpus}{$cpu}, 'model_id', $id2); set_unless($cpus{cpus}{$cpu}, 'stepping_id', $id3); } $xml = \%{$cpus{cpus}{$cpu}}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{cpus}->{cpu}}, $xml); $xml->{handle} = $xml_handle++; } } else { $xml = {}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{cpus}->{cpu}}, $xml); $xml->{handle} = $xml_handle++; # dmidecode doesn't provide accurate FSB and it's going away anyway, so stop using it #$xml->{fsb} = $procs{proc}{$proc_id}{clock} || ''; # ???? $xml->{speed} = $speed || ''; $xml->{model} = $raw_model; $xml->{cpuid} = $cpuid if (defined $cpuid); $xml->{features_ecx} = $ecx if (defined $ecx); $xml->{features_ext_ecx} = $ext_ecx if (defined $ext_ecx); $xml->{features_edx} = $edx if (defined $edx); $xml->{features_ext_edx} = $ext_edx if (defined $ext_edx); $xml->{features_support} = $features if (defined $features); $xml->{stepping} = $stepping if (defined $stepping); $xml->{codename} = $codename if (defined $codename); $xml->{process} = $process if (defined $process); $xml->{vendor} = $vendor; if ($id =~ /^(.*),(\d+),(\d+),(\d+)$/) { $xml->{family_id} = $2; $xml->{model_id} = $3; $xml->{stepping_id} = $4; } } } sub msr { # http://download.intel.com/design/processor/manuals/253668.pdf # http://download.intel.com/design/processor/manuals/253669.pdf # http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/41256.pdf # http://support.amd.com/de/Processor_TechDocs/31116.pdf my(@args) = @_; if ($os_type eq 'linux') { return msr_linux(@args); } elsif ($os_type eq 'freebsd') { return msr_freebsd(@args); } return 0; } sub msr_linux { # mknod /dev/cpu/0/msr c 202 0 # mknod /dev/cpu/1/msr c 202 1 my($cpu, $idx) = @_; my($status) = 0; my($hi, $lo) = (0, 0); my($file) = "/dev/cpu/$cpu/msr"; my($fh) = new IO::File; if (-e $file) { my($buffer); if ($fh->open("< $file")) { sysseek($fh, $idx, SEEK_SET) || return; my($bytes) = sysread($fh, $buffer, 8); if ($bytes) { $lo = '0x' . unpack("H*", reverse(substr($buffer, 0, 4))); $hi = '0x' . unpack("H*", reverse(substr($buffer, 4, 4))); $status = 1; } $fh->close; } } return $status, $hi, $lo; } sub msr_freebsd { my($cpu, $idx) = @_; my($status) = 0; my($hi, $lo); my($line); system('which cpucontrol > /dev/null 2>&1'); return $status, $hi, $lo if ($CHILD_ERROR); my($hex) = sprintf("0x%08x", $idx); chomp($line = `cpucontrol -m $hex /dev/cpuctl$cpu 2> /dev/null`); if ($line =~ /^MSR (\S+): (.*)/) { ($hi, $lo) = split(' ', $2); $status = 1; } return $status, $hi, $lo; } my($force_affinity) = 0; my($cpuid_memory); sub cpuid { my($cpu, $eax_in, $ecx_in, $affinity) = @_; my($func); my($status, $pin, $eax, $ebx, $ecx, $edx); if ($force_affinity) { $affinity = 1; } else { if ($cpus{steppings}) { my(@steps) = keys %{$cpus{steppings}}; if ($#steps > 0) { $affinity = 1; $force_affinity = 1; } } if ($cpus{models}) { my(@models) = keys %{$cpus{models}}; if ($#models > 0) { $affinity = 1; $force_affinity = 1; } } } if ($os_type eq 'linux') { $func = \&cpuid_linux; } elsif ($os_type eq 'freebsd') { $func = \&cpuid_freebsd; } else { return 0; } ($status, $pin, $eax, $ebx, $ecx, $edx) = $func->($cpu, $eax_in, $ecx_in, $affinity); # verify that results match between cpus when we don't need affinity my($key) = sprintf("0x%08x,0x%08x", $eax_in, $ecx_in); if ($affinity) { delete $cpuid_memory->{$key}; # and don't save } elsif ($status) { my($val) = "$eax,$ebx,$ecx,$edx"; if ($cpuid_memory->{$key} && ($cpuid_memory->{$key}->{val} ne $val)) { internal_warn("cpuid for $key on cpu $cpu does not match cpu " . $cpuid_memory->{$key}->{cpu} . ": " . $cpuid_memory->{$key}->{val} . " != $val"); } $cpuid_memory->{$key}->{val} = $val; $cpuid_memory->{$key}->{cpu} = $cpu; } if ($status) { $debug_cpuid .= sprintf("%2d,$affinity,$pin: 0x%08x,0x%08x = $eax,$ebx,$ecx,$edx\n", $cpu, $eax_in, $ecx_in); } return $status, $eax, $ebx, $ecx, $edx; } my($c_dir); my($nvram_c_path); my($cpuid_c_path); sub nvram_c_init { return 1 if $nvram_c_path; system('which cc > /dev/null 2>&1'); return 0 if ($CHILD_ERROR); if (!$c_dir) { system('which mktemp > /dev/null 2>&1'); return 0 if ($CHILD_ERROR); chomp($c_dir = `mktemp -d /tmp/$zero-XXXXXXXXXX 2> /dev/null || mktemp -d /var/tmp/$zero-XXXXXXXXXX 2> /dev/null`); return 0 if (!$c_dir); } my($fh) = new IO::File; if ($fh->open("> $c_dir/nvram.c")) { $fh->print(' #include #include #ifdef linux #include #else #include #include #include #endif main() { int i; #ifdef linux if (iopl(3) < 0) { perror("iopl"); exit(1); } #else if (open("/dev/io", O_RDWR) < 0) { perror("open"); exit(1); } #endif for (i=0; i<256; i++) { #ifdef linux outb(i%128, 0x70 + 2*(i/128)); #else outb(0x70 + 2*(i/128), i%128); #endif printf("%02X", inb(0x71 + 2*(i/128))); } } '); $fh->close; system("cd $c_dir && cc -o nvram nvram.c > /dev/null 2>&1"); return 0 if ($CHILD_ERROR); $nvram_c_path = $c_dir . '/nvram'; } else { warn("open: $c_dir/nvram.c: $!"); return 0; } return 1; } sub cpuid_c_init { return 1 if $cpuid_c_path; system('which cc > /dev/null 2>&1'); return 0 if ($CHILD_ERROR); if (!$c_dir) { system('which mktemp > /dev/null 2>&1'); return 0 if ($CHILD_ERROR); chomp($c_dir = `mktemp -d /tmp/$zero-XXXXXXXXXX 2> /dev/null || mktemp -d /var/tmp/$zero-XXXXXXXXXX 2> /dev/null`); return 0 if (!$c_dir); } my($fh) = new IO::File; if ($fh->open("> $c_dir/cpuid.c")) { $fh->print('#include main(int argc, char **argv) { unsigned int eax, ebx, ecx, edx; asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (strtoul(argv[1], 0, 0)), "c" (strtoul(argv[2], 0, 0))); printf("0x%08x,0x%08x,0x%08x,0x%08x", eax, ebx, ecx, edx); } '); $fh->close; system("cd $c_dir && cc -o cpuid cpuid.c > /dev/null 2>&1"); return 0 if ($CHILD_ERROR); $cpuid_c_path = $c_dir . '/cpuid'; } else { warn("open: $c_dir/cpuid.c: $!"); return 0; } return 1; } sub cpuid_c { my($cpu, $eax_in, $ecx_in, $affinity) = @_; my($eax, $ebx, $ecx, $edx); my($status) = 0; my($pin, $pin_args); if ($os_type eq 'linux') { $pin = 'taskset'; if ($os_version < 206000000) { $pin_args = sprintf("0x%08x", 1 << $cpu); } else { $pin_args = "-c $cpu"; } } elsif ($os_type eq 'freebsd') { $pin = 'cpuset'; $pin_args = "-l $cpu"; } else { return 0; } system("which $pin > /dev/null 2>&1"); if ($CHILD_ERROR) { if ($affinity) { # need affinity, but don't have it return 0; } else { # don't need affinity $pin = ''; $pin_args = ''; } } cpuid_c_init(); if ($cpuid_c_path && -x $cpuid_c_path) { my($out) = `$pin $pin_args $cpuid_c_path $eax_in $ecx_in 2> /dev/null`; if ($out) { ($eax, $ebx, $ecx, $edx) = split(/,/, $out); $status = 1; } } return $status, ($pin ne ''), $eax, $ebx, $ecx, $edx; } sub cpuid_linux { my($cpu, $eax_in, $ecx_in, $affinity) = @_; my($status, $pin); my($eax, $ebx, $ecx, $edx); ($status, $pin, $eax, $ebx, $ecx, $edx) = cpuid_c($cpu, $eax_in, $ecx_in, $affinity); if ($status) { return $status, $pin, $eax, $ebx, $ecx, $edx; } my($file) = "/dev/cpu/$cpu/cpuid"; my($offset) = $eax_in; if (!-e $file || ($os_version < 206018164 && ($eax_in == 4 || $eax_in == 11))) { # /dev/cpu is flakey prior to RHEL 5 for cpuid.4 and cpuid.11 # for these two, you'll either get correct results or all zeros # also known to be flakey on L5335 procs on anything prior to RHEL 5.4 return 0; } if (defined $ecx_in) { $offset |= ($ecx_in << 32); } if (-e $file) { my($fh) = new IO::File; my($buffer); if ($fh->open("< $file")) { $status = $fh->sysseek($offset, SEEK_SET) || return; $fh->sysread($buffer, 16); $eax = '0x' . unpack("H*", reverse(substr($buffer, 0, 4))); $ebx = '0x' . unpack("H*", reverse(substr($buffer, 4, 4))); $ecx = '0x' . unpack("H*", reverse(substr($buffer, 8, 4))); $edx = '0x' . unpack("H*", reverse(substr($buffer, 12, 4))); $fh->close; $status = 1; } } return $status, 1, $eax, $ebx, $ecx, $edx; } sub cpuid_freebsd { my($cpu, $eax_in, $ecx_in, $affinity) = @_; my($status, $pin); my($eax, $ebx, $ecx, $edx); my($line); ($status, $pin, $eax, $ebx, $ecx, $edx) = cpuid_c($cpu, $eax_in, $ecx_in, $affinity); if ($status) { return $status, $pin, $eax, $ebx, $ecx, $edx; } system('which cpucontrol > /dev/null 2>&1'); if ($CHILD_ERROR || defined $ecx_in) { # no support for ecx input return 0; } my($hex) = sprintf("0x%08x", $eax_in); chomp($line = `cpucontrol -i $hex /dev/cpuctl$cpu 2> /dev/null`); if ($line =~ /^cpuid level (\S+): (.*)/) { ($eax, $ebx, $ecx, $edx) = split(' ', $2); $status = 1; } return $status, 1, $eax, $ebx, $ecx, $edx; } sub dev_cpu { # http://www.intel.com/Assets/PDF/appnote/241618.pdf my($result) = 0; my($dd) = new DirHandle; my(@cpus); if ($os_type eq 'linux') { my($root) = '/sys/devices/system/cpu'; if (-d $root) { $dd->open($root) || warn("opendir: $root: $!"); @cpus = map { /^cpu(\d+)/ } $dd->read; $dd->close; } else { $root = '/dev/cpu'; if (-d "$root/0") { $dd->open($root) || warn("opendir: $root: $!"); @cpus = grep(/^\d+$/, $dd->read); $dd->close; } elsif ($procs{active_threads}) { # from cpuinfo @cpus = 0 .. ($procs{active_threads} - 1); } else { return 0; } } } elsif ($os_type eq 'freebsd') { my($root) = '/dev'; if (-d $root) { $dd->open($root) || warn("opendir: $root: $!"); @cpus = map { /^cpuctl(\d+)/ } $dd->read; $dd->close; } if ($#cpus < 0) { my($sysctl); chomp($sysctl = `sysctl -n hw.ncpu 2> /dev/null`); if ($sysctl =~ /^\d+$/) { @cpus = 0 .. ($sysctl - 1); } else { return 0; } } } my($features); my($power_features); my($features_disabled); my(%threads); my(%apic_to_cpu); my($topology) = {}; foreach my $n (sort { $a <=> $b } @cpus) { my $cpu = "cpu$n"; my($cpuid_level, $cpuid_ext_level); $features = {}; $power_features = {}; $features_disabled = {}; my($vendor); my($base_clock) = 0; my($apic_id); my($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 0, 0, 0); if ($status) { $cpus{cpus}{$cpu}{cpuid_level} = $cpuid_level = hex($eax); $vendor = reverse(pack("H*", substr($ecx, 2) . substr($edx, 2) . substr($ebx, 2))); } else { # no reason to keep going, rest will fail next; } ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 1, 0, 0); if ($status) { cpuid_features($features, $vendor, $ecx, $edx, 0, 0); if (defined $cpus{cpus}{$cpu}{cpuid}) { # already have from cpuinfo if (hex($eax) != hex($cpus{cpus}{$cpu}{cpuid})) { # rhel4u6 and below get cpuid wrong unless ($os_type eq 'linux' && $os_version <= 206009067) { $debug .= "Debug-CPU:\tcpu$n cpuid: $eax (/dev) != $cpus{cpus}{$cpu}{cpuid} (cpuinfo)\n"; } } } my($family, $model, $stepping); ($vendor, $family, $model, $stepping) = decode_cpuid($vendor, $eax); $cpus{cpus}{$cpu}{vendor} = $vendor; $cpus{cpus}{$cpu}{family_id} = $family; $cpus{cpus}{$cpu}{model_id} = $model; $cpus{cpus}{$cpu}{stepping_id} = $stepping; $cpus{cpus}{$cpu}{cpuid} = $eax; $cpus{cpus}{$cpu}{features_ecx} = $ecx; $cpus{cpus}{$cpu}{features_edx} = $edx; $cpus{cpus}{$cpu}{name} = $cpu; $cpus{cpuid}{dev} = $eax; $cpus{features_ecx}{dev} = $ecx; $cpus{features_edx}{dev} = $edx; $result++; if ($family == 6 && ($model == 0x2a || $model == 0x2d)) { # sandy bridge $base_clock = 100 * 1000000; } else { $base_clock = (400/3) * 1000000; } ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 1, 0, 1); if ($status) { # will be superceded by cpuid.11 if possible $apic_id = (hex($ebx) >> 24) & 0xff; $cpus{cpus}{$cpu}{logical_procs} = (hex($ebx) >> 16) & 0xff; } } ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 0x80000000, 0, 0); if ($status) { $cpus{cpus}{$cpu}{cpuid_ext_level} = $eax; $cpuid_ext_level = hex($eax); } if ($cpuid_ext_level >= 0x80000001) { ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 0x80000001, 0, 0); if ($status) { cpuid_features($features, $vendor, 0, 0, $ecx, $edx); $cpus{cpus}{$cpu}{features_ext_ecx} = $ecx; $cpus{cpus}{$cpu}{features_ext_edx} = $edx; $cpus{features_ext_ecx}{dev} = $ecx; $cpus{features_ext_edx}{dev} = $edx; } } if ($cpuid_ext_level >= 0x80000004) { my($brand) = ''; foreach my $in (2 .. 4) { ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 0x80000000 + $in, 0, 0); if ($status) { $brand .= reverse(pack("H*", substr($edx, 2) . substr($ecx, 2) . substr($ebx, 2) . substr($eax, 2))); } else { $brand = ''; last; } } if ($brand) { $brand =~ s/\000.*//; $cpus{cpus}{$cpu}{brand} = clean_white($brand); } } my($hi, $lo); if ($vendor =~ /Intel/) { if ($cpuid_level >= 6) { ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 6, 0, 0); if ($status) { $features->{DTS}++ if ((hex($eax) >> 0) & 0x01); $features->{TURBO}++ if ((hex($eax) >> 1) & 0x01); $features->{ARAT}++ if ((hex($eax) >> 2) & 0x01); $features->{PLN}++ if ((hex($eax) >> 4) & 0x01); $features->{ECMD}++ if ((hex($eax) >> 5) & 0x01); $features->{PTM}++ if ((hex($eax) >> 6) & 0x01); $features->{EPB}++ if ((hex($ecx) >> 3) & 0x01); } } if ($cpuid_level >= 7) { ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 7, 0, 0); if ($status) { $features->{FGSBASE}++ if ((hex($ebx) >> 0) & 0x01); } } if ($cpuid_level >= 11) { my($level) = 0; my($prev_shift) = 0; while (1) { ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 0xb, $level, 1); if ($status) { if ($level == 0 && hex($ebx) == 0) { # leaf 0x0000000b not implemented, bail last; } my $shift = ((hex($eax) >> 0) & 0x1f); my $threads = ((hex($ebx) >> 0) & 0xff); $apic_id = hex($edx); my %types = ( 0 => 'invalid', 1 => 'thread', 2 => 'core', ); my $level_type = $types{((hex($ecx) >> 8) & 0xff)}; my($mod) = $apic_id & ((1 << $shift) - 1); my($id) = $mod >> $prev_shift; my($rest) = $apic_id >> $shift; if ($level_type eq 'thread') { $cpus{cpus}{$cpu}{topology}{thread_id} = $id; } elsif ($level_type eq 'core') { $cpus{cpus}{$cpu}{topology}{core_id} = $id; $cpus{cpus}{$cpu}{topology}{package_id} = $rest; $cpus{cpus}{$cpu}{topology}{apic_id} = $apic_id; $topology->{$rest}->{$id}->{$cpus{cpus}{$cpu}{topology}{thread_id}} = $apic_id; } $threads{$level} = $threads; $prev_shift = $shift; } last unless ($status && (hex($eax) || hex($ebx))); $level++; } } if ($cpuid_level >= 4) { # should come after cpuid.11 for apic_id my($i) = 0; my($previous) = ''; while (1) { ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 4, $i, 1); my($type) = (hex($eax || 0) >> 0) & 0x1f; if ($status && $type) { my(%type) = ( 1 => 'data', 2 => 'instruction', 3 => 'unified', ); my($level) = (hex($eax) >> 5) & 0x7; my($ways) = ((hex($ebx) >> 22) & 0x3ff) + 1; my($partitions) = ((hex($ebx) >> 12) & 0x3ff) + 1; my($line_size) = ((hex($ebx) >> 0) & 0xfff) + 1; my($sets) = hex($ecx) + 1; my($size) = $ways * $partitions * $line_size * $sets; my($dmi) = sprintf("l%d_cache_size", $level); delete $cpus{cpus}{$cpu}{$dmi}; my($apics) = ((hex($eax) >> 26) & 0x3f) + 1; my($threads) = ((hex($eax) >> 14) & 0x3ff) + 1; my($cache_id) = $apic_id & ~($threads-1); my($name) = sprintf("l%d_%s_%d", $level, $type{$type}, $cache_id); push(@{$cpus{cpus}{$cpu}->{cache}}, $name); $cpus{caches}->{$name}->{name} = $name; $cpus{caches}->{$name}->{type} = $type{$type}; $cpus{caches}->{$name}->{level} = $level; $cpus{caches}->{$name}->{ways} = $ways; $cpus{caches}->{$name}->{partitions} = $partitions; $cpus{caches}->{$name}->{line_size} = $line_size; $cpus{caches}->{$name}->{sets} = $sets; $cpus{caches}->{$name}->{size} = $size; push(@{$cpus{caches}->{$name}->{apic_id}}, $apic_id); if ("$eax,$ebx,$ecx,$edx" eq $previous) { internal_warn("ecx input not working for cpuid.4 on `$cpu'"); last; } $previous = "$eax,$ebx,$ecx,$edx"; } else { last; } $i++; } } if ($cpuid_ext_level >= 0x80000007) { ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 0x80000007, 0, 0); if ($status) { $features->{CONSTANT_TSC}++ if ((hex($edx) >> 8) & 0x01); } } if ($cpuid_ext_level >= 0x80000008) { ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 0x80000008, 0, 0); if ($status) { $cpus{cpus}{$cpu}{physical_address_bits} = ((hex($eax) >> 0) & 0xff); $cpus{cpus}{$cpu}{virtual_address_bits} = ((hex($eax) >> 8) & 0xff); } } ($status, $hi, $lo) = msr($n, 0x008b); if ($status) { $cpus{cpus}{$cpu}{microcode_sig} = sprintf("0x%08x", hex($hi)); } ($status, $hi, $lo) = msr($n, 0x00cd); if ($status) { my(%fsb) = ( 5 => '400MHz', 1 => '533MHz', 3 => '667MHz', 2 => '800MHz', 0 => '1067MHz', 4 => '1333MHz', 6 => '1600MHz', ); $cpus{cpus}{$cpu}{fsb_freq} = $fsb{((hex($lo) >> 0) & 0x07)}; } ($status, $hi, $lo) = msr($n, 0x00ce); if ($status) { $cpus{cpus}{$cpu}{normal_freq} = int(((hex($lo) >> 8) & 0xff) * $base_clock); $cpus{cpus}{$cpu}{slow_freq} = int(((hex($hi) >> 8) & 0xff) * $base_clock); } ($status, $hi, $lo) = msr($n, 0x00e2); if ($status) { my(%cstate) = ( 0 => 'C0', 1 => 'C1', 2 => 'C3', 3 => 'C6', 4 => 'C7', 7 => 'None', ); $cpus{cpus}{$cpu}{cstate_limit} = $cstate{((hex($lo) >> 0) & 0x07)}; } ($status, $hi, $lo) = msr($n, 0x003a); if ($status) { $features_disabled->{VMX}++ unless ((hex($lo) >> 2) & 0x01); } ($status, $hi, $lo) = msr($n, 0x01aa); if ($status) { $cpus{cpus}{$cpu}{eist_hcd} = ((hex($lo) >> 0) & 0x01); $cpus{cpus}{$cpu}{epbe} = ((hex($lo) >> 1) & 0x01); } ($status, $hi, $lo) = msr($n, 0x01ac); if ($status) { $cpus{cpus}{$cpu}{tdp_limit} = ((hex($lo) >> 0) & 0x7F); $cpus{cpus}{$cpu}{tdc_limit} = ((hex($lo) >> 16) & 0x7F); } ($status, $hi, $lo) = msr($n, 0x01ad); if ($status) { my($hex) = hex($lo); my(@freqs); foreach my $i (1 .. 4) { last unless ($hex && 0xff); push(@freqs, int(($hex & 0xff) * $base_clock)); $hex = $hex >> 8; } $hex = hex($hi); foreach my $i (1 .. 4) { last unless ($hex && 0xff); push(@freqs, int(($hex & 0xff) * $base_clock)); $hex = $hex >> 8; } $cpus{cpus}{$cpu}{turbo_frequencies} = join(' ', @freqs); $features->{TURBO}++; } ($status, $hi, $lo) = msr($n, 0x01a0); if ($status) { # this EIST bit doesn't seem accurate, often on even when disabled in BIOS $features_disabled->{EIST}++ unless ((hex($lo) >> 16) & 0x01); $features_disabled->{NX}++ if ((hex($hi) >> 2) & 0x01); $features_disabled->{TURBO}++ if ($features->{TURBO} && (hex($hi) >> 6) & 0x01); } } elsif ($vendor =~ /AMD/) { if ($cpuid_level >= 6) { ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 6, 0, 0); if ($status) { $features->{APERFMPERF}++ if ((hex($ecx) >> 0) & 0x01); } } if ($cpuid_ext_level >= 0x80000007) { ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 0x80000007, 0, 0); if ($status) { $power_features->{TS}++ if ((hex($edx) >> 0) & 0x01); $power_features->{TTP}++ if ((hex($edx) >> 3) & 0x01); $power_features->{TM}++ if ((hex($edx) >> 4) & 0x01); $power_features->{STC}++ if ((hex($edx) >> 5) & 0x01); $power_features->{'100MHZSTEPS'}++ if ((hex($edx) >> 6) & 0x01); $power_features->{HWPSTATE}++ if ((hex($edx) >> 7) & 0x01); $features->{CONSTANT_TSC}++ if ((hex($edx) >> 8) & 0x01); $features->{CPB}++ if ((hex($edx) >> 9) & 0x01); # AMD turbo } } if ($cpuid_ext_level >= 0x8000000a) { ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 0x8000000a, 0, 0); if ($status) { $features->{NPT}++ if ((hex($edx) >> 0) & 0x01); $features->{LBRV}++ if ((hex($edx) >> 1) & 0x01); $features->{SVML}++ if ((hex($edx) >> 2) & 0x01); $features->{NRIPS}++ if ((hex($edx) >> 3) & 0x01); } } if ($cpuid_ext_level >= 0x8000001e) { ($status, $eax, $ebx, $ecx, $edx) = cpuid($n, 0x8000001e, 0, 1); if ($status) { $cpus{cpus}{$cpu}{nodeid} = ((hex($ecx) >> 0) & 0xff); $cpus{cpus}{$cpu}{nodes_per_proc} = ((hex($ecx) >> 8) & 0x07); } } elsif ($features->{NODEID_MSR}) { ($status, $hi, $lo) = msr($n, 0xc001100c); if ($status) { $cpus{cpus}{$cpu}{nodeid} = ((hex($lo) >> 0) & 0x07); $cpus{cpus}{$cpu}{nodes_per_proc} = ((hex($lo) >> 3) & 0x07) + 1; } } ($status, $hi, $lo) = msr($n, 0xc0000080); if ($status) { $features_disabled->{SVM}++ unless ((hex($lo) >> 2) & 0x01); } } $cpus{cpus}{$cpu}{features_support} = features_to_string($features, $features_disabled); $cpus{cpus}{$cpu}{features_disabled} = features_to_string($features_disabled); if (defined $apic_id) { $apic_to_cpu{$apic_id} = $cpu; } } foreach my $cache (keys %{$cpus{caches}}) { @{$cpus{caches}->{$cache}->{apic_id}} = sort { $a <=> $b } @{$cpus{caches}->{$cache}->{apic_id}}; my $pkg; my $core; my $prev_pkg; my $prev_core; my $one_core = 1; foreach my $apic (@{$cpus{caches}->{$cache}->{apic_id}}) { my $cpu; if (defined $apic_to_cpu{$apic}) { $cpu = $apic_to_cpu{$apic}; } else { $one_core = 0; } $pkg = $cpus{cpus}{$cpu}{topology}{package_id}; if (defined $prev_pkg && $prev_pkg != $pkg) { internal_warn("package_id mismatch for cache `$cache'"); } $prev_pkg = $pkg; $core = $cpus{cpus}{$cpu}{topology}{core_id}; if (defined $prev_core && $prev_core != $core) { $one_core = 0; } $prev_core = $core; } if (defined $pkg) { $cpus{caches}->{$cache}->{package_id} = $pkg; } if (defined $core && $one_core) { $cpus{caches}->{$cache}->{core_id} = $core; } } if (keys %{$topology}) { my($threads) = 0; my($cores) = 0; my($pkgs) = 0; foreach my $pkg (keys %{$topology}) { $pkgs++; foreach my $core (keys %{$topology->{$pkg}}) { $cores++; foreach my $thread (keys %{$topology->{$pkg}->{$core}}) { $threads++; } } } foreach my $n (sort { $a <=> $b } @cpus) { my $cpu = "cpu$n"; my($pkg) = $cpus{cpus}{$cpu}{topology}{package_id}; my(@count) = keys %{$topology}; $cpus{cpus}{$cpu}{topology}{pkg_siblings} = $#count + 1; my($core) = $cpus{cpus}{$cpu}{topology}{core_id}; @count = keys %{$topology->{$pkg}}; $cpus{cpus}{$cpu}{topology}{core_siblings} = $#count + 1; my($thread) = $cpus{cpus}{$cpu}{topology}{thread_id}; @count = keys %{$topology->{$pkg}->{$core}}; $cpus{cpus}{$cpu}{topology}{thread_siblings} = $#count + 1; } $cpus{topology}{active_pkgs} = $pkgs; $cpus{topology}{active_cores} = $cores; $cpus{topology}{active_threads} = $threads; $cpus{topology}{threads_per_core} = $threads{0}; $cpus{topology}{threads_per_pkg} = $threads{1}; my($cores_per_pkg) = int($threads{1}/$threads{0}); $cpus{topology}{cores_per_pkg} = $cores_per_pkg; $cpus{topology}{total_threads} = $pkgs * $threads{1}; $cpus{topology}{total_cores} = $pkgs * $cores_per_pkg; } return $result; } sub sysctl_cpu { # assume grok_sysctl_dev() has already run if ($sysctl_dev_raw{cpu}) { my($save_freq, $save_levels) = ('', ''); foreach my $n (sort keys %{$sysctl_dev_raw{cpu}}) { my $cpu = "cpu$n"; # as of 20090429 only cpu.0 has any data and it controls all cores. # so for now, we need to use the $save vars my($freq) = $sysctl_dev_raw{cpu}{$n}{freq} || ''; $freq *= 1000000 if $freq; $save_freq = $freq if ($freq); $cpus{cpus}{$cpu}{scaling_cur_freq} = $save_freq;; my($levels) = $sysctl_dev_raw{cpu}{$n}{freq_levels} || ''; # nuke power data, don't have any use for it today $levels =~ s/(\d+)\/([0-9\-]+)/${1}000000/g; $save_levels = $levels if ($levels); $cpus{cpus}{$cpu}{scaling_available_frequencies} = $save_levels; } } } sub nvram_freebsd { my $result = ''; nvram_c_init(); if ($nvram_c_path && -x $nvram_c_path) { $result = `$nvram_c_path 2> /dev/null`; } return $result; } sub nvram_linux { my($fh) = new IO::File; my($dev) = '/dev/port'; my($result) = ''; if (-e $dev) { if ($fh->open("+< $dev")) { for (my $i=0; $i<256; $i++) { sysseek($fh, ($i<128) ? 0x70 : 0x72, SEEK_SET) || return; my $char = pack('C', $i % 128); $fh->syswrite($char, 1); $fh->sysread($char, 1); $result .= sprintf("%02X", unpack('C', $char)); } } } return $result; } sub nvram { my $nvram = ''; if ($os_type eq 'linux') { $nvram = nvram_linux(); } elsif ($os_type eq 'freebsd') { $nvram = nvram_freebsd(); } # zero out rtc substr($nvram, 0, 28) = '00' x 14; return $nvram; } my $blocks; sub block_register { my($vol, $args) = @_; trace("block_register vol = $vol"); foreach my $key (keys %{$args}) { my $val = $args->{$key}; next if !defined $val; $val = clean_white($val); $blocks->{vols}->{$vol}->{$key}->{$val}++; $blocks->{attrs}->{$key}->{$val}->{$vol}++; trace("\t$key -> $val"); if ($key eq 'bytes') { block_register($vol, { 'size' => print_bytes($val, 1000, 1), }); } } } sub block_match_attr { my($hash, $attr, $val) = @_; my($result) = 0; if ($attr eq 'size') { my($check) = parse_bytes($val, 1000); if ($check) { foreach my $key (keys %{$hash->{$attr}}) { my($bytes) = parse_bytes($key, 1000); if (abs(($check - $bytes) / $check) < 0.01) { $result = 1; last; } } } } elsif ($hash->{$attr}->{$val}) { $result = 1; } return $result; } sub block_match { my($args) = @_; my $result; my %hit; my %miss; trace("looking for block_match"); foreach my $attr (keys %{$args}) { my $val = $args->{$attr}; trace("\tmatching $attr, $val"); next if !defined $val; $val = clean_white($val); foreach my $vol (keys %{$blocks->{vols}}) { if ($blocks->{vols}->{$vol}->{$attr}) { if (block_match_attr($blocks->{vols}->{$vol}, $attr, $val)) { $hit{vol}->{$vol}++; $hit{attr}->{$attr}++; trace("\t\thit for $attr=$val on $vol"); } else { $miss{vol}->{$vol}++; trace("\t\tmiss for $attr on $vol"); } } } } my $max = keys %{$hit{attr}}; foreach my $vol (keys %{$hit{vol}}) { trace("\tvol $vol score = $hit{vol}->{$vol} (max = $max)"); if ($hit{vol}->{$vol} == $max && !$miss{vol}->{$vol}) { if ($result) { # ambiguous, could return list here, but for now return undef trace("\tambiguous result = $vol"); return; } trace("\tresult = $vol"); $result = $vol; } } return $result; } sub dev_disk { my($dir) = '/dev/disk/by-id'; if (-d $dir) { my($dd) = new DirHandle; $dd->open($dir) || warn("opendir: $dir: $!"); foreach my $link ($dd->read) { next if ($link =~ /-part\d+$/); if ($link =~ /^scsi-SATA_(([^_]+)_)?([^_]+)_([^_]+)$/) { my($vendor, $model, $serial) = ($2, $3, $4); my($dev) = readlink("$dir/$link"); $dev =~ s{.*/}{}; my(@drives) = keys %{$drives{$dev}}; if ($#drives == 0) { $props{drives}{$drives[0]}{serial} = $serial; } } } $dd->close; } } sub sys_module { my($result) = 0; my($root) = "/sys/module"; my($dd) = new DirHandle; return $result if (! -d $root); $dd->open($root) || warn("opendir: $root: $!"); foreach my $mod ($dd->read) { my($file) = "$root/$mod/version"; my($cat); if (-f $file) { $cat = clean_white(`cat $file 2> /dev/null`); if ($cat) { $driver_version{$mod} = $cat; $result++; } } } $dd->close; return $result; } sub sys_block { my($result) = 0; my($root) = "/sys/block"; my($dd) = new DirHandle; return $result if (! -d $root); $dd->open($root) || warn("opendir: $root: $!"); my(@vols) = grep(/^(hd|sd|cciss)/, $dd->read); $dd->close; my($path, $file); my($cat); foreach my $vol (@vols) { $path = "$root/$vol"; $vol =~ s/\!/\//; $file = "$path/queue/scheduler"; if (-f $file) { $cat = clean_white(`cat $file 2> /dev/null`); if ($cat =~ /\[(.+)\]/) { $props{volumes}{$vol}{scheduler} = $1; } } next unless (-l "$path/device"); $result++; $file = "$path/device/queue_depth"; if (-f $file) { $props{volumes}{$vol}{queue_depth} = clean_white(`cat $file 2> /dev/null`); } my($size); $file = "$path/size"; if (-f $file) { $size = clean_white(`cat $file 2> /dev/null`); $props{volumes}{$vol}{bytes} = $size * 512; } block_register($vol, { 'bytes' => $size * 512, }); if ($vol =~ /^cciss\/c(\d+)d\d+$/) { my($raid); my($controller) = "cciss$1"; $file = "$path/device/raid_level"; if (-f $file) { $raid = canon_raid(clean_white(`cat $file 2> /dev/null`)); } block_register($vol, { 'controller' => $controller, 'driver' => 'cciss', 'raid' => $raid, }); } elsif ($vol =~ /^sd/) { # for now just parse sd drives for /proc/scsi/scsi replacement my($link) = readlink("$path/device"); if ($link =~ m{/host\d+/.*/(\d+):(\d+):(\d+):(\d+)$}) { my($host, $channel, $id, $lun) = ($1, $2, $3, $4); $got_sysblock++; my($model, $vendor, $rev, $sas_addr, $sas_handle); $file = "$path/device/model"; if (-f $file) { $model = clean_white(`cat $file 2> /dev/null`); } $file = "$path/device/vendor"; if (-f $file) { $vendor = clean_white(`cat $file 2> /dev/null`); } $file = "$path/device/rev"; if (-f $file) { $rev = clean_white(`cat $file 2> /dev/null`); } $file = "$path/device/sas_address"; if (-f $file) { $sas_addr = clean_white(`cat $file 2> /dev/null`); } $file = "$path/device/sas_device_handle"; if (-f $file) { $sas_handle = hex(clean_white(`cat $file 2> /dev/null`)); } my($vendor_model) = "$vendor $model"; my($device) = "host$host"; my($driver) = $hostid_to_driver{$device} || ''; block_register($vol, { 'controller' => $driver, 'vendor' => $vendor, 'model' => $model, 'firmware' => $rev, 'host' => $host, 'channel' => $channel, 'id' => $id, 'lun' => $lun, 'sas_address' => $sas_addr, 'sas_handle' => $sas_handle, }); # skip the case where lshal has already filled in this info if (!defined $props{volumes}{$vol}{source}{lshal}) { $volumes{$vol}++; $props{volumes}{$vol}{raid} = parse_model_for_raid($vendor_model); $props{volumes}{$vol}{device} = $device if ($device); $props{volumes}{$vol}{source}{sysblock} = 1; $drives{$vol}{$drive_id}++; $props{drives}{$drive_id}{type} = 'scsi-volume'; $props{drives}{$drive_id}{model} = canon_drive($vendor_model); $props{drives}{$drive_id}{firmware} = $rev; $props{drives}{$drive_id}{volume} = $vol; $props{drives}{$drive_id}{size} = $props{volumes}{$vol}{bytes}; if ($vendor_model =~ /^($ignore_scsi_models)/) { $props{volumes}{$vol}{hidden} = 1; $props{drives}{$drive_id}{hidden} = 1; } smartctl($vol, "/dev/$vol", $vendor, $drive_id); hdparm($vol, "/dev/$vol", $drive_id); $drive_id++; $ndrives++; my($logical) = sprintf("scsi%d-%d-%d-%d", $host, $channel, $id, $lun); my($logical_channel) = sprintf("scsi%d-%d", $host, $channel); $logical_to_os{all}{dev}{$logical} = $vol; $logical_to_os{all}{channel}{$logical_channel}++; if ($vendor_model =~ /$perc_names/ || $driver =~ /megaraid_sas/) { $logical_to_os{perc}{dev}{$logical} = $vol; $logical_to_os{perc}{channel}{$logical_channel}++; } elsif ($vendor_model =~ /MegaRAID/ || $driver =~ /megaraid/) { $logical_to_os{megaraid}{dev}{$logical} = $vol; $logical_to_os{megaraid}{channel}{$logical_channel}++; } elsif ($vendor_model =~ /LSILOGIC/ || $driver =~ /(mptsas|mptspi)/) { $logical_to_os{lsi}{dev}{$logical} = $vol; $logical_to_os{lsi}{channel}{$logical_channel}++; } elsif ($vendor_model =~ /(3ware|AMCC)/ || $driver =~ /3w/) { $logical = sprintf("c%d-u%d", $host, $id); $logical_to_os{tw}{dev}{$logical} = $vol; $logical_to_os{tw}{channel}{$logical_channel}++; } else { $logical_to_os{other}{dev}{$model} = $vol; $logical_to_os{other}{channel}{$logical_channel}++; } } if ($vendor_model =~ /$perc_names/) { # no /i so that PepperC doesn't match PERC $need_megacli++; } elsif ($vendor_model =~ /MegaRAID/) { $need_megarc++; $want_megacli++; } elsif ($vendor_model =~ /LSILOGIC/) { $need_linuxmpt++; } elsif ($vendor_model =~ /(3ware|AMCC)/) { $need_twcli++; } if ($driver =~ /($linux_mpt_drivers)/ && $vendor_model !~ /VMware/) { $want_linuxmpt++; $need_linuxmpt++ if ($vendor_model =~ /(LSILOGIC|VIRTUAL)/); } elsif ($driver =~ /mpt2sas/) { $need_linuxmpt2++; } elsif ($driver =~ /megaraid_sas/) { $need_megacli++; } elsif ($driver =~ /megaraid/) { $need_megarc++; } elsif ($driver =~ /3w/) { $need_twcli++; } elsif ($driver =~ /aacraid/) { $need_arcconf++; } } } } return $result; } sub sys_cpu { my($result) = 0; my($root) = '/sys/devices/system/cpu'; my($dd) = new DirHandle; # we assume we've already run cpuinfo by this point return $result unless (-d $root); $dd->open($root) || warn("opendir: $root: $!"); my(@cpus) = grep(/^cpu\d+/, $dd->read); $dd->close; foreach my $cpu (@cpus) { my($cat); my($dir) = "$root/$cpu/cpufreq"; if (-d $dir) { $cat = clean_white(`cat $dir/scaling_available_governors 2> /dev/null`); $cpus{cpus}{$cpu}{scaling_available_governors} = $cat; $cat = clean_white(`cat $dir/scaling_governor 2> /dev/null`); $cpus{cpus}{$cpu}{scaling_governor} = $cat; $cat = clean_white(`cat $dir/scaling_driver 2> /dev/null`); $cpus{cpus}{$cpu}{scaling_driver} = $cat; $cat = clean_white(`cat $dir/scaling_available_frequencies 2> /dev/null`); $cat =~ s/(\d+)/${1}000/g; $cpus{cpus}{$cpu}{scaling_available_frequencies} = $cat; $cat = clean_white(`cat $dir/scaling_cur_freq 2> /dev/null`); $cat =~ s/(\d+)/${1}000/g; $cpus{cpus}{$cpu}{scaling_cur_freq} = $cat; } $dir = "$root/$cpu/cache"; if (-d $dir) { $dd->open($dir) || warn("opendir: $dir: $!"); my(@caches) = grep(/^index\d+/, $dd->read); $dd->close; foreach my $cache (sort @caches) { my($level, $size); chomp($level = `cat $dir/$cache/level 2> /dev/null`); chomp($size = `cat $dir/$cache/size 2> /dev/null`); $cpus{cpus}{$cpu}{"l${level}_cache_size"} = parse_bytes($size, 1024); } } my($file) = "$root/$cpu/online"; if (-f $file) { $cpus{cpus}{$cpu}{online} = clean_white(`cat $file 2> /dev/null` || '1'); } else { $cpus{cpus}{$cpu}{online} = 1; } } return $result; } sub top_memory { my($total) = 0; my($fh) = new IO::File; my($cmd); my($line); $cmd = "top -n"; trace($cmd); $fh->open("$cmd 2> /dev/null |") || return 0; $debug_memory .= ">> $cmd\n"; while ($line = <$fh>) { $debug_memory .= $line; chomp($line); if ($line =~ /^Mem:/) { # Mem: 2016M Active, 724M Inact, 377M Wired, 89M Cache, 163M Buf, 51M Free $total += parse_bytes($1, 1024) if ($line =~ /(\S+) Active/); $total += parse_bytes($1, 1024) if ($line =~ /(\S+) Inact/); $total += parse_bytes($1, 1024) if ($line =~ /(\S+) Wired/); $total += parse_bytes($1, 1024) if ($line =~ /(\S+) Cache/); $total += parse_bytes($1, 1024) if ($line =~ /(\S+) Free/); } } $fh->close; return $total; } sub decode_drive { my($part, $id) = @_; my($result) = ''; # http://www.wdc.com/en/library/2579-001028.pdf my($wd) = { 'form' => { 'A' => '3.5"', 'B' => '2.5"', 'C' => '1.0"', 'E' => '3.5"', 'F' => '3.5"', 'G' => '3.5"', 'H' => '3.5"', 'J' => '2.5"', }, 'brand' => { 'A' => 'WD Caviar', 'B' => 'WD RE (3-platter)', 'C' => 'WD Protege', 'D' => 'WD Raptor', 'E' => 'WD Scorpio', 'H' => 'WD Raptor X', 'J' => 'WD Scorpio FFS', 'K' => 'WD Scorpio S25', 'L' => 'WD VelociRaptor', 'M' => 'WD Branded', 'V' => 'WD AV', 'Y' => 'WD RE (4-platter)', }, 'rpm' => { 'A' => { 'rpm' => 5400, 'cache' => 2 * 1024 * 1024, }, 'B' => { 'rpm' => 7200, 'cache' => 2 * 1024 * 1024, }, 'C' => { 'rpm' => 5400, 'cache' => 16 * 1024 * 1024, }, 'D' => { 'rpm' => 5400, 'cache' => 32 * 1024 * 1024, }, 'E' => { 'rpm' => 7200, 'cache' => 64 * 1024 * 1024, }, 'F' => { 'rpm' => 10000, 'cache' => 16 * 1024 * 1024, }, 'G' => { 'rpm' => 10000, 'cache' => 8 * 1024 * 1024, }, 'H' => { 'rpm' => 10000, 'cache' => 32 * 1024 * 1024, }, 'J' => { 'rpm' => 7200, 'cache' => 8 * 1024 * 1024, }, 'K' => { 'rpm' => 7200, 'cache' => 16 * 1024 * 1024, }, 'L' => { 'rpm' => 7200, 'cache' => 32 * 1024 * 1024, }, 'P' => { 'rpm' => 5400, # intellipower }, 'R' => { 'rpm' => 5400, 'cache' => 64 * 1024 * 1024, }, 'S' => { 'rpm' => 7200, 'cache' => 64 * 1024 * 1024, }, 'V' => { 'rpm' => 5400, 'cache' => 8 * 1024 * 1024, }, 'Y' => { 'rpm' => 7200, }, }, 'int' => { 'A' => 'ATA/66', 'B' => 'ATA/100', 'C' => 'ATA', 'D' => 'SATA/150', 'E' => 'ATA/144', 'F' => 'SAS/3', 'G' => 'SAS/6', 'S' => 'SATA/300', 'T' => 'SATA/300', 'X' => 'SATA/600', }, }; if ($part =~ /\bWD(\d{2,4})([ABCEFGHJ])([ABCDEHJKLMVY])([ABCDEFGHJKLPRSVY])([ABCDEFGSTX])\b/) { my($size, $form, $brand, $rpm, $int) = ($1, $2, $3, $4, $5); if ($brand =~ /[BDKLY]/) { $size =~ s/.$/0/; # drop last digit if enterprise } if ($form =~ /[F]/) { $size =~ s/^(\d)(\d+)$/$1.$2/; } else { $size =~ s/^(\d+)(\d)$/$1.$2/; } if ($form =~ /[EFJ]/) { $size = $size * 1000000000000; } else { $size = $size * 1000000000; } $result = print_bytes($size, 1000, 1); $result .= ' ' . print_rpm($wd->{rpm}->{$rpm}->{rpm}); $result .= " $wd->{int}->{$int}"; $result .= " $wd->{form}->{$form}"; $result .= " $wd->{brand}->{$brand}"; $result .= " $wd->{rpm}->{$rpm}->{cache}" if $wd->{rpm}->{$rpm}->{cache}; } elsif ($part =~ /^((COMPAQ|HP|ATA)-?)?(BD|BF|DB|DD|DF|DG|DH|EF|EG|EH|FB|FJ|GB|MB)([0-9]{3,4})([0-9A-Z]{5})\b/) { my($vendor, $type, $size, $seq) = ($2, $3, $4, $5); $result = print_bytes($size*1000*1000*1000, 1000, 1); $result .= ' '; if ($type eq "BD") { $result .= "10K "; if (hex($seq) >= 0x85A24) { $result .= "U320 "; } else { $result .= "SCSI "; } } elsif ($type eq "BF") { $result .= "15K "; if (hex($seq) >= 0x84961) { $result .= "U320 "; } else { $result .= "SCSI "; } } elsif ($type eq "DB") { $result .= "7.2K SAS/3 "; } elsif ($type eq "DD") { $result .= "10K SAS/3 "; } elsif ($type eq "DF") { $result .= "15K SAS/3 "; } elsif ($type eq "EF") { $result .= "15K SAS/6 "; } elsif ($type eq 'DG' || $type eq 'EG') { $result .= "10K SAS"; $result .= (length($size) > 3) ? "/6" : "/3"; $result .= " 2.5\" "; } elsif ($type eq 'DH' || $type eq 'EH') { $result .= "15K SAS"; $result .= (length($size) > 3) ? "/6" : "/3"; $result .= " 2.5\" "; } elsif ($type eq "FB") { $result .= "7.2K SATA/150 "; } elsif ($type eq "FJ") { $result .= "5.4K SATA/150 "; } elsif ($type eq "GB" || $type eq "MB") { $result .= "7.2K "; if ($props{drives}{$id}{interface} && $props{drives}{$id}{interface} =~ /SATA/) { $result .= "SATA/300 "; } elsif ($vendor && $vendor eq 'ATA') { $result .= "SATA/300 "; } else { $result .= "SAS/3 "; } } $result .= "HP"; } return $result; } sub decode_memory { my($part) = @_; my($result) = ''; my($ecc) = 0; my($ddr_peak) = { 'SDRAM-100' => 'PC100', 'SDRAM-133' => 'PC133', 'DDR-266' => 'PC-2100', 'DDR-333' => 'PC-2700', 'DDR-400' => 'PC-3200', 'DDR2-400' => 'PC2-3200', 'DDR2-533' => 'PC2-4200', 'DDR2-667' => 'PC2-5300', 'DDR2-800' => 'PC2-6400', 'DDR2-1066' => 'PC2-8500', 'DDR3-800' => 'PC3-6400', 'DDR3-1066' => 'PC3-8500', 'DDR3-1333' => 'PC3-10600', 'DDR3-1600' => 'PC3-12800', }; # http://www.elpida.com/pdfs/ECT-TS-1984.pdf my($elpida) = { 'family' => { 'J' => { 'family' => 'DDR3', 'speed' => { 'GN' => { 'speed' => '1600', 'cl' => '11', }, 'DJ' => { 'speed' => '1333', 'cl' => '9', }, 'AE' => { 'speed' => '1066', 'cl' => '7', }, '8C' => { 'speed' => '800', 'cl' => '6', }, }, }, 'E' => { 'family' => 'DDR2', 'speed' => { '8E' => { 'speed' => '800', 'cl' => '5', }, '8G' => { 'speed' => '800', 'cl' => '6', }, '6E' => { 'speed' => '667', 'cl' => '5', }, '5C' => { 'speed' => '533', 'cl' => '4', }, '4A' => { 'speed' => '400', 'cl' => '3', }, }, }, 'D' => { 'family' => 'DDR', 'speed' => { '5B' => { 'speed' => '400', 'cl' => '3', }, '5C' => { 'speed' => '400', 'cl' => '3', }, '6B' => { 'speed' => '333', 'cl' => '2.5', }, '75' => { 'speed' => '266', 'cl' => '2', }, '7A' => { 'speed' => '266', 'cl' => '2', }, '7B' => { 'speed' => '266', 'cl' => '2.5', }, }, }, }, 'size' => { '12' => { 'size' => 128 * 1024 * 1024, 'ranks' => 1, }, '13' => { 'size' => 128 * 1024 * 1024, 'ranks' => 2, }, '25' => { 'size' => 256 * 1024 * 1024, 'ranks' => 1, }, '26' => { 'size' => 256 * 1024 * 1024, 'ranks' => 2, }, '51' => { 'size' => 512 * 1024 * 1024, 'ranks' => 1, }, '52' => { 'size' => 512 * 1024 * 1024, 'ranks' => 2, }, '10' => { 'size' => 1 * 1024 * 1024 * 1024, 'ranks' => 1, }, '11' => { 'size' => 1 * 1024 * 1024 * 1024, 'ranks' => 2, }, '20' => { 'size' => 2 * 1024 * 1024 * 1024, 'ranks' => 1, }, '21' => { 'size' => 2 * 1024 * 1024 * 1024, 'ranks' => 2, }, '40' => { 'size' => 4 * 1024 * 1024 * 1024, 'ranks' => 1, }, '41' => { 'size' => 4 * 1024 * 1024 * 1024, 'ranks' => 2, }, '42' => { 'size' => 4 * 1024 * 1024 * 1024, 'ranks' => 4, }, '80' => { 'size' => 8 * 1024 * 1024 * 1024, 'ranks' => 1, }, '81' => { 'size' => 8 * 1024 * 1024 * 1024, 'ranks' => 2, }, '82' => { 'size' => 8 * 1024 * 1024 * 1024, 'ranks' => 4, }, }, 'type' => { 'A' => { 'type' => 'Registered', # with addr parity 'ecc' => 1, }, 'H' => { 'type' => 'Registered', # with heat spreader 'ecc' => 1, }, 'R' => { 'type' => 'Registered', 'ecc' => 1, }, 'U' => { 'type' => 'Unbuffered', 'ecc' => 0, }, 'E' => { 'type' => 'Unbuffered', 'ecc' => 1, }, 'F' => { 'type' => 'Fully Buffered', 'ecc' => 1, }, }, 'density' => { 'B' => { 'size' => 128 * 1024 * 1024, 'package' => 'SDP', }, 'C' => { 'size' => 256 * 1024 * 1024, 'package' => 'SDP', }, 'D' => { 'size' => 512 * 1024 * 1024, 'package' => 'SDP', }, 'E' => { 'size' => 1 * 1024 * 1024 * 1024, 'package' => 'SDP', }, 'F' => { 'size' => 2 * 1024 * 1024 * 1024, 'package' => 'SDP', }, '1' => { 'size' => 2 * 1024 * 1024 * 1024, 'package' => 'DDP', } }, 'org' => { '4' => 4, '8' => 8, '6' => 16, }, }; # http://www.qimonda.com/download.jsp?ref=/qis_docs/Downloads%20Computing/DDR2%20%26%20DDR_SDRAM_Mod.pdf my($qimonda) = { 'width' => { # no useful pattern here '16301' => '1Rx8', '32000' => '1Rx8', # oops - 72T32000HR5A (1Rx8) vs. 64T32000HU3.7A (1Rx16) '32300' => '1Rx4', '64000' => '1Rx8', '64001' => '1Rx8', '64300' => '1Rx4', '64400' => '1Rx8', '64020' => '2Rx8', '64320' => '2Rx8', '128000' => '1Rx4', '128001' => '1Rx8', '128300' => '1Rx4', '128020' => '2Rx8', '128320' => '2Rx4', '128420' => '2Rx8', '128520' => '2Rx4', '128521' => '2Rx4', '256000' => '1Rx4', '256020' => '2Rx8', '256220' => '2Rx4', '256420' => '2Rx4', '256920' => '2Rx4', '512022' => '2Rx4 DDP', '512220' => '2Rx4', '512420' => '2Rx4', '512520' => '2Rx4', '512920' => '2Rx4', '512922' => '2Rx4 DDP', '512040' => '4Rx8', }, 'ecc' => { '64' => 0, '72' => 1, }, 'family' => { 'D' => 'DDR', 'T' => 'DDR2', }, 'size' => { '32' => 256 * 1024 * 1024, '64' => 512 * 1024 * 1024, '128' => 1 * 1024 * 1024 * 1024, '256' => 2 * 1024 * 1024 * 1024, '512' => 4 * 1024 * 1024 * 1024, '1G' => 8 * 1024 * 1024 * 1024, }, 'ranks' => { '0' => 1, '2' => 2, '4' => 4, }, 'type' => { 'U' => 'Unbuffered', 'R' => 'Registered', 'P' => 'Registered', # with addr parity 'F' => 'Fully Buffered', }, 'speed' => { '7F' => { 'speed' => '266', 'cl' => '2', }, '7' => { 'speed' => '266', 'cl' => '2', }, '6' => { 'speed' => '333', 'cl' => '2.5', }, '5' => { 'speed' => '400', 'cl' => '3', }, '3.7' => { 'speed' => '533', 'cl' => '4', }, '3S' => { 'speed' => '667', 'cl' => '5', }, '3' => { 'speed' => '667', 'cl' => '4', }, '2.5' => { 'speed' => '800', 'cl' => '6', }, '25F' => { 'speed' => '800', 'cl' => '5', }, '19H' => { 'speed' => '1066', 'cl' => '5', }, '19F' => { 'speed' => '1066', 'cl' => '6', }, '1.9' => { 'speed' => '1066', 'cl' => '7', }, }, }; # http://download.micron.com/pdf/numbering/numsdrammod.pdf my($micron) = { # TBD }; # http://www.hynix.com/inc/pdfDownload.jsp?path=/upload/products/gl/products/dram/down/DDR2MODULE.pdf # http://www.hynix.com/inc/pdfDownload.jsp?path=/upload/products/gl/products/dram/down/DDR3MODULE.pdf my($hynix) = { 'family' => { 'P' => 'DDR2', 'T' => 'DDR3', }, 'density' => { '2' => 256 * 1024 * 1024, '5' => 512 * 1024 * 1024, '1' => 1 * 1024 * 1024 * 1024, '3' => 2 * 1024 * 1024 * 1024, '4' => 4 * 1024 * 1024 * 1024, '8' => 8 * 1024 * 1024 * 1024, }, 'size' => { '16' => 128 * 1024 * 1024, '32' => 256 * 1024 * 1024, '64' => 512 * 1024 * 1024, '12' => 1 * 1024 * 1024 * 1024, '25' => 2 * 1024 * 1024 * 1024, '51' => 4 * 1024 * 1024 * 1024, '1G' => 8 * 1024 * 1024 * 1024, '2G' => 16 * 1024 * 1024 * 1024, '4G' => 32 * 1024 * 1024 * 1024, '8G' => 64 * 1024 * 1024 * 1024, }, 'type' => { 'U' => 'Unbuffered', 'S' => 'Unbuffered', # 200pin SO-DIMM 'R' => 'Registered', 'P' => 'Registered', # with addr parity 'B' => 'Fully Buffered', 'F' => 'Fully Buffered', }, 'ecc' => { '6' => 0, '64' => 0, '7' => 1, '72' => 1, }, 'package' => { 'F' => 'SDP', 'S' => 'Stack', 'M' => 'DDP', 'H' => 'QDP', }, 'org' => { '4' => 4, '8' => 8, '6' => 16, }, 'speed' => { 'E3' => { 'speed' => '400', 'cl' => '3', }, 'C4' => { 'speed' => '533', 'cl' => '4', }, 'Y4' => { 'speed' => '667', 'cl' => '4', }, 'Y5' => { 'speed' => '667', 'cl' => '5', }, 'S5' => { 'speed' => '800', 'cl' => '5', }, 'S6' => { 'speed' => '800', 'cl' => '6', }, 'G6' => { 'speed' => '1066', 'cl' => '6', }, 'G7' => { 'speed' => '1066', 'cl' => '7', }, 'G8' => { 'speed' => '1066', 'cl' => '8', }, 'H8' => { 'speed' => '1333', 'cl' => '8', }, 'H9' => { 'speed' => '1333', 'cl' => '9', }, 'HA' => { 'speed' => '1333', 'cl' => '10', }, 'P9' => { 'speed' => '1600', 'cl' => '9', }, 'PA' => { 'speed' => '1600', 'cl' => '10', }, 'PB' => { 'speed' => '1600', 'cl' => '11', }, }, }; # http://www.elixir-memory.com/sup_name_rul_2.asp # very similar to nanya (elixir is sub-brand), use most of nanya def my($elixir) = { 'type' => { 'U' => 'Unbuffered', 'P' => 'Unbuffered', 'Y' => 'Unbuffered', # green 'D' => 'Fully Buffered', 'L' => 'Registered', 'K' => 'Registered', 'J' => 'Registered', }, }; # http://www.nanya.com/NanyaAdmin/GetFiles.ashx?ID=351 # very similar to elixir my($nanya) = { 'size' => { '256' => 256 * 1024 * 1024, '512' => 512 * 1024 * 1024, '1G' => 1 * 1024 * 1024 * 1024, '2G' => 2 * 1024 * 1024 * 1024, '4G' => 4 * 1024 * 1024 * 1024, '8G' => 8 * 1024 * 1024 * 1024, }, 'family' => { 'D' => 'DDR', 'T' => 'DDR2', 'C' => 'DDR3', }, 'ecc' => { '64' => 0, '72' => 1, }, 'voltage' => { 'C' => 1.35, 'B' => 1.5, 'U' => 1.8, 'S' => 2.5, }, 'org' => { '4' => 4, '8' => 8, 'H' => 16, }, 'chips' => { '4' => 4, '8' => 8, '9' => 8, 'H' => 16, 'P' => 16, 'N' => 32, }, 'type' => { 'Y' => 'Unbuffered', 'F' => 'Unbuffered', 'V' => 'Registered', 'K' => 'Registered', 'L' => 'Registered', 'N' => 'Fully Buffered', 'D' => 'Fully Buffered', 'E' => 'Fully Buffered', 'U' => 'Registered', # not documented 'G' => 'Unbuffered', # not documented }, 'speed' => { '75B' => { 'speed' => '266', 'cl' => '2.5', }, '6' => { 'speed' => '333', 'cl' => '2.5', }, '6K' => { 'speed' => '333', 'cl' => '2.5', }, '5' => { 'speed' => '400', 'cl' => '2.5', }, '5T' => { 'speed' => '400', 'cl' => '3', }, '5A' => { 'speed' => '400', 'cl' => '3', }, '5B' => { 'speed' => '400', 'cl' => '4', }, '37' => { # not documented 'speed' => '533', 'cl' => '4', }, '37A' => { # not documented 'speed' => '533', 'cl' => '3', }, '37B' => { 'speed' => '533', 'cl' => '4', }, '3C' => { 'speed' => '667', 'cl' => '5', }, '25C' => { 'speed' => '800', 'cl' => '5', }, 'AC' => { 'speed' => '800', 'cl' => '5', }, '2C' => { 'speed' => '800', 'cl' => '5', }, '25D' => { 'speed' => '800', 'cl' => '6', }, 'AD' => { 'speed' => '800', 'cl' => '6', }, 'BC' => { 'speed' => '1066', 'cl' => '5', }, 'BD' => { 'speed' => '1066', 'cl' => '6', }, 'BE' => { 'speed' => '1066', 'cl' => '7', }, 'BF' => { 'speed' => '1066', 'cl' => '8', }, 'CF' => { 'speed' => '1333', 'cl' => '8', }, 'CG' => { 'speed' => '1333', 'cl' => '9', }, 'DG' => { 'speed' => '1600', 'cl' => '9', }, 'DH' => { 'speed' => '1600', 'cl' => '10', }, 'EG' => { 'speed' => '1866', 'cl' => '9', }, 'EH' => { 'speed' => '1866', 'cl' => '10', }, 'EH' => { 'speed' => '2133', 'cl' => '10', }, }, }; # Samsung SDRAM, DDR, DDR2, DDR3 # http://www.samsung.com/global/business/semiconductor/products/dram/downloads/ddr2_product_guide_aug_09.pdf # http://www.samsung.com/global/system/business/semiconductor/family/2009/1/28/410927DDR3_SDRAM_Module.pdf # http://www.samsung.com/global/business/semiconductor/partnumberDecoder.do my($samsung) = { 'base' => { 'S' => 'SDRAM', 'L' => 'DDR', 'T' => 'DDR2', 'B' => 'DDR3', }, 'dimm' => { '3' => 'DIMM', '4' => 'SODIMM', }, 'type' => { '12' => { 'type' => 'Registered', 'ecc' => 1, 'low_profile' => 1, }, '66' => { 'type' => 'Unbuffered', 'ecc' => 0, }, '68' => { 'type' => 'Unbuffered', 'ecc' => 0, }, '70' => { 'type' => 'Unbuffered', 'ecc' => 0, }, '71' => { # 204pin Unbuffered SODIMM 'type' => 'Unbuffered', 'ecc' => 0, }, '74' => { 'type' => 'Unbuffered', 'ecc' => 1, }, '78' => { # 240pin Unbuffered DIMM 'type' => 'Unbuffered', 'ecc' => 0, }, '81' => { 'type' => 'Unbuffered', 'ecc' => 1, }, '83' => { 'type' => 'Registered', 'ecc' => 1, }, '91' => { # 240pin ECC unbuffered DIMM 'type' => 'Unbuffered', 'ecc' => 1, }, '92' => { # 240pin VLP Registered DIMM 'type' => 'Registered', 'ecc' => 1, }, '93' => { # 240pin Registered DIMM 'type' => 'Registered', 'ecc' => 1, }, '95' => { 'type' => 'Fully Buffered', 'ecc' => 1, }, }, 'size_rank' => { '164' => { 'size' => 128 * 1024 * 1024, 'rank' => 1, }, '323' => { 'size' => 256 * 1024 * 1024, 'rank' => 1, }, '333' => { 'size' => 256 * 1024 * 1024, 'rank' => 2, }, '334' => { 'size' => 256 * 1024 * 1024, 'rank' => 1, }, '640' => { 'size' => 512 * 1024 * 1024, 'rank' => 1, }, '643' => { 'size' => 512 * 1024 * 1024, 'rank' => 2, }, '644' => { 'size' => 512 * 1024 * 1024, 'rank' => 1, }, '653' => { 'size' => 512 * 1024 * 1024, 'rank' => 1, }, '654' => { 'size' => 512 * 1024 * 1024, 'rank' => 2, }, '283' => { 'size' => 1 * 1024 * 1024 * 1024, 'rank' => 1, }, '284' => { 'size' => 1 * 1024 * 1024 * 1024, 'rank' => 2, }, '290' => { 'size' => 1 * 1024 * 1024 * 1024, 'rank' => 1, }, '293' => { 'size' => 1 * 1024 * 1024 * 1024, 'rank' => 2, }, '560' => { 'size' => 2 * 1024 * 1024 * 1024, 'rank' => 1, }, '563' => { 'size' => 2 * 1024 * 1024 * 1024, 'rank' => 2, }, '570' => { 'size' => 2 * 1024 * 1024 * 1024, 'rank' => 2, }, '573' => { 'size' => 2 * 1024 * 1024 * 1024, 'rank' => 1, }, '510' => { 'size' => 4 * 1024 * 1024 * 1024, 'rank' => 2, }, '513' => { 'size' => 4 * 1024 * 1024 * 1024, 'rank' => 4, }, '516' => { 'size' => 4 * 1024 * 1024 * 1024, 'rank' => 2, }, '520' => { 'size' => 4 * 1024 * 1024 * 1024, 'rank' => 1, }, '523' => { 'size' => 4 * 1024 * 1024 * 1024, 'rank' => 2, }, '1G0' => { 'size' => 8 * 1024 * 1024 * 1024, 'rank' => 4, }, '1K0' => { 'size' => 8 * 1024 * 1024 * 1024, 'rank' => 2, }, '1K3' => { 'size' => 8 * 1024 * 1024 * 1024, 'rank' => 4, }, '1K6' => { 'size' => 8 * 1024 * 1024 * 1024, 'rank' => 2, }, '2K0' => { 'size' => 16 * 1024 * 1024 * 1024, 'rank' => 4, }, }, 'org' => { '0' => 4, '3' => 8, '4' => 16, '6' => 4, }, 'package' => { 'Z' => 'SDP', 'J' => 'DDP', 'Q' => 'QDP', 'H' => 'SDP', 'M' => 'DDP', 'E' => 'QDP', }, 'speed' => { '7A' => { 'speed' => '133', 'cl' => '3', }, '7C' => { 'speed' => '133', 'cl' => '2', }, '1L' => { 'speed' => '100', 'cl' => '3', }, '1H' => { 'speed' => '100', 'cl' => '2', }, 'B0' => { 'speed' => '266', 'cl' => '2.5', }, 'A2' => { 'speed' => '266', 'cl' => '2', }, 'B3' => { 'speed' => '333', 'cl' => '2.5', }, 'CC' => { 'speed' => '400', 'cl' => '3', }, 'D5' => { 'speed' => '533', 'cl' => '4', }, 'E6' => { 'speed' => '667', 'cl' => '5', }, 'F7' => { 'speed' => '800', 'cl' => '6', }, 'E7' => { 'speed' => '800', 'cl' => '5', }, 'F8' => { 'speed' => '1066', 'cl' => '7', }, 'H9' => { 'speed' => '1333', 'cl' => '9', }, 'K0' => { 'speed' => '1600', 'cl' => '11', }, }, }; my($base, $type, $size, $speed, $cl, $bits, $chips, $ranks, $vendor); my($ddp) = 0; my($qdp) = 0; if ($part =~ /^HY?M/) { my($family, $density, $depth, $type_code, $width, $die, $power, $pkg, $lead, $org, $rev, $amb, $speed_code, $options); if ($part =~ /^HM([PT])([251348])(16|32|64|12|25|51|1G|2G|4G|8G)([URPFS])([67])([MABCDEFGT])([FMH])([LPR])([486])([CLEIA])-(E3|C4|Y4|Y5|S5|S6|G6|G7|H8|H9|HA|P9|PA|PB)(..)?$/) { ($family, $density, $depth, $type_code, $width, $die, $pkg, $lead, $org, $power, $speed_code, $options) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12); } elsif ($part =~ /^HYM(P)([25134])(16|32|64|12|25|51|1G|2G|4G|8G)([BFPRUS])(64|72)([ABCDEFG])?([L])?([SMH])?([PR])?([486])([RLT])?([NEDCPAM].)?-?(E3|C4|Y4|Y5|S5|S6|G7)$/) { ($family, $density, $depth, $type_code, $width, $die, $power, $pkg, $lead, $org, $rev, $amb, $speed_code) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13); } if ($family) { $size = $hynix->{size}->{$depth} || return; $base = $hynix->{family}->{$family} || return; $type = $hynix->{type}->{$type_code} || return; $ecc = $hynix->{ecc}->{$width}; $bits = $hynix->{org}->{$org} || return; my($dense) = $hynix->{density}->{$density} || return; $chips = ($size * 8) / $dense; if ($pkg && $hynix->{package}->{$pkg}) { $ddp = ($hynix->{package}->{$pkg} eq 'DDP'); $chips *= 2 if ($ddp); $qdp = ($hynix->{package}->{$pkg} eq 'QDP'); $chips *= 4 if ($qdp); } $ranks = int(($chips * $bits) / 64); $speed = $hynix->{speed}->{$speed_code}->{speed} || return; $cl = $hynix->{speed}->{$speed_code}->{cl} || return; $speed = "$base-$speed"; $vendor = 'Hynix'; } } if ($part =~ /^(64|72)([DT])(32|64|128|256|512|1G).([024]).([GHE])(U|R|BR|P|F|M|D|BD)([LAND]?)(7F|7|6|5|3\.7|3S|3|2\.5|25F|19H|19F|1\.9)..?$/) { my($width, $family, $size_code, $ranks_code, $mod, $speed_code) = ($1, $2, $3, $4, $6, $8); $size = $qimonda->{size}->{$size_code} || return; $base = $qimonda->{family}->{$family} || return; $type = $qimonda->{type}->{$mod} || return; $ecc = $qimonda->{ecc}->{$width}; $ranks = $qimonda->{ranks}->{$ranks_code} || return; $bits = 0; # can't decode $speed = $qimonda->{speed}->{$speed_code}->{speed} || return; $cl = $qimonda->{speed}->{$speed_code}->{cl} || return; $speed = "$base-$speed"; $vendor = 'Qimonda'; } if ($part =~ /^EB([DEJ])(12|13|25|26|51|52|10|11|20|21|40|41|42|80|81|82)([ARUEFH])([BCDEF1])([486])([ABE]).([FNWHSUDR]).-(7B|7A|75|6B|5B|4A|5C|6E|8G|8E|8C|AE|DJ|GN)(-.)?$/) { my($family, $size_code, $type_code, $density, $org, $speed_code) = ($1, $2, $3, $4, $5, $8); $base = $elpida->{family}->{$family}->{family} || return; $size = $elpida->{size}->{$size_code}->{size} || return; $ranks = $elpida->{size}->{$size_code}->{ranks} || return; $type = $elpida->{type}->{$type_code}->{type} || return; $ecc = $elpida->{type}->{$type_code}->{ecc}; $bits = $elpida->{org}->{$org} || return; $speed = $elpida->{family}->{$family}->{speed}->{$speed_code}->{speed} || return; $cl = $elpida->{family}->{$family}->{speed}->{$speed_code}->{cl} || return; $ddp = ($elpida->{density}->{$density}->{package} eq 'DDP'); $speed = "$base-$speed"; $vendor = 'Elpida'; } # the (T?) was (T)? which perl v5.005_03 incorrectly matches for NT1GT72U8PA0BY-37B if ($part =~ /^NT(256|512|1G|2G|4G|8G)(T?)([DTC])(64|72)([SUBC])([48H])([489HPN])([ABCDEFG])([0123478])([GFBFJMUYNP]?)([YVNDEFKLUG])-(75B|6|6K|5|5T|5A|37|37B|3C|25C|AC|25D|AD|BE|BF|CF|CG)$/) { my($size_code, $ddp_code, $family, $width, $power, $comp, $chips_code, $die, $rev, $pkg, $mod, $speed_code) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12); $size = $nanya->{size}->{$size_code} || return; $ddp = 1 if ($ddp_code); $base = $nanya->{family}->{$family} || return; $type = $nanya->{type}->{$mod} || return; $ecc = $nanya->{ecc}->{$width}; $bits = $nanya->{org}->{$comp} || return; $chips = $nanya->{chips}->{$chips_code} || return; $chips *= 2 if ($ddp); $ranks = int(($chips * $bits) / 64); $speed = $nanya->{speed}->{$speed_code}->{speed} || return; $cl = $nanya->{speed}->{$speed_code}->{cl} || return; $speed = "$base-$speed"; $vendor = 'Nanya'; } if ($part =~ /^M2([UPDYNSFXLKJ])(512|1G|2G|4G)(T?)(64|72)([DTC])([SUBC])([48H])([489HPN])([ABCD])([01234])([GFBJFMUNP])-(75B|6K|5T|5A|5B|37|37A|37B|3C|25C|AC|2C|25D|AD|BC|BD|BE|BF|CF|CG|DG|DH|EG|EH|FH)$/) { my($mod, $size_code, $ddp_code, $width, $family, $power, $comp, $chips_code, $die, $rev, $pkg, $speed_code) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12); $size = $nanya->{size}->{$size_code} || return; $ddp = 1 if ($ddp_code); $base = $nanya->{family}->{$family} || return; $type = $elixir->{type}->{$mod} || return; $ecc = $nanya->{ecc}->{$width}; $bits = $nanya->{org}->{$comp} || return; $chips = $nanya->{chips}->{$chips_code} || return; $chips *= 2 if ($ddp); $ranks = int(($chips * $bits) / 64); $speed = $nanya->{speed}->{$speed_code}->{speed} || return; $cl = $nanya->{speed}->{$speed_code}->{cl} || return; $speed = "$base-$speed"; $vendor = 'Elixir'; } if ($part =~ /^M([34]) ?(12|66|68|70|71|74|78|81|83|91|92|93|95)([SLTB])(09|16|17|32|33|64|65|28|29|56|57|51|52|1G|1K|2G|2K)([12567])([0346789])([MABCDEFGHJQR])([TUNVGSZYJQHME])([01234ALMNUSPD])-([CLY])(7A|7C|1L|1H|B0|A2|B3|CC|D5|E6|F7|E7|F8|F9|H9|K0)(.)?.?$/) { my($dimm_type, $type_code, $base_code, $depth, $banks, $org_code, $chip_rev, $pkg, $pcb_rev, $power, $speed_code, $amb) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12); $base = $samsung->{base}->{$base_code} || return; $type = $samsung->{type}->{$type_code}->{type} || return; $ecc = $samsung->{type}->{$type_code}->{ecc}; $size = $samsung->{size_rank}->{"$depth$org_code"}->{size} || return; $ranks = $samsung->{size_rank}->{"$depth$org_code"}->{rank} || return; $bits = $samsung->{org}->{$org_code} || return; $speed = $samsung->{speed}->{$speed_code}->{speed} || return; $cl = $samsung->{speed}->{$speed_code}->{cl} || return; if ($samsung->{package}->{$pkg}) { $ddp = ($samsung->{package}->{$pkg} eq 'DDP'); $qdp = ($samsung->{package}->{$pkg} eq 'QDP'); } $speed = "$base-$speed"; $vendor = 'Samsung'; } if ($size) { $result .= print_bytes($size, 1024, 1); $result .= " $ddr_peak->{$speed}"; $result .= " $vendor"; if ($base eq 'SDRAM') { $result .= " $base"; } else { $result .= " $speed"; } $result .= " ECC" if ($ecc); $result .= " $type"; $result .= " CL$cl"; $result .= " ${ranks}R"; $result .= "x$bits" if ($bits); $result .= " DDP" if ($ddp); $result .= " QDP" if ($qdp); } return $result; } sub memory { my($system) = @_; my($mem, $memory) = ("", ""); my($total_visible) = 0; my($total_physical) = 0; my($total) = 0; my($fh) = new IO::File; if (-r $meminfo) { my($in) = "MEMINFO"; $fh->open("< $meminfo") || warn "open: $meminfo: $!"; $debug_memory .= ">> cat /proc/meminfo\n"; while (my $line = <$fh>) { $debug_memory .= $line; chomp($line); if ($line =~ /^Mem:\s*(\d+)/i) { $total = $1; } elsif ($line =~ /^MemTotal:\s*(\d+)\s*kB/i) { $total = $1 * 1024 unless $total; } } $fh->close; } else { # first check with dmesg if ($dmesg_buf =~ /^Physical memory chunk/m) { my($match) = 0; foreach my $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); if (!$total) { # no dmesg and sysctl not working $total = top_memory(); } } $total_visible = $total; $mem = print_bytes($total, 1024, 1, 100); # probably shouldn't force int=1 here, but didn't have .0 in legacy if ($smbios{'Memory'}{'Count'}) { my($sum) = 0; my($device, %device); my($sep) = ""; my($speed) = 0; my($type); foreach my $i (1 .. $smbios{'Memory'}{'Count'}) { my($size) = $smbios{'Memory'}{$i}{'Size'}; if ($size =~ /(\d+)(MB)?/i) { $size = $1 * 1024 * 1024; if ($size) { # 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; my $key = "$size,"; $key .= $smbios{'Memory'}{$i}{'Part Number'} if ($smbios{'Memory'}{$i}{'Part Number'}); push(@{$device{$key}{ids}}, $i); $device{$key}{count}++; } $total_physical = $sum; $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 my $key (keys %device) { my($size, $part) = ($key =~ /^(.*?),(.*)/); my($found) = ''; if ($part) { foreach my $try (keys %memory_models) { if ($part =~ /^$try$/i) { $found = $memory_models{$try}; last; } } if (!$found) { $found = decode_memory($part); if (!defined($found)) { internal_warn("decode_memory failed on `$part'"); $found = ''; } } if ($found) { foreach my $i (@{$device{$key}{ids}}) { $smbios{'Memory'}{$i}{pretty} = $found; } } else { $debug .= "Debug-Memory:\t$part\n"; } } $pretty{"$size,$found"} += $device{$key}{count}; } $sep = ""; # sort by memory size first, then number of dimms, then length of description foreach my $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 = ", "; } } } # warnings if ($kernel{boot}{memory} && $kernel{boot}{memory} < $total_physical) { # memory is limited at boot user_warn(1, 10026, "only " . print_bytes($kernel{boot}{memory}, 1024, 1) . " of " . print_bytes($total_physical, 1024, 1) . " memory is active due to kernel boot limit"); } return ($mem, $memory, $total_visible, $total_physical); } # consolidate drive data to main id, e.g. get data from pass devices to augment mfiutil data sub resolve_disks { my(%serials); foreach my $id (keys %{$props{drives}}) { my($serial) = $props{drives}{$id}{serial} || ''; if ($serial) { $serials{$serial}{$id} = 1; } } foreach my $id (keys %{$props{drives}}) { next if ($id == 0); next if $props{drives}{$id}{hidden}; my($serial) = $props{drives}{$id}{serial} || ''; if ($serial) { foreach my $try (keys %{$serials{$serial}}) { foreach my $key ('tcq_support', 'tcq_depth', 'tcq_depth', 'wcache_support', 'wcache_enable', 'rcache_support', 'rcache_enable', 'rpm', 'arre', 'awre', 'size', 'speed') { if (!defined $props{drives}{$id}{$key} && defined $props{drives}{$try}{$key}) { $props{drives}{$id}{$key} = $props{drives}{$try}{$key}; } } } } } } sub print_network { my($result) = ''; foreach my $interface (sort cmp_devs keys %interfaces) { next if ($interfaces{$interface}{hidden}); next if ($interface =~ /^($ignore_networks)\d+$/); my($driver) = $interface_to_driver{$interface}; $result .= "Network:\t$interface"; $result .= " ($driver)" if ($driver); $result .= ": "; my($sep) = ''; if ($driver && $interfaces{$driver} && $interfaces{$driver}{model}) { # only example of this is msk0 (interface) -> mskc0 (pci-device/driver) $result .= $interfaces{$driver}{model}; $sep = ', '; } elsif ($interfaces{$interface}{model}) { $result .= $interfaces{$interface}{model}; $sep = ', '; } if ($interfaces{$interface}{mac}) { $result .= "$sep$interfaces{$interface}{mac}"; $sep = ', '; } if (defined($interfaces{$interface}{status})) { if ($interfaces{$interface}{status} eq "active") { $result .= "$sep$interfaces{$interface}{media}" if ($interfaces{$interface}{media}); } else { $result .= "$sep$interfaces{$interface}{status}"; } } $result .= "\n"; if ($opts{verbose} && defined $interfaces{$interface}{xml_handle}) { my $xml = $handle_to_xml{$interfaces{$interface}{xml_handle}}; my @opts; push(@opts, "firmware=$xml->{firmware}") if ($xml->{firmware}); if ($xml->{pci_handle}) { my $pci = $handle_to_xml{$xml->{pci_handle}}; if ($pci->{driver}) { my $driver = $pci->{driver}->{name}; if ($pci->{driver}->{version}) { $driver .= '-' . $pci->{driver}->{version}; } push(@opts, "driver=$driver"); } } if (@opts) { $result .= "\t\t\t" . join(', ', @opts) . "\n"; } @opts = (); push(@opts, "speed=$xml->{speed}") if ($xml->{speed}); push(@opts, "duplex=$xml->{duplex}") if ($xml->{duplex}); push(@opts, "auto=$xml->{autoselect}") if ($xml->{autoselect}); push(@opts, "mtu=$xml->{mtu}") if ($xml->{mtu}); push(@opts, "status=$xml->{status}") if ($xml->{status}); if (@opts) { $result .= "\t\t\t" . join(', ', @opts) . "\n"; } if ($xml->{flags}) { $result .= "\t\t\tflags=$xml->{flags}\n"; } if ($xml->{options}) { $result .= "\t\t\toptions=$xml->{options}\n"; } foreach my $ip (@{$xml->{ip}}) { $result .= "\t\t\tinet $ip->{address}"; $result .= " netmask $ip->{netmask}" if $ip->{netmask}; $result .= " broadcast $ip->{broadcast}" if $ip->{broadcast}; $result .= "\n"; } } } return $result; } sub print_disks { my($result) = ''; foreach my $volume (sort { cmp_disks($a, $b) } keys %volumes) { next if ($volume =~ /^ata-/); next unless ($drives{$volume} || $props{volumes}{$volume}{bytes}); next if ($props{volumes}{$volume}{hidden}); next if ($volume =~ /^ar\d+$/ && !($props{volumes}{$volume}{df} && $props{volumes}{$volume}{df}{size})); my(%pretty); my($count) = 0; foreach my $key (keys %{$drives{$volume}}) { next if $props{drives}{$key}{hidden}; my($found) = 0; my($model) = $props{drives}{$key}{model} || "Unknown"; if ($model) { # smartcl has been known to reverse the model, serial, firmware data. seems to be very rare. e.g. TS13003004SN my($reversed) = $model; my($crunched) = $model; $reversed =~ s/(.)(.)/$2$1/g; $crunched =~ s/[^0-9a-z]//ig; # find all matches my(%matches); foreach my $try (keys %drive_models) { if ($model =~ /($try)/i || $reversed =~ /($try)/i || $crunched =~ /($try)/i) { if (defined $matches{$1}) { internal_warn("ambiguous match for `$model': `$matches{$1}' and `$try'"); } else { $matches{$1} = $try; } } } # find longest match my $pretty; if (keys %matches) { my $match = (sort { length($b) <=> length($a) } keys %matches)[0]; my $try = $matches{$match}; $props{drives}{$key}{'model_match'} = $match; if (ref($drive_models{$try}) eq "HASH") { $pretty = $drive_models{$try}{pretty}; } else { $pretty = $drive_models{$try}; } $found++; } else { # match the reverse way to deal with chopped models by things like cissutil my($clean) = $model; $clean =~ s/^(ATA-)?((Hitachi|Fujitsu|Maxtor|Intel)-)?//i; my($total_matches) = 0; foreach my $try (keys %drive_models) { if ($try =~ /^$clean/i) { if (ref($drive_models{$try}) eq "HASH") { $pretty = $drive_models{$try}{pretty}; } else { $pretty = $drive_models{$try}; } my($new) = $pretty; $new =~ s/^[\d\.]+(MB|GB|TB|PB)/%B/; $matches{$new} = $pretty; $total_matches++; } } my(@matches) = keys %matches; if ($#matches == 0) { $found++; my($match) = $matches[0]; if ($total_matches == 1) { # can use original pretty $pretty = $matches{$match}; } else { # use the %B version $pretty = $match; $debug .= "Debug-Disk-Ambiguous:\t$model resolved $total_matches matches\n"; } } elsif ($#matches > 0) { $debug .= "Debug-Disk-Ambiguous:\t$model unresolved $total_matches matches\n"; } } if ($found) { my($size) = $props{drives}{$key}{size} || 0; if ($size) { $pretty =~ s/\%B/print_bytes($size, 1000, 1)/e; } else { $pretty =~ s/\%B\s*//; } $props{drives}{$key}{'pretty'} = $pretty; $pretty{$pretty}++; } } if (!$found) { unless (($model =~ /^($ignore_disk_models)/i) || $props{drives}{$key}{no_debug}) { $debug .= "Debug-Disk:\t$model\n"; } my($guess) = decode_drive($model, $key); if ($guess) { $props{drives}{$key}{'pretty'} = $guess; $pretty{$guess}++; $found++; } } if (!$found) { my($str) = ''; my($size) = $props{drives}{$key}{size} || 0; $str .= print_bytes($size, 1000, 1) . ' ' if ($size); my($rpm) = print_rpm($props{drives}{$key}{rpm} || 0); $str .= $rpm . ' ' if ($rpm); my($interface) = $props{drives}{$key}{interface} || ''; $str .= parse_drive_interface($interface) . ' ' if ($interface); my($speed) = $props{drives}{$key}{speed} || ''; $str .= print_rate($speed, 1024, 1) . ' ' if ($speed); $str .= $model; $pretty{$str}++; } $count++ if ($found); } if (!$props{volumes}{$volume}{raid} && $count == 1) { $props{volumes}{$volume}{raid} = 'JBOD'; } my($out) = "$volume"; my($out_dev) = ""; if ($props{volumes}{$volume}{channel}) { my($channel) = $props{volumes}{$volume}{channel}; my($dev) = $props{channels}{$channel}{device}; $props{volumes}{$volume}{device} = $dev unless ($props{volumes}{$volume}{device}); if ($dev) { my($driver) = device_to_driver($dev); $out_dev .= "$driver:"; $props{volumes}{$volume}{driver} = $driver; } $channel =~ s/^ahcich/ch/; $out_dev .= $channel; $out_dev .= '-' . substr($props{volumes}{$volume}{ms}, 0, 1) if (defined $props{volumes}{$volume}{ms}); } elsif ($props{volumes}{$volume}{device}) { my($driver) = device_to_driver($props{volumes}{$volume}{device}); $out_dev .= $driver; $props{volumes}{$volume}{driver} = $driver; $out_dev .= "-" . substr($props{volumes}{$volume}{'ms'}, 0, 1) if $props{volumes}{$volume}{'ms'}; } elsif ($props{volumes}{$volume}{driver}) { $out_dev .= $props{volumes}{$volume}{driver}; $out_dev .= "-" . substr($props{volumes}{$volume}{'ms'}, 0, 1) if $props{volumes}{$volume}{'ms'}; } elsif ($dmesg_buf =~ /^$volume at (\S+)/m) { $out_dev .= $1; $props{volumes}{$volume}{driver} = $1; } elsif ($dmesg_buf =~ /^$volume: <.*> on (\S+)/m) { $out_dev .= $1; $props{volumes}{$volume}{driver} = $1; } next if ($out_dev =~ /^umass/); $out .= " ($out_dev)" if ($out_dev); $out .= ":"; my($bytes) = 0; if ($props{volumes}{$volume}{bytes}) { $out .= " " . print_bytes($props{volumes}{$volume}{bytes}, 1000, 0); $bytes = $props{volumes}{$volume}{bytes}; } elsif ($props{volumes}{$volume}{df}{size}) { $out .= " " . print_bytes($props{volumes}{$volume}{df}{size}, 1000, 0); } if ($props{volumes}{$volume}{usage}) { $out .= sprintf(" (%d%%)", round($props{volumes}{$volume}{usage} * 100)); } my($raid) = canon_raid($props{volumes}{$volume}{raid}); if ($raid) { $props{volumes}{$volume}{raid} = $raid; if ($props{volumes}{$volume}{spans} && $props{volumes}{$volume}{spans} > 1) { $raid .= "0" if ($raid eq "RAID-1"); $props{volumes}{$volume}{raid} = $raid; $raid .= "/$props{volumes}{$volume}{spans}"; } my(@keys) = keys %{$drives{$volume}}; # if raid-1, drives > 3 and no span data, assume raid-10 if (($raid eq "RAID-1") && ($#keys > 2) && !defined($props{volumes}{$volume}{spans})) { $raid .= "0"; $props{volumes}{$volume}{raid} = $raid; } $out .= " $raid"; } # this output is meant for debugger, will hopefully use it later in real output # $out .= sprintf(" (stripe %s)", print_bytes($props{volumes}{$volume}{stripe}, 1024, 1)) if ($props{volumes}{$volume}{stripe}); if ($props{volumes}{$volume}{spare} || $props{volumes}{$volume}{free} || $props{volumes}{$volume}{failed} || $props{volumes}{$volume}{failing} || $props{volumes}{$volume}{rebuild} || $props{volumes}{$volume}{missing}) { $out .= " ("; my($sep) = ""; if ($props{volumes}{$volume}{spare}) { $out .= "$sep$props{volumes}{$volume}{spare} spare"; $sep .= ", "; } if ($props{volumes}{$volume}{free}) { $out .= "$sep$props{volumes}{$volume}{free} free"; $sep .= ", "; } if ($props{volumes}{$volume}{failed}) { $out .= "$sep$props{volumes}{$volume}{failed} failed"; $sep .= ", "; } if ($props{volumes}{$volume}{failing}) { $out .= "$sep$props{volumes}{$volume}{failing} failing"; $sep .= ", "; } if ($props{volumes}{$volume}{rebuild}) { $out .= "$sep$props{volumes}{$volume}{rebuild} rebuild"; $sep .= ", "; } if ($props{volumes}{$volume}{missing}) { $out .= "$sep$props{volumes}{$volume}{missing} missing"; $sep .= ", "; } $out .= ")"; } $result .= "Disk:\t\t"; $result .= $out; my($sep) = " == "; foreach my $key (sort { $pretty{$b} <=> $pretty{$a} || length($b) <=> length($a) } keys %pretty) { if ($volume =~ /^(md|ccd|ar|dm)\d+/) { $result .= "$sep$key"; } else { $result .= "$sep$pretty{$key} x $key"; } if ($opts{'n'}) { $sep = ", "; } else { $sep = sprintf("\n\t\t%*s", length($out) + 4, " "); } } $result .= "\n"; } return $result; } sub guess_yspec { my($cpus) = @_; my($yspec, $spec); # http://github.com/euriion/TomorrowWorks/sysinfo/guide/PEGTSRYSpec, hugo's brain # http://www.spec.org/cgi-bin/osgresults?conf=cpu2006 if ($cpus =~ /^2 x Xeon X5670/) { $yspec = '42.2'; $spec = 330; } elsif ($cpus =~ /^2 x Xeon X5650/) { $yspec = '39.5'; $spec = 318; } elsif ($cpus =~ /^2 x Xeon E5620/) { $yspec = '25.0'; $spec = 210; } elsif ($cpus =~ /^2 x Xeon X5570/) { $yspec = '29.1'; $spec = 234; } elsif ($cpus =~ /^2 x Xeon E5530/) { $yspec = '25.0'; $spec = 192; } elsif ($cpus =~ /^2 x Xeon E5520/) { $yspec = '21.7'; $spec = 185; } elsif ($cpus =~ /^2 x Xeon [EL]5420/) { $yspec = '17.4'; $spec = 99; } elsif ($cpus =~ /^2 x Xeon [EL]5335/) { $yspec = '13.0'; $spec = 78; } elsif ($cpus =~ /^2 x Xeon [EL]5320/) { $yspec = '11.7'; $spec = 64; } elsif ($cpus =~ /^2 x Xeon [EL]5310/) { $yspec = '10.0'; $spec = 59; } elsif ($cpus =~ /^1 x Xeon X3450/) { $yspec = '12.6'; $spec = 101; } elsif ($cpus =~ /^1 x Xeon X3440/) { $yspec = '12.4'; $spec = 98; } elsif ($cpus =~ /^1 x Xeon X3430/) { $yspec = '9.8'; $spec = 81; } elsif ($cpus =~ /^1 x Xeon X3350/) { $yspec = '9.7'; $spec = 62; } elsif ($cpus =~ /^1 x Xeon X3320/) { $yspec = '8.2'; $spec = 53; } elsif ($cpus =~ /^1 x Xeon X3220/) { $yspec = '8.0'; $spec = 50; } elsif ($cpus =~ /^1 x Xeon X3210/) { $yspec = '6.6'; $spec = 46; } elsif ($cpus =~ /^1 x Xeon 3050/) { $yspec = '3.4'; $spec = 23; } elsif ($cpus =~ /^2 x 3.00GHz.*Irwindale/) { $yspec = '3.1'; } elsif ($cpus =~ /^2 x 2.80GHz.*Irwindale/) { $yspec = '2.9'; } elsif ($cpus =~ /^2 x 2.80GHz.*Nocona/) { $yspec = '2.7'; } elsif ($cpus =~ /^Pentium D 3.40GHz.*Presler/) { $yspec = '3.1'; } elsif ($cpus =~ /^Pentium D 3.20GHz.*Presler/) { $yspec = '3.0'; } elsif ($cpus =~ /^Pentium D 3.00GHz.*Presler/) { $yspec = '2.8'; } elsif ($cpus =~ /^Pentium D 3.00GHz.*Smithfield/) { $yspec = '2.6'; } elsif ($cpus =~ /^Pentium D 2.80GHz.*Smithfield/) { $yspec = '2.4'; } return $yspec; } sub guess_ymodel { my($memory) = @_; my($ymodel) = ''; my($gigs) = int(($memory/1024/1024/1024)+0.5); my($drives) = 0; my($drive_type) = ''; my($cpu_model) = $procs{model} || ''; my($cpu_gen) = $procs{gen} || 0; my($cores) = $procs{cores} || 0; my(%drive_summary); my($chassis) = ''; my($bbu) = 0; if ($system_model_index) { $chassis = $system_models[$system_model_index]->{chassis} || ''; } if ($xml_top->{storage}->{drive}) { foreach my $drive (@{$xml_top->{storage}->{drive}}) { if ($drive->{pretty}) { # these should all be real hard drives, but will miss unknowns $drives++; if ($drive->{volume_handle}) { $xml = $handle_to_xml{$drive->{volume_handle}}; if ($xml->{controller_handle}) { $xml = $handle_to_xml{$xml->{controller_handle}}; if ($xml->{bbu}) { $bbu++; } } } if ($drive->{interface}) { $drive_type = $drive->{interface}; } else { $drive_type = parse_drive_interface($drive->{pretty}); } if ($drive->{pretty} =~ /^([\d\.]+(MB|GB|TB|PB)) (10K|15K)?/) { my($key) = print_bytes(parse_bytes($1, 1000), 1000, 1, 10, 'G'); $key .= "-$3" if ($3); $key .= " " . parse_drive_interface($drive->{pretty}); $drive_summary{$key}++; } else { $drive_summary{Unknown}++; } } } } my($drive_count, $drive_size) = (0, 0); my(@keys) = keys %drive_summary; if ($#keys == 0) { $drive_count = $drive_summary{$keys[0]}; $drive_size = $keys[0]; $drive_size =~ s/GB.*//; } if ($cpu_gen >= 4) { my($ycpu); if ($cpu_model =~ /(E5530|E5620)/) { $ycpu = 'N'; } elsif ($cpu_model =~ /X5650/) { $ycpu = 'P'; } elsif ($cpu_model =~ /X3440/) { $ycpu = 'M' } if ($ycpu && $cores > 6) { if ($drive_count == 1 && $drive_type =~ /^(ATA|SATA)$/) { $ymodel = 'C-2'; } elsif ($drive_count == 2 && $chassis eq '2U') { $ymodel = 'C-9'; } elsif ($drive_count == 2 && $drive_type =~ /^(ATA|SATA)$/) { $ymodel = 'C-8'; } elsif ($drive_count == 4) { $ymodel = 'C-4'; } elsif ($drive_count == 12) { $ymodel = 'C-5'; } elsif ($drive_count == 6) { if ($bbu) { $ymodel = 'C-98'; } else { $ymodel = 'C-99'; } } if ($ymodel) { $ymodel .= $ycpu; $ymodel .= "/$gigs"; $ymodel .= "/$drive_size"; } } elsif ($ycpu && $cores == 4) { if ($drives == 1 && $drive_type =~ /^(ATA|SATA)$/) { $ymodel = 'C-1'; } if ($ymodel) { $ymodel .= $ycpu; $ymodel .= "/$gigs"; $ymodel .= "/$drive_size"; } } } elsif ($cpu_gen >= 2) { if ($cores == 8) { if ($drives == 1 && $drive_type =~ /^(ATA|SATA)$/) { if ($gigs >= 16) { $ymodel = 'Config 3'; $ymodel .= " - ${gigs}G" if ($gigs != 16); } else { $ymodel = 'Config 2'; $ymodel .= " - ${gigs}G" if ($gigs != 8); } } elsif ($drives == 4) { if ($gigs >= 32) { $ymodel = 'Config 6'; $ymodel .= " - ${gigs}G" if ($gigs != 32); } else { $ymodel = 'Config 4'; $ymodel .= " - ${gigs}G" if ($gigs != 8); } } elsif ($drives == 6) { $ymodel = 'Config 5'; $ymodel .= " - ${gigs}G" if ($gigs != 16); } elsif ($drives == 12) { $ymodel = 'Config 5 - 12x' . $drive_type; $ymodel .= ", ${gigs}G" if ($gigs != 16); } } elsif ($cores == 4) { if ($drives == 1 && $drive_type =~ /^(ATA|SATA)$/) { $ymodel = 'Config 1'; $ymodel .= " - ${gigs}G" if ($gigs != 4); } } } elsif ($cores < 4 && $cpu_bits == 64 && $drives == 1) { $ymodel = 'C-0'; $ymodel .= "/$gigs"; $ymodel .= "/$drive_size"; } return $ymodel; } sub diff_cpu_models { my(@models) = @_; my($word); my($match); while (1) { if ($models[0] =~ /^(\S+)/) { $word = "\Q$1"; } else { last; } $match = 1; foreach my $i (0 .. $#models) { if ($models[$i] !~ /^$word/) { $match = 0; last; } } if ($match) { foreach my $i (0 .. $#models) { $models[$i] =~ s/^$word\s*//; } } else { last; } } while (1) { if ($models[0] =~ /(\S+)$/) { $word = "\Q$1"; } else { last; } $match = 1; foreach my $i (0 .. $#models) { if ($models[$i] !~ /$word$/) { $match = 0; last; } } if ($match) { foreach my $i (0 .. $#models) { $models[$i] =~ s/\s*$word$//; } } else { last; } } return @models; } sub check_cpu { if ($cpus{models}) { my(@models) = keys %{$cpus{models}}; if ($#models > 0) { my($models) = join(',', diff_cpu_models(@models)); user_warn(1, 10034, "cpu models '$models' do not match", $xml_top->{cpus}); } } if ($cpus{steppings}) { my(@steps) = keys %{$cpus{steppings}}; if ($#steps > 0) { unless ($hypervisor && $hypervisor =~ /(Xen|ESX)/) { user_warn(1, 10032, "cpu steppings do not match", $xml_top->{cpus}); } } } if ($os_type eq 'linux') { check_cpu_linux(); } } sub check_cpu_linux { my($dir) = "/sys/devices/system/cpu/cpu0/cpufreq"; my($avail) = ''; my($current) = ''; if (-e "$dir/scaling_governor") { chomp($current = `cat $dir/scaling_governor 2> /dev/null`); if ($current) { if ($current eq 'userspace') { my($pids); chomp($pids = `pidof cpuspeed` || ''); unless ($pids) { user_warn(100, 10030, "freq scaling governor 'userspace' requires cpuspeed daemon", $xml_top->{cpus}); } } elsif ($current ne 'ondemand') { user_warn(1, 10009, "freq scaling governor should be 'ondemand', not '$current'", $xml_top->{cpus}); } } } elsif ($cpus{cpus}->{cpu0}->{features_support} =~ /\bEIST\b/) { unless ($os_version < 206000000 || ($hypervisor && $hypervisor =~ /(Xen|ESX)/)) { system('chkconfig cpuspeed > /dev/null 2>&1'); if ($CHILD_ERROR) { user_warn(1, 10033, "cpuspeed service is not enabled", $xml_top->{cpus}); } else { user_warn(1, 10031, "SpeedStep appears to be disabled in the BIOS", $xml_top->{cpus}); } } } my($online) = 0; my($offline) = 0; foreach my $cpu (keys %{$cpus{cpus}}) { if (defined $cpus{cpus}->{$cpu}->{online}) { if ($cpus{cpus}->{$cpu}->{online}) { $online++; } else { $offline++; } } } if ($offline) { my($total) = $online + $offline; user_warn(1, 10035, "$offline out of $total cpus are offline", $xml_top->{cpus}); } } sub check_controllers { foreach my $id (sort { $a cmp $b } keys %{$props{controllers}}) { if (defined $props{controllers}{$id}{bbu_status}) { if ($props{controllers}{$id}{bbu_status} =~ /(failed)/) { user_warn(100, 10012, "battery has failed on controller '$id'", $props{controllers}{$id}{xml_handle}); $phone_home++; } elsif ($props{controllers}{$id}{bbu_status} =~ /(missing)/) { user_warn(1, 10013, "battery is missing on controller '$id'", $props{controllers}{$id}{xml_handle}); $phone_home++; } } my($cache) = $props{controllers}{$id}{write_cache}; if ($cache && $cache->{policy}) { # most accurate indication is policy if ($cache->{policy} eq 'write-through') { user_warn(1, 10022, "write cache is disabled on controller '$id'", $props{controllers}{$id}{xml_handle}); $phone_home++; } else { # we have write-back so no warning here, and no warning on disk write cache below } } elsif ($cache && defined $cache->{enable} && !$cache->{enable}) { # if we don't have policy, use enable, which is less accurate user_warn(1, 10022, "write cache is disabled on controller '$id'", $props{controllers}{$id}{xml_handle}); $phone_home++; } else { $cache = $props{controllers}{$id}{drive_write_cache}; if ($cache && $cache eq 'disabled') { user_warn(1, 10023, "drive write caches are disabled on controller '$id'", $props{controllers}{$id}{xml_handle}); $phone_home++; } } } } sub parse_nvram { return unless ($system_model_index && defined $system_models[$system_model_index]{'bios-spec'}); return unless ($xml_top->{bios} && $xml_top->{bios}->{nvram}); my($bios_version) = $xml_top->{bios}->{version}; my($date) = parse_date($xml_top->{bios}->{date}); my($nvram) = $xml_top->{bios}->{nvram}; my(@nvram) = ($nvram =~ m/../g); my(@models); foreach my $model (split(/,/, $system_models[$system_model_index]{'bios-spec'})) { if ($date && $bios_dates{$model}) { my $found = 0; foreach my $match (sort keys %{$bios_dates{$model}}) { if ($date >= $match) { $model = $bios_dates{$model}->{$match}; $found++; } } if (!$found) { internal_warn("BIOS date `$date' unrecognized for model `$model'"); } } elsif ($bios_version && $bios_versions{$model}) { my $found = 0; foreach my $match (keys %{$bios_versions{$model}}) { if ($bios_version =~ /$match/) { $model = $bios_versions{$model}->{$match}; $found++; last; } } if (!$found) { internal_warn("BIOS version `$bios_version' unrecognized for model `$model'"); } } push(@models, split(/,/, $model)); } foreach my $key (keys %bios_spec) { foreach my $model (@models) { if ($bios_spec{$key}->{$model}) { my $spec; if (ref($bios_spec{$key}->{$model}) eq 'HASH') { $spec = $bios_spec{$key}->{$model}; } else { $spec = $bios_spec{$key}->{$bios_spec{$key}->{$model}}; } my $index = $spec->{address}; my $mask = $spec->{mask}; my $length = $spec->{length} || 1; my $type = $spec->{type} || 'int'; if (defined $nvram[$index]) { my $val; if ($type eq 'int') { $val = hex(join('', @nvram[$index..($index+$length-1)])); while (($mask & 0x01) == 0) { $mask >>= 1; $val >>= 1; } $val &= $mask; } elsif ($type eq 'string') { $val = join('', map { sprintf("%c", hex($_)) } @nvram[$index..($index+$length-1)]); } if (ref($spec->{values}) eq 'HASH') { if (defined $spec->{values}->{$val}) { $xml_top->{bios}->{settings}->{$key} = $spec->{values}->{$val}; } else { internal_warn("BIOS setting `$key' has unknown value `$val'"); } } else { $xml_top->{bios}->{settings}->{$key} = eval $spec->{values}; } } last; } } } } sub check_memory { # currently only supports 1-2 socket systems return unless ($system_model_index && defined $system_models[$system_model_index]{'memory-population-order'}); my($warn) = 0; my(@order) = split(/,/, $system_models[$system_model_index]{'memory-population-order'}); my($slots) = $#order + 1; my(@slot_count, @channel_count, @match); my(@sockets) = split(/,/, $system_models[$system_model_index]{'memory-per-socket'} || '.'); my($sockets) = $#sockets + 1; my($channels) = $system_models[$system_model_index]{'memory-channels'} || 1; my($channels_per_socket) = $channels / ($system_models[$system_model_index]{'sockets'} || 1); my(@socket_count); # init foreach my $i (0 .. $sockets-1) { $socket_count[$i] = 0; foreach my $j (0 .. $channels_per_socket-1) { $channel_count[$i][$j] = 0; } foreach my $j (0 .. $slots-1) { $slot_count[$i][$j] = 0; } } my($dimms) = 0; foreach my $mem (@{$xml_top->{memory_array}->{system_memory}->{memory_device}}) { if ($mem->{size} && $mem->{locator}) { my $locator = $mem->{bank_locator} || ''; $locator .= '-' . $mem->{locator}; $dimms++; foreach my $i (0 .. $sockets-1) { if ($locator =~ /$sockets[$i]/) { $socket_count[$i]++; foreach my $j (0 .. $slots-1) { my($order, $channel); if ($order[$j] =~ /:/) { ($order, $channel) = split(/:/, $order[$j]); } else { $order = $order[$j]; $channel = $j % $channels_per_socket; } if ($locator =~ /$order/) { $slot_count[$i][$j]++; $channel_count[$i][$channel]++ if (defined $channel); push(@{$match[$i][$j]}, $mem); } } } } } } return unless $dimms; if ($sockets > 1 && $xml_top->{cpus}->{sockets_populated} && $xml_top->{cpus}->{sockets_populated} > 1) { foreach my $i (1 .. $sockets-1) { if ($socket_count[$i] != $socket_count[$i-1]) { user_warn(1, 10029, "memory not balanced across cpus 'CPU" . ($i-1) . "' and 'CPU" . $i . "'", $xml_top->{memory_array}->{system_memory}); $phone_home++; $warn++; } } return if $warn; # no need to belabor the point } my($imbalances) = $system_models[$system_model_index]{'memory-imbalances'} || 0; my(%imbalances); if ($imbalances) { foreach my $imbalance (split(/;/, $imbalances)) { $imbalances{$imbalance}++; } } my($equal_channels) = 1; my($all_clear) = 1; foreach my $i (0 .. $#channel_count) { my($slots_full) = 1; foreach my $j (0 .. $#{$slot_count[$i]}) { if (!$slot_count[$i][$j]) { $slots_full = 0; } } my($last); foreach my $j (0 .. $#{$channel_count[$i]}) { if ($j && $channel_count[$i][$j] != $last) { $equal_channels = 0; } $last = $channel_count[$i][$j]; } my($channel_pop) = join(',', sort @{$channel_count[$i]}); if ($equal_channels) { # balanced channels are good } elsif ($imbalances{$channel_pop}) { # approved imbalances } elsif ($slots_full) { # can't do any better } else { # imbalanced, so drop down to check which dimms are out of place $all_clear = 0; } } return if ($all_clear); foreach my $i (0 .. $sockets-1) { my($last); foreach my $j (0 .. $slots-1) { if ($j && $slot_count[$i][$j]) { if (!$last) { foreach my $match (@{$match[$i][$j]}) { user_warn(1, 10027, "memory slot '$match->{locator}' is populated out of order", $match); } $phone_home++; } } $last = $slot_count[$i][$j]; } } } sub check_network { foreach my $interface (@{$xml_top->{network}->{interface}}) { if ($interface->{duplex} && $interface->{duplex} eq 'half') { user_warn(100, 10017, "network interface '$interface->{name}' is running half-duplex", $interface); $phone_home++; } } } sub check_volumes { foreach my $vol (sort { cmp_disks($a, $b) } keys %volumes) { next if ($props{volumes}{$vol}{hidden}); my($cache) = $props{volumes}{$vol}{write_cache}; my($handle) = $props{volumes}{$vol}{xml_handle}; if ($cache && defined $cache->{enable} && !$cache->{enable}) { user_warn(1, 10019, "write cache is disabled on volume '$vol'", $handle); $phone_home++; } elsif ($cache && $cache->{policy}) { if ($cache->{policy} ne 'write-back') { user_warn(1, 10019, "write cache is disabled on volume '$vol'", $handle); $phone_home++; } else { # we have write-back so no warning here, and no warning on disk write cache below } } else { $cache = $props{volumes}{$vol}{drive_write_cache}; if ($cache && $cache eq 'disabled') { user_warn(1, 10020, "drive write caches are disabled on volume '$vol'", $handle); $phone_home++; } } my($status) = $props{volumes}{$vol}{status}; if ($status) { if ($status eq 'degraded' || $status eq 'rebuilding') { user_warn(1, 10024, "volume '$vol' is degraded", $handle); $phone_home++; } elsif ($status eq 'failed') { user_warn(100, 10025, "volume '$vol' has failed", $handle); $phone_home++; } } } } sub is_dwc_disabled_for_vol_on_controller { my($controller) = @_; foreach my $id (keys %volumes) { if ($props{volumes}{$id}{device} && device_to_driver($props{volumes}{$id}{device}) eq $controller) { my $cache = $props{volumes}{$id}{drive_write_cache}; if ($cache && $cache eq 'disabled') { return 1; } } } return 0; } sub is_wc_enabled_for_vol_on_controller { my($controller) = @_; foreach my $id (keys %volumes) { if ($props{volumes}{$id}{device} && device_to_driver($props{volumes}{$id}{device}) eq $controller) { my $cache = $props{volumes}{$id}{write_cache}; if ($cache && $cache->{policy} && $cache->{policy} eq 'write-back') { return 1; } } } return 0; } sub does_controller_have_write_cache { my($controller) = @_; return 1 if ($controller && $props{controllers}{$controller} && $props{controllers}{$controller}{write_cache}); foreach my $id (keys %volumes) { if ($props{volumes}{$id}{device} && device_to_driver($props{volumes}{$id}{device}) eq $controller) { return 1 if ($props{volumes}{$id}{write_cache}); } } return 0; } sub broken_ahci { my($broken) = 0; if ($system_model_index && defined $system_models[$system_model_index]{'broken-ahci'}) { my($ahci) = $system_models[$system_model_index]{'broken-ahci'}; if (ref($ahci) eq 'HASH') { my($date) = parse_date($xml_top->{bios}->{date}); if (defined $ahci->{'bad-before'} && $date && ($date < $ahci->{'bad-before'})) { $broken = 1; } } else { $broken = 1; } } return $broken; } sub check_drives { my(%seen); foreach my $id (sort cmp_drives keys %{$props{drives}}) { next if ($id == 0); my($pretty) = $props{drives}{$id}{pretty} || ''; my($model) = $props{drives}{$id}{model_match} || ''; my($vol) = $props{drives}{$id}{volume}; my($serial) = $props{drives}{$id}{serial} || ''; # skip pass devs if we've already seen this drive next if ($serial && $seen{$serial}++ && $vol =~ /^pass/); my($drive); if ($props{drives}{$id}{location}) { $drive = $props{drives}{$id}{location}; } elsif ($props{drives}{$id}{model}) { $drive = "model=$props{drives}{$id}{model}"; $drive .= ",serial=$serial" if ($serial); } elsif ($serial) { $drive = "serial=$serial"; } else { $drive = 'Unknown'; } if (defined $props{drives}{$id}{status}) { if ($props{drives}{$id}{status} =~ /fail/) { user_warn(100, 10014, "$props{drives}{$id}{status} drive '$drive' in volume '$vol'", $props{drives}{$id}{xml_handle}); $phone_home++; } } if ($props{drives}{$id}{wcache_support} && !$props{drives}{$id}{wcache_enable}) { my($vol_cache) = $props{volumes}{$vol}{write_cache}; my($vol_drive_cache) = $props{volumes}{$vol}{drive_write_cache}; my($controller_cache); my($driver) = device_to_driver($props{volumes}{$vol}{device} || ''); if ($driver && $props{controllers}{$driver}) { $controller_cache = $props{controllers}{$driver}{write_cache}; } if ($vol_cache && $vol_cache->{policy} && $vol_cache->{policy} eq 'write-back') { # don't report this case since volume write cache is enabled } elsif ($controller_cache && $controller_cache->{policy} && $controller_cache->{policy} eq 'write-back') { # don't report this case since controller write cache is enabled } elsif ($vol_drive_cache && $vol_drive_cache eq 'disabled') { # don't report this case since we've already reported this at volume level } elsif ($vol =~ /^pass/ && is_dwc_disabled_for_vol_on_controller($driver)) { # does any volume/controller have drive write cache disabled on this controller? # if so, don't report as already reported and we assume this pass device is covered, # although we don't know for sure. } elsif ($vol =~ /^pass/ && is_wc_enabled_for_vol_on_controller($driver)) { # does any volume/controller have write cache enabled on this controller? # if so, don't report as we assume this pass device is covered, # although we don't know for sure. } elsif ($vol =~ /^pass/ && does_controller_have_write_cache($driver)) { # does any volume/controller have write cache disabled on this controller? # if so, don't report as we guess this pass device is covered, # and a warning has already been made about vol cache disabled. # i.e. put the attention on the bigger issue: vol cache disabled. } elsif (!$serial && !$props{drives}{$id}{location}) { # if no serial or location, then unlikely this is a drive. should be a raid volume } else { user_warn(1, 10021, "write cache is disabled on drive '$drive' in volume '$vol'", $props{drives}{$id}{xml_handle}); $phone_home++; } } if (defined $props{drives}{$id}{tcq_depth}) { if ($props{drives}{$id}{tcq_depth} < 16) { if (defined $props{drives}{$id}{device} && $props{drives}{$id}{device} =~ /umass/) { # don't care about tags on usb devices } else { # mainly looking for cases of 1 and 2, but < 16 doesn't make sense user_warn(1, 10008, "tcq_depth=$props{drives}{$id}{tcq_depth} on volume '$vol' is set too low", $props{volumes}{$vol}{xml_handle}); } } } if ($props{drives}{$id}{ncq_depth} && $props{drives}{$id}{ncq_depth} > 1) { my($cam) = 0; if ($os_type eq 'freebsd') { chomp($cam = `sysctl -n hw.ata.newcamata 2> /dev/null` || 0); } my($driver) = $props{volumes}{$vol}{driver} || ''; if ($driver =~ /^ata_piix/ || ($cam && $driver =~ /^atapci/)) { my($device) = $props{volumes}{$vol}{device}; my($pci) = $dev_to_pci{$device} || $hostid_to_pci{$device} || $device; my($hostid) = pci_to_hostid($pci) || $pci; my($description) = $other_devices{'Disk-Control'}{$hostid} || $other_devices{'Disk-Control'}{$device} || ''; if ($description =~ /\b(ICH(9|10)|PCH\d*|631xESB)\b/) { if (broken_ahci()) { # these models have ahci hardware, but don't enable } else { user_warn(1, 10011, "NCQ not enabled on '$vol'; controller '$props{volumes}{$vol}{driver}' not in AHCI mode", $props{volumes}{$vol}{xml_handle}); $phone_home++; } } } } if ($vol =~ /^hd/ && $pretty =~ /SATA/) { user_warn(1, 10010, "SATA drive '$vol' is running in legacy IDE mode", $props{volumes}{$vol}{xml_handle}); $phone_home++; } if ($model) { if (ref($drive_models{$model}) eq 'HASH' && defined $drive_models{$model}{'firmware-advisory'} && defined $props{drives}{$id}{firmware}) { my($check) = $drive_models{$model}{'firmware-advisory'}{firmware}; my($negate) = ($check =~ s/^!//); my($match); if ($negate) { $match = ($props{drives}{$id}{firmware} !~ /$check/); } else { $match = ($props{drives}{$id}{firmware} =~ /$check/); } if ($match && ($drive_models{$model}{'firmware-advisory'}{severity} > 0)) { my($error) = "firmware upgrade advised for drive 'model=$props{drives}{$id}{model_match},firmware=$props{drives}{$id}{firmware}"; $error .= ",serial=$props{drives}{$id}{serial}" if (defined $props{drives}{$id}{serial}); $error .= "' in volume '$vol'"; user_warn(1, $drive_models{$model}{'firmware-advisory'}{yerr}, $error, $props{drives}{$id}{xml_handle}); } } } } } sub linux_checks { check_cpu(); check_volumes(); check_drives(); check_controllers(); check_network(); check_memory(); } sub freebsd_checks { check_cpu(); check_volumes(); check_drives(); check_controllers(); check_network(); check_memory(); } sub printable { my($input) = @_; $input =~ s/[^ -~]//g; return $input; } sub xml_encode { my($input) = @_; if (defined $input) { $input =~ s/\&/&/g; $input =~ s/\"/"/g; $input =~ s/\>/>/g; $input =~ s/\{$dst_key}) { $status = 1; } elsif (defined $src) { $dst->{$dst_key} = $src; $status = 2; } elsif (defined $default) { $dst->{$dst_key} = $default; $status = 3; } return $status; } sub set { my($dst, $dst_key, $src, $default) = @_; my($status) = 0; if (defined $src) { $dst->{$dst_key} = $src; $status++; } elsif (defined $default) { $dst->{$dst_key} = $default; } return $status; } sub print_xml { my($fh, $tag, $name, $indent, $ptr) = @_; my(@children); my($count) = 0; my($attributes) = ''; if (ref($ptr) eq 'ARRAY') { foreach my $key (@{$ptr}) { if (ref($key) eq "HASH") { print_xml($fh, $tag, '', $indent, $key); } else { if ($name) { $fh->printf("$indent<$tag id=\"$name\">%s\n", xml_encode($key)); } else { $fh->printf("$indent<$tag>%s\n", xml_encode($key)); } } } } else { foreach my $key (sort keys %{$ptr}) { if (ref($ptr->{$key}) eq "HASH" || ref($ptr->{$key}) eq "ARRAY") { push(@children, $key); $count++; } elsif (defined $ptr->{$key}) { $attributes .= sprintf(' %s="%s"', $key, xml_encode($ptr->{$key})); } } if (!$count) { if ($name) { $fh->print("$indent<$tag id=\"$name\"$attributes />\n"); } else { $fh->print("$indent<$tag$attributes />\n"); } } else { if ($name) { $fh->print("$indent<$tag id=\"$name\"$attributes>\n"); } else { $fh->print("$indent<$tag$name$attributes>\n"); } foreach my $key (@children) { print_xml($fh, $key, '', "$indent ", $ptr->{$key}); } $fh->print("$indent\n"); } } } sub gather_raw_source { return if $raw_source; if ($sig_pci || $debug_pciconf || $debug_lspci) { $raw_source .= "> pci\n" ; $raw_source .= ">> pci signature\n$sig_pci" if ($sig_pci); $raw_source .= $debug_pciconf if ($debug_pciconf); $raw_source .= $debug_lspci if ($debug_lspci); $raw_source .= "\n"; } $raw_source .= "> lshal\n$debug_lshal\n" if ($debug_lshal); $raw_source .= "> sysctl dev\n$debug_sysctl_dev\n" if ($debug_sysctl_dev); $raw_source .= "> dmidecode\n$debug_dmidecode\n" if ($debug_dmidecode); $raw_source .= "> ipmi\n$debug_ipmi\n" if ($debug_ipmi); $raw_source .= "> cpuinfo\n$debug_cpuinfo\n" if ($debug_cpuinfo); $raw_source .= "> cpuid\ncpu,need_pin,is_pin: eax_in,ecx_in = eax,ebx,ecx,edx\n$debug_cpuid\n" if ($debug_cpuid); $raw_source .= "> mptable\n$debug_mptable\n" if ($debug_mptable); $raw_source .= "> memory\n$debug_memory\n" if ($debug_memory); $raw_source .= "> storage\n$debug_storage\n" if ($debug_storage); $raw_source .= "> network\n$debug_network\n" if ($debug_network); $raw_source .= "> virtualization\n$debug_virt\n" if ($debug_virt); $raw_source .= "> lock\n$debug_lock\n" if ($debug_lock); $raw_source .= "> kernel config\n$debug_kernel_config\n" if ($debug_kernel_config); $raw_source .= "> dmesg\n$dmesg_buf\n" if ($dmesg_buf); } sub email { my($old, $new, $force) = @_; my($fh) = new IO::File; return 0 if ($sent_email); system("which sendmail > /dev/null 2>&1"); return 0 if ($CHILD_ERROR); my($tmp) = "/var/tmp/$zero-email"; rename($tmp, "$tmp.old"); if ($fh->open("> $tmp")) { $fh->print($output); $fh->print($debug) if ($debug); $fh->print($stderr_buf) if ($stderr_buf); $fh->print($perl_warn) if ($perl_warn); $fh->close; my($v1) = `cat $tmp.old 2> /dev/null` || ''; my($v2) = `cat $tmp 2> /dev/null` || ''; if ($v1 && $v2 && ($v1 eq $v2)) { return 0 unless $force; } } gather_raw_source(); $sent_email++; # not really, but if we fail from here, no need to try again $fh->open("| sendmail -odb $email > /dev/null 2>&1") || warn("exec: sendmail: $!"); $fh->print("To: $email\n"); $fh->print("From: tmr_sysinfo\n"); $fh->print("Subject: tmr_sysinfo"); $fh->print(" diff") if ($old ne $new); $fh->print(" for $hostname\n"); $fh->print("\n"); $fh->print($output); $fh->print("Version:\t$version\n"); $fh->print("\n$debug") unless ($opts{'d'}); $fh->print("Debug-System:\t$guess_system\n") unless ($debug =~ /^Debug-System/m); $fh->print("\n", $stderr_buf, "\n") if ($stderr_buf); $fh->print("\n", $old, "\n") if ($old); $fh->print("\n> command\npid=$PID,uid=$UID"); $fh->print(",user=$ENV{USER}") if (defined $ENV{USER}); $fh->print(",sudo_uid=$ENV{SUDO_UID}") if (defined $ENV{SUDO_UID}); $fh->print(",sudo_user=$ENV{SUDO_USER}") if (defined $ENV{SUDO_USER}); $fh->print("\n"); $fh->print("$command\n") if ($command); $fh->print("\n> time\n" . time() . " - " . `date; uptime`); $fh->print("\n> perl warnings\n", $perl_warn) if ($perl_warn); $fh->print("\n> perl version - $]\n"); $fh->print(`/usr/bin/perl -v`); $fh->print("\n"); $fh->print($raw_source); $fh->print("\n.\n"); $fh->close; return 1; } sub main { $command = join(' ', $PROGRAM_NAME, @ARGV); $zero = $PROGRAM_NAME; $zero =~ s{.*/}{}; delete $ENV{PATH}; $ENV{PATH} = $PATH; $stdout = new IO::Handle; $stdout->fdopen(fileno(STDOUT), 'w'); Getopt::Long::Configure('bundling'); my($status) = GetOptions(\%opts, 'h|?|help', 'b', 'c', 'C', 'd', 'trace=s', 'e=s', 'm', 'n', 'N', 'V|version' => \$opts{version}, 't=i', 'o=s', 'r:s', 'x=s', 'v|verbose' => \$opts{verbose}); if ($opts{version}) { print $stderr_buf; print "$version\n"; print "XML $xml_version\n"; print "$rcsid\n"; exit(0); } if (!$status || $opts{'h'} || $opts{'?'} || $opts{'help'}) { print $stderr_buf; usage(); exit(0); } if ($UID) { $stderr_buf .= "$zero: warning: run as root for more detailed and accurate data\n"; } if ($opts{'b'}) { daemonize(); } $timeout = $opts{'t'} if (defined $opts{'t'}); $SIG{'ALRM'} = 'watchdog'; alarm($timeout); # safer to wait for other instances to finish for things like raid utils $fh_lock = new IO::File; if ($fh_lock->open("< $PROGRAM_NAME")) { flock($fh_lock, LOCK_EX) || warn("flock: $PROGRAM_NAME"); } else { warn("open: $PROGRAM_NAME"); } if ($opts{'b'}) { # 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 $debug_lock .= ">> cat $lock\n"; my $cat = `cat $lock 2> /dev/null` || ''; $debug_lock .= $cat; if ($cat =~ /pid=(\d+)/) { my($proc) = "/proc/$1"; if (-d $proc) { $debug_lock .= ">> cat $proc/cmdline\n"; $cat = `cat $proc/cmdline 2> /dev/null` || ''; $debug_lock .= join(' ', split(/\000/, $cat)); $debug_lock .= "\n"; $debug_lock .= ">> cat $proc/status\n"; $cat = `cat $proc/status 2> /dev/null` || "\n"; $debug_lock .= $cat; } } unlink($lock); die "$zero: lock file '$lock' already exists, bailing out at time=" . time(); } eval { local $SIG{'__DIE__'} = ''; # ignore errors about sync not implemented, e.g. old versions of perl my($fh) = new IO::File; if ($fh->open("> $lock")) { $fh->printf("time=%d,uid=%d,pid=%d,command=%s\n", time(), $UID, $PID, $command); $fh->flush; $fh->sync; $fh->close; } }; } grok_os(); grok_boot_options(); $xml = $xml_top->{os} = {}; $xml->{pretty} = $os || ''; $xml->{type} = $os_type || ''; $xml->{date} = $os_date || ''; $xml->{version} = $os_version_pretty || ''; set($xml, 'distro', $os_distro); set($xml, 'custom_distro', $custom_distro); $xml->{bits} = ($os =~ /amd64|x86_64/) ? '64' : '32'; init_dmesg(); grok_dmesg(); if ($os_type eq "linux") { my($one, $two); chomp($one = `hostname 2> /dev/null`); chomp($two = `hostname -f 2> /dev/null`); if ($one =~ /\blocalhost\b/i) { $hostname = $two || $one; } elsif ($two =~ /\blocalhost\b/i) { $hostname = $one || $two; } elsif (length($one) > length($two)) { $hostname = $one; } else { $hostname = $two; } } else { chomp($hostname = `hostname 2> /dev/null`); } if ($os_type eq 'freebsd') { grok_sysctl_dev() if ($os_version >= 600000000); grok_pciconf(); } elsif ($os_type eq "linux") { grok_proc_partitions(); # run before lshal for volume sizes pci_to_driver(); # run before sys_scsi_host sys_module(); sys_scsi_host(); grok_proc_ioports(); grok_lspci(); grok_lshal(); } ipmi(); dmidecode() || smbinfo(); my($system) = 'Unknown'; my($sys); # first attempt at system name if ($smbios{'System'}{1}{'Manufacturer'} && $smbios{'System'}{1}{'Product Name'}) { $system = "$smbios{'System'}{1}{'Manufacturer'} $smbios{'System'}{1}{'Product Name'}"; } # use guess_system as 2nd best source my($guess) = guess_system($system); $system = $guess if ($system eq 'Unknown'); # next fall back to base_board my($base_board); if ($system_model_index && defined $system_models[$system_model_index]{'base-board'}) { $base_board = $system_models[$system_model_index]{'base-board'}; } elsif ($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'}"); } $system = $base_board if ($system eq 'Unknown' && $base_board); # finally in desperation take anything we can get 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($bios); if ($smbios{'BIOS'}{1}{'Vendor'}) { my($vendor, $ver, $rev, $date) = ($smbios{'BIOS'}{1}{'Vendor'}, $smbios{'BIOS'}{1}{'Version'}, $smbios{'BIOS'}{1}{'Revision'}, $smbios{'BIOS'}{1}{'Release Date'}); $bios = clean_system($vendor); $bios =~ s/\s+/_/g; if ($ver) { $ver =~ s/\s+/_/g; $bios .= " $ver"; } if ($date) { $date =~ s/\s+/_/g; $bios .= " $date"; } if ($rev && $ver !~ /^$rev/) { $rev =~ s/\s+/_/g; $bios .= ", rev $rev"; } $xml = $xml_top->{bios} = {}; $xml->{manufacturer} = $smbios{'BIOS'}{1}{'Vendor'} || ''; $xml->{version} = $smbios{'BIOS'}{1}{'Version'} || ''; $xml->{rev} = $smbios{'BIOS'}{1}{'Revision'} || ''; $xml->{date} = $smbios{'BIOS'}{1}{'Release Date'} || ''; $xml->{pretty} = $bios; my $nvram = nvram(); $xml->{nvram} = $nvram if ($nvram); parse_nvram(); if ($opts{verbose}) { if ($xml->{settings}) { my($max) = 0; foreach my $key (keys %{$xml->{settings}}) { my($len) = length($key); $max = $len if ($len > $max); } $max += 2; foreach my $key (sort keys %{$xml->{settings}}) { my($val) = printable($xml->{settings}->{$key}); $bios .= sprintf("\n\t\t\t%-${max}s%s", $key, $val); } } } } # check for hypervisor hypervisor($system, $bios); if ($system eq 'Unknown' && $hypervisor =~ /Xen/) { $system = $hypervisor; $system =~ s/Xen ([\d\.]+) /Xen /; $sys = $system; } if ($system eq 'VMware') { # so far haven't found any case where VMware doesn't screw with cpuid # need this before grok_procs() $cpuid_vmware++; } $xml = $xml_top->{system} = {}; set($xml, 'manufacturer', $smbios{'System'}{1}{'Manufacturer'}); set($xml, 'model', $smbios{'System'}{1}{'Product Name'}); set($xml, 'version', $smbios{'System'}{1}{'Version'}); set($xml, 'serial', $smbios{'System'}{1}{'Serial Number'}); set($xml, 'uuid', $smbios{'System'}{1}{'UUID'}); set($xml, 'part_number', $smbios{'System'}{1}{'Part Number'}); set($xml, 'family', $smbios{'System'}{1}{'Family'}); set($xml, 'asset', $smbios{'System'}{1}{'Asset Tag'}); set($xml, 'pretty', $sys); $xml = $xml_top->{base_board} = {}; set($xml, 'manufacturer', $smbios{'Base Board'}{1}{'Manufacturer'}); set($xml, 'model', $smbios{'Base Board'}{1}{'Product Name'}); set($xml, 'version', $smbios{'Base Board'}{1}{'Version'}); set($xml, 'serial', $smbios{'Base Board'}{1}{'Serial Number'}); set($xml, 'location', $smbios{'Base Board'}{1}{'Location'}); set($xml, 'asset', $smbios{'Base Board'}{1}{'Asset Tag'}); $xml = $xml_top->{chassis} = {}; set($xml, 'manufacturer', $smbios{'Chassis'}{1}{'Manufacturer'}); set($xml, 'version', $smbios{'Chassis'}{1}{'Version'}); set($xml, 'serial', $smbios{'Chassis'}{1}{'Serial Number'}); set($xml, 'height', $smbios{'Chassis'}{1}{'Height'}); set($xml, 'type', $smbios{'Chassis'}{1}{'Type'}); set($xml, 'asset', $smbios{'Chassis'}{1}{'Asset Tag'}); if ($smbios{'System Power Supply'}{'Count'}) { foreach my $id (1 .. $smbios{'System Power Supply'}{'Count'}) { $xml = {}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{power_supplies}->{power_supply}}, $xml); $xml->{handle} = $xml_handle++; set($xml, 'manufacturer', $smbios{'System Power Supply'}{$id}{'Manufacturer'}); set($xml, 'revision', $smbios{'System Power Supply'}{$id}{'Revision'}); set($xml, 'serial', $smbios{'System Power Supply'}{$id}{'Serial Number'}); set($xml, 'part_number', $smbios{'System Power Supply'}{$id}{'Part Number'}); set($xml, 'asset', $smbios{'System Power Supply'}{$id}{'Asset Tag'}); set($xml, 'location', $smbios{'System Power Supply'}{$id}{'Location'}); if ($smbios{'System Power Supply'}{$id}{'Status'}) { set($xml, 'status', parse_ps_status($smbios{'System Power Supply'}{$id}{'Status'})); } } } grok_procs(); my($mem, $memory, $mem_visible, $mem_physical) = memory($system); if ($os_type eq 'freebsd') { freebsd_disks($system); } elsif ($os_type eq 'linux') { sys_block(); grok_proc_ide(); grok_proc_scsi(); grok_proc_cciss(); if ($need_mdstat) { mdadm() || mdstat(); } grok_swap(); dev_disk(); } if ($need_hpacucli || $want_hpacucli) { # hpacucli() can be slow; eval wrap will cause it to die on alarm eval { hpacucli(); }; } if ($need_twcli || $want_twcli) { twcli(); } if ($need_mptutil || $want_mptutil) { if ($hypervisor =~ /vmware/i) { # FreeBSD 6.4-YAHOO-20081117 under VMware crashes on mptutil # at this point there is not a known version that doesn't crash # not useful to run it anyway, so just ignore it $need_mptutil = $want_mptutil = 0; } else { mptutil(); } } if ($need_linuxmpt2 || $want_linuxmpt2) { mpt2(); } if ($need_linuxmpt || $want_linuxmpt) { mpt(); } if ($need_mfiutil || $want_mfiutil) { mfiutil(); } if ($need_megarc || $want_megarc) { # megarc() can infinite hang; eval wrap will cause it to die on alarm eval { omreport() || megarc(); }; } if ($need_megacli || $want_megacli) { # megacli() can be slow; eval wrap will cause it to die on alarm eval { omreport() || megacli(); }; } if ($need_cissutil || $want_cissutil) { # cissutil() can be slow; eval wrap will cause it to die on alarm eval { cissutil(); }; } if ($need_arcconf || $want_arcconf) { omreport () || arcconf(); } if ($need_fio || $want_fio) { fio(); } if ($os_type eq 'freebsd') { freebsd_disks_unknown(); freebsd_disk_ioctls(); } lvdisplay() if ($need_lvm); eval { # this can hang indefinitely on rhel4u6 df(); disk_usage(); }; ccdconfig() if ($need_ccdconfig); resolve_disks(); $output{disks} = print_disks(); # need this before other_devices() grok_network(); $output{other} = other_devices(); $output{network} = print_network(); my($error); if ($need_cissutil && !$got_cissutil) { $error = "could not run $cissutil"; $error .= "; please install $cissutil" unless ($have_cissutil); user_warn(1, 0, $error); } if ($need_megarc && !$got_megarc && !$got_omreport) { $error = "could not run $megarc"; $error .= "; please install $megarc" unless ($have_megarc); user_warn(1, 0, $error); } if ($need_megacli && !$got_megacli && !$got_omreport) { $error = "could not run megacli"; unless ($have_megacli) { if ($os_type eq 'linux') { $error .= "; please install ports/MegaCli"; $error .= " -contrib"; } else { $error .= "; please install ports/MegaCli"; } } user_warn(1, 0, $error); } if ($need_mfiutil && !$got_mfiutil) { $error = "could not run $mfiutil"; $error .= "; please install $mfiutil" unless ($have_mfiutil); user_warn(1, 0, $error); } if ($need_mptutil && !$got_mptutil) { $error = "could not run $mptutil"; $error .= "; please install $mptutil" unless ($have_mptutil); user_warn(1, 0, $error); } if ($need_linuxmpt2 && !$got_sas2ircu) { $error = "could not run sas2ircu"; $error .= "; please install sas2ircu" unless ($have_sas2ircu); user_warn(1, 0, $error); } if ($need_linuxmpt && !$got_lsiutil && !$got_mptstatus) { $error = ''; if ($have_mptstatus) { $error .= "could not run $mptstatus"; } else { $error .= "could not run lsiutil"; unless ($have_lsiutil) { $error .= "; please install ports/lsiutil"; $error .= " -contrib"; } } user_warn(1, 0, $error); } if ($need_hpacucli && !$got_hpacucli) { $error = "could not run $hpacucli"; if (!$have_hpacucli && ($UID == 0)) { # which(1) can't tell that we have it if not root $error .= "; please install ports/$hpacucli"; $error .= " -contrib"; } user_warn(1, 0, $error); } if ($need_twcli && !$got_twcli) { $error = "could not run $twcli"; $error .= "; please install $twcli" unless ($have_twcli); user_warn(1, 0, $error); } if ($need_arcconf && !$got_arcconf && !$got_omreport) { $error = "could not run $arcconf"; user_warn(1, 0, $error); } $xml_top->{hostname} = $hostname; $xml_top->{execution}->{program} = $command; $xml_top->{execution}->{uid} = $UID; $xml_top->{execution}->{code_version} = $version; $xml_top->{execution}->{code_rcsid} = $rcsid; $xml_top->{execution}->{xml_version} = $xml_version; $xml_top->{execution}->{perl_version} = $]; $xml_top->{ipmi} = \%ipmi; my($src); foreach my $id (sort cmp_devs keys %{$props{controllers}}) { $src = \%{$props{controllers}{$id}}; next if ($src->{hidden}); $xml = {}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{storage}->{controller}}, $xml); $props{controllers}{$id}{xml_handle} = $xml->{handle} = $xml_handle++; $xml->{name} = $id; set($xml, 'model', $src->{model}); my($pci) = $src->{pci} || $driver_to_pci{$id} || ''; if ($pci) { $xml->{pci} = $pci; $xml->{pci_handle} = $pci_to_handle{$pci}; } set($xml, 'firmware_pkg', $src->{package}); set($xml, 'firmware', $src->{firmware}); set($xml, 'rev', $src->{revision}); set($xml, 'bios', $src->{bios}); set($xml, 'serial', $src->{serial}); set($xml, 'drive_write_cache', $src->{drive_write_cache}); my($patrol) = {}; set($patrol, 'mode', $src->{patrol_mode}); set($patrol, 'interval', $src->{patrol_interval}); $xml->{patrol} = $patrol if (keys %{$patrol}); my($cache) = {}; set($cache, 'status', $src->{cache}{status}); set($cache, 'size', $src->{cache}{size}); set($cache, 'serial', $src->{'cache_serial'}); set($cache, 'write', $src->{write_cache}); set($cache, 'read', $src->{read_cache}); $xml->{cache} = $cache if (keys %{$cache}); my($bbu) = {}; set($bbu, 'count', $src->{'bbu_count'}); set($bbu, 'status', $src->{'bbu_status'}); set($bbu, 'type', $src->{'bbu_type'}); set($bbu, 'model', $src->{'bbu_model'}); set($bbu, 'manufacturer', $src->{'bbu_manufacturer'}); set($bbu, 'date', $src->{'bbu_date'}); set($bbu, 'serial', $src->{'bbu_serial'}); set($bbu, 'chemistry', $src->{'bbu_chemistry'}); set($bbu, 'charge', $src->{'bbu_charge'}); $xml->{bbu} = $bbu if (keys %{$bbu}); } foreach my $id (sort keys %{$props{drives}}) { next if ($id < 1); # real drive ids start at 1 $src = \%{$props{drives}{$id}}; next if ($src->{hidden}); $xml = {}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{storage}->{drive}}, $xml); $props{drives}{$id}{xml_handle} = $xml->{handle} = $xml_handle++; # set($xml, 'type', $src->{type}); set($xml, 'manufacturer', $src->{manufacturer}); set($xml, 'status', $src->{status}); set($xml, 'serial', $src->{serial}); set($xml, 'form_factor', $src->{form}); set($xml, 'sectors', $src->{sectors}); set($xml, 'logical_sector', $src->{logical_sector}); set($xml, 'physical_sector', $src->{physical_sector}); set($xml, 'firmware', $src->{firmware}); set($xml, 'model', $src->{model}); set($xml, 'pretty', $src->{pretty}); set($xml, 'volume', $src->{volume}); set($xml, 'size', $src->{size}); set($xml, 'cache_size', $src->{cache_size}); if (defined $src->{rpm}) { set($xml, 'rpm', parse_rpm($src->{rpm})); } set($xml, 'wwn', $src->{wwn}); set($xml, 'date', $src->{date}); set($xml, 'speed', $src->{speed}); if (defined $src->{interface}) { set($xml, 'interface', parse_drive_interface($src->{interface})); } set($xml, 'protocol', $src->{protocol}); if ($src->{readahead_support}) { $xml->{read_ahead} = {}; set($xml->{read_ahead}, 'support', $src->{readahead_support}); set($xml->{read_ahead}, 'enable', $src->{readahead_enable}); } if ($src->{wcache_support}) { $xml->{write_cache} = {}; set($xml->{write_cache}, 'support', $src->{wcache_support}); set($xml->{write_cache}, 'enable', $src->{wcache_enable}); } if ($src->{smart_support}) { $xml->{smart} = {}; set($xml->{smart}, 'support', $src->{smart_support}); set($xml->{smart}, 'enable', $src->{smart_enable}); } if ($src->{trim_support}) { $xml->{trim} = {}; set($xml->{trim}, 'support', $src->{trim_support}); set($xml->{trim}, 'enable', $src->{trim_enable}); } if ($src->{ncq_support}) { $xml->{ncq} = {}; set($xml->{ncq}, 'support', $src->{ncq_support}); set($xml->{ncq}, 'enable', $src->{ncq_enable}); set($xml->{ncq}, 'depth', $src->{ncq_depth}); } if ($src->{location}) { $xml->{location} = {}; foreach my $attr (split(/,/, $src->{location})) { my($key, $val) = split(/=/, $attr); set($xml->{location}, $key, $val); } } } foreach my $id (sort { cmp_disks($a, $b) } keys %volumes) { next if ($props{volumes}{$id}{hidden}); $src = \%{$props{volumes}{$id}}; $xml = {}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{storage}->{volume}}, $xml); $props{volumes}{$id}{xml_handle} = $xml->{handle} = $xml_handle++; $xml->{name} = $id; set($xml, 'size', $src->{bytes} || $src->{df}{size}); set($xml, 'stripe', $src->{stripe}); set($xml, 'raid', $src->{raid}); set($xml, 'spans', $src->{spans}); set($xml, 'status', $src->{status}); set($xml, 'channel', $src->{channel}); set($xml, 'ms', $src->{ms}); set($xml, 'read_cache', $src->{read_cache}); set($xml, 'read_ahead', $src->{read_ahead}); set($xml, 'write_cache', $src->{write_cache}); set($xml, 'drive_write_cache', $src->{drive_write_cache}); set($xml, 'scheduler', $src->{scheduler}); my($driver) = device_to_driver($src->{device} || ''); if ($driver) { $xml->{controller} = $driver; my($controller_handle) = $props{controllers}{$driver}{xml_handle}; if ($controller_handle) { # point to parent controller of this volume $xml->{controller_handle} = $controller_handle; # have parent controller point back at this volume my($controller_xml) = $handle_to_xml{$controller_handle}; push(@{$controller_xml->{volumes}->{volume}}, $xml->{handle}); } } foreach my $key (sort keys %{$drives{$id}}) { next if $props{drives}{$key}{hidden}; # point at each drive in this volume my($drive_handle) = $props{drives}{$key}{xml_handle}; push(@{$xml->{drives}->{drive}}, $drive_handle); # link the drive back to this volume $handle_to_xml{$drive_handle}->{volume_handle} = $xml->{handle}; } } $xml = $xml_top->{memory_array}->{system_memory} = {}; foreach my $id (1 .. $smbios{'Memory'}{'Count'}) { $src = \%{$smbios{Memory}{$id}}; $xml = {}; $handle_to_xml{$xml_handle} = $xml; push(@{$xml_top->{memory_array}->{system_memory}->{memory_device}}, $xml); $xml->{handle} = $xml_handle++; set($xml, 'serial', $src->{serial}); set($xml, 'part_number', $src->{'Part Number'}); set($xml, 'size', $src->{Size}); set($xml, 'type', $src->{Type}); set($xml, 'speed', $src->{Speed}); set($xml, 'asset', $src->{asset}); set($xml, 'locator', $src->{locator}); set($xml, 'bank_locator', $src->{bank_locator}); set($xml, 'form', $src->{form}); set($xml, 'width', $src->{width}); set($xml, 'pretty', $src->{pretty}); if ($src->{pretty} && $src->{pretty} =~ /\bCL(\S+)\s+(\d+)R(x\d+)$/) { $xml->{cas} = $1; $xml->{ranks} = $2; $xml->{org} = $3; } if ($src->{'Manufacturer'}) { ($xml->{manufacturer}->{jedec}, $xml->{manufacturer}->{name}) = decode_jedec($src->{'Manufacturer'}); } } $xml = $xml_top->{memory_array}->{system_memory}; set($xml, 'size', $mem_physical); set($xml, 'visible', $mem_visible); if ($system_model_index) { $src = \%{$system_models[$system_model_index]}; set($xml, 'max_ranks', $src->{'memory-max-ranks'}); set($xml, 'max_size', $src->{'memory-max-size'}); set($xml, 'type', $src->{'memory-type'}); set($xml, 'min_speed', $src->{'memory-min-speed'}); set($xml, 'max_speed', $src->{'memory-max-speed'}); set($xml, 'channels', $src->{'memory-channels'}); my($slot) = {}; set($slot, 'count', $src->{'memory-slots'}); set($slot, 'type', $src->{'memory-slot-type'}); set($slot, 'max_size', $src->{'memory-max-size-per-slot'}); set($slot, 'max_ranks', $src->{'memory-max-ranks-per-slot'}); $xml->{slot} = $slot if (keys %{$slot}); } if ($os_type eq 'linux') { linux_checks(); } elsif ($os_type eq 'freebsd') { freebsd_checks(); } # begin output generation my(%drive_summary); if ($xml_top->{storage}->{drive}) { foreach my $drive (@{$xml_top->{storage}->{drive}}) { if ($drive->{pretty}) { # these should all be real hard drives, but will miss unknowns if ($drive->{pretty} =~ /^([\d\.]+(MB|GB|TB|PB)) (10K|15K)?/) { my($key) = $1; $key = '36GB' if ($key eq '37GB'); $key = '72GB' if ($key eq '73GB'); $key = '146GB' if ($key eq '147GB'); $key .= "-$3" if ($3); $key .= " " . parse_drive_interface($drive->{pretty}); $drive_summary{$key}++; } else { $drive_summary{Unknown}++; } } } } my(@keys) = keys %drive_summary; $output .= "Summary:\t"; $output .= "$sys, $procs, $mem"; if ($#keys == 0) { $output .= ", $drive_summary{$keys[0]} x $keys[0]"; } $output .= "\nSystem:\t\t$system"; $output .= " ($base_board)" if ($base_board && $system !~ /$base_board/i && !defined($smbios{'Base Board'}{2})); my($ymodel) = guess_ymodel($mem_physical || $mem_visible); set($xml_top->{system}, 'ymodel', $ymodel); $output .= ", $ymodel" if ($ymodel); my($yspec) = guess_yspec($processors); set($xml_top->{system}, 'yspec', $yspec); $output .= ", ySPEC $yspec" if ($yspec); $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"; $output .= $output{disks} if ($output{disks}); $output .= $output{other} if ($output{other}); $output .= $output{network} if ($output{network}); if ($os) { $output .= "OS:\t\t$os"; if ($os =~ /amd64|x86_64/) { $output .= ", 64-bit"; } else { $output .= ", 32-bit"; if ($cpu_bits == 64) { if ($os_type eq 'freebsd' && $os_version < 600000000) { # freebsd 4.x doesn't support 64-bit } elsif ($hypervisor) { # generally we don't know hardware } else { user_warn(1, 10018, "running a 32-bit OS on a 64-bit CPU", $xml_top->{os}); } } } $output .= "\n"; } if ($hypervisor) { $output .= "Hypervisor:\t$hypervisor"; $output .= "\n"; } if ($bios) { $output .= "BIOS:\t\t$bios"; # not useful as is, need to mask the variable bits, e.g. asset tag in 2950 # my($nvram) = 0; # chomp($nvram = `cksum /dev/nvram 2> /dev/null`); # if ($nvram) { # $nvram =~ s/ .*//; # $output .= ", nvram=$nvram"; # } $output .= "\n"; } if ($hostname) { $output .= "Hostname:\t$hostname"; my($pre, $post) = (" (", ""); if ($jailed) { $output .= $pre . "jailed"; $output .= " on $jailer" if ($jailer); $pre = ", "; $post = ")"; } $output .= $post . "\n"; } $output .= "\n$debug" if ($opts{'d'} && $debug); my($out_sep) = ''; if ($stderr_buf) { if ($opts{'e'} && $opts{'e'} ne '-') { my($fh) = new IO::File; if ($fh->open("> $opts{'e'}")) { $fh->print($stderr_buf); $fh->close; } } elsif (defined $opts{'c'} || (!defined $opts{'C'} && !defined $ENV{ANSI_COLORS_DISABLED} && -t STDERR)) { print STDERR highlight($stderr_buf); $out_sep = "\n"; } else { print STDERR $stderr_buf; $out_sep = "\n"; } } if ($opts{'o'} && $opts{'o'} ne '-') { my($fh) = new IO::File; if ($fh->open("> $opts{'o'}")) { $fh->print($output); $fh->close; } else { warn("open: $opts{'o'}: $!"); } if ($opts{'b'} && ($debug || $perl_warn || $phone_home) && !$jailed) { my($old, $new, $old_strip, $new_strip) = ("", "", "", ""); my($tmp) = $opts{'o'}; $tmp =~ s/^.*\///; $tmp = "/var/tmp/$tmp"; if (-e $tmp) { $old = `cat $tmp`; # nuke disk usage, hostnames, OS for diff $old_strip = $old; $old_strip =~ s/(\s*\d+)\%//gm; $old_strip =~ s/^(Hostname|OS):.*//m; $new = $output; $new_strip = $new; $new_strip =~ s/(\s*\d+)\%//gm; $new_strip =~ s/^(Hostname|OS):.*//m; } if (! -e $tmp || $old_strip ne $new_strip) { eval { email($old, $new, 0); }; if ($fh->open("> $tmp")) { $fh->print($output); $fh->close; } else { warn("open: $tmp: $!"); } } } } else { $stdout->print($out_sep); $stdout->print($output); $out_sep = "\n"; } $xml_top->{execution}->{end} = time; if (defined $opts{'x'}) { if ($opts{'x'} && $opts{'x'} ne '-') { my($fh) = new IO::File; if ($fh->open("> $opts{'x'}")) { print_xml($fh, 'system', '', '', $xml_top); $fh->close; } else { warn("open: $opts{'x'}: $!"); } } else { $stdout->print($out_sep); print_xml($stdout, 'system', '', '', $xml_top); $out_sep = "\n"; } } if (defined $opts{'r'}) { gather_raw_source(); if ($raw_source) { if ($opts{'r'} && $opts{'r'} ne '-') { my($fh) = new IO::File; if ($fh->open("> $opts{'r'}")) { $fh->print($raw_source); $fh->close; } else { warn("open: $opts{'r'}: $!"); } } else { $stdout->print($out_sep); $stdout->print($raw_source); $out_sep = "\n"; } } } if ($UID == 0 && !$opts{'N'}) { # when run as root, populate /var/run files my($fh) = new IO::File; my($dir) = '/var/run'; if ($fh->open("> $dir/tmr_sysinfo.txt")) { $fh->print($output); $fh->close; } if ($fh->open("> $dir/tmr_sysinfo.xml")) { print_xml($fh, 'system', '', '', $xml_top); $fh->close; } gather_raw_source(); if ($raw_source && $fh->open("> $dir/tmr_sysinfo.raw")) { $fh->print($raw_source); $fh->close; } if ($stderr_buf && $fh->open("> $dir/tmr_sysinfo.err")) { $fh->print($stderr_buf); $fh->close; } } if ($opts{'m'}) { email('', '', 1); } elsif ($phone_home) { email('', '', 0); } } main(); END { unlink $lock if ($opts{'b'}); system("rm -rf $c_dir") if ($c_dir && -d $c_dir); email('', '', 0) if ($perl_warn); $fh_lock->close if ($fh_lock); }