<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package modules;



use common qw(:common :file :system);
use detect_devices;
use run_program;
use log;


my %conf;
my %loaded; 
my $scsi = 0;
my %deps = ();

my @drivers_by_category = (
[ 'net', {
  "3c509" =&gt; "3com 3c509",
  "3c501" =&gt; "3com 3c501",
  "3c503" =&gt; "3com 3c503",
  "3c505" =&gt; "3com 3c505",
  "3c507" =&gt; "3com 3c507",
  "3c515" =&gt; "3com 3c515",
  "3c59x" =&gt; "3com 3c59x (Vortex)",
  "3c59x" =&gt; "3com 3c90x (Boomerang)",
  "3c90x" =&gt; "3Com 3c90x (Cyclone/Hurricane/Tornado)",
  "at1700" =&gt; "Allied Telesis AT1700",
  "ac3200" =&gt; "Ansel Communication AC3200",
  "acenic" =&gt; "AceNIC Gigabit Ethernet",
  "pcnet32" =&gt; "AMD PC/Net 32",
  "82596" =&gt; "Apricot 82596",
#  "atp" =&gt; "ATP", # builtin the kernel
  "cs89x0" =&gt; "CS89x0",
  "de4x5" =&gt; "Digital 425,434,435,450,500",
  "depca" =&gt; "Digital DEPCA and EtherWORKS",
  "e2100" =&gt; "Cabletron E2100",
  "ewrk3" =&gt; "Digital EtherWORKS 3",
  "old_tulip" =&gt; "Digital 21040/21041/21140 (old Tulip driver)",
  "tulip" =&gt; "Digital 21040/21041/21140 (Tulip)",
  "de600" =&gt; "D-Link DE-600 pocket adapter",
  "de620" =&gt; "D-Link DE-620 pocket adapter",
  "dgrs" =&gt; "Digi International RightSwitch",
  "epic100" =&gt; "EPIC 100",
  "hp100" =&gt; "HP10/100VG any LAN ",
  "hp" =&gt; "HP LAN/AnyLan",
  "hp-plus" =&gt; "HP PCLAN/plus",
  "eth16i" =&gt; "ICL EtherTeam 16i",
  "eexpress" =&gt; "Intel EtherExpress",
  "eepro" =&gt; "Intel EtherExpress Pro",
  "eepro100" =&gt; "Intel EtherExpress Pro 100",
  "lance" =&gt; "Lance",
  "lne390" =&gt; "Mylex LNE390",
  "ne" =&gt; "NE2000 and compatible",
  "ne2k-pci" =&gt; "NE2000 PCI",
  "ne3210" =&gt; "NE3210",
  "ni5010" =&gt; "NI 5010",
  "ni52" =&gt; "NI 5210",
  "ni65" =&gt; "NI 6510",
  "rtl8139" =&gt; "RealTek RTL8129/8139",
  "es3210" =&gt; "Racal-Interlan ES3210",
#  "rcpci" =&gt; "RedCreek Virtual Private Network", # TODO
  "epic100" =&gt; "SMC 83c170 EPIC/100",
  "sktr" =&gt; "Syskonnect Token ring adaptor",
  "smc9194" =&gt; "SMC 9000 series",
  "smc-ultra" =&gt; "SMC Ultra",
  "smc-ultra32" =&gt; "SMC Ultra 32",
#  "sunhme" =&gt; "Sun Happy Meal", # not there anymore?
  "tlan" =&gt; "Compaq Netelligent",
  "via-rhine" =&gt; "VIA Rhine",
#  "wavelan" =&gt; "AT&amp;T WaveLAN &amp; DEC RoamAbout DS", # TODO
  "wd" =&gt; "WD8003, WD8013 and compatible",
  "yellowfin" =&gt; "Symbios Yellowfin G-NIC",

  "8390" =&gt; "8390",
  "dmfe" =&gt; "dmfe",
  "dummy" =&gt; "dummy",
  "fmv18x" =&gt; "fmv18x",
  "ibmtr" =&gt; "Token Ring Tropic",
  "olympic" =&gt; "olympic",
  "plip" =&gt; "PLIP (parallel port)",
  "rl100a" =&gt; "rl100a",
  "sb1000" =&gt; "sb1000",
  "sbni" =&gt; "sbni",
  "sis900" =&gt; "sis900",
  "nfs" =&gt; "Network File System (nfs)",
  "lockd" =&gt; "lockd",
  "sunrpc" =&gt; "sunrpc",
}],
[ 'scsi', {
  "aha152x" =&gt; "Adaptec 152x",
  "aha1542" =&gt; "Adaptec 1542",
  "aha1740" =&gt; "Adaptec 1740",
  "aic7xxx" =&gt; "Adaptec 2740, 2840, 2940",
  "advansys" =&gt; "AdvanSys Adapters",
  "in2000" =&gt; "Always IN2000",
  "AM53C974" =&gt; "AMD SCSI",
  "BusLogic" =&gt; "BusLogic Adapters",
  "dtc" =&gt; "DTC 3180/3280",
  "seagate" =&gt; "Future Domain TMC-885, TMC-950",
  "fdomain" =&gt; "Future Domain TMC-16x0",
  "initio" =&gt; "Initio",
  "g_NCR5380" =&gt; "NCR 5380",
  "NCR53c406a" =&gt; "NCR 53c406a",
  "53c7,8xx" =&gt; "NCR 53c7xx",
  "ncr53c8xx" =&gt; "NCR 53C8xx PCI",
#  "pci2000" =&gt; "Perceptive Solutions PCI-2000", # TODO
  "qlogicfas" =&gt; "Qlogic FAS",
  "qlogicisp" =&gt; "Qlogic ISP",
  "seagate" =&gt; "Seagate ST01/02",
  "sym53c8xx" =&gt; "Symbios 53c8xx",
  "t128" =&gt; "Trantor T128/T128F/T228",
  "u14-34f" =&gt; "UltraStor 14F/34F",
  "ultrastor" =&gt; "UltraStor 14F/24F/34F",
  "wd7000" =&gt; "Western Digital wd7000",

  "a100u2w" =&gt; "a100u2w",
  "atp870u" =&gt; "atp870u (Acard/Artop)",
  "dc395x_trm" =&gt; "dc395x_trm",
  "psi240i" =&gt; "psi240i",
  "qlogicfc" =&gt; "qlogicfc",
  "sim710" =&gt; "sim710",
  "sym53c416" =&gt; "sym53c416",
  "tmscsim" =&gt; "tmscsim",
}],
[ 'disk', {
  "DAC960" =&gt; "Mylex DAC960",
#  "dpt" =&gt; "Distributed Tech SmartCache/Raid I-IV Controller", # not there anymore?
  "megaraid" =&gt; "AMI MegaRAID",
  "cpqarray" =&gt; "Compaq Smart-2/P RAID Controller",
  "gdth" =&gt; "ICP Disk Array Controller",
  "ips" =&gt; "IBM ServeRAID controller",
  "eata" =&gt; "EATA SCSI PM2x24/PM3224",
  "eata_pio" =&gt; "EATA PIO Adapters",
  "eata_dma" =&gt; "EATA DMA Adapters",
  "ppa" =&gt; "Iomega PPA3 (parallel port Zip)",
  "imm" =&gt; "Iomega Zip (new driver)",
}],
[ 'cdrom', {
  "sbpcd" =&gt; "SoundBlaster/Panasonic",
  "aztcd" =&gt; "Aztech CD",
  "gscd" =&gt; "Goldstar R420",
  "isp16" =&gt; "ISP16/MAD16/Mozart",

  "mcdx" =&gt; "Mitsumi (alternate)",
  "optcd" =&gt; "Optics Storage 8000",
  "cm206" =&gt; "Phillips CM206/CM260",
  "sjcd" =&gt; "Sanyo",
  "cdu31a" =&gt; "Sony CDU-31A",
  "sonycd535" =&gt; "Sony CDU-5xx",
  "isofs" =&gt; "iso9660",
  "ide-cd" =&gt; "ide-cd",
}],
[ 'sound', {
  "alsa" =&gt; "ALSA sound module, many sound cards",
  "cmpci" =&gt; "C-Media Electronics CMI8338A CMI8338B CMI8738",
  "es1370" =&gt; "Ensoniq ES1370 [AudioPCI]",
  "es1371" =&gt; "Ensoniq ES1371 [AudioPCI-97]",
  "esssolo1" =&gt; "ESS Technology ES1969 Solo-1 Audiodrive",
  "maestro" =&gt; "Maestro",
  "nm256" =&gt; "Neomagic MagicMedia 256AV",
  "pas16" =&gt; "Pro Audio Spectrum/Studio 16",
  "via82cxxx" =&gt; "VIA VT82C686_5",
  "sonicvibes" =&gt; "S3 SonicVibes",
}],
[ 'pcmcia', {
  "ide_cs" =&gt; "ide_cs",
  "fmvj18x_cs" =&gt; "fmvj18x_cs",
  "fdomain_cs" =&gt; "fdomain_cs",
  "netwave_cs" =&gt; "netwave_cs",
  "serial_cs" =&gt; "serial_cs",
  "wavelan_cs" =&gt; "wavelan_cs",
  "pcnet_cs" =&gt; "pcnet_cs",
  "aha152x_cs" =&gt; "aha152x_cs",
  "xirc2ps_cs" =&gt; "xirc2ps_cs",
  "3c574_cs" =&gt; "3c574_cs",
  "qlogic_cs" =&gt; "qlogic_cs",
  "nmclan_cs" =&gt; "nmclan_cs",
  "ibmtr_cs" =&gt; "ibmtr_cs",
  "dummy_cs" =&gt; "dummy_cs",
  "memory_cs" =&gt; "memory_cs",
  "ftl_cs" =&gt; "ftl_cs",
  "smc91c92_cs" =&gt; "smc91c92_cs",
  "3c589_cs" =&gt; "3c589_cs",
  "parport_cs" =&gt; "parport_cs", 
  "3c575_cb" =&gt; "3c575_cb",
  "apa1480_cb" =&gt; "apa1480_cb",
  "cb_enabler" =&gt; "cb_enabler",
  "epic_cb" =&gt; "epic_cb",
  "iflash2+_mtd" =&gt; "iflash2+_mtd",
  "iflash2_mtd" =&gt; "iflash2_mtd",
  "memory_cb" =&gt; "memory_cb",
  "serial_cb" =&gt; "serial_cb",
  "sram_mtd" =&gt; "sram_mtd",
  "tulip_cb" =&gt; "tulip_cb",

}],
[ 'pcmcia_everywhere', {
  "pcmcia_core" =&gt; "PCMCIA core support",
  "tcic" =&gt; "PCMCIA tcic controller",
  "ds" =&gt; "PCMCIA card support",
  "i82365" =&gt; "PCMCIA i82365 controller",
}],
[ 'paride', {
  "aten" =&gt; "ATEN EH-100",
  "bpck" =&gt; "Microsolutions backpack",
  "comm" =&gt; "DataStor (older type) commuter adapter",
  "dstr" =&gt; "DataStor EP-2000",
  "epat" =&gt; "Shuttle EPAT",
  "epia" =&gt; "Shuttle EPIA",
  "fit2" =&gt; "Fidelity Intl. (older type)",
  "fit3" =&gt; "Fidelity Intl. TD-3000",
  "frpw" =&gt; "Freecom Power",
  "friq" =&gt; "Freecom IQ (ASIC-2)",
  "kbic" =&gt; "KingByte KBIC-951A and KBIC-971A",
  "ktti" =&gt; "KT Tech. PHd",
  "on20" =&gt; "OnSpec 90c20",
  "on26" =&gt; "OnSpec 90c26",
  "pd"   =&gt; "Parallel port IDE disks",
  "pcd"  =&gt; "Parallel port CD-ROM",
  "pf"   =&gt; "Parallel port ATAPI disk",
  "paride" =&gt; "Main parallel port module",
}],
[ 'raid', {
  "linear" =&gt; "linear",
  "raid0" =&gt; "raid0",
  "raid1" =&gt; "raid1",
  "raid5" =&gt; "raid5",
}],
[ 'mouse', {
  "busmouse" =&gt; "busmouse",
  "msbusmouse" =&gt; "msbusmouse",
  "serial" =&gt; "serial",
  "qpmouse" =&gt; "qpmouse",
  "atixlmouse" =&gt; "atixlmouse",

  "usb-uhci", "USB (uhci)",
  "usb-ohci", "USB (ohci)",
  "usb-ohci-hcd", "USB (ohci-hcd)",
}],
[ 'fs', {
  "smbfs" =&gt; "Windows SMB",
  "fat" =&gt; "fat",
  "msdos" =&gt; "msdos",
  "romfs" =&gt; "romfs",
  "sysv" =&gt; "sysv",
  "ufs" =&gt; "ufs",
  "umsdos" =&gt; "umsdos",
  "vfat" =&gt; "vfat",
}],
[ 'other', {
  "st" =&gt; "st",
  "sg" =&gt; "sg",
  "ide-scsi" =&gt; "ide-scsi",
  "loop" =&gt; "Loopback device",
  "lp" =&gt; "Parallel Printer",
  "ide-floppy" =&gt; "ide-floppy",
  "ide-tape" =&gt; "ide-tape",
  "nbd" =&gt; "nbd",
}],
);

