summaryrefslogtreecommitdiffstats
path: root/perl-install/detect_devices.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/detect_devices.pm')
-rw-r--r--perl-install/detect_devices.pm272
1 files changed, 171 insertions, 101 deletions
diff --git a/perl-install/detect_devices.pm b/perl-install/detect_devices.pm
index 5e573574d..2361f3f9d 100644
--- a/perl-install/detect_devices.pm
+++ b/perl-install/detect_devices.pm
@@ -34,7 +34,7 @@ sub get() {
getIDE(), getSCSI(), getDAC960(), getCompaqSmartArray(), getATARAID();
}
-sub hds() { grep { $_->{media_type} eq 'hd' && !isRemovableDrive($_) } get() }
+sub hds() { grep { may_be_a_hd($_) } get() }
sub tapes() { grep { $_->{media_type} eq 'tape' } get() }
sub cdroms() { grep { $_->{media_type} eq 'cdrom' } get() }
sub burners() { grep { isBurner($_) } cdroms() }
@@ -52,7 +52,7 @@ sub zips() {
sub floppies() {
require modules;
- eval { modules::load("floppy") };
+ eval { modules::load("floppy") } if $::isInstall;
my @fds = $@ ? () : map {
my $info = (!dev_is_devfs() || -e "/dev/fd$_") && c::floppy_info(devices::make("fd$_"));
if_($info && $info ne '(null)', { device => "fd$_", devfs_device => "floppy/$_", media_type => 'fd', info => $info })
@@ -175,12 +175,26 @@ sub isDvdDrive {
sub isZipDrive { $_[0]{info} =~ /ZIP\s+\d+/ } #- accept ZIP 100, untested for bigger ZIP drive.
sub isJazzDrive { $_[0]{info} =~ /\bJAZZ?\b/i } #- accept "iomega jaz 1GB"
sub isLS120Drive { $_[0]{info} =~ /LS-?120|144MB/ }
-sub isRemovableUsb { $_[0]{usb_media_type} && index($_[0]{usb_media_type}, 'Mass Storage') == 0 && usb2removable($_[0]) }
-sub isKeyUsb { $_[0]{usb_media_type} && index($_[0]{usb_media_type}, 'Mass Storage') == 0 && $_[0]{media_type} eq 'hd' }
+sub isRemovableUsb { begins_with($_[0]{usb_media_type} || '', 'Mass Storage') && usb2removable($_[0]) }
+sub isKeyUsb { begins_with($_[0]{usb_media_type} || '', 'Mass Storage') && $_[0]{media_type} eq 'hd' }
sub isFloppyUsb { $_[0]{usb_driver} && $_[0]{usb_driver} eq 'Removable:floppy' }
-sub isRemovableDrive {
+sub may_be_a_hd {
my ($e) = @_;
- isZipDrive($e) || isLS120Drive($e) || $e->{media_type} && $e->{media_type} eq 'fd' || isRemovableUsb($e) || $e->{usb_media_type} && index($e->{usb_media_type}, 'Mass Storage|Floppy (UFI)') == 0;
+ $e->{media_type} eq 'hd' && !(
+ isZipDrive($e)
+ || isLS120Drive($e)
+ || begins_with($e->{usb_media_type} || '', 'Mass Storage|Floppy (UFI)')
+ );
+}
+
+sub get_scsi_driver {
+ my (@l) = @_;
+ my %host2driver = map { if_(m!.*/(.*)/(.*)!, $2, $1) } glob("/proc/scsi/*/*");
+ foreach (@l) {
+ if (my $driver = $host2driver{$_->{host}}) {
+ $_->{driver} = $driver;
+ }
+ }
}
sub getSCSI_24() {
@@ -222,6 +236,7 @@ sub getSCSI_24() {
get_devfs_devices(@l);
get_sys_cdrom_info(@l);
+ get_scsi_driver(@l);
@l;
}
@@ -270,6 +285,8 @@ sub getSCSI_26() {
};
} all($dev_dir);
+ @l = sort { $a->{host} <=> $b->{host} || $a->{channel} <=> $b->{channel} || $a->{id} <=> $b->{id} || $a->{lun} <=> $b->{lun} } @l;
+
complete_usb_storage_info(@l);
foreach (@l) {
@@ -278,6 +295,7 @@ sub getSCSI_26() {
get_devfs_devices(@l);
get_sys_cdrom_info(@l);
+ get_scsi_driver(@l);
@l;
}
sub getSCSI() { c::kernel_version() =~ /^\Q2.6/ ? getSCSI_26() : getSCSI_24() }
@@ -344,6 +362,12 @@ sub getIDE() {
@idi;
}
+sub block_devices() {
+ -d '/sys/block'
+ ? map { s|!|/|; $_ } all('/sys/block')
+ : map { $_->{dev} } devices::read_proc_partitions_raw();
+}
+
sub getCompaqSmartArray() {
my (@idi, $f);
@@ -353,12 +377,14 @@ sub getCompaqSmartArray() {
my ($name) = m|/(.*)|;
for (my $i = 0; -r ($f = "${prefix}$i"); $i++) {
- foreach (cat_($f)) {
- if (my ($raw_device) = m|^\s*($name/.*?):|) {
- my $device = -d "/dev/$raw_device" ? "$raw_device/disc" : $raw_device;
- push @idi, { device => $device, prefix => $raw_device . 'p', info => "Compaq RAID logical disk",
- media_type => 'hd', bus => 'ida' };
- }
+ my @raw_devices = cat_($f) =~ m|^\s*($name/.*?):|gm;
+ @raw_devices or @raw_devices = grep { m!^$name/! } block_devices();
+
+ foreach my $raw_device (@raw_devices) {
+ my $device = -d "/dev/$raw_device" ? "$raw_device/disc" : $raw_device;
+ push @idi, { device => $device, prefix => $raw_device . 'p',
+ info => "Compaq RAID logical disk",
+ media_type => 'hd', bus => $name };
}
}
}
@@ -412,7 +438,7 @@ sub getCPUs() {
}
sub getSoundDevices() {
- (arch() =~ /ppc/ ? \&modules::load_category : \&modules::probe_category)->('multimedia/sound');
+ modules::probe_category('multimedia/sound');
}
sub isTVcard { member($_[0]{driver}, qw(bttv cx8800 saa7134 usbvision)) }
@@ -421,8 +447,29 @@ sub getTVcards() {
grep { isTVcard($_) } detect_devices::probeall();
}
+sub getInputDevices() {
+ my (@devices, $device);
+ foreach (cat_('/proc/bus/input/devices')) {
+ if (/^I:/) {
+ push @devices, $device if $device;
+ $device = {};
+ $device->{vendor} = $1 if /Vendor=([0-9a-f]+)/;
+ $device->{id} = $1 if /Product=([0-9a-f]+)/;
+ }
+ $device->{description} = "|$1" if /N: Name="(.*)"/;
+ $device->{driver} = $1 if /H: Handlers=(\w+)/;
+ if (/P: Phys=(.*)/) {
+ $device->{location} = $1;
+ $device->{bus} = 'isa' if $device->{location} =~ /^isa/;
+ $device->{bus} = 'usb' if $device->{location} =~ /^usb/i;
+ }
+ }
+ push @devices, $device if $device;
+ @devices;
+}
+
sub getSerialModem {
- my ($o_mouse) = @_;
+ my ($modules_conf, $o_mouse) = @_;
my $mouse = $o_mouse || {};
$mouse->{device} = readlink "/dev/mouse";
my $serdev = arch() =~ /ppc/ ? "macserial" : "serial";
@@ -441,14 +488,16 @@ sub getSerialModem {
my @devs = pcmcia_probe();
foreach my $modem (@modems) {
#- add an alias for macserial on PPC
- modules::set_alias('serial', $serdev) if arch() =~ /ppc/ && $modem->{device};
+ $modules_conf->set_alias('serial', $serdev) if arch() =~ /ppc/ && $modem->{device};
foreach (@devs) { $_->{type} =~ /serial/ and $modem->{device} = $_->{device} }
}
@modems;
}
-sub getModem() {
- getSerialModem({}), matching_driver('www\.linmodems\.org');
+sub getModem {
+ my ($modules_conf) = @_;
+ getSerialModem($modules_conf, {}), matching_driver__regexp('www\.linmodems\.org'),
+ matching_driver('ltmodem', list_modules::category2modules('network/slmodem'));
}
sub getSpeedtouch() {
@@ -456,11 +505,10 @@ sub getSpeedtouch() {
}
sub getBewan() {
- grep { $_->{description} =~ /Bewan Systems\|PCI ADSL Modem|BEWAN ADSL USB/ } probeall();
-
+ matching_desc__regexp('Bewan Systems\|.*ADSL|BEWAN ADSL USB');
}
sub getSagem() {
- grep { member($_->{driver}, qw(adiusbadsl eagle-usb)) } probeall();
+ matching_driver(qw(adiusbadsl eagle-usb));
}
# generate from the following from eci driver sources:
@@ -511,7 +559,7 @@ sub getNet() {
grep { !/^(?:lo|ippp|isdn|plip|ppp|sit0)/ }
uniq(
- (map { if_(/^\s*([A-Za-z0-9:\.]*):\s/, $1) } cat_("/proc/net/dev")),
+ (map { if_(/^\s*([A-Za-z0-9:\.]*):/, $1) } cat_("/proc/net/dev")),
c::get_netdevices(),
);
}
@@ -520,29 +568,27 @@ sub getNet() {
# mapgrep(sub {member (($_[0] =~ /\s*(\w*):/), @netdevices), $1 }, split(/\n/, cat_("/proc/net/dev")));
#}
-# heavily inspirated from hidups driver from nut:
sub getUPS() {
- # nut/driver/hidups.h:
- my $UPS_USAGE = 0x840004;
- my $POWER_USAGE = 0x840020;
- my $hiddev_find_application = sub {
- my ($fd, $usage) = @_;
- my $i = 0;
- my $ret;
- do { $i++ } while ($ret = ioctl($fd, c::HIDIOCAPPLICATION(), $i)) && $ret != $usage;
- return $ret == $usage ? 1 : 0;
- };
-
- (map { $_->{driver} = "mge-shut"; $_ } grep { $_->{DESCRIPTION} =~ /MGE UPS/ } values %serialprobe),
+ # MGE serial PnP devices:
+ my @usb_devices = map { ($_->{name} = $_->{description}) =~ s/.*\|//; $_ } usb_probe();
+
(map {
- open(my $f, $_);
- if_(!$hiddev_find_application->($f, $UPS_USAGE) && !$hiddev_find_application->($f, $POWER_USAGE),
- { port => $_,
- name => c::get_usb_ups_name(fileno($f)),
- driver => "hidups",
- }
- );
- } -e "/dev/.devfsd" ? glob("/dev/usb/hid/hiddev*") : glob("/dev/usb/hiddev*"));
+ $_->{port} = $_->{DEVICE};
+ $_->{bus} = "Serial";
+ $_->{driver} = "mge-utalk" if $_->{MODEL} =~ /0001/;
+ $_->{driver} = "mge-shut" if $_->{MODEL} =~ /0002/;
+ $_->{media_type} = 'UPS';
+ $_->{description} = "MGE UPS SYSTEMS|UPS - Uninterruptible Power Supply" if $_->{MODEL} =~ /000[12]/;
+ $_;
+ } grep { $_->{DESCRIPTION} =~ /MGE UPS/ } values %serialprobe),
+ # USB UPSs;
+ (grep { $_->{description} =~ /American Power Conversion\|Back-UPS/ } @usb_devices),
+ (map {
+ $_->{port} = "auto";
+ $_->{media_type} = 'UPS';
+ $_->{driver} = 'newhidups';
+ $_;
+ } grep { $_->{driver} =~ /ups$/ } @usb_devices);
}
$pcitable_addons = <<'EOF';
@@ -609,7 +655,19 @@ sub usb_probe() {
}
sub firewire_probe() {
- my ($e, @l);
+ my $dev_dir = '/sys/bus/ieee1394/devices';
+ my @l = map {
+ my $dir = "$dev_dir/$_";
+ my $get = sub { chomp_(cat_($_[0])) };
+ {
+ version => hex($get->("$dir/../vendor_id")),
+ specifier_id => hex($get->("$dir/specifier_id")),
+ specifier_version => hex($get->("$dir/version")),
+ bus => 'Firewire',
+ }
+ } grep { -f "$dev_dir/$_/specifier_id" } all($dev_dir);
+
+ my $e;
foreach (cat_('/proc/bus/ieee1394/devices')) {
if (m!Vendor/Model ID: (.*) \[(\w+)\] / (.*) \[(\w+)\]!) {
push @l, $e = {
@@ -623,14 +681,23 @@ sub firewire_probe() {
$e->{specifier_version} = hex $1;
}
}
+
foreach (@l) {
- if ($e->{specifier_id} == 0x00609e && $e->{specifier_version} == 0x010483) {
+ if ($_->{specifier_id} == 0x00609e && $_->{specifier_version} == 0x010483) {
add2hash($_, { driver => 'sbp2', description => "Generic Firewire Storage Controller" });
+ } elsif ($_->{specifier_id} == 0x00005e && $_->{specifier_version} == 0x000001) {
+ add2hash($_, { driver => 'eth1394', description => "IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)" });
}
}
@l;
}
+sub real_pcmcia_probe() {
+ return if $::testing;
+
+ c::pcmcia_probe() || (find { $_->{driver} eq 'yenta_socket' } pci_probe()) && 'yenta_socket';
+}
+
sub pcmcia_probe() {
-e '/var/run/stab' || -e '/var/lib/pcmcia/stab' or return ();
@@ -654,14 +721,20 @@ sub probeall() {
require sbus_probing::main;
pci_probe(), usb_probe(), firewire_probe(), pcmcia_probe(), sbus_probing::main::probe();
}
-sub matching_desc {
+sub matching_desc__regexp {
my ($regexp) = @_;
grep { $_->{description} =~ /$regexp/i } probeall();
}
-sub matching_driver {
+sub matching_driver__regexp {
my ($regexp) = @_;
grep { $_->{driver} =~ /$regexp/i } probeall();
}
+
+sub matching_driver {
+ my (@list) = @_;
+ grep { member($_->{driver}, @list) } probeall();
+}
+
sub stringlist() {
map {
sprintf("%-16s: %s%s%s",
@@ -715,19 +788,60 @@ sub hasSMP() {
}
sub hasPCMCIA() { $::o->{pcmcia} } #- because /proc/pcmcia seems not to be present on 2.4 at least (or use /var/run/stab)
+sub dmidecode() {
+ my (%l, $cat);
+
+ my $dmidecode_infos if 0;
+
+ if (!$dmidecode_infos) {
+ foreach (run_program::get_stdout('dmidecode')) {
+ if (/^\t\t(.*)/) {
+ $l{$cat} .= "$1\n";
+ } elsif (my ($s) = /^\t(.*)/) {
+ next if $s =~ /^DMI type /;
+ $s =~ s/ Information$//;
+ $cat = $s;
+ }
+ }
+ my $Chassis = $l{Chassis} =~ /^Type:\s*(\S+)/m && $1;
+ my $BIOS_Year = $l{BIOS} =~ m!^Release Date:.*?(\d{4})!m && $1 ||
+ $l{BIOS} =~ m!^Release Date:.*?\d\d/\d\d/(\d\d)!m && "20$1";
+
+ $dmidecode_infos = {
+ isLaptop => member($Chassis, 'Portable', 'Laptop', 'Notebook', 'Sub Notebook', 'Docking Station'),
+ if_($BIOS_Year, BIOS_Year => $BIOS_Year),
+ };
+ }
+ $dmidecode_infos;
+}
+
#- 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() {
- hasPCMCIA() || (matching_desc('C&T.*655[45]\d') || matching_desc('C&T.*68554') ||
- matching_desc('Neomagic.*Magic(Media|Graph)') ||
- matching_desc('ViRGE.MX') || matching_desc('S3.*Savage.*[IM]X') ||
- matching_desc('ATI.*(Mobility|LT)'))
- || cat_('/proc/cpuinfo') =~ /\bmobile\b/i;
+ arch() =~ /ppc/ ?
+ get_mac_model() =~ /Book/ :
+ dmidecode()->{isLaptop}
+ || (matching_desc__regexp('C&T.*655[45]\d') || matching_desc__regexp('C&T.*68554') ||
+ matching_desc__regexp('Neomagic.*Magic(Media|Graph)') ||
+ matching_desc__regexp('ViRGE.MX') || matching_desc__regexp('S3.*Savage.*[IM]X') ||
+ matching_desc__regexp('ATI.*(Mobility|LT)'))
+ || cat_('/proc/cpuinfo') =~ /\bmobile\b/i;
+}
+
+sub is_i586() {
+ my $cpuinfo = cat_('/proc/cpuinfo');
+ $cpuinfo =~ /^cpu family\s*:\s*(\d+)/m && $1 < 6 ||
+ $cpuinfo !~ /^flags.*\bcmov\b/m;
+}
+
+sub matching_type {
+ my ($type) = @_;
+ $type =~ /laptop/i && isLaptop();
}
-sub usbMice() { grep { $_->{media_type} =~ /\|Mouse/ && $_->{driver} !~ /Tablet:wacom/ ||
+sub usbMice() { grep { $_->{media_type} =~ /\|Mouse/ && $_->{driver} !~ /wacom/ ||
$_->{driver} =~ /Mouse:USB/ } usb_probe() }
-sub usbWacom() { grep { $_->{driver} =~ /Tablet:wacom/ } usb_probe() }
+sub usbWacom() { grep { $_->{driver} =~ /wacom/ } usb_probe() }
sub usbKeyboards() { grep { $_->{media_type} =~ /\|Keyboard/ } usb_probe() }
sub usbStorage() { grep { $_->{media_type} =~ /Mass Storage\|/ } usb_probe() }
@@ -785,49 +899,6 @@ sub hasMousePS2 {
my $t; sysread(tryOpen($_[0]) || return, $t, 256) != 1 || $t ne "\xFE";
}
-sub raidAutoStartIoctl() {
- sysopen(my $F, devices::make("md0"), 2) or return;
- ioctl $F, 0x914, 0; #- RAID_AUTORUN
-}
-
-sub raidAutoStartRaidtab {
- my (@parts) = @_;
- $::isInstall or return;
- require raid;
- #- faking a raidtab, it seems to be working :-)))
- #- (choosing any inactive md)
- raid::inactivate_all();
- my $detect_one = sub {
- my ($device) = @_;
- my $free_md = devices::make(find { !raid::is_active($_) } map { "md$_" } 0 .. raid::max_nb());
- output("/tmp/raidtab", "raiddev $free_md\n device " . devices::make($device) . "\n");
- log::l("raidAutoStartRaidtab: trying $device");
- run_program::run('raidstart', '-c', "/tmp/raidtab", $free_md);
- };
- $detect_one->($_->{device}) foreach @parts;
-
- #- try again to detect RAID 10
- $detect_one->($_) foreach raid::active_mds();
-
- unlink "/tmp/raidtab";
-}
-
-sub raidAutoStart {
- my (@parts) = @_;
-
- log::l("raidAutoStart");
- eval { modules::load('md') };
- my %personalities = ('1' => 'linear', '2' => 'raid0', '3' => 'raid1', '4' => 'raid5');
- raidAutoStartIoctl() or raidAutoStartRaidtab(@parts);
- foreach (1..2) { #- try twice for RAID 10
- my @needed_perso = map {
- if_(/^kmod: failed.*md-personality-(.)/ ||
- /^md: personality (.) is not loaded/, $personalities{$1}) } syslog() or last;
- eval { modules::load(@needed_perso) };
- raidAutoStartIoctl() or raidAutoStartRaidtab(@parts);
- }
-}
-
sub usb_description2removable {
local ($_) = @_;
return 'camera' if /\bcamera\b/i;
@@ -854,13 +925,12 @@ sub suggest_mount_point {
my ($e) = @_;
my $name = $e->{media_type};
- if (member($name, 'hd', 'fd')) {
+ if (member($e->{media_type}, 'hd', 'fd')) {
if (exists $e->{usb_driver}) {
- return usb2removable($e) || 'removable';
- }
- if (isZipDrive($e)) {
+ $name = usb2removable($e) || 'removable';
+ } elsif (isZipDrive($e)) {
$name = 'zip';
- } elsif ($name eq 'fd') {
+ } elsif ($e->{media_type} eq 'fd') {
$name = 'floppy';
} else {
log::l("suggest_mount_point: don't know what to with hd $e->{device}");