package detect_devices; # $Id: detect_devices.pm 267151 2010-03-30 14:27:41Z blino $
use diagnostics;
use strict;
use vars qw($pcitable_addons $usbtable_addons);
#-######################################################################################
#- misc imports
#-######################################################################################
use log;
use MDK::Common; # help perl_checker
use common;
use devices;
use run_program;
use modules;
use c;
use feature 'state';
#-#####################################################################################
#- Globals
#-#####################################################################################
my %serialprobe;
#-######################################################################################
#- Functions
#-######################################################################################
sub get() {
#- Detect the default BIOS boot harddrive is kind of tricky. We may have IDE,
#- SCSI and RAID devices on the same machine. From what I see so far, the default
#- BIOS boot harddrive will be
#- 1. The first IDE device if IDE exists. Or
#- 2. The first SCSI device if SCSI exists. Or
#- 3. The first RAID device if RAID exists.
getIDE(), getSCSI(), getVirtIO(), getDAC960(), getCompaqSmartArray(), getATARAID();
}
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() }
sub dvdroms() { grep { isDvdDrive($_) } cdroms() }
sub raw_zips() { grep { member($_->{media_type}, 'fd', 'hd') && isZipDrive($_) } get() }
sub ls120s() { grep { member($_->{media_type}, 'fd', 'hd') && isLS120Drive($_) } get() }
sub zips() {
map {
$_->{device} .= 4;
$_;
} raw_zips();
}
sub floppies {
my ($o_not_detect_legacy_floppies) = @_;
require modules;
state @fds;
state $legacy_already_detected;
if (arch() =~ /mips|arm/) {
$o_not_detect_legacy_floppies = 1;
}
if (!$o_not_detect_legacy_floppies && !$legacy_already_detected) {
$legacy_already_detected = 1;
eval { modules::load("floppy") if $::isInstall };
#- do not bother probing /dev/fd0 and loading floppy device uselessly,
#- it takes time and it is already done by boot process (if not in install):
#- /dev/fd0 is created by start_udev (/etc/udev/devices.d/default.nodes)
#- then hal probes /dev/fd0 and triggers floppy module loading through kernel's kmod
if (any { (split)[1] eq 'fd' } cat_("/proc/devices")) {
@fds = map {
my $info = c::floppy_info(devices::make("fd$_"));
if_($info && $info ne '(null)', { device => "fd$_", media_type => 'fd', info => $info });
} qw(0 1);
}
}
my @ide = ls120s() and eval { modules::load("ide_floppy") };
eval { modules::load("usb_storage") } if $::isInstall && usbStorage();
my @scsi = grep { $_->{media_type} eq 'fd' } getSCSI();
@ide, @scsi, @fds;
}
sub floppies_dev() { map { $_->{device} } floppies() }
sub floppy() { first(floppies_dev()) }
#- example ls120, model = "LS-120 SLIM 02 UHD Floppy"
sub removables() {
floppies(), cdroms(), zips();
}
sub get_sys_cdrom_info {
my (@drives) = @_;
my @drives_order;
foreach (cat_("/proc/sys/dev/cdrom/info")) {
my ($t, $l) = split ':';
my @l;
@l = split(' ', $l) if $l;
if ($t eq 'drive name') {
@drives_order = map {
my $dev = $_;
find { $_->{device} eq $dev } @drives;
} @l;
} else {
my $capacity;
if ($t eq 'Can write CD-R') {
$capacity = 'burner';
} elsif ($t eq 'Can read DVD') {
$capacity = 'DVD';
}
if ($capacity) {
each_index {
($drives_order[$::i] || {})->{capacity} .= "$capacity " if $_;
} @l;
}
}
}
}
sub complete_usb_storage_info {
my (@l) = @_;
my @usb = grep { exists $_->{usb_vendor} } @l;
foreach my $usb (usb_probe()) {
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) {
my $file = "/sys/block/$host/../serial";
$e->{info} = chomp_(cat_($file)) if -e $file;
$e->{usb_description} = join('|',
chomp_(cat_("/sys/block/$host/../manufacturer")),
chomp_(cat_("/sys/block/$host/../product")));
}
local $e->{found} = 1;
$e->{"usb_$_"} ||= $usb->{$_} foreach keys %$usb;
}
}
}
sub isBurner {
my ($e) = @_;
$e->{capacity} =~ /burner/ and return 1;
#- do not work for SCSI
my $f = tryOpen($e->{device}); #- SCSI burner are not detected this way.
$f && c::isBurner(fileno($f));
}
sub isDvdDrive {
my ($e) = @_;
$e->{capacity} =~ /DVD/ || $e->{info} =~ /DVD/ and return 1;
#- do not work for SCSI
my $f = tryOpen($e->{device});
$f && c::isDvdDrive(fileno($f));
}
sub isZipDrive { $_[0]{info} =~ /ZIP\s+\d+/ } #- accept ZIP 100, untested for bigger ZIP drive.
sub isLS120Drive { $_[0]{info} =~ /LS-?120|144MB/ }
|