Binary files linux-2.4.21.replun1/drivers/scsi/.scsi_scan.c.swp and linux-2.4.21.replun2/drivers/scsi/.scsi_scan.c.swp differ diff -uNr linux-2.4.21.replun1/drivers/scsi/scsi_scan.c linux-2.4.21.replun2/drivers/scsi/scsi_scan.c --- linux-2.4.21.replun1/drivers/scsi/scsi_scan.c 2003-08-24 21:15:46.000000000 +0200 +++ linux-2.4.21.replun2/drivers/scsi/scsi_scan.c 2003-08-24 21:16:04.000000000 +0200 @@ -40,14 +40,12 @@ #define BLIST_ISDISK 0x100 /* Treat as (removable) disk */ #define BLIST_ISROM 0x200 /* Treat as (removable) CD-ROM */ #define BLIST_LARGELUN 0x400 /* LUNs larger than 7 despite reporting as SCSI 2 */ -/* TODO: Add - * BLIST_INQUIRY_36 - * BLIST_INQUIRY_58 - * BLIST_NOSTARTONADD - * BLIST_NOREPLUN - * Remove - * BLIST_FORCELUN - */ +#define BLIST_INQUIRY_36 0x400 /* override additional length field */ +#define BLIST_INQUIRY_58 0x800 /* ... for broken inquiry responses */ +#if 0 // 2.6 kernel +#define BLIST_NOSTARTONADD 0x1000 /* do not do automatic start on add */ +#endif +#define BLIST_NOREPLUN 0x2000 /* do not try to use REPORT_LUNS when scanning */ static void print_inquiry(unsigned char *data); static int scan_scsis_single(unsigned int channel, unsigned int dev, @@ -248,25 +246,27 @@ } -/* - * TODO: Add - * "scsi_sparselun": Switches off optimization to stop scanning after - * a missing LUN. - * "scsi_largelun": Scan beyond LUN 7 even for devices reporting as SCSI-2 - * "scsi_reportlun": Use REPORT_LUNS - * "scsi_reportlun2": Use REPORT_LUNS even for SCSI-2 devs (if the host- - * adapter supports LUNs beyond 7). - * "max_scsi_sparseluns": To further limit the LUNs probed for BLIST_SPARSELUN - * devices (currently shpnt->max_lun is used) - */ +static int scsi_sparselun; +static int scsi_largelun; +static int max_scsi_sparseluns; + #ifdef MODULE MODULE_PARM(max_scsi_luns, "i"); MODULE_PARM_DESC(max_scsi_luns, "last scsi LUN (should be between 1 and 2^32-1)"); MODULE_PARM(llun_blklst, "3-24i"); -MODULE_PARM_DESC(llun_blklst, "SCSI-2 devs (C,B,T) that need large luns support"); - +MODULE_PARM_DESC(llun_blklst, "SCSI-2 devs (C,B,T) that need sparse+large LUNs support"); + +MODULE_PARM(scsi_sparselun, "i"); +MODULE_PARM_DESC(scsi_sparselun, "Assume sparse LUNs for all SCSI devices"); + +MODULE_PARM(scsi_largelun, "i"); +MODULE_PARM_DESC(scsi_largelun, "Assume all SCSI-2 devs support more than 8 LUNs"); + +MODULE_PARM(max_scsi_sparseluns, "i"); +MODULE_PARM_DESC(max_scsi_sparseluns, "Limit LUNs for scanning sparse LUN devices"); + #else static int __init scsi_luns_setup(char *str) @@ -309,6 +309,52 @@ __setup("llun_blklst=", llun_blklst_setup); +static int __init scsi_sparselun_setup(char *str) +{ + unsigned int tmp; + + if (get_option(&str, &tmp) == 1) { + scsi_sparselun = tmp; + return 1; + } else { + scsi_sparselun = 1; + return 0; + } +} + +__setup("scsi_sparselun=", scsi_sparselun_setup); + +static int __init scsi_largelun_setup(char *str) +{ + unsigned int tmp; + + if (get_option(&str, &tmp) == 1) { + scsi_largelun = tmp; + return 1; + } else { + scsi_largelun = 1; + return 0; + } +} + +__setup("scsi_largelun=", scsi_largelun_setup); + +static int __init scsi_max_sparseluns_setup(char *str) +{ + unsigned int tmp; + + if (get_option(&str, &tmp) == 1) { + max_scsi_sparseluns = tmp; + return 1; + } else { + printk("scsi_max_sparseluns_setup : usage max_scsi_sparseluns=n " + "(n should be between 1 and 2^32-1)\n"); + return 0; + } +} + +__setup("max_scsi_sparseluns=", scsi_max_sparseluns_setup); + #endif static void print_inquiry(unsigned char *data) @@ -583,15 +629,13 @@ */ for (lun = 0; lun < max_dev_lun; ++lun) { /* don't probe further for luns > 7 for targets <= SCSI_2 */ - /* TODO: Add knob to turn check off completely */ - if ((lun0_sl < SCSI_3) && (lun > 7)) + if ((lun0_sl < SCSI_3) && (lun > 7) && !scsi_largelun) break; - /* TODO: Knob to switch off SPARSELUN optimization */ if (!scan_scsis_single(channel, target_id, lun, lun0_sl, &max_dev_lun, &sparse_lun, &SDpnt, scsi_result) - && !sparse_lun) + && !sparse_lun && (lun == 0 || !scsi_sparselun)) break; if (SDpnt && (0 == lun)) { @@ -699,9 +743,6 @@ unsigned char scsi_cmd[MAX_COMMAND_SIZE]; Scsi_Device *SDpnt = SRpnt->sr_device; - if (alloclen > 254) - alloclen = 254; - scsi_cmd[0] = INQUIRY; scsi_cmd[1] = (inq_lun << 5) & 0xe0; scsi_cmd[2] = 0; @@ -758,6 +799,13 @@ * which might be snooped by the HBA. */ inq_len = (unsigned char)scsi_result[4] + 5; + if (BLIST_INQUIRY_36 & *bflags) + inq_len = 36; + else if (BLIST_INQUIRY_58 & *bflags) + inq_len = 58; + else if (inq_len > 255) + inq_len = 36; /* sanity */ + if (inq_len > 36 && ((unsigned char)scsi_result[2] & 0x7f) >= 3) send_inquiry(SRpnt, scsi_result, inq_lun, SCSI_TIMEOUT+4*HZ, inq_len); @@ -1021,9 +1069,10 @@ is_on_llun_blklst (shpnt->host_no, channel, id)) { /* Normally max_dev_lun = min(max_scsi_luns, shpny-max_lun) * For SparseLUN devs, it's increased to shpnt->max_lun */ - *max_dev_lun = shpnt->max_lun; + *max_dev_lun = (max_scsi_sparseluns > 0 && max_scsi_sparseluns < shpnt->max_lun)? + max_scsi_sparseluns: shpnt->max_lun; *sparse_lun = 1; - return 1; + return 1; /* Not really needed, handled in the caller */ } /* * If this device is known to support multiple units, override the other