my %type_aliases = (
  scsi =&gt; 'disk',
);


my @drivers_fields = qw(text type);
%drivers = ();

foreach (@drivers_by_category) {
    my @l = @$_;
    my $l = pop @l;
    foreach (keys %$l) { $drivers{$_} = [ $l-&gt;{$_}, @l ]; }
}
while (my ($k, $v) = each %drivers) {
    my %l; @l{@drivers_fields} = @$v;
    $drivers{$k} = \%l;
}


1;

sub module_of_type($) {
    my ($type) = @_;
    grep { $drivers{$_}{type} =~ /^($type)$/ } keys %drivers;
}

sub text_of_type($) {
    my ($type) = @_;
    my $alias = $type_aliases{$type};

    map { $_-&gt;{text} } grep { $_-&gt;{type} eq $type || $_-&gt;{type} eq $alias } values %drivers;
}

sub text2driver($) {
    my ($text) = @_;
    while (my ($k, $v) = each %drivers) {
	$v-&gt;{text} eq $text and return $k;
    }
    die "$text is not a valid module description";
}

sub add_alias($$) { 
    my ($alias, $name) = @_;
    /\Q$alias/ &amp;&amp; $conf{$_}{alias} &amp;&amp; $conf{$_}{alias} eq $name and return foreach keys %conf;
    $alias .= $scsi++ || '' if $alias eq 'scsi_hostadapter';
    log::l("adding alias $alias to $name");
    $conf{$alias}{alias} ||= $name;
    1;
}

