diff options
Diffstat (limited to 'perl-install/detect_devices.pm')
-rw-r--r-- | perl-install/detect_devices.pm | 118 |
1 files changed, 71 insertions, 47 deletions
diff --git a/perl-install/detect_devices.pm b/perl-install/detect_devices.pm index 2b0266e37..42f14aff6 100644 --- a/perl-install/detect_devices.pm +++ b/perl-install/detect_devices.pm @@ -1,4 +1,4 @@ -package detect_devices; # $Id: detect_devices.pm 260571 2009-09-17 14:51:24Z pterjan $ +package detect_devices; # $Id: detect_devices.pm 267151 2010-03-30 14:27:41Z blino $ use diagnostics; use strict; @@ -121,10 +121,11 @@ sub complete_usb_storage_info { if (my $e = find { !$_->{found} && $_->{usb_vendor} == $usb->{vendor} && $_->{usb_id} == $usb->{id} } @usb) { my $host = get_sysfs_usbpath_for_block($e->{device}); if ($host) { - $e->{info} = chomp_(cat_("/sys/block/$e->{device}/$host/../serial")); + my $file = "/sys/block/$host/../serial"; + $e->{info} = chomp_(cat_($file)) if -e $file; $e->{usb_description} = join('|', - chomp_(cat_("/sys/block/$e->{device}/$host/../manufacturer")), - chomp_(cat_("/sys/block/$e->{device}/$host/../product"))); + chomp_(cat_("/sys/block/$host/../manufacturer")), + chomp_(cat_("/sys/block/$host/../product"))); } local $e->{found} = 1; $e->{"usb_$_"} ||= $usb->{$_} foreach keys %$usb; @@ -170,7 +171,7 @@ sub get_sysfs_field_from_link { sub get_sysfs_usbpath_for_block { my ($device) = @_; - my $host = readlink("/sys/block/$device/device"); + my $host = readlink("/sys/block/$device"); $host =~ s!/host.*!!; $host; } @@ -181,7 +182,8 @@ sub get_scsi_driver { foreach (@l) { next if $_->{driver}; my $host = get_sysfs_usbpath_for_block($_->{device}); - $_->{driver} = get_sysfs_field_from_link("/sys/block/$_->{device}/$host", 'driver'); + require list_modules; + $_->{driver} = list_modules::filename2modname(get_sysfs_field_from_link("/sys/block/$host", 'driver')); } } @@ -203,7 +205,9 @@ sub getSCSI() { my @l; foreach (all($dev_dir)) { - my ($host, $channel, $id, $lun) = split ':' or log::l("bad entry in $dev_dir: $_"), next; + my ($host, $channel, $id, $lun) = split ':'; + defined $lun or next; + my $dir = "$dev_dir/$_"; # handle both old and new kernels: @@ -214,7 +218,7 @@ sub getSCSI() { } warn("cannot get info for device ($_)"), next if !$device; - my $usb_dir = readlink("$node/device") =~ m!/usb! && "$node/device/../../../.."; + my $usb_dir = readlink($dir) =~ m!/usb! && "$dir/../../../.."; my $get_usb = sub { chomp_(cat_("$usb_dir/$_[0]")) }; my $get = sub { @@ -230,8 +234,13 @@ sub getSCSI() { my $media_type = ${{ st => 'tape', sr => 'cdrom', sd => 'hd', sg => 'generic' }}{substr($device, 0, 2)} || $raw_type =~ /Scanner|Processor/ && 'scanner'; - push @l, { info => $get->('vendor') . ' ' . $get->('model'), host => $host, channel => $channel, id => $id, lun => $lun, - description => join('|', $get->('vendor'), $get->('model')), + my ($vendor, $model) = ($get->('vendor'), $get->('model')); + my ($v, $m) = _get_hd_vendor($model); + if ($v && $v) { + ($vendor, $model) = ($v, $m); + } + push @l, { info => $vendor . ' ' . $model, host => $host, channel => $channel, id => $id, lun => $lun, + description => join('|', $vendor, $model), bus => 'SCSI', media_type => $media_type, device => $device, $usb_dir ? ( usb_vendor => hex($get_usb->('idVendor')), usb_id => hex($get_usb->('idProduct')), @@ -253,8 +262,9 @@ sub getSCSI() { } -my %eide_hds = ( +my %hd_vendors = ( "ASUS" => "Asus", + "ATA Maxtor" => "Maxtor", "CD-ROM CDU" => "Sony", "CD-ROM Drive/F5D" => "ASUSTeK", "Compaq" => "Compaq", @@ -280,6 +290,16 @@ my %eide_hds = ( "WDC" => "Western Digital Corp.", ); +# return ($vendor, $model) +sub _get_hd_vendor { + my ($info) = @_; + foreach my $name (keys %hd_vendors) { + next if !$name; + return ($hd_vendors{$name}, $2) if $info =~ /^$name(-|\s)*(.*)/; + } + return ("Hitachi", $info) if $info =~ /^HD[ST][0-9]/; +} + sub getIDE() { my @idi; @@ -295,9 +315,7 @@ sub getIDE() { my $info = chomp_(cat_("$d/model")) || "(none)"; my $num = ord(($d =~ /(.)$/)[0]) - ord 'a'; - my ($vendor, $model) = map { - if_($info =~ /^$_(-|\s)*(.*)/, $eide_hds{$_}, $2); - } keys %eide_hds; + my ($vendor, $model) = _get_hd_vendor($info); my $host = $num; ($host, my $id) = divide($host, 2); @@ -370,11 +388,9 @@ sub getATARAID() { sub getVirtIO() { -d '/sys/bus/virtio/devices' or return; map { - my $dev = basename($_); - $dev =~ s/block://; - { device => $dev, info => "VirtIO block device", media_type => 'hd', bus => 'virtio' } + { device => basename($_), info => "VirtIO block device", media_type => 'hd', bus => 'virtio' }; } - glob("/sys/bus/virtio/devices/*/block:*"); + glob("/sys/bus/virtio/devices/*/block/*"); } # cpu_name : arch() =~ /^alpha/ ? "cpu " : @@ -493,6 +509,7 @@ sub getInputDevices() { $device->{Synaptics} = $descr eq 'SynPS/2 Synaptics TouchPad'; $device->{ALPS} = $descr =~ m!^AlpsPS/2 ALPS!; + $device->{Elantech} = $descr eq 'ETPS/2 Elantech Touchpad'; } elsif (/H: Handlers=(.*)/) { my @l = split(' ', $1); @@ -543,6 +560,11 @@ sub getInputDevices_and_usb() { @l; } +sub serialPorts() { map { "ttyS$_" } 0..7 } +sub serialPort2text { + $_[0] =~ /ttyS(\d+)/ ? "$_[0] / COM" . ($1 + 1) : $_[0]; +} + sub getSerialModem { my ($modules_conf, $o_mouse) = @_; my $mouse = $o_mouse || {}; @@ -553,7 +575,7 @@ sub getSerialModem { my @modems; probeSerialDevices(); - foreach my $port (map { "ttyS$_" } (0..7)) { + foreach my $port (serialPorts()) { next if $mouse->{device} =~ /$port/; my $device = "/dev/$port"; next if !-e $device || !hasModem($device); @@ -569,9 +591,10 @@ sub getSerialModem { @modems; } +our $detect_serial_modem = 1; sub getModem { my ($modules_conf) = @_; - getSerialModem($modules_conf, {}), get_winmodems(); + ($detect_serial_modem ? getSerialModem($modules_conf, {}) : ()), get_winmodems(); } sub get_winmodems() { @@ -684,7 +707,6 @@ sub get_ids_from_sysfs_device { my $usb_root = -f "$dev_path/bInterfaceNumber" && "../" || -f "$dev_path/idVendor" && ""; my $is_pcmcia = -f "$dev_path/card_id"; my $sysfs_ids; - #my $bus = get_sysfs_field_from_link($dev_path, "bus"); my $bus = get_sysfs_field_from_link($dev_path, "subsystem"); #- FIXME: use $bus if ($is_pcmcia) { @@ -703,7 +725,7 @@ sub get_ids_from_sysfs_device { if ($bus eq 'pci') { my $device = basename(readlink $dev_path); my @ids = $device =~ /^(.{4}):(.{2}):(.{2})\.(.+)$/; - @{$sysfs_ids}{qw(pci_domain pci_bus pci_device pci_function)} = map { hex($_) } @ids if @ids; + @$sysfs_ids{qw(pci_domain pci_bus pci_device pci_function)} = map { hex($_) } @ids if @ids; } } $sysfs_ids; @@ -796,22 +818,22 @@ sub add_addons { sub get_pci_sysfs_path { my ($l) = @_; - sprintf('%04x:%02x:%02x.%d', $l->{pci_domain}, $l->{pci_bus}, $l->{pci_device}, $l->{pci_function}); + sprintf('%04x:%02x:%02x.%d', $l->{pci_domain}, $l->{pci_bus}, $l->{pci_device}, $l->{pci_function}); } my (@pci, @usb); + sub pci_probe__real() { add_addons($pcitable_addons, map { my %l; - @l{qw(vendor id subvendor subid pci_domain pci_bus pci_device pci_function pci_revision is_pciexpress media_type nice_media_type driver description)} = split "\t"; + @l{qw(vendor id subvendor subid pci_domain pci_bus pci_device pci_function pci_revision is_pciexpress media_type nice_media_type driver description)} = split "\t"; $l{$_} = hex $l{$_} foreach qw(vendor id subvendor subid); $l{bus} = 'PCI'; $l{sysfs_device} = '/sys/bus/pci/devices/' . get_pci_sysfs_path(\%l); \%l; } c::pci_probe()); } - sub pci_probe() { state $done; if (!$done) { @@ -828,10 +850,10 @@ sub usb_probe__real() { add_addons($usbtable_addons, map { my %l; - @l{qw(vendor id media_type driver description pci_bus pci_device)} = split "\t"; + @l{qw(vendor id media_type driver description pci_bus pci_device usb_port)} = split "\t"; $l{media_type} = join('|', grep { $_ ne '(null)' } split('\|', $l{media_type})); $l{$_} = hex $l{$_} foreach qw(vendor id); - $l{sysfs_device} = "/sys/class/usb_device/usbdev$l{pci_bus}.$l{pci_device}/device"; + $l{sysfs_device} = "/sys/bus/usb/devices/$l{pci_bus}-" . ($l{usb_port} + 1); $l{bus} = 'USB'; \%l; } c::usb_probe()); @@ -899,8 +921,8 @@ sub pcmcia_probe() { map { my $dir = "$dev_dir/$_"; my $get = sub { chomp_(cat_("$dir/$_[0]")) }; - my $class_dev = first(glob_("$dir/tty*")); - my $device = $class_dev && get_sysfs_field_from_link($dir, basename($class_dev)); + my $class_dev = first(glob_("$dir/tty/tty*")); + my $device = $class_dev && basename($class_dev); my $modalias = $get->('modalias'); my $driver = get_sysfs_field_from_link($dir, 'driver'); #- fallback on modalias result @@ -1026,7 +1048,10 @@ sub dmidecode() { my ($ver, @l) = run_program::get_stdout('dmidecode'); my $tab = "\t"; - if ($ver =~ /(\d+\.\d+)/ && $1 >= 2.7) { + + my ($major, $minor) = $ver =~ /(\d+)\.(\d+)/; + + if ($major > 2 || $major == 2 && $minor > 7) { #- new dmidecode output is less indented $tab = ''; #- drop header @@ -1055,9 +1080,7 @@ sub dmidecode_category { #- size in MB sub dmi_detect_memory() { my @l1 = map { $_->{'Enabled Size'} =~ /(\d+) MB/ && $1 } dmidecode_category('Memory Module'); -# my @l2 = map { $_->{'Form Factor'} =~ /^(SIMM|SIP|DIP|DIMM|RIMM|SODIMM|SRIMM)$/ && - my @l2 = map { $_->{'Form Factor'} =~ /^(SIMM|SIP|DIP|DIMM|FB-DIMM|RIMM|SODIMM|SRIMM)$/ && - + my @l2 = map { $_->{'Form Factor'} =~ /^(SIMM|SIP|DIP|DIMM|FB-DIMM|RIMM|SODIMM|SRIMM)$/ && ($_->{Size} =~ /(\d+) MB/ && $1 || $_->{Size} =~ /(\d+) kB/ && $1 * 1024); } dmidecode_category('Memory Device'); max(sum(@l1), sum(@l2)); @@ -1077,17 +1100,6 @@ sub computer_info() { }; } -sub isServer() { - computer_info()->{isServer} - || (any { $_->{Type} =~ /ECC/ } dmidecode_category('Memory Module')) - || dmidecode_category('System Information')->{Manufacturer} =~ /Supermicro/i - || dmidecode_category('System Information')->{'Product Name'} =~ /NetServer|Proliant|PowerEdge|eServer|IBM System x|ThinkServer/i - || matching_desc__regexp('LSI Logic.*SCSI') - || matching_desc__regexp('MegaRAID') - || matching_desc__regexp('NetServer') - || (any { $_->{'model name'} =~ /(Xeon|Opteron)/i } getCPUs()); -} - #- try to detect a laptop, we assume pcmcia service is an indication of a laptop or #- the following regexp to match graphics card apparently only used for such systems. sub isLaptop() { @@ -1106,6 +1118,17 @@ sub isLaptop() { || (any { member($_->{driver}, qw(ipw2100 ipw2200 ipw3945)) } pci_probe()); } +sub isServer() { + computer_info()->{isServer} + || (any { $_->{Type} =~ /ECC/ } dmidecode_category('Memory Module')) + || dmidecode_category('System Information')->{Manufacturer} =~ /Supermicro/i + || dmidecode_category('System Information')->{'Product Name'} =~ /NetServer|Proliant|PowerEdge|eServer|IBM System x|ThinkServer/i + || matching_desc__regexp('LSI Logic.*SCSI') + || matching_desc__regexp('MegaRAID') + || matching_desc__regexp('NetServer') + || (any { $_->{'model name'} =~ /(Xeon|Opteron)/i } getCPUs()); +} + sub BIGMEM() { arch() !~ /x86_64|ia64/ && $> == 0 && dmi_detect_memory() > 4 * 1024; } @@ -1149,7 +1172,7 @@ sub has_cpu_flag { } sub matching_types() { - { + +{ laptop => isLaptop(), 'touchpad' => hasTouchpad(), '64bit' => to_bool(arch() =~ /64/), @@ -1158,8 +1181,9 @@ sub matching_types() { } sub hasWacom() { find { $_->{vendor} == 0x056a || $_->{driver} =~ /wacom/ } usb_probe() } -sub usbWacom() { grep { $_->{vendor} eq '056a' } getInputDevices() } sub hasTouchpad() { any { $_->{Synaptics} || $_->{ALPS} || $_->{Elantech} } getInputDevices() } + +sub usbWacom() { grep { $_->{vendor} eq '056a' } getInputDevices() } sub usbKeyboards() { grep { $_->{media_type} =~ /\|Keyboard/ } usb_probe() } sub usbStorage() { grep { $_->{media_type} =~ /Mass Storage\|/ } usb_probe() } sub has_mesh() { find { /mesh/ } all_files_rec("/proc/device-tree") } @@ -1233,7 +1257,7 @@ sub probeall_unavailable_modules() { } probeall(); } -sub probeall_dkms_modules { +sub probeall_dkms_modules() { my @unavailable_modules = probeall_unavailable_modules() or return; require modalias; my $dkms_modules = modalias::parse_file_modules($::prefix . "/usr/share/ldetect-lst/dkms-modules.alias"); |