@@ -676,13 +676,32 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
676676 **/
677677static int scsi_probe_and_add_lun (struct Scsi_Host * host ,
678678 uint channel , uint id , uint lun , int * bflagsp ,
679- struct scsi_device * * sdevp )
679+ struct scsi_device * * sdevp , int rescan )
680680{
681681 struct scsi_device * sdev ;
682682 struct scsi_request * sreq ;
683683 unsigned char * result ;
684684 int bflags , res = SCSI_SCAN_NO_RESPONSE ;
685685
686+ /*
687+ * The rescan flag is used as an optimization, the first scan of a
688+ * host adapter calls into here with rescan == 0.
689+ */
690+ if (rescan ) {
691+ sdev = scsi_find_device (host , channel , id , lun );
692+ if (sdev ) {
693+ SCSI_LOG_SCAN_BUS (3 , printk (KERN_INFO
694+ "scsi scan: device exists on <%d:%d:%d:%d>\n" ,
695+ host -> host_no , channel , id , lun ));
696+ if (sdevp )
697+ * sdevp = sdev ;
698+ if (bflagsp )
699+ * bflagsp = scsi_get_device_flags (sdev -> vendor ,
700+ sdev -> model );
701+ return SCSI_SCAN_LUN_PRESENT ;
702+ }
703+ }
704+
686705 sdev = scsi_alloc_sdev (host , channel , id , lun );
687706 if (!sdev )
688707 goto out ;
@@ -757,7 +776,7 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
757776 * Modifies sdevscan->lun.
758777 **/
759778static void scsi_sequential_lun_scan (struct Scsi_Host * shost , uint channel ,
760- uint id , int bflags , int lun0_res , int scsi_level )
779+ uint id , int bflags , int lun0_res , int scsi_level , int rescan )
761780{
762781 unsigned int sparse_lun , lun , max_dev_lun ;
763782
@@ -826,7 +845,8 @@ static void scsi_sequential_lun_scan(struct Scsi_Host *shost, uint channel,
826845 */
827846 for (lun = 1 ; lun < max_dev_lun ; ++ lun )
828847 if ((scsi_probe_and_add_lun (shost , channel , id , lun ,
829- NULL , NULL ) != SCSI_SCAN_LUN_PRESENT ) && !sparse_lun )
848+ NULL , NULL , rescan ) != SCSI_SCAN_LUN_PRESENT ) &&
849+ !sparse_lun )
830850 return ;
831851}
832852
@@ -877,7 +897,8 @@ static int scsilun_to_int(struct scsi_lun *scsilun)
877897 * 0: scan completed (or no memory, so further scanning is futile)
878898 * 1: no report lun scan, or not configured
879899 **/
880- static int scsi_report_lun_scan (struct scsi_device * sdev , int bflags )
900+ static int scsi_report_lun_scan (struct scsi_device * sdev , int bflags ,
901+ int rescan )
881902{
882903 char devname [64 ];
883904 unsigned char scsi_cmd [MAX_COMMAND_SIZE ];
@@ -1031,7 +1052,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags)
10311052 int res ;
10321053
10331054 res = scsi_probe_and_add_lun (sdev -> host , sdev -> channel ,
1034- sdev -> id , lun , NULL , NULL );
1055+ sdev -> id , lun , NULL , NULL , rescan );
10351056 if (res == SCSI_SCAN_NO_RESPONSE ) {
10361057 /*
10371058 * Got some results, but now none, abort.
@@ -1057,7 +1078,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags)
10571078 return 0 ;
10581079}
10591080#else
1060- # define scsi_report_lun_scan (sdev , blags ) (1)
1081+ # define scsi_report_lun_scan (sdev , blags , rescan ) (1)
10611082#endif /* CONFIG_SCSI_REPORT_LUNS */
10621083
10631084struct scsi_device * scsi_add_device (struct Scsi_Host * shost ,
@@ -1066,7 +1087,7 @@ struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
10661087 struct scsi_device * sdev ;
10671088 int res ;
10681089
1069- res = scsi_probe_and_add_lun (shost , channel , id , lun , NULL , & sdev );
1090+ res = scsi_probe_and_add_lun (shost , channel , id , lun , NULL , & sdev , 1 );
10701091 if (res != SCSI_SCAN_LUN_PRESENT )
10711092 sdev = ERR_PTR (- ENODEV );
10721093 return sdev ;
@@ -1103,7 +1124,7 @@ void scsi_rescan_device(struct device *dev)
11031124 * sequential scan of LUNs on the target id.
11041125 **/
11051126static void scsi_scan_target (struct Scsi_Host * shost , unsigned int channel ,
1106- unsigned int id )
1127+ unsigned int id , unsigned int lun , int rescan )
11071128{
11081129 int bflags = 0 ;
11091130 int res ;
@@ -1115,19 +1136,29 @@ static void scsi_scan_target(struct Scsi_Host *shost, unsigned int channel,
11151136 */
11161137 return ;
11171138
1139+ if (lun != SCAN_WILD_CARD ) {
1140+ /*
1141+ * Scan for a specific host/chan/id/lun.
1142+ */
1143+ scsi_probe_and_add_lun (shost , channel , id , lun , NULL , NULL ,
1144+ rescan );
1145+ return ;
1146+ }
1147+
11181148 /*
11191149 * Scan LUN 0, if there is some response, scan further. Ideally, we
11201150 * would not configure LUN 0 until all LUNs are scanned.
11211151 */
1122- res = scsi_probe_and_add_lun (shost , channel , id , 0 , & bflags , & sdev );
1152+ res = scsi_probe_and_add_lun (shost , channel , id , 0 , & bflags , & sdev ,
1153+ rescan );
11231154 if (res == SCSI_SCAN_LUN_PRESENT ) {
1124- if (scsi_report_lun_scan (sdev , bflags ) != 0 )
1155+ if (scsi_report_lun_scan (sdev , bflags , rescan ) != 0 )
11251156 /*
11261157 * The REPORT LUN did not scan the target,
11271158 * do a sequential scan.
11281159 */
11291160 scsi_sequential_lun_scan (shost , channel , id , bflags ,
1130- res , sdev -> scsi_level );
1161+ res , sdev -> scsi_level , rescan );
11311162 } else if (res == SCSI_SCAN_TARGET_PRESENT ) {
11321163 /*
11331164 * There's a target here, but lun 0 is offline so we
@@ -1136,47 +1167,66 @@ static void scsi_scan_target(struct Scsi_Host *shost, unsigned int channel,
11361167 * a default scsi level of SCSI_2
11371168 */
11381169 scsi_sequential_lun_scan (shost , channel , id , BLIST_SPARSELUN ,
1139- SCSI_SCAN_TARGET_PRESENT , SCSI_2 );
1170+ SCSI_SCAN_TARGET_PRESENT , SCSI_2 , rescan );
11401171 }
11411172}
11421173
1143- /**
1144- * scsi_scan_host - scan the given adapter
1145- * @shost: adapter to scan
1146- *
1147- * Description:
1148- * Iterate and call scsi_scan_target to scan all possible target id's
1149- * on all possible channels.
1150- **/
1151- void scsi_scan_host (struct Scsi_Host * shost )
1174+ static void scsi_scan_channel (struct Scsi_Host * shost , unsigned int channel ,
1175+ unsigned int id , unsigned int lun , int rescan )
11521176{
1153- uint channel , id , order_id ;
1177+ uint order_id ;
11541178
1155- /*
1156- * The sdevscan host, channel, id and lun are filled in as
1157- * needed to scan.
1158- */
1159- for (channel = 0 ; channel <= shost -> max_channel ; channel ++ ) {
1160- /*
1161- * XXX adapter drivers when possible (FCP, iSCSI)
1162- * could modify max_id to match the current max,
1163- * not the absolute max.
1164- *
1165- * XXX add a shost id iterator, so for example,
1166- * the FC ID can be the same as a target id
1167- * without a huge overhead of sparse id's.
1168- */
1179+ if (id == SCAN_WILD_CARD )
11691180 for (id = 0 ; id < shost -> max_id ; ++ id ) {
1181+ /*
1182+ * XXX adapter drivers when possible (FCP, iSCSI)
1183+ * could modify max_id to match the current max,
1184+ * not the absolute max.
1185+ *
1186+ * XXX add a shost id iterator, so for example,
1187+ * the FC ID can be the same as a target id
1188+ * without a huge overhead of sparse id's.
1189+ */
11701190 if (shost -> reverse_ordering )
11711191 /*
11721192 * Scan from high to low id.
11731193 */
11741194 order_id = shost -> max_id - id - 1 ;
11751195 else
11761196 order_id = id ;
1177- scsi_scan_target (shost , channel , order_id );
1197+ scsi_scan_target (shost , channel , order_id , lun , rescan );
11781198 }
1179- }
1199+ else
1200+ scsi_scan_target (shost , channel , id , lun , rescan );
1201+ }
1202+
1203+ int scsi_scan_host_selected (struct Scsi_Host * shost , unsigned int channel ,
1204+ unsigned int id , unsigned int lun , int rescan )
1205+ {
1206+ SCSI_LOG_SCAN_BUS (3 , printk (KERN_INFO "%s: <%u:%u:%u:%u>\n" ,
1207+ __FUNCTION__ , shost -> host_no , channel , id , lun ));
1208+
1209+ if (((channel != SCAN_WILD_CARD ) && (channel > shost -> max_channel )) ||
1210+ ((id != SCAN_WILD_CARD ) && (id > shost -> max_id )) ||
1211+ ((lun != SCAN_WILD_CARD ) && (lun > shost -> max_lun )))
1212+ return - EINVAL ;
1213+
1214+ if (channel == SCAN_WILD_CARD )
1215+ for (channel = 0 ; channel <= shost -> max_channel ; channel ++ )
1216+ scsi_scan_channel (shost , channel , id , lun , rescan );
1217+ else
1218+ scsi_scan_channel (shost , channel , id , lun , rescan );
1219+ return 0 ;
1220+ }
1221+
1222+ /**
1223+ * scsi_scan_host - scan the given adapter
1224+ * @shost: adapter to scan
1225+ **/
1226+ void scsi_scan_host (struct Scsi_Host * shost )
1227+ {
1228+ scsi_scan_host_selected (shost , SCAN_WILD_CARD , SCAN_WILD_CARD ,
1229+ SCAN_WILD_CARD , 0 );
11801230}
11811231
11821232void scsi_forget_host (struct Scsi_Host * shost )
0 commit comments