Index: loader2/Makefile =================================================================== RCS file: /cvs/devel/anaconda/loader2/Makefile,v retrieving revision 1.28 diff -u -p -r1.28 Makefile --- loader2/Makefile 8 Jul 2003 03:00:54 -0000 1.28 +++ loader2/Makefile 24 Oct 2003 22:26:37 -0000 @@ -16,7 +16,7 @@ MODULELINKAGE :=-lmodutils -lmodutilutil BINS = loader -HWOBJS = pcmcia.o usb.o firewire.o hardware.o +HWOBJS = pcmcia.o usb.o firewire.o rescan-sbp2-bus.o hardware.o METHOBJS = method.o cdinstall.o hdinstall.o nfsinstall.o urlinstall.o OBJS = log.o moduleinfo.o loadermisc.o modules.o moduledeps.o windows.o \ lang.o kbd.o modstubs.o driverdisk.o \ @@ -116,6 +116,10 @@ loader-local.o: loader.c loader-net.o: loader.c $(CC) -DINCLUDE_NETWORK $(CFLAGS) -o $@ -c $< + +# dietlibc doesn't have 64-bit scandir, and we don't need dirent64, so... +rescan-sbp2-bus.o: rescan-sbp2-bus.c + $(CC) $(CFLAGS) -U_FILE_OFFSET_BITS -o $@ -c $< loader: loader.o $(OBJS) $(NETOBJS) $(CC) -g $(STATIC) -o $@ $^ -lpopt \ Index: loader2/firewire.c =================================================================== RCS file: /cvs/devel/anaconda/loader2/firewire.c,v retrieving revision 1.2 diff -u -p -r1.2 firewire.c --- loader2/firewire.c 6 Dec 2002 20:28:40 -0000 1.2 +++ loader2/firewire.c 24 Oct 2003 22:26:38 -0000 @@ -66,6 +66,20 @@ int firewireInitialize(moduleList modLoa sleep(3); logMessage("probing for firewire scsi devices"); + + if (!mlLoadModuleSet("sbp2", modLoaded, modDeps, modInfo, flags)) { + int oldpwd = open(".", 0); + if (!chdir("/proc/scsi")) + { + extern void rescan_scsi_bus (int chmax, int idmax, int lunxmax); + + rescan_scsi_bus(0, 7, 0); + fchdir(oldpwd); + } + close(oldpwd); + sleep(3); + } + devices = probeDevices(CLASS_SCSI, BUS_FIREWIRE, PROBE_ALL); if (!devices) { Index: loader2/rescan-sbp2-bus.c --- /dev/null 2003-09-15 10:02:32.000000000 -0300 +++ loader2/rescan-sbp2-bus.c 2003-10-24 19:01:27.000000000 -0200 @@ -0,0 +1,143 @@ +/* This program issues add-single-device commands to /proc/scsi/scsi + for all SCSI hosts found in /proc/scsi/sbp2*?/. + + It can be used as a stand-alone binary, to be run in initrd, or + compiled into other programs (in compliance with the GNU GPL) that + may call rescan_scsi_bus(chmax, idmax, lunmax) to scan channels + from 0 to chmax, IDs from 0 to idmax, Luns from 0 to lunmax, in all + SCSI hosts found in the current directory (that is expected to be + /proc/scsi). + + Copyright (C) 2003 Alexandre Oliva + based on the rescan-scsi-bus.sh script by Kurt Garloff + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING. If not, write to the +Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +#include +#include +#include +#include +#include + +/* Variables to determine the ranges to be scanned for each SCSI host. + Set from the arguments passed to rescan_scsi_bus(int, int, int). */ +static int channel_max, id_max, lun_max; + +/* Tell /proc/scsi/scsi to attempt to add a device for all + combinations of channel, id and lun in the given SCSI host. */ +static void +add_devices_for_host (int host) +{ + int channel, id, lun; + + for (channel = 0; channel <= channel_max; channel++) + for (id = 0; id <= id_max; id++) + for (lun = 0; lun <= lun_max; lun++) + { + /* This assumes CWD is /proc/scsi. */ + FILE *proc_scsi_scsi = fopen ("scsi", "w"); + + if (! proc_scsi_scsi) + return; + + fprintf (proc_scsi_scsi, "scsi add-single-device %i %i %i %i\n", + host, channel, id, lun); + fclose (proc_scsi_scsi); + } +} + +/* Look for a files whose names are decimal numbers, take them as a + SCSI host numbers and scan them. */ +static int +scan_driver_dir (const struct dirent *entry) +{ + char *endptr; + int host; + + host = strtol (entry->d_name, &endptr, 10); + if (*endptr) + { +#if 0 + if (entry->d_name[0] == '.' + || strcmp (entry->d_name, "add_map") == 0 + || strcmp (entry->d_name, "map") == 0 + || strcmp (entry->d_name, "mod_parm") == 0) + return 0; + + if (strcmp (entry->d_name, "status") == 0) + { + /* FIXME: extract host from a line that looks like: + SCSI host number: + + This file AFAIK is only present in kernel 2.6, that AFAIK + doesn't really need rescanning. */ + host = ...; + } + else +#endif + return 0; + } + add_devices_for_host (host); + return 0; +} + +/* Skipping drivers that make no sense to scan, scan scsi hosts. */ +static int +rescan_driver_bus (const struct dirent *entry) +{ + struct dirent **namelist; + +#if 1 + /* We only want to rescan sbp2 buses for now. */ + if (strncmp (entry->d_name, "sbp2", 4) != 0) + return 0; +#else + if (entry->d_name[0] == '.' + || strcmp (entry->d_name, "scsi") == 0 + || strcmp (entry->d_name, "sg") == 0 + || strcmp (entry->d_name, "dummy") == 0) + return 0; +#endif + + scandir (entry->d_name, &namelist, scan_driver_dir, NULL); + + return 0; +} + +/* Main entry point. CWD must be /proc/scsi. CHMAX, IDMAX and LUNMAX + are the maximum numbers to scan in each SCSI host. */ +void +rescan_scsi_bus(int chmax, int idmax, int lunmax) +{ + struct dirent **namelist; + + channel_max = chmax; + id_max = idmax; + lun_max = lunmax; + + scandir (".", &namelist, rescan_driver_bus, NULL); +} + +#ifdef MAIN +int +main() +{ + if (chdir ("/proc/scsi")) + return 0; + rescan_scsi_bus (0, 7, 0); + return 0; +} +#endif