|
@@ -96,10 +96,13 @@ MODULE_PARM_DESC(max_luns,
|
|
|
#define SCSI_SCAN_TYPE_DEFAULT "sync"
|
|
|
#endif
|
|
|
|
|
|
-char scsi_scan_type[6] = SCSI_SCAN_TYPE_DEFAULT;
|
|
|
+char scsi_scan_type[7] = SCSI_SCAN_TYPE_DEFAULT;
|
|
|
|
|
|
-module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO);
|
|
|
-MODULE_PARM_DESC(scan, "sync, async or none");
|
|
|
+module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type),
|
|
|
+ S_IRUGO|S_IWUSR);
|
|
|
+MODULE_PARM_DESC(scan, "sync, async, manual, or none. "
|
|
|
+ "Setting to 'manual' disables automatic scanning, but allows "
|
|
|
+ "for manual device scan via the 'scan' sysfs attribute.");
|
|
|
|
|
|
static unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ + 18;
|
|
|
|
|
@@ -1040,7 +1043,8 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
|
|
|
* @lun: LUN of target device
|
|
|
* @bflagsp: store bflags here if not NULL
|
|
|
* @sdevp: probe the LUN corresponding to this scsi_device
|
|
|
- * @rescan: if nonzero skip some code only needed on first scan
|
|
|
+ * @rescan: if not equal to SCSI_SCAN_INITIAL skip some code only
|
|
|
+ * needed on first scan
|
|
|
* @hostdata: passed to scsi_alloc_sdev()
|
|
|
*
|
|
|
* Description:
|
|
@@ -1055,7 +1059,8 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
|
|
|
**/
|
|
|
static int scsi_probe_and_add_lun(struct scsi_target *starget,
|
|
|
u64 lun, int *bflagsp,
|
|
|
- struct scsi_device **sdevp, int rescan,
|
|
|
+ struct scsi_device **sdevp,
|
|
|
+ enum scsi_scan_mode rescan,
|
|
|
void *hostdata)
|
|
|
{
|
|
|
struct scsi_device *sdev;
|
|
@@ -1069,7 +1074,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
|
|
|
*/
|
|
|
sdev = scsi_device_lookup_by_target(starget, lun);
|
|
|
if (sdev) {
|
|
|
- if (rescan || !scsi_device_created(sdev)) {
|
|
|
+ if (rescan != SCSI_SCAN_INITIAL || !scsi_device_created(sdev)) {
|
|
|
SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
|
|
|
"scsi scan: device exists on %s\n",
|
|
|
dev_name(&sdev->sdev_gendev)));
|
|
@@ -1205,7 +1210,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
|
|
|
* Modifies sdevscan->lun.
|
|
|
**/
|
|
|
static void scsi_sequential_lun_scan(struct scsi_target *starget,
|
|
|
- int bflags, int scsi_level, int rescan)
|
|
|
+ int bflags, int scsi_level,
|
|
|
+ enum scsi_scan_mode rescan)
|
|
|
{
|
|
|
uint max_dev_lun;
|
|
|
u64 sparse_lun, lun;
|
|
@@ -1300,7 +1306,7 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
|
|
|
* 1: could not scan with REPORT LUN
|
|
|
**/
|
|
|
static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
|
|
|
- int rescan)
|
|
|
+ enum scsi_scan_mode rescan)
|
|
|
{
|
|
|
char devname[64];
|
|
|
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
|
|
@@ -1546,7 +1552,7 @@ void scsi_rescan_device(struct device *dev)
|
|
|
EXPORT_SYMBOL(scsi_rescan_device);
|
|
|
|
|
|
static void __scsi_scan_target(struct device *parent, unsigned int channel,
|
|
|
- unsigned int id, u64 lun, int rescan)
|
|
|
+ unsigned int id, u64 lun, enum scsi_scan_mode rescan)
|
|
|
{
|
|
|
struct Scsi_Host *shost = dev_to_shost(parent);
|
|
|
int bflags = 0;
|
|
@@ -1604,7 +1610,10 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
|
|
|
* @channel: channel to scan
|
|
|
* @id: target id to scan
|
|
|
* @lun: Specific LUN to scan or SCAN_WILD_CARD
|
|
|
- * @rescan: passed to LUN scanning routines
|
|
|
+ * @rescan: passed to LUN scanning routines; SCSI_SCAN_INITIAL for
|
|
|
+ * no rescan, SCSI_SCAN_RESCAN to rescan existing LUNs,
|
|
|
+ * and SCSI_SCAN_MANUAL to force scanning even if
|
|
|
+ * 'scan=manual' is set.
|
|
|
*
|
|
|
* Description:
|
|
|
* Scan the target id on @parent, @channel, and @id. Scan at least LUN 0,
|
|
@@ -1614,13 +1623,17 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
|
|
|
* sequential scan of LUNs on the target id.
|
|
|
**/
|
|
|
void scsi_scan_target(struct device *parent, unsigned int channel,
|
|
|
- unsigned int id, u64 lun, int rescan)
|
|
|
+ unsigned int id, u64 lun, enum scsi_scan_mode rescan)
|
|
|
{
|
|
|
struct Scsi_Host *shost = dev_to_shost(parent);
|
|
|
|
|
|
if (strncmp(scsi_scan_type, "none", 4) == 0)
|
|
|
return;
|
|
|
|
|
|
+ if (rescan != SCSI_SCAN_MANUAL &&
|
|
|
+ strncmp(scsi_scan_type, "manual", 6) == 0)
|
|
|
+ return;
|
|
|
+
|
|
|
mutex_lock(&shost->scan_mutex);
|
|
|
if (!shost->async_scan)
|
|
|
scsi_complete_async_scans();
|
|
@@ -1634,7 +1647,8 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
|
|
|
EXPORT_SYMBOL(scsi_scan_target);
|
|
|
|
|
|
static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
|
|
|
- unsigned int id, u64 lun, int rescan)
|
|
|
+ unsigned int id, u64 lun,
|
|
|
+ enum scsi_scan_mode rescan)
|
|
|
{
|
|
|
uint order_id;
|
|
|
|
|
@@ -1665,7 +1679,8 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
|
|
|
}
|
|
|
|
|
|
int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
|
|
|
- unsigned int id, u64 lun, int rescan)
|
|
|
+ unsigned int id, u64 lun,
|
|
|
+ enum scsi_scan_mode rescan)
|
|
|
{
|
|
|
SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost,
|
|
|
"%s: <%u:%u:%llu>\n",
|
|
@@ -1844,7 +1859,8 @@ void scsi_scan_host(struct Scsi_Host *shost)
|
|
|
{
|
|
|
struct async_scan_data *data;
|
|
|
|
|
|
- if (strncmp(scsi_scan_type, "none", 4) == 0)
|
|
|
+ if (strncmp(scsi_scan_type, "none", 4) == 0 ||
|
|
|
+ strncmp(scsi_scan_type, "manual", 6) == 0)
|
|
|
return;
|
|
|
if (scsi_autopm_get_host(shost) < 0)
|
|
|
return;
|