sub remove_alias($) {
    my ($name) = @_;
    foreach (keys %conf) {
	$conf{$_}{alias} &amp;&amp; $conf{$_}{alias} eq $name or next;
	delete $conf{$_}{alias};
	return 1;
    }
    0;
}

sub load {
    my ($name, $type, @options) = @_;

    if ($::testing) {
	print join ",", @options, "\n";
	log::l("i try to install $name module (@options)");
    } else {
	$conf{$name}{loaded} and return;

	$type ||= ($drivers{$name} || { type =&gt; 'unknown'})-&gt;{type};

	load($_, 'prereq') foreach @{$deps{$name}};
	load_raw($name, @options);
    }
    push @{$loaded{$type}}, $name;

    if ($type) {
	add_alias('usbmouse', $name) if $type =~ /serial_usb/i;
	add_alias('scsi_hostadapter', $name) if $type eq 'scsi';
    }
    $conf{$name}{options} = join " ", @options if @options;
}

sub unload($;$) {
    my ($m, $remove_alias) = @_; 
    if ($::testing) {
	log::l("rmmod $m");
    } else {	
	run_program::run("rmmod", $m) &amp;&amp; delete $conf{$m}{loaded};
    }
    remove_alias($m) if $remove_alias;
}

sub load_raw($@) {
    my ($name, @options) = @_;

    run_program::run("insmod", $name, @options) or die("insmod $name failed");

    
    if ($name eq "parport_pc") {
	foreach (@options) {
	    /^irq=(\d+)/ or next;
	    log::l("writing to /proc/parport/0/irq");
	    local *F;
	    open F, "&gt; /proc/parport/0/irq" or last;
	    print F $1;
	}
    }
    $conf{$name}{loaded} = 1;
}

