18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * scsi_scan.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2000 Eric Youngdale,
68c2ecf20Sopenharmony_ci * Copyright (C) 2002 Patrick Mansfield
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * The general scanning/probing algorithm is as follows, exceptions are
98c2ecf20Sopenharmony_ci * made to it depending on device specific flags, compilation options, and
108c2ecf20Sopenharmony_ci * global variable (boot or module load time) settings.
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * A specific LUN is scanned via an INQUIRY command; if the LUN has a
138c2ecf20Sopenharmony_ci * device attached, a scsi_device is allocated and setup for it.
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci * For every id of every channel on the given host:
168c2ecf20Sopenharmony_ci *
178c2ecf20Sopenharmony_ci * 	Scan LUN 0; if the target responds to LUN 0 (even if there is no
188c2ecf20Sopenharmony_ci * 	device or storage attached to LUN 0):
198c2ecf20Sopenharmony_ci *
208c2ecf20Sopenharmony_ci * 		If LUN 0 has a device attached, allocate and setup a
218c2ecf20Sopenharmony_ci * 		scsi_device for it.
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci * 		If target is SCSI-3 or up, issue a REPORT LUN, and scan
248c2ecf20Sopenharmony_ci * 		all of the LUNs returned by the REPORT LUN; else,
258c2ecf20Sopenharmony_ci * 		sequentially scan LUNs up until some maximum is reached,
268c2ecf20Sopenharmony_ci * 		or a LUN is seen that cannot have a device attached to it.
278c2ecf20Sopenharmony_ci */
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#include <linux/module.h>
308c2ecf20Sopenharmony_ci#include <linux/moduleparam.h>
318c2ecf20Sopenharmony_ci#include <linux/init.h>
328c2ecf20Sopenharmony_ci#include <linux/blkdev.h>
338c2ecf20Sopenharmony_ci#include <linux/delay.h>
348c2ecf20Sopenharmony_ci#include <linux/kthread.h>
358c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
368c2ecf20Sopenharmony_ci#include <linux/async.h>
378c2ecf20Sopenharmony_ci#include <linux/slab.h>
388c2ecf20Sopenharmony_ci#include <asm/unaligned.h>
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci#include <scsi/scsi.h>
418c2ecf20Sopenharmony_ci#include <scsi/scsi_cmnd.h>
428c2ecf20Sopenharmony_ci#include <scsi/scsi_device.h>
438c2ecf20Sopenharmony_ci#include <scsi/scsi_driver.h>
448c2ecf20Sopenharmony_ci#include <scsi/scsi_devinfo.h>
458c2ecf20Sopenharmony_ci#include <scsi/scsi_host.h>
468c2ecf20Sopenharmony_ci#include <scsi/scsi_transport.h>
478c2ecf20Sopenharmony_ci#include <scsi/scsi_dh.h>
488c2ecf20Sopenharmony_ci#include <scsi/scsi_eh.h>
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci#include "scsi_priv.h"
518c2ecf20Sopenharmony_ci#include "scsi_logging.h"
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci#define ALLOC_FAILURE_MSG	KERN_ERR "%s: Allocation failure during" \
548c2ecf20Sopenharmony_ci	" SCSI scanning, some SCSI devices might not be configured\n"
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci/*
578c2ecf20Sopenharmony_ci * Default timeout
588c2ecf20Sopenharmony_ci */
598c2ecf20Sopenharmony_ci#define SCSI_TIMEOUT (2*HZ)
608c2ecf20Sopenharmony_ci#define SCSI_REPORT_LUNS_TIMEOUT (30*HZ)
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci/*
638c2ecf20Sopenharmony_ci * Prefix values for the SCSI id's (stored in sysfs name field)
648c2ecf20Sopenharmony_ci */
658c2ecf20Sopenharmony_ci#define SCSI_UID_SER_NUM 'S'
668c2ecf20Sopenharmony_ci#define SCSI_UID_UNKNOWN 'Z'
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci/*
698c2ecf20Sopenharmony_ci * Return values of some of the scanning functions.
708c2ecf20Sopenharmony_ci *
718c2ecf20Sopenharmony_ci * SCSI_SCAN_NO_RESPONSE: no valid response received from the target, this
728c2ecf20Sopenharmony_ci * includes allocation or general failures preventing IO from being sent.
738c2ecf20Sopenharmony_ci *
748c2ecf20Sopenharmony_ci * SCSI_SCAN_TARGET_PRESENT: target responded, but no device is available
758c2ecf20Sopenharmony_ci * on the given LUN.
768c2ecf20Sopenharmony_ci *
778c2ecf20Sopenharmony_ci * SCSI_SCAN_LUN_PRESENT: target responded, and a device is available on a
788c2ecf20Sopenharmony_ci * given LUN.
798c2ecf20Sopenharmony_ci */
808c2ecf20Sopenharmony_ci#define SCSI_SCAN_NO_RESPONSE		0
818c2ecf20Sopenharmony_ci#define SCSI_SCAN_TARGET_PRESENT	1
828c2ecf20Sopenharmony_ci#define SCSI_SCAN_LUN_PRESENT		2
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_cistatic const char *scsi_null_device_strs = "nullnullnullnull";
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci#define MAX_SCSI_LUNS	512
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_cistatic u64 max_scsi_luns = MAX_SCSI_LUNS;
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_cimodule_param_named(max_luns, max_scsi_luns, ullong, S_IRUGO|S_IWUSR);
918c2ecf20Sopenharmony_ciMODULE_PARM_DESC(max_luns,
928c2ecf20Sopenharmony_ci		 "last scsi LUN (should be between 1 and 2^64-1)");
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci#ifdef CONFIG_SCSI_SCAN_ASYNC
958c2ecf20Sopenharmony_ci#define SCSI_SCAN_TYPE_DEFAULT "async"
968c2ecf20Sopenharmony_ci#else
978c2ecf20Sopenharmony_ci#define SCSI_SCAN_TYPE_DEFAULT "sync"
988c2ecf20Sopenharmony_ci#endif
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cichar scsi_scan_type[7] = SCSI_SCAN_TYPE_DEFAULT;
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_cimodule_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type),
1038c2ecf20Sopenharmony_ci		    S_IRUGO|S_IWUSR);
1048c2ecf20Sopenharmony_ciMODULE_PARM_DESC(scan, "sync, async, manual, or none. "
1058c2ecf20Sopenharmony_ci		 "Setting to 'manual' disables automatic scanning, but allows "
1068c2ecf20Sopenharmony_ci		 "for manual device scan via the 'scan' sysfs attribute.");
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_cistatic unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ + 18;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_cimodule_param_named(inq_timeout, scsi_inq_timeout, uint, S_IRUGO|S_IWUSR);
1118c2ecf20Sopenharmony_ciMODULE_PARM_DESC(inq_timeout,
1128c2ecf20Sopenharmony_ci		 "Timeout (in seconds) waiting for devices to answer INQUIRY."
1138c2ecf20Sopenharmony_ci		 " Default is 20. Some devices may need more; most need less.");
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci/* This lock protects only this list */
1168c2ecf20Sopenharmony_cistatic DEFINE_SPINLOCK(async_scan_lock);
1178c2ecf20Sopenharmony_cistatic LIST_HEAD(scanning_hosts);
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_cistruct async_scan_data {
1208c2ecf20Sopenharmony_ci	struct list_head list;
1218c2ecf20Sopenharmony_ci	struct Scsi_Host *shost;
1228c2ecf20Sopenharmony_ci	struct completion prev_finished;
1238c2ecf20Sopenharmony_ci};
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci/**
1268c2ecf20Sopenharmony_ci * scsi_complete_async_scans - Wait for asynchronous scans to complete
1278c2ecf20Sopenharmony_ci *
1288c2ecf20Sopenharmony_ci * When this function returns, any host which started scanning before
1298c2ecf20Sopenharmony_ci * this function was called will have finished its scan.  Hosts which
1308c2ecf20Sopenharmony_ci * started scanning after this function was called may or may not have
1318c2ecf20Sopenharmony_ci * finished.
1328c2ecf20Sopenharmony_ci */
1338c2ecf20Sopenharmony_ciint scsi_complete_async_scans(void)
1348c2ecf20Sopenharmony_ci{
1358c2ecf20Sopenharmony_ci	struct async_scan_data *data;
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	do {
1388c2ecf20Sopenharmony_ci		if (list_empty(&scanning_hosts))
1398c2ecf20Sopenharmony_ci			return 0;
1408c2ecf20Sopenharmony_ci		/* If we can't get memory immediately, that's OK.  Just
1418c2ecf20Sopenharmony_ci		 * sleep a little.  Even if we never get memory, the async
1428c2ecf20Sopenharmony_ci		 * scans will finish eventually.
1438c2ecf20Sopenharmony_ci		 */
1448c2ecf20Sopenharmony_ci		data = kmalloc(sizeof(*data), GFP_KERNEL);
1458c2ecf20Sopenharmony_ci		if (!data)
1468c2ecf20Sopenharmony_ci			msleep(1);
1478c2ecf20Sopenharmony_ci	} while (!data);
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci	data->shost = NULL;
1508c2ecf20Sopenharmony_ci	init_completion(&data->prev_finished);
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci	spin_lock(&async_scan_lock);
1538c2ecf20Sopenharmony_ci	/* Check that there's still somebody else on the list */
1548c2ecf20Sopenharmony_ci	if (list_empty(&scanning_hosts))
1558c2ecf20Sopenharmony_ci		goto done;
1568c2ecf20Sopenharmony_ci	list_add_tail(&data->list, &scanning_hosts);
1578c2ecf20Sopenharmony_ci	spin_unlock(&async_scan_lock);
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	printk(KERN_INFO "scsi: waiting for bus probes to complete ...\n");
1608c2ecf20Sopenharmony_ci	wait_for_completion(&data->prev_finished);
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	spin_lock(&async_scan_lock);
1638c2ecf20Sopenharmony_ci	list_del(&data->list);
1648c2ecf20Sopenharmony_ci	if (!list_empty(&scanning_hosts)) {
1658c2ecf20Sopenharmony_ci		struct async_scan_data *next = list_entry(scanning_hosts.next,
1668c2ecf20Sopenharmony_ci				struct async_scan_data, list);
1678c2ecf20Sopenharmony_ci		complete(&next->prev_finished);
1688c2ecf20Sopenharmony_ci	}
1698c2ecf20Sopenharmony_ci done:
1708c2ecf20Sopenharmony_ci	spin_unlock(&async_scan_lock);
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	kfree(data);
1738c2ecf20Sopenharmony_ci	return 0;
1748c2ecf20Sopenharmony_ci}
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci/**
1778c2ecf20Sopenharmony_ci * scsi_unlock_floptical - unlock device via a special MODE SENSE command
1788c2ecf20Sopenharmony_ci * @sdev:	scsi device to send command to
1798c2ecf20Sopenharmony_ci * @result:	area to store the result of the MODE SENSE
1808c2ecf20Sopenharmony_ci *
1818c2ecf20Sopenharmony_ci * Description:
1828c2ecf20Sopenharmony_ci *     Send a vendor specific MODE SENSE (not a MODE SELECT) command.
1838c2ecf20Sopenharmony_ci *     Called for BLIST_KEY devices.
1848c2ecf20Sopenharmony_ci **/
1858c2ecf20Sopenharmony_cistatic void scsi_unlock_floptical(struct scsi_device *sdev,
1868c2ecf20Sopenharmony_ci				  unsigned char *result)
1878c2ecf20Sopenharmony_ci{
1888c2ecf20Sopenharmony_ci	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	sdev_printk(KERN_NOTICE, sdev, "unlocking floptical drive\n");
1918c2ecf20Sopenharmony_ci	scsi_cmd[0] = MODE_SENSE;
1928c2ecf20Sopenharmony_ci	scsi_cmd[1] = 0;
1938c2ecf20Sopenharmony_ci	scsi_cmd[2] = 0x2e;
1948c2ecf20Sopenharmony_ci	scsi_cmd[3] = 0;
1958c2ecf20Sopenharmony_ci	scsi_cmd[4] = 0x2a;     /* size */
1968c2ecf20Sopenharmony_ci	scsi_cmd[5] = 0;
1978c2ecf20Sopenharmony_ci	scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, result, 0x2a, NULL,
1988c2ecf20Sopenharmony_ci			 SCSI_TIMEOUT, 3, NULL);
1998c2ecf20Sopenharmony_ci}
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci/**
2028c2ecf20Sopenharmony_ci * scsi_alloc_sdev - allocate and setup a scsi_Device
2038c2ecf20Sopenharmony_ci * @starget: which target to allocate a &scsi_device for
2048c2ecf20Sopenharmony_ci * @lun: which lun
2058c2ecf20Sopenharmony_ci * @hostdata: usually NULL and set by ->slave_alloc instead
2068c2ecf20Sopenharmony_ci *
2078c2ecf20Sopenharmony_ci * Description:
2088c2ecf20Sopenharmony_ci *     Allocate, initialize for io, and return a pointer to a scsi_Device.
2098c2ecf20Sopenharmony_ci *     Stores the @shost, @channel, @id, and @lun in the scsi_Device, and
2108c2ecf20Sopenharmony_ci *     adds scsi_Device to the appropriate list.
2118c2ecf20Sopenharmony_ci *
2128c2ecf20Sopenharmony_ci * Return value:
2138c2ecf20Sopenharmony_ci *     scsi_Device pointer, or NULL on failure.
2148c2ecf20Sopenharmony_ci **/
2158c2ecf20Sopenharmony_cistatic struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
2168c2ecf20Sopenharmony_ci					   u64 lun, void *hostdata)
2178c2ecf20Sopenharmony_ci{
2188c2ecf20Sopenharmony_ci	struct scsi_device *sdev;
2198c2ecf20Sopenharmony_ci	int display_failure_msg = 1, ret;
2208c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	sdev = kzalloc(sizeof(*sdev) + shost->transportt->device_size,
2238c2ecf20Sopenharmony_ci		       GFP_KERNEL);
2248c2ecf20Sopenharmony_ci	if (!sdev)
2258c2ecf20Sopenharmony_ci		goto out;
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci	sdev->vendor = scsi_null_device_strs;
2288c2ecf20Sopenharmony_ci	sdev->model = scsi_null_device_strs;
2298c2ecf20Sopenharmony_ci	sdev->rev = scsi_null_device_strs;
2308c2ecf20Sopenharmony_ci	sdev->host = shost;
2318c2ecf20Sopenharmony_ci	sdev->queue_ramp_up_period = SCSI_DEFAULT_RAMP_UP_PERIOD;
2328c2ecf20Sopenharmony_ci	sdev->id = starget->id;
2338c2ecf20Sopenharmony_ci	sdev->lun = lun;
2348c2ecf20Sopenharmony_ci	sdev->channel = starget->channel;
2358c2ecf20Sopenharmony_ci	mutex_init(&sdev->state_mutex);
2368c2ecf20Sopenharmony_ci	sdev->sdev_state = SDEV_CREATED;
2378c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&sdev->siblings);
2388c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&sdev->same_target_siblings);
2398c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&sdev->starved_entry);
2408c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&sdev->event_list);
2418c2ecf20Sopenharmony_ci	spin_lock_init(&sdev->list_lock);
2428c2ecf20Sopenharmony_ci	mutex_init(&sdev->inquiry_mutex);
2438c2ecf20Sopenharmony_ci	INIT_WORK(&sdev->event_work, scsi_evt_thread);
2448c2ecf20Sopenharmony_ci	INIT_WORK(&sdev->requeue_work, scsi_requeue_run_queue);
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci	sdev->sdev_gendev.parent = get_device(&starget->dev);
2478c2ecf20Sopenharmony_ci	sdev->sdev_target = starget;
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci	/* usually NULL and set by ->slave_alloc instead */
2508c2ecf20Sopenharmony_ci	sdev->hostdata = hostdata;
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci	/* if the device needs this changing, it may do so in the
2538c2ecf20Sopenharmony_ci	 * slave_configure function */
2548c2ecf20Sopenharmony_ci	sdev->max_device_blocked = SCSI_DEFAULT_DEVICE_BLOCKED;
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci	/*
2578c2ecf20Sopenharmony_ci	 * Some low level driver could use device->type
2588c2ecf20Sopenharmony_ci	 */
2598c2ecf20Sopenharmony_ci	sdev->type = -1;
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci	/*
2628c2ecf20Sopenharmony_ci	 * Assume that the device will have handshaking problems,
2638c2ecf20Sopenharmony_ci	 * and then fix this field later if it turns out it
2648c2ecf20Sopenharmony_ci	 * doesn't
2658c2ecf20Sopenharmony_ci	 */
2668c2ecf20Sopenharmony_ci	sdev->borken = 1;
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci	sdev->request_queue = scsi_mq_alloc_queue(sdev);
2698c2ecf20Sopenharmony_ci	if (!sdev->request_queue) {
2708c2ecf20Sopenharmony_ci		/* release fn is set up in scsi_sysfs_device_initialise, so
2718c2ecf20Sopenharmony_ci		 * have to free and put manually here */
2728c2ecf20Sopenharmony_ci		put_device(&starget->dev);
2738c2ecf20Sopenharmony_ci		kfree(sdev);
2748c2ecf20Sopenharmony_ci		goto out;
2758c2ecf20Sopenharmony_ci	}
2768c2ecf20Sopenharmony_ci	WARN_ON_ONCE(!blk_get_queue(sdev->request_queue));
2778c2ecf20Sopenharmony_ci	sdev->request_queue->queuedata = sdev;
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	scsi_change_queue_depth(sdev, sdev->host->cmd_per_lun ?
2808c2ecf20Sopenharmony_ci					sdev->host->cmd_per_lun : 1);
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci	scsi_sysfs_device_initialize(sdev);
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci	if (shost->hostt->slave_alloc) {
2858c2ecf20Sopenharmony_ci		ret = shost->hostt->slave_alloc(sdev);
2868c2ecf20Sopenharmony_ci		if (ret) {
2878c2ecf20Sopenharmony_ci			/*
2888c2ecf20Sopenharmony_ci			 * if LLDD reports slave not present, don't clutter
2898c2ecf20Sopenharmony_ci			 * console with alloc failure messages
2908c2ecf20Sopenharmony_ci			 */
2918c2ecf20Sopenharmony_ci			if (ret == -ENXIO)
2928c2ecf20Sopenharmony_ci				display_failure_msg = 0;
2938c2ecf20Sopenharmony_ci			goto out_device_destroy;
2948c2ecf20Sopenharmony_ci		}
2958c2ecf20Sopenharmony_ci	}
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ci	return sdev;
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ciout_device_destroy:
3008c2ecf20Sopenharmony_ci	__scsi_remove_device(sdev);
3018c2ecf20Sopenharmony_ciout:
3028c2ecf20Sopenharmony_ci	if (display_failure_msg)
3038c2ecf20Sopenharmony_ci		printk(ALLOC_FAILURE_MSG, __func__);
3048c2ecf20Sopenharmony_ci	return NULL;
3058c2ecf20Sopenharmony_ci}
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_cistatic void scsi_target_destroy(struct scsi_target *starget)
3088c2ecf20Sopenharmony_ci{
3098c2ecf20Sopenharmony_ci	struct device *dev = &starget->dev;
3108c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = dev_to_shost(dev->parent);
3118c2ecf20Sopenharmony_ci	unsigned long flags;
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci	BUG_ON(starget->state == STARGET_DEL);
3148c2ecf20Sopenharmony_ci	starget->state = STARGET_DEL;
3158c2ecf20Sopenharmony_ci	transport_destroy_device(dev);
3168c2ecf20Sopenharmony_ci	spin_lock_irqsave(shost->host_lock, flags);
3178c2ecf20Sopenharmony_ci	if (shost->hostt->target_destroy)
3188c2ecf20Sopenharmony_ci		shost->hostt->target_destroy(starget);
3198c2ecf20Sopenharmony_ci	list_del_init(&starget->siblings);
3208c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(shost->host_lock, flags);
3218c2ecf20Sopenharmony_ci	put_device(dev);
3228c2ecf20Sopenharmony_ci}
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_cistatic void scsi_target_dev_release(struct device *dev)
3258c2ecf20Sopenharmony_ci{
3268c2ecf20Sopenharmony_ci	struct device *parent = dev->parent;
3278c2ecf20Sopenharmony_ci	struct scsi_target *starget = to_scsi_target(dev);
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci	kfree(starget);
3308c2ecf20Sopenharmony_ci	put_device(parent);
3318c2ecf20Sopenharmony_ci}
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_cistatic struct device_type scsi_target_type = {
3348c2ecf20Sopenharmony_ci	.name =		"scsi_target",
3358c2ecf20Sopenharmony_ci	.release =	scsi_target_dev_release,
3368c2ecf20Sopenharmony_ci};
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ciint scsi_is_target_device(const struct device *dev)
3398c2ecf20Sopenharmony_ci{
3408c2ecf20Sopenharmony_ci	return dev->type == &scsi_target_type;
3418c2ecf20Sopenharmony_ci}
3428c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_is_target_device);
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_cistatic struct scsi_target *__scsi_find_target(struct device *parent,
3458c2ecf20Sopenharmony_ci					      int channel, uint id)
3468c2ecf20Sopenharmony_ci{
3478c2ecf20Sopenharmony_ci	struct scsi_target *starget, *found_starget = NULL;
3488c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = dev_to_shost(parent);
3498c2ecf20Sopenharmony_ci	/*
3508c2ecf20Sopenharmony_ci	 * Search for an existing target for this sdev.
3518c2ecf20Sopenharmony_ci	 */
3528c2ecf20Sopenharmony_ci	list_for_each_entry(starget, &shost->__targets, siblings) {
3538c2ecf20Sopenharmony_ci		if (starget->id == id &&
3548c2ecf20Sopenharmony_ci		    starget->channel == channel) {
3558c2ecf20Sopenharmony_ci			found_starget = starget;
3568c2ecf20Sopenharmony_ci			break;
3578c2ecf20Sopenharmony_ci		}
3588c2ecf20Sopenharmony_ci	}
3598c2ecf20Sopenharmony_ci	if (found_starget)
3608c2ecf20Sopenharmony_ci		get_device(&found_starget->dev);
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci	return found_starget;
3638c2ecf20Sopenharmony_ci}
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci/**
3668c2ecf20Sopenharmony_ci * scsi_target_reap_ref_release - remove target from visibility
3678c2ecf20Sopenharmony_ci * @kref: the reap_ref in the target being released
3688c2ecf20Sopenharmony_ci *
3698c2ecf20Sopenharmony_ci * Called on last put of reap_ref, which is the indication that no device
3708c2ecf20Sopenharmony_ci * under this target is visible anymore, so render the target invisible in
3718c2ecf20Sopenharmony_ci * sysfs.  Note: we have to be in user context here because the target reaps
3728c2ecf20Sopenharmony_ci * should be done in places where the scsi device visibility is being removed.
3738c2ecf20Sopenharmony_ci */
3748c2ecf20Sopenharmony_cistatic void scsi_target_reap_ref_release(struct kref *kref)
3758c2ecf20Sopenharmony_ci{
3768c2ecf20Sopenharmony_ci	struct scsi_target *starget
3778c2ecf20Sopenharmony_ci		= container_of(kref, struct scsi_target, reap_ref);
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_ci	/*
3808c2ecf20Sopenharmony_ci	 * if we get here and the target is still in a CREATED state that
3818c2ecf20Sopenharmony_ci	 * means it was allocated but never made visible (because a scan
3828c2ecf20Sopenharmony_ci	 * turned up no LUNs), so don't call device_del() on it.
3838c2ecf20Sopenharmony_ci	 */
3848c2ecf20Sopenharmony_ci	if ((starget->state != STARGET_CREATED) &&
3858c2ecf20Sopenharmony_ci	    (starget->state != STARGET_CREATED_REMOVE)) {
3868c2ecf20Sopenharmony_ci		transport_remove_device(&starget->dev);
3878c2ecf20Sopenharmony_ci		device_del(&starget->dev);
3888c2ecf20Sopenharmony_ci	}
3898c2ecf20Sopenharmony_ci	scsi_target_destroy(starget);
3908c2ecf20Sopenharmony_ci}
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_cistatic void scsi_target_reap_ref_put(struct scsi_target *starget)
3938c2ecf20Sopenharmony_ci{
3948c2ecf20Sopenharmony_ci	kref_put(&starget->reap_ref, scsi_target_reap_ref_release);
3958c2ecf20Sopenharmony_ci}
3968c2ecf20Sopenharmony_ci
3978c2ecf20Sopenharmony_ci/**
3988c2ecf20Sopenharmony_ci * scsi_alloc_target - allocate a new or find an existing target
3998c2ecf20Sopenharmony_ci * @parent:	parent of the target (need not be a scsi host)
4008c2ecf20Sopenharmony_ci * @channel:	target channel number (zero if no channels)
4018c2ecf20Sopenharmony_ci * @id:		target id number
4028c2ecf20Sopenharmony_ci *
4038c2ecf20Sopenharmony_ci * Return an existing target if one exists, provided it hasn't already
4048c2ecf20Sopenharmony_ci * gone into STARGET_DEL state, otherwise allocate a new target.
4058c2ecf20Sopenharmony_ci *
4068c2ecf20Sopenharmony_ci * The target is returned with an incremented reference, so the caller
4078c2ecf20Sopenharmony_ci * is responsible for both reaping and doing a last put
4088c2ecf20Sopenharmony_ci */
4098c2ecf20Sopenharmony_cistatic struct scsi_target *scsi_alloc_target(struct device *parent,
4108c2ecf20Sopenharmony_ci					     int channel, uint id)
4118c2ecf20Sopenharmony_ci{
4128c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = dev_to_shost(parent);
4138c2ecf20Sopenharmony_ci	struct device *dev = NULL;
4148c2ecf20Sopenharmony_ci	unsigned long flags;
4158c2ecf20Sopenharmony_ci	const int size = sizeof(struct scsi_target)
4168c2ecf20Sopenharmony_ci		+ shost->transportt->target_size;
4178c2ecf20Sopenharmony_ci	struct scsi_target *starget;
4188c2ecf20Sopenharmony_ci	struct scsi_target *found_target;
4198c2ecf20Sopenharmony_ci	int error, ref_got;
4208c2ecf20Sopenharmony_ci
4218c2ecf20Sopenharmony_ci	starget = kzalloc(size, GFP_KERNEL);
4228c2ecf20Sopenharmony_ci	if (!starget) {
4238c2ecf20Sopenharmony_ci		printk(KERN_ERR "%s: allocation failure\n", __func__);
4248c2ecf20Sopenharmony_ci		return NULL;
4258c2ecf20Sopenharmony_ci	}
4268c2ecf20Sopenharmony_ci	dev = &starget->dev;
4278c2ecf20Sopenharmony_ci	device_initialize(dev);
4288c2ecf20Sopenharmony_ci	kref_init(&starget->reap_ref);
4298c2ecf20Sopenharmony_ci	dev->parent = get_device(parent);
4308c2ecf20Sopenharmony_ci	dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
4318c2ecf20Sopenharmony_ci	dev->bus = &scsi_bus_type;
4328c2ecf20Sopenharmony_ci	dev->type = &scsi_target_type;
4338c2ecf20Sopenharmony_ci	starget->id = id;
4348c2ecf20Sopenharmony_ci	starget->channel = channel;
4358c2ecf20Sopenharmony_ci	starget->can_queue = 0;
4368c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&starget->siblings);
4378c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&starget->devices);
4388c2ecf20Sopenharmony_ci	starget->state = STARGET_CREATED;
4398c2ecf20Sopenharmony_ci	starget->scsi_level = SCSI_2;
4408c2ecf20Sopenharmony_ci	starget->max_target_blocked = SCSI_DEFAULT_TARGET_BLOCKED;
4418c2ecf20Sopenharmony_ci retry:
4428c2ecf20Sopenharmony_ci	spin_lock_irqsave(shost->host_lock, flags);
4438c2ecf20Sopenharmony_ci
4448c2ecf20Sopenharmony_ci	found_target = __scsi_find_target(parent, channel, id);
4458c2ecf20Sopenharmony_ci	if (found_target)
4468c2ecf20Sopenharmony_ci		goto found;
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci	list_add_tail(&starget->siblings, &shost->__targets);
4498c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(shost->host_lock, flags);
4508c2ecf20Sopenharmony_ci	/* allocate and add */
4518c2ecf20Sopenharmony_ci	transport_setup_device(dev);
4528c2ecf20Sopenharmony_ci	if (shost->hostt->target_alloc) {
4538c2ecf20Sopenharmony_ci		error = shost->hostt->target_alloc(starget);
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci		if(error) {
4568c2ecf20Sopenharmony_ci			if (error != -ENXIO)
4578c2ecf20Sopenharmony_ci				dev_err(dev, "target allocation failed, error %d\n", error);
4588c2ecf20Sopenharmony_ci			/* don't want scsi_target_reap to do the final
4598c2ecf20Sopenharmony_ci			 * put because it will be under the host lock */
4608c2ecf20Sopenharmony_ci			scsi_target_destroy(starget);
4618c2ecf20Sopenharmony_ci			return NULL;
4628c2ecf20Sopenharmony_ci		}
4638c2ecf20Sopenharmony_ci	}
4648c2ecf20Sopenharmony_ci	get_device(dev);
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ci	return starget;
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_ci found:
4698c2ecf20Sopenharmony_ci	/*
4708c2ecf20Sopenharmony_ci	 * release routine already fired if kref is zero, so if we can still
4718c2ecf20Sopenharmony_ci	 * take the reference, the target must be alive.  If we can't, it must
4728c2ecf20Sopenharmony_ci	 * be dying and we need to wait for a new target
4738c2ecf20Sopenharmony_ci	 */
4748c2ecf20Sopenharmony_ci	ref_got = kref_get_unless_zero(&found_target->reap_ref);
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(shost->host_lock, flags);
4778c2ecf20Sopenharmony_ci	if (ref_got) {
4788c2ecf20Sopenharmony_ci		put_device(dev);
4798c2ecf20Sopenharmony_ci		return found_target;
4808c2ecf20Sopenharmony_ci	}
4818c2ecf20Sopenharmony_ci	/*
4828c2ecf20Sopenharmony_ci	 * Unfortunately, we found a dying target; need to wait until it's
4838c2ecf20Sopenharmony_ci	 * dead before we can get a new one.  There is an anomaly here.  We
4848c2ecf20Sopenharmony_ci	 * *should* call scsi_target_reap() to balance the kref_get() of the
4858c2ecf20Sopenharmony_ci	 * reap_ref above.  However, since the target being released, it's
4868c2ecf20Sopenharmony_ci	 * already invisible and the reap_ref is irrelevant.  If we call
4878c2ecf20Sopenharmony_ci	 * scsi_target_reap() we might spuriously do another device_del() on
4888c2ecf20Sopenharmony_ci	 * an already invisible target.
4898c2ecf20Sopenharmony_ci	 */
4908c2ecf20Sopenharmony_ci	put_device(&found_target->dev);
4918c2ecf20Sopenharmony_ci	/*
4928c2ecf20Sopenharmony_ci	 * length of time is irrelevant here, we just want to yield the CPU
4938c2ecf20Sopenharmony_ci	 * for a tick to avoid busy waiting for the target to die.
4948c2ecf20Sopenharmony_ci	 */
4958c2ecf20Sopenharmony_ci	msleep(1);
4968c2ecf20Sopenharmony_ci	goto retry;
4978c2ecf20Sopenharmony_ci}
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_ci/**
5008c2ecf20Sopenharmony_ci * scsi_target_reap - check to see if target is in use and destroy if not
5018c2ecf20Sopenharmony_ci * @starget: target to be checked
5028c2ecf20Sopenharmony_ci *
5038c2ecf20Sopenharmony_ci * This is used after removing a LUN or doing a last put of the target
5048c2ecf20Sopenharmony_ci * it checks atomically that nothing is using the target and removes
5058c2ecf20Sopenharmony_ci * it if so.
5068c2ecf20Sopenharmony_ci */
5078c2ecf20Sopenharmony_civoid scsi_target_reap(struct scsi_target *starget)
5088c2ecf20Sopenharmony_ci{
5098c2ecf20Sopenharmony_ci	/*
5108c2ecf20Sopenharmony_ci	 * serious problem if this triggers: STARGET_DEL is only set in the if
5118c2ecf20Sopenharmony_ci	 * the reap_ref drops to zero, so we're trying to do another final put
5128c2ecf20Sopenharmony_ci	 * on an already released kref
5138c2ecf20Sopenharmony_ci	 */
5148c2ecf20Sopenharmony_ci	BUG_ON(starget->state == STARGET_DEL);
5158c2ecf20Sopenharmony_ci	scsi_target_reap_ref_put(starget);
5168c2ecf20Sopenharmony_ci}
5178c2ecf20Sopenharmony_ci
5188c2ecf20Sopenharmony_ci/**
5198c2ecf20Sopenharmony_ci * scsi_sanitize_inquiry_string - remove non-graphical chars from an
5208c2ecf20Sopenharmony_ci *                                INQUIRY result string
5218c2ecf20Sopenharmony_ci * @s: INQUIRY result string to sanitize
5228c2ecf20Sopenharmony_ci * @len: length of the string
5238c2ecf20Sopenharmony_ci *
5248c2ecf20Sopenharmony_ci * Description:
5258c2ecf20Sopenharmony_ci *	The SCSI spec says that INQUIRY vendor, product, and revision
5268c2ecf20Sopenharmony_ci *	strings must consist entirely of graphic ASCII characters,
5278c2ecf20Sopenharmony_ci *	padded on the right with spaces.  Since not all devices obey
5288c2ecf20Sopenharmony_ci *	this rule, we will replace non-graphic or non-ASCII characters
5298c2ecf20Sopenharmony_ci *	with spaces.  Exception: a NUL character is interpreted as a
5308c2ecf20Sopenharmony_ci *	string terminator, so all the following characters are set to
5318c2ecf20Sopenharmony_ci *	spaces.
5328c2ecf20Sopenharmony_ci **/
5338c2ecf20Sopenharmony_civoid scsi_sanitize_inquiry_string(unsigned char *s, int len)
5348c2ecf20Sopenharmony_ci{
5358c2ecf20Sopenharmony_ci	int terminated = 0;
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_ci	for (; len > 0; (--len, ++s)) {
5388c2ecf20Sopenharmony_ci		if (*s == 0)
5398c2ecf20Sopenharmony_ci			terminated = 1;
5408c2ecf20Sopenharmony_ci		if (terminated || *s < 0x20 || *s > 0x7e)
5418c2ecf20Sopenharmony_ci			*s = ' ';
5428c2ecf20Sopenharmony_ci	}
5438c2ecf20Sopenharmony_ci}
5448c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_sanitize_inquiry_string);
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_ci/**
5478c2ecf20Sopenharmony_ci * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY
5488c2ecf20Sopenharmony_ci * @sdev:	scsi_device to probe
5498c2ecf20Sopenharmony_ci * @inq_result:	area to store the INQUIRY result
5508c2ecf20Sopenharmony_ci * @result_len: len of inq_result
5518c2ecf20Sopenharmony_ci * @bflags:	store any bflags found here
5528c2ecf20Sopenharmony_ci *
5538c2ecf20Sopenharmony_ci * Description:
5548c2ecf20Sopenharmony_ci *     Probe the lun associated with @req using a standard SCSI INQUIRY;
5558c2ecf20Sopenharmony_ci *
5568c2ecf20Sopenharmony_ci *     If the INQUIRY is successful, zero is returned and the
5578c2ecf20Sopenharmony_ci *     INQUIRY data is in @inq_result; the scsi_level and INQUIRY length
5588c2ecf20Sopenharmony_ci *     are copied to the scsi_device any flags value is stored in *@bflags.
5598c2ecf20Sopenharmony_ci **/
5608c2ecf20Sopenharmony_cistatic int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
5618c2ecf20Sopenharmony_ci			  int result_len, blist_flags_t *bflags)
5628c2ecf20Sopenharmony_ci{
5638c2ecf20Sopenharmony_ci	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
5648c2ecf20Sopenharmony_ci	int first_inquiry_len, try_inquiry_len, next_inquiry_len;
5658c2ecf20Sopenharmony_ci	int response_len = 0;
5668c2ecf20Sopenharmony_ci	int pass, count, result;
5678c2ecf20Sopenharmony_ci	struct scsi_sense_hdr sshdr;
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci	*bflags = 0;
5708c2ecf20Sopenharmony_ci
5718c2ecf20Sopenharmony_ci	/* Perform up to 3 passes.  The first pass uses a conservative
5728c2ecf20Sopenharmony_ci	 * transfer length of 36 unless sdev->inquiry_len specifies a
5738c2ecf20Sopenharmony_ci	 * different value. */
5748c2ecf20Sopenharmony_ci	first_inquiry_len = sdev->inquiry_len ? sdev->inquiry_len : 36;
5758c2ecf20Sopenharmony_ci	try_inquiry_len = first_inquiry_len;
5768c2ecf20Sopenharmony_ci	pass = 1;
5778c2ecf20Sopenharmony_ci
5788c2ecf20Sopenharmony_ci next_pass:
5798c2ecf20Sopenharmony_ci	SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
5808c2ecf20Sopenharmony_ci				"scsi scan: INQUIRY pass %d length %d\n",
5818c2ecf20Sopenharmony_ci				pass, try_inquiry_len));
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_ci	/* Each pass gets up to three chances to ignore Unit Attention */
5848c2ecf20Sopenharmony_ci	for (count = 0; count < 3; ++count) {
5858c2ecf20Sopenharmony_ci		int resid;
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ci		memset(scsi_cmd, 0, 6);
5888c2ecf20Sopenharmony_ci		scsi_cmd[0] = INQUIRY;
5898c2ecf20Sopenharmony_ci		scsi_cmd[4] = (unsigned char) try_inquiry_len;
5908c2ecf20Sopenharmony_ci
5918c2ecf20Sopenharmony_ci		memset(inq_result, 0, try_inquiry_len);
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_ci		result = scsi_execute_req(sdev,  scsi_cmd, DMA_FROM_DEVICE,
5948c2ecf20Sopenharmony_ci					  inq_result, try_inquiry_len, &sshdr,
5958c2ecf20Sopenharmony_ci					  HZ / 2 + HZ * scsi_inq_timeout, 3,
5968c2ecf20Sopenharmony_ci					  &resid);
5978c2ecf20Sopenharmony_ci
5988c2ecf20Sopenharmony_ci		SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
5998c2ecf20Sopenharmony_ci				"scsi scan: INQUIRY %s with code 0x%x\n",
6008c2ecf20Sopenharmony_ci				result ? "failed" : "successful", result));
6018c2ecf20Sopenharmony_ci
6028c2ecf20Sopenharmony_ci		if (result) {
6038c2ecf20Sopenharmony_ci			/*
6048c2ecf20Sopenharmony_ci			 * not-ready to ready transition [asc/ascq=0x28/0x0]
6058c2ecf20Sopenharmony_ci			 * or power-on, reset [asc/ascq=0x29/0x0], continue.
6068c2ecf20Sopenharmony_ci			 * INQUIRY should not yield UNIT_ATTENTION
6078c2ecf20Sopenharmony_ci			 * but many buggy devices do so anyway.
6088c2ecf20Sopenharmony_ci			 */
6098c2ecf20Sopenharmony_ci			if (driver_byte(result) == DRIVER_SENSE &&
6108c2ecf20Sopenharmony_ci			    scsi_sense_valid(&sshdr)) {
6118c2ecf20Sopenharmony_ci				if ((sshdr.sense_key == UNIT_ATTENTION) &&
6128c2ecf20Sopenharmony_ci				    ((sshdr.asc == 0x28) ||
6138c2ecf20Sopenharmony_ci				     (sshdr.asc == 0x29)) &&
6148c2ecf20Sopenharmony_ci				    (sshdr.ascq == 0))
6158c2ecf20Sopenharmony_ci					continue;
6168c2ecf20Sopenharmony_ci			}
6178c2ecf20Sopenharmony_ci		} else {
6188c2ecf20Sopenharmony_ci			/*
6198c2ecf20Sopenharmony_ci			 * if nothing was transferred, we try
6208c2ecf20Sopenharmony_ci			 * again. It's a workaround for some USB
6218c2ecf20Sopenharmony_ci			 * devices.
6228c2ecf20Sopenharmony_ci			 */
6238c2ecf20Sopenharmony_ci			if (resid == try_inquiry_len)
6248c2ecf20Sopenharmony_ci				continue;
6258c2ecf20Sopenharmony_ci		}
6268c2ecf20Sopenharmony_ci		break;
6278c2ecf20Sopenharmony_ci	}
6288c2ecf20Sopenharmony_ci
6298c2ecf20Sopenharmony_ci	if (result == 0) {
6308c2ecf20Sopenharmony_ci		scsi_sanitize_inquiry_string(&inq_result[8], 8);
6318c2ecf20Sopenharmony_ci		scsi_sanitize_inquiry_string(&inq_result[16], 16);
6328c2ecf20Sopenharmony_ci		scsi_sanitize_inquiry_string(&inq_result[32], 4);
6338c2ecf20Sopenharmony_ci
6348c2ecf20Sopenharmony_ci		response_len = inq_result[4] + 5;
6358c2ecf20Sopenharmony_ci		if (response_len > 255)
6368c2ecf20Sopenharmony_ci			response_len = first_inquiry_len;	/* sanity */
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_ci		/*
6398c2ecf20Sopenharmony_ci		 * Get any flags for this device.
6408c2ecf20Sopenharmony_ci		 *
6418c2ecf20Sopenharmony_ci		 * XXX add a bflags to scsi_device, and replace the
6428c2ecf20Sopenharmony_ci		 * corresponding bit fields in scsi_device, so bflags
6438c2ecf20Sopenharmony_ci		 * need not be passed as an argument.
6448c2ecf20Sopenharmony_ci		 */
6458c2ecf20Sopenharmony_ci		*bflags = scsi_get_device_flags(sdev, &inq_result[8],
6468c2ecf20Sopenharmony_ci				&inq_result[16]);
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_ci		/* When the first pass succeeds we gain information about
6498c2ecf20Sopenharmony_ci		 * what larger transfer lengths might work. */
6508c2ecf20Sopenharmony_ci		if (pass == 1) {
6518c2ecf20Sopenharmony_ci			if (BLIST_INQUIRY_36 & *bflags)
6528c2ecf20Sopenharmony_ci				next_inquiry_len = 36;
6538c2ecf20Sopenharmony_ci			else if (sdev->inquiry_len)
6548c2ecf20Sopenharmony_ci				next_inquiry_len = sdev->inquiry_len;
6558c2ecf20Sopenharmony_ci			else
6568c2ecf20Sopenharmony_ci				next_inquiry_len = response_len;
6578c2ecf20Sopenharmony_ci
6588c2ecf20Sopenharmony_ci			/* If more data is available perform the second pass */
6598c2ecf20Sopenharmony_ci			if (next_inquiry_len > try_inquiry_len) {
6608c2ecf20Sopenharmony_ci				try_inquiry_len = next_inquiry_len;
6618c2ecf20Sopenharmony_ci				pass = 2;
6628c2ecf20Sopenharmony_ci				goto next_pass;
6638c2ecf20Sopenharmony_ci			}
6648c2ecf20Sopenharmony_ci		}
6658c2ecf20Sopenharmony_ci
6668c2ecf20Sopenharmony_ci	} else if (pass == 2) {
6678c2ecf20Sopenharmony_ci		sdev_printk(KERN_INFO, sdev,
6688c2ecf20Sopenharmony_ci			    "scsi scan: %d byte inquiry failed.  "
6698c2ecf20Sopenharmony_ci			    "Consider BLIST_INQUIRY_36 for this device\n",
6708c2ecf20Sopenharmony_ci			    try_inquiry_len);
6718c2ecf20Sopenharmony_ci
6728c2ecf20Sopenharmony_ci		/* If this pass failed, the third pass goes back and transfers
6738c2ecf20Sopenharmony_ci		 * the same amount as we successfully got in the first pass. */
6748c2ecf20Sopenharmony_ci		try_inquiry_len = first_inquiry_len;
6758c2ecf20Sopenharmony_ci		pass = 3;
6768c2ecf20Sopenharmony_ci		goto next_pass;
6778c2ecf20Sopenharmony_ci	}
6788c2ecf20Sopenharmony_ci
6798c2ecf20Sopenharmony_ci	/* If the last transfer attempt got an error, assume the
6808c2ecf20Sopenharmony_ci	 * peripheral doesn't exist or is dead. */
6818c2ecf20Sopenharmony_ci	if (result)
6828c2ecf20Sopenharmony_ci		return -EIO;
6838c2ecf20Sopenharmony_ci
6848c2ecf20Sopenharmony_ci	/* Don't report any more data than the device says is valid */
6858c2ecf20Sopenharmony_ci	sdev->inquiry_len = min(try_inquiry_len, response_len);
6868c2ecf20Sopenharmony_ci
6878c2ecf20Sopenharmony_ci	/*
6888c2ecf20Sopenharmony_ci	 * XXX Abort if the response length is less than 36? If less than
6898c2ecf20Sopenharmony_ci	 * 32, the lookup of the device flags (above) could be invalid,
6908c2ecf20Sopenharmony_ci	 * and it would be possible to take an incorrect action - we do
6918c2ecf20Sopenharmony_ci	 * not want to hang because of a short INQUIRY. On the flip side,
6928c2ecf20Sopenharmony_ci	 * if the device is spun down or becoming ready (and so it gives a
6938c2ecf20Sopenharmony_ci	 * short INQUIRY), an abort here prevents any further use of the
6948c2ecf20Sopenharmony_ci	 * device, including spin up.
6958c2ecf20Sopenharmony_ci	 *
6968c2ecf20Sopenharmony_ci	 * On the whole, the best approach seems to be to assume the first
6978c2ecf20Sopenharmony_ci	 * 36 bytes are valid no matter what the device says.  That's
6988c2ecf20Sopenharmony_ci	 * better than copying < 36 bytes to the inquiry-result buffer
6998c2ecf20Sopenharmony_ci	 * and displaying garbage for the Vendor, Product, or Revision
7008c2ecf20Sopenharmony_ci	 * strings.
7018c2ecf20Sopenharmony_ci	 */
7028c2ecf20Sopenharmony_ci	if (sdev->inquiry_len < 36) {
7038c2ecf20Sopenharmony_ci		if (!sdev->host->short_inquiry) {
7048c2ecf20Sopenharmony_ci			shost_printk(KERN_INFO, sdev->host,
7058c2ecf20Sopenharmony_ci				    "scsi scan: INQUIRY result too short (%d),"
7068c2ecf20Sopenharmony_ci				    " using 36\n", sdev->inquiry_len);
7078c2ecf20Sopenharmony_ci			sdev->host->short_inquiry = 1;
7088c2ecf20Sopenharmony_ci		}
7098c2ecf20Sopenharmony_ci		sdev->inquiry_len = 36;
7108c2ecf20Sopenharmony_ci	}
7118c2ecf20Sopenharmony_ci
7128c2ecf20Sopenharmony_ci	/*
7138c2ecf20Sopenharmony_ci	 * Related to the above issue:
7148c2ecf20Sopenharmony_ci	 *
7158c2ecf20Sopenharmony_ci	 * XXX Devices (disk or all?) should be sent a TEST UNIT READY,
7168c2ecf20Sopenharmony_ci	 * and if not ready, sent a START_STOP to start (maybe spin up) and
7178c2ecf20Sopenharmony_ci	 * then send the INQUIRY again, since the INQUIRY can change after
7188c2ecf20Sopenharmony_ci	 * a device is initialized.
7198c2ecf20Sopenharmony_ci	 *
7208c2ecf20Sopenharmony_ci	 * Ideally, start a device if explicitly asked to do so.  This
7218c2ecf20Sopenharmony_ci	 * assumes that a device is spun up on power on, spun down on
7228c2ecf20Sopenharmony_ci	 * request, and then spun up on request.
7238c2ecf20Sopenharmony_ci	 */
7248c2ecf20Sopenharmony_ci
7258c2ecf20Sopenharmony_ci	/*
7268c2ecf20Sopenharmony_ci	 * The scanning code needs to know the scsi_level, even if no
7278c2ecf20Sopenharmony_ci	 * device is attached at LUN 0 (SCSI_SCAN_TARGET_PRESENT) so
7288c2ecf20Sopenharmony_ci	 * non-zero LUNs can be scanned.
7298c2ecf20Sopenharmony_ci	 */
7308c2ecf20Sopenharmony_ci	sdev->scsi_level = inq_result[2] & 0x07;
7318c2ecf20Sopenharmony_ci	if (sdev->scsi_level >= 2 ||
7328c2ecf20Sopenharmony_ci	    (sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1))
7338c2ecf20Sopenharmony_ci		sdev->scsi_level++;
7348c2ecf20Sopenharmony_ci	sdev->sdev_target->scsi_level = sdev->scsi_level;
7358c2ecf20Sopenharmony_ci
7368c2ecf20Sopenharmony_ci	/*
7378c2ecf20Sopenharmony_ci	 * If SCSI-2 or lower, and if the transport requires it,
7388c2ecf20Sopenharmony_ci	 * store the LUN value in CDB[1].
7398c2ecf20Sopenharmony_ci	 */
7408c2ecf20Sopenharmony_ci	sdev->lun_in_cdb = 0;
7418c2ecf20Sopenharmony_ci	if (sdev->scsi_level <= SCSI_2 &&
7428c2ecf20Sopenharmony_ci	    sdev->scsi_level != SCSI_UNKNOWN &&
7438c2ecf20Sopenharmony_ci	    !sdev->host->no_scsi2_lun_in_cdb)
7448c2ecf20Sopenharmony_ci		sdev->lun_in_cdb = 1;
7458c2ecf20Sopenharmony_ci
7468c2ecf20Sopenharmony_ci	return 0;
7478c2ecf20Sopenharmony_ci}
7488c2ecf20Sopenharmony_ci
7498c2ecf20Sopenharmony_ci/**
7508c2ecf20Sopenharmony_ci * scsi_add_lun - allocate and fully initialze a scsi_device
7518c2ecf20Sopenharmony_ci * @sdev:	holds information to be stored in the new scsi_device
7528c2ecf20Sopenharmony_ci * @inq_result:	holds the result of a previous INQUIRY to the LUN
7538c2ecf20Sopenharmony_ci * @bflags:	black/white list flag
7548c2ecf20Sopenharmony_ci * @async:	1 if this device is being scanned asynchronously
7558c2ecf20Sopenharmony_ci *
7568c2ecf20Sopenharmony_ci * Description:
7578c2ecf20Sopenharmony_ci *     Initialize the scsi_device @sdev.  Optionally set fields based
7588c2ecf20Sopenharmony_ci *     on values in *@bflags.
7598c2ecf20Sopenharmony_ci *
7608c2ecf20Sopenharmony_ci * Return:
7618c2ecf20Sopenharmony_ci *     SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
7628c2ecf20Sopenharmony_ci *     SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
7638c2ecf20Sopenharmony_ci **/
7648c2ecf20Sopenharmony_cistatic int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
7658c2ecf20Sopenharmony_ci		blist_flags_t *bflags, int async)
7668c2ecf20Sopenharmony_ci{
7678c2ecf20Sopenharmony_ci	int ret;
7688c2ecf20Sopenharmony_ci
7698c2ecf20Sopenharmony_ci	/*
7708c2ecf20Sopenharmony_ci	 * XXX do not save the inquiry, since it can change underneath us,
7718c2ecf20Sopenharmony_ci	 * save just vendor/model/rev.
7728c2ecf20Sopenharmony_ci	 *
7738c2ecf20Sopenharmony_ci	 * Rather than save it and have an ioctl that retrieves the saved
7748c2ecf20Sopenharmony_ci	 * value, have an ioctl that executes the same INQUIRY code used
7758c2ecf20Sopenharmony_ci	 * in scsi_probe_lun, let user level programs doing INQUIRY
7768c2ecf20Sopenharmony_ci	 * scanning run at their own risk, or supply a user level program
7778c2ecf20Sopenharmony_ci	 * that can correctly scan.
7788c2ecf20Sopenharmony_ci	 */
7798c2ecf20Sopenharmony_ci
7808c2ecf20Sopenharmony_ci	/*
7818c2ecf20Sopenharmony_ci	 * Copy at least 36 bytes of INQUIRY data, so that we don't
7828c2ecf20Sopenharmony_ci	 * dereference unallocated memory when accessing the Vendor,
7838c2ecf20Sopenharmony_ci	 * Product, and Revision strings.  Badly behaved devices may set
7848c2ecf20Sopenharmony_ci	 * the INQUIRY Additional Length byte to a small value, indicating
7858c2ecf20Sopenharmony_ci	 * these strings are invalid, but often they contain plausible data
7868c2ecf20Sopenharmony_ci	 * nonetheless.  It doesn't matter if the device sent < 36 bytes
7878c2ecf20Sopenharmony_ci	 * total, since scsi_probe_lun() initializes inq_result with 0s.
7888c2ecf20Sopenharmony_ci	 */
7898c2ecf20Sopenharmony_ci	sdev->inquiry = kmemdup(inq_result,
7908c2ecf20Sopenharmony_ci				max_t(size_t, sdev->inquiry_len, 36),
7918c2ecf20Sopenharmony_ci				GFP_KERNEL);
7928c2ecf20Sopenharmony_ci	if (sdev->inquiry == NULL)
7938c2ecf20Sopenharmony_ci		return SCSI_SCAN_NO_RESPONSE;
7948c2ecf20Sopenharmony_ci
7958c2ecf20Sopenharmony_ci	sdev->vendor = (char *) (sdev->inquiry + 8);
7968c2ecf20Sopenharmony_ci	sdev->model = (char *) (sdev->inquiry + 16);
7978c2ecf20Sopenharmony_ci	sdev->rev = (char *) (sdev->inquiry + 32);
7988c2ecf20Sopenharmony_ci
7998c2ecf20Sopenharmony_ci	if (strncmp(sdev->vendor, "ATA     ", 8) == 0) {
8008c2ecf20Sopenharmony_ci		/*
8018c2ecf20Sopenharmony_ci		 * sata emulation layer device.  This is a hack to work around
8028c2ecf20Sopenharmony_ci		 * the SATL power management specifications which state that
8038c2ecf20Sopenharmony_ci		 * when the SATL detects the device has gone into standby
8048c2ecf20Sopenharmony_ci		 * mode, it shall respond with NOT READY.
8058c2ecf20Sopenharmony_ci		 */
8068c2ecf20Sopenharmony_ci		sdev->allow_restart = 1;
8078c2ecf20Sopenharmony_ci	}
8088c2ecf20Sopenharmony_ci
8098c2ecf20Sopenharmony_ci	if (*bflags & BLIST_ISROM) {
8108c2ecf20Sopenharmony_ci		sdev->type = TYPE_ROM;
8118c2ecf20Sopenharmony_ci		sdev->removable = 1;
8128c2ecf20Sopenharmony_ci	} else {
8138c2ecf20Sopenharmony_ci		sdev->type = (inq_result[0] & 0x1f);
8148c2ecf20Sopenharmony_ci		sdev->removable = (inq_result[1] & 0x80) >> 7;
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_ci		/*
8178c2ecf20Sopenharmony_ci		 * some devices may respond with wrong type for
8188c2ecf20Sopenharmony_ci		 * well-known logical units. Force well-known type
8198c2ecf20Sopenharmony_ci		 * to enumerate them correctly.
8208c2ecf20Sopenharmony_ci		 */
8218c2ecf20Sopenharmony_ci		if (scsi_is_wlun(sdev->lun) && sdev->type != TYPE_WLUN) {
8228c2ecf20Sopenharmony_ci			sdev_printk(KERN_WARNING, sdev,
8238c2ecf20Sopenharmony_ci				"%s: correcting incorrect peripheral device type 0x%x for W-LUN 0x%16xhN\n",
8248c2ecf20Sopenharmony_ci				__func__, sdev->type, (unsigned int)sdev->lun);
8258c2ecf20Sopenharmony_ci			sdev->type = TYPE_WLUN;
8268c2ecf20Sopenharmony_ci		}
8278c2ecf20Sopenharmony_ci
8288c2ecf20Sopenharmony_ci	}
8298c2ecf20Sopenharmony_ci
8308c2ecf20Sopenharmony_ci	if (sdev->type == TYPE_RBC || sdev->type == TYPE_ROM) {
8318c2ecf20Sopenharmony_ci		/* RBC and MMC devices can return SCSI-3 compliance and yet
8328c2ecf20Sopenharmony_ci		 * still not support REPORT LUNS, so make them act as
8338c2ecf20Sopenharmony_ci		 * BLIST_NOREPORTLUN unless BLIST_REPORTLUN2 is
8348c2ecf20Sopenharmony_ci		 * specifically set */
8358c2ecf20Sopenharmony_ci		if ((*bflags & BLIST_REPORTLUN2) == 0)
8368c2ecf20Sopenharmony_ci			*bflags |= BLIST_NOREPORTLUN;
8378c2ecf20Sopenharmony_ci	}
8388c2ecf20Sopenharmony_ci
8398c2ecf20Sopenharmony_ci	/*
8408c2ecf20Sopenharmony_ci	 * For a peripheral qualifier (PQ) value of 1 (001b), the SCSI
8418c2ecf20Sopenharmony_ci	 * spec says: The device server is capable of supporting the
8428c2ecf20Sopenharmony_ci	 * specified peripheral device type on this logical unit. However,
8438c2ecf20Sopenharmony_ci	 * the physical device is not currently connected to this logical
8448c2ecf20Sopenharmony_ci	 * unit.
8458c2ecf20Sopenharmony_ci	 *
8468c2ecf20Sopenharmony_ci	 * The above is vague, as it implies that we could treat 001 and
8478c2ecf20Sopenharmony_ci	 * 011 the same. Stay compatible with previous code, and create a
8488c2ecf20Sopenharmony_ci	 * scsi_device for a PQ of 1
8498c2ecf20Sopenharmony_ci	 *
8508c2ecf20Sopenharmony_ci	 * Don't set the device offline here; rather let the upper
8518c2ecf20Sopenharmony_ci	 * level drivers eval the PQ to decide whether they should
8528c2ecf20Sopenharmony_ci	 * attach. So remove ((inq_result[0] >> 5) & 7) == 1 check.
8538c2ecf20Sopenharmony_ci	 */
8548c2ecf20Sopenharmony_ci
8558c2ecf20Sopenharmony_ci	sdev->inq_periph_qual = (inq_result[0] >> 5) & 7;
8568c2ecf20Sopenharmony_ci	sdev->lockable = sdev->removable;
8578c2ecf20Sopenharmony_ci	sdev->soft_reset = (inq_result[7] & 1) && ((inq_result[3] & 7) == 2);
8588c2ecf20Sopenharmony_ci
8598c2ecf20Sopenharmony_ci	if (sdev->scsi_level >= SCSI_3 ||
8608c2ecf20Sopenharmony_ci			(sdev->inquiry_len > 56 && inq_result[56] & 0x04))
8618c2ecf20Sopenharmony_ci		sdev->ppr = 1;
8628c2ecf20Sopenharmony_ci	if (inq_result[7] & 0x60)
8638c2ecf20Sopenharmony_ci		sdev->wdtr = 1;
8648c2ecf20Sopenharmony_ci	if (inq_result[7] & 0x10)
8658c2ecf20Sopenharmony_ci		sdev->sdtr = 1;
8668c2ecf20Sopenharmony_ci
8678c2ecf20Sopenharmony_ci	sdev_printk(KERN_NOTICE, sdev, "%s %.8s %.16s %.4s PQ: %d "
8688c2ecf20Sopenharmony_ci			"ANSI: %d%s\n", scsi_device_type(sdev->type),
8698c2ecf20Sopenharmony_ci			sdev->vendor, sdev->model, sdev->rev,
8708c2ecf20Sopenharmony_ci			sdev->inq_periph_qual, inq_result[2] & 0x07,
8718c2ecf20Sopenharmony_ci			(inq_result[3] & 0x0f) == 1 ? " CCS" : "");
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_ci	if ((sdev->scsi_level >= SCSI_2) && (inq_result[7] & 2) &&
8748c2ecf20Sopenharmony_ci	    !(*bflags & BLIST_NOTQ)) {
8758c2ecf20Sopenharmony_ci		sdev->tagged_supported = 1;
8768c2ecf20Sopenharmony_ci		sdev->simple_tags = 1;
8778c2ecf20Sopenharmony_ci	}
8788c2ecf20Sopenharmony_ci
8798c2ecf20Sopenharmony_ci	/*
8808c2ecf20Sopenharmony_ci	 * Some devices (Texel CD ROM drives) have handshaking problems
8818c2ecf20Sopenharmony_ci	 * when used with the Seagate controllers. borken is initialized
8828c2ecf20Sopenharmony_ci	 * to 1, and then set it to 0 here.
8838c2ecf20Sopenharmony_ci	 */
8848c2ecf20Sopenharmony_ci	if ((*bflags & BLIST_BORKEN) == 0)
8858c2ecf20Sopenharmony_ci		sdev->borken = 0;
8868c2ecf20Sopenharmony_ci
8878c2ecf20Sopenharmony_ci	if (*bflags & BLIST_NO_ULD_ATTACH)
8888c2ecf20Sopenharmony_ci		sdev->no_uld_attach = 1;
8898c2ecf20Sopenharmony_ci
8908c2ecf20Sopenharmony_ci	/*
8918c2ecf20Sopenharmony_ci	 * Apparently some really broken devices (contrary to the SCSI
8928c2ecf20Sopenharmony_ci	 * standards) need to be selected without asserting ATN
8938c2ecf20Sopenharmony_ci	 */
8948c2ecf20Sopenharmony_ci	if (*bflags & BLIST_SELECT_NO_ATN)
8958c2ecf20Sopenharmony_ci		sdev->select_no_atn = 1;
8968c2ecf20Sopenharmony_ci
8978c2ecf20Sopenharmony_ci	/*
8988c2ecf20Sopenharmony_ci	 * Maximum 512 sector transfer length
8998c2ecf20Sopenharmony_ci	 * broken RA4x00 Compaq Disk Array
9008c2ecf20Sopenharmony_ci	 */
9018c2ecf20Sopenharmony_ci	if (*bflags & BLIST_MAX_512)
9028c2ecf20Sopenharmony_ci		blk_queue_max_hw_sectors(sdev->request_queue, 512);
9038c2ecf20Sopenharmony_ci	/*
9048c2ecf20Sopenharmony_ci	 * Max 1024 sector transfer length for targets that report incorrect
9058c2ecf20Sopenharmony_ci	 * max/optimal lengths and relied on the old block layer safe default
9068c2ecf20Sopenharmony_ci	 */
9078c2ecf20Sopenharmony_ci	else if (*bflags & BLIST_MAX_1024)
9088c2ecf20Sopenharmony_ci		blk_queue_max_hw_sectors(sdev->request_queue, 1024);
9098c2ecf20Sopenharmony_ci
9108c2ecf20Sopenharmony_ci	/*
9118c2ecf20Sopenharmony_ci	 * Some devices may not want to have a start command automatically
9128c2ecf20Sopenharmony_ci	 * issued when a device is added.
9138c2ecf20Sopenharmony_ci	 */
9148c2ecf20Sopenharmony_ci	if (*bflags & BLIST_NOSTARTONADD)
9158c2ecf20Sopenharmony_ci		sdev->no_start_on_add = 1;
9168c2ecf20Sopenharmony_ci
9178c2ecf20Sopenharmony_ci	if (*bflags & BLIST_SINGLELUN)
9188c2ecf20Sopenharmony_ci		scsi_target(sdev)->single_lun = 1;
9198c2ecf20Sopenharmony_ci
9208c2ecf20Sopenharmony_ci	sdev->use_10_for_rw = 1;
9218c2ecf20Sopenharmony_ci
9228c2ecf20Sopenharmony_ci	/* some devices don't like REPORT SUPPORTED OPERATION CODES
9238c2ecf20Sopenharmony_ci	 * and will simply timeout causing sd_mod init to take a very
9248c2ecf20Sopenharmony_ci	 * very long time */
9258c2ecf20Sopenharmony_ci	if (*bflags & BLIST_NO_RSOC)
9268c2ecf20Sopenharmony_ci		sdev->no_report_opcodes = 1;
9278c2ecf20Sopenharmony_ci
9288c2ecf20Sopenharmony_ci	/* set the device running here so that slave configure
9298c2ecf20Sopenharmony_ci	 * may do I/O */
9308c2ecf20Sopenharmony_ci	mutex_lock(&sdev->state_mutex);
9318c2ecf20Sopenharmony_ci	ret = scsi_device_set_state(sdev, SDEV_RUNNING);
9328c2ecf20Sopenharmony_ci	if (ret)
9338c2ecf20Sopenharmony_ci		ret = scsi_device_set_state(sdev, SDEV_BLOCK);
9348c2ecf20Sopenharmony_ci	mutex_unlock(&sdev->state_mutex);
9358c2ecf20Sopenharmony_ci
9368c2ecf20Sopenharmony_ci	if (ret) {
9378c2ecf20Sopenharmony_ci		sdev_printk(KERN_ERR, sdev,
9388c2ecf20Sopenharmony_ci			    "in wrong state %s to complete scan\n",
9398c2ecf20Sopenharmony_ci			    scsi_device_state_name(sdev->sdev_state));
9408c2ecf20Sopenharmony_ci		return SCSI_SCAN_NO_RESPONSE;
9418c2ecf20Sopenharmony_ci	}
9428c2ecf20Sopenharmony_ci
9438c2ecf20Sopenharmony_ci	if (*bflags & BLIST_NOT_LOCKABLE)
9448c2ecf20Sopenharmony_ci		sdev->lockable = 0;
9458c2ecf20Sopenharmony_ci
9468c2ecf20Sopenharmony_ci	if (*bflags & BLIST_RETRY_HWERROR)
9478c2ecf20Sopenharmony_ci		sdev->retry_hwerror = 1;
9488c2ecf20Sopenharmony_ci
9498c2ecf20Sopenharmony_ci	if (*bflags & BLIST_NO_DIF)
9508c2ecf20Sopenharmony_ci		sdev->no_dif = 1;
9518c2ecf20Sopenharmony_ci
9528c2ecf20Sopenharmony_ci	if (*bflags & BLIST_UNMAP_LIMIT_WS)
9538c2ecf20Sopenharmony_ci		sdev->unmap_limit_for_ws = 1;
9548c2ecf20Sopenharmony_ci
9558c2ecf20Sopenharmony_ci	sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT;
9568c2ecf20Sopenharmony_ci
9578c2ecf20Sopenharmony_ci	if (*bflags & BLIST_TRY_VPD_PAGES)
9588c2ecf20Sopenharmony_ci		sdev->try_vpd_pages = 1;
9598c2ecf20Sopenharmony_ci	else if (*bflags & BLIST_SKIP_VPD_PAGES)
9608c2ecf20Sopenharmony_ci		sdev->skip_vpd_pages = 1;
9618c2ecf20Sopenharmony_ci
9628c2ecf20Sopenharmony_ci	transport_configure_device(&sdev->sdev_gendev);
9638c2ecf20Sopenharmony_ci
9648c2ecf20Sopenharmony_ci	if (sdev->host->hostt->slave_configure) {
9658c2ecf20Sopenharmony_ci		ret = sdev->host->hostt->slave_configure(sdev);
9668c2ecf20Sopenharmony_ci		if (ret) {
9678c2ecf20Sopenharmony_ci			/*
9688c2ecf20Sopenharmony_ci			 * if LLDD reports slave not present, don't clutter
9698c2ecf20Sopenharmony_ci			 * console with alloc failure messages
9708c2ecf20Sopenharmony_ci			 */
9718c2ecf20Sopenharmony_ci			if (ret != -ENXIO) {
9728c2ecf20Sopenharmony_ci				sdev_printk(KERN_ERR, sdev,
9738c2ecf20Sopenharmony_ci					"failed to configure device\n");
9748c2ecf20Sopenharmony_ci			}
9758c2ecf20Sopenharmony_ci			return SCSI_SCAN_NO_RESPONSE;
9768c2ecf20Sopenharmony_ci		}
9778c2ecf20Sopenharmony_ci	}
9788c2ecf20Sopenharmony_ci
9798c2ecf20Sopenharmony_ci	if (sdev->scsi_level >= SCSI_3)
9808c2ecf20Sopenharmony_ci		scsi_attach_vpd(sdev);
9818c2ecf20Sopenharmony_ci
9828c2ecf20Sopenharmony_ci	sdev->max_queue_depth = sdev->queue_depth;
9838c2ecf20Sopenharmony_ci	sdev->sdev_bflags = *bflags;
9848c2ecf20Sopenharmony_ci
9858c2ecf20Sopenharmony_ci	/*
9868c2ecf20Sopenharmony_ci	 * Ok, the device is now all set up, we can
9878c2ecf20Sopenharmony_ci	 * register it and tell the rest of the kernel
9888c2ecf20Sopenharmony_ci	 * about it.
9898c2ecf20Sopenharmony_ci	 */
9908c2ecf20Sopenharmony_ci	if (!async && scsi_sysfs_add_sdev(sdev) != 0)
9918c2ecf20Sopenharmony_ci		return SCSI_SCAN_NO_RESPONSE;
9928c2ecf20Sopenharmony_ci
9938c2ecf20Sopenharmony_ci	return SCSI_SCAN_LUN_PRESENT;
9948c2ecf20Sopenharmony_ci}
9958c2ecf20Sopenharmony_ci
9968c2ecf20Sopenharmony_ci#ifdef CONFIG_SCSI_LOGGING
9978c2ecf20Sopenharmony_ci/**
9988c2ecf20Sopenharmony_ci * scsi_inq_str - print INQUIRY data from min to max index, strip trailing whitespace
9998c2ecf20Sopenharmony_ci * @buf:   Output buffer with at least end-first+1 bytes of space
10008c2ecf20Sopenharmony_ci * @inq:   Inquiry buffer (input)
10018c2ecf20Sopenharmony_ci * @first: Offset of string into inq
10028c2ecf20Sopenharmony_ci * @end:   Index after last character in inq
10038c2ecf20Sopenharmony_ci */
10048c2ecf20Sopenharmony_cistatic unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
10058c2ecf20Sopenharmony_ci				   unsigned first, unsigned end)
10068c2ecf20Sopenharmony_ci{
10078c2ecf20Sopenharmony_ci	unsigned term = 0, idx;
10088c2ecf20Sopenharmony_ci
10098c2ecf20Sopenharmony_ci	for (idx = 0; idx + first < end && idx + first < inq[4] + 5; idx++) {
10108c2ecf20Sopenharmony_ci		if (inq[idx+first] > ' ') {
10118c2ecf20Sopenharmony_ci			buf[idx] = inq[idx+first];
10128c2ecf20Sopenharmony_ci			term = idx+1;
10138c2ecf20Sopenharmony_ci		} else {
10148c2ecf20Sopenharmony_ci			buf[idx] = ' ';
10158c2ecf20Sopenharmony_ci		}
10168c2ecf20Sopenharmony_ci	}
10178c2ecf20Sopenharmony_ci	buf[term] = 0;
10188c2ecf20Sopenharmony_ci	return buf;
10198c2ecf20Sopenharmony_ci}
10208c2ecf20Sopenharmony_ci#endif
10218c2ecf20Sopenharmony_ci
10228c2ecf20Sopenharmony_ci/**
10238c2ecf20Sopenharmony_ci * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
10248c2ecf20Sopenharmony_ci * @starget:	pointer to target device structure
10258c2ecf20Sopenharmony_ci * @lun:	LUN of target device
10268c2ecf20Sopenharmony_ci * @bflagsp:	store bflags here if not NULL
10278c2ecf20Sopenharmony_ci * @sdevp:	probe the LUN corresponding to this scsi_device
10288c2ecf20Sopenharmony_ci * @rescan:     if not equal to SCSI_SCAN_INITIAL skip some code only
10298c2ecf20Sopenharmony_ci *              needed on first scan
10308c2ecf20Sopenharmony_ci * @hostdata:	passed to scsi_alloc_sdev()
10318c2ecf20Sopenharmony_ci *
10328c2ecf20Sopenharmony_ci * Description:
10338c2ecf20Sopenharmony_ci *     Call scsi_probe_lun, if a LUN with an attached device is found,
10348c2ecf20Sopenharmony_ci *     allocate and set it up by calling scsi_add_lun.
10358c2ecf20Sopenharmony_ci *
10368c2ecf20Sopenharmony_ci * Return:
10378c2ecf20Sopenharmony_ci *
10388c2ecf20Sopenharmony_ci *   - SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
10398c2ecf20Sopenharmony_ci *   - SCSI_SCAN_TARGET_PRESENT: target responded, but no device is
10408c2ecf20Sopenharmony_ci *         attached at the LUN
10418c2ecf20Sopenharmony_ci *   - SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
10428c2ecf20Sopenharmony_ci **/
10438c2ecf20Sopenharmony_cistatic int scsi_probe_and_add_lun(struct scsi_target *starget,
10448c2ecf20Sopenharmony_ci				  u64 lun, blist_flags_t *bflagsp,
10458c2ecf20Sopenharmony_ci				  struct scsi_device **sdevp,
10468c2ecf20Sopenharmony_ci				  enum scsi_scan_mode rescan,
10478c2ecf20Sopenharmony_ci				  void *hostdata)
10488c2ecf20Sopenharmony_ci{
10498c2ecf20Sopenharmony_ci	struct scsi_device *sdev;
10508c2ecf20Sopenharmony_ci	unsigned char *result;
10518c2ecf20Sopenharmony_ci	blist_flags_t bflags;
10528c2ecf20Sopenharmony_ci	int res = SCSI_SCAN_NO_RESPONSE, result_len = 256;
10538c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
10548c2ecf20Sopenharmony_ci
10558c2ecf20Sopenharmony_ci	/*
10568c2ecf20Sopenharmony_ci	 * The rescan flag is used as an optimization, the first scan of a
10578c2ecf20Sopenharmony_ci	 * host adapter calls into here with rescan == 0.
10588c2ecf20Sopenharmony_ci	 */
10598c2ecf20Sopenharmony_ci	sdev = scsi_device_lookup_by_target(starget, lun);
10608c2ecf20Sopenharmony_ci	if (sdev) {
10618c2ecf20Sopenharmony_ci		if (rescan != SCSI_SCAN_INITIAL || !scsi_device_created(sdev)) {
10628c2ecf20Sopenharmony_ci			SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
10638c2ecf20Sopenharmony_ci				"scsi scan: device exists on %s\n",
10648c2ecf20Sopenharmony_ci				dev_name(&sdev->sdev_gendev)));
10658c2ecf20Sopenharmony_ci			if (sdevp)
10668c2ecf20Sopenharmony_ci				*sdevp = sdev;
10678c2ecf20Sopenharmony_ci			else
10688c2ecf20Sopenharmony_ci				scsi_device_put(sdev);
10698c2ecf20Sopenharmony_ci
10708c2ecf20Sopenharmony_ci			if (bflagsp)
10718c2ecf20Sopenharmony_ci				*bflagsp = scsi_get_device_flags(sdev,
10728c2ecf20Sopenharmony_ci								 sdev->vendor,
10738c2ecf20Sopenharmony_ci								 sdev->model);
10748c2ecf20Sopenharmony_ci			return SCSI_SCAN_LUN_PRESENT;
10758c2ecf20Sopenharmony_ci		}
10768c2ecf20Sopenharmony_ci		scsi_device_put(sdev);
10778c2ecf20Sopenharmony_ci	} else
10788c2ecf20Sopenharmony_ci		sdev = scsi_alloc_sdev(starget, lun, hostdata);
10798c2ecf20Sopenharmony_ci	if (!sdev)
10808c2ecf20Sopenharmony_ci		goto out;
10818c2ecf20Sopenharmony_ci
10828c2ecf20Sopenharmony_ci	result = kmalloc(result_len, GFP_KERNEL |
10838c2ecf20Sopenharmony_ci			((shost->unchecked_isa_dma) ? __GFP_DMA : 0));
10848c2ecf20Sopenharmony_ci	if (!result)
10858c2ecf20Sopenharmony_ci		goto out_free_sdev;
10868c2ecf20Sopenharmony_ci
10878c2ecf20Sopenharmony_ci	if (scsi_probe_lun(sdev, result, result_len, &bflags))
10888c2ecf20Sopenharmony_ci		goto out_free_result;
10898c2ecf20Sopenharmony_ci
10908c2ecf20Sopenharmony_ci	if (bflagsp)
10918c2ecf20Sopenharmony_ci		*bflagsp = bflags;
10928c2ecf20Sopenharmony_ci	/*
10938c2ecf20Sopenharmony_ci	 * result contains valid SCSI INQUIRY data.
10948c2ecf20Sopenharmony_ci	 */
10958c2ecf20Sopenharmony_ci	if ((result[0] >> 5) == 3) {
10968c2ecf20Sopenharmony_ci		/*
10978c2ecf20Sopenharmony_ci		 * For a Peripheral qualifier 3 (011b), the SCSI
10988c2ecf20Sopenharmony_ci		 * spec says: The device server is not capable of
10998c2ecf20Sopenharmony_ci		 * supporting a physical device on this logical
11008c2ecf20Sopenharmony_ci		 * unit.
11018c2ecf20Sopenharmony_ci		 *
11028c2ecf20Sopenharmony_ci		 * For disks, this implies that there is no
11038c2ecf20Sopenharmony_ci		 * logical disk configured at sdev->lun, but there
11048c2ecf20Sopenharmony_ci		 * is a target id responding.
11058c2ecf20Sopenharmony_ci		 */
11068c2ecf20Sopenharmony_ci		SCSI_LOG_SCAN_BUS(2, sdev_printk(KERN_INFO, sdev, "scsi scan:"
11078c2ecf20Sopenharmony_ci				   " peripheral qualifier of 3, device not"
11088c2ecf20Sopenharmony_ci				   " added\n"))
11098c2ecf20Sopenharmony_ci		if (lun == 0) {
11108c2ecf20Sopenharmony_ci			SCSI_LOG_SCAN_BUS(1, {
11118c2ecf20Sopenharmony_ci				unsigned char vend[9];
11128c2ecf20Sopenharmony_ci				unsigned char mod[17];
11138c2ecf20Sopenharmony_ci
11148c2ecf20Sopenharmony_ci				sdev_printk(KERN_INFO, sdev,
11158c2ecf20Sopenharmony_ci					"scsi scan: consider passing scsi_mod."
11168c2ecf20Sopenharmony_ci					"dev_flags=%s:%s:0x240 or 0x1000240\n",
11178c2ecf20Sopenharmony_ci					scsi_inq_str(vend, result, 8, 16),
11188c2ecf20Sopenharmony_ci					scsi_inq_str(mod, result, 16, 32));
11198c2ecf20Sopenharmony_ci			});
11208c2ecf20Sopenharmony_ci
11218c2ecf20Sopenharmony_ci		}
11228c2ecf20Sopenharmony_ci
11238c2ecf20Sopenharmony_ci		res = SCSI_SCAN_TARGET_PRESENT;
11248c2ecf20Sopenharmony_ci		goto out_free_result;
11258c2ecf20Sopenharmony_ci	}
11268c2ecf20Sopenharmony_ci
11278c2ecf20Sopenharmony_ci	/*
11288c2ecf20Sopenharmony_ci	 * Some targets may set slight variations of PQ and PDT to signal
11298c2ecf20Sopenharmony_ci	 * that no LUN is present, so don't add sdev in these cases.
11308c2ecf20Sopenharmony_ci	 * Two specific examples are:
11318c2ecf20Sopenharmony_ci	 * 1) NetApp targets: return PQ=1, PDT=0x1f
11328c2ecf20Sopenharmony_ci	 * 2) USB UFI: returns PDT=0x1f, with the PQ bits being "reserved"
11338c2ecf20Sopenharmony_ci	 *    in the UFI 1.0 spec (we cannot rely on reserved bits).
11348c2ecf20Sopenharmony_ci	 *
11358c2ecf20Sopenharmony_ci	 * References:
11368c2ecf20Sopenharmony_ci	 * 1) SCSI SPC-3, pp. 145-146
11378c2ecf20Sopenharmony_ci	 * PQ=1: "A peripheral device having the specified peripheral
11388c2ecf20Sopenharmony_ci	 * device type is not connected to this logical unit. However, the
11398c2ecf20Sopenharmony_ci	 * device server is capable of supporting the specified peripheral
11408c2ecf20Sopenharmony_ci	 * device type on this logical unit."
11418c2ecf20Sopenharmony_ci	 * PDT=0x1f: "Unknown or no device type"
11428c2ecf20Sopenharmony_ci	 * 2) USB UFI 1.0, p. 20
11438c2ecf20Sopenharmony_ci	 * PDT=00h Direct-access device (floppy)
11448c2ecf20Sopenharmony_ci	 * PDT=1Fh none (no FDD connected to the requested logical unit)
11458c2ecf20Sopenharmony_ci	 */
11468c2ecf20Sopenharmony_ci	if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) &&
11478c2ecf20Sopenharmony_ci	    (result[0] & 0x1f) == 0x1f &&
11488c2ecf20Sopenharmony_ci	    !scsi_is_wlun(lun)) {
11498c2ecf20Sopenharmony_ci		SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
11508c2ecf20Sopenharmony_ci					"scsi scan: peripheral device type"
11518c2ecf20Sopenharmony_ci					" of 31, no device added\n"));
11528c2ecf20Sopenharmony_ci		res = SCSI_SCAN_TARGET_PRESENT;
11538c2ecf20Sopenharmony_ci		goto out_free_result;
11548c2ecf20Sopenharmony_ci	}
11558c2ecf20Sopenharmony_ci
11568c2ecf20Sopenharmony_ci	res = scsi_add_lun(sdev, result, &bflags, shost->async_scan);
11578c2ecf20Sopenharmony_ci	if (res == SCSI_SCAN_LUN_PRESENT) {
11588c2ecf20Sopenharmony_ci		if (bflags & BLIST_KEY) {
11598c2ecf20Sopenharmony_ci			sdev->lockable = 0;
11608c2ecf20Sopenharmony_ci			scsi_unlock_floptical(sdev, result);
11618c2ecf20Sopenharmony_ci		}
11628c2ecf20Sopenharmony_ci	}
11638c2ecf20Sopenharmony_ci
11648c2ecf20Sopenharmony_ci out_free_result:
11658c2ecf20Sopenharmony_ci	kfree(result);
11668c2ecf20Sopenharmony_ci out_free_sdev:
11678c2ecf20Sopenharmony_ci	if (res == SCSI_SCAN_LUN_PRESENT) {
11688c2ecf20Sopenharmony_ci		if (sdevp) {
11698c2ecf20Sopenharmony_ci			if (scsi_device_get(sdev) == 0) {
11708c2ecf20Sopenharmony_ci				*sdevp = sdev;
11718c2ecf20Sopenharmony_ci			} else {
11728c2ecf20Sopenharmony_ci				__scsi_remove_device(sdev);
11738c2ecf20Sopenharmony_ci				res = SCSI_SCAN_NO_RESPONSE;
11748c2ecf20Sopenharmony_ci			}
11758c2ecf20Sopenharmony_ci		}
11768c2ecf20Sopenharmony_ci	} else
11778c2ecf20Sopenharmony_ci		__scsi_remove_device(sdev);
11788c2ecf20Sopenharmony_ci out:
11798c2ecf20Sopenharmony_ci	return res;
11808c2ecf20Sopenharmony_ci}
11818c2ecf20Sopenharmony_ci
11828c2ecf20Sopenharmony_ci/**
11838c2ecf20Sopenharmony_ci * scsi_sequential_lun_scan - sequentially scan a SCSI target
11848c2ecf20Sopenharmony_ci * @starget:	pointer to target structure to scan
11858c2ecf20Sopenharmony_ci * @bflags:	black/white list flag for LUN 0
11868c2ecf20Sopenharmony_ci * @scsi_level: Which version of the standard does this device adhere to
11878c2ecf20Sopenharmony_ci * @rescan:     passed to scsi_probe_add_lun()
11888c2ecf20Sopenharmony_ci *
11898c2ecf20Sopenharmony_ci * Description:
11908c2ecf20Sopenharmony_ci *     Generally, scan from LUN 1 (LUN 0 is assumed to already have been
11918c2ecf20Sopenharmony_ci *     scanned) to some maximum lun until a LUN is found with no device
11928c2ecf20Sopenharmony_ci *     attached. Use the bflags to figure out any oddities.
11938c2ecf20Sopenharmony_ci *
11948c2ecf20Sopenharmony_ci *     Modifies sdevscan->lun.
11958c2ecf20Sopenharmony_ci **/
11968c2ecf20Sopenharmony_cistatic void scsi_sequential_lun_scan(struct scsi_target *starget,
11978c2ecf20Sopenharmony_ci				     blist_flags_t bflags, int scsi_level,
11988c2ecf20Sopenharmony_ci				     enum scsi_scan_mode rescan)
11998c2ecf20Sopenharmony_ci{
12008c2ecf20Sopenharmony_ci	uint max_dev_lun;
12018c2ecf20Sopenharmony_ci	u64 sparse_lun, lun;
12028c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
12038c2ecf20Sopenharmony_ci
12048c2ecf20Sopenharmony_ci	SCSI_LOG_SCAN_BUS(3, starget_printk(KERN_INFO, starget,
12058c2ecf20Sopenharmony_ci		"scsi scan: Sequential scan\n"));
12068c2ecf20Sopenharmony_ci
12078c2ecf20Sopenharmony_ci	max_dev_lun = min(max_scsi_luns, shost->max_lun);
12088c2ecf20Sopenharmony_ci	/*
12098c2ecf20Sopenharmony_ci	 * If this device is known to support sparse multiple units,
12108c2ecf20Sopenharmony_ci	 * override the other settings, and scan all of them. Normally,
12118c2ecf20Sopenharmony_ci	 * SCSI-3 devices should be scanned via the REPORT LUNS.
12128c2ecf20Sopenharmony_ci	 */
12138c2ecf20Sopenharmony_ci	if (bflags & BLIST_SPARSELUN) {
12148c2ecf20Sopenharmony_ci		max_dev_lun = shost->max_lun;
12158c2ecf20Sopenharmony_ci		sparse_lun = 1;
12168c2ecf20Sopenharmony_ci	} else
12178c2ecf20Sopenharmony_ci		sparse_lun = 0;
12188c2ecf20Sopenharmony_ci
12198c2ecf20Sopenharmony_ci	/*
12208c2ecf20Sopenharmony_ci	 * If less than SCSI_1_CCS, and no special lun scanning, stop
12218c2ecf20Sopenharmony_ci	 * scanning; this matches 2.4 behaviour, but could just be a bug
12228c2ecf20Sopenharmony_ci	 * (to continue scanning a SCSI_1_CCS device).
12238c2ecf20Sopenharmony_ci	 *
12248c2ecf20Sopenharmony_ci	 * This test is broken.  We might not have any device on lun0 for
12258c2ecf20Sopenharmony_ci	 * a sparselun device, and if that's the case then how would we
12268c2ecf20Sopenharmony_ci	 * know the real scsi_level, eh?  It might make sense to just not
12278c2ecf20Sopenharmony_ci	 * scan any SCSI_1 device for non-0 luns, but that check would best
12288c2ecf20Sopenharmony_ci	 * go into scsi_alloc_sdev() and just have it return null when asked
12298c2ecf20Sopenharmony_ci	 * to alloc an sdev for lun > 0 on an already found SCSI_1 device.
12308c2ecf20Sopenharmony_ci	 *
12318c2ecf20Sopenharmony_ci	if ((sdevscan->scsi_level < SCSI_1_CCS) &&
12328c2ecf20Sopenharmony_ci	    ((bflags & (BLIST_FORCELUN | BLIST_SPARSELUN | BLIST_MAX5LUN))
12338c2ecf20Sopenharmony_ci	     == 0))
12348c2ecf20Sopenharmony_ci		return;
12358c2ecf20Sopenharmony_ci	 */
12368c2ecf20Sopenharmony_ci	/*
12378c2ecf20Sopenharmony_ci	 * If this device is known to support multiple units, override
12388c2ecf20Sopenharmony_ci	 * the other settings, and scan all of them.
12398c2ecf20Sopenharmony_ci	 */
12408c2ecf20Sopenharmony_ci	if (bflags & BLIST_FORCELUN)
12418c2ecf20Sopenharmony_ci		max_dev_lun = shost->max_lun;
12428c2ecf20Sopenharmony_ci	/*
12438c2ecf20Sopenharmony_ci	 * REGAL CDC-4X: avoid hang after LUN 4
12448c2ecf20Sopenharmony_ci	 */
12458c2ecf20Sopenharmony_ci	if (bflags & BLIST_MAX5LUN)
12468c2ecf20Sopenharmony_ci		max_dev_lun = min(5U, max_dev_lun);
12478c2ecf20Sopenharmony_ci	/*
12488c2ecf20Sopenharmony_ci	 * Do not scan SCSI-2 or lower device past LUN 7, unless
12498c2ecf20Sopenharmony_ci	 * BLIST_LARGELUN.
12508c2ecf20Sopenharmony_ci	 */
12518c2ecf20Sopenharmony_ci	if (scsi_level < SCSI_3 && !(bflags & BLIST_LARGELUN))
12528c2ecf20Sopenharmony_ci		max_dev_lun = min(8U, max_dev_lun);
12538c2ecf20Sopenharmony_ci	else
12548c2ecf20Sopenharmony_ci		max_dev_lun = min(256U, max_dev_lun);
12558c2ecf20Sopenharmony_ci
12568c2ecf20Sopenharmony_ci	/*
12578c2ecf20Sopenharmony_ci	 * We have already scanned LUN 0, so start at LUN 1. Keep scanning
12588c2ecf20Sopenharmony_ci	 * until we reach the max, or no LUN is found and we are not
12598c2ecf20Sopenharmony_ci	 * sparse_lun.
12608c2ecf20Sopenharmony_ci	 */
12618c2ecf20Sopenharmony_ci	for (lun = 1; lun < max_dev_lun; ++lun)
12628c2ecf20Sopenharmony_ci		if ((scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan,
12638c2ecf20Sopenharmony_ci					    NULL) != SCSI_SCAN_LUN_PRESENT) &&
12648c2ecf20Sopenharmony_ci		    !sparse_lun)
12658c2ecf20Sopenharmony_ci			return;
12668c2ecf20Sopenharmony_ci}
12678c2ecf20Sopenharmony_ci
12688c2ecf20Sopenharmony_ci/**
12698c2ecf20Sopenharmony_ci * scsi_report_lun_scan - Scan using SCSI REPORT LUN results
12708c2ecf20Sopenharmony_ci * @starget: which target
12718c2ecf20Sopenharmony_ci * @bflags: Zero or a mix of BLIST_NOLUN, BLIST_REPORTLUN2, or BLIST_NOREPORTLUN
12728c2ecf20Sopenharmony_ci * @rescan: nonzero if we can skip code only needed on first scan
12738c2ecf20Sopenharmony_ci *
12748c2ecf20Sopenharmony_ci * Description:
12758c2ecf20Sopenharmony_ci *   Fast scanning for modern (SCSI-3) devices by sending a REPORT LUN command.
12768c2ecf20Sopenharmony_ci *   Scan the resulting list of LUNs by calling scsi_probe_and_add_lun.
12778c2ecf20Sopenharmony_ci *
12788c2ecf20Sopenharmony_ci *   If BLINK_REPORTLUN2 is set, scan a target that supports more than 8
12798c2ecf20Sopenharmony_ci *   LUNs even if it's older than SCSI-3.
12808c2ecf20Sopenharmony_ci *   If BLIST_NOREPORTLUN is set, return 1 always.
12818c2ecf20Sopenharmony_ci *   If BLIST_NOLUN is set, return 0 always.
12828c2ecf20Sopenharmony_ci *   If starget->no_report_luns is set, return 1 always.
12838c2ecf20Sopenharmony_ci *
12848c2ecf20Sopenharmony_ci * Return:
12858c2ecf20Sopenharmony_ci *     0: scan completed (or no memory, so further scanning is futile)
12868c2ecf20Sopenharmony_ci *     1: could not scan with REPORT LUN
12878c2ecf20Sopenharmony_ci **/
12888c2ecf20Sopenharmony_cistatic int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflags,
12898c2ecf20Sopenharmony_ci				enum scsi_scan_mode rescan)
12908c2ecf20Sopenharmony_ci{
12918c2ecf20Sopenharmony_ci	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
12928c2ecf20Sopenharmony_ci	unsigned int length;
12938c2ecf20Sopenharmony_ci	u64 lun;
12948c2ecf20Sopenharmony_ci	unsigned int num_luns;
12958c2ecf20Sopenharmony_ci	unsigned int retries;
12968c2ecf20Sopenharmony_ci	int result;
12978c2ecf20Sopenharmony_ci	struct scsi_lun *lunp, *lun_data;
12988c2ecf20Sopenharmony_ci	struct scsi_sense_hdr sshdr;
12998c2ecf20Sopenharmony_ci	struct scsi_device *sdev;
13008c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
13018c2ecf20Sopenharmony_ci	int ret = 0;
13028c2ecf20Sopenharmony_ci
13038c2ecf20Sopenharmony_ci	/*
13048c2ecf20Sopenharmony_ci	 * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set.
13058c2ecf20Sopenharmony_ci	 * Also allow SCSI-2 if BLIST_REPORTLUN2 is set and host adapter does
13068c2ecf20Sopenharmony_ci	 * support more than 8 LUNs.
13078c2ecf20Sopenharmony_ci	 * Don't attempt if the target doesn't support REPORT LUNS.
13088c2ecf20Sopenharmony_ci	 */
13098c2ecf20Sopenharmony_ci	if (bflags & BLIST_NOREPORTLUN)
13108c2ecf20Sopenharmony_ci		return 1;
13118c2ecf20Sopenharmony_ci	if (starget->scsi_level < SCSI_2 &&
13128c2ecf20Sopenharmony_ci	    starget->scsi_level != SCSI_UNKNOWN)
13138c2ecf20Sopenharmony_ci		return 1;
13148c2ecf20Sopenharmony_ci	if (starget->scsi_level < SCSI_3 &&
13158c2ecf20Sopenharmony_ci	    (!(bflags & BLIST_REPORTLUN2) || shost->max_lun <= 8))
13168c2ecf20Sopenharmony_ci		return 1;
13178c2ecf20Sopenharmony_ci	if (bflags & BLIST_NOLUN)
13188c2ecf20Sopenharmony_ci		return 0;
13198c2ecf20Sopenharmony_ci	if (starget->no_report_luns)
13208c2ecf20Sopenharmony_ci		return 1;
13218c2ecf20Sopenharmony_ci
13228c2ecf20Sopenharmony_ci	if (!(sdev = scsi_device_lookup_by_target(starget, 0))) {
13238c2ecf20Sopenharmony_ci		sdev = scsi_alloc_sdev(starget, 0, NULL);
13248c2ecf20Sopenharmony_ci		if (!sdev)
13258c2ecf20Sopenharmony_ci			return 0;
13268c2ecf20Sopenharmony_ci		if (scsi_device_get(sdev)) {
13278c2ecf20Sopenharmony_ci			__scsi_remove_device(sdev);
13288c2ecf20Sopenharmony_ci			return 0;
13298c2ecf20Sopenharmony_ci		}
13308c2ecf20Sopenharmony_ci	}
13318c2ecf20Sopenharmony_ci
13328c2ecf20Sopenharmony_ci	/*
13338c2ecf20Sopenharmony_ci	 * Allocate enough to hold the header (the same size as one scsi_lun)
13348c2ecf20Sopenharmony_ci	 * plus the number of luns we are requesting.  511 was the default
13358c2ecf20Sopenharmony_ci	 * value of the now removed max_report_luns parameter.
13368c2ecf20Sopenharmony_ci	 */
13378c2ecf20Sopenharmony_ci	length = (511 + 1) * sizeof(struct scsi_lun);
13388c2ecf20Sopenharmony_ciretry:
13398c2ecf20Sopenharmony_ci	lun_data = kmalloc(length, GFP_KERNEL |
13408c2ecf20Sopenharmony_ci			   (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0));
13418c2ecf20Sopenharmony_ci	if (!lun_data) {
13428c2ecf20Sopenharmony_ci		printk(ALLOC_FAILURE_MSG, __func__);
13438c2ecf20Sopenharmony_ci		goto out;
13448c2ecf20Sopenharmony_ci	}
13458c2ecf20Sopenharmony_ci
13468c2ecf20Sopenharmony_ci	scsi_cmd[0] = REPORT_LUNS;
13478c2ecf20Sopenharmony_ci
13488c2ecf20Sopenharmony_ci	/*
13498c2ecf20Sopenharmony_ci	 * bytes 1 - 5: reserved, set to zero.
13508c2ecf20Sopenharmony_ci	 */
13518c2ecf20Sopenharmony_ci	memset(&scsi_cmd[1], 0, 5);
13528c2ecf20Sopenharmony_ci
13538c2ecf20Sopenharmony_ci	/*
13548c2ecf20Sopenharmony_ci	 * bytes 6 - 9: length of the command.
13558c2ecf20Sopenharmony_ci	 */
13568c2ecf20Sopenharmony_ci	put_unaligned_be32(length, &scsi_cmd[6]);
13578c2ecf20Sopenharmony_ci
13588c2ecf20Sopenharmony_ci	scsi_cmd[10] = 0;	/* reserved */
13598c2ecf20Sopenharmony_ci	scsi_cmd[11] = 0;	/* control */
13608c2ecf20Sopenharmony_ci
13618c2ecf20Sopenharmony_ci	/*
13628c2ecf20Sopenharmony_ci	 * We can get a UNIT ATTENTION, for example a power on/reset, so
13638c2ecf20Sopenharmony_ci	 * retry a few times (like sd.c does for TEST UNIT READY).
13648c2ecf20Sopenharmony_ci	 * Experience shows some combinations of adapter/devices get at
13658c2ecf20Sopenharmony_ci	 * least two power on/resets.
13668c2ecf20Sopenharmony_ci	 *
13678c2ecf20Sopenharmony_ci	 * Illegal requests (for devices that do not support REPORT LUNS)
13688c2ecf20Sopenharmony_ci	 * should come through as a check condition, and will not generate
13698c2ecf20Sopenharmony_ci	 * a retry.
13708c2ecf20Sopenharmony_ci	 */
13718c2ecf20Sopenharmony_ci	for (retries = 0; retries < 3; retries++) {
13728c2ecf20Sopenharmony_ci		SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
13738c2ecf20Sopenharmony_ci				"scsi scan: Sending REPORT LUNS to (try %d)\n",
13748c2ecf20Sopenharmony_ci				retries));
13758c2ecf20Sopenharmony_ci
13768c2ecf20Sopenharmony_ci		result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
13778c2ecf20Sopenharmony_ci					  lun_data, length, &sshdr,
13788c2ecf20Sopenharmony_ci					  SCSI_REPORT_LUNS_TIMEOUT, 3, NULL);
13798c2ecf20Sopenharmony_ci
13808c2ecf20Sopenharmony_ci		SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
13818c2ecf20Sopenharmony_ci				"scsi scan: REPORT LUNS"
13828c2ecf20Sopenharmony_ci				" %s (try %d) result 0x%x\n",
13838c2ecf20Sopenharmony_ci				result ?  "failed" : "successful",
13848c2ecf20Sopenharmony_ci				retries, result));
13858c2ecf20Sopenharmony_ci		if (result == 0)
13868c2ecf20Sopenharmony_ci			break;
13878c2ecf20Sopenharmony_ci		else if (scsi_sense_valid(&sshdr)) {
13888c2ecf20Sopenharmony_ci			if (sshdr.sense_key != UNIT_ATTENTION)
13898c2ecf20Sopenharmony_ci				break;
13908c2ecf20Sopenharmony_ci		}
13918c2ecf20Sopenharmony_ci	}
13928c2ecf20Sopenharmony_ci
13938c2ecf20Sopenharmony_ci	if (result) {
13948c2ecf20Sopenharmony_ci		/*
13958c2ecf20Sopenharmony_ci		 * The device probably does not support a REPORT LUN command
13968c2ecf20Sopenharmony_ci		 */
13978c2ecf20Sopenharmony_ci		ret = 1;
13988c2ecf20Sopenharmony_ci		goto out_err;
13998c2ecf20Sopenharmony_ci	}
14008c2ecf20Sopenharmony_ci
14018c2ecf20Sopenharmony_ci	/*
14028c2ecf20Sopenharmony_ci	 * Get the length from the first four bytes of lun_data.
14038c2ecf20Sopenharmony_ci	 */
14048c2ecf20Sopenharmony_ci	if (get_unaligned_be32(lun_data->scsi_lun) +
14058c2ecf20Sopenharmony_ci	    sizeof(struct scsi_lun) > length) {
14068c2ecf20Sopenharmony_ci		length = get_unaligned_be32(lun_data->scsi_lun) +
14078c2ecf20Sopenharmony_ci			 sizeof(struct scsi_lun);
14088c2ecf20Sopenharmony_ci		kfree(lun_data);
14098c2ecf20Sopenharmony_ci		goto retry;
14108c2ecf20Sopenharmony_ci	}
14118c2ecf20Sopenharmony_ci	length = get_unaligned_be32(lun_data->scsi_lun);
14128c2ecf20Sopenharmony_ci
14138c2ecf20Sopenharmony_ci	num_luns = (length / sizeof(struct scsi_lun));
14148c2ecf20Sopenharmony_ci
14158c2ecf20Sopenharmony_ci	SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
14168c2ecf20Sopenharmony_ci		"scsi scan: REPORT LUN scan\n"));
14178c2ecf20Sopenharmony_ci
14188c2ecf20Sopenharmony_ci	/*
14198c2ecf20Sopenharmony_ci	 * Scan the luns in lun_data. The entry at offset 0 is really
14208c2ecf20Sopenharmony_ci	 * the header, so start at 1 and go up to and including num_luns.
14218c2ecf20Sopenharmony_ci	 */
14228c2ecf20Sopenharmony_ci	for (lunp = &lun_data[1]; lunp <= &lun_data[num_luns]; lunp++) {
14238c2ecf20Sopenharmony_ci		lun = scsilun_to_int(lunp);
14248c2ecf20Sopenharmony_ci
14258c2ecf20Sopenharmony_ci		if (lun > sdev->host->max_lun) {
14268c2ecf20Sopenharmony_ci			sdev_printk(KERN_WARNING, sdev,
14278c2ecf20Sopenharmony_ci				    "lun%llu has a LUN larger than"
14288c2ecf20Sopenharmony_ci				    " allowed by the host adapter\n", lun);
14298c2ecf20Sopenharmony_ci		} else {
14308c2ecf20Sopenharmony_ci			int res;
14318c2ecf20Sopenharmony_ci
14328c2ecf20Sopenharmony_ci			res = scsi_probe_and_add_lun(starget,
14338c2ecf20Sopenharmony_ci				lun, NULL, NULL, rescan, NULL);
14348c2ecf20Sopenharmony_ci			if (res == SCSI_SCAN_NO_RESPONSE) {
14358c2ecf20Sopenharmony_ci				/*
14368c2ecf20Sopenharmony_ci				 * Got some results, but now none, abort.
14378c2ecf20Sopenharmony_ci				 */
14388c2ecf20Sopenharmony_ci				sdev_printk(KERN_ERR, sdev,
14398c2ecf20Sopenharmony_ci					"Unexpected response"
14408c2ecf20Sopenharmony_ci					" from lun %llu while scanning, scan"
14418c2ecf20Sopenharmony_ci					" aborted\n", (unsigned long long)lun);
14428c2ecf20Sopenharmony_ci				break;
14438c2ecf20Sopenharmony_ci			}
14448c2ecf20Sopenharmony_ci		}
14458c2ecf20Sopenharmony_ci	}
14468c2ecf20Sopenharmony_ci
14478c2ecf20Sopenharmony_ci out_err:
14488c2ecf20Sopenharmony_ci	kfree(lun_data);
14498c2ecf20Sopenharmony_ci out:
14508c2ecf20Sopenharmony_ci	if (scsi_device_created(sdev))
14518c2ecf20Sopenharmony_ci		/*
14528c2ecf20Sopenharmony_ci		 * the sdev we used didn't appear in the report luns scan
14538c2ecf20Sopenharmony_ci		 */
14548c2ecf20Sopenharmony_ci		__scsi_remove_device(sdev);
14558c2ecf20Sopenharmony_ci	scsi_device_put(sdev);
14568c2ecf20Sopenharmony_ci	return ret;
14578c2ecf20Sopenharmony_ci}
14588c2ecf20Sopenharmony_ci
14598c2ecf20Sopenharmony_cistruct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
14608c2ecf20Sopenharmony_ci				      uint id, u64 lun, void *hostdata)
14618c2ecf20Sopenharmony_ci{
14628c2ecf20Sopenharmony_ci	struct scsi_device *sdev = ERR_PTR(-ENODEV);
14638c2ecf20Sopenharmony_ci	struct device *parent = &shost->shost_gendev;
14648c2ecf20Sopenharmony_ci	struct scsi_target *starget;
14658c2ecf20Sopenharmony_ci
14668c2ecf20Sopenharmony_ci	if (strncmp(scsi_scan_type, "none", 4) == 0)
14678c2ecf20Sopenharmony_ci		return ERR_PTR(-ENODEV);
14688c2ecf20Sopenharmony_ci
14698c2ecf20Sopenharmony_ci	starget = scsi_alloc_target(parent, channel, id);
14708c2ecf20Sopenharmony_ci	if (!starget)
14718c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
14728c2ecf20Sopenharmony_ci	scsi_autopm_get_target(starget);
14738c2ecf20Sopenharmony_ci
14748c2ecf20Sopenharmony_ci	mutex_lock(&shost->scan_mutex);
14758c2ecf20Sopenharmony_ci	if (!shost->async_scan)
14768c2ecf20Sopenharmony_ci		scsi_complete_async_scans();
14778c2ecf20Sopenharmony_ci
14788c2ecf20Sopenharmony_ci	if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
14798c2ecf20Sopenharmony_ci		scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
14808c2ecf20Sopenharmony_ci		scsi_autopm_put_host(shost);
14818c2ecf20Sopenharmony_ci	}
14828c2ecf20Sopenharmony_ci	mutex_unlock(&shost->scan_mutex);
14838c2ecf20Sopenharmony_ci	scsi_autopm_put_target(starget);
14848c2ecf20Sopenharmony_ci	/*
14858c2ecf20Sopenharmony_ci	 * paired with scsi_alloc_target().  Target will be destroyed unless
14868c2ecf20Sopenharmony_ci	 * scsi_probe_and_add_lun made an underlying device visible
14878c2ecf20Sopenharmony_ci	 */
14888c2ecf20Sopenharmony_ci	scsi_target_reap(starget);
14898c2ecf20Sopenharmony_ci	put_device(&starget->dev);
14908c2ecf20Sopenharmony_ci
14918c2ecf20Sopenharmony_ci	return sdev;
14928c2ecf20Sopenharmony_ci}
14938c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__scsi_add_device);
14948c2ecf20Sopenharmony_ci
14958c2ecf20Sopenharmony_ciint scsi_add_device(struct Scsi_Host *host, uint channel,
14968c2ecf20Sopenharmony_ci		    uint target, u64 lun)
14978c2ecf20Sopenharmony_ci{
14988c2ecf20Sopenharmony_ci	struct scsi_device *sdev =
14998c2ecf20Sopenharmony_ci		__scsi_add_device(host, channel, target, lun, NULL);
15008c2ecf20Sopenharmony_ci	if (IS_ERR(sdev))
15018c2ecf20Sopenharmony_ci		return PTR_ERR(sdev);
15028c2ecf20Sopenharmony_ci
15038c2ecf20Sopenharmony_ci	scsi_device_put(sdev);
15048c2ecf20Sopenharmony_ci	return 0;
15058c2ecf20Sopenharmony_ci}
15068c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_add_device);
15078c2ecf20Sopenharmony_ci
15088c2ecf20Sopenharmony_civoid scsi_rescan_device(struct device *dev)
15098c2ecf20Sopenharmony_ci{
15108c2ecf20Sopenharmony_ci	struct scsi_device *sdev = to_scsi_device(dev);
15118c2ecf20Sopenharmony_ci
15128c2ecf20Sopenharmony_ci	device_lock(dev);
15138c2ecf20Sopenharmony_ci
15148c2ecf20Sopenharmony_ci	scsi_attach_vpd(sdev);
15158c2ecf20Sopenharmony_ci
15168c2ecf20Sopenharmony_ci	if (sdev->handler && sdev->handler->rescan)
15178c2ecf20Sopenharmony_ci		sdev->handler->rescan(sdev);
15188c2ecf20Sopenharmony_ci
15198c2ecf20Sopenharmony_ci	if (dev->driver && try_module_get(dev->driver->owner)) {
15208c2ecf20Sopenharmony_ci		struct scsi_driver *drv = to_scsi_driver(dev->driver);
15218c2ecf20Sopenharmony_ci
15228c2ecf20Sopenharmony_ci		if (drv->rescan)
15238c2ecf20Sopenharmony_ci			drv->rescan(dev);
15248c2ecf20Sopenharmony_ci		module_put(dev->driver->owner);
15258c2ecf20Sopenharmony_ci	}
15268c2ecf20Sopenharmony_ci	device_unlock(dev);
15278c2ecf20Sopenharmony_ci}
15288c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_rescan_device);
15298c2ecf20Sopenharmony_ci
15308c2ecf20Sopenharmony_cistatic void __scsi_scan_target(struct device *parent, unsigned int channel,
15318c2ecf20Sopenharmony_ci		unsigned int id, u64 lun, enum scsi_scan_mode rescan)
15328c2ecf20Sopenharmony_ci{
15338c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = dev_to_shost(parent);
15348c2ecf20Sopenharmony_ci	blist_flags_t bflags = 0;
15358c2ecf20Sopenharmony_ci	int res;
15368c2ecf20Sopenharmony_ci	struct scsi_target *starget;
15378c2ecf20Sopenharmony_ci
15388c2ecf20Sopenharmony_ci	if (shost->this_id == id)
15398c2ecf20Sopenharmony_ci		/*
15408c2ecf20Sopenharmony_ci		 * Don't scan the host adapter
15418c2ecf20Sopenharmony_ci		 */
15428c2ecf20Sopenharmony_ci		return;
15438c2ecf20Sopenharmony_ci
15448c2ecf20Sopenharmony_ci	starget = scsi_alloc_target(parent, channel, id);
15458c2ecf20Sopenharmony_ci	if (!starget)
15468c2ecf20Sopenharmony_ci		return;
15478c2ecf20Sopenharmony_ci	scsi_autopm_get_target(starget);
15488c2ecf20Sopenharmony_ci
15498c2ecf20Sopenharmony_ci	if (lun != SCAN_WILD_CARD) {
15508c2ecf20Sopenharmony_ci		/*
15518c2ecf20Sopenharmony_ci		 * Scan for a specific host/chan/id/lun.
15528c2ecf20Sopenharmony_ci		 */
15538c2ecf20Sopenharmony_ci		scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan, NULL);
15548c2ecf20Sopenharmony_ci		goto out_reap;
15558c2ecf20Sopenharmony_ci	}
15568c2ecf20Sopenharmony_ci
15578c2ecf20Sopenharmony_ci	/*
15588c2ecf20Sopenharmony_ci	 * Scan LUN 0, if there is some response, scan further. Ideally, we
15598c2ecf20Sopenharmony_ci	 * would not configure LUN 0 until all LUNs are scanned.
15608c2ecf20Sopenharmony_ci	 */
15618c2ecf20Sopenharmony_ci	res = scsi_probe_and_add_lun(starget, 0, &bflags, NULL, rescan, NULL);
15628c2ecf20Sopenharmony_ci	if (res == SCSI_SCAN_LUN_PRESENT || res == SCSI_SCAN_TARGET_PRESENT) {
15638c2ecf20Sopenharmony_ci		if (scsi_report_lun_scan(starget, bflags, rescan) != 0)
15648c2ecf20Sopenharmony_ci			/*
15658c2ecf20Sopenharmony_ci			 * The REPORT LUN did not scan the target,
15668c2ecf20Sopenharmony_ci			 * do a sequential scan.
15678c2ecf20Sopenharmony_ci			 */
15688c2ecf20Sopenharmony_ci			scsi_sequential_lun_scan(starget, bflags,
15698c2ecf20Sopenharmony_ci						 starget->scsi_level, rescan);
15708c2ecf20Sopenharmony_ci	}
15718c2ecf20Sopenharmony_ci
15728c2ecf20Sopenharmony_ci out_reap:
15738c2ecf20Sopenharmony_ci	scsi_autopm_put_target(starget);
15748c2ecf20Sopenharmony_ci	/*
15758c2ecf20Sopenharmony_ci	 * paired with scsi_alloc_target(): determine if the target has
15768c2ecf20Sopenharmony_ci	 * any children at all and if not, nuke it
15778c2ecf20Sopenharmony_ci	 */
15788c2ecf20Sopenharmony_ci	scsi_target_reap(starget);
15798c2ecf20Sopenharmony_ci
15808c2ecf20Sopenharmony_ci	put_device(&starget->dev);
15818c2ecf20Sopenharmony_ci}
15828c2ecf20Sopenharmony_ci
15838c2ecf20Sopenharmony_ci/**
15848c2ecf20Sopenharmony_ci * scsi_scan_target - scan a target id, possibly including all LUNs on the target.
15858c2ecf20Sopenharmony_ci * @parent:	host to scan
15868c2ecf20Sopenharmony_ci * @channel:	channel to scan
15878c2ecf20Sopenharmony_ci * @id:		target id to scan
15888c2ecf20Sopenharmony_ci * @lun:	Specific LUN to scan or SCAN_WILD_CARD
15898c2ecf20Sopenharmony_ci * @rescan:	passed to LUN scanning routines; SCSI_SCAN_INITIAL for
15908c2ecf20Sopenharmony_ci *              no rescan, SCSI_SCAN_RESCAN to rescan existing LUNs,
15918c2ecf20Sopenharmony_ci *              and SCSI_SCAN_MANUAL to force scanning even if
15928c2ecf20Sopenharmony_ci *              'scan=manual' is set.
15938c2ecf20Sopenharmony_ci *
15948c2ecf20Sopenharmony_ci * Description:
15958c2ecf20Sopenharmony_ci *     Scan the target id on @parent, @channel, and @id. Scan at least LUN 0,
15968c2ecf20Sopenharmony_ci *     and possibly all LUNs on the target id.
15978c2ecf20Sopenharmony_ci *
15988c2ecf20Sopenharmony_ci *     First try a REPORT LUN scan, if that does not scan the target, do a
15998c2ecf20Sopenharmony_ci *     sequential scan of LUNs on the target id.
16008c2ecf20Sopenharmony_ci **/
16018c2ecf20Sopenharmony_civoid scsi_scan_target(struct device *parent, unsigned int channel,
16028c2ecf20Sopenharmony_ci		      unsigned int id, u64 lun, enum scsi_scan_mode rescan)
16038c2ecf20Sopenharmony_ci{
16048c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = dev_to_shost(parent);
16058c2ecf20Sopenharmony_ci
16068c2ecf20Sopenharmony_ci	if (strncmp(scsi_scan_type, "none", 4) == 0)
16078c2ecf20Sopenharmony_ci		return;
16088c2ecf20Sopenharmony_ci
16098c2ecf20Sopenharmony_ci	if (rescan != SCSI_SCAN_MANUAL &&
16108c2ecf20Sopenharmony_ci	    strncmp(scsi_scan_type, "manual", 6) == 0)
16118c2ecf20Sopenharmony_ci		return;
16128c2ecf20Sopenharmony_ci
16138c2ecf20Sopenharmony_ci	mutex_lock(&shost->scan_mutex);
16148c2ecf20Sopenharmony_ci	if (!shost->async_scan)
16158c2ecf20Sopenharmony_ci		scsi_complete_async_scans();
16168c2ecf20Sopenharmony_ci
16178c2ecf20Sopenharmony_ci	if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
16188c2ecf20Sopenharmony_ci		__scsi_scan_target(parent, channel, id, lun, rescan);
16198c2ecf20Sopenharmony_ci		scsi_autopm_put_host(shost);
16208c2ecf20Sopenharmony_ci	}
16218c2ecf20Sopenharmony_ci	mutex_unlock(&shost->scan_mutex);
16228c2ecf20Sopenharmony_ci}
16238c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_scan_target);
16248c2ecf20Sopenharmony_ci
16258c2ecf20Sopenharmony_cistatic void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
16268c2ecf20Sopenharmony_ci			      unsigned int id, u64 lun,
16278c2ecf20Sopenharmony_ci			      enum scsi_scan_mode rescan)
16288c2ecf20Sopenharmony_ci{
16298c2ecf20Sopenharmony_ci	uint order_id;
16308c2ecf20Sopenharmony_ci
16318c2ecf20Sopenharmony_ci	if (id == SCAN_WILD_CARD)
16328c2ecf20Sopenharmony_ci		for (id = 0; id < shost->max_id; ++id) {
16338c2ecf20Sopenharmony_ci			/*
16348c2ecf20Sopenharmony_ci			 * XXX adapter drivers when possible (FCP, iSCSI)
16358c2ecf20Sopenharmony_ci			 * could modify max_id to match the current max,
16368c2ecf20Sopenharmony_ci			 * not the absolute max.
16378c2ecf20Sopenharmony_ci			 *
16388c2ecf20Sopenharmony_ci			 * XXX add a shost id iterator, so for example,
16398c2ecf20Sopenharmony_ci			 * the FC ID can be the same as a target id
16408c2ecf20Sopenharmony_ci			 * without a huge overhead of sparse id's.
16418c2ecf20Sopenharmony_ci			 */
16428c2ecf20Sopenharmony_ci			if (shost->reverse_ordering)
16438c2ecf20Sopenharmony_ci				/*
16448c2ecf20Sopenharmony_ci				 * Scan from high to low id.
16458c2ecf20Sopenharmony_ci				 */
16468c2ecf20Sopenharmony_ci				order_id = shost->max_id - id - 1;
16478c2ecf20Sopenharmony_ci			else
16488c2ecf20Sopenharmony_ci				order_id = id;
16498c2ecf20Sopenharmony_ci			__scsi_scan_target(&shost->shost_gendev, channel,
16508c2ecf20Sopenharmony_ci					order_id, lun, rescan);
16518c2ecf20Sopenharmony_ci		}
16528c2ecf20Sopenharmony_ci	else
16538c2ecf20Sopenharmony_ci		__scsi_scan_target(&shost->shost_gendev, channel,
16548c2ecf20Sopenharmony_ci				id, lun, rescan);
16558c2ecf20Sopenharmony_ci}
16568c2ecf20Sopenharmony_ci
16578c2ecf20Sopenharmony_ciint scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
16588c2ecf20Sopenharmony_ci			    unsigned int id, u64 lun,
16598c2ecf20Sopenharmony_ci			    enum scsi_scan_mode rescan)
16608c2ecf20Sopenharmony_ci{
16618c2ecf20Sopenharmony_ci	SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost,
16628c2ecf20Sopenharmony_ci		"%s: <%u:%u:%llu>\n",
16638c2ecf20Sopenharmony_ci		__func__, channel, id, lun));
16648c2ecf20Sopenharmony_ci
16658c2ecf20Sopenharmony_ci	if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
16668c2ecf20Sopenharmony_ci	    ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
16678c2ecf20Sopenharmony_ci	    ((lun != SCAN_WILD_CARD) && (lun >= shost->max_lun)))
16688c2ecf20Sopenharmony_ci		return -EINVAL;
16698c2ecf20Sopenharmony_ci
16708c2ecf20Sopenharmony_ci	mutex_lock(&shost->scan_mutex);
16718c2ecf20Sopenharmony_ci	if (!shost->async_scan)
16728c2ecf20Sopenharmony_ci		scsi_complete_async_scans();
16738c2ecf20Sopenharmony_ci
16748c2ecf20Sopenharmony_ci	if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
16758c2ecf20Sopenharmony_ci		if (channel == SCAN_WILD_CARD)
16768c2ecf20Sopenharmony_ci			for (channel = 0; channel <= shost->max_channel;
16778c2ecf20Sopenharmony_ci			     channel++)
16788c2ecf20Sopenharmony_ci				scsi_scan_channel(shost, channel, id, lun,
16798c2ecf20Sopenharmony_ci						  rescan);
16808c2ecf20Sopenharmony_ci		else
16818c2ecf20Sopenharmony_ci			scsi_scan_channel(shost, channel, id, lun, rescan);
16828c2ecf20Sopenharmony_ci		scsi_autopm_put_host(shost);
16838c2ecf20Sopenharmony_ci	}
16848c2ecf20Sopenharmony_ci	mutex_unlock(&shost->scan_mutex);
16858c2ecf20Sopenharmony_ci
16868c2ecf20Sopenharmony_ci	return 0;
16878c2ecf20Sopenharmony_ci}
16888c2ecf20Sopenharmony_ci
16898c2ecf20Sopenharmony_cistatic void scsi_sysfs_add_devices(struct Scsi_Host *shost)
16908c2ecf20Sopenharmony_ci{
16918c2ecf20Sopenharmony_ci	struct scsi_device *sdev;
16928c2ecf20Sopenharmony_ci	shost_for_each_device(sdev, shost) {
16938c2ecf20Sopenharmony_ci		/* target removed before the device could be added */
16948c2ecf20Sopenharmony_ci		if (sdev->sdev_state == SDEV_DEL)
16958c2ecf20Sopenharmony_ci			continue;
16968c2ecf20Sopenharmony_ci		/* If device is already visible, skip adding it to sysfs */
16978c2ecf20Sopenharmony_ci		if (sdev->is_visible)
16988c2ecf20Sopenharmony_ci			continue;
16998c2ecf20Sopenharmony_ci		if (!scsi_host_scan_allowed(shost) ||
17008c2ecf20Sopenharmony_ci		    scsi_sysfs_add_sdev(sdev) != 0)
17018c2ecf20Sopenharmony_ci			__scsi_remove_device(sdev);
17028c2ecf20Sopenharmony_ci	}
17038c2ecf20Sopenharmony_ci}
17048c2ecf20Sopenharmony_ci
17058c2ecf20Sopenharmony_ci/**
17068c2ecf20Sopenharmony_ci * scsi_prep_async_scan - prepare for an async scan
17078c2ecf20Sopenharmony_ci * @shost: the host which will be scanned
17088c2ecf20Sopenharmony_ci * Returns: a cookie to be passed to scsi_finish_async_scan()
17098c2ecf20Sopenharmony_ci *
17108c2ecf20Sopenharmony_ci * Tells the midlayer this host is going to do an asynchronous scan.
17118c2ecf20Sopenharmony_ci * It reserves the host's position in the scanning list and ensures
17128c2ecf20Sopenharmony_ci * that other asynchronous scans started after this one won't affect the
17138c2ecf20Sopenharmony_ci * ordering of the discovered devices.
17148c2ecf20Sopenharmony_ci */
17158c2ecf20Sopenharmony_cistatic struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
17168c2ecf20Sopenharmony_ci{
17178c2ecf20Sopenharmony_ci	struct async_scan_data *data = NULL;
17188c2ecf20Sopenharmony_ci	unsigned long flags;
17198c2ecf20Sopenharmony_ci
17208c2ecf20Sopenharmony_ci	if (strncmp(scsi_scan_type, "sync", 4) == 0)
17218c2ecf20Sopenharmony_ci		return NULL;
17228c2ecf20Sopenharmony_ci
17238c2ecf20Sopenharmony_ci	mutex_lock(&shost->scan_mutex);
17248c2ecf20Sopenharmony_ci	if (shost->async_scan) {
17258c2ecf20Sopenharmony_ci		shost_printk(KERN_DEBUG, shost, "%s called twice\n", __func__);
17268c2ecf20Sopenharmony_ci		goto err;
17278c2ecf20Sopenharmony_ci	}
17288c2ecf20Sopenharmony_ci
17298c2ecf20Sopenharmony_ci	data = kmalloc(sizeof(*data), GFP_KERNEL);
17308c2ecf20Sopenharmony_ci	if (!data)
17318c2ecf20Sopenharmony_ci		goto err;
17328c2ecf20Sopenharmony_ci	data->shost = scsi_host_get(shost);
17338c2ecf20Sopenharmony_ci	if (!data->shost)
17348c2ecf20Sopenharmony_ci		goto err;
17358c2ecf20Sopenharmony_ci	init_completion(&data->prev_finished);
17368c2ecf20Sopenharmony_ci
17378c2ecf20Sopenharmony_ci	spin_lock_irqsave(shost->host_lock, flags);
17388c2ecf20Sopenharmony_ci	shost->async_scan = 1;
17398c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(shost->host_lock, flags);
17408c2ecf20Sopenharmony_ci	mutex_unlock(&shost->scan_mutex);
17418c2ecf20Sopenharmony_ci
17428c2ecf20Sopenharmony_ci	spin_lock(&async_scan_lock);
17438c2ecf20Sopenharmony_ci	if (list_empty(&scanning_hosts))
17448c2ecf20Sopenharmony_ci		complete(&data->prev_finished);
17458c2ecf20Sopenharmony_ci	list_add_tail(&data->list, &scanning_hosts);
17468c2ecf20Sopenharmony_ci	spin_unlock(&async_scan_lock);
17478c2ecf20Sopenharmony_ci
17488c2ecf20Sopenharmony_ci	return data;
17498c2ecf20Sopenharmony_ci
17508c2ecf20Sopenharmony_ci err:
17518c2ecf20Sopenharmony_ci	mutex_unlock(&shost->scan_mutex);
17528c2ecf20Sopenharmony_ci	kfree(data);
17538c2ecf20Sopenharmony_ci	return NULL;
17548c2ecf20Sopenharmony_ci}
17558c2ecf20Sopenharmony_ci
17568c2ecf20Sopenharmony_ci/**
17578c2ecf20Sopenharmony_ci * scsi_finish_async_scan - asynchronous scan has finished
17588c2ecf20Sopenharmony_ci * @data: cookie returned from earlier call to scsi_prep_async_scan()
17598c2ecf20Sopenharmony_ci *
17608c2ecf20Sopenharmony_ci * All the devices currently attached to this host have been found.
17618c2ecf20Sopenharmony_ci * This function announces all the devices it has found to the rest
17628c2ecf20Sopenharmony_ci * of the system.
17638c2ecf20Sopenharmony_ci */
17648c2ecf20Sopenharmony_cistatic void scsi_finish_async_scan(struct async_scan_data *data)
17658c2ecf20Sopenharmony_ci{
17668c2ecf20Sopenharmony_ci	struct Scsi_Host *shost;
17678c2ecf20Sopenharmony_ci	unsigned long flags;
17688c2ecf20Sopenharmony_ci
17698c2ecf20Sopenharmony_ci	if (!data)
17708c2ecf20Sopenharmony_ci		return;
17718c2ecf20Sopenharmony_ci
17728c2ecf20Sopenharmony_ci	shost = data->shost;
17738c2ecf20Sopenharmony_ci
17748c2ecf20Sopenharmony_ci	mutex_lock(&shost->scan_mutex);
17758c2ecf20Sopenharmony_ci
17768c2ecf20Sopenharmony_ci	if (!shost->async_scan) {
17778c2ecf20Sopenharmony_ci		shost_printk(KERN_INFO, shost, "%s called twice\n", __func__);
17788c2ecf20Sopenharmony_ci		dump_stack();
17798c2ecf20Sopenharmony_ci		mutex_unlock(&shost->scan_mutex);
17808c2ecf20Sopenharmony_ci		return;
17818c2ecf20Sopenharmony_ci	}
17828c2ecf20Sopenharmony_ci
17838c2ecf20Sopenharmony_ci	wait_for_completion(&data->prev_finished);
17848c2ecf20Sopenharmony_ci
17858c2ecf20Sopenharmony_ci	scsi_sysfs_add_devices(shost);
17868c2ecf20Sopenharmony_ci
17878c2ecf20Sopenharmony_ci	spin_lock_irqsave(shost->host_lock, flags);
17888c2ecf20Sopenharmony_ci	shost->async_scan = 0;
17898c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(shost->host_lock, flags);
17908c2ecf20Sopenharmony_ci
17918c2ecf20Sopenharmony_ci	mutex_unlock(&shost->scan_mutex);
17928c2ecf20Sopenharmony_ci
17938c2ecf20Sopenharmony_ci	spin_lock(&async_scan_lock);
17948c2ecf20Sopenharmony_ci	list_del(&data->list);
17958c2ecf20Sopenharmony_ci	if (!list_empty(&scanning_hosts)) {
17968c2ecf20Sopenharmony_ci		struct async_scan_data *next = list_entry(scanning_hosts.next,
17978c2ecf20Sopenharmony_ci				struct async_scan_data, list);
17988c2ecf20Sopenharmony_ci		complete(&next->prev_finished);
17998c2ecf20Sopenharmony_ci	}
18008c2ecf20Sopenharmony_ci	spin_unlock(&async_scan_lock);
18018c2ecf20Sopenharmony_ci
18028c2ecf20Sopenharmony_ci	scsi_autopm_put_host(shost);
18038c2ecf20Sopenharmony_ci	scsi_host_put(shost);
18048c2ecf20Sopenharmony_ci	kfree(data);
18058c2ecf20Sopenharmony_ci}
18068c2ecf20Sopenharmony_ci
18078c2ecf20Sopenharmony_cistatic void do_scsi_scan_host(struct Scsi_Host *shost)
18088c2ecf20Sopenharmony_ci{
18098c2ecf20Sopenharmony_ci	if (shost->hostt->scan_finished) {
18108c2ecf20Sopenharmony_ci		unsigned long start = jiffies;
18118c2ecf20Sopenharmony_ci		if (shost->hostt->scan_start)
18128c2ecf20Sopenharmony_ci			shost->hostt->scan_start(shost);
18138c2ecf20Sopenharmony_ci
18148c2ecf20Sopenharmony_ci		while (!shost->hostt->scan_finished(shost, jiffies - start))
18158c2ecf20Sopenharmony_ci			msleep(10);
18168c2ecf20Sopenharmony_ci	} else {
18178c2ecf20Sopenharmony_ci		scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
18188c2ecf20Sopenharmony_ci				SCAN_WILD_CARD, 0);
18198c2ecf20Sopenharmony_ci	}
18208c2ecf20Sopenharmony_ci}
18218c2ecf20Sopenharmony_ci
18228c2ecf20Sopenharmony_cistatic void do_scan_async(void *_data, async_cookie_t c)
18238c2ecf20Sopenharmony_ci{
18248c2ecf20Sopenharmony_ci	struct async_scan_data *data = _data;
18258c2ecf20Sopenharmony_ci	struct Scsi_Host *shost = data->shost;
18268c2ecf20Sopenharmony_ci
18278c2ecf20Sopenharmony_ci	do_scsi_scan_host(shost);
18288c2ecf20Sopenharmony_ci	scsi_finish_async_scan(data);
18298c2ecf20Sopenharmony_ci}
18308c2ecf20Sopenharmony_ci
18318c2ecf20Sopenharmony_ci/**
18328c2ecf20Sopenharmony_ci * scsi_scan_host - scan the given adapter
18338c2ecf20Sopenharmony_ci * @shost:	adapter to scan
18348c2ecf20Sopenharmony_ci **/
18358c2ecf20Sopenharmony_civoid scsi_scan_host(struct Scsi_Host *shost)
18368c2ecf20Sopenharmony_ci{
18378c2ecf20Sopenharmony_ci	struct async_scan_data *data;
18388c2ecf20Sopenharmony_ci
18398c2ecf20Sopenharmony_ci	if (strncmp(scsi_scan_type, "none", 4) == 0 ||
18408c2ecf20Sopenharmony_ci	    strncmp(scsi_scan_type, "manual", 6) == 0)
18418c2ecf20Sopenharmony_ci		return;
18428c2ecf20Sopenharmony_ci	if (scsi_autopm_get_host(shost) < 0)
18438c2ecf20Sopenharmony_ci		return;
18448c2ecf20Sopenharmony_ci
18458c2ecf20Sopenharmony_ci	data = scsi_prep_async_scan(shost);
18468c2ecf20Sopenharmony_ci	if (!data) {
18478c2ecf20Sopenharmony_ci		do_scsi_scan_host(shost);
18488c2ecf20Sopenharmony_ci		scsi_autopm_put_host(shost);
18498c2ecf20Sopenharmony_ci		return;
18508c2ecf20Sopenharmony_ci	}
18518c2ecf20Sopenharmony_ci
18528c2ecf20Sopenharmony_ci	/* register with the async subsystem so wait_for_device_probe()
18538c2ecf20Sopenharmony_ci	 * will flush this work
18548c2ecf20Sopenharmony_ci	 */
18558c2ecf20Sopenharmony_ci	async_schedule(do_scan_async, data);
18568c2ecf20Sopenharmony_ci
18578c2ecf20Sopenharmony_ci	/* scsi_autopm_put_host(shost) is called in scsi_finish_async_scan() */
18588c2ecf20Sopenharmony_ci}
18598c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_scan_host);
18608c2ecf20Sopenharmony_ci
18618c2ecf20Sopenharmony_civoid scsi_forget_host(struct Scsi_Host *shost)
18628c2ecf20Sopenharmony_ci{
18638c2ecf20Sopenharmony_ci	struct scsi_device *sdev;
18648c2ecf20Sopenharmony_ci	unsigned long flags;
18658c2ecf20Sopenharmony_ci
18668c2ecf20Sopenharmony_ci restart:
18678c2ecf20Sopenharmony_ci	spin_lock_irqsave(shost->host_lock, flags);
18688c2ecf20Sopenharmony_ci	list_for_each_entry(sdev, &shost->__devices, siblings) {
18698c2ecf20Sopenharmony_ci		if (sdev->sdev_state == SDEV_DEL)
18708c2ecf20Sopenharmony_ci			continue;
18718c2ecf20Sopenharmony_ci		spin_unlock_irqrestore(shost->host_lock, flags);
18728c2ecf20Sopenharmony_ci		__scsi_remove_device(sdev);
18738c2ecf20Sopenharmony_ci		goto restart;
18748c2ecf20Sopenharmony_ci	}
18758c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(shost->host_lock, flags);
18768c2ecf20Sopenharmony_ci}
18778c2ecf20Sopenharmony_ci
18788c2ecf20Sopenharmony_ci/**
18798c2ecf20Sopenharmony_ci * scsi_get_host_dev - Create a scsi_device that points to the host adapter itself
18808c2ecf20Sopenharmony_ci * @shost: Host that needs a scsi_device
18818c2ecf20Sopenharmony_ci *
18828c2ecf20Sopenharmony_ci * Lock status: None assumed.
18838c2ecf20Sopenharmony_ci *
18848c2ecf20Sopenharmony_ci * Returns:     The scsi_device or NULL
18858c2ecf20Sopenharmony_ci *
18868c2ecf20Sopenharmony_ci * Notes:
18878c2ecf20Sopenharmony_ci *	Attach a single scsi_device to the Scsi_Host - this should
18888c2ecf20Sopenharmony_ci *	be made to look like a "pseudo-device" that points to the
18898c2ecf20Sopenharmony_ci *	HA itself.
18908c2ecf20Sopenharmony_ci *
18918c2ecf20Sopenharmony_ci *	Note - this device is not accessible from any high-level
18928c2ecf20Sopenharmony_ci *	drivers (including generics), which is probably not
18938c2ecf20Sopenharmony_ci *	optimal.  We can add hooks later to attach.
18948c2ecf20Sopenharmony_ci */
18958c2ecf20Sopenharmony_cistruct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
18968c2ecf20Sopenharmony_ci{
18978c2ecf20Sopenharmony_ci	struct scsi_device *sdev = NULL;
18988c2ecf20Sopenharmony_ci	struct scsi_target *starget;
18998c2ecf20Sopenharmony_ci
19008c2ecf20Sopenharmony_ci	mutex_lock(&shost->scan_mutex);
19018c2ecf20Sopenharmony_ci	if (!scsi_host_scan_allowed(shost))
19028c2ecf20Sopenharmony_ci		goto out;
19038c2ecf20Sopenharmony_ci	starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id);
19048c2ecf20Sopenharmony_ci	if (!starget)
19058c2ecf20Sopenharmony_ci		goto out;
19068c2ecf20Sopenharmony_ci
19078c2ecf20Sopenharmony_ci	sdev = scsi_alloc_sdev(starget, 0, NULL);
19088c2ecf20Sopenharmony_ci	if (sdev)
19098c2ecf20Sopenharmony_ci		sdev->borken = 0;
19108c2ecf20Sopenharmony_ci	else
19118c2ecf20Sopenharmony_ci		scsi_target_reap(starget);
19128c2ecf20Sopenharmony_ci	put_device(&starget->dev);
19138c2ecf20Sopenharmony_ci out:
19148c2ecf20Sopenharmony_ci	mutex_unlock(&shost->scan_mutex);
19158c2ecf20Sopenharmony_ci	return sdev;
19168c2ecf20Sopenharmony_ci}
19178c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_get_host_dev);
19188c2ecf20Sopenharmony_ci
19198c2ecf20Sopenharmony_ci/**
19208c2ecf20Sopenharmony_ci * scsi_free_host_dev - Free a scsi_device that points to the host adapter itself
19218c2ecf20Sopenharmony_ci * @sdev: Host device to be freed
19228c2ecf20Sopenharmony_ci *
19238c2ecf20Sopenharmony_ci * Lock status: None assumed.
19248c2ecf20Sopenharmony_ci *
19258c2ecf20Sopenharmony_ci * Returns:     Nothing
19268c2ecf20Sopenharmony_ci */
19278c2ecf20Sopenharmony_civoid scsi_free_host_dev(struct scsi_device *sdev)
19288c2ecf20Sopenharmony_ci{
19298c2ecf20Sopenharmony_ci	BUG_ON(sdev->id != sdev->host->this_id);
19308c2ecf20Sopenharmony_ci
19318c2ecf20Sopenharmony_ci	__scsi_remove_device(sdev);
19328c2ecf20Sopenharmony_ci}
19338c2ecf20Sopenharmony_ciEXPORT_SYMBOL(scsi_free_host_dev);
19348c2ecf20Sopenharmony_ci
1935