diff -ruN -X ../patches/dontdiff linux-2.4.20-clean/drivers/scsi/hosts.h linux-2.4.20/drivers/scsi/hosts.h --- linux-2.4.20-clean/drivers/scsi/hosts.h Wed May 21 10:22:27 2003 +++ linux-2.4.20/drivers/scsi/hosts.h Tue Apr 15 17:29:34 2003 @@ -508,6 +508,7 @@ uint hlun); extern void scsi_mark_host_reset(struct Scsi_Host *Host); +extern void scsi_scan_new_devices(void); #define BLANK_HOST {"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} diff -ruN -X ../patches/dontdiff linux-2.4.20-clean/drivers/scsi/scsi.c linux-2.4.20/drivers/scsi/scsi.c --- linux-2.4.20-clean/drivers/scsi/scsi.c Wed May 21 10:22:27 2003 +++ linux-2.4.20/drivers/scsi/scsi.c Wed May 21 11:12:55 2003 @@ -1858,6 +1858,26 @@ } err = 0; } + /* + * Usage: echo "scsi scan-new-devices" >/proc/scsi/scsi + * + * Scans all host adapters again to see if there are any + * new devices. + */ +#define SCAN_DEVICES_RATE 18000UL + else if(!strncmp("scan-new-devices", buffer + 5, 16)) { + static unsigned long last = 0; + + if (last != 0 && jiffies < (last + SCAN_DEVICES_RATE)){ + err=-EINVAL; + goto out; + } + last = jiffies; + err = length; + printk("scsi scan-new-devices\n"); + scsi_scan_new_devices(); + goto out; + } out: free_page((unsigned long) buffer); diff -ruN -X ../patches/dontdiff linux-2.4.20-clean/drivers/scsi/scsi.h linux-2.4.20/drivers/scsi/scsi.h --- linux-2.4.20-clean/drivers/scsi/scsi.h Wed May 21 10:22:27 2003 +++ linux-2.4.20/drivers/scsi/scsi.h Tue Apr 15 17:29:34 2003 @@ -577,6 +577,7 @@ char type; char scsi_level; char vendor[8], model[16], rev[4]; + int bflags; /* store the device flags for later use */ unsigned char current_tag; /* current tag */ unsigned char sync_min_period; /* Not less than this period */ unsigned char sync_max_offset; /* Not greater than this offset */ diff -ruN -X ../patches/dontdiff linux-2.4.20-clean/drivers/scsi/scsi_scan.c linux-2.4.20/drivers/scsi/scsi_scan.c --- linux-2.4.20-clean/drivers/scsi/scsi_scan.c Wed May 21 10:22:27 2003 +++ linux-2.4.20/drivers/scsi/scsi_scan.c Wed May 21 10:32:20 2003 @@ -650,7 +650,7 @@ /* * Get any flags for this device. */ - bflags = get_device_flags (scsi_result); + SDpnt->bflags = bflags = get_device_flags (scsi_result); if (bflags & BLIST_SPARSELUN) { *sparse_lun = 1; @@ -954,3 +954,56 @@ /* haven't found lun0, should send INQUIRY but take easy route */ return res; } + +/* scan the hosts for new devices using the explicit hardcoded call to + * scan_scsis. + */ +void scsi_scan_new_devices(void) +{ + struct Scsi_Host *shpnt; + int channel,dev, order_dev; + + for (shpnt = scsi_hostlist; shpnt != NULL; shpnt = shpnt->next) { + for (channel = 0; channel <= shpnt->max_channel; channel++){ + for (dev = 0; dev < shpnt->max_id; ++dev) { + if( shpnt->reverse_ordering) + /* Shift to scanning 15,14,13... or 7,6,5,4, */ + order_dev = shpnt->max_id-dev-1; + else + order_dev = dev; + if (shpnt->this_id != order_dev) { + Scsi_Device *sdev; + /* first check to see if we've already seen this device */ + for(sdev = shpnt->host_queue; sdev; sdev = sdev->next) { + if(sdev->channel == channel + && sdev->id == order_dev + && sdev->lun == 0) { + break; + } + } + if (sdev) continue; + scan_scsis(shpnt, 1, channel, order_dev, 0); + /* now check to see if we found lun 0 */ + for(sdev = shpnt->host_queue; sdev; sdev = sdev->next) { + if(sdev->channel == channel + && sdev->id == order_dev + && sdev->lun == 0) { + break; + } + } + if(sdev && sdev->type == TYPE_DISK && + !(sdev->bflags & BLIST_NOLUN)) { + int lun, max_lun; + if(sdev->scsi_level == SCSI_3 || + sdev->bflags & BLIST_FORCELUN) + max_lun = shpnt->max_lun; + else + max_lun = min_t(unsigned, 8, shpnt->max_lun); + for(lun = 1; lun < max_lun; lun++) + scan_scsis(shpnt, 1, channel, order_dev, lun); + } + } /* this_id != dev */ + } /* for dev */ + } /* for channel */ + } /* for host */ +} diff -ruN -X ../patches/dontdiff linux-2.4.20-clean/drivers/scsi/scsi_syms.c linux-2.4.20/drivers/scsi/scsi_syms.c --- linux-2.4.20-clean/drivers/scsi/scsi_syms.c Wed May 21 10:22:27 2003 +++ linux-2.4.20/drivers/scsi/scsi_syms.c Thu Apr 10 10:43:46 2003 @@ -82,6 +82,7 @@ EXPORT_SYMBOL(scsi_register_blocked_host); EXPORT_SYMBOL(scsi_deregister_blocked_host); +EXPORT_SYMBOL(scsi_scan_new_devices); /* * This symbol is for the highlevel drivers (e.g. sg) only.