11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi_scan.c
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2000 Eric Youngdale,
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2002 Patrick Mansfield
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The general scanning/probing algorithm is as follows, exceptions are
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * made to it depending on device specific flags, compilation options, and
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * global variable (boot or module load time) settings.
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A specific LUN is scanned via an INQUIRY command; if the LUN has a
12f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig * device attached, a scsi_device is allocated and setup for it.
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For every id of every channel on the given host:
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 	Scan LUN 0; if the target responds to LUN 0 (even if there is no
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 	device or storage attached to LUN 0):
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 		If LUN 0 has a device attached, allocate and setup a
20f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig * 		scsi_device for it.
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 		If target is SCSI-3 or up, issue a REPORT LUN, and scan
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 		all of the LUNs returned by the REPORT LUN; else,
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 		sequentially scan LUNs up until some maximum is reached,
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 		or a LUN is seen that cannot have a device attached to it.
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/moduleparam.h>
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/blkdev.h>
323e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox#include <linux/delay.h>
333e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox#include <linux/kthread.h>
343e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox#include <linux/spinlock.h>
354ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven#include <linux/async.h>
365a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi.h>
39beb40487508290f5d6565598c60a3f44261beef2Christoph Hellwig#include <scsi/scsi_cmnd.h>
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_device.h>
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_driver.h>
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_devinfo.h>
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_host.h>
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_transport.h>
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_eh.h>
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "scsi_priv.h"
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "scsi_logging.h"
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ALLOC_FAILURE_MSG	KERN_ERR "%s: Allocation failure during" \
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	" SCSI scanning, some SCSI devices might not be configured\n"
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Default timeout
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SCSI_TIMEOUT (2*HZ)
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
59405ae7d381302468ecc803f2148a2ae40a04c999Robert P. J. Day * Prefix values for the SCSI id's (stored in sysfs name field)
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SCSI_UID_SER_NUM 'S'
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SCSI_UID_UNKNOWN 'Z'
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Return values of some of the scanning functions.
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SCSI_SCAN_NO_RESPONSE: no valid response received from the target, this
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * includes allocation or general failures preventing IO from being sent.
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SCSI_SCAN_TARGET_PRESENT: target responded, but no device is available
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * on the given LUN.
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SCSI_SCAN_LUN_PRESENT: target responded, and a device is available on a
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * given LUN.
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SCSI_SCAN_NO_RESPONSE		0
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SCSI_SCAN_TARGET_PRESENT	1
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SCSI_SCAN_LUN_PRESENT		2
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
800ad78200baf1f85a21e6b26c225717ad80980d8fArjan van de Venstatic const char *scsi_null_device_strs = "nullnullnullnull";
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_SCSI_LUNS	512
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SCSI_MULTI_LUN
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int max_scsi_luns = MAX_SCSI_LUNS;
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int max_scsi_luns = 1;
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9010f4b89a0f0586a67f57efb2f5d12fffbb371490Masatake YAMATOmodule_param_named(max_luns, max_scsi_luns, uint, S_IRUGO|S_IWUSR);
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(max_luns,
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 "last scsi LUN (should be between 1 and 2^32-1)");
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9421db1882f79a1ad5977cae6766376a63f60ec414Matthew Wilcox#ifdef CONFIG_SCSI_SCAN_ASYNC
9521db1882f79a1ad5977cae6766376a63f60ec414Matthew Wilcox#define SCSI_SCAN_TYPE_DEFAULT "async"
9621db1882f79a1ad5977cae6766376a63f60ec414Matthew Wilcox#else
9721db1882f79a1ad5977cae6766376a63f60ec414Matthew Wilcox#define SCSI_SCAN_TYPE_DEFAULT "sync"
9821db1882f79a1ad5977cae6766376a63f60ec414Matthew Wilcox#endif
9921db1882f79a1ad5977cae6766376a63f60ec414Matthew Wilcox
10021db1882f79a1ad5977cae6766376a63f60ec414Matthew Wilcoxstatic char scsi_scan_type[6] = SCSI_SCAN_TYPE_DEFAULT;
1013e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1023e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcoxmodule_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO);
1033e082a910d217b2e7b186077ebf5a1126a68c62fMatthew WilcoxMODULE_PARM_DESC(scan, "sync, async or none");
1043e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * max_scsi_report_luns: the maximum number of LUNS that will be
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * returned from the REPORT LUNS command. 8 times this value must
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * be allocated. In theory this could be up to an 8 byte value, but
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * in practice, the maximum number of LUNs suppored by any device
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is about 16k.
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int max_scsi_report_luns = 511;
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11410f4b89a0f0586a67f57efb2f5d12fffbb371490Masatake YAMATOmodule_param_named(max_report_luns, max_scsi_report_luns, uint, S_IRUGO|S_IWUSR);
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(max_report_luns,
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 "REPORT LUNS maximum number of LUNS received (should be"
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 " between 1 and 16384)");
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11914faf12f7df8404c3e8e54baad8d178c327a2f87Alan Sternstatic unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ + 18;
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12110f4b89a0f0586a67f57efb2f5d12fffbb371490Masatake YAMATOmodule_param_named(inq_timeout, scsi_inq_timeout, uint, S_IRUGO|S_IWUSR);
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(inq_timeout,
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 "Timeout (in seconds) waiting for devices to answer INQUIRY."
12414faf12f7df8404c3e8e54baad8d178c327a2f87Alan Stern		 " Default is 20. Some devices may need more; most need less.");
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1266b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox/* This lock protects only this list */
1273e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcoxstatic DEFINE_SPINLOCK(async_scan_lock);
1283e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcoxstatic LIST_HEAD(scanning_hosts);
1293e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1303e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcoxstruct async_scan_data {
1313e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	struct list_head list;
1323e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	struct Scsi_Host *shost;
1333e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	struct completion prev_finished;
1343e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox};
1353e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1363e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox/**
1373e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * scsi_complete_async_scans - Wait for asynchronous scans to complete
1383e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox *
1398bcc24127be12967588db0ad0e614be937ee1d5aMatthew Wilcox * When this function returns, any host which started scanning before
1408bcc24127be12967588db0ad0e614be937ee1d5aMatthew Wilcox * this function was called will have finished its scan.  Hosts which
1418bcc24127be12967588db0ad0e614be937ee1d5aMatthew Wilcox * started scanning after this function was called may or may not have
1428bcc24127be12967588db0ad0e614be937ee1d5aMatthew Wilcox * finished.
1433e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox */
1443e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcoxint scsi_complete_async_scans(void)
1453e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox{
1463e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	struct async_scan_data *data;
1473e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1483e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	do {
1493e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		if (list_empty(&scanning_hosts))
1503e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox			return 0;
1513e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		/* If we can't get memory immediately, that's OK.  Just
1523e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		 * sleep a little.  Even if we never get memory, the async
1533e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		 * scans will finish eventually.
1543e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		 */
1553e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		data = kmalloc(sizeof(*data), GFP_KERNEL);
1563e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		if (!data)
1573e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox			msleep(1);
1583e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	} while (!data);
1593e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1603e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	data->shost = NULL;
1613e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	init_completion(&data->prev_finished);
1623e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1633e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	spin_lock(&async_scan_lock);
1643e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	/* Check that there's still somebody else on the list */
1653e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (list_empty(&scanning_hosts))
1663e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		goto done;
1673e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	list_add_tail(&data->list, &scanning_hosts);
1683e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	spin_unlock(&async_scan_lock);
1693e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1703e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	printk(KERN_INFO "scsi: waiting for bus probes to complete ...\n");
1713e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	wait_for_completion(&data->prev_finished);
1723e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1733e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	spin_lock(&async_scan_lock);
1743e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	list_del(&data->list);
1758bcc24127be12967588db0ad0e614be937ee1d5aMatthew Wilcox	if (!list_empty(&scanning_hosts)) {
1768bcc24127be12967588db0ad0e614be937ee1d5aMatthew Wilcox		struct async_scan_data *next = list_entry(scanning_hosts.next,
1778bcc24127be12967588db0ad0e614be937ee1d5aMatthew Wilcox				struct async_scan_data, list);
1788bcc24127be12967588db0ad0e614be937ee1d5aMatthew Wilcox		complete(&next->prev_finished);
1798bcc24127be12967588db0ad0e614be937ee1d5aMatthew Wilcox	}
1803e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox done:
1813e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	spin_unlock(&async_scan_lock);
1823e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1833e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	kfree(data);
1843e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	return 0;
1853e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox}
1863e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1873e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox/* Only exported for the benefit of scsi_wait_scan */
1883e082a910d217b2e7b186077ebf5a1126a68c62fMatthew WilcoxEXPORT_SYMBOL_GPL(scsi_complete_async_scans);
1893e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
190f2f027c6e9912840020be8b78f037d5c8ac665e0Hugh Dickins#ifndef MODULE
191f2f027c6e9912840020be8b78f037d5c8ac665e0Hugh Dickins/*
192f2f027c6e9912840020be8b78f037d5c8ac665e0Hugh Dickins * For async scanning we need to wait for all the scans to complete before
193f2f027c6e9912840020be8b78f037d5c8ac665e0Hugh Dickins * trying to mount the root fs.  Otherwise non-modular drivers may not be ready
194f2f027c6e9912840020be8b78f037d5c8ac665e0Hugh Dickins * yet.
195f2f027c6e9912840020be8b78f037d5c8ac665e0Hugh Dickins */
196f2f027c6e9912840020be8b78f037d5c8ac665e0Hugh Dickinslate_initcall(scsi_complete_async_scans);
197f2f027c6e9912840020be8b78f037d5c8ac665e0Hugh Dickins#endif
198f2f027c6e9912840020be8b78f037d5c8ac665e0Hugh Dickins
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi_unlock_floptical - unlock device via a special MODE SENSE command
201392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley * @sdev:	scsi device to send command to
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @result:	area to store the result of the MODE SENSE
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Description:
205392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley *     Send a vendor specific MODE SENSE (not a MODE SELECT) command.
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Called for BLIST_KEY devices.
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/
208392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomleystatic void scsi_unlock_floptical(struct scsi_device *sdev,
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  unsigned char *result)
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk(KERN_NOTICE "scsi: unlocking floptical drive\n");
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_cmd[0] = MODE_SENSE;
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_cmd[1] = 0;
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_cmd[2] = 0x2e;
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_cmd[3] = 0;
218392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley	scsi_cmd[4] = 0x2a;     /* size */
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_cmd[5] = 0;
220392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley	scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, result, 0x2a, NULL,
221f4f4e47e4af6b02dd1c425b931c65d0165356e33FUJITA Tomonori			 SCSI_TIMEOUT, 3, NULL);
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi_alloc_sdev - allocate and setup a scsi_Device
226eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * @starget: which target to allocate a &scsi_device for
227eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * @lun: which lun
228eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * @hostdata: usually NULL and set by ->slave_alloc instead
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Description:
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Allocate, initialize for io, and return a pointer to a scsi_Device.
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Stores the @shost, @channel, @id, and @lun in the scsi_Device, and
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     adds scsi_Device to the appropriate list.
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Return value:
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     scsi_Device pointer, or NULL on failure.
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					   unsigned int lun, void *hostdata)
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct scsi_device *sdev;
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int display_failure_msg = 1, ret;
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
244a341cd0f6a0fde1f85fec9aa8f81f824ea4a3f92Jeff Garzik	extern void scsi_evt_thread(struct work_struct *work);
2459937a5e2f32892db0dbeefc2b3bc74b3ae3ea9c7Jens Axboe	extern void scsi_requeue_run_queue(struct work_struct *work);
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24724669f75a3231fa37444977c92d1f4838bec1233Jes Sorensen	sdev = kzalloc(sizeof(*sdev) + shost->transportt->device_size,
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       GFP_ATOMIC);
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!sdev)
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto out;
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->vendor = scsi_null_device_strs;
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->model = scsi_null_device_strs;
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->rev = scsi_null_device_strs;
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->host = shost;
2564a84067dbfce436b81779e585bf712b02ceee552Vasu Dev	sdev->queue_ramp_up_period = SCSI_DEFAULT_RAMP_UP_PERIOD;
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->id = starget->id;
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->lun = lun;
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->channel = starget->channel;
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->sdev_state = SDEV_CREATED;
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	INIT_LIST_HEAD(&sdev->siblings);
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	INIT_LIST_HEAD(&sdev->same_target_siblings);
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	INIT_LIST_HEAD(&sdev->cmd_list);
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	INIT_LIST_HEAD(&sdev->starved_entry);
265a341cd0f6a0fde1f85fec9aa8f81f824ea4a3f92Jeff Garzik	INIT_LIST_HEAD(&sdev->event_list);
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_init(&sdev->list_lock);
267a341cd0f6a0fde1f85fec9aa8f81f824ea4a3f92Jeff Garzik	INIT_WORK(&sdev->event_work, scsi_evt_thread);
2689937a5e2f32892db0dbeefc2b3bc74b3ae3ea9c7Jens Axboe	INIT_WORK(&sdev->requeue_work, scsi_requeue_run_queue);
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->sdev_gendev.parent = get_device(&starget->dev);
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->sdev_target = starget;
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* usually NULL and set by ->slave_alloc instead */
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->hostdata = hostdata;
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* if the device needs this changing, it may do so in the
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * slave_configure function */
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->max_device_blocked = SCSI_DEFAULT_DEVICE_BLOCKED;
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Some low level driver could use device->type
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->type = -1;
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Assume that the device will have handshaking problems,
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * and then fix this field later if it turns out it
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * doesn't
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->borken = 1;
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->request_queue = scsi_alloc_queue(sdev);
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!sdev->request_queue) {
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* release fn is set up in scsi_sysfs_device_initialise, so
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * have to free and put manually here */
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		put_device(&starget->dev);
29793f56089898a1b27fc0c89b5c1c748291353f679Dave Jones		kfree(sdev);
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto out;
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
30009ac46c429464c919d04bb737b27edd84d944f02Tejun Heo	WARN_ON_ONCE(!blk_get_queue(sdev->request_queue));
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->request_queue->queuedata = sdev;
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_sysfs_device_initialize(sdev);
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (shost->hostt->slave_alloc) {
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret = shost->hostt->slave_alloc(sdev);
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ret) {
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * if LLDD reports slave not present, don't clutter
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * console with alloc failure messages
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (ret == -ENXIO)
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				display_failure_msg = 0;
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto out_device_destroy;
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return sdev;
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout_device_destroy:
3224e6c82b3614a18740ef63109d58743a359266dafJames Bottomley	__scsi_remove_device(sdev);
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout:
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (display_failure_msg)
325cadbd4a5e36dde7e6c49b587b2c419103c0b7218Harvey Harrison		printk(ALLOC_FAILURE_MSG, __func__);
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return NULL;
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
329643eb2d932c97a0583381629d632d486934cf7eeJames Bottomleystatic void scsi_target_destroy(struct scsi_target *starget)
330643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley{
331643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	struct device *dev = &starget->dev;
332643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	struct Scsi_Host *shost = dev_to_shost(dev->parent);
333643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	unsigned long flags;
334643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley
335643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	transport_destroy_device(dev);
336643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	spin_lock_irqsave(shost->host_lock, flags);
337643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	if (shost->hostt->target_destroy)
338643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley		shost->hostt->target_destroy(starget);
339643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	list_del_init(&starget->siblings);
340643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	spin_unlock_irqrestore(shost->host_lock, flags);
341643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	put_device(dev);
342643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley}
343643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void scsi_target_dev_release(struct device *dev)
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device *parent = dev->parent;
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct scsi_target *starget = to_scsi_target(dev);
348a283bd37d00e92e8874ca6325ae071691d4db388James Bottomley
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(starget);
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	put_device(parent);
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
353453cd0f3ff3bf25d86c96e62d271ba238f06d5ffAdrian Bunkstatic struct device_type scsi_target_type = {
354b0ed43360fdca227048d88a08290365cb681c1a8Hannes Reinecke	.name =		"scsi_target",
355b0ed43360fdca227048d88a08290365cb681c1a8Hannes Reinecke	.release =	scsi_target_dev_release,
356b0ed43360fdca227048d88a08290365cb681c1a8Hannes Reinecke};
357b0ed43360fdca227048d88a08290365cb681c1a8Hannes Reinecke
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint scsi_is_target_device(const struct device *dev)
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
360b0ed43360fdca227048d88a08290365cb681c1a8Hannes Reinecke	return dev->type == &scsi_target_type;
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(scsi_is_target_device);
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct scsi_target *__scsi_find_target(struct device *parent,
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					      int channel, uint id)
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct scsi_target *starget, *found_starget = NULL;
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct Scsi_Host *shost = dev_to_shost(parent);
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Search for an existing target for this sdev.
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	list_for_each_entry(starget, &shost->__targets, siblings) {
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (starget->id == id &&
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    starget->channel == channel) {
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			found_starget = starget;
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (found_starget)
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		get_device(&found_starget->dev);
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return found_starget;
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
385884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley/**
386884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley * scsi_alloc_target - allocate a new or find an existing target
387884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley * @parent:	parent of the target (need not be a scsi host)
388884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley * @channel:	target channel number (zero if no channels)
389884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley * @id:		target id number
390884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley *
391884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley * Return an existing target if one exists, provided it hasn't already
392884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley * gone into STARGET_DEL state, otherwise allocate a new target.
393884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley *
394884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley * The target is returned with an incremented reference, so the caller
395884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley * is responsible for both reaping and doing a last put
396884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley */
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct scsi_target *scsi_alloc_target(struct device *parent,
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					     int channel, uint id)
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct Scsi_Host *shost = dev_to_shost(parent);
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device *dev = NULL;
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	const int size = sizeof(struct scsi_target)
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		+ shost->transportt->target_size;
4055c44cd2afad3f7b015542187e147a820600172f1James.Smart@Emulex.Com	struct scsi_target *starget;
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct scsi_target *found_target;
40732f95792500794a0a7cce266b7dafb2bee323bf8Brian King	int error;
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
40924669f75a3231fa37444977c92d1f4838bec1233Jes Sorensen	starget = kzalloc(size, GFP_KERNEL);
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!starget) {
411cadbd4a5e36dde7e6c49b587b2c419103c0b7218Harvey Harrison		printk(KERN_ERR "%s: allocation failure\n", __func__);
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev = &starget->dev;
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	device_initialize(dev);
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	starget->reap_ref = 1;
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev->parent = get_device(parent);
41871610f55fa4db63dbf5385929a47c9fb2451f332Kay Sievers	dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
419b0ed43360fdca227048d88a08290365cb681c1a8Hannes Reinecke	dev->bus = &scsi_bus_type;
420b0ed43360fdca227048d88a08290365cb681c1a8Hannes Reinecke	dev->type = &scsi_target_type;
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	starget->id = id;
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	starget->channel = channel;
423f0c0a376d0fcd4c5579ecf5e95f88387cba85211Mike Christie	starget->can_queue = 0;
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	INIT_LIST_HEAD(&starget->siblings);
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	INIT_LIST_HEAD(&starget->devices);
426643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	starget->state = STARGET_CREATED;
4277c9d6f16f50d3aeb780e4f103a1ba8b35d9ae803Alan Stern	starget->scsi_level = SCSI_2;
428c53a284f8be23735dc6b53929640a987055f2933Edward Goggin	starget->max_target_blocked = SCSI_DEFAULT_TARGET_BLOCKED;
429ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley retry:
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave(shost->host_lock, flags);
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	found_target = __scsi_find_target(parent, channel, id);
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (found_target)
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto found;
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	list_add_tail(&starget->siblings, &shost->__targets);
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore(shost->host_lock, flags);
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* allocate and add */
439a283bd37d00e92e8874ca6325ae071691d4db388James Bottomley	transport_setup_device(dev);
440a283bd37d00e92e8874ca6325ae071691d4db388James Bottomley	if (shost->hostt->target_alloc) {
44132f95792500794a0a7cce266b7dafb2bee323bf8Brian King		error = shost->hostt->target_alloc(starget);
442a283bd37d00e92e8874ca6325ae071691d4db388James Bottomley
443a283bd37d00e92e8874ca6325ae071691d4db388James Bottomley		if(error) {
444a283bd37d00e92e8874ca6325ae071691d4db388James Bottomley			dev_printk(KERN_ERR, dev, "target allocation failed, error %d\n", error);
445a283bd37d00e92e8874ca6325ae071691d4db388James Bottomley			/* don't want scsi_target_reap to do the final
446a283bd37d00e92e8874ca6325ae071691d4db388James Bottomley			 * put because it will be under the host lock */
447643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley			scsi_target_destroy(starget);
448a283bd37d00e92e8874ca6325ae071691d4db388James Bottomley			return NULL;
449a283bd37d00e92e8874ca6325ae071691d4db388James Bottomley		}
450a283bd37d00e92e8874ca6325ae071691d4db388James Bottomley	}
451884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley	get_device(dev);
452a283bd37d00e92e8874ca6325ae071691d4db388James Bottomley
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return starget;
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds found:
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	found_target->reap_ref++;
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore(shost->host_lock, flags);
458ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley	if (found_target->state != STARGET_DEL) {
45912fb8c1574d7d0c262d2f4c667047889c4f27ebeAlan Stern		put_device(dev);
460ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley		return found_target;
461ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley	}
462ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley	/* Unfortunately, we found a dying target; need to
463ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley	 * wait until it's dead before we can get a new one */
464ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley	put_device(&found_target->dev);
465ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley	flush_scheduled_work();
466ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley	goto retry;
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
46965f27f38446e1976cc98fd3004b110fedcddd189David Howellsstatic void scsi_target_reap_usercontext(struct work_struct *work)
47065110b2168950a19cc78b5027ed18cb811fbdae8James Bottomley{
47165f27f38446e1976cc98fd3004b110fedcddd189David Howells	struct scsi_target *starget =
47265f27f38446e1976cc98fd3004b110fedcddd189David Howells		container_of(work, struct scsi_target, ew.work);
473863a930a40eb7f2d18534c2c166b22582f5c6cfdJames Bottomley
474ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley	transport_remove_device(&starget->dev);
475ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley	device_del(&starget->dev);
476643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	scsi_target_destroy(starget);
477863a930a40eb7f2d18534c2c166b22582f5c6cfdJames Bottomley}
478863a930a40eb7f2d18534c2c166b22582f5c6cfdJames Bottomley
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi_target_reap - check to see if target is in use and destroy if not
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @starget: target to be checked
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is used after removing a LUN or doing a last put of the target
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it checks atomically that nothing is using the target and removes
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it if so.
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid scsi_target_reap(struct scsi_target *starget)
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
489ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
490ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley	unsigned long flags;
491643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	enum scsi_target_state state;
492f9e8894ae5157796dd69249c56062042d02a431dAlan Stern	int empty = 0;
493ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley
494ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley	spin_lock_irqsave(shost->host_lock, flags);
495643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	state = starget->state;
496f9e8894ae5157796dd69249c56062042d02a431dAlan Stern	if (--starget->reap_ref == 0 && list_empty(&starget->devices)) {
497f9e8894ae5157796dd69249c56062042d02a431dAlan Stern		empty = 1;
498f9e8894ae5157796dd69249c56062042d02a431dAlan Stern		starget->state = STARGET_DEL;
499f9e8894ae5157796dd69249c56062042d02a431dAlan Stern	}
500643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	spin_unlock_irqrestore(shost->host_lock, flags);
501ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley
502643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	if (!empty)
503ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley		return;
504ffedb4522571ac170f941678d138a31bc0884ab4James Bottomley
505643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	BUG_ON(state == STARGET_DEL);
506643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	if (state == STARGET_CREATED)
507643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley		scsi_target_destroy(starget);
508643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley	else
509643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley		execute_in_process_context(scsi_target_reap_usercontext,
510643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley					   &starget->ew);
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
514e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern * sanitize_inquiry_string - remove non-graphical chars from an INQUIRY result string
515e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern * @s: INQUIRY result string to sanitize
516e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern * @len: length of the string
517e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern *
518e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern * Description:
519e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern *	The SCSI spec says that INQUIRY vendor, product, and revision
520e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern *	strings must consist entirely of graphic ASCII characters,
521e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern *	padded on the right with spaces.  Since not all devices obey
522e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern *	this rule, we will replace non-graphic or non-ASCII characters
523e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern *	with spaces.  Exception: a NUL character is interpreted as a
524e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern *	string terminator, so all the following characters are set to
525e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern *	spaces.
526e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern **/
527e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Sternstatic void sanitize_inquiry_string(unsigned char *s, int len)
528e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern{
529e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern	int terminated = 0;
530e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern
531e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern	for (; len > 0; (--len, ++s)) {
532e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern		if (*s == 0)
533e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern			terminated = 1;
534e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern		if (terminated || *s < 0x20 || *s > 0x7e)
535e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern			*s = ' ';
536e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern	}
537e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern}
538e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern
539e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern/**
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY
541392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley * @sdev:	scsi_device to probe
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @inq_result:	area to store the INQUIRY result
543392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley * @result_len: len of inq_result
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @bflags:	store any bflags found here
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Description:
547392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley *     Probe the lun associated with @req using a standard SCSI INQUIRY;
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
549392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley *     If the INQUIRY is successful, zero is returned and the
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     INQUIRY data is in @inq_result; the scsi_level and INQUIRY length
551f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig *     are copied to the scsi_device any flags value is stored in *@bflags.
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/
553e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Sternstatic int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
554392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley			  int result_len, int *bflags)
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int first_inquiry_len, try_inquiry_len, next_inquiry_len;
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int response_len = 0;
559392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley	int pass, count, result;
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct scsi_sense_hdr sshdr;
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*bflags = 0;
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Perform up to 3 passes.  The first pass uses a conservative
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * transfer length of 36 unless sdev->inquiry_len specifies a
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * different value. */
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	first_inquiry_len = sdev->inquiry_len ? sdev->inquiry_len : 36;
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	try_inquiry_len = first_inquiry_len;
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pass = 1;
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds next_pass:
5729ccfc756a70d454dfa82f48897e2883560c01a0eJames Bottomley	SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
5739ccfc756a70d454dfa82f48897e2883560c01a0eJames Bottomley				"scsi scan: INQUIRY pass %d length %d\n",
5749ccfc756a70d454dfa82f48897e2883560c01a0eJames Bottomley				pass, try_inquiry_len));
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Each pass gets up to three chances to ignore Unit Attention */
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (count = 0; count < 3; ++count) {
5785cd3bbfad088f86bde3e0f038ff4dd5bb0ac5290FUJITA Tomonori		int resid;
5795cd3bbfad088f86bde3e0f038ff4dd5bb0ac5290FUJITA Tomonori
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		memset(scsi_cmd, 0, 6);
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		scsi_cmd[0] = INQUIRY;
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		scsi_cmd[4] = (unsigned char) try_inquiry_len;
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		memset(inq_result, 0, try_inquiry_len);
585392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley
586392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley		result = scsi_execute_req(sdev,  scsi_cmd, DMA_FROM_DEVICE,
587ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley					  inq_result, try_inquiry_len, &sshdr,
588f4f4e47e4af6b02dd1c425b931c65d0165356e33FUJITA Tomonori					  HZ / 2 + HZ * scsi_inq_timeout, 3,
5895cd3bbfad088f86bde3e0f038ff4dd5bb0ac5290FUJITA Tomonori					  &resid);
5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY %s "
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				"with code 0x%x\n",
593392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley				result ? "failed" : "successful", result));
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
595392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley		if (result) {
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * not-ready to ready transition [asc/ascq=0x28/0x0]
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * or power-on, reset [asc/ascq=0x29/0x0], continue.
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * INQUIRY should not yield UNIT_ATTENTION
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * but many buggy devices do so anyway.
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
602392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley			if ((driver_byte(result) & DRIVER_SENSE) &&
603ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley			    scsi_sense_valid(&sshdr)) {
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if ((sshdr.sense_key == UNIT_ATTENTION) &&
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				    ((sshdr.asc == 0x28) ||
6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				     (sshdr.asc == 0x29)) &&
6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				    (sshdr.ascq == 0))
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					continue;
6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6105cd3bbfad088f86bde3e0f038ff4dd5bb0ac5290FUJITA Tomonori		} else {
6115cd3bbfad088f86bde3e0f038ff4dd5bb0ac5290FUJITA Tomonori			/*
6125cd3bbfad088f86bde3e0f038ff4dd5bb0ac5290FUJITA Tomonori			 * if nothing was transferred, we try
6135cd3bbfad088f86bde3e0f038ff4dd5bb0ac5290FUJITA Tomonori			 * again. It's a workaround for some USB
6145cd3bbfad088f86bde3e0f038ff4dd5bb0ac5290FUJITA Tomonori			 * devices.
6155cd3bbfad088f86bde3e0f038ff4dd5bb0ac5290FUJITA Tomonori			 */
6165cd3bbfad088f86bde3e0f038ff4dd5bb0ac5290FUJITA Tomonori			if (resid == try_inquiry_len)
6175cd3bbfad088f86bde3e0f038ff4dd5bb0ac5290FUJITA Tomonori				continue;
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
622392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley	if (result == 0) {
623e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern		sanitize_inquiry_string(&inq_result[8], 8);
624e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern		sanitize_inquiry_string(&inq_result[16], 16);
625e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern		sanitize_inquiry_string(&inq_result[32], 4);
626e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern
627e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Stern		response_len = inq_result[4] + 5;
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (response_len > 255)
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			response_len = first_inquiry_len;	/* sanity */
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Get any flags for this device.
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 *
634f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig		 * XXX add a bflags to scsi_device, and replace the
635f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig		 * corresponding bit fields in scsi_device, so bflags
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * need not be passed as an argument.
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*bflags = scsi_get_device_flags(sdev, &inq_result[8],
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				&inq_result[16]);
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* When the first pass succeeds we gain information about
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * what larger transfer lengths might work. */
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (pass == 1) {
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (BLIST_INQUIRY_36 & *bflags)
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				next_inquiry_len = 36;
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else if (BLIST_INQUIRY_58 & *bflags)
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				next_inquiry_len = 58;
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else if (sdev->inquiry_len)
6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				next_inquiry_len = sdev->inquiry_len;
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				next_inquiry_len = response_len;
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* If more data is available perform the second pass */
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (next_inquiry_len > try_inquiry_len) {
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				try_inquiry_len = next_inquiry_len;
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				pass = 2;
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				goto next_pass;
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else if (pass == 2) {
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_INFO "scsi scan: %d byte inquiry failed.  "
6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				"Consider BLIST_INQUIRY_36 for this device\n",
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				try_inquiry_len);
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* If this pass failed, the third pass goes back and transfers
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * the same amount as we successfully got in the first pass. */
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		try_inquiry_len = first_inquiry_len;
6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pass = 3;
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto next_pass;
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* If the last transfer attempt got an error, assume the
6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * peripheral doesn't exist or is dead. */
675392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley	if (result)
676392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley		return -EIO;
6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Don't report any more data than the device says is valid */
6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->inquiry_len = min(try_inquiry_len, response_len);
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * XXX Abort if the response length is less than 36? If less than
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * 32, the lookup of the device flags (above) could be invalid,
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * and it would be possible to take an incorrect action - we do
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * not want to hang because of a short INQUIRY. On the flip side,
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * if the device is spun down or becoming ready (and so it gives a
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * short INQUIRY), an abort here prevents any further use of the
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * device, including spin up.
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
690e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern	 * On the whole, the best approach seems to be to assume the first
691e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern	 * 36 bytes are valid no matter what the device says.  That's
692e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern	 * better than copying < 36 bytes to the inquiry-result buffer
693e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern	 * and displaying garbage for the Vendor, Product, or Revision
694e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern	 * strings.
695e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern	 */
696e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern	if (sdev->inquiry_len < 36) {
697e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern		printk(KERN_INFO "scsi scan: INQUIRY result too short (%d),"
698e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern				" using 36\n", sdev->inquiry_len);
699e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern		sdev->inquiry_len = 36;
700e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern	}
701e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern
702e423ee31db92d4e298c137814a4341e1cd05739eAlan Stern	/*
7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Related to the above issue:
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * XXX Devices (disk or all?) should be sent a TEST UNIT READY,
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * and if not ready, sent a START_STOP to start (maybe spin up) and
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * then send the INQUIRY again, since the INQUIRY can change after
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * a device is initialized.
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Ideally, start a device if explicitly asked to do so.  This
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * assumes that a device is spun up on power on, spun down on
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * request, and then spun up on request.
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * The scanning code needs to know the scsi_level, even if no
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * device is attached at LUN 0 (SCSI_SCAN_TARGET_PRESENT) so
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * non-zero LUNs can be scanned.
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->scsi_level = inq_result[2] & 0x07;
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (sdev->scsi_level >= 2 ||
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    (sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1))
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->scsi_level++;
7246f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	sdev->sdev_target->scsi_level = sdev->scsi_level;
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
726392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley	return 0;
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
730f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig * scsi_add_lun - allocate and fully initialze a scsi_device
7316d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox * @sdev:	holds information to be stored in the new scsi_device
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @inq_result:	holds the result of a previous INQUIRY to the LUN
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @bflags:	black/white list flag
7346d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox * @async:	1 if this device is being scanned asynchronously
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Description:
7376d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox *     Initialize the scsi_device @sdev.  Optionally set fields based
7386d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox *     on values in *@bflags.
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Return:
741f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig *     SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
742f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig *     SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/
744e5b3cd42960a10c1bc3701d4f00767463c88ec9dAlan Sternstatic int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
7453e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		int *bflags, int async)
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7476f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley	int ret;
7486f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * XXX do not save the inquiry, since it can change underneath us,
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * save just vendor/model/rev.
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Rather than save it and have an ioctl that retrieves the saved
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * value, have an ioctl that executes the same INQUIRY code used
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * in scsi_probe_lun, let user level programs doing INQUIRY
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * scanning run at their own risk, or supply a user level program
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * that can correctly scan.
7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
75909123d230a294cd3b860f4ea042235b988277f0aAlan Stern
76009123d230a294cd3b860f4ea042235b988277f0aAlan Stern	/*
76109123d230a294cd3b860f4ea042235b988277f0aAlan Stern	 * Copy at least 36 bytes of INQUIRY data, so that we don't
76209123d230a294cd3b860f4ea042235b988277f0aAlan Stern	 * dereference unallocated memory when accessing the Vendor,
76309123d230a294cd3b860f4ea042235b988277f0aAlan Stern	 * Product, and Revision strings.  Badly behaved devices may set
76409123d230a294cd3b860f4ea042235b988277f0aAlan Stern	 * the INQUIRY Additional Length byte to a small value, indicating
76509123d230a294cd3b860f4ea042235b988277f0aAlan Stern	 * these strings are invalid, but often they contain plausible data
76609123d230a294cd3b860f4ea042235b988277f0aAlan Stern	 * nonetheless.  It doesn't matter if the device sent < 36 bytes
76709123d230a294cd3b860f4ea042235b988277f0aAlan Stern	 * total, since scsi_probe_lun() initializes inq_result with 0s.
76809123d230a294cd3b860f4ea042235b988277f0aAlan Stern	 */
76909123d230a294cd3b860f4ea042235b988277f0aAlan Stern	sdev->inquiry = kmemdup(inq_result,
77009123d230a294cd3b860f4ea042235b988277f0aAlan Stern				max_t(size_t, sdev->inquiry_len, 36),
77109123d230a294cd3b860f4ea042235b988277f0aAlan Stern				GFP_ATOMIC);
77209123d230a294cd3b860f4ea042235b988277f0aAlan Stern	if (sdev->inquiry == NULL)
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return SCSI_SCAN_NO_RESPONSE;
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->vendor = (char *) (sdev->inquiry + 8);
7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->model = (char *) (sdev->inquiry + 16);
7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->rev = (char *) (sdev->inquiry + 32);
7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (*bflags & BLIST_ISROM) {
7806d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox		sdev->type = TYPE_ROM;
7816d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox		sdev->removable = 1;
7826d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox	} else {
7836d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox		sdev->type = (inq_result[0] & 0x1f);
7846d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox		sdev->removable = (inq_result[1] & 0x80) >> 7;
7856d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox	}
7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7876d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox	switch (sdev->type) {
788ddaf6fc85459d161c39a70a2cf9e04343dafe47fJames Bottomley	case TYPE_RBC:
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case TYPE_TAPE:
7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case TYPE_DISK:
7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case TYPE_PRINTER:
7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case TYPE_MOD:
7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case TYPE_PROCESSOR:
7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case TYPE_SCANNER:
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case TYPE_MEDIUM_CHANGER:
7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case TYPE_ENCLOSURE:
7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case TYPE_COMM:
7984d7db04a7a69099accd84984a78c64d2178252f1James Bottomley	case TYPE_RAID:
79982443a58d361123d418033e9e32ac29a842fce68Boaz Harrosh	case TYPE_OSD:
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->writeable = 1;
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case TYPE_ROM:
803ddaf6fc85459d161c39a70a2cf9e04343dafe47fJames Bottomley	case TYPE_WORM:
8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->writeable = 0;
8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_INFO "scsi: unknown device type %d\n", sdev->type);
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8106d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox	if (sdev->type == TYPE_RBC || sdev->type == TYPE_ROM) {
8116d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox		/* RBC and MMC devices can return SCSI-3 compliance and yet
8126d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox		 * still not support REPORT LUNS, so make them act as
8136d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox		 * BLIST_NOREPORTLUN unless BLIST_REPORTLUN2 is
8146d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox		 * specifically set */
8156d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox		if ((*bflags & BLIST_REPORTLUN2) == 0)
8166d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox			*bflags |= BLIST_NOREPORTLUN;
8176d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox	}
8186d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox
8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * For a peripheral qualifier (PQ) value of 1 (001b), the SCSI
8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * spec says: The device server is capable of supporting the
8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * specified peripheral device type on this logical unit. However,
8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * the physical device is not currently connected to this logical
8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * unit.
8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * The above is vague, as it implies that we could treat 001 and
8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * 011 the same. Stay compatible with previous code, and create a
828f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig	 * scsi_device for a PQ of 1
8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Don't set the device offline here; rather let the upper
8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * level drivers eval the PQ to decide whether they should
8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * attach. So remove ((inq_result[0] >> 5) & 7) == 1 check.
8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->inq_periph_qual = (inq_result[0] >> 5) & 7;
8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->lockable = sdev->removable;
8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->soft_reset = (inq_result[7] & 1) && ((inq_result[3] & 7) == 2);
8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8396d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox	if (sdev->scsi_level >= SCSI_3 ||
8406d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox			(sdev->inquiry_len > 56 && inq_result[56] & 0x04))
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->ppr = 1;
8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (inq_result[7] & 0x60)
8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->wdtr = 1;
8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (inq_result[7] & 0x10)
8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->sdtr = 1;
8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
84719ac0db3e22de3b00cc4aadc7efbad0420c7aa08James Bottomley	sdev_printk(KERN_NOTICE, sdev, "%s %.8s %.16s %.4s PQ: %d "
8484ff36718ede26ee2da73f2dae94d71e2b06845fcMatthew Wilcox			"ANSI: %d%s\n", scsi_device_type(sdev->type),
8494ff36718ede26ee2da73f2dae94d71e2b06845fcMatthew Wilcox			sdev->vendor, sdev->model, sdev->rev,
8504ff36718ede26ee2da73f2dae94d71e2b06845fcMatthew Wilcox			sdev->inq_periph_qual, inq_result[2] & 0x07,
8514ff36718ede26ee2da73f2dae94d71e2b06845fcMatthew Wilcox			(inq_result[3] & 0x0f) == 1 ? " CCS" : "");
8524ff36718ede26ee2da73f2dae94d71e2b06845fcMatthew Wilcox
8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((sdev->scsi_level >= SCSI_2) && (inq_result[7] & 2) &&
8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    !(*bflags & BLIST_NOTQ))
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->tagged_supported = 1;
8566d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox
8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Some devices (Texel CD ROM drives) have handshaking problems
8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * when used with the Seagate controllers. borken is initialized
8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * to 1, and then set it to 0 here.
8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((*bflags & BLIST_BORKEN) == 0)
8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->borken = 0;
8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8656d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox	if (*bflags & BLIST_NO_ULD_ATTACH)
8666d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox		sdev->no_uld_attach = 1;
8676d877688ef411313c94aa3c83c7473fbec6db32cMatthew Wilcox
8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Apparently some really broken devices (contrary to the SCSI
8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * standards) need to be selected without asserting ATN
8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (*bflags & BLIST_SELECT_NO_ATN)
8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->select_no_atn = 1;
8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
8764d7db04a7a69099accd84984a78c64d2178252f1James Bottomley	 * Maximum 512 sector transfer length
8774d7db04a7a69099accd84984a78c64d2178252f1James Bottomley	 * broken RA4x00 Compaq Disk Array
8784d7db04a7a69099accd84984a78c64d2178252f1James Bottomley	 */
8794d7db04a7a69099accd84984a78c64d2178252f1James Bottomley	if (*bflags & BLIST_MAX_512)
880086fa5ff0854c676ec333760f4c0154b3b242616Martin K. Petersen		blk_queue_max_hw_sectors(sdev->request_queue, 512);
8814d7db04a7a69099accd84984a78c64d2178252f1James Bottomley
8824d7db04a7a69099accd84984a78c64d2178252f1James Bottomley	/*
8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Some devices may not want to have a start command automatically
8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * issued when a device is added.
8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (*bflags & BLIST_NOSTARTONADD)
8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->no_start_on_add = 1;
8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (*bflags & BLIST_SINGLELUN)
89025d7c363f2663fe399e623c9bd819258c9760bdcTony Battersby		scsi_target(sdev)->single_lun = 1;
8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev->use_10_for_rw = 1;
8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (*bflags & BLIST_MS_SKIP_PAGE_08)
8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->skip_ms_page_8 = 1;
8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (*bflags & BLIST_MS_SKIP_PAGE_3F)
8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->skip_ms_page_3f = 1;
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (*bflags & BLIST_USE_10_BYTE_MS)
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->use_10_for_ms = 1;
9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* set the device running here so that slave configure
9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * may do I/O */
9056f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley	ret = scsi_device_set_state(sdev, SDEV_RUNNING);
9066f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley	if (ret) {
9076f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley		ret = scsi_device_set_state(sdev, SDEV_BLOCK);
9086f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley
9096f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley		if (ret) {
9106f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley			sdev_printk(KERN_ERR, sdev,
9116f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley				    "in wrong state %s to complete scan\n",
9126f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley				    scsi_device_state_name(sdev->sdev_state));
9136f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley			return SCSI_SCAN_NO_RESPONSE;
9146f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley		}
9156f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley	}
9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (*bflags & BLIST_MS_192_BYTES_FOR_3F)
9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->use_192_bytes_for_3f = 1;
9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (*bflags & BLIST_NOT_LOCKABLE)
9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->lockable = 0;
9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (*bflags & BLIST_RETRY_HWERROR)
9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->retry_hwerror = 1;
9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	transport_configure_device(&sdev->sdev_gendev);
9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
928938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig	if (sdev->host->hostt->slave_configure) {
9296f4267e3bd1211b3d09130e626b0b3d885077610James Bottomley		ret = sdev->host->hostt->slave_configure(sdev);
930938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig		if (ret) {
931938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig			/*
932938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig			 * if LLDD reports slave not present, don't clutter
933938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig			 * console with alloc failure messages
934938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig			 */
935938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig			if (ret != -ENXIO) {
936938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig				sdev_printk(KERN_ERR, sdev,
937938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig					"failed to configure device\n");
938938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig			}
939938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig			return SCSI_SCAN_NO_RESPONSE;
940938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig		}
941938050916f57f08e20595b1fa1c1e57c2fbf7243Christoph Hellwig	}
9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9434a84067dbfce436b81779e585bf712b02ceee552Vasu Dev	sdev->max_queue_depth = sdev->queue_depth;
9444a84067dbfce436b81779e585bf712b02ceee552Vasu Dev
9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Ok, the device is now all set up, we can
9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * register it and tell the rest of the kernel
9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * about it.
9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
9503e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (!async && scsi_sysfs_add_sdev(sdev) != 0)
951b24b1033451fcc87087a692fc47ca45daebd51acAlan Stern		return SCSI_SCAN_NO_RESPONSE;
9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return SCSI_SCAN_LUN_PRESENT;
9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
956c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Morton#ifdef CONFIG_SCSI_LOGGING
9576c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff/**
958eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * scsi_inq_str - print INQUIRY data from min to max index, strip trailing whitespace
9596c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff * @buf:   Output buffer with at least end-first+1 bytes of space
9606c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff * @inq:   Inquiry buffer (input)
9616c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff * @first: Offset of string into inq
9626c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff * @end:   Index after last character in inq
9636c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff */
964c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Mortonstatic unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
9656c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff				   unsigned first, unsigned end)
9666c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff{
9676c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff	unsigned term = 0, idx;
968c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Morton
969c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Morton	for (idx = 0; idx + first < end && idx + first < inq[4] + 5; idx++) {
970c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Morton		if (inq[idx+first] > ' ') {
9716c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff			buf[idx] = inq[idx+first];
9726c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff			term = idx+1;
9736c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff		} else {
9746c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff			buf[idx] = ' ';
9756c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff		}
9766c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff	}
9776c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff	buf[term] = 0;
9786c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff	return buf;
9796c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff}
980c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Morton#endif
9816f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley
9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @starget:	pointer to target device structure
9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @lun:	LUN of target device
9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @bflagsp:	store bflags here if not NULL
987eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * @sdevp:	probe the LUN corresponding to this scsi_device
988eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * @rescan:     if nonzero skip some code only needed on first scan
989eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * @hostdata:	passed to scsi_alloc_sdev()
9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Description:
9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Call scsi_probe_lun, if a LUN with an attached device is found,
9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     allocate and set it up by calling scsi_add_lun.
9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Return:
996f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig *     SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     SCSI_SCAN_TARGET_PRESENT: target responded, but no device is
9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *         attached at the LUN
999f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig *     SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/
10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int scsi_probe_and_add_lun(struct scsi_target *starget,
10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  uint lun, int *bflagsp,
10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  struct scsi_device **sdevp, int rescan,
10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  void *hostdata)
10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct scsi_device *sdev;
10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char *result;
1008392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley	int bflags, res = SCSI_SCAN_NO_RESPONSE, result_len = 256;
10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * The rescan flag is used as an optimization, the first scan of a
10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * host adapter calls into here with rescan == 0.
10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
10156f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	sdev = scsi_device_lookup_by_target(starget, lun);
10166f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	if (sdev) {
10170f1d87a2acb8fd1f2ef8af109a785123ddc1a6cbJames Bottomley		if (rescan || !scsi_device_created(sdev)) {
10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				"scsi scan: device exists on %s\n",
102071610f55fa4db63dbf5385929a47c9fb2451f332Kay Sievers				dev_name(&sdev->sdev_gendev)));
10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (sdevp)
10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*sdevp = sdev;
10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else
10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				scsi_device_put(sdev);
10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (bflagsp)
10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*bflagsp = scsi_get_device_flags(sdev,
10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds								 sdev->vendor,
10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds								 sdev->model);
10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return SCSI_SCAN_LUN_PRESENT;
10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
10326f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley		scsi_device_put(sdev);
10336f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	} else
10346f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley		sdev = scsi_alloc_sdev(starget, lun, hostdata);
10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!sdev)
10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto out;
1037392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley
1038392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley	result = kmalloc(result_len, GFP_ATOMIC |
1039bc86120a85ebf553180946e8854d1993f074e9f5Al Viro			((shost->unchecked_isa_dma) ? __GFP_DMA : 0));
10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!result)
1041392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley		goto out_free_sdev;
10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1043392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley	if (scsi_probe_lun(sdev, result, result_len, &bflags))
10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto out_free_result;
10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10464186ab1973758190916703eb8889ebe8002c5c8fKurt Garloff	if (bflagsp)
10474186ab1973758190916703eb8889ebe8002c5c8fKurt Garloff		*bflagsp = bflags;
10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * result contains valid SCSI INQUIRY data.
10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
105113f7e5acc8b329080672c13f05f252ace5b79825Kurt Garloff	if (((result[0] >> 5) == 3) && !(bflags & BLIST_ATTACH_PQ3)) {
10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * For a Peripheral qualifier 3 (011b), the SCSI
10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * spec says: The device server is not capable of
10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * supporting a physical device on this logical
10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * unit.
10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 *
10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * For disks, this implies that there is no
10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * logical disk configured at sdev->lun, but there
10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * is a target id responding.
10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
10626c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff		SCSI_LOG_SCAN_BUS(2, sdev_printk(KERN_INFO, sdev, "scsi scan:"
10636c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff				   " peripheral qualifier of 3, device not"
10646c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff				   " added\n"))
10656c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff		if (lun == 0) {
1066c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Morton			SCSI_LOG_SCAN_BUS(1, {
1067c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Morton				unsigned char vend[9];
1068c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Morton				unsigned char mod[17];
1069c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Morton
1070c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Morton				sdev_printk(KERN_INFO, sdev,
10716c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff					"scsi scan: consider passing scsi_mod."
10723424a65d717ca87ce11acfb03cfd2f713886bfb4Kurt Garloff					"dev_flags=%s:%s:0x240 or 0x1000240\n",
10736c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff					scsi_inq_str(vend, result, 8, 16),
1074c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Morton					scsi_inq_str(mod, result, 16, 32));
1075c5f2e6404c65e8380c9ba80a7d58a27d2642743bAndrew Morton			});
1076643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley
10776c7154c97e20c0ea28547240dc86731c0cee1b2fKurt Garloff		}
1078643eb2d932c97a0583381629d632d486934cf7eeJames Bottomley
10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		res = SCSI_SCAN_TARGET_PRESENT;
10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto out_free_result;
10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10831bfc5d9d5eb8e1a2efacc306bc55c248ed259a8eAlan Stern	/*
108484961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * Some targets may set slight variations of PQ and PDT to signal
108584961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * that no LUN is present, so don't add sdev in these cases.
108684961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * Two specific examples are:
108784961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * 1) NetApp targets: return PQ=1, PDT=0x1f
108884961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * 2) USB UFI: returns PDT=0x1f, with the PQ bits being "reserved"
108984961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 *    in the UFI 1.0 spec (we cannot rely on reserved bits).
109084961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 *
109184961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * References:
109284961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * 1) SCSI SPC-3, pp. 145-146
109384961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * PQ=1: "A peripheral device having the specified peripheral
109484961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * device type is not connected to this logical unit. However, the
109584961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * device server is capable of supporting the specified peripheral
109684961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * device type on this logical unit."
109784961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * PDT=0x1f: "Unknown or no device type"
109884961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * 2) USB UFI 1.0, p. 20
109984961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * PDT=00h Direct-access device (floppy)
110084961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	 * PDT=1Fh none (no FDD connected to the requested logical unit)
11011bfc5d9d5eb8e1a2efacc306bc55c248ed259a8eAlan Stern	 */
110284961f28e9d13a4b193d0c8545f3c060c1890ff3dave wysochanski	if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) &&
110301b291bd66564b4bd826326af6bd0b6d17e99439James Bottomley	    (result[0] & 0x1f) == 0x1f &&
110401b291bd66564b4bd826326af6bd0b6d17e99439James Bottomley	    !scsi_is_wlun(lun)) {
11051bfc5d9d5eb8e1a2efacc306bc55c248ed259a8eAlan Stern		SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
11061bfc5d9d5eb8e1a2efacc306bc55c248ed259a8eAlan Stern					"scsi scan: peripheral device type"
11071bfc5d9d5eb8e1a2efacc306bc55c248ed259a8eAlan Stern					" of 31, no device added\n"));
11081bfc5d9d5eb8e1a2efacc306bc55c248ed259a8eAlan Stern		res = SCSI_SCAN_TARGET_PRESENT;
11091bfc5d9d5eb8e1a2efacc306bc55c248ed259a8eAlan Stern		goto out_free_result;
11101bfc5d9d5eb8e1a2efacc306bc55c248ed259a8eAlan Stern	}
11111bfc5d9d5eb8e1a2efacc306bc55c248ed259a8eAlan Stern
11123e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	res = scsi_add_lun(sdev, result, &bflags, shost->async_scan);
11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (res == SCSI_SCAN_LUN_PRESENT) {
11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (bflags & BLIST_KEY) {
11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sdev->lockable = 0;
1116392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley			scsi_unlock_floptical(sdev, result);
11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out_free_result:
11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(result);
11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out_free_sdev:
11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (res == SCSI_SCAN_LUN_PRESENT) {
11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (sdevp) {
1125b70d37bf61f278f9d9adf17c52af6b2d0ae7800cAlan Stern			if (scsi_device_get(sdev) == 0) {
1126b70d37bf61f278f9d9adf17c52af6b2d0ae7800cAlan Stern				*sdevp = sdev;
1127b70d37bf61f278f9d9adf17c52af6b2d0ae7800cAlan Stern			} else {
1128b70d37bf61f278f9d9adf17c52af6b2d0ae7800cAlan Stern				__scsi_remove_device(sdev);
1129b70d37bf61f278f9d9adf17c52af6b2d0ae7800cAlan Stern				res = SCSI_SCAN_NO_RESPONSE;
1130b70d37bf61f278f9d9adf17c52af6b2d0ae7800cAlan Stern			}
11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
11326f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	} else
1133860dc73608a091e0b325218acc2701709d5f221aJames Bottomley		__scsi_remove_device(sdev);
11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out:
11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return res;
11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi_sequential_lun_scan - sequentially scan a SCSI target
11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @starget:	pointer to target structure to scan
11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @bflags:	black/white list flag for LUN 0
1142eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * @scsi_level: Which version of the standard does this device adhere to
1143eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * @rescan:     passed to scsi_probe_add_lun()
11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Description:
11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Generally, scan from LUN 1 (LUN 0 is assumed to already have been
11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     scanned) to some maximum lun until a LUN is found with no device
11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     attached. Use the bflags to figure out any oddities.
11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Modifies sdevscan->lun.
11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/
11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void scsi_sequential_lun_scan(struct scsi_target *starget,
11534186ab1973758190916703eb8889ebe8002c5c8fKurt Garloff				     int bflags, int scsi_level, int rescan)
11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int sparse_lun, lun, max_dev_lun;
11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: Sequential scan of"
115971610f55fa4db63dbf5385929a47c9fb2451f332Kay Sievers				    "%s\n", dev_name(&starget->dev)));
11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	max_dev_lun = min(max_scsi_luns, shost->max_lun);
11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * If this device is known to support sparse multiple units,
11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * override the other settings, and scan all of them. Normally,
11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * SCSI-3 devices should be scanned via the REPORT LUNS.
11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (bflags & BLIST_SPARSELUN) {
11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		max_dev_lun = shost->max_lun;
11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sparse_lun = 1;
11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else
11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sparse_lun = 0;
11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * If less than SCSI_1_CSS, and no special lun scaning, stop
11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * scanning; this matches 2.4 behaviour, but could just be a bug
11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * (to continue scanning a SCSI_1_CSS device).
11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * This test is broken.  We might not have any device on lun0 for
11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * a sparselun device, and if that's the case then how would we
11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * know the real scsi_level, eh?  It might make sense to just not
11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * scan any SCSI_1 device for non-0 luns, but that check would best
11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * go into scsi_alloc_sdev() and just have it return null when asked
11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * to alloc an sdev for lun > 0 on an already found SCSI_1 device.
11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((sdevscan->scsi_level < SCSI_1_CCS) &&
11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    ((bflags & (BLIST_FORCELUN | BLIST_SPARSELUN | BLIST_MAX5LUN))
11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	     == 0))
11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * If this device is known to support multiple units, override
11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * the other settings, and scan all of them.
11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (bflags & BLIST_FORCELUN)
11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		max_dev_lun = shost->max_lun;
11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * REGAL CDC-4X: avoid hang after LUN 4
11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (bflags & BLIST_MAX5LUN)
12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		max_dev_lun = min(5U, max_dev_lun);
12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Do not scan SCSI-2 or lower device past LUN 7, unless
12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * BLIST_LARGELUN.
12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (scsi_level < SCSI_3 && !(bflags & BLIST_LARGELUN))
12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		max_dev_lun = min(8U, max_dev_lun);
12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * We have already scanned LUN 0, so start at LUN 1. Keep scanning
12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * until we reach the max, or no LUN is found and we are not
12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * sparse_lun.
12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (lun = 1; lun < max_dev_lun; ++lun)
12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan,
12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					    NULL) != SCSI_SCAN_LUN_PRESENT) &&
12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    !sparse_lun)
12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return;
12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
12219f6aa5750de30b1ba35f6cb8de50c17b4fb59cabRandy Dunlap * scsilun_to_int - convert a scsi_lun to an int
12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @scsilun:	struct scsi_lun to be converted.
12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Description:
12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Convert @scsilun from a struct scsi_lun to a four byte host byte-ordered
12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     integer, and return the result. The caller must check for
12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     truncation before using this function.
12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Notes:
12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     The struct scsi_lun is assumed to be four levels, with each level
12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     effectively containing a SCSI byte-ordered (big endian) short; the
12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     addressing bits of each level are ignored (the highest two bits).
12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     For a description of the LUN format, post SCSI-3 see the SCSI
12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Architecture Model, for SCSI-3 see the SCSI Controller Commands.
12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Given a struct scsi_lun of: 0a 04 0b 03 00 00 00 00, this function returns
12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     the integer: 0x0b030a04
12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/
1239462b7859a07c9c2b060fa2b5b1d49f8b33706d4eChristof Schmittint scsilun_to_int(struct scsi_lun *scsilun)
12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int lun;
12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lun = 0;
12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < sizeof(lun); i += 2)
12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		lun = lun | (((scsilun->scsi_lun[i] << 8) |
12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			      scsilun->scsi_lun[i + 1]) << (i * 8));
12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return lun;
12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1250462b7859a07c9c2b060fa2b5b1d49f8b33706d4eChristof SchmittEXPORT_SYMBOL(scsilun_to_int);
12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
12539f6aa5750de30b1ba35f6cb8de50c17b4fb59cabRandy Dunlap * int_to_scsilun - reverts an int into a scsi_lun
1254eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * @lun:        integer to be reverted
12552f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com * @scsilun:	struct scsi_lun to be set.
12562f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com *
12572f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com * Description:
12582f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com *     Reverts the functionality of the scsilun_to_int, which packed
12592f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com *     an 8-byte lun value into an int. This routine unpacks the int
12602f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com *     back into the lun value.
12612f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com *     Note: the scsilun_to_int() routine does not truly handle all
12622f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com *     8bytes of the lun value. This functions restores only as much
12632f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com *     as was set by the routine.
12642f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com *
12652f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com * Notes:
12662f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com *     Given an integer : 0x0b030a04,  this function returns a
12672f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com *     scsi_lun of : struct scsi_lun of: 0a 04 0b 03 00 00 00 00
12682f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com *
12692f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com **/
12702f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Comvoid int_to_scsilun(unsigned int lun, struct scsi_lun *scsilun)
12712f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com{
12722f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com	int i;
12732f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com
12742f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com	memset(scsilun->scsi_lun, 0, sizeof(scsilun->scsi_lun));
12752f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com
12762f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com	for (i = 0; i < sizeof(lun); i += 2) {
12772f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com		scsilun->scsi_lun[i] = (lun >> 8) & 0xFF;
12782f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com		scsilun->scsi_lun[i+1] = lun & 0xFF;
12792f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com		lun = lun >> 16;
12802f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com	}
12812f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com}
12822f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.ComEXPORT_SYMBOL(int_to_scsilun);
12832f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com
12842f4701d8274c8663f5c50323dc72fefa24b55091James.Smart@Emulex.Com/**
12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi_report_lun_scan - Scan using SCSI REPORT LUN results
1286eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * @starget: which target
1287eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * @bflags: Zero or a mix of BLIST_NOLUN, BLIST_REPORTLUN2, or BLIST_NOREPORTLUN
1288eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley * @rescan: nonzero if we can skip code only needed on first scan
12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Description:
1291eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley *   Fast scanning for modern (SCSI-3) devices by sending a REPORT LUN command.
1292eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley *   Scan the resulting list of LUNs by calling scsi_probe_and_add_lun.
12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1294eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley *   If BLINK_REPORTLUN2 is set, scan a target that supports more than 8
1295eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley *   LUNs even if it's older than SCSI-3.
1296eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley *   If BLIST_NOREPORTLUN is set, return 1 always.
1297eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley *   If BLIST_NOLUN is set, return 0 always.
129809b6b51b0b6c1b9bb61815baf205e4d74c89ff04Alan Stern *   If starget->no_report_luns is set, return 1 always.
12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Return:
13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     0: scan completed (or no memory, so further scanning is futile)
1302eb44820c28bc9a042e1157b41c677018a8fdfc74Rob Landley *     1: could not scan with REPORT LUN
13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/
13046f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomleystatic int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				int rescan)
13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char devname[64];
13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int length;
13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int lun;
13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int num_luns;
13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int retries;
1313392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley	int result;
13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct scsi_lun *lunp, *lun_data;
13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 *data;
13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct scsi_sense_hdr sshdr;
13176f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	struct scsi_device *sdev;
13186f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
13192ef8919830a262f10fb5e4a685e95f71a64bce6cAlan Stern	int ret = 0;
13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set.
13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Also allow SCSI-2 if BLIST_REPORTLUN2 is set and host adapter does
13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * support more than 8 LUNs.
132509b6b51b0b6c1b9bb61815baf205e4d74c89ff04Alan Stern	 * Don't attempt if the target doesn't support REPORT LUNS.
13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
13274d7db04a7a69099accd84984a78c64d2178252f1James Bottomley	if (bflags & BLIST_NOREPORTLUN)
13284d7db04a7a69099accd84984a78c64d2178252f1James Bottomley		return 1;
13294d7db04a7a69099accd84984a78c64d2178252f1James Bottomley	if (starget->scsi_level < SCSI_2 &&
13304d7db04a7a69099accd84984a78c64d2178252f1James Bottomley	    starget->scsi_level != SCSI_UNKNOWN)
13314d7db04a7a69099accd84984a78c64d2178252f1James Bottomley		return 1;
13324d7db04a7a69099accd84984a78c64d2178252f1James Bottomley	if (starget->scsi_level < SCSI_3 &&
13334d7db04a7a69099accd84984a78c64d2178252f1James Bottomley	    (!(bflags & BLIST_REPORTLUN2) || shost->max_lun <= 8))
13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 1;
13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (bflags & BLIST_NOLUN)
13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
133709b6b51b0b6c1b9bb61815baf205e4d74c89ff04Alan Stern	if (starget->no_report_luns)
133809b6b51b0b6c1b9bb61815baf205e4d74c89ff04Alan Stern		return 1;
13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13406f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	if (!(sdev = scsi_device_lookup_by_target(starget, 0))) {
13416f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley		sdev = scsi_alloc_sdev(starget, 0, NULL);
13426f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley		if (!sdev)
13436f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley			return 0;
134475f8ee8e01a6c96652f27da40d4bdac9e2e485f0Alan Stern		if (scsi_device_get(sdev)) {
134575f8ee8e01a6c96652f27da40d4bdac9e2e485f0Alan Stern			__scsi_remove_device(sdev);
13466f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley			return 0;
134775f8ee8e01a6c96652f27da40d4bdac9e2e485f0Alan Stern		}
13486f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	}
13496f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley
13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sprintf(devname, "host %d channel %d id %d",
13516f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley		shost->host_no, sdev->channel, sdev->id);
13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Allocate enough to hold the header (the same size as one scsi_lun)
13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * plus the max number of luns we are requesting.
13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Reallocating and trying again (with the exact amount we need)
13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * would be nice, but then we need to somehow limit the size
13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * allocated based on the available memory and the limits of
13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * kmalloc - we don't want a kmalloc() failure of a huge value to
13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * prevent us from finding any LUNs on this target.
13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	length = (max_scsi_report_luns + 1) * sizeof(struct scsi_lun);
13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lun_data = kmalloc(length, GFP_ATOMIC |
13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0));
13666f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	if (!lun_data) {
1367cadbd4a5e36dde7e6c49b587b2c419103c0b7218Harvey Harrison		printk(ALLOC_FAILURE_MSG, __func__);
1368392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley		goto out;
13696f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	}
13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_cmd[0] = REPORT_LUNS;
13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * bytes 1 - 5: reserved, set to zero.
13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&scsi_cmd[1], 0, 5);
13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * bytes 6 - 9: length of the command.
13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_cmd[6] = (unsigned char) (length >> 24) & 0xff;
13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_cmd[7] = (unsigned char) (length >> 16) & 0xff;
13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_cmd[8] = (unsigned char) (length >> 8) & 0xff;
13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_cmd[9] = (unsigned char) length & 0xff;
13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_cmd[10] = 0;	/* reserved */
13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_cmd[11] = 0;	/* control */
13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * We can get a UNIT ATTENTION, for example a power on/reset, so
13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * retry a few times (like sd.c does for TEST UNIT READY).
13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Experience shows some combinations of adapter/devices get at
13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * least two power on/resets.
13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Illegal requests (for devices that do not support REPORT LUNS)
13961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * should come through as a check condition, and will not generate
13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * a retry.
13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (retries = 0; retries < 3; retries++) {
14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: Sending"
14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				" REPORT LUNS to %s (try %d)\n", devname,
14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				retries));
1403392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley
1404392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley		result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
1405ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley					  lun_data, length, &sshdr,
1406f4f4e47e4af6b02dd1c425b931c65d0165356e33FUJITA Tomonori					  SCSI_TIMEOUT + 4 * HZ, 3, NULL);
1407392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley
14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUNS"
1409392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley				" %s (try %d) result 0x%x\n", result
1410392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley				?  "failed" : "successful", retries, result));
1411392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley		if (result == 0)
14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
1413ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley		else if (scsi_sense_valid(&sshdr)) {
14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (sshdr.sense_key != UNIT_ATTENTION)
14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1419392160335c798bbe94ab3aae6ea0c85d32b81bbcJames Bottomley	if (result) {
14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
14211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * The device probably does not support a REPORT LUN command
14221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
14232ef8919830a262f10fb5e4a685e95f71a64bce6cAlan Stern		ret = 1;
14242ef8919830a262f10fb5e4a685e95f71a64bce6cAlan Stern		goto out_err;
14251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
14261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Get the length from the first four bytes of lun_data.
14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data = (u8 *) lun_data->scsi_lun;
14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	length = ((data[0] << 24) | (data[1] << 16) |
14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		  (data[2] << 8) | (data[3] << 0));
14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	num_luns = (length / sizeof(struct scsi_lun));
14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (num_luns > max_scsi_report_luns) {
14361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_WARNING "scsi: On %s only %d (max_scsi_report_luns)"
14371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       " of %d luns reported, try increasing"
14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       " max_scsi_report_luns.\n", devname,
14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       max_scsi_report_luns, num_luns);
14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		num_luns = max_scsi_report_luns;
14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14433bf743e7c891d8be8295650b7a6a9b5af083b096Jeff Garzik	SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
14443bf743e7c891d8be8295650b7a6a9b5af083b096Jeff Garzik		"scsi scan: REPORT LUN scan\n"));
14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Scan the luns in lun_data. The entry at offset 0 is really
14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * the header, so start at 1 and go up to and including num_luns.
14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (lunp = &lun_data[1]; lunp <= &lun_data[num_luns]; lunp++) {
14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		lun = scsilun_to_int(lunp);
14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Check if the unused part of lunp is non-zero, and so
14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * does not fit in lun.
14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (memcmp(&lunp->scsi_lun[sizeof(lun)], "\0\0\0\0", 4)) {
14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			int i;
14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * Output an error displaying the LUN in byte order,
14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * this differs from what linux would print for the
14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * integer LUN value.
14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printk(KERN_WARNING "scsi: %s lun 0x", devname);
14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			data = (char *)lunp->scsi_lun;
14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (i = 0; i < sizeof(struct scsi_lun); i++)
14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printk("%02x", data[i]);
14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printk(" has a LUN larger than currently supported.\n");
14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else if (lun > sdev->host->max_lun) {
14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printk(KERN_WARNING "scsi: %s lun%d has a LUN larger"
14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       " than allowed by the host adapter\n",
14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       devname, lun);
14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			int res;
14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			res = scsi_probe_and_add_lun(starget,
14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				lun, NULL, NULL, rescan, NULL);
14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (res == SCSI_SCAN_NO_RESPONSE) {
14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/*
14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * Got some results, but now none, abort.
14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
14833bf743e7c891d8be8295650b7a6a9b5af083b096Jeff Garzik				sdev_printk(KERN_ERR, sdev,
14843bf743e7c891d8be8295650b7a6a9b5af083b096Jeff Garzik					"Unexpected response"
14853bf743e7c891d8be8295650b7a6a9b5af083b096Jeff Garzik				        " from lun %d while scanning, scan"
14863bf743e7c891d8be8295650b7a6a9b5af083b096Jeff Garzik				        " aborted\n", lun);
14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14922ef8919830a262f10fb5e4a685e95f71a64bce6cAlan Stern out_err:
14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(lun_data);
14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out:
14956f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	scsi_device_put(sdev);
14960f1d87a2acb8fd1f2ef8af109a785123ddc1a6cbJames Bottomley	if (scsi_device_created(sdev))
14976f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley		/*
14986f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley		 * the sdev we used didn't appear in the report luns scan
14996f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley		 */
1500860dc73608a091e0b325218acc2701709d5f221aJames Bottomley		__scsi_remove_device(sdev);
15012ef8919830a262f10fb5e4a685e95f71a64bce6cAlan Stern	return ret;
15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				      uint id, uint lun, void *hostdata)
15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1507a97a83a06b44d4d1cb01191423caf9813a150b95Matthew Wilcox	struct scsi_device *sdev = ERR_PTR(-ENODEV);
15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device *parent = &shost->shost_gendev;
1509e02f3f59225d8c3b2a0ad0dc941a09865e27da61Christoph Hellwig	struct scsi_target *starget;
15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1511938e2ac0b7ac72d264783b0b548eb6078c295294Matthew Wilcox	if (strncmp(scsi_scan_type, "none", 4) == 0)
1512938e2ac0b7ac72d264783b0b548eb6078c295294Matthew Wilcox		return ERR_PTR(-ENODEV);
1513938e2ac0b7ac72d264783b0b548eb6078c295294Matthew Wilcox
1514e02f3f59225d8c3b2a0ad0dc941a09865e27da61Christoph Hellwig	starget = scsi_alloc_target(parent, channel, id);
15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!starget)
15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ERR_PTR(-ENOMEM);
1517bc4f24014de58f045f169742701a6598884d93dbAlan Stern	scsi_autopm_get_target(starget);
15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15190b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven	mutex_lock(&shost->scan_mutex);
15206b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	if (!shost->async_scan)
15216b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox		scsi_complete_async_scans();
15226b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox
1523bc4f24014de58f045f169742701a6598884d93dbAlan Stern	if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
1524a97a83a06b44d4d1cb01191423caf9813a150b95Matthew Wilcox		scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
1525bc4f24014de58f045f169742701a6598884d93dbAlan Stern		scsi_autopm_put_host(shost);
1526bc4f24014de58f045f169742701a6598884d93dbAlan Stern	}
15270b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven	mutex_unlock(&shost->scan_mutex);
1528bc4f24014de58f045f169742701a6598884d93dbAlan Stern	scsi_autopm_put_target(starget);
15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_target_reap(starget);
15301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	put_device(&starget->dev);
15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return sdev;
15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(__scsi_add_device);
15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1536146f7262ee0ec7fc6882f06e5fcb13883308073cJames Bottomleyint scsi_add_device(struct Scsi_Host *host, uint channel,
1537146f7262ee0ec7fc6882f06e5fcb13883308073cJames Bottomley		    uint target, uint lun)
1538146f7262ee0ec7fc6882f06e5fcb13883308073cJames Bottomley{
1539146f7262ee0ec7fc6882f06e5fcb13883308073cJames Bottomley	struct scsi_device *sdev =
1540146f7262ee0ec7fc6882f06e5fcb13883308073cJames Bottomley		__scsi_add_device(host, channel, target, lun, NULL);
1541146f7262ee0ec7fc6882f06e5fcb13883308073cJames Bottomley	if (IS_ERR(sdev))
1542146f7262ee0ec7fc6882f06e5fcb13883308073cJames Bottomley		return PTR_ERR(sdev);
1543146f7262ee0ec7fc6882f06e5fcb13883308073cJames Bottomley
1544146f7262ee0ec7fc6882f06e5fcb13883308073cJames Bottomley	scsi_device_put(sdev);
1545146f7262ee0ec7fc6882f06e5fcb13883308073cJames Bottomley	return 0;
1546146f7262ee0ec7fc6882f06e5fcb13883308073cJames Bottomley}
1547146f7262ee0ec7fc6882f06e5fcb13883308073cJames BottomleyEXPORT_SYMBOL(scsi_add_device);
1548146f7262ee0ec7fc6882f06e5fcb13883308073cJames Bottomley
15491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid scsi_rescan_device(struct device *dev)
15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct scsi_driver *drv;
15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!dev->driver)
15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drv = to_scsi_driver(dev->driver);
15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (try_module_get(drv->owner)) {
15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (drv->rescan)
15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			drv->rescan(dev);
15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		module_put(drv->owner);
15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(scsi_rescan_device);
15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1565e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Sternstatic void __scsi_scan_target(struct device *parent, unsigned int channel,
1566e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern		unsigned int id, unsigned int lun, int rescan)
15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct Scsi_Host *shost = dev_to_shost(parent);
15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int bflags = 0;
15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int res;
15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct scsi_target *starget;
15721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (shost->this_id == id)
15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Don't scan the host adapter
15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
15781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	starget = scsi_alloc_target(parent, channel, id);
15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!starget)
15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
1582bc4f24014de58f045f169742701a6598884d93dbAlan Stern	scsi_autopm_get_target(starget);
15831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (lun != SCAN_WILD_CARD) {
15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Scan for a specific host/chan/id/lun.
15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan, NULL);
15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto out_reap;
15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Scan LUN 0, if there is some response, scan further. Ideally, we
15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * would not configure LUN 0 until all LUNs are scanned.
15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
15966f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	res = scsi_probe_and_add_lun(starget, 0, &bflags, NULL, rescan, NULL);
15976f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley	if (res == SCSI_SCAN_LUN_PRESENT || res == SCSI_SCAN_TARGET_PRESENT) {
15986f3a20242db2597312c50abc11f1e747c5d2326aJames Bottomley		if (scsi_report_lun_scan(starget, bflags, rescan) != 0)
15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * The REPORT LUN did not scan the target,
16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * do a sequential scan.
16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			scsi_sequential_lun_scan(starget, bflags,
16044186ab1973758190916703eb8889ebe8002c5c8fKurt Garloff						 starget->scsi_level, rescan);
16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out_reap:
1608bc4f24014de58f045f169742701a6598884d93dbAlan Stern	scsi_autopm_put_target(starget);
16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* now determine if the target has any children at all
16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * and if not, nuke it */
16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scsi_target_reap(starget);
16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	put_device(&starget->dev);
16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1615e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern
1616e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern/**
1617e59e4a09729b06a131de9042b2a5b05b7ad26174Randy Dunlap * scsi_scan_target - scan a target id, possibly including all LUNs on the target.
1618e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern * @parent:	host to scan
1619e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern * @channel:	channel to scan
1620e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern * @id:		target id to scan
1621e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern * @lun:	Specific LUN to scan or SCAN_WILD_CARD
1622e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern * @rescan:	passed to LUN scanning routines
1623e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern *
1624e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern * Description:
1625e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern *     Scan the target id on @parent, @channel, and @id. Scan at least LUN 0,
1626e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern *     and possibly all LUNs on the target id.
1627e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern *
1628e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern *     First try a REPORT LUN scan, if that does not scan the target, do a
1629e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern *     sequential scan of LUNs on the target id.
1630e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern **/
1631e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Sternvoid scsi_scan_target(struct device *parent, unsigned int channel,
1632e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern		      unsigned int id, unsigned int lun, int rescan)
1633e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern{
1634e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern	struct Scsi_Host *shost = dev_to_shost(parent);
1635e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern
163693b45af5c6b9d41bbe9da11442291ac4eefc15b4Matthew Wilcox	if (strncmp(scsi_scan_type, "none", 4) == 0)
163793b45af5c6b9d41bbe9da11442291ac4eefc15b4Matthew Wilcox		return;
163893b45af5c6b9d41bbe9da11442291ac4eefc15b4Matthew Wilcox
16396b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	mutex_lock(&shost->scan_mutex);
16403e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (!shost->async_scan)
16413e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		scsi_complete_async_scans();
16423e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1643bc4f24014de58f045f169742701a6598884d93dbAlan Stern	if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
1644e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern		__scsi_scan_target(parent, channel, id, lun, rescan);
1645bc4f24014de58f045f169742701a6598884d93dbAlan Stern		scsi_autopm_put_host(shost);
1646bc4f24014de58f045f169742701a6598884d93dbAlan Stern	}
16470b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven	mutex_unlock(&shost->scan_mutex);
1648e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern}
16491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(scsi_scan_target);
16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			      unsigned int id, unsigned int lun, int rescan)
16531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
16541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	uint order_id;
16551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (id == SCAN_WILD_CARD)
16571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (id = 0; id < shost->max_id; ++id) {
16581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
16591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * XXX adapter drivers when possible (FCP, iSCSI)
16601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * could modify max_id to match the current max,
16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * not the absolute max.
16621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 *
16631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * XXX add a shost id iterator, so for example,
16641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * the FC ID can be the same as a target id
16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * without a huge overhead of sparse id's.
16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
16671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (shost->reverse_ordering)
16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/*
16691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * Scan from high to low id.
16701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
16711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				order_id = shost->max_id - id - 1;
16721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else
16731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				order_id = id;
1674e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern			__scsi_scan_target(&shost->shost_gendev, channel,
1675e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern					order_id, lun, rescan);
16761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
16771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
1678e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern		__scsi_scan_target(&shost->shost_gendev, channel,
1679e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern				id, lun, rescan);
16801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
16831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    unsigned int id, unsigned int lun, int rescan)
16841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
16853bf743e7c891d8be8295650b7a6a9b5af083b096Jeff Garzik	SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost,
16863bf743e7c891d8be8295650b7a6a9b5af083b096Jeff Garzik		"%s: <%u:%u:%u>\n",
1687cadbd4a5e36dde7e6c49b587b2c419103c0b7218Harvey Harrison		__func__, channel, id, lun));
16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
1690091686d3b5569d2ec76b9e6dab7f3608b6f64497Amit Arora	    ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16940b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven	mutex_lock(&shost->scan_mutex);
16956b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	if (!shost->async_scan)
16966b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox		scsi_complete_async_scans();
16976b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox
1698bc4f24014de58f045f169742701a6598884d93dbAlan Stern	if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
169982f29467a025f6a2192d281e97fca0be46e905ccMike Anderson		if (channel == SCAN_WILD_CARD)
170082f29467a025f6a2192d281e97fca0be46e905ccMike Anderson			for (channel = 0; channel <= shost->max_channel;
170182f29467a025f6a2192d281e97fca0be46e905ccMike Anderson			     channel++)
170282f29467a025f6a2192d281e97fca0be46e905ccMike Anderson				scsi_scan_channel(shost, channel, id, lun,
170382f29467a025f6a2192d281e97fca0be46e905ccMike Anderson						  rescan);
170482f29467a025f6a2192d281e97fca0be46e905ccMike Anderson		else
17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			scsi_scan_channel(shost, channel, id, lun, rescan);
1706bc4f24014de58f045f169742701a6598884d93dbAlan Stern		scsi_autopm_put_host(shost);
170782f29467a025f6a2192d281e97fca0be46e905ccMike Anderson	}
17080b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven	mutex_unlock(&shost->scan_mutex);
17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
17111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
17121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17133e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcoxstatic void scsi_sysfs_add_devices(struct Scsi_Host *shost)
17143e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox{
17153e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	struct scsi_device *sdev;
17163e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	shost_for_each_device(sdev, shost) {
17176b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox		if (!scsi_host_scan_allowed(shost) ||
17186b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox		    scsi_sysfs_add_sdev(sdev) != 0)
1719860dc73608a091e0b325218acc2701709d5f221aJames Bottomley			__scsi_remove_device(sdev);
17203e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	}
17213e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox}
17223e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
17233e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox/**
17243e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * scsi_prep_async_scan - prepare for an async scan
17253e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * @shost: the host which will be scanned
17263e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * Returns: a cookie to be passed to scsi_finish_async_scan()
17273e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox *
17283e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * Tells the midlayer this host is going to do an asynchronous scan.
17293e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * It reserves the host's position in the scanning list and ensures
17303e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * that other asynchronous scans started after this one won't affect the
17313e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * ordering of the discovered devices.
17323e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox */
17331aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcoxstatic struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
17343e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox{
17353e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	struct async_scan_data *data;
17366b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	unsigned long flags;
17373e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
17383e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (strncmp(scsi_scan_type, "sync", 4) == 0)
17393e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		return NULL;
17403e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
17413e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (shost->async_scan) {
1742cadbd4a5e36dde7e6c49b587b2c419103c0b7218Harvey Harrison		printk("%s called twice for host %d", __func__,
17433e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox				shost->host_no);
17443e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		dump_stack();
17453e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		return NULL;
17463e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	}
17473e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
17483e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	data = kmalloc(sizeof(*data), GFP_KERNEL);
17493e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (!data)
17503e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		goto err;
17513e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	data->shost = scsi_host_get(shost);
17523e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (!data->shost)
17533e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		goto err;
17543e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	init_completion(&data->prev_finished);
17553e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
17566b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	mutex_lock(&shost->scan_mutex);
17576b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	spin_lock_irqsave(shost->host_lock, flags);
17583e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	shost->async_scan = 1;
17596b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	spin_unlock_irqrestore(shost->host_lock, flags);
17606b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	mutex_unlock(&shost->scan_mutex);
17616b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox
17626b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	spin_lock(&async_scan_lock);
17633e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (list_empty(&scanning_hosts))
17643e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		complete(&data->prev_finished);
17653e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	list_add_tail(&data->list, &scanning_hosts);
17663e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	spin_unlock(&async_scan_lock);
17673e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
17683e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	return data;
17693e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
17703e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox err:
17713e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	kfree(data);
17723e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	return NULL;
17733e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox}
17743e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
17753e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox/**
17763e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * scsi_finish_async_scan - asynchronous scan has finished
17773e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * @data: cookie returned from earlier call to scsi_prep_async_scan()
17783e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox *
17793e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * All the devices currently attached to this host have been found.
17803e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * This function announces all the devices it has found to the rest
17813e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox * of the system.
17823e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox */
17831aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcoxstatic void scsi_finish_async_scan(struct async_scan_data *data)
17843e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox{
17853e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	struct Scsi_Host *shost;
17866b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	unsigned long flags;
17873e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
17883e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (!data)
17893e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		return;
17903e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
17913e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	shost = data->shost;
17926b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox
17936b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	mutex_lock(&shost->scan_mutex);
17946b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox
17953e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (!shost->async_scan) {
1796cadbd4a5e36dde7e6c49b587b2c419103c0b7218Harvey Harrison		printk("%s called twice for host %d", __func__,
17973e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox				shost->host_no);
17983e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		dump_stack();
1799773e82f6cdb026282ff7d26aaac291a5fa84ee3aJulia Lawall		mutex_unlock(&shost->scan_mutex);
18003e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		return;
18013e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	}
18023e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
18033e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	wait_for_completion(&data->prev_finished);
18043e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
18053e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	scsi_sysfs_add_devices(shost);
18063e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
18076b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	spin_lock_irqsave(shost->host_lock, flags);
18083e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	shost->async_scan = 0;
18096b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	spin_unlock_irqrestore(shost->host_lock, flags);
18106b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox
18116b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	mutex_unlock(&shost->scan_mutex);
18126b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox
18136b7f123f378743d739377871c0cbfbaf28c7d25aMatthew Wilcox	spin_lock(&async_scan_lock);
18143e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	list_del(&data->list);
18153e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (!list_empty(&scanning_hosts)) {
18163e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		struct async_scan_data *next = list_entry(scanning_hosts.next,
18173e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox				struct async_scan_data, list);
18183e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		complete(&next->prev_finished);
18193e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	}
18203e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	spin_unlock(&async_scan_lock);
18213e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
1822267a6ad4aefaafbde607804c60945bcf97f91c1bHuajun Li	scsi_autopm_put_host(shost);
18233e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	scsi_host_put(shost);
18243e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	kfree(data);
18253e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox}
18263e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
18271aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcoxstatic void do_scsi_scan_host(struct Scsi_Host *shost)
18283e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox{
18291aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox	if (shost->hostt->scan_finished) {
18301aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox		unsigned long start = jiffies;
18311aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox		if (shost->hostt->scan_start)
18321aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox			shost->hostt->scan_start(shost);
18331aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox
18341aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox		while (!shost->hostt->scan_finished(shost, jiffies - start))
18351aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox			msleep(10);
18361aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox	} else {
18371aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox		scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
18383e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox				SCAN_WILD_CARD, 0);
18391aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox	}
18401aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox}
18413e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
18421aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcoxstatic int do_scan_async(void *_data)
18431aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox{
18441aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox	struct async_scan_data *data = _data;
1845bc4f24014de58f045f169742701a6598884d93dbAlan Stern	struct Scsi_Host *shost = data->shost;
1846bc4f24014de58f045f169742701a6598884d93dbAlan Stern
1847bc4f24014de58f045f169742701a6598884d93dbAlan Stern	do_scsi_scan_host(shost);
18483e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	scsi_finish_async_scan(data);
18493e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	return 0;
18503e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox}
18513e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
18521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
18531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi_scan_host - scan the given adapter
18541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @shost:	adapter to scan
18551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/
18561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid scsi_scan_host(struct Scsi_Host *shost)
18571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1858a57b1fccdfa65b78481f5e651833d979e545de04Matthew Wilcox	struct task_struct *p;
18593e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	struct async_scan_data *data;
18603e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
18613e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (strncmp(scsi_scan_type, "none", 4) == 0)
18623e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		return;
1863bc4f24014de58f045f169742701a6598884d93dbAlan Stern	if (scsi_autopm_get_host(shost) < 0)
1864bc4f24014de58f045f169742701a6598884d93dbAlan Stern		return;
18653e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox
18663e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	data = scsi_prep_async_scan(shost);
18673e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	if (!data) {
18681aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox		do_scsi_scan_host(shost);
1869bc4f24014de58f045f169742701a6598884d93dbAlan Stern		scsi_autopm_put_host(shost);
18703e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox		return;
18713e082a910d217b2e7b186077ebf5a1126a68c62fMatthew Wilcox	}
18721aa8fab2acf1cb8b341131b726773fcff0abc707Matthew Wilcox
1873a57b1fccdfa65b78481f5e651833d979e545de04Matthew Wilcox	p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
1874801678c5a3b4c79236970bcca27c733f5559e0d1Hirofumi Nakagawa	if (IS_ERR(p))
1875a57b1fccdfa65b78481f5e651833d979e545de04Matthew Wilcox		do_scan_async(data);
1876267a6ad4aefaafbde607804c60945bcf97f91c1bHuajun Li	/* scsi_autopm_put_host(shost) is called in scsi_finish_async_scan() */
18771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
18781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(scsi_scan_host);
18791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid scsi_forget_host(struct Scsi_Host *shost)
18811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1882a64358db1253b35d508a411e80a3ad23b859ec88Alan Stern	struct scsi_device *sdev;
18831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
18841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1885a64358db1253b35d508a411e80a3ad23b859ec88Alan Stern restart:
18861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave(shost->host_lock, flags);
1887a64358db1253b35d508a411e80a3ad23b859ec88Alan Stern	list_for_each_entry(sdev, &shost->__devices, siblings) {
1888a64358db1253b35d508a411e80a3ad23b859ec88Alan Stern		if (sdev->sdev_state == SDEV_DEL)
1889a64358db1253b35d508a411e80a3ad23b859ec88Alan Stern			continue;
18901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		spin_unlock_irqrestore(shost->host_lock, flags);
1891a64358db1253b35d508a411e80a3ad23b859ec88Alan Stern		__scsi_remove_device(sdev);
1892a64358db1253b35d508a411e80a3ad23b859ec88Alan Stern		goto restart;
18931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore(shost->host_lock, flags);
18951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
18961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18979f6aa5750de30b1ba35f6cb8de50c17b4fb59cabRandy Dunlap/**
18989f6aa5750de30b1ba35f6cb8de50c17b4fb59cabRandy Dunlap * scsi_get_host_dev - Create a scsi_device that points to the host adapter itself
18999f6aa5750de30b1ba35f6cb8de50c17b4fb59cabRandy Dunlap * @shost: Host that needs a scsi_device
19001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
19011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Lock status: None assumed.
19021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1903f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig * Returns:     The scsi_device or NULL
19041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
19051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Notes:
1906f64a181d898e0518d5ae90c4870069510de977e1Christoph Hellwig *	Attach a single scsi_device to the Scsi_Host - this should
19071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	be made to look like a "pseudo-device" that points to the
19081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	HA itself.
19091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
19101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Note - this device is not accessible from any high-level
19111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	drivers (including generics), which is probably not
19129f6aa5750de30b1ba35f6cb8de50c17b4fb59cabRandy Dunlap *	optimal.  We can add hooks later to attach.
19131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
19141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
19151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1916e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern	struct scsi_device *sdev = NULL;
19171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct scsi_target *starget;
19181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19190b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven	mutex_lock(&shost->scan_mutex);
1920e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern	if (!scsi_host_scan_allowed(shost))
1921e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern		goto out;
19221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id);
19231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!starget)
1924e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern		goto out;
19251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sdev = scsi_alloc_sdev(starget, 0, NULL);
1927d5469119f0098881ab7f991990ef4f81ef13a194Alan Stern	if (sdev)
19281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sdev->borken = 0;
1929d5469119f0098881ab7f991990ef4f81ef13a194Alan Stern	else
1930884d25cc4fda20908fd4ef93dbb41d817984b68bJames Bottomley		scsi_target_reap(starget);
19311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	put_device(&starget->dev);
1932e517d3133f62c27b211f305a6dbd6f6ccac0db1bAlan Stern out:
19330b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven	mutex_unlock(&shost->scan_mutex);
19341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return sdev;
19351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
19361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(scsi_get_host_dev);
19371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19389f6aa5750de30b1ba35f6cb8de50c17b4fb59cabRandy Dunlap/**
19399f6aa5750de30b1ba35f6cb8de50c17b4fb59cabRandy Dunlap * scsi_free_host_dev - Free a scsi_device that points to the host adapter itself
19409f6aa5750de30b1ba35f6cb8de50c17b4fb59cabRandy Dunlap * @sdev: Host device to be freed
19411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
19421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Lock status: None assumed.
19431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
19441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:     Nothing
19451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
19461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid scsi_free_host_dev(struct scsi_device *sdev)
19471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
19481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	BUG_ON(sdev->id != sdev->host->this_id);
19491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1950860dc73608a091e0b325218acc2701709d5f221aJames Bottomley	__scsi_remove_device(sdev);
19511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
19521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(scsi_free_host_dev);
19531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1954