diff options
| author | 2025-09-08 03:10:10 -0400 | |
|---|---|---|
| committer | 2025-09-08 03:10:10 -0400 | |
| commit | 7422e185a5db8bdcb6f8a98302f9f954eae2915f (patch) | |
| tree | bf41f84294b0d98492850f85171b78a08e098002 | |
| parent | 38a7a9de17336897360108f563571cb22d98a28f (diff) | |
New upstream version 3.3.39-1.upstream/3.3.39-1
| -rwxr-xr-x | inxi | 1005 | ||||
| -rw-r--r-- | inxi.1 | 46 | ||||
| -rw-r--r-- | inxi.changelog | 687 |
3 files changed, 1188 insertions, 550 deletions
@@ -49,8 +49,8 @@ use POSIX qw(ceil uname strftime ttyname); ## INXI INFO ## my $self_name='inxi'; -my $self_version='3.3.38'; -my $self_date='2025-04-06'; +my $self_version='3.3.39'; +my $self_date='2025-08-29'; my $self_patch='00'; ## END INXI INFO ## @@ -515,6 +515,9 @@ sub set_os { if ($cpu_arch =~ /arm|aarch/){ $risc{'arm'} = 1; $risc{'id'} = 'arm';} + elsif ($cpu_arch =~ /loong|godson/){ + $risc{'loongson'} = 1; + $risc{'id'} = 'loongson';} elsif ($cpu_arch =~ /mips/){ $risc{'mips'} = 1; $risc{'id'} = 'mips';} @@ -527,7 +530,7 @@ sub set_os { elsif ($cpu_arch =~ /(sparc|sun4[uv])/){ $risc{'sparc'} = 1; $risc{'id'} = 'sparc';} - # aarch32 mips32, i386. centaur/via/intel/amd handled in cpu + # aarch32 mips32, i386. amd/centaur/intel/via/zhaoxin handled in cpu if ($cpu_arch =~ /(armv[1-7]|32|[23456]86)/){ $bits_sys = 32; } @@ -1922,6 +1925,12 @@ sub disk_data { ['vmstat', '-H'], ); run_commands(\@cmds,'disk-bsd'); + # for issue 56, which will probably never be done, but bootloader data + @cmds = ( + ['efibootmgr', ''], # root, of course + ); + run_commands(\@cmds,'bootleader'); + } sub display_data { @@ -1961,6 +1970,7 @@ sub display_data { 'kde-full-session' => $ENV{'KDE_FULL_SESSION'}, 'kde-session-version' => $ENV{'KDE_SESSION_VERSION'}, 'vdpau-driver' => $ENV{'VDPAU_DRIVER'}, + 'windowmanager' => $ENV{'WINDOWMANAGER'}, 'xdg-current-desktop' => $ENV{'XDG_CURRENT_DESKTOP'}, 'xdg-session-desktop' => $ENV{'XDG_SESSION_DESKTOP'}, 'xdg-vtnr' => $ENV{'XDG_VTNR'}, @@ -2787,7 +2797,10 @@ sub download_file { sub get_file_http_tiny { my ($type,$url,$file,$ua) = @_; $ua = ($ua && $dl{'ua'}) ? $dl{'ua'} . $ua: ''; - my %headers = ($ua) ? ('agent' => $ua) : (); + my %headers; + $headers{'agent'} = $ua if $ua; + # default behavior of no check may change to check, not sure why, be explicit + $headers{'verify_SSL'} = 0 if $force{'no-ssl'}; my $tiny = HTTP::Tiny->new(%headers); # note: default is no verify, so default here actually is to verify unless overridden $tiny->verify_SSL => 1 if !$force{'no-ssl'}; @@ -4045,7 +4058,7 @@ sub is_hex { } ## NOTE: for perl pre 5.012 length(undef) returns warning -# receives string, returns boolean 1 if integer +# receives string, returns boolean 1 if integer. tr/// 4x faster than regex sub is_int { if (defined $_[0] && length($_[0]) && length($_[0]) == ($_[0] =~ tr/0123456789//)){ @@ -5106,6 +5119,10 @@ sub get { }}, 'irc' => sub { $b_irc = 1;}, + 'loongson' => sub { + undef %risc; + $risc{'id'} = 'loongson'; + $risc{'loongson'} = 1;}, 'man' => sub { $force{'man'} = 1;}, 'max-wrap|wrap-max|indent-min:i' => sub { @@ -5153,13 +5170,8 @@ sub get { }}, 'output-file|export-file:s' => sub { my ($opt,$arg) = @_; - if ($arg){ - if ($arg eq 'print' || main::check_output_path($arg)){ - $output_file = $arg; - } - else { - main::error_handler('output-file-bad', $opt, $arg); - } + if ($arg =~ /^(json|screen|xml)$/){ + $output_type = $arg; } else { main::error_handler('bad-arg', $opt, $arg); @@ -5172,6 +5184,16 @@ sub get { $risc{'ppc'} = 1;}, 'recommends' => sub { $show{'recommends'} = 1;}, + 'risc' => sub { + my ($opt,$arg) = @_; + if ($arg =~ /^(arm|loongson|mips|ppc|riscv|sparc)$/){ + undef %risc; + $risc{'id'} = $arg; + $risc{$arg} = 1; + } + else { + main::error_handler('bad-arg', $opt, $arg); + }}, 'riscv' => sub { undef %risc; $risc{'id'} = 'riscv'; @@ -5480,8 +5502,9 @@ sub show_options { ['1', '-b', '--basic', "Basic report: System (-S); basic CPU; Machine (-M); Battery (-B) (if found); Graphics (-G); Network devices (-N); basic Disk; Info (-I). Same as $self_name^-v2. See -e for expanded report."], - ['1', '-B', '--battery', "System battery info, including charge, condition - voltage (if critical), plus extra info (if battery present/detected)."], + ['1', '-B', '--battery', "System battery info, including charge, condition, + health (if avalable and not good), voltage (if critical), plus extra info + (if battery present/detected)."], ['1', '-C', '--cpu', "CPU report (if each item available): basic topology, model, type (see man for types), cache, average CPU speed, min/max speeds, per core clock speeds."], @@ -5664,8 +5687,9 @@ sub show_options { ['2', '-A', '', "Specific vendor/product information (if relevant); PCI/USB ID of device; Version/port(s)/driver version (if available); inactive sound servers/APIs."], - ['2', '-B', '', "Current/minimum voltage, vendor/model, status (if available); - attached devices (e.g. wireless mouse, keyboard, if present)."], + ['2', '-B', '', "Health, if available; urrent/minimum voltage, vendor/model, + status (if available); temperature (if available); attached devices (e.g. + wireless mouse, keyboard, if present)."], ['2', '-C', '', "L1/L3 cache (if most Linux, or if root and dmidecode installed); smt if disabled, CPU $flags (short list, use -f to see full list); Highest core speed (if > 1 core); CPU boost (turbo) enabled/disabled, if @@ -5722,7 +5746,8 @@ sub show_options { ['2', '-A', '', "Chip vendor:product ID for each audio device; PCIe speed, lanes (if found); USB rev, speed, lanes (if found); sound server/api helper daemons/plugins."], - ['2', '-B', '', "Power used, in watts; serial number."], + ['2', '-B', '', "Power used, in watts; serial number/ adds 'charging:' + section for charge info; charge cycles."], ['2', '-D', '', "Disk transfer speed; NVMe lanes; USB rev, speed, lanes (if found); Disk serial number; LVM volume group free space (if available); disk duid (some BSDs)."], @@ -5773,7 +5798,8 @@ sub show_options { ['1', '-xxx', '--extra 3', "Show extra, extra, extra data (only works with verbose or line reports, not short form):"], ['2', '-A', '', "Serial number, class ID."], - ['2', '-B', '', "Chemistry, cycles, location (if available)."], + ['2', '-B', '', "Manufacure date (uncommen); chemistry; location (uncommon); + temp min, max (uncommon); charge type (uncommon)."], ['2', '-C', '', "CPU voltage, external clock speed (if root and dmidecode installed); smt status, if available."], ['2', '-D', '', "Firmware rev. if available; partition scheme, in some cases; @@ -5817,6 +5843,8 @@ sub show_options { ['2', '-A', '', "If available: list of alternate kernel modules/drivers for device(s); PCIe lanes-max: gen, speed, lanes (if relevant); USB mode (if found); list of installed tools for servers."], + ['2', '-B', '', "Charge control min/max (if available); available charging + types (uncommon)."], ['2', '-C', '', "If available: microarchitecture level (64 bit AMD/Intel only).CPU generation, process node, built years; CPU socket type, base/boost speeds (dmidecode+root/sudo/doas required); Full topology line, with dies, @@ -6476,7 +6504,7 @@ sub clean_disk { my ($item) = @_; return $item if !$item; # <?unknown>?| - $item =~ s/vendor.*|product.*|O\.?E\.?M\.?//gi; + $item =~ s/vendor.*|product.*|(name\s)?n\/a|O\.?E\.?M\.?//gi; $item =~ s/^\s+|\s+$//g; $item =~ s/\s\s+/ /g; return $item; @@ -6484,8 +6512,8 @@ sub clean_disk { sub clean_dmi { my ($string) = @_; - $string = clean_unset($string,'AssetTagNum|^Base Board .*|^Chassis .*|' . - 'Manufacturer.*| Or Motherboard|\bOther\b.*|PartNum.*|SerNum|' . + $string = clean_unset($string,'Asset\s?Tag\s?Num.*|^Base\s?Board.*|^Chassis.*|' . + 'Manufacturer.*| Or Motherboard|\bOther\b.*|Part\s?Num.*|Ser(ial)?\s?Num.*|' . '^System .*|^0x[0]+$'); $string =~ s/\bbios\b|\bacpi\b//gi; $string =~ s/http:\/\/www.abit.com.tw\//Abit/i; @@ -6698,11 +6726,11 @@ sub message { $id ||= ''; $id2 ||= ''; my %message = ( - 'arm-cpu-f' => 'Use -f option to see features', 'audio-server-on-pipewire-pulse' => 'off (using pipewire-pulse)', 'audio-server-process-on' => 'active (process)', 'audio-server-root-na' => 'n/a (root, process)', 'audio-server-root-on' => 'active (root, process)', + 'battery-bad' => 'bad battery?', 'battery-data' => 'No system battery data found. Is one present?', 'battery-data-bsd' => 'No battery data found. Try with --dmidecode', 'battery-data-sys' => 'No /sys data found.', @@ -6794,6 +6822,7 @@ sub message { 'recommends' => 'see --recommends', 'repo-data', "No repo data detected. Does $self_name support your package manager?", 'repo-data-bsd', "No repo data detected. Does $self_name support $id?", + 'risc-cpu-f' => 'Use -f option to see features', 'risc-pci' => 'No ' . uc($id) . ' data found for this feature.', 'root-feature' => 'Feature requires superuser permissions.', 'root-item-incomplete' => "Full $id report requires superuser permissions.", @@ -7986,11 +8015,11 @@ sub sound_tools { { package BatteryItem; my (@upower_items,$b_upower,$upower); +my $battery = {}; sub get { eval $start if $b_log; my ($key1,$val1); - my $battery = {}; my $rows = []; my $num = 0; if ($force{'dmidecode'}){ @@ -8001,7 +8030,7 @@ sub get { @$rows = ({main::key($num++,0,1,$key1) => $val1}); } else { - battery_data_dmi($battery); + battery_data_dmi(); if (!%$battery){ if ($show{'battery-forced'}){ $key1 = 'Message'; @@ -8010,12 +8039,12 @@ sub get { } } else { - battery_output($rows,$battery); + battery_output($rows); } } } elsif ($bsd_type && ($sysctl{'battery'} || $show{'battery-forced'})){ - battery_data_sysctl($battery) if $sysctl{'battery'}; + battery_data_sysctl() if $sysctl{'battery'}; if (!%$battery){ if ($show{'battery-forced'}){ $key1 = 'Message'; @@ -8024,11 +8053,11 @@ sub get { } } else { - battery_output($rows,$battery); + battery_output($rows); } } elsif (-d '/sys/class/power_supply/'){ - battery_data_sys($battery); + battery_data_sys(); if (!%$battery){ if ($show{'battery-forced'}){ $key1 = 'Message'; @@ -8037,7 +8066,7 @@ sub get { } } else { - battery_output($rows,$battery); + battery_output($rows); } } else { @@ -8052,146 +8081,231 @@ sub get { return $rows; } -# alarm capacity capacity_level charge_full charge_full_design charge_now -# cycle_count energy_full energy_full_design energy_now location manufacturer model_name -# power_now present serial_number status technology type voltage_min_design voltage_now -# 0: name - battery id, not used -# 1: status -# 2: present -# 3: technology -# 4: cycle_count -# 5: voltage_min_design -# 6: voltage_now -# 7: power_now -# 8: energy_full_design -# 9: energy_full -# 10: energy_now -# 11: capacity -# 12: capacity_level -# 13: of_orig -# 14: model_name -# 15: manufacturer -# 16: serial_number -# 17: location +# sys files, these form the names used for sysctl and dmi sources too. +# see: pinxi/docs/inxi-battery.txt for more info on these items. +# +# %$battery keys: +# alarm +# capacity +# capacity_level +# charge_behaviour +# charge_control_end_threshold +# charge_control_start_threshold +# cycle_count +# energy_capacity +# energy_capacity_check +# energy_full +# energy_full_design +# energy_full_raw - use if low battery wh, < 1 +# energy_now +# energy_now_raw - use if low battery wh, < 1 +# health +# location - dmidecode has sometimes, but not usual +# manufacter_date +# manufacturer +# model_name +# name - battery id, not used +# of_orig +# of_orig_raw - use if low battery wh, < 1 +# power_now +# present +# purpose +# serial_number +# status +# technology +# temp +# temp_max +# temp_min +# voltage_min_design +# voltage_now sub battery_output { eval $start if $b_log; - my ($rows,$battery) = @_; - my ($key); + my $rows = $_[0]; my $num = 0; my $j = 0; # print Data::Dumper::Dumper $battery; - foreach $key (sort keys %$battery){ + foreach my $id (sort keys %$battery){ $num = 0; my ($charge,$condition,$model,$serial,$status) = ('','','','',''); my ($chemistry,$cycles,$location) = ('','',''); - next if !$battery->{$key}{'purpose'} || $battery->{$key}{'purpose'} ne 'primary'; - # $battery->{$key}{''}; + next if !$battery->{$id}{'purpose'} || $battery->{$id}{'purpose'} ne 'primary'; + # $battery->{$id}{''}; # we need to handle cases where charge or energy full is 0 - if (defined $battery->{$key}{'energy_now'} && $battery->{$key}{'energy_now'} ne ''){ - $charge = "$battery->{$key}{'energy_now'} Wh"; - if ($battery->{$key}{'energy_full'} && - main::is_numeric($battery->{$key}{'energy_full'})){ - my $percent = sprintf("%.1f", $battery->{$key}{'energy_now'}/$battery->{$key}{'energy_full'}*100); - $charge .= ' (' . $percent . '%)'; + if (defined $battery->{$id}{'energy_now'}){ + if (defined $battery->{$id}{'energy_now_raw'}){ + $battery->{$id}{'energy_now'} = $battery->{$id}{'energy_now_raw'}; + } + $charge = "$battery->{$id}{'energy_now'} Wh"; + # if energy_full is non zero or zero, and less than 1, capacity is not set + if ($battery->{$id}{'energy_capacity'}){ + $charge .= ' (' . $battery->{$id}{'energy_capacity'} . '%'; + # Got 'critical' for an almost fully charged battery, hold off on this. + # if ($extra > 0 && $battery->{$id}{'capacity_level'}){ + # $charge .= ' ' . $battery->{$id}{'capacity_level'}; + # } + $charge .= ')'; } } # better than nothing, shows the charged percent - elsif (defined $battery->{$key}{'capacity'} && $battery->{$key}{'capacity'} ne ''){ - $charge = $battery->{$key}{'capacity'} . '%' + elsif (defined $battery->{$id}{'energy_capacity'} && + main::is_numeric($battery->{$id}{'energy_capacity'})){ + $charge = $battery->{$id}{'energy_capacity'} . '%' + } + elsif (defined $battery->{$id}{'capacity'} && + main::is_numeric($battery->{$id}{'capacity'})){ + $charge = $battery->{$id}{'capacity'} . '%' } else { $charge = 'N/A'; } - if ($battery->{$key}{'energy_full'} || $battery->{$key}{'energy_full_design'}){ - $battery->{$key}{'energy_full_design'} ||= 'N/A'; - $battery->{$key}{'energy_full'} = (defined $battery->{$key}{'energy_full'} && - $battery->{$key}{'energy_full'} ne '') ? $battery->{$key}{'energy_full'} : 'N/A'; - $condition = "$battery->{$key}{'energy_full'}/$battery->{$key}{'energy_full_design'} Wh"; - if ($battery->{$key}{'of_orig'}){ - $condition .= " ($battery->{$key}{'of_orig'}%)"; + if ($battery->{$id}{'energy_full'} || $battery->{$id}{'energy_full_design'}){ + $battery->{$id}{'energy_full_design'} ||= 'N/A'; + # can be zero or close to it. + if (!defined $battery->{$id}{'energy_full'}){ + $battery->{$id}{'energy_full'} = 'N/A'; + } + elsif (defined $battery->{$id}{'energy_full_raw'}){ + $battery->{$id}{'energy_full'} = $battery->{$id}{'energy_full_raw'}; + } + $condition = "$battery->{$id}{'energy_full'}/$battery->{$id}{'energy_full_design'} Wh"; + if ($battery->{$id}{'of_orig'}){ + $condition .= " ($battery->{$id}{'of_orig'}%)"; + } + # if energy_full is non zero or zero, but less than 1, of_origin is 0 + # and of_origin_raw is the actual decimal value + elsif (defined $battery->{$id}{'of_orig'} && + $battery->{$id}{'of_orig'} == 0){ + if ($battery->{$id}{'of_orig_raw'}){ + $battery->{$id}{'of_orig'} = $battery->{$id}{'of_orig_raw'}; + } + $condition .= ' (' . $battery->{$id}{'of_orig'} . '%)'; } } $condition ||= 'N/A'; $j = scalar @$rows; push(@$rows, { - main::key($num++,1,1,'ID') => $key, - main::key($num++,0,2,'charge') => $charge, - main::key($num++,0,2,'condition') => $condition, + main::key($num++,1,1,'ID') => $id, }); - if ($extra > 2){ - if ($battery->{$key}{'power_now'}){ - $rows->[$j]{main::key($num++,0,2,'power')} = sprintf('%0.1f W',($battery->{$key}{'power_now'}/10**6)); + $rows->[$j]{main::key($num++,1,2,'charge')} = $charge; + if ($battery->{$id}{'energy_capacity_check'}){ + $rows->[$j]{main::key($num++,0,3,'note')} = $battery->{$id}{'energy_capacity_check'}; + } + $rows->[$j]{main::key($num++,1,2,'condition')} = $condition; + if ($battery->{$id}{'battery_bad'}){ + $rows->[$j]{main::key($num++,0,3,'alert')} = $battery->{$id}{'battery_bad'}; + } + if ($battery->{$id}{'health'} && + ($extra > 0 || $battery->{$id}{'health'} ne 'good')){ + $rows->[$j]{main::key($num++,0,3,'health')} = $battery->{$id}{'health'}; + } + if ($extra > 0 && $battery->{$id}{'temp'}){ + $rows->[$j]{main::key($num++,1,3,'temp')} = $battery->{$id}{'temp'} . ' C'; + if ($extra > 2 && $battery->{$id}{'temp_max'}){ + if ($battery->{$id}{'temp_min'}){ + $rows->[$j]{main::key($num++,0,4,'min')} = $battery->{$id}{'temp_min'} . ' C'; + } + $rows->[$j]{main::key($num++,0,4,'max')} = $battery->{$id}{'temp_max'} . ' C'; } } - if ($extra > 0 || ($battery->{$key}{'voltage_now'} && - $battery->{$key}{'voltage_min_design'} && - ($battery->{$key}{'voltage_now'} - $battery->{$key}{'voltage_min_design'}) < 0.5)){ - $battery->{$key}{'voltage_now'} ||= 'N/A'; - $rows->[$j]{main::key($num++,1,2,'volts')} = $battery->{$key}{'voltage_now'}; - if ($battery->{$key}{'voltage_now'} ne 'N/A' || $battery->{$key}{'voltage_min_design'}){ - $battery->{$key}{'voltage_min_design'} ||= 'N/A'; - $rows->[$j]{main::key($num++,0,3,'min')} = $battery->{$key}{'voltage_min_design'}; + if ($extra > 2 && $battery->{$id}{'power_now'}){ + $rows->[$j]{main::key($num++,0,2,'power')} = $battery->{$id}{'power_now'} . ' W'; + } + if ($extra > 0 || ($battery->{$id}{'voltage_now'} && + $battery->{$id}{'voltage_min_design'} && + ($battery->{$id}{'voltage_now'} - $battery->{$id}{'voltage_min_design'}) < 0.5)){ + $battery->{$id}{'voltage_now'} ||= 'N/A'; + $rows->[$j]{main::key($num++,1,2,'volts')} = $battery->{$id}{'voltage_now'}; + if ($battery->{$id}{'voltage_now'} ne 'N/A' || $battery->{$id}{'voltage_min_design'}){ + $battery->{$id}{'voltage_min_design'} ||= 'N/A'; + $rows->[$j]{main::key($num++,0,3,'min')} = $battery->{$id}{'voltage_min_design'}; } } if ($extra > 0){ - if ($battery->{$key}{'manufacturer'} || $battery->{$key}{'model_name'}){ - if ($battery->{$key}{'manufacturer'} && $battery->{$key}{'model_name'}){ - $model = "$battery->{$key}{'manufacturer'} $battery->{$key}{'model_name'}"; + if ($battery->{$id}{'manufacturer'} || $battery->{$id}{'model_name'}){ + if ($battery->{$id}{'manufacturer'} && $battery->{$id}{'model_name'}){ + $model = "$battery->{$id}{'manufacturer'} $battery->{$id}{'model_name'}"; } - elsif ($battery->{$key}{'manufacturer'}){ - $model = $battery->{$key}{'manufacturer'}; + elsif ($battery->{$id}{'manufacturer'}){ + $model = $battery->{$id}{'manufacturer'}; } - elsif ($battery->{$key}{'model_name'}){ - $model = $battery->{$key}{'model_name'}; + elsif ($battery->{$id}{'model_name'}){ + $model = $battery->{$id}{'model_name'}; } } else { $model = 'N/A'; } - $rows->[$j]{main::key($num++,0,2,'model')} = $model; + $rows->[$j]{main::key($num++,1,2,'model')} = $model; if ($extra > 2){ - $chemistry = ($battery->{$key}{'technology'}) ? $battery->{$key}{'technology'}: 'N/A'; + if ($battery->{$id}{'manufacture_date'}){ + $rows->[$j]{main::key($num++,0,3,'made')} = $battery->{$id}{'manufacture_date'}; + } + $chemistry = ($battery->{$id}{'technology'}) ? $battery->{$id}{'technology'}: 'N/A'; $rows->[$j]{main::key($num++,0,2,'type')} = $chemistry; } if ($extra > 1){ - $serial = main::filter($battery->{$key}{'serial_number'}); + $serial = main::filter($battery->{$id}{'serial_number'}); $rows->[$j]{main::key($num++,0,2,'serial')} = $serial; } - $status = ($battery->{$key}{'status'}) ? $battery->{$key}{'status'}: 'N/A'; - $rows->[$j]{main::key($num++,0,2,'status')} = $status; - if ($extra > 2){ - if ($battery->{$key}{'cycle_count'}){ - $rows->[$j]{main::key($num++,0,2,'cycles')} = $battery->{$key}{'cycle_count'}; + if ($extra > 2 && $battery->{$id}{'location'}){ + $rows->[$j]{main::key($num++,0,2,'location')} = $battery->{$id}{'location'}; + } + $status = ($battery->{$id}{'status'}) ? $battery->{$id}{'status'}: 'N/A'; + if ($extra > 1){ + $rows->[$j]{main::key($num++,1,2,'charging')} = ''; + $rows->[$j]{main::key($num++,0,3,'status')} = $status; + if ($b_admin && defined $battery->{$id}{'charge_control_end_threshold'} || + defined $battery->{$id}{'charge_control_start_threshold'} || + $battery->{$id}{'charge_behavior'}){ + $rows->[$j]{main::key($num++,1,3,'control')} = ''; + my $start = (defined $battery->{$id}{'charge_control_start_threshold'}) ? + $battery->{$id}{'charge_control_start_threshold'} . '%': 'N/A'; + my $end = (defined $battery->{$id}{'charge_control_end_threshold'}) ? + $battery->{$id}{'charge_control_end_threshold'} . '%': 'N/A'; + $rows->[$j]{main::key($num++,0,4,'start')} = $start; + $rows->[$j]{main::key($num++,0,4,'end')} = $end; + if ($battery->{$id}{'charge_behavior'}){ + $rows->[$j]{main::key($num++,0,4,'behavior')} = $battery->{$id}{'charge_behavior'}; + } } - if ($battery->{$key}{'location'}){ - $rows->[$j]{main::key($num++,0,2,'location')} = $battery->{$key}{'location'}; + if ($extra > 2 && $battery->{$id}{'charge_type'}){ + $rows->[$j]{main::key($num++,1,3,'type')} = $battery->{$id}{'charge_type'}; + if ($b_admin && $battery->{$id}{'charge_types'}){ + $rows->[$j]{main::key($num++,0,4,'avail')} = $battery->{$id}{'charge_types'}; + } } + # this is surprisingly uncommon, and sometimes is 0, which is false + my $cycles = ($battery->{$id}{'cycle_count'}) ? $battery->{$id}{'cycle_count'}: 'N/A'; + $rows->[$j]{main::key($num++,0,3,'cycles')} = $cycles; + } + else { + $rows->[$j]{main::key($num++,0,2,'status')} = $status; } } - $battery->{$key} = undef; + # dump the primary battery now + $battery->{$id} = undef; } - # print Data::Dumper::Dumper \%$battery; # now if there are any devices left, print them out, excluding Mains if ($extra > 0){ + # print Data::Dumper::Dumper \%$battery; $upower = main::check_program('upower'); - foreach $key (sort keys %$battery){ + foreach my $id (sort keys %$battery){ $num = 0; - next if !defined $battery->{$key} || $battery->{$key}{'purpose'} eq 'mains'; + next if !defined $battery->{$id} || $battery->{$id}{'purpose'} eq 'mains'; my ($charge,$model,$serial,$percent,$status,$vendor) = ('','','','','',''); $j = scalar @$rows; - my $upower_data = ($upower) ? upower_data($key) : {}; + my $upower_data = ($upower) ? upower_data($id) : {}; if ($upower_data->{'percent'}){ $charge = $upower_data->{'percent'}; } - elsif ($battery->{$key}{'capacity_level'} && - lc($battery->{$key}{'capacity_level'}) ne 'unknown'){ - $charge = $battery->{$key}{'capacity_level'}; + elsif ($battery->{$id}{'capacity_level'}){ + $charge = $battery->{$id}{'capacity_level'}; } else { $charge = 'N/A'; } - $model = $battery->{$key}{'model_name'} if $battery->{$key}{'model_name'}; - $vendor = $battery->{$key}{'manufacturer'} if $battery->{$key}{'manufacturer'}; + $model = $battery->{$id}{'model_name'} if $battery->{$id}{'model_name'}; + $vendor = $battery->{$id}{'manufacturer'} if $battery->{$id}{'manufacturer'}; if ($vendor || $model){ if ($vendor && $model){ $model = "$vendor $model"; @@ -8204,84 +8318,198 @@ sub battery_output { $model = 'N/A'; } push(@$rows, { - main::key($num++,1,1,'Device') => $key, + main::key($num++,1,1,'Device') => $id, main::key($num++,0,2,'model') => $model, },); if ($extra > 1){ - $serial = main::filter($battery->{$key}{'serial_number'}); + $serial = main::filter($battery->{$id}{'serial_number'}); $rows->[$j]{main::key($num++,0,2,'serial')} = $serial; } $rows->[$j]{main::key($num++,0,2,'charge')} = $charge; if ($extra > 2 && $upower_data->{'rechargeable'}){ $rows->[$j]{main::key($num++,0,2,'rechargeable')} = $upower_data->{'rechargeable'}; } - $status = ($battery->{$key}{'status'}) ? $battery->{$key}{'status'}: 'N/A' ; + $status = ($battery->{$id}{'status'}) ? $battery->{$id}{'status'}: 'N/A' ; $rows->[$j]{main::key($num++,0,2,'status')} = $status; } } eval $end if $b_log; } +## BATTERY DATA ## + +# BATTERY DATA PROCESSOR # +sub process_battery_data { + eval $start if $b_log; + for my $id (keys %$battery){ + # note:voltage_now fluctuates, which will make capacity numbers change a bit + # if any of these values failed, the math will be wrong, but no way to fix that + # tests show more systems give right capacity/charge with voltage_min_design + # than with voltage_now. Because of this, only use these as fallbacks to energy_*. + if ($battery->{$id}{'voltage_min_design'}){ + # CHARGE is Ah, which are converted to Wh by: Ah x voltage. + if (!$battery->{$id}{'energy_now'} && $battery->{$id}{'charge_now'}){ + $battery->{$id}{'energy_now'} = $battery->{$id}{'charge_now'} * $battery->{$id}{'voltage_min_design'}; + } + if (!$battery->{$id}{'energy_full'} && $battery->{$id}{'charge_full'}){ + $battery->{$id}{'energy_full'} = $battery->{$id}{'charge_full'}*$battery->{$id}{'voltage_min_design'}; + } + if (!$battery->{$id}{'energy_full_design'} && $battery->{$id}{'charge_full_design'}){ + $battery->{$id}{'energy_full_design'} = $battery->{$id}{'charge_full_design'} * $battery->{$id}{'voltage_min_design'}; + } + } + # Emulation data: + # $battery->{$id}{'energy_full'} = 0.01; + # $battery->{$id}{'energy_now'} = 0.01; + # Format Percentages + # Even with failing battery now and full should retain right proportions + if ($battery->{$id}{'energy_now'} && $battery->{$id}{'energy_full'}){ + $battery->{$id}{'energy_capacity'} = 100 * ($battery->{$id}{'energy_now'}/$battery->{$id}{'energy_full'}); + $battery->{$id}{'energy_capacity'} = sprintf('%.1f',$battery->{$id}{'energy_capacity'}) + 0; + if ($battery->{$id}{'energy_capacity'} > 100){ + $battery->{$id}{'energy_capacity_check'} = main::message('note-check'); + } + } + if ($battery->{$id}{'energy_full_design'} && $battery->{$id}{'energy_full'}){ + $battery->{$id}{'of_orig'} = 100 * ($battery->{$id}{'energy_full'}/$battery->{$id}{'energy_full_design'}); + if ($battery->{$id}{'of_orig'} < 1){ + # note: g prints only significant digits + $battery->{$id}{'of_orig_raw'} = sprintf('%.1g',$battery->{$id}{'of_orig'}); + } + elsif ($battery->{$id}{'of_orig'} < 5){ + $battery->{$id}{'battery_bad'} = main::message('battery-bad'); + } + $battery->{$id}{'of_orig'} = sprintf('%.1f',$battery->{$id}{'of_orig'}) + 0; + } + # format energy + if ($battery->{$id}{'energy_full'}){ + if ($battery->{$id}{'energy_full'} < 1){ + # note: g prints only significant digits + $battery->{$id}{'energy_full_raw'} = sprintf('%.1g',$battery->{$id}{'energy_full'}); + if (!$battery->{$id}{'battery_bad'}){ + $battery->{$id}{'battery_bad'} = main::message('battery-bad'); + } + } + $battery->{$id}{'energy_full'} = sprintf('%.1f',$battery->{$id}{'energy_full'}) + 0; + } + if ($battery->{$id}{'energy_full_design'}){ + $battery->{$id}{'energy_full_design'} = sprintf('%.1f',$battery->{$id}{'energy_full_design'}) + 0; + } + if ($battery->{$id}{'energy_now'}){ + if ($battery->{$id}{'energy_now'} < 1){ + # note: g prints only significant digits + $battery->{$id}{'energy_now_raw'} = sprintf('%.1g',$battery->{$id}{'energy_now'}); + } + $battery->{$id}{'energy_now'} = sprintf('%.1f',$battery->{$id}{'energy_now'}) + 0; + } + if ($battery->{$id}{'power_now'}){ + $battery->{$id}{'power_now'} = sprintf('%.1f',$battery->{$id}{'power_now'}) + 0; + } + # format voltages + if ($battery->{$id}{'voltage_min_design'}){ + $battery->{$id}{'voltage_min_design'} = sprintf("%.2f", $battery->{$id}{'voltage_min_design'}) + 0; + } + # could be zero + if (defined $battery->{$id}{'voltage_now'}){ + $battery->{$id}{'voltage_now'} = sprintf("%.2f", $battery->{$id}{'voltage_now'}) + 0; + } + # Format special values + if ($battery->{$id}{'manufacture_year'}){ + $battery->{$id}{'manufacture_date'} = $battery->{$id}{'manufacture_year'}; + if ($battery->{$id}{'manufacture_month'}){ + $battery->{$id}{'manufacture_date'} .= sprintf('-%02d',$battery->{$id}{'manufacture_month'}); + if ($battery->{$id}{'manufacture_day'}){ + $battery->{$id}{'manufacture_date'} .= sprintf('-%02d',$battery->{$id}{'manufacture_day'}); + } + } + } + } + print Data::Dumper::Dumper $battery if $dbg[33]; + main::log_data('dump','process: %$battery',$battery) if $b_log; + eval $end if $b_log; +} + +# BATTERY DATA SOURCES # + # charge: mAh energy: Wh sub battery_data_sys { eval $start if $b_log; - my $battery = $_[0]; - my ($b_ma,$file,$id,$item,$path,$value); + my ($file,$id,$item,$path,$value); my $num = 0; my @batteries = main::globber("/sys/class/power_supply/*"); # note: there is no 'location' file, but dmidecode has it # 'type' is generic, like: Battery, Mains # capacity_level is a string, like: Normal - my @items = qw(alarm capacity capacity_level charge_full charge_full_design - charge_now constant_charge_current constant_charge_current_max cycle_count - energy_full energy_full_design energy_now location manufacturer model_name - power_now present scope serial_number status technology type voltage_min_design - voltage_now); + my @items = qw(alarm capacity capacity_level charge_behaviour + charge_control_end_threshold charge_control_start_threshold + charge_full charge_full_design charge_now charge_type charge_types + constant_charge_current constant_charge_current_max cycle_count + energy_full energy_full_design energy_now health location manufacture_day + manufacture_month manufacture_year manufacturer model_name + power_now present scope serial_number status technology temp temp_alert_max + temp_alert_min temp_max temp_min type voltage_min_design voltage_now); foreach $item (@batteries){ - $b_ma = 0; $id = $item; $id =~ s%/sys/class/power_supply/%%g; foreach $file (@items){ $path = "$item/$file"; + undef $value; # android shows some files only root readable - $value = (-r $path) ? main::reader($path,'',0): ''; + $value = main::reader($path,'',0) if -r $path; # mains, plus in psu if ($file eq 'type' && $value && lc($value) ne 'battery'){ $battery->{$id}{'purpose'} = 'mains'; } if ($value){ $value = main::trimmer($value); - if ($file eq 'voltage_min_design'){ - $value = sprintf("%.1f", $value/1000000); - } - elsif ($file eq 'voltage_now'){ - $value = sprintf("%.1f", $value/1000000); - } - elsif ($file eq 'energy_full_design'){ - $value = $value/1000000; - } - elsif ($file eq 'energy_full'){ - $value = $value/1000000; + if ($file eq 'capacity_level'){ + $value = lc($value); + $value =~ s/unknown//; } - elsif ($file eq 'energy_now'){ - $value = sprintf("%.1f", $value/1000000); + # overides threshhold behavior + elsif ($file eq 'charge_behaviour'){ + $value = lc($value); } # note: the following 3 were off, 100000 instead of 1000000 # why this is, I do not know. I did not document any reason for that # so going on assumption it is a mistake. # CHARGE is mAh, which are converted to Wh by: mAh x voltage. # Note: voltage fluctuates so will make results vary slightly. - elsif ($file eq 'charge_full_design'){ + if ($file eq 'charge_full_design'){ $value = $value/1000000; - $b_ma = 1; } elsif ($file eq 'charge_full'){ $value = $value/1000000; - $b_ma = 1; } elsif ($file eq 'charge_now'){ $value = $value/1000000; - $b_ma = 1; + } + elsif ($file eq 'charge_type'){ + $value = lc($value); + $value =~ s/unknown|n\/a//; # both are valid values + } + # active in [] + elsif ($file eq 'charge_types'){ + $value = lc($value); + $value =~ s/\bunknown|n\/a\b//g; # both are valid values + if (!$battery->{$id}{'charge_type'} && $value =~ /\[([^]]+)\]/){ + $battery->{$id}{'charge_type'} = $1; + } + $value =~ s/\[|\]//g; + $value = join(',',sort(split(/\s+/,$value))); + } + elsif ($file eq 'energy_full_design'){ + $value = $value/1000000; + } + elsif ($file eq 'energy_full'){ + $value = $value/1000000; + } + elsif ($file eq 'energy_now'){ + $value = $value/1000000; + } + elsif ($file eq 'health'){ + $value = lc($value); + $value =~ s/unknown//; } elsif ($file eq 'manufacturer'){ $value = main::clean_dmi($value); @@ -8289,15 +8517,38 @@ sub battery_data_sys { elsif ($file eq 'model_name'){ $value = main::clean_dmi($value); } + elsif ($file eq 'power_now'){ + $value = $value/1000000; + } # Valid values: Unknown,Charging,Discharging,Not charging,Full # don't use clean_unset because Not charging is a valid value. elsif ($file eq 'status'){ $value = lc($value); $value =~ s/unknown//; - + } + elsif ($file eq 'temp'){ + $value = $value/10; + } + elsif ($file eq 'temp_alert_max'){ + $value = $value/10; + } + elsif ($file eq 'temp_alert_min'){ + $value = $value/10; + } + elsif ($file eq 'temp_max'){ + $value = $value/10; + } + elsif ($file eq 'temp_min'){ + $value = $value/10; + } + elsif ($file eq 'voltage_min_design'){ + $value = $value/1000000; + } + elsif ($file eq 'voltage_now'){ + $value = $value/1000000; } } - elsif ($b_root && -e $path && ! -r $path){ + elsif (!$b_root && -e $path && ! -r $path){ $value = main::message('root-required'); } $battery->{$id}{$file} = $value; @@ -8319,48 +8570,16 @@ sub battery_data_sys { $battery->{$id}{'purpose'} = 'device'; } } - # note:voltage_now fluctuates, which will make capacity numbers change a bit - # if any of these values failed, the math will be wrong, but no way to fix that - # tests show more systems give right capacity/charge with voltage_min_design - # than with voltage_now - if ($b_ma && $battery->{$id}{'voltage_min_design'}){ - if ($battery->{$id}{'charge_now'}){ - $battery->{$id}{'energy_now'} = $battery->{$id}{'charge_now'} * $battery->{$id}{'voltage_min_design'}; - } - if ($battery->{$id}{'charge_full'}){ - $battery->{$id}{'energy_full'} = $battery->{$id}{'charge_full'}*$battery->{$id}{'voltage_min_design'}; - } - if ($battery->{$id}{'charge_full_design'}){ - $battery->{$id}{'energy_full_design'} = $battery->{$id}{'charge_full_design'} * $battery->{$id}{'voltage_min_design'}; - } - } - if ($battery->{$id}{'energy_now'} && $battery->{$id}{'energy_full'}){ - $battery->{$id}{'capacity'} = 100 * $battery->{$id}{'energy_now'}/$battery->{$id}{'energy_full'}; - $battery->{$id}{'capacity'} = sprintf("%.1f", $battery->{$id}{'capacity'}); - } - if ($battery->{$id}{'energy_full_design'} && $battery->{$id}{'energy_full'}){ - $battery->{$id}{'of_orig'} = 100 * $battery->{$id}{'energy_full'}/$battery->{$id}{'energy_full_design'}; - $battery->{$id}{'of_orig'} = sprintf("%.1f", $battery->{$id}{'of_orig'}); - } - if ($battery->{$id}{'energy_now'}){ - $battery->{$id}{'energy_now'} = sprintf("%.1f", $battery->{$id}{'energy_now'}); - } - if ($battery->{$id}{'energy_full_design'}){ - $battery->{$id}{'energy_full_design'} = sprintf("%.1f",$battery->{$id}{'energy_full_design'}); - } - if ($battery->{$id}{'energy_full'}){ - $battery->{$id}{'energy_full'} = sprintf("%.1f", $battery->{$id}{'energy_full'}); - } } print Data::Dumper::Dumper $battery if $dbg[33]; main::log_data('dump','sys: %$battery',$battery) if $b_log; + process_battery_data(); eval $end if $b_log; } sub battery_data_sysctl { eval $start if $b_log; - my $battery = $_[0]; - my ($id); + my $id; for (@{$sysctl{'battery'}}){ if (/^(hw\.sensors\.)acpi([^\.]+)(\.|:)/){ $id = uc($2); @@ -8407,48 +8626,19 @@ sub battery_data_sysctl { } } } - # then do the condition/charge percent math + # then set to primary for my $id (keys %$battery){ $battery->{$id}{'purpose'} = 'primary'; - # CHARGE is Ah, which are converted to Wh by: Ah x voltage. - if ($battery->{$id}{'voltage_min_design'}){ - if ($battery->{$id}{'charge_now'}){ - $battery->{$id}{'energy_now'} = $battery->{$id}{'charge_now'} * $battery->{$id}{'voltage_min_design'}; - } - if ($battery->{$id}{'charge_full'}){ - $battery->{$id}{'energy_full'} = $battery->{$id}{'charge_full'}*$battery->{$id}{'voltage_min_design'}; - } - if ($battery->{$id}{'charge_full_design'}){ - $battery->{$id}{'energy_full_design'} = $battery->{$id}{'charge_full_design'} * $battery->{$id}{'voltage_min_design'}; - } - } - if ($battery->{$id}{'energy_full_design'} && $battery->{$id}{'energy_full'}){ - $battery->{$id}{'of_orig'} = 100 * $battery->{$id}{'energy_full'}/$battery->{$id}{'energy_full_design'}; - $battery->{$id}{'of_orig'} = sprintf("%.1f", $battery->{$id}{'of_orig'}); - } - if ($battery->{$id}{'energy_now'} && $battery->{$id}{'energy_full'}){ - $battery->{$id}{'capacity'} = 100 * $battery->{$id}{'energy_now'}/$battery->{$id}{'energy_full'}; - $battery->{$id}{'capacity'} = sprintf("%.1f", $battery->{$id}{'capacity'}); - } - if ($battery->{$id}{'energy_now'}){ - $battery->{$id}{'energy_now'} = sprintf("%.1f", $battery->{$id}{'energy_now'}); - } - if ($battery->{$id}{'energy_full'}){ - $battery->{$id}{'energy_full'} = sprintf("%.1f", $battery->{$id}{'energy_full'}); - } - if ($battery->{$id}{'energy_full_design'}){ - $battery->{$id}{'energy_full_design'} = sprintf("%.1f", $battery->{$id}{'energy_full_design'}); - } } print Data::Dumper::Dumper $battery if $dbg[33]; main::log_data('dump','dmi: %$battery',$battery) if $b_log; + process_battery_data(); eval $end if $b_log; } # note, dmidecode does not have charge_now or charge_full sub battery_data_dmi { eval $start if $b_log; - my $battery = $_[0]; my ($id); my $i = 0; foreach my $row (@dmi){ @@ -8473,21 +8663,13 @@ sub battery_data_dmi { $battery->{$id}{'model_name'} = main::clean_dmi($value[1])} elsif ($value[0] eq 'Design Capacity'){ $value[1] =~ s/\s*mwh$//i; - $battery->{$id}{'energy_full_design'} = sprintf("%.1f", $value[1]/1000); + $battery->{$id}{'energy_full_design'} = $value[1]/1000; } elsif ($value[0] eq 'Design Voltage'){ $value[1] =~ s/\s*mv$//i; - $battery->{$id}{'voltage_min_design'} = sprintf("%.1f", $value[1]/1000); + $battery->{$id}{'voltage_min_design'} = $value[1]/1000; } } - if ($battery->{$id}{'energy_now'} && $battery->{$id}{'energy_full'}){ - $battery->{$id}{'capacity'} = 100 * $battery->{$id}{'energy_now'} / $battery->{$id}{'energy_full'}; - $battery->{$id}{'capacity'} = sprintf("%.1f%", $battery->{$id}{'capacity'}); - } - if ($battery->{$id}{'energy_full_design'} && $battery->{$id}{'energy_full'}){ - $battery->{$id}{'of_orig'} = 100 * $battery->{$id}{'energy_full'} / $battery->{$id}{'energy_full_design'}; - $battery->{$id}{'of_orig'} = sprintf("%.0f%", $battery->{$id}{'of_orig'}); - } } elsif ($row->[0] > 22){ last; @@ -8495,11 +8677,12 @@ sub battery_data_dmi { } print Data::Dumper::Dumper $battery if $dbg[33]; main::log_data('dump','dmi: %$battery',$battery) if $b_log; + process_battery_data(); eval $end if $b_log; } sub upower_data { - my ($id) = @_; + my $id = $_[0]; eval $start if $b_log; my $data = {}; if (!$b_upower && $upower){ @@ -9367,25 +9550,29 @@ sub full_output { if (($extra > 0 && !$show{'cpu-flag'}) || $show{'cpu-flag'}){ my @flags = ($cpu->{'flags'}) ? split(/\s+/, $cpu->{'flags'}) : (); my $flag_key = (%risc || $bsd_type) ? 'Features': 'Flags'; - my $flag = 'N/A'; + my $flag_list = 'N/A'; if (!$show{'cpu-flag'}){ - if (@flags){ - # failure to read dmesg.boot: dmesg.boot permissions; then short -Cx list flags - @flags = grep {/^(dmesg.boot|permissions|avx[2-9]?|ht|lm|nx|pae|pni|(sss|ss)e([2-9])?([a-z])?(_[0-9])?|svm|vmx)$/} @flags; + $flag_key .= '-basic' if !%risc; + # failure to read dmesg.boot: dmesg.boot permissions + if ($bsd_type && (@flags = grep {/^(dmesg.boot|permissions)$/} @flags)){ + # do nothing, we're done, it's bad data + } + # ARM/Loongson have Features, never seen them for MIPS/PPC/SPARC/RISCV, but check + elsif (%risc && @flags){ + $flag_list = main::message('risc-cpu-f'); + @flags = (); # dump it, we're not printing it + } + # not risc or bad bsd data, create the short list + elsif (@flags) { + @flags = grep {/^(avx[2-9]?|ht|lm|nx|pae|pni|(sss|ss)e([2-9])?([a-z])?(_[0-9])?|svm|vmx)$/} @flags; @flags = map {s/pni/sse3/; $_} @flags if @flags; - @flags = sort @flags; - } - # only ARM has Features, never seen them for MIPS/PPC/SPARC/RISCV, but check - if ($risc{'arm'} && $flag eq 'N/A'){ - $flag = main::message('arm-cpu-f'); } } if (@flags){ - @flags = sort @flags; - $flag = join(' ', @flags); + $flag_list = join(' ', sort @flags); } push(@$rows, { - main::key($num++,0,1,$flag_key) => $flag, + main::key($num++,0,1,$flag_key) => $flag_list, },); } if ($b_admin){ @@ -9603,38 +9790,56 @@ sub set_fake_cpu_data { # $ci = "$fake_data_dir/cpu/loongson/3A5000M-4-core-4.19.0.txt"; ## CPU CPUINFO/SYS PAIRS DATA FILES ## + ## Android # $ci = "$fake_data_dir/cpu/sys-ci-pairs/android-pocom3-fake-cpuinfo.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/android-pocom3-fake-sys.txt"; + ## ARM # $ci = "$fake_data_dir/cpu/sys-ci-pairs/arm-pine64-cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/arm-pine64-sys-1.txt"; # $ci = "$fake_data_dir/cpu/sys-ci-pairs/arm-riscyslack2-cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/arm-riscyslack2-sys-1.txt"; + ## Elbrus + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/elbrus-e16c-1-cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/elbrus-e16c-1-sys.txt"; + ## PPC # $ci = "$fake_data_dir/cpu/sys-ci-pairs/ppc-stuntkidz~cpuinfo.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/ppc-stuntkidz~sys.txt"; + ## RISCV # $ci = "$fake_data_dir/cpu/sys-ci-pairs/riscv-unmatched-2021~cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/riscv-unmatched-2021~sys-1.txt"; - # $ci = "$fake_data_dir/cpu/sys-ci-pairs/x86-brickwizard-atom-n270~cpuinfo-1.txt"; - # $sys = "$fake_data_dir/cpu/sys-ci-pairs/x86-brickwizard-atom-n270~sys-1.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/risc-v-spacemit-8-core-cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/risc-v-spacemit-8-core-sys.txt"; + ## Loongson + $ci = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3a5000-hv/cpuinfo.txt"; + $sys = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3a5000-hv/cpu-sys.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3a5000m/cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3a5000m/cpu-sys.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3c5000/cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3c5000/cpu-sys.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3d5000/cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3d5000/cpu-sys.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3a6000-hw/cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/loongson/loongson-3a6000-hw/cpu-sys.txt"; + # AMD # $ci = "$fake_data_dir/cpu/sys-ci-pairs/x86-amd-phenom-chrisretusn-cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/x86-amd-phenom-chrisretusn-sys-1.txt"; - # $ci = "$fake_data_dir/cpu/sys-ci-pairs/x86-drgibbon-intel-i7-cpuinfo.txt"; - # $sys = "$fake_data_dir/cpu/sys-ci-pairs/x86-drgibbon-intel-i7-sys.txt"; # $ci = "$fake_data_dir/cpu/sys-ci-pairs/ryzen-threadripper-1x64-3950x-cpuinfo.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/ryzen-threadripper-1x64-3950x-sys.txt"; # $ci = "$fake_data_dir/cpu/sys-ci-pairs/amd-threadripper-1x12-5945wx-cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/amd-threadripper-1x12-5945wx-sys-1.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/amd-epyc-2x-16-core-4-die-cpuinfo-1.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/amd-epyc-2x-16-core-4-die-sys-1.txt"; + # Intel + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/x86-brickwizard-atom-n270~cpuinfo-1.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/x86-brickwizard-atom-n270~sys-1.txt"; + # $ci = "$fake_data_dir/cpu/sys-ci-pairs/x86-drgibbon-intel-i7-cpuinfo.txt"; + # $sys = "$fake_data_dir/cpu/sys-ci-pairs/x86-drgibbon-intel-i7-sys.txt"; # $ci = "$fake_data_dir/cpu/sys-ci-pairs/intel-i7-1165G7-4-core-no-smt-cpuinfo.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/intel-i7-1165G7-4-core-no-smt-sys.txt"; - # $ci = "$fake_data_dir/cpu/sys-ci-pairs/elbrus-e16c-1-cpuinfo.txt"; - # $sys = "$fake_data_dir/cpu/sys-ci-pairs/elbrus-e16c-1-sys.txt"; # $ci = "$fake_data_dir/cpu/sys-ci-pairs/intel-raptor-lake-10-core-cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/intel-raptor-lake-10-core-sys-1.txt"; - # $ci = "$fake_data_dir/cpu/sys-ci-pairs/risc-v-spacemit-8-core-cpuinfo.txt"; - # $sys = "$fake_data_dir/cpu/sys-ci-pairs/risc-v-spacemit-8-core-sys.txt"; # $ci = "$fake_data_dir/cpu/sys-ci-pairs/intel-xeon-2x12-core-mt-cpuinfo-1.txt"; # $sys = "$fake_data_dir/cpu/sys-ci-pairs/intel-xeon-2x12-core-mt-sys-1.txt"; - $ci = "$fake_data_dir/cpu/sys-ci-pairs/amd-epyc-2x-16-core-4-die-cpuinfo-1.txt"; - $sys = "$fake_data_dir/cpu/sys-ci-pairs/amd-epyc-2x-16-core-4-die-sys-1.txt"; $fake_data{'cpuinfo'} = $ci; $fake_data{'sys'} = $sys; } @@ -9687,8 +9892,8 @@ sub cpuinfo_data_grabber { main::log_data('dump','%cpuinfo_machine',\%cpuinfo_machine); } if ($dbg[41]){ - print Data::Dumper::Dumper \@cpuinfo; - print Data::Dumper::Dumper \%cpuinfo_machine; + print 'cpuinfo: ', Data::Dumper::Dumper \@cpuinfo; + print 'cpuinfo_machine: ', Data::Dumper::Dumper \%cpuinfo_machine; } eval $end if $b_log; } @@ -9722,7 +9927,7 @@ sub cpuinfo_data { next if !$block; if ($b_block_1){ $b_block_1 = 0; - # this may also kick in for centaur/via types, but no data available, guess + # this may also kick in for centaur/via/zhaoxin types. zhaoxin shows as centaur if (!$cpu->{'type'} && $block->{'vendor_id'}){ $cpu->{'type'} = cpu_vendor($block->{'vendor_id'}); } @@ -9747,12 +9952,15 @@ sub cpuinfo_data { # print "p0:\n"; } } - elsif ($cpu->{'model_name'} =~ /loongson|godson/i){ + elsif ($risc{'loongson'} || $cpu->{'model_name'} =~ /loong|godson/i){ $cpu->{'type'} = 'loongson'; } elsif ($risc{'mips'} || $cpu->{'model_name'} =~ /mips/i){ $cpu->{'type'} = 'mips'; } + elsif (!%risc && $cpu->{'model_name'} =~ /zhaoxin/i){ + $cpu->{'type'} = 'zhaoxin'; + } } $temp = main::get_defined($block->{'architecture'}, $block->{'cpu family'},$block->{'cpu architecture'}); @@ -9761,11 +9969,14 @@ sub cpuinfo_data { # translate integers to hex $cpu->{'family'} = uc(sprintf("%x",$temp)); } + elsif ($risc{'loongson'}){ + $cpu->{'family'} = $temp; + } elsif ($risc{'arm'}){ $cpu->{'arch'} = $temp; } } - # note: stepping and ARM cpu revision are integers + # note: stepping and ARM cpu revision integers, loongson hex $temp = main::get_defined($block->{'stepping'},$block->{'cpu revision'}); # can be 0, but can be 'unknown' if (defined $temp || @@ -9816,7 +10027,7 @@ sub cpuinfo_data { $block->{'l3 cache size'} =~ /(\d+\s*[KMG])i?B?$/){ $cpu->{'l3-cache'} = main::translate_size($1); } - $temp = main::get_defined($block->{'flags'} || $block->{'features'}); + $temp = main::get_defined($block->{'flags'},$block->{'features'}); if ($temp){ $cpu->{'flags'} = $temp; } @@ -11637,6 +11848,8 @@ sub cp_cpu_arch { # print "type:$type fam:$family model:$model step:$stepping\n"; # Note: AMD family is not Ext fam . fam but rather Ext-fam + fam. # But model is Ext model . model... + # This is very confusing because cpuinfo shows say, family: 23 for 17h, aka 8F + # which gives: 8 + F = 23. hex of which is 17h if ($type eq 'amd'){ if ($family eq '3'){ $arch = 'Am386'; @@ -11712,7 +11925,7 @@ sub cp_cpu_arch { $year = '2003-14';} } # note: family F K8 needs granular breakdowns, was a long lived family - elsif ($family eq 'F'){ + elsif ($family eq 'F'){ # F, aka 15 ## verified # check: B|E|F if ($model =~ /^(4|5|7|8|B|C|E|F)$/){ @@ -11740,7 +11953,7 @@ sub cp_cpu_arch { $year = '2004-2008';} } # K9 was planned but skipped - elsif ($family eq '10'){ # 1F + elsif ($family eq '10'){ # 1F, aka 16 ## verified if ($model =~ /^(2)$/){ $arch = 'K10'; # 2:2:budapest;2:1,3:barcelona @@ -11759,7 +11972,7 @@ sub cp_cpu_arch { } # very loose, all stepping 1: covers athlon x2, sempron, turion x2 # years unclear, could be 2005 start, or 2008 - elsif ($family eq '11'){ # 2F + elsif ($family eq '11'){ # 2F, aka 17 if ($model =~ /^(3)$/){ $arch = 'K11 Turion X2'; # mix of K8/K10 $note = $check; @@ -11767,7 +11980,7 @@ sub cp_cpu_arch { $year = ''; } } # might also need cache handling like 14/16 - elsif ($family eq '12'){ # 3F + elsif ($family eq '12'){ # 3F, aka 18 if ($model =~ /^(1)$/){ $arch = 'K12 Fusion'; # K10 based apu, llano $process = 'GF 32nm'; @@ -11778,7 +11991,7 @@ sub cp_cpu_arch { $year = '2011';} # check years } # SOC, apu - elsif ($family eq '14'){ # 5F + elsif ($family eq '14'){ # 5F, aka 20 if ($model =~ /^(1|2)$/){ $arch = 'Bobcat'; $process = 'GF 40nm'; @@ -11788,7 +12001,7 @@ sub cp_cpu_arch { $process = 'GF 40nm'; $year = '2011-13';} } - elsif ($family eq '15'){ # 6F + elsif ($family eq '15'){ # 6F, aka 21 # note: only model 1 confirmd if ($model =~ /^(0|1|3|4|5|6|7|8|9|A|B|C|D|E|F)$/){ $arch = 'Bulldozer'; @@ -11815,7 +12028,7 @@ sub cp_cpu_arch { $year = '2011-12';} } # SOC, apu - elsif ($family eq '16'){ # 7F + elsif ($family eq '16'){ # 7F, aka 22 if ($model =~ /^(0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F)$/){ $arch = 'Jaguar'; $process = 'GF 28nm'; @@ -11829,7 +12042,7 @@ sub cp_cpu_arch { $process = 'GF 28nm'; $year = '2013-14';} } - elsif ($family eq '17'){ # 8F + elsif ($family eq '17'){ # 8F, aka 23 # can't find stepping/model for no ht 2x2 core/die models, only first ones if ($model =~ /^(1|11|20)$/){ $arch = 'Zen'; @@ -11863,13 +12076,13 @@ sub cp_cpu_arch { $year = '';} } # Joint venture between AMD and Chinese companies. Type amd? or hygon? - elsif ($family eq '18'){ # 9F + elsif ($family eq '18'){ # 9F, aka 24 # model 0, zen 1 $arch = 'Zen (Hygon Dhyana)'; $gen = '1'; $process = 'GF 14nm'; $year = '';} - elsif ($family eq '19'){ # AF + elsif ($family eq '19'){ # AF, aka 25 # zen 4 raphael, phoenix 1 use n5 I believe # Epyc Bergamo zen4c 4nm, only few full model IDs, update when appear # zen4c is for cloud hyperscale @@ -11904,7 +12117,7 @@ sub cp_cpu_arch { $year = '2021-22';} } # Zen 5: TSMC n3/n4, epyc turin / granite ridge? / turin dense zen 5c 3nm - elsif ($family eq '20'){ # BF + elsif ($family eq '1A'){ # BF, aka 26 if ($model =~ /^(0)$/){ $arch = 'Zen 5'; $gen = '5'; @@ -11916,17 +12129,38 @@ sub cp_cpu_arch { $process = 'TSMC n3 (3nm)'; # turin could be 4nm, need more data $year = '2024+';} # Strix Point; Granite Ridge; Krackan Point; Strix Halo - elsif ($model =~ /^(2.|4.|6.|7.)$/){ + elsif ($model =~ /^[2-7].$/){ $arch = 'Zen 5'; $gen = '5'; $process = 'TSMC n4 (4nm)'; # desktop, granite ridge, confirm 2024 $year = '2024+';} + # seen: 90,A0,C0 + elsif ($model =~ /^(9|[A-G]).$/){ + $arch = 'Zen 6'; + $note = '6'; + $process = 'TSMC n2/n3 (2,3nm)'; + $year = '2025+';} else { $arch = 'Zen 5'; $note = $check; $process = 'TSMC n3/n4 (3,4nm)'; $year = '2024+';} } + # note: no live data on zen 7 yet + elsif ($family eq '1B'){ # CF, aka 27 + $arch = 'Zen 7'; + $note = $check; + $process = 'TSMC n2/n3 (2,3nm)'; + $year = '2026+'; + } + # this is a guess + elsif ($family eq '1D'){ # DF, aka 28 + $arch = 'Zen 8'; + $note = $check; + $process = 'TSMC a14 (1.4nm)'; + $year = '2027+'; + } + # Roadmap: check to verify, AMD is usually closer to target than Intel # Epyc 4 genoa: zen 4, nm, 2022+ (dec 2022), cxl-1.1,pcie-5, ddr-5 } @@ -11983,18 +12217,16 @@ sub cp_cpu_arch { elsif ($stepping <= 12){ $arch = 'Via Isaah';} elsif ($stepping <= 13){ + $arch = 'Via Isaah';} + # these are both stepping E + elsif ($stepping <= 14){ $arch = 'Via Eden';} elsif ($stepping <= 14){ $arch = 'Zhaoxin ZX';} - $process = '90nm'; # guess - $year = '';} - } - elsif ($family eq '7'){ - if ($model =~ /^(1.|3.)$/){ - $arch = 'Zhaoxin ZX'; - $process = '90nm'; # guess - $year = ''; - } + $process = '40nm'; + $year = '2014';} + elsif ($model =~ /^(47)$/){ + $arch = 'Centaur CNS';} } } # note, to test uncoment $cpu{'type'} = Elbrus in proc/cpuinfo logic @@ -12433,6 +12665,15 @@ sub cp_cpu_arch { $arch = 'Emerald Rapids'; # 5th gen xeon $process = 'Intel 7 (10nm)'; $year = '2023+';} + elsif ($model =~ /^(D5)$/){ + $arch = 'Wildcat Lake'; + $process = 'Intel 18a (1.8nm)'; + $year = '2025+';} + elsif ($model =~ /^(D7)$/){ + $arch = 'Bartlett Lake'; + $note = $check; # confirm process + $process = 'Intel 18a (1.8nm)'; + $year = '2026+';} elsif ($model =~ /^(DD)$/){ $arch = 'Clearwater Forest'; $process = 'Intel 18a (1.8nm)'; @@ -12530,27 +12771,27 @@ sub cp_cpu_arch { # can't safely match model 1, but nobody will run inxi on that # Not certain when SMIC took over from STM, which is a swiss firm. if ($name =~ /\b2[BCE]\b/){ - $arch = 'Godson'; + $arch = 'Godson-1'; $process = 'STM 180nm'; $year = '2003-2006';} elsif ($name =~ /\b1[ABCD]\b/){ - $arch = 'Loongson-1'; + $arch = 'Godson-1/Loongson-1'; $process = 'STM 130nm'; $year = '2010-2014';} elsif ($name =~ /\b1C101/){ - $arch = 'Loongson-1'; + $arch = 'Godson-1/Loongson-1'; $process = 'STM 130nm'; $year = '2018';} elsif ($name =~ /\b2F\b/){ - $arch = 'Loongson-2'; + $arch = 'Godson-2/Loongson-2'; $process = 'STM 90nm'; $year = '2007';} elsif ($name =~ /\b2[GIH]\b/){ - $arch = 'Loongson-2'; + $arch = 'Godson-2/Loongson-2'; $process = 'STM 65nm'; $year = '2012-2013';} elsif ($name =~ /\b2K(1000)?\b/){ - $arch = 'Loongson-2'; + $arch = 'Godson-2/Loongson-2'; $process = 'STM 40nm'; $year = '2017';} elsif ($name =~ /3A1000/){ @@ -12581,10 +12822,71 @@ sub cp_cpu_arch { $arch = 'Loongson-3/LoongArch'; $process = 'SMIC 12-14nm'; $year = '2021+';} - elsif ($name =~ /3[A-C]6000/){ + elsif ($name =~ /3[D]5000/){ + $arch = 'Loongson-3/LoongArch'; + $process = 'SMIC 12-14nm'; + $year = '2023+';} + elsif ($name =~ /3[AB]6000/){ $arch = 'Loongson-3/LoongArch'; $process = 'SMIC 12-14nm'; $year = '2023+';} + elsif ($name =~ /3[CD]6000/){ + $arch = 'Loongson-3/LoongArch'; + $process = 'SMIC 12-14nm'; + $year = '2024+';} + elsif ($name =~ /3[A-D]7000/){ + $arch = 'Loongson-3/LoongArch'; + $process = 'SMIC 7nm'; + $year = '2025+';} + } + # this is an x86_64 cpu so has full CPUID + elsif ($type eq 'zhaoxin'){ + # family 1-6 was via and very early zhaoxin + if ($family eq '6'){ + # no model IDs for first gen via clones + # A?000 KaiXian, A??000 Kaisheng; Successor to via isiah 2 + if ($model =~ /^\d$/){ # guess early + $arch = 'VIA-Isaiah2'; + $process = 'TSMC 40nm'; + $year = '2014+';} + # B3000 KaiXian, B3000 Kaisheng; Successor to via isiah 2 + elsif ($model =~ /^x$/){ + $arch = 'VIA-Isaiah2'; + $process = 'TSMC 40nm'; + $year = '2014-15+';} + # C,C+4000 KaiXian, C+4000 Kaisheng; Successor to via isiah 2 + elsif ($model =~ /^([A-F]|1\d)$/){ # seen F, 19 + $arch = 'ZhangJian'; + $process = 'HLMC 28nm'; # also reported as TSMC + $year = '2015+';} + # D4600 + elsif ($model =~ /^(1[A-F])$/){ # seen 1F + $arch = 'ZhangJian'; + $process = 'HLMC 28nm'; # also reported as TSMC + $year = '2015+';} + } + elsif ($family eq '7'){ + # KX5000 KaiXian, KH20000 Kaisheng, seen: 1B + if ($model =~ /^(.|1.)$/){ # seen B + $arch = 'WuDaoKou'; + $process = 'HLMC 28nm'; # also reported as TSMC + $year = '2017+';} + # KX6000 KaiXian, KH30000 Kaisheng, seen: 3B + elsif ($model =~ /^3.$/){ + $arch = 'LuJiaZui'; + $process = 'TSMC 16nm'; + $year = '2019+';} + # KH40000 Kaisheng + elsif ($model =~ /^(5.)$/){ # seen 5B for 40000 + $arch = 'YongFeng'; # 世纪大道 + $process = '16nm'; # smic? + $year = '2023+';} + # KZ,KX7000 KaiXian + elsif ($model =~ /^[67].$/){ # guess + $arch = 'Shijidadao'; + $process = '7nm'; # smic,huawei 7nm? + $year = '2024+';} + } } eval $end if $b_log; return [$arch,$note,$process,$gen,$year]; @@ -12800,15 +13102,15 @@ sub cpu_vendor { my $string = $_[0]; my $vendor = ''; $string = lc($string); - if ($string =~ /intel/){ + if ($string =~ /intel/i){ $vendor = "intel"; } - elsif ($string =~ /amd/){ + elsif ($string =~ /amd/i){ $vendor = "amd"; } - # via/centaur/zhaoxin branding - elsif ($string =~ /centaur|zhaoxin/){ - $vendor = "centaur"; + # via/centaur/zhaoxin branding, but zhaoxin shows centaurhauls as vendor + elsif ($string =~ /(centaur|zhaoxin)/i){ + $vendor = lc($1); } elsif ($string eq 'elbrus'){ $vendor = "elbrus"; @@ -14219,14 +14521,14 @@ sub set_disk_vendors { ['(\bINTEL\b|^(SSD(PAM|SA2)|HBR|(MEM|SSD)PEB?K|SSD(MCE|S[AC])))','\bINTEL\b','Intel',''], ['^(Intel[\s_-]?)?SRCSAS?','^Intel','Intel RAID',''], # note: S[AV][1-9]\d can trigger false positives - ['(K(ING)?STON|^(A400|ASTC|OM8P|RBU|S100\d\d|S[AV][1234]00|S[HMN]S|SK[CY]|SQ5|SS200|SVP|SS0|SUV|SNV|T52|T[ABY]29|Y29\d|Ultimate CF)|V100|DataTraveler|DT\s?(DUO|Microduo|101)|HyperX|13fe\b)','(KINGSTON|13fe)','Kingston',''], # maybe SHS: SHSS37A SKC SUV + ['(K(ING)?STON|^(A29\d\d\d|A400|ASTC|OM8P|Fury|RBU|S100\d\d|S[AV][1234]00|S[HMN]S|SK[CY]|SQ5|SS200|SVP|SS0|SUV|SNV|T52|T[ABY]29|Y29\d|Ultimate CF)|V100|DataTraveler|DT\s?(DUO|Microduo|101)|HyperX|13fe\b)','(KINGSTON|13fe)','Kingston',''], # maybe SHS: SHSS37A SKC SUV # must come before samsung MU. NOTE: toshiba can have: TOSHIBA_MK6475GSX: mush: MKNSSDCR120GB_ ['(^MKN|Mushkin)','Mushkin','Mushkin',''], # MKNS # MU = Multiple_Flash_Reader too risky: |M[UZ][^L] HD103SI HD start risky # HM320II HM320II HM - ['(SAMSUNG|^(AGN[BD]|AWMB|[BC]DS20|[BCD]WB|BJ[NT]|[BC]GND|CJ[NT]|CKT|CUT|[DG]3 Station|DUO\b|DUT|EB\dMW|E[CS]\d[A-Z]\d|ED2|EE4|FD\d[A-Z]\d|[GS]2 Portable|GE4|GN|HD\d{3}[A-Z]{2}$|(HM|SP)\d{2}|HS\d|KLUD|M[AB]G\d[FG]|MCC|MCBOE|MCG\d+GC|[CD]JN|MZ|^G[CD][1-9][QS]|P[BM]\d|(SSD\s?)?SM\s?841)|^SSD\s?[89]\d{2}\s(DCT|PRO|QVD|\d+[GT]B)|\bEVO\b|SV\d|[BE][A-Z][1-9]QT|YP\b|[CH]N-M|MMC[QR]E)','SAMSUNG','Samsung',''], # maybe ^SM, ^HM + ['(SAMSUNG|^(A[GJ]N[BD]|AWMB|[BC]DS20|[BCD]WB|BJ[NT]|[BC]GND|CJ[NT]|CKT|CUT|[DG]3 Station|DUO\b|DUT|EB\dMW|E[CS]\d[A-Z]\d|ED2|EE4|FD\d[A-Z]\d|[GS]2 Portable|GE4|GN|HD\d{3}[A-Z]{2}$|(HM|SP)\d{2}|HS\d|KLUD|M[AB]G\d[FG]|MCC|MCBOE|MCG\d+GC|[CD]JN|MZ|^G[CD][1-9][QS]|P[BM]\d|(SSD\s?)?SM\s?841)|^SSD\s?[89]\d{2}\s(DCT|PRO|QVD|\d+[GT]B)|\bEVO\b|SV\d|[BE][A-Z][1-9]QT|YP\b|[CH]N-M|MMC[QR]E)','SAMSUNG','Samsung',''], # maybe ^SM, ^HM # Android UMS Composite?U1 - ['(SanDisk|0781|^(A[BCD]LC[DE]|AFGCE|D[AB]4|DX[1-9]|Extreme|EZSD|Firebird|S[CD]\d{2}G|SB\d+G|SC\d{3,4}|SD(CF|S[S]?[ADQ]|SL\d+G|SU\d|U\d|\sUltra)|SDW[1-9]|SE\d{2}|SEM\d{2}|\d[STU]|U(3\b|1\d0))|Clip Sport|Cruzer|iXpand|SN(\d+G|128|256)|SSD (Plus|U1[01]0) [1-9]|SU(02|04|08|16|32|64)G|ULTRA\s(FIT|trek|II)|^X[1-6]\d{2})','(SanDisk|0781)','SanDisk',''], + ['(SanDisk|0781|^(A[BCD]LC[DE]|AFGCE|D[AB]4|DX[1-9]|Extreme|EZSD|Firebird|MDG|S[CD]\d{2}G|SB\d+G|SC\d{3,4}|SD(CF|S[S]?[ADQ]|SL\d+G|SU\d|U\d|\sUltra)|SDW[1-9]|SE\d{2}|SEM\d{2}|\d[STU]|U(3\b|1\d0))|Clip Sport|Cruzer|iXpand|SN(\d+G|128|256)|SSD (Plus|U1[01]0) [1-9]|SU(02|04|08|16|32|64)G|ULTRA\s(FIT|trek|II)|^X[1-6]\d{2})','(SanDisk|0781)','SanDisk',''], # these are HP/Sandisk cobranded. DX110064A5xnNMRI ids as HP and Sandisc ['(^DX[1-9])','^(HP\b|SANDDISK)','Sandisk/HP',''], # ssd drive, must come before seagate ST test # real, SSEAGATE Backup+; XP1600HE30002 | 024 HN (spinpoint) ; possible usb: 24AS @@ -14335,7 +14637,7 @@ sub set_disk_vendors { ['^BIOSTAR','^BIOSTAR','Biostar',''], ['^BIWIN','^BIWIN','BIWIN',''], ['^Blackpcs','^Blackpcs','Blackpcs',''], - ['^(BlitzWolf|BW-?PSSD)','^BlitzWolf','BlitzWolf',''], + ['^(BlitzWolf|BW)','^BlitzWolf','BlitzWolf',''], ['^(BlueCase|BS2N\d)','^BlueCase[\s-]?(Horizon)?','BlueCase Horizon',''], ['^(Blue[\s-]?Feather|BF\d)','^Blue[\s-]?Feather','Blue Feather',''], ['^(BlueRay|SDM\d)','^BlueRay','BlueRay',''], @@ -14364,6 +14666,7 @@ sub set_disk_vendors { ['^CnMemory|Spaceloop','^CnMemory','CnMemory',''], ['^(Creative|(Nomad\s?)?MuVo)','^Creative','Creative',''], ['^CSD','^CSD','CSD',''], + ['^(Cusu|CV\d\d\d)','^Cusu','Cusu',''], ['^CYX\b','^CYX','CYX',''], ['^(Dane-?Elec|Z Mate)','^Dane-?Elec','DaneElec',''], ['^DATABAR','^DATABAR','DataBar',''], @@ -14473,6 +14776,7 @@ sub set_disk_vendors { # Wilk Elektronik SA, poland ['^((Wilk|WE)\s*)?(GOODRAM|GOODDRIVE|IR[\s-]?SSD|IRP|SSDPR|Iridium)','^GOODRAM','GOODRAM',''], ['^(Gost)','^Gost','Gost',''], + ['^(Graviton)','^Graviton','Graviton-Enclosure',''], ['^(GreatWall|GW\d{3})','^GreatWall','GreatWall',''], ['^(GreenHouse|GH\b)','^GreenHouse','GreenHouse',''], ['^Gritronix','^Gritronixx?','Gritronix',''], @@ -14497,6 +14801,7 @@ sub set_disk_vendors { ['^(HMZM)','^HMZM','HMZM',''], ['^Hoodisk','^Hoodisk','Hoodisk',''], ['^(HRUIYL)','^HRUIYL','HRUIYL',''], + ['^(HUADISK|HY)','^HUADISK','HUADISK',''], ['^(HUAWEI|HWE)','^HUAWEI','Huawei',''], ['^Hypertec','^Hypertec','Hypertec',''], ['^HyperX','^HyperX','HyperX',''], @@ -14515,7 +14820,7 @@ sub set_disk_vendors { ['^(Infokit)','^Infokit','Infokit',''], # note: Initio default controller, means master/slave jumper is off/wrong, not a vendor ['^Inland','^Inland','Inland',''], - ['^(InnoDisk|DEM\d|Innolite|SATA\s?Slim|DRPS)','^InnoDisk( Corp.)?','InnoDisk',''], + ['^(InnoDisk|DEM\d|EverGreen|Innolite|SATA\s?Slim|DRPS)','^InnoDisk( Corp.)?','InnoDisk',''], ['(Innostor|1f75)','(Innostor|1f75)','Innostor',''], ['(^Innovation|Innovation\s?IT)','Innovation(\s*IT)?','Innovation IT',''], ['^Innovera','^Innovera','Innovera',''], @@ -14547,7 +14852,7 @@ sub set_disk_vendors { ['(Kaizen|KZ\d\d)','Kaizen','Kaizen',''], ['^Kazuk','^Kazuk','Kazuk',''], ['(\bKDI\b|^OM3P)','\bKDI\b','KDI',''], - ['^KEEPDATA','^KEEPDATA','KeepData',''], + ['^(KEEPDATA|KD)','^KEEPDATA','KeepData',''], ['^KLLISRE','^KLLISRE','KLLISRE',''], ['^KimMIDI','^KimMIDI','KimMIDI',''], ['^Kimtigo','^Kimtigo','Kimtigo',''], @@ -14558,6 +14863,7 @@ sub set_disk_vendors { ['(KingDian|^NGF|S(280|400))','KingDian','KingDian',''], ['^(Kingfast|TYFS|2710)','^Kingfast','Kingfast',''], ['^KingMAX','^KingMAX','KingMAX',''], + ['^(KingPrice|KP)','^KingPrice','KingPrice',''], ['^Kingrich','^Kingrich','Kingrich',''], ['^Kingsand','^Kingsand','Kingsand',''], ['KING\s?SHA\s?RE','KING\s?SHA\s?RE','KingShare',''], @@ -14573,10 +14879,12 @@ sub set_disk_vendors { ['^(KNUP|KP\b)','^KNUP','KNUP',''], ['^(Kodak|Memory\s?Saver)','^Kodak','Kodak',''], ['^(KOOTION|X12)','^KOOTION','KOOTION',''], + ['^(Kowin|KW)','^Kowin','Kowin',''], ['^(KUAIKAI|MSAM)','^KUAIKAI','KuaKai',''], ['(KUIJIA|DAHUA)','^KUIJIA','KUIJIA',''], ['^KUNUP','^KUNUP','KUNUP',''], ['^KUU','^KUU\b','KUU',''], # KUU-128GB + ['^(Kioxia|KYO)','^Kioxia','Kioxia',''], ['^(Lacie|P92|itsaKey|iamaKey)','^Lacie','LaCie',''], ['^LANBO','^LANBO','LANBO',''], ['^LankXin','^LankXin','LankXin',''], @@ -14616,6 +14924,7 @@ sub set_disk_vendors { ['^MARVELL','^MARVELL','Marvell',''], ['^Maxsun','^Maxsun','Maxsun',''], ['^(McQuest)','^McQuest([\s-]?Digital)?','McQuest Digital',''], + ['^(MCTECH)','^MCTECH','MCTECH',''], ['^MDT\b','^MDT','MDT (rebuilt WD/Seagate)',''], # mdt rebuilds wd/seagate hdd # MD1TBLSSHD, careful with this MD starter!! ['^MD[1-9]','^Max\s*Digital','MaxDigital',''], @@ -14624,6 +14933,7 @@ sub set_disk_vendors { ['^(MEDIAMAX|WL\d{2})','^MEDIAMAX','MediaMax',''], ['^(Memorex|TravelDrive|TD\s?Classic)','^Memorex','Memorex',''], ['^Mengmi','^Mengmi','Mengmi',''], + ['^MLD','^MLD','MLD',''], ['^MGTEC','^MGTEC','MGTEC',''], ['^MicroFrom','^MicroFrom','MicroFrom',''], ['^(MILLENNIUM[\s-]?TECHNOLOGY|MIL\d\d)','^MILLENNIUM[\s-]?TECHNOLOGY','Millenium Technology',''], @@ -14672,6 +14982,7 @@ sub set_disk_vendors { ['(Origin|Inception|^TLC\d)','^Origin','Origin',''], ['^Ortial','^Ortial','Ortial',''], ['^OSC','^OSC\b','OSC',''], + ['^OV','^OV','OV',''], ['^(Ovation)','^Ovation','Ovation',''], ['^oyunkey','^oyunkey','Oyunkey',''], ['^PALIT','PALIT','Palit',''], # ssd @@ -14682,7 +14993,7 @@ sub set_disk_vendors { ['^PERC\b','','Dell PowerEdge RAID Card',''], # ssd ['(\bPhilips)','\bPhilips','Philips',''], ['(PHISON[\s-]?|ESR\d|PS[5E]|311CD|\bSSG\d\d)','PHISON[\s-]?','Phison',''],# E12-256G-PHISON-SSD-B3-BB1 - ['^(Pichau[\s-]?Gaming|PG\d{2})','^Pichau[\s-]?Gaming','Pichau Gaming',''], + ['^(Pichau|PG\d{2}|PCH[-s_-])','^Pichau[\s-]?(Gaming)?','Pichau',''], ['^Pioneer','Pioneer','Pioneer',''], ['^Platinet','Platinet','Platinet',''], ['^(PLEXTOR|PX-)','^PLEXTOR','Plextor',''], @@ -14751,8 +15062,9 @@ sub set_disk_vendors { ['^(SMART( Storage Systems)?|TX)','^(SMART( Storage Systems)?)','Smart Storage Systems',''], ['^Sobetter','^Sobetter','Sobetter',''], ['^Solidata','^Solidata','Solidata',''], - ['^(SOLIDIGM|SSDPFK)','^SOLIDIGM\b','solidgm',''], + ['^(SOLIDIGM|SSDPFK|P41PL)','^SOLIDIGM\b','Solidgm',''], ['^(Sony|IM9|Microvalut|S[FR]-)','^Sony','Sony',''], + ['^Speed[\s_-]?Star','^Speed[\s_-]?Star','Speed Star',''], # Note: SSC can be prefix for several companies ['^SSK\b','^SSK','SSK',''], ['^(SSSTC|CL1-)','^SSSTC','SSSTC',''], @@ -14781,6 +15093,7 @@ sub set_disk_vendors { ['^(TDK|TF[1-9]\d|LoR)','^TDK','TDK',''], ['(^TEAC|\bUF00)','^TEAC','TEAC',''], ['^(TEAM|T[\s-]?Create|CX[12]\b|L\d\s?Lite|T\d{3,}[A-Z]|TM\d|(Dark\s?)?L3\b|T[\s-]?Force)','^TEAM(\s*Group)?','TeamGroup',''], + ['^(Techbyte|TEC[\s_-])','^Techbyte','Techbyte',''], ['^(Teclast|CoolFlash)','^Teclast','Teclast',''], ['^(tecmiyo)','^tecmiyo','TECMIYO',''], ['^Teelkoou','^Teelkoou','Teelkoou',''], @@ -14797,11 +15110,12 @@ sub set_disk_vendors { ['^TopSunligt','^TopSunligt','TopSunligt',''], # is this a typo? hard to know ['^TopSunlight','^TopSunlight','TopSunlight',''], ['^TOROSUS','^TOROSUS','Torosus',''], - ['(Transcend|^((SSD\s|F)?TS|ESD\d|EZEX|USDU)|1307|JetDrive|JetFlash)','\b(Transcend|1307)\b','Transcend',''], + ['(Transcend|^((ATA\s|SSD\s|F)?TS|ESD\d|EZEX|USDU)|1307|JetDrive|JetFlash)','\b(Transcend|1307)\b','Transcend',''], ['^(TrekStor|DS (maxi|pocket)|DataStation)','^TrekStor','TrekStor',''], ['^Turbox','^Turbox','Turbox',''], ['^TurXun','^TurXun','TurXun',''], ['^(TwinMOS|TW\d)','^TwinMOS','TwinMOS',''], + ['^(TWSC|TSC\d)','^TWSC','TWSC',''], # note: udisk means usb disk, it's not a vendor ID ['^UDinfo','^UDinfo','UDinfo',''], ['^UMAX','^UMAX','UMAX',''], @@ -14829,6 +15143,7 @@ sub set_disk_vendors { ['^(Visipro|SDVP)','^Visipro','Visipro',''], ['^VISIONTEK','^VISIONTEK','VisionTek',''], ['^VMware','^VMware','VMware',''], + ['^(VSP)','^VSP[\s_-]?Tech(nology)?','VSP Technology',''], ['^(Vseky|Vaseky|V8\d{2})','^Vaseky','Vaseky',''], # ata-Vseky_V880_350G_ ['^(Walgreen|Infinitive)','^Walgreen','Walgreen',''], ['^Walram','^Walram','WALRAM',''], @@ -14840,7 +15155,7 @@ sub set_disk_vendors { ['^(wicgtyp|[MN][V]?900)','^wicgtyp','wicgtyp',''], ['^Wilk','^Wilk','Wilk',''], ['^(WinMemory|SW[GR]\d)','^WinMemory','WinMemory',''], - ['^(Winton|WT\d{2})','^Winton','Winton',''], + ['^(Winten|WT(\d{2}|M2))','^Winten','Winten',''], ['^(WISE)','^WISE','WISE',''], ['^WPC','^WPC','WPC',''], # WPC-240GB ['^(Wortmann(\sAG)?|Terra\s?US)','^Wortmann(\sAG)?','Wortmann AG',''], @@ -18448,7 +18763,7 @@ sub set_amd_data { 'years' => '2022+', }, {'arch' => 'RDNA-3', - 'ids' => '73f0|7480|7481|7483|7487|7489|748b|7499', + 'ids' => '73f0|7480|7481|7483|7487|7489|748b|7499|749f', 'code' => 'Navi-3x', 'process' => 'TSMC n6 (6nm)', 'years' => '2023+', @@ -18459,6 +18774,12 @@ sub set_amd_data { 'process' => 'TSMC n4 (4nm)', 'years' => '2023+', }, + {'arch' => 'RDNA-4', + 'ids' => '7550|7551|7590', + 'code' => 'Navi-4x', + 'process' => 'TSMC n4 (4nm)', + 'years' => '2025+', + }, {'arch' => 'CDNA-1', 'ids' => '7388|738c|738e', 'code' => 'Instinct-MI1xx', @@ -18472,7 +18793,7 @@ sub set_amd_data { 'years' => '2021-22+', }, {'arch' => 'CDNA-3', - 'ids' => '74a0|74a1|74a2|74a5|74a9|74b5|74bd', + 'ids' => '74a0|74a1|74a2|74a5|74a9|74b5|74b9|74bd', 'code' => 'Instinct-MI3xx', 'process' => 'TSMC n5 (5nm)', 'years' => '2023+', @@ -18576,8 +18897,9 @@ sub set_intel_data { 'years' => '2012-13', }, {'arch' => 'Gen-8', - 'ids' => '1602|1606|160a|160b|160d|160e|1612|1616|161a|161b|161d|161e|1622|' . - '1626|162a|162b|162d|162e|1632|1636|163a|163b|163d|163e|22b0|22b1|22b2|22b3', + 'ids' => '0d22|1602|1606|160a|160b|160d|160e|1612|1616|161a|161b|161d|161e|' . + '1622|1626|162a|162b|162d|162e|1632|1636|163a|163b|163d|163e|22b0|22b1|22b2|' . + '22b3', 'code' => '', 'process' => 'Intel 14nm', 'years' => '2014-15', @@ -18602,9 +18924,9 @@ sub set_intel_data { }, # gen10 was cancelled. {'arch' => 'Gen-11', - 'ids' => '0d16|0d26|0d36|4541|4551|4555|4557|4571|4e51|4e55|4e57|4e61|4e71|' . - '8a50|8a51|8a52|8a53|8a54|8a56|8a57|8a58|8a59|8a5a|8a5b|8a5c|8a5d|8a70|8a71|' . - '9840|9841', + 'ids' => '0d12|0d16|0d26|0d36|4541|4551|4555|4557|4571|4e51|4e55|4e57|4e61|' . + '4e71|8a50|8a51|8a52|8a53|8a54|8a56|8a57|8a58|8a59|8a5a|8a5b|8a5c|8a5d|8a70|' . + '8a71|9840|9841', 'code' => '', 'process' => 'Intel 10nm', 'years' => '2019-21', @@ -18652,21 +18974,28 @@ sub set_intel_data { 'years' => '2023+', }, {'arch' => 'Xe2', - 'ids' => 'e202|e20b|e20c|e20d|e210|e212|e215|e216', + 'ids' => 'e202|e20b|e20c|e20d|e210|e211|e212|e215|e216', 'code' => '', 'process' => 'TSMC n4 (4nm)', 'years' => '2024+', }, {'arch' => 'Xe2', - 'ids' => '6420|64a0|64b0|b080|b081|b082|b083|b08f|b090|b0a0|b0b0', + 'ids' => '6420|64a0|64b0', 'code' => '', 'process' => 'TSMC n3 (3nm)', 'years' => '2024+', }, - {'arch' => 'Xe-LPG', + {'arch' => 'Xe2-LPG', 'ids' => '7d41|7d51|7d67|7dd1|b640', 'code' => '', - 'process' => 'TSMC 3nm?', + 'process' => 'TSMC n3 (3nm)', + 'years' => '2025+', + }, + {'arch' => 'Xe3', + 'ids' => 'b080|b081|b082|b083|b084|b085|b086|b087|b08f|b090|b0a0|b0b0|fd80|' . + 'fd81', + 'code' => '', + 'process' => 'TSMC 18A', 'years' => '2025+', }, ]; @@ -18900,7 +19229,7 @@ sub set_nv_data { 'legacy' => 0, 'process' => 'TSMC 28nm', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => main::message('nv-current-eol',$date,'2026-12-xx'), 'xorg' => '', 'years' => '2014-2019', @@ -18917,7 +19246,7 @@ sub set_nv_data { 'legacy' => 0, 'process' => 'TSMC 16nm', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => main::message('nv-current-eol',$date,'2026-12-xx'), 'xorg' => '', 'years' => '2016-2021', @@ -18929,25 +19258,25 @@ sub set_nv_data { 'legacy' => 0, 'process' => 'TSMC 12nm', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => main::message('nv-current-eol',$date,'2026-12-xx'), 'xorg' => '', 'years' => '2017-2020', }, {'arch' => 'Turing', 'ids' => '1e02|1e04|1e07|1e09|1e30|1e36|1e78|1e81|1e82|1e84|1e87|1e89|1e90|' . - '1e91|1e93|1eb0|1eb1|1eb5|1eb6|1ec2|1ec7|1ed0|1ed1|1ed3|1ef5|1f02|1f03|1f06|' . - '1f07|1f08|1f0a|1f0b|1f10|1f11|1f12|1f14|1f15|1f36|1f42|1f47|1f50|1f51|1f54|' . - '1f55|1f76|1f82|1f83|1f91|1f95|1f96|1f97|1f98|1f99|1f9c|1f9d|1f9f|1fa0|1fb0|' . - '1fb1|1fb2|1fb6|1fb7|1fb8|1fb9|1fba|1fbb|1fbc|1fdd|1ff0|1ff2|1ff9|2182|2184|' . - '2187|2188|2189|2191|2192|21c4|21d1|25a6|25a7|25a9|25aa|25ad|25ed|28b0|28b8|' . - '28f8', + '1e91|1e93|1eb0|1eb1|1eb5|1eb6|1eb8|1ec2|1ec7|1ed0|1ed1|1ed3|1ef5|1f02|1f03|' . + '1f06|1f07|1f08|1f0a|1f0b|1f10|1f11|1f12|1f14|1f15|1f36|1f42|1f47|1f50|1f51|' . + '1f54|1f55|1f76|1f82|1f83|1f91|1f95|1f96|1f97|1f98|1f99|1f9c|1f9d|1f9f|1fa0|' . + '1fb0|1fb1|1fb2|1fb6|1fb7|1fb8|1fb9|1fba|1fbb|1fbc|1fdd|1ff0|1ff2|1ff9|2182|' . + '2184|2187|2188|2189|2191|2192|21c4|21d1|25a6|25a7|25a9|25aa|25ad|25ed|28b0|' . + '28b8|28f8', 'code' => 'TUxxx', 'kernel' => '', 'legacy' => 0, 'process' => 'TSMC 12nm FF', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => main::message('nv-current-eol',$date,'2026-12-xx'), 'xorg' => '', 'years' => '2018-2022', @@ -18959,13 +19288,13 @@ sub set_nv_data { '24b1|24b6|24b7|24b8|24b9|24ba|24bb|24c7|24c9|24dc|24dd|24e0|24fa|2503|2504|' . '2507|2508|2520|2521|2523|2531|2544|2560|2563|2571|2582|2584|25a0|25a2|25a5|' . '25ab|25ac|25b0|25b2|25b6|25b8|25b9|25ba|25bb|25bc|25bd|25e0|25e2|25e5|25ec|' . - '25f9|25fa|25fb|2822|2838|28a3', + '25f9|25fa|25fb|2822|2838|28a3|28e3', 'code' => 'GAxxx', 'kernel' => '', 'legacy' => 0, 'process' => 'TSMC n7 (7nm)', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => main::message('nv-current-eol',$date,'2026-12-xx'), 'xorg' => '', 'years' => '2020-2023', @@ -18977,7 +19306,7 @@ sub set_nv_data { 'legacy' => 0, 'process' => 'TSMC n4 (5nm)', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => $status_current, 'xorg' => '', 'years' => '2022+', @@ -18986,25 +19315,27 @@ sub set_nv_data { 'ids' => '2684|2685|2689|26b1|26b2|26b3|26b5|26b9|26ba|2702|2704|2705|2709|' . '2717|2730|2757|2770|2782|2783|2786|2788|27a0|27b0|27b1|27b2|27b6|27b8|27ba|' . '27bb|27e0|27fb|2803|2805|2808|2820|2860|2882|28a0|28a1|28b0|28b9|28ba|28bb|' . - '28e0|28e1|2b85|2b87|2c02', + '28e0|28e1|2b85|2b87|2b8c|2c02|2c05|2c18|2c19|2c58|2c59|2d04|2d05|2d18|2d19|' . + '2d58|2d59|2d83|2d98|2dd8|2f04|2f18|2f58', 'code' => 'AD1xx', 'kernel' => '', 'legacy' => 0, 'process' => 'TSMC n4 (5nm)', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => $status_current, 'xorg' => '', 'years' => '2022+', }, {'arch' => 'Blackwell', - 'ids' => '2901', + 'ids' => '2901|2941|2bb1|2bb3|2bb4|2bb5|2c31|2c33|2c34|2c38|2c39|2d30|2d39|' . + '2db8|2db9|2f38', 'code' => 'GB2xx', 'kernel' => '', 'legacy' => 0, 'process' => 'TSMC 4np (5nm)', 'release' => '', - 'series' => '550-570.xx+', + 'series' => '550-580.xx+', 'status' => $status_current, 'xorg' => '', 'years' => '2024+', @@ -20150,7 +20481,7 @@ sub machine_output { } $bios_date ||= 'N/A'; if ($extra > 1 && $data->{'bios_romsize'}){ - $bios_romsize = $data->{'bios_romsize'}; + $bios_romsize = main::get_size($data->{'bios_romsize'},'string'); } $rows->[$j]{main::key($num++,1,1,'Mobo')} = $mobo_vendor; $rows->[$j]{main::key($num++,1,2,'model')} = $mobo_model; @@ -20535,7 +20866,12 @@ sub machine_data_dmi { elsif ($value[0] eq 'Version'){ $data->{'bios_version'} = main::clean_dmi($value[1]) } elsif ($value[0] eq 'ROM Size'){ - $data->{'bios_romsize'} = main::clean_dmi($value[1]) } + $data->{'bios_romsize'} = main::clean_dmi($value[1]); + # Translate to KiB + if ($data->{'bios_romsize'} =~ /(\d+\s*[kKMG])i?B?$/){ + $data->{'bios_romsize'} = main::translate_size($1); + } + } elsif ($value[0] eq 'BIOS Revision'){ $data->{'bios_rev'} = main::clean_dmi($value[1]) } } @@ -25590,6 +25926,7 @@ sub set_ram_vendors { ['^(AX[\d]{4}|Axiom)','Axiom','Axiom',''], ['^(BD\d|Black[s-]?Diamond)','Black[s-]?Diamond','Black Diamond',''], ['^(-BN$|Brute[s-]?Networks)','Brute[s-]?Networks','Brute Networks',''], + ['^(CXMT|ChangXin)','ChangXin([s-]?Memory[s-]?Technologies)?','CXMT',''], ['^(CM|Corsair)','Corsair','Corsair',''], ['^(CT\d|BL|Crucial)','Crucial','Crucial',''], ['^(CY|Cypress)','Cypress','Cypress',''], @@ -30073,7 +30410,7 @@ sub set_dboot_data { { package DesktopData; my ($b_dbg_de,$desktop_session,$gdmsession,$kde_full_session, -$kde_session_version,$tk_test,$xdg_desktop,@data,%xprop); +$kde_session_version,$tk_test,$windowmanager,$xdg_desktop,@data,%xprop); my $desktop = []; sub get { @@ -30287,11 +30624,13 @@ sub de_kde_tde_data { $kded = $program; $kded_name = 'kded'; } - # note: if TDM is used to start kde, can pass ps tde test + # note: if TDM is used to start kde, can pass ps tde test. To avoid this, + # in some cases WINDOWMANAGER is set with starttde|startkde|startplasma if ($desktop_session eq 'trinity' || $xdg_desktop eq 'trinity' || - (!$desktop_session && !$xdg_desktop && @{$ps_data{'de-ps-detect'}} && - (grep {/^tde/} @{$ps_data{'de-ps-detect'}}))){ - # 14.2 moved kdesktop to location not in PATH in some distros, so either of these will fail + $windowmanager =~ /starttde/ || + (!$desktop_session && !$xdg_desktop && $windowmanager !~ /start(kde|plasma)/ && + @{$ps_data{'de-ps-detect'}} && (grep {/^tde/} @{$ps_data{'de-ps-detect'}}))){ + # 14.2 moved kdesktop to location not in PATH in some distros, so eithe# start of these will fail if (($program = main::check_program('kdesktop')) || ($program = main::check_program('twin'))){ ($desktop->[0],$desktop->[1],$v_data) = ProgramData::full('kdesktop-trinity',$program,0,'raw'); @@ -30308,8 +30647,10 @@ sub de_kde_tde_data { # KDE_SESSION_VERSION is the integer version of the desktop # NOTE: as of plasma 5, the tool: about-distro MAY be available, that will show # actual desktop data, so once that's in debian/ubuntu, if it gets in, add that test + # corner case root start, all env variables empty except WINDOWMANAGER elsif ($desktop_session eq 'kde-plasma' || $desktop_session eq 'plasma' || - $xdg_desktop eq 'kde' || $kde_session_version){ + $xdg_desktop eq 'kde' || $kde_session_version || + ($windowmanager && $windowmanager =~ /start(kde|plasma)/)){ # KDE <= 4 if ($kde_session_version && $kde_session_version <= 4){ if ($program = main::check_program($kded_name)){ @@ -30839,6 +31180,7 @@ sub set_env_data { $kde_session_version = ($ENV{'KDE_SESSION_VERSION'}) ? $ENV{'KDE_SESSION_VERSION'} : ''; # for fallback to fallback protections re false gnome id $gdmsession = ($ENV{'GDMSESSION'}) ? clean_env($ENV{'GDMSESSION'}) : ''; + $windowmanager = ($ENV{'WINDOWMANAGER'}) ? clean_env($ENV{'WINDOWMANAGER'}) : ''; main::feature_debugger('desktop-scalars', ['$desktop_session: ' . $desktop_session, '$xdg_desktop: ' . $xdg_desktop, @@ -33008,6 +33350,7 @@ sub debian_id { '12' => 'bookworm', '13' => 'trixie', '14' => 'forky', + '15' => 'duke', ); } else { @@ -33020,7 +33363,7 @@ sub debian_id { '5' => 'daedalus', # bookworm '6' => 'excalibur',# trixie '7' => 'freia', # forky - # '' => 'ceres/daedalus', # sid/unstable + # '' => 'ceres', # sid/unstable ); } # debian often numeric, devuan usually not @@ -33063,10 +33406,12 @@ sub ubuntu_id { my ($id) = (''); # xx.04, xx.10 my %codenames = ( - # '??' => '26.04', - # '??' => '25.10', - # '??' => '25.04', - # '??' => '24.10', + # '??' => '27.04', + # '??' => '26.10', + # '??' => '26.04 LTS', + 'questing' => '25.10', + 'plucky' => '25.04', + 'oracular' => '24.10', 'noble' => '24.04 LTS', 'mantic' => '23.10', 'lunar' => '23.04', @@ -15,7 +15,7 @@ .\" with this program; if not, write to the Free Software Foundation, Inc., .\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. .\" -.TH INXI 1 "2025\-04\-06" "inxi 3.3.38" "inxi manual" +.TH INXI 1 "2025\-08\-29" "inxi 3.3.39" "inxi manual" .SH NAME inxi \- Command line system information tool for console and IRC @@ -182,12 +182,23 @@ available capacity of the battery is \fB22.2 Wh\fR. \fBcharge: 20.1 Wh (95.4%)\fR +If charge percent > 100, adds \fBnote: check\fR. The causes from that can range +from driver bugs, hardware bugs, odd behaviors, so there's no way to know why. + The \fBcondition:\fR item shows the remaining available capacity / original design capacity, and then this figure as a percentage of original capacity available in the battery. \fBcondition: 22.2/36.4 Wh (61%)\fR +Corner cases of failing battery show < 1 Wh and percent values for charge, +capacity, and condition, and an alert. + +\fBcondition: 0.01/62.6 Wh (0.02%) alert: bad battery?\fR + +If health item is available and if it is not 'good', shows \fBhealth:\fR value. +Always shows with \fB\-x\fR if present. + With \fB\-x\fR, or if voltage difference is critical, \fBvolts:\fR item shows the current voltage, and the \fBmin:\fR voltage. Note that if the current is below the minimum listed the battery is essentially dead and will not charge. @@ -297,7 +308,7 @@ unless you use those arguments in the command, e.g.: \fBinxi \-ermxx\fR The basic CPU line is expanded to full CPU data (\fB\-C\fR); the basic disk information line is expanded to full drive information (\fB\-D\fR) plus primary -system partion data (\fB\-P\fR), along with adding, if found, RAID (\fB\-R\fR) +system partition data (\fB\-P\fR), along with adding, if found, RAID (\fB\-R\fR) and Logical (\fB\-L\fR) items; the Network line (\fB\-N\fR) is expanded to advanced network (\fB\-n\fR). @@ -1330,6 +1341,11 @@ vendor [product] information. .TP .B \-x \-B\fR +\- Adds battery \fBhealth:\fR (uncommon. If other than 'good', always shows for +\fB\-B\fR. + +\- Adds battery temperature, in C (uncommon). + \- Adds vendor/model, battery status (if battery present). \- Adds attached battery powered peripherals (\fBDevice\-[number]:\fR) if @@ -1351,7 +1367,8 @@ data, which tends to be better, so in general don't do that. \- Adds \fBboost: [enabled|disabled]\fR if detected, aka \fBturbo\fR. Not all CPUs have this feature. -\- Adds CPU Flags (short list). Use \fB\-f\fR to see full flag/feature list. +\- Adds CPU \fBFlags\-basic:\fR (short list). Use \fB\-f\fR to see full +flag/feature list. \- Adds CPU microarchitecture + revision (e.g. Sandy Bridge, K8, ARMv8, P6, etc.). Only shows data if detected. Newer microarchitectures will have to be @@ -1591,10 +1608,17 @@ the sound API/server. .TP .B \-xx \-B\fR -\- Adds current power use, in watts. +\- Adds current power use, in watts (if available). \- Adds serial number. +\- Adds a \fBcharging:\fR container for all charging specific information. + +\- Adds charge cycles (NOTE: there appears to be a problem with the Linux kernel +obtaining the cycle count, so this often shows \fB0\fR. There's nothing that can +be done about this glitch, the data is simply not available as of +2018\-04\-03), Since 0 isn't a real value, shows N/A if not found or 0. + .TP .B \-xx \-D\fR \- Adds HDD/SSD drive serial number. @@ -1864,11 +1888,15 @@ to observation time), if available. .TP .B \-xxx \-B\fR -\- Adds battery chemistry (e.g. \fBLi\-ion\fR), cycles (NOTE: there appears to -be a problem with the Linux kernel obtaining the cycle count, so this almost -always shows \fB0\fR. There's nothing that can be done about this glitch, the -data is simply not available as of 2018\-04\-03), location (only available from -\fBdmidecode\fR derived output). +\- Adds battery temperature (uncommon). + +\- Adds battery build date (uncommon). + +\- Adds battery chemistry (e.g. \fBLi\-ion\fR)). + +\- Adds location (only available from \fBdmidecode\fR derived output. + +\- Adds battery charging type (uncommon). \- Adds attached device \fBrechargeable: [yes|no]\fR information. diff --git a/inxi.changelog b/inxi.changelog index cd7444b..23fea32 100644 --- a/inxi.changelog +++ b/inxi.changelog @@ -1,4 +1,263 @@ ================================================================================ +Version: 3.3.39 +Patch: 00 +Date: 2025-08-29 +-------------------------------------------------------------------------------- +RELEASE NOTES: +-------------------------------------------------------------------------------- + +Refactor and updated of the Battery item, that was sorely in need of tightening +and better testing and robustness. Now all math occurs either in data sources, +to set to consistent units, or in the processing function. Also long overdue +fixes for Chinese CPU makers Loongson and XhaoXin. Plus other general fixes and +updates. + +Note the new section UPDATES:, which is for routnely updated data and matching +tables. These were previously tossed into ENHANCEMENTS:, but that never seemed +quite right since they aren't really new features or anything, just ongoing +updates. So now they go in their own section. This will also make ite easier to +see what's actually new vs what is just updated. + +-------------------------------------------------------------------------------- +SPECIAL THANKS: + +1. MrMazda, for plugging away at thankless testing and tasks all these years, +keeping the desktop and graphics parts honest. + +2. matt-2025, codeberg issue #340, for giving enough data and feedback to expose +that the Battery item needed a significant refactor to improve reliability and +accuracy. + +3. iv-m, codeberg issue #342, for supplying data required to properly support +Loongson CPUs. I've waited a long time to find such data, so it was great to +finally get the real debugger data required. + +4. Ricky-Tigg: for finding some nice subtle things that needed fixing. + +-------------------------------------------------------------------------------- +KNOWN ISSUES: + +1a. CPU: cpu_arch is making some guesses about family of zen 7, but no data is +available. The guess is that amd is going to give 7 a new family ID. 6 did not +get a new family ID afterall, so that's back with 5 now. + +1b. CPU: ARCH: I'm finding it, as with GPU, increasingly difficult and tedious +to dig up Intel data. I may give up trying at some point because it's getting +too convoluted and boring to track. + +2. GRAPHICS: GPU: I'm finding it increasingly difficult to track gpu product IDs +and their relative architecture data. If you want this to be more accurate and +reliable, it's probably time for someone other than me to step up and start +tracking this data. Intel in particular is extremmely difficult to track since +they blend marketing and engineering so badly, both in GPUs and CPUs. + +3. BATTERY: Sometimes charge_full is less than charge_now, or energy_full < +energy_now. This is a bug with the battery, since the _full is supposed to show +current max capacity when full, which is not the same as the original design +capacity, which is almost always more. Since it's not possible to know which +value is wrong, inxi just shows them as is, which leads to sometimes charge: +item showing a value > 100, like (110%)> There are too many possible reasons +to try to figure it out or guess. It does show note: check now though. + +One system that did this stopped immediately whenn I unplugged it, and when I +plugged it back in, it showed the correct 100%. So this is something that is +not updating, or is getting the wrong data at some times. + +-------------------------------------------------------------------------------- +BUGS: + +1a. BATTERY: in case /sys power file not readable, tested for is root, not is not +root. That means the message would not have shown for non root users, who are +who needed to see it. + +1b. BATTERY: See Fixes 4. The bug was dividing by zero, but that was just a +symptom of the core issue, which required fixing the entire battery item. inxi +had prematurely switched 0.01 Wh to 0 with sprintf, which then created the +divide by 0 condition, and also some other oddities. + +2. CPU: incorrect use of get_defined in one test led to useless result. + +-------------------------------------------------------------------------------- +FIXES: + +1. Downloader: Tiny::HTTP is supposed to default to no check ssl, but I found a +case where it has to be set explicitlly to not check or it does. + +2a. CPU: cpu_arch() had the wrong family ID for amd zen 5 cpus, it had 20 instead +of 1A, I forgot that was hex number. Also fixed comments there, and made more +clear how the hyper confusing amd cpu family matches to what you see in cpuinfo +and other places. + +2b. CPU: cpu_arch: corrected some Loongson Arch names; fixed glitch that made +features use -f message not appear for -Cx with Loongson CPUs. Overall added +loongsn to %risc ID method which solved most of the Loongson issues. + +3. DesktopData: Extreme corner case, it looks like OpenSuse now correctly does +not set the environmental variables used for desktop detection, which then broke +kde/tde detections. Note this condition only happens when the session is started +as root, AND when kde was started by tdelauncher. I believe the number of people +in the world this might affect numbers around 1, maybe 2 or 3 on the outside, +and only on new OpenSuse. + +When started as non root, all the environmental variables are set as expected. +It is however faintly possible that kde detection might also have failed since +that required postiive matches to the environmental variables, but it might get +caught later on in a fallback test, I don't know. + +3. GRAPHICS: GPU: I changed some Intel GPU ids, with more recent data, but +tracking this stuff is getting tiresome, so if there are errors, do the research +and help, don't complain. + +4. BATTERY: Thanks codeberg issue #340 matt-2025 for noting a crash when his +values were 0 for energy_full. Due to premature rounding of 0.01 and connversion +to string with sprintf, 0.0 was being treated as a string and not 0. + +Also, if energy_full is less than 1, will show the actual energy and of_orig +values, using sprintf('%.1g', which trims to first signficant number in decimal. + +Battery: + ID-1: BAT0 charge: 0.01 Wh (100%) condition: 0.01/62.6 Wh (0.02%) + alert: bad battery? volts: 11.7 min: 10.8 model: SANYO 45N1172 type: Li-ion + serial: 3058 status: not charging + +Adds an alert: item if percent of original capacity is < 5%, or if energy_full, +the current maximum real capacity, is less than 1 Wh. + +This is a corner case for sure, first time I'd ever seen a battery this degraded +but still showing values for Wh available. + +5. MACHINE: dmidecode sourced EEPROM size was in MB instead of having been +internally translated to KiB integers then correctly shown as MiB for output. + +-------------------------------------------------------------------------------- +UPDATES: + +1a. TOOLS: tools/cpu_arch.pl: Expanded Loongson section significantly. + +1b. TOOLS: tools/cpu_arch.pl: Added separate ZhaoXin section, before it was with +Centaur, which was useless since the two have developed separately. This allows +for detecting both types more accurately. + +1c: TOOLS: tools/gpu_raw.pl, tools/gpu_ids.pl: added nvidia 580. + +2. RAM: tools/ram_vendors.pl > set_ram_vendors(): added CXMT ChangXin Memory +Technologie ID. + +3. GRAPHICS: GPU: Added new AMD, Intel, Nvidia gpu IDs. + +4a. CPU: cp_cpu_arch(): New AMD, Intel cpu IDs, a few changed or fixed with new +data. + +4b. CPU: cp_cpu_arch(): Big expansion of ZhaoXin CPU arch data, and added +explicit detection for zhaozin $cpu->{type}, before fell into centaur. + +4c. CPU: cp_cpu_arch(): Big expansion of Loongson CPU arch data, and added +explicit detection for loongson $cpu->{type} and $risc{'loongson'} %risc type., + +5. SYSTEM: DistroData: updated ubuntu_id() up to 25-10. Those had fallen behind; +updated debian_id() to 15. + +6. DRIVES: set_disk_vendors(): More vendors, ID matches. Less than usual, but +it's getting more likely inxi has it handled. + +-------------------------------------------------------------------------------- +ENHANCEMENTS: + +1. BATTERY: Added new fields/values: +* -B - added note: check if capacity > 100%, causes unknown and inconsistent. +* -x - health. String report. Always show if health not 'good'. Not common. +* -x - battery temperature, in C. Not common. +* -x - append capacity_level string if capacity is present. [not used due to + weird string value critical on a near fully charged battery] +* -xxx - manufacter date made:, Doesn't show if not available since not common. +* -xxx - add temp_min/temp_max under temp if available +* -xxx - add charge_type if found +* -a - add charge_control_start_threshold/charge_control_end_threshold + charge_behavior if found. +* -a - add available charge_types list, if found. This will include the active + one. + +Changed: +* -xx - creates new 'charging:' block. +* -xxx cycles to -xx cycles. And show N/A if not found, I think it's good to +know that info is not available. + +-------------------------------------------------------------------------------- +CHANGES: + +1. BATTERY: Switched voltage decimals to 2 places, and also added 0 to all +resultss to both convert back to numeric, and to get rid of extra 0s at end of +the decimal. Some data sources already had 2 decimal voltages, like OpenBSD, so +this just makes them all have them. Also slightly reordered output fields to +make them fit into somewhat logical sub catetories. Put main battery status +into a 'report' container. + +2. GRAPHICS: GPU: Changed RDNA-4 release data and process node size. Data for +this stuff is getting harder to find that is solid. + +3. CPU: For -Cx, shows Flags-basic: instead of Flags if -f is not used. It has +never been intuitive that there might be more flags, you'd need to be into it +to get that. + +-------------------------------------------------------------------------------- +DOCUMENTATION: + +1a. inxi.changelog/pinxi.changelog: fixed 3.3.38 date on bottom, ooops. + +1b. inxi.changelog/pinxi.changelog: Added UPDATES: section, this holds updates +to existing matching data tables and manually generated matching rules, like gpu +ids, cpu microarch data, disk vendors, ram data, etc. inxi has an unfortunately +large number of such manually generated rules, or tool generated, and updates to +that have never really been enhancements to inxi, it's just an update to +somoething that already exists but is missing matching sets. + +2a. MAN page: fixed typo. + +2b. MAN pages: Added info about bad battery data for -B Battery. + +3. MAN/OPTIONS: Updated for new battery features and changes. + +4a. DOCS: inxi-cpu.txt: updated the amd cpu family id list, that was not clear, +but is hopefully more clear now. + +4b. DOCS: inxi-cpu.txt; inxi-values.txt: Added loongson docs, and loongson %risc +values. + +4c. DOCS: inxi-cpu.txt: Added zhaoxin docs. + +4d: DOCS: inxi-battery.txt: upgraded, added more sections, /sys data types. + +-------------------------------------------------------------------------------- +CODE: + +1. BATTERY: refactored significantly. Moved all math out of output, remooved all +sprintf %.1f in early stages, and moved all advanced processing for all data +source types to one function, process_battery_data(), which also got rid of +redundant logic, and removed sources of error. It was very clear that Battery +item was one of the Bash > Perl literal translation items I did early on, and +quickly. + +Also got rid of random ways of testing for null data, and switched to using +undefined as false, and left all numeric values as number types until the very +last processing stage, where they are converted with sprintf for print output. + +Since 0 is now 0 and not the string '0.0', true/false tests work as expected, +with 0 values triggering the use of the smaller > 0, < 1 decimal numbers and +showing the alert message as well. + +2a. MAIN: clean_dmi: failed to filter for SerialNumber as unset value, but did +oddly have SerNum. Made all default unset strings more robust. + +2b: MAIN: Added $risc{'id'} = 'loongson'. Turns out since 5000, it's its own +ISA. Also added --risc [available risc types] in case that is easier to remember +for devs or me. + +2c. MAIN: clean_disk(): Added (name\s)?n\/a to cleaner. + +-------------------------------------------------------------------------------- +-- Harald Hope - Fri, 29 Aug 2025 15:37:40 -0700 + +================================================================================ Version: 3.3.38 Patch: 00 Date: 2025-04-06 @@ -53,9 +312,10 @@ been there. This made the 'driver:' for device always show N/A. Solution was to just use the other field name, since it's always been there as far as I can tell. -4. MAIN: set_display_size OpenBSD showed errors, because error suppression not -on for tput. Also is_jnt test passed for "" for some reason, resulting in more -errors. +4. MAIN: set_display_size OpenBSD showed errors, because error suppression not +on for tput. Also is_jnt test passed for "", resulting in more errors. Cause was +not first testing for 0 length, wnich made 0 occurances of tr/// result match 0 +length of string. 5. CPU: cpu_sysctl_data failed to test if $line[1] was set. This resulted in OpenBSD errors since the value was 'unknown', which had been stripped out by @@ -76,6 +336,11 @@ side, which uses pisi. 3. GRAPHICS: New gpu ids: amd, intel, nvidia. Added blackwell gpu ids. Added a missing kepler gpu product ID via manual method. +4. BATTERY: Prompted by codeberg issue #341 checked and found newer battery +power data in /sys/class/power_supply. + +alarm ([t minimum Ah level] + -------------------------------------------------------------------------------- CHANGES: @@ -100,7 +365,7 @@ OpenBSD error which I can't reproduce but a vm instance did since it was missing more data. -------------------------------------------------------------------------------- --- Harald Hope - Tue, 07 Jan 2025 11:34:53 -0800 +-- Harald Hope - Sat, 06 Apr 2025 11:34:53 -0800 ================================================================================ Version: 3.3.37 @@ -272,22 +537,22 @@ that information. If scaling != 1, also showed scaled dimensions. For scaled (wayland): res: - mode: 1680x1050 - scale: 125% (1.25) + mode: 1680x1050 + scale: 125% (1.25) to: 1344x840 hz: 60 For scaled (xrandr): res: - mode: 1680x1050 - scale: 125% (0.8) + mode: 1680x1050 + scale: 125% (0.8) to: 1344x840 hz: 60 For scaling == 1: res: - mode: 1680x1050 - scale: 100% (1) + mode: 1680x1050 + scale: 100% (1) hz: 60 If no scaling data found, or if less than -Gxxx: @@ -338,14 +603,14 @@ maintained it when I did the perl inxi rewrite. That would have been the time to change it, but I was busy with the rewrite and it didn't register enough. 2a. GRAPHICS: if -xxx and monitor scaling detectable shows if not scaling 1: - res: mode: widthxheight scale: 80% (0.8) to: widthxheight +res: mode: widthxheight scale: 80% (0.8) to: widthxheight If scaling 1, just shows: - res: mode: widthxheight scale: 100% (1) - +res: mode: widthxheight scale: 100% (1) + So far scaling can only be detected with xrandr, swaymsg, wayland-info, wlr-randr, and maybe weston-info. This translates the real terms used internally by x11 and wayland. - + This is a change from res: widthxheight. 2b. GRAPHICS: To show hz, now shows with -Gxx, not -Gxxx, it never made sense to @@ -2975,7 +3240,7 @@ PC-2700 which then allows for mapping. 9. RAM/PROCESSES/INFO/SHORT: Finally tracked down a long time oddity, where for example: - RAM: total: 31.28 GiB +RAM: total: 31.28 GiB does not match 32 GiB physical installed. This is because that is the total available after kernel and system reserved RAM is deducted, and in some cases, GPU allocated RAM. There are also corner cases where the listed amount can be @@ -2987,7 +3252,7 @@ man -m/--memory. Changed -m, -tm to show: System RAM: available: 31.28 GiB used 26.23 GiB (83.9%) - + and -I to show: Memory: available: 31.28 GiB used 26.23 GiB (83.9%) @@ -3257,10 +3522,10 @@ version_data() function, which loads all the data based on what is calling it. This helps consolidate the logic across usb data sources. 5a. GLOBAL: made functions/methods use same comment syntax for args: - args: 0:...; 1:... +args: 0:...; 1:... always starting with 0, to match array index. Same syntax for return array index values. In some cases simply note a variable is passed by ref: - args: $value passed by reference. +args: $value passed by reference. 5b. GLOBAL: made all sub/functions/methods follow the same spacing syntax. This seems to be a good compromise for space/readability. Note that adding in these @@ -3451,10 +3716,10 @@ pipewire: pw-cat pw-cli wpctl) [+pactl if pipewire-pulse and no pulseaudio pulse: pacat pactl pamix pamixer pavucontrol pulsemixer roar: roarcat roarctl sndiod: aucat midicat mixerctl sndioctl - + Note that inxi-perl/docs/inxi-audio.txt has lists of alternates or rejected helpers and tools, but we want to keep that output short and sane. - + 3c. AUDIO: For BSDs, if sndiod is detected, adds an API line for sndio. Note this may create 2 API lines for FreeBSD using OSS. @@ -3703,28 +3968,28 @@ combination that may be causing issues. 3. START: Removed this code block from set_konvi_data. I had left this in place for a release or two to make sure no need for it was found, but it will never be used since it never worked in the first place. - # my $config_cmd = ''; - # there's no current kde 5 konvi config tool that we're aware of. Correct if changes. - # This part may never have worked, but I don't have legacy data to determine. - # The idea was to get inxi.conf files from konvi data stores, but that was never right. - # if (main::check_program('kde4-config')){ - # $config_cmd = 'kde4-config --path data'; - # } - # kde5-coinfig never existed, was replaced by $XDG_DATA_HOME in KDE - # elsif (main::check_program('kde-config')){ - # $config_cmd = 'kde-config --path data'; - # } - # elsif (main::check_program('qtpaths')){ - # $config_cmd = 'qtpaths --paths GenericDataLocation'; - # } - # The section below is on request of Argonel from the Konversation developer team: - # it sources config files like $HOME/.kde/share/apps/konversation/scripts/inxi.conf - # if ($config_cmd){ - # my @data = main::grabber("$config_cmd 2>/dev/null",':'); - # Configs::set(\@data) if @data; - # main::log_data('dump',"kde config \@data",\@data) if $b_log; - # } - + # my $config_cmd = ''; + # there's no current kde 5 konvi config tool that we're aware of. Correct if changes. + # This part may never have worked, but I don't have legacy data to determine. + # The idea was to get inxi.conf files from konvi data stores, but that was never right. + # if (main::check_program('kde4-config')){ + # $config_cmd = 'kde4-config --path data'; + # } + # kde5-coinfig never existed, was replaced by $XDG_DATA_HOME in KDE + # elsif (main::check_program('kde-config')){ + # $config_cmd = 'kde-config --path data'; + # } + # elsif (main::check_program('qtpaths')){ + # $config_cmd = 'qtpaths --paths GenericDataLocation'; + # } + # The section below is on request of Argonel from the Konversation developer team: + # it sources config files like $HOME/.kde/share/apps/konversation/scripts/inxi.conf + # if ($config_cmd){ + # my @data = main::grabber("$config_cmd 2>/dev/null",':'); + # Configs::set(\@data) if @data; + # main::log_data('dump',"kde config \@data",\@data) if $b_log; + # } + 4. OPTIONS: in OptionsHandler::post_process(), reorganized the various run and exit triggers, help, configs, recommends, version, etc. All on top now. @@ -4066,7 +4331,7 @@ failure to understand something about the core tech. 2. Changed wrapping of values from 3 words or more to 3 or more words AND length > 24 characters. Saw example of: - .... used: 28.45 GiB +.... used: 28.45 GiB (4.5%) which isn't desirable. @@ -4663,14 +4928,14 @@ see it. # we want to handle ARM errors in main get if (!@$rows && !%risc){ - my $key = 'Message'; - my $type = 'pci-card-data'; - if ($pci_tool && $alerts{$pci_tool}->{'action'} eq 'permissions'){ - $type = 'pci-card-data-root'; - } - @$rows = ({ - main::key($num++,0,1,$key) => main::message($type,'') - }); + my $key = 'Message'; + my $type = 'pci-card-data'; + if ($pci_tool && $alerts{$pci_tool}->{'action'} eq 'permissions'){ + $type = 'pci-card-data-root'; + } + @$rows = ({ + main::key($num++,0,1,$key) => main::message($type,'') + }); } -------------------------------------------------------------------------------- @@ -4932,7 +5197,7 @@ FIXES: 1. Fixed some disk vendor detection rules. 2. Failing to return default target for systemd/systemctl when no: - /etc/systemd/system/default.target +/etc/systemd/system/default.target file exists. Corrected to use systemctl get-default as fallback if file doesn't exist. @@ -5883,21 +6148,21 @@ more than 1 place. Part of the ongoing process of avoiding extra hash and array copies globally. 2. Moved to consistent undef behaviors. - * For lists of variables use () to undefine, changed all of the the following: +* For lists of variables use () to undefine, changed all of the the following: 1. (@a,$b,$c,%d) = (undef,undef,undef,undef); 2. (@a,$b,$c,%d) = (undef); 3. (@a,$b,$c,%d) = undef; - to use: (@a,$b,$c,%d) = (); This undefines all the variables in the list. - Note that assigning undef to @a in the first example creates an array of 1 - key, with the value undef, and (@a,@b) = (undef,undef) creates arrays of 2 - indexes, or something like that. Not what was wanted. - Examples 2 and 3 assign undef to @a: an array of 1 index, value undef, and - undefine the others variables in the list. This was not the desired behavior! - * For most scalars, arrays, and hashes, use: undef @a; undef $s; undef %h. - * For some hash and array index values, use $h{a} = undef. These cases may want - the key itself to exist, with the value of undef, though I believe: + to use: (@a,$b,$c,%d) = (); This undefines all the variables in the list. + Note that assigning undef to @a in the first example creates an array of 1 + key, with the value undef, and (@a,@b) = (undef,undef) creates arrays of 2 + indexes, or something like that. Not what was wanted. + Examples 2 and 3 assign undef to @a: an array of 1 index, value undef, and + undefine the others variables in the list. This was not the desired behavior! +* For most scalars, arrays, and hashes, use: undef @a; undef $s; undef %h. +* For some hash and array index values, use $h{a} = undef. These cases may want + the key itself to exist, with the value of undef, though I believe: undef $h{a}; - is synonymous, but still have to verify that. + is synonymous, but still have to verify that. I did some testing, and realized that some of the undef I had used in the various previous ways of using undef were not actually resulting in the expected @@ -6393,7 +6658,7 @@ Options for -Y are: * -Y [1-xxx]: Set maximum block line height to given integer. * -Y -1: Print out one primary data block item at a time, with -F for example. * -Y -2: Do not remove color codes when piped or redirected. Mostly useful for - piping to less -R, to preserve color codes. + piping to less -R, to preserve color codes. * -Y -3: Restore default unlimited height if LINES_MAX configuration item used. 15. And finally, more disk vendors/vendor ids. As usual. As expected. @@ -6403,13 +6668,13 @@ CHANGES: 1. If /sys or /proc/cpuinfo speed data available: * For -b CPU item: - speed: [speed MHz] min/max: [min]/[max] MHz + speed: [speed MHz] min/max: [min]/[max] MHz becomes: - speed (MHz): avg: [speed] min/max: [min]/[max] + speed (MHz): avg: [speed] min/max: [min]/[max] * For -C, Speed item - Speed: [speed MHz] min/max: [min]/[max] MHz Cores (MHz): ... + Speed: [speed MHz] min/max: [min]/[max] MHz Cores (MHz): ... becomes: - Speed (MHz): avg: [speed] min/max: [min]/[max] cores: ... + Speed (MHz): avg: [speed] min/max: [min]/[max] cores: ... * For short form, shows speed/min/max but uses average speed if available. For -b and -C, only shows one MHz in Speed line starter, which slightly shortens @@ -6428,8 +6693,8 @@ that's a verbose --admin option after all, no need to save lines! 4. Going along with Fix 5, give up on trying to pretend we can guess at L2 cache, now if only 'cache' data was available from cpuinfo, will just say: cache: [cache size] - note: check - +note: check + and call it a day. 5a. Change default width to 80 columns in display, and 100 and out. Too many @@ -6446,15 +6711,15 @@ time to just force 80 column widths as default and call it a day. You can change these new defaults using configuration options (these are the previous options, though due to a bug, COLS_MAX_CONSOLE was never being used): - COLS_MAX_CONSOLE=115 # in display, terminal client max width - COLS_MAX_IRC=100 - COLS_MAX_NO_DISPLAY=130 # not in display, no X/Wayland running - +COLS_MAX_CONSOLE=115 # in display, terminal client max width +COLS_MAX_IRC=100 +COLS_MAX_NO_DISPLAY=130 # not in display, no X/Wayland running + 5b. Made second and greater rows of a line indent +2 to make it more clear that it is a child row of its parent row. Note that because no arg short form and -I are special types of rows, this behavior is not used, they just print out as usual. This makes for more readable and easy to follow flow of output data. - + 6. If > 1 physical cpu detected, no longer uses single/dual/triple/quad core strings, rather uses: 2x 2-core. Also uses lower case -core, not -Core. @@ -6983,7 +7248,7 @@ possible errors, and makes pci detections far more robust. inxi-legacy/xorg-c, moved branch xiin to /xiin, moved branch inxi-legacy (binxi) to inxi-legacy/inxi-legacy. Those directories each contain all the files each branch had in it. - + This gets rid of some branches clutter, and nobody needs to see those anymore, but if they care, they can look at them. Note that to do this, I had to merge their histories, which was not that nice, but git is just really bad at this @@ -7696,15 +7961,15 @@ that can be quite useful. Note that bluetooth is a real pain for users to debug because you can have: - * Bluetooth Service: enabled/disabled - * Bluetooth Service: started/stopped - * bluetoothctl: start/stop - * bt-adapter: start/stop - * hciconfig: start/stop - * rfkill: software: block/unblock; hardware: block/unblock - however, for - hardware, that means a physical button has been pressed to disable it, on the - laptop that is. - +* Bluetooth Service: enabled/disabled +* Bluetooth Service: started/stopped +* bluetoothctl: start/stop +* bt-adapter: start/stop +* hciconfig: start/stop +* rfkill: software: block/unblock; hardware: block/unblock - however, for + hardware, that means a physical button has been pressed to disable it, on the + laptop that is. + To make matters worse, one tool does not always even know when another tool has changed something, for example, if I rfkill blocked hci0, then unblocked it, hciconfig would keep seeing it as down until it was switched to on with @@ -8655,19 +8920,19 @@ difference. 3. There were some missing cases for LVM missing data messages, so the following fixes were added: - * In cases where lsblk is installed and user is non root, or lvs is not - installed, but no lvm data is present, inxi now shows the expected 'Message: - No LVM data found.' instead of the permissions or missing program error that - showed before. If lsblk is not installed, and lvm is installed (or missing), - with lvs not root readable, the permissiosn message (or missing program) will - show since at that point, inxi has no way to know if there is lvm data or not. - - * Not an inxi, but rather an Arch Linux packaging bug, the maintainer of lvm - has made lvs and vgs fail to return error number on non root start, which is - a bug (pvs does return expected error return). Rather than wait for this bug - to be fixed, inxi will just test if lvs and lsblk lvm data, it will show - permissions message, otherwse the no lvm data message as expected. - +* In cases where lsblk is installed and user is non root, or lvs is not +installed, but no lvm data is present, inxi now shows the expected 'Message: +No LVM data found.' instead of the permissions or missing program error that +showed before. If lsblk is not installed, and lvm is installed (or missing), +with lvs not root readable, the permissiosn message (or missing program) will +show since at that point, inxi has no way to know if there is lvm data or not. + +* Not an inxi, but rather an Arch Linux packaging bug, the maintainer of lvm +has made lvs and vgs fail to return error number on non root start, which is +a bug (pvs does return expected error return). Rather than wait for this bug +to be fixed, inxi will just test if lvs and lsblk lvm data, it will show +permissions message, otherwse the no lvm data message as expected. + I think these cover the last unhandled LVM cases I came across, so ideally, the lvm data messages will be reasonably correct. @@ -8937,7 +9202,7 @@ RAID running. Sample: inxi -D Drives: Local Storage: total: raw: 340.19 GiB usable: 276.38 GiB - lvm-free: 84.61 GiB used: 8.49 GiB (3.1%) + lvm-free: 84.61 GiB used: 8.49 GiB (3.1%) lvm-free is non assigned volume group size, that is, size not assigned to a logical volume in the volume group, but available in the volume group. raw: is @@ -9896,17 +10161,17 @@ packages, repos, fits. Note that in some systems getting full package counts takes some time so it's an -x option not default. If -rx, -rxx, -ra, package info moved to -r section, and if -Ix, -Ixx, or -Ia, the following data shows: - * -Ix or -rx: show total package counts: Packages: 2429 - * -Ixx or -rxx: shows Packages then counts by package manager located. If there - was only one package manager with packages, the total moves from right after - Packages: to the package manager, like: Packages: apt: 3241 but if there were - for example 2 or more found, it would show the total then: - Packages 3245 apt:3241 snap: 4 - * -Ia or -ra: adds package managers with 0 packages managed, those are not - shown with -xx, and also shows how many of those packages per package manager - is a library type lib file. - Sample: - inxi -Iay1 +* -Ix or -rx: show total package counts: Packages: 2429 +* -Ixx or -rxx: shows Packages then counts by package manager located. If there +was only one package manager with packages, the total moves from right after +Packages: to the package manager, like: Packages: apt: 3241 but if there were +for example 2 or more found, it would show the total then: +Packages 3245 apt:3241 snap: 4 +* -Ia or -ra: adds package managers with 0 packages managed, those are not +shown with -xx, and also shows how many of those packages per package manager +is a library type lib file. +Sample: +inxi -Iay1 Info: Processes: 470 Uptime: 8d 10h 42m @@ -10069,7 +10334,7 @@ Audio: CODE: 1. Redo of all internal full key strings, added two new # separated items: - xx#x#y#key-name: +xx#x#y#key-name: * xx remains the main 0 padded 2 digit sorter per row/block. * x is a new 0/1 boolean, that shows if the value is a container or not. As currently implemented probably not hugely useful since it won't say when @@ -10304,21 +10569,21 @@ outside the post or issue report, which is hard to read. Hopefully support people will catch onto this one. 4. This closes issue #217 - Adds dmidecode based extra data: - -xxx - shows CPU voltage and external clock speeds - -a - shows CPU socket type and base/boost: speed items. These are --admin - options because neither is particularly reliable, sometimes they are right, - sometimes they aren't, as usual with dmi data. As far as tests show, base - speed, what dmidecode misleadingly calls 'Current Speed', which it isn't, - is the actual normal non throttled speed of the CPU / motherboard setup. - boost is what dmidecode calls 'Max Speed', which it also isn't, though - sometimes it is, as with AMD cpus with boost, and no overclocking. With - overclocking, sometimes base will be higher, sometimes the actual real - current cpu speeds will be higher than all the max/boost values. - Motherboard CPU socket type is likewise randomly correct, incorrect, empty, - misleading, depending on the age and type of the system, and the CPU - vendor. It appears that in general, AMD CPUs will be more or less right - if they have this data, and Intel CPUs will sometimes be right, sometimes - not, or empty. For > 1 CPU systems, the data is much less reliable. +-xxx - shows CPU voltage and external clock speeds +-a - shows CPU socket type and base/boost: speed items. These are --admin +options because neither is particularly reliable, sometimes they are right, +sometimes they aren't, as usual with dmi data. As far as tests show, base +speed, what dmidecode misleadingly calls 'Current Speed', which it isn't, +is the actual normal non throttled speed of the CPU / motherboard setup. +boost is what dmidecode calls 'Max Speed', which it also isn't, though +sometimes it is, as with AMD cpus with boost, and no overclocking. With +overclocking, sometimes base will be higher, sometimes the actual real +current cpu speeds will be higher than all the max/boost values. +Motherboard CPU socket type is likewise randomly correct, incorrect, empty, +misleading, depending on the age and type of the system, and the CPU +vendor. It appears that in general, AMD CPUs will be more or less right +if they have this data, and Intel CPUs will sometimes be right, sometimes +not, or empty. For > 1 CPU systems, the data is much less reliable. -------------------------------------------------------------------------------- -- Harald Hope - Sun, 31 May 2020 14:26:37 -0700 @@ -10731,15 +10996,15 @@ production systems. This issue report led to 2 new options: --memory-short, which only shows a basic RAM report. Memory: RAM: total: 31.43 GiB used: 14.98 GiB (47.7%) - Report: arrays: 1 slots: 4 modules: 2 type: DDR4 + Report: arrays: 1 slots: 4 modules: 2 type: DDR4 And a 2nd, --memory-modules, only shows the occupied slots. This can be useful in situations where it's a server or vm with a lot of slots, most empty: Memory: RAM: total: 31.43 GiB used: 15.44 GiB (49.1%) - Array-1: capacity: 256 GiB slots: 4 EC: None - Device-1: DIMM 1 size: 16 GiB speed: 2400 MT/s - Device-2: DIMM 1 size: 16 GiB speed: 2400 MT/s + Array-1: capacity: 256 GiB slots: 4 EC: None + Device-1: DIMM 1 size: 16 GiB speed: 2400 MT/s + Device-2: DIMM 1 size: 16 GiB speed: 2400 MT/s Note that both of these options trigger -m, so -m itself is not required. @@ -11416,12 +11681,12 @@ These options are to help debug debugger failures, and so far have been tested and solved the failures, so I'm adding them all to the main man and help menu, thus raising them to the level of supported tools. These were enormously helpful in solving proc or sys debugger hangs. - * --debug-proc - * --debug-proc-print - * --debug-no-sys - * --debug-sys - * --debug-sys-print - +* --debug-proc +* --debug-proc-print +* --debug-no-sys +* --debug-sys +* --debug-sys-print + 2. Added findmnt output to debugger, that may be useful in the future. Also added df -kTPa to also catch hidden partitions in debugger. @@ -11551,16 +11816,16 @@ database, somehow you have users that manage to use every obscure usb/ssd/hdd known to humanity. 14. Big update to --admin, now has the following: - A: partitions: shows 'raw size: ' of partition, this lets users see the amount - of file system overhead, along with the available size as usual. - B: partitions: show percent of raw in size: - C: partitions: show if root, block size of partition file system. Uses - blockdev --getbsz <part> - D: partition: swap: show swappiness and vfs cache pressure, with (default) - or (default [default value]) added. This apparently can help debugging some - kernel issues etc. Whatever, I'll take someone's word for that. - E: Disks: show block size: logical: physical: - +A: partitions: shows 'raw size: ' of partition, this lets users see the amount +of file system overhead, along with the available size as usual. +B: partitions: show percent of raw in size: +C: partitions: show if root, block size of partition file system. Uses +blockdev --getbsz <part> +D: partition: swap: show swappiness and vfs cache pressure, with (default) +or (default [default value]) added. This apparently can help debugging some +kernel issues etc. Whatever, I'll take someone's word for that. +E: Disks: show block size: logical: physical: + 15. New option and configuration item: --partition-sort / PARTITION_SORT This lets users change default mount point sort order to any available ordering in the partition item. Man page and help menu show options. @@ -11579,12 +11844,12 @@ number, like 3.1. Note that this is going to be wrong for BSDs, but that's fine. 2. Changed slightly the output of Memory item, now it follows the following rules: - A: if -m/--memory is triggered (> -v4, or -m) Memory line always shows in - Memory: item, which makes sense. Note that -m overrides all other options of - where Memory minireport could be located. - B: if -tm is triggered, and -I is not triggered, Memory shows in in -tm - C: if -I is triggered, and -m is not triggered, Memory: shows in -I line. - D: no change in short form inxi no arg output, Memory is there. +A: if -m/--memory is triggered (> -v4, or -m) Memory line always shows in +Memory: item, which makes sense. Note that -m overrides all other options of +where Memory minireport could be located. +B: if -tm is triggered, and -I is not triggered, Memory shows in in -tm +C: if -I is triggered, and -m is not triggered, Memory: shows in -I line. +D: no change in short form inxi no arg output, Memory is there. -------------------------------------------------------------------------------- -- Harald Hope - Mon, 24 Sep 2018 15:58:00 -0700 @@ -11949,37 +12214,37 @@ response to a second set of issues in #156 by gm10, USB drivers. Depending on the system, using only /sys data, while slightly less informative, is between 20 and 2000 milliseconds faster, so if you want speed, either use the new --usb-sys option, or the configuration file USB_SYS=[true|false] option. - 1. switched to cleaner more efficient data structures - 2. added ports count to hub report, linux and BSD. - 3. added [--usb|-A|-N] -xxx serial for Device items, if present. - 4. added --usb -xx drivers, per interface, can be 1 or more drivers. - 5. fully refactored -A and -N usb device logic, far cleaner and simple now, - much easier to work with, no more hacks to find things and match them. - 6. USB type: now comes from /sys, and is in general going to be more accurate - than the lsusb -v based method, which was always an ugly and incomplete hack. - As with drivers, it also now lists all the interface types found per device, - not just the first one as with the previous method. Note that HID means the - more verbose: Human Interface Device, but I shortened it. Now that the type: - data is created by inxi reading the class/subclass/protocal IDs, and then - figuring out what to do itself, I can have quite a bit more flexibility in - terms of how type is generated. - 7. added --usb -xxx interfaces: [count] for devices, which lists the device - interface count. This can be useful to determine if say, a usb/keyboard adapter - is a 2 interface device. Note that Audio devices generally have many interfaces, - since they do more than 1 thing (audio output, microphone input, etc.). - 8. Support for user configuration file item: USB_SYS=[true|false]. This is - useful if you want to see only the /sys version of the data, or if you want the - significant speed boost not using lsusb offers, particularly on older systems - with a complex USB setup, many buses, many devices, etc. - New option --usb-tool overrides USB_SYS value, and forces lsusb use. - 9. New options: --usb-sys - forces all usb items to use /sys data, and skip - lsusb. Note that you still have to use the feature options, like --usb, -A, or - -N. This can lead to a significant improvement in execution time for inxi. - 10. Rather than the previous bus:device ID string, to go along with the - internal sorting strings used, inxi now shows the real Bus / port /port ids, - like: - 1-3.2.1:3 - Bus-Port[.port]:device id. - +1. switched to cleaner more efficient data structures +2. added ports count to hub report, linux and BSD. +3. added [--usb|-A|-N] -xxx serial for Device items, if present. +4. added --usb -xx drivers, per interface, can be 1 or more drivers. +5. fully refactored -A and -N usb device logic, far cleaner and simple now, +much easier to work with, no more hacks to find things and match them. +6. USB type: now comes from /sys, and is in general going to be more accurate +than the lsusb -v based method, which was always an ugly and incomplete hack. +As with drivers, it also now lists all the interface types found per device, +not just the first one as with the previous method. Note that HID means the +more verbose: Human Interface Device, but I shortened it. Now that the type: +data is created by inxi reading the class/subclass/protocal IDs, and then +figuring out what to do itself, I can have quite a bit more flexibility in +terms of how type is generated. +7. added --usb -xxx interfaces: [count] for devices, which lists the device +interface count. This can be useful to determine if say, a usb/keyboard adapter +is a 2 interface device. Note that Audio devices generally have many interfaces, +since they do more than 1 thing (audio output, microphone input, etc.). +8. Support for user configuration file item: USB_SYS=[true|false]. This is +useful if you want to see only the /sys version of the data, or if you want the +significant speed boost not using lsusb offers, particularly on older systems +with a complex USB setup, many buses, many devices, etc. +New option --usb-tool overrides USB_SYS value, and forces lsusb use. +9. New options: --usb-sys - forces all usb items to use /sys data, and skip +lsusb. Note that you still have to use the feature options, like --usb, -A, or +-N. This can lead to a significant improvement in execution time for inxi. +10. Rather than the previous bus:device ID string, to go along with the +internal sorting strings used, inxi now shows the real Bus / port /port ids, +like: +1-3.2.1:3 - Bus-Port[.port]:device id. + 6. Added support for Xvesa display server. Thanks for exposing that one, TinyCore! @@ -12036,7 +12301,7 @@ USB: Hub: 4:1 usb: 3.1 type: Full speed (or root) hub Hub: 5:1 usb: 2.0 type: Full speed (or root) hub Hub: 6:1 usb: 3.0 type: Full speed (or root) hub - + Corrected: sort by BusID in 3.0.21: inxi --usb @@ -13464,8 +13729,8 @@ BUGS: 1. RAID - both mdraid and zfs bugs corrected. Issue #135 2. EPYC cpu wrong die count corrected, and also added support for the EPYC type. - Issue #135 - + Issue #135 + 3. Possible ARM data glitch that made reader fail on a non-existent file. -------------------------------------------------------------------------------- @@ -14560,8 +14825,8 @@ Note the following changes required to make the wraps more consistent: -S - the gcc/bits have been made separate, like: bits: 32 gcc: 5.3 -C - the new microarchitecture -x option now is: arch: K7 [for example] - cache wraps to next line with arch. with -f, bmips now shows on same line - as arch/cache + cache wraps to next line with arch. with -f, bmips now shows on same line + as arch/cache -------------------------------------------------------------------------------- -- Harald Hope - Sun, 30 Jul 2017 14:02:33 -0700 @@ -15110,9 +15375,9 @@ respectively. $HOME/.config $HOME/.local/share to place the inxi data directory, which was previously here: - + $HOME/.inxi - + 3. If neither of these cases are present, inxi will default to its legacy user data: $HOME/.inxi as before @@ -15134,7 +15399,7 @@ legacy man page would show up instead, which isn't good, but there was no perfect fix for the man issue so I just picked the easiest way, ignoring all man pages installed into /usr/share/man/man1 and treating them as final location, otherwise using if present the /usr/local/share/man/man1 location for new manual - install users. +install users. Also, for users with existing man locations and an inxi manually installed, you have to update to inxi current, then move your man file to @@ -15905,7 +16170,7 @@ New version, new tarball. Two great bug report, issues. 1. Tightened runit init detection to use proc, note that if runit works on BSDs inxi will require more data to properly detect it on BSDs.. - + 2. Use openrc runlevel tests natively if openrc detected. 3. Fixed subtle issue with alias to inxi file and paths. @@ -16240,7 +16505,7 @@ data. 6. BSDs, maybe all, different syntax in xorg.0.log made unloaded gfx drivers not show, that is fixed now. - + -p fixed file system type in -p/-P for openBSD, now shows. -I / inxi short - fixed used memory, did not show in openBSD, now does. @@ -16931,27 +17196,27 @@ awk 'BEGIN {total=0} /^total/ {total = total + $4 }END {print total}' result: 614562228 - df -P -T --exclude-type=aufs --exclude-type=devfs --exclude-type=devtmpfs \ - --exclude-type=fdescfs --exclude-type=iso9660 --exclude-type=linprocfs \ - --exclude-type=procfs --exclude-type=squashfs --exclude-type=sysfs \ - --exclude-type=tmpfs --exclude-type=unionfs | awk 'BEGIN {total=0} \ - {total = total + $4 }END {print total}' +df -P -T --exclude-type=aufs --exclude-type=devfs --exclude-type=devtmpfs \ +--exclude-type=fdescfs --exclude-type=iso9660 --exclude-type=linprocfs \ +--exclude-type=procfs --exclude-type=squashfs --exclude-type=sysfs \ +--exclude-type=tmpfs --exclude-type=unionfs | awk 'BEGIN {total=0} \ +{total = total + $4 }END {print total}' + +result: +614562236 - result: - 614562236 - - In my tests, using --total gives a greater disk user percentage than adding the +In my tests, using --total gives a greater disk user percentage than adding the results up manually, as inxi did before, and still does for systems without --total for df. - - df --total -P -T --exclude-type=aufs --exclude-type=devfs \ - --exclude-type=devtmpfs --exclude-type=fdescfs --exclude-type=iso9660 \ - --exclude-type=linprocfs --exclude-type=procfs --exclude-type=squashfs \ - --exclude-type=sysfs --exclude-type=tmpfs --exclude-type=unionfs - + +df --total -P -T --exclude-type=aufs --exclude-type=devfs \ +--exclude-type=devtmpfs --exclude-type=fdescfs --exclude-type=iso9660 \ +--exclude-type=linprocfs --exclude-type=procfs --exclude-type=squashfs \ +--exclude-type=sysfs --exclude-type=tmpfs --exclude-type=unionfs + Filesystem Type 1024-blocks Used Available Capacity Mounted on /dev/disk/by-label/root-data\ - ext3 12479556 12015624 335816 98% / + ext3 12479556 12015624 335816 98% / /dev/sdc9 ext3 20410156 18013360 1979432 91% /home /dev/sdc7 ext3 4904448 3785460 1016672 79% /media/sdb2 /dev/sdc5 ext3 30382896 27467220 2295720 93% /var/www/m @@ -18489,8 +18754,8 @@ application the shell is running in. Example: Info: Processes: 271 Uptime: 5:36 Memory: 3255.8/4048.5MB Runlevel: 3 - Gcc sys: 4.7.2 alt: 4.0/4.2/4.4/4.5/4.6 - Client: Shell (bash 4.2.37 - started in konsole) inxi: 1.8.33 + Gcc sys: 4.7.2 alt: 4.0/4.2/4.4/4.5/4.6 + Client: Shell (bash 4.2.37 - started in konsole) inxi: 1.8.33 -------------------------------------------------------------------------------- -- Harald Hope - Mon, 28 Jan 2013 15:57:15 -0800 |
