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*?/<hostnumber>.
+
+   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 <aoliva@redhat.com>
+   based on the rescan-scsi-bus.sh script by Kurt Garloff <garloff@suse.de>
+
+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 <dirent.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* 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: <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