sub read_already_loaded() {
    foreach (cat_("/proc/modules", "die")) {
	my ($name) = split;
	$conf{$name}{loaded} = 1;
    }
}

sub load_deps($) {
    my ($file) = @_;

    local *F;
    open F, $file or log::l("error opening $file: $!"), return 0;
    foreach (&lt;F&gt;) {
	my ($f, $deps) = split ':';
	push @{$deps{$f}}, split ' ', $deps;
    }
}

sub read_conf($;$) {
    my ($file, $scsi) = @_;
    my %c;

    foreach (cat_($file)) {
	do {
	    $c{$2}{$1} = $3;
	    $$scsi = max($$scsi, $1 || 0) if /^\s*alias\s+scsi_hostadapter (\d*)/x &amp;&amp; $scsi; 
	} if /^\s*(\S+)\s+(\S+)\s+(.*?)\s*$/;
    }
    
    while (my ($k, $v) = each %c) {

	if (my $a = $v-&gt;{alias}) {
	    local $c{$a}{alias};
	    add2hash($c{$a}, $v);
	}
    }
    \%c;
}

sub write_conf {
    my ($file) = @_;

    
    substInFile { $_ = '' if /post-install supermount/ } $file;

    my $written = read_conf($file);

    my %net = detect_devices::net2module();
    while (my ($k, $v) = each %net) { add_alias($k, $v) }

    add_alias('scsi_hostadapter', 'ide-scsi') if detect_devices::getIDEBurners();

    if (my @scsis = grep { $conf{$_}{alias} &amp;&amp; /scsi_hostadapter/ } keys %conf) {
	log::l("has scsis ", join " ; ", map { "modprobe $_" } @scsis);
	$conf{supermount}{"post-install"} = join " ; ", map { "modprobe $_" } @scsis;
    }

    local *F;
    open F, "&gt;&gt; $file" or die("cannot write module config file $file: $!\n");
    while (my ($mod, $h) = each %conf) {
	while (my ($type, $v2) = each %$h) {
	    print F "$type $mod $v2\n" if $v2 &amp;&amp; $type ne "loaded" &amp;&amp; !$written-&gt;{$mod}{$type};
	}
    }
}

