package detect_devices; # $Id$ use diagnostics; use strict; use vars qw($pcitable_addons $usbtable_addons); #-###################################################################################### #- misc imports #-###################################################################################### use log; use common; use devices; use run_program; use modules; use c; #-##################################################################################### #- 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(), 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; my @fds; if (!$o_not_detect_legacy_floppies) { eval { modules::load("floppy") if $::isInstall }; if (!is_xbox()) { @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) { $e->{info} = chomp_(cat_("/sys/block/$e->{device}/$host/../serial")); $e->{usb_description} = join('|', chomp_(cat_("/sys/block/$e->{device}/$host/../manufacturer")), chomp_(cat_("/sys/block/$e->{device}/$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/ } 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 may_be_a_hd { my ($e) = @_; $e->{media_type} eq 'hd' && !( isZipDrive($e) || isLS120Drive($e) || begins_with($e->{usb_media_type} || '', 'Mass Storage|Floppy (UFI)') ); } sub get_sysfs_field_from_link { my ($device, $field) = @_; my $l = readlink("$device/$field"); $l =~ s!.*/!!; $l; } sub get_sysfs_usbpath_for_block { my ($device) = @_; my $host = readlink("/sys/block/$device/device"); $host =~ s!/host.*!!; $host; } sub get_scsi_driver { my (@l) = @_; # find driver of host controller from sysfs: foreach (@l) { next if $_->{driver}; my $host = get_sysfs_usbpath_for_block($_->{device}); $_->{driver} = get_sysfs_field_from_link("/sys/block/$_->{device}/$host", 'driver'); } } sub getSCSI() { my $dev_dir = '/sys/bus/scsi/devices'; my @scsi_types = ( "Direct-Access", "Sequential-Access", "Printer", "Processor", "WORM", "CD-ROM", "Scanner", "Optical Device", "Medium Changer", "Communications", ); my @l; foreach (all($dev_dir)) { my ($host, $channel, $id, $lun) = split ':' or log::l("bad entry in $dev_dir: $_"), next; my $dir = "$dev_dir/$_"; # handle both old and new kernels: my $node = -e "$dir/block" ? "$dir/block" : top(glob_("$dir/block*")); my ($device) = readlink($node) =~ m!/block/(.*)!; warn("cannot get info for device ($_)"), next if !$device; my $usb_dir = readlink("$node/device") =~ m!/usb! && "$node/device/../../../.."; my $get_usb = sub { chomp_(cat_("$usb_dir/$_[0]")) }; my $get = sub { my $s = cat_("$dir/$_[0]"); $s =~ s/\s+$//; $s; }; # Old hp scanners report themselves as "Processor"s # (see linux/include/scsi/scsi.h and sans-find-scanner.1) my $raw_type = $scsi_types[$get->('type')]; my $media_type = ${{ st => 'tape', sr => 'cdrom', sd => 'hd' }}{substr($device, 0, 2)} || $raw_type =~ /Scanner|Processor/ && 'scanner'; push @l, { info => $get->('vendor') . ' ' . $get->('model'), host => $host, channel => $channel, id => $id, lun => $lun, bus => 'SCSI', media_type => $media_type, device => $device, $usb_dir ? ( usVarius fixes to css and js for correct displaying permission role combbox in RTL mode PHPBB3-15492