sub read_stage1_conf {
    add2hash(\%conf, read_conf($_[0], \$scsi));
    $conf{parport_lowlevel}{alias} ||= "parport_pc";
    $conf{pcmcia_core}{"pre-install"} ||= "CARDMGR_OPTS=-f /etc/rc.d/init.d/pcmcia start";
    $conf{plip}{"pre-install"} ||= "modprobe parport_pc ; echo 7 &gt; /proc/parport/0/irq";
}

sub load_thiskind($;&amp;$) {
    my ($type, $f, $pcic) = @_;

    require pci_probing::main;
    my @pcidevs = pci_probing::main::probe($type);
    log::l("pci probe found " . scalar @pcidevs . " $type devices");

    my @pcmciadevs = get_pcmcia_devices($type, $pcic);
    log::l("pcmcia probe found " . scalar @pcmciadevs . " $type devices");

    my @devs = (@pcidevs, @pcmciadevs);

    my %devs; foreach (@devs) {
	my ($text, $mod) = @$_;
	$devs{$mod}++ and log::l("multiple $mod devices found"), next;
	log::l("found driver for $mod");
	&amp;$f($text, $mod) if $f;
	load($mod, $type);
    }
    @devs, map { [ $_, $_ ] } @{$loaded{$type} || []};
}

sub pcmcia_need_config($) {
    return $_[0] &amp;&amp; ! -s "/var/run/stab";
}

sub get_pcmcia_devices($$) {
    my ($type, $pcic) = @_;
    my (@devs, $module, $desc);

    
    if (pcmcia_need_config($pcic)) {
	log::l("i try to configure pcmcia services");

	symlink("/tmp/stage2/etc/pcmcia", "/etc/pcmcia") unless -e "/etc/pcmcia";
	symlink("/sbin/install", "/sbin/cardmgr") unless -x "/sbin/cardmgr";

	load("pcmcia_core");
	load($pcic);
	load("ds");

	
	run_program::run("cardmgr", "-f", "-m" ,"/modules");
	sleep(3);

	
	read_already_loaded();
    }

    foreach (cat_("/var/run/stab")) {
	$desc = $1 if /^Socket\s+\d+:\s+(.*)/;
	$module = $1 if /^\d+\s+$type[^\s]*\s+([^\s]+)/;
	if ($desc &amp;&amp; $module) {
	    push @devs, [ $desc, $module ];
	    $desc = $module = undef;
	}
    }
    @devs;
}
</pre></body></html>