Blame view

drivers/scsi/scsi_scan.c 54.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
  /*
   * scsi_scan.c
   *
   * Copyright (C) 2000 Eric Youngdale,
   * Copyright (C) 2002 Patrick Mansfield
   *
   * The general scanning/probing algorithm is as follows, exceptions are
   * made to it depending on device specific flags, compilation options, and
   * global variable (boot or module load time) settings.
   *
   * A specific LUN is scanned via an INQUIRY command; if the LUN has a
f64a181d8   Christoph Hellwig   [SCSI] remove Scs...
12
   * device attached, a scsi_device is allocated and setup for it.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
18
19
   *
   * For every id of every channel on the given host:
   *
   * 	Scan LUN 0; if the target responds to LUN 0 (even if there is no
   * 	device or storage attached to LUN 0):
   *
   * 		If LUN 0 has a device attached, allocate and setup a
f64a181d8   Christoph Hellwig   [SCSI] remove Scs...
20
   * 		scsi_device for it.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
23
24
25
26
   *
   * 		If target is SCSI-3 or up, issue a REPORT LUN, and scan
   * 		all of the LUNs returned by the REPORT LUN; else,
   * 		sequentially scan LUNs up until some maximum is reached,
   * 		or a LUN is seen that cannot have a device attached to it.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
30
  #include <linux/module.h>
  #include <linux/moduleparam.h>
  #include <linux/init.h>
  #include <linux/blkdev.h>
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
31
32
33
  #include <linux/delay.h>
  #include <linux/kthread.h>
  #include <linux/spinlock.h>
4ace92fc1   Arjan van de Ven   fastboot: make sc...
34
  #include <linux/async.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
35
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
  
  #include <scsi/scsi.h>
beb404875   Christoph Hellwig   [SCSI] remove scs...
38
  #include <scsi/scsi_cmnd.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
  #include <scsi/scsi_device.h>
  #include <scsi/scsi_driver.h>
  #include <scsi/scsi_devinfo.h>
  #include <scsi/scsi_host.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  #include <scsi/scsi_transport.h>
  #include <scsi/scsi_eh.h>
  
  #include "scsi_priv.h"
  #include "scsi_logging.h"
  
  #define ALLOC_FAILURE_MSG	KERN_ERR "%s: Allocation failure during" \
  	" SCSI scanning, some SCSI devices might not be configured
  "
  
  /*
   * Default timeout
   */
  #define SCSI_TIMEOUT (2*HZ)
  
  /*
405ae7d38   Robert P. J. Day   Replace remaining...
59
   * Prefix values for the SCSI id's (stored in sysfs name field)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
   */
  #define SCSI_UID_SER_NUM 'S'
  #define SCSI_UID_UNKNOWN 'Z'
  
  /*
   * Return values of some of the scanning functions.
   *
   * SCSI_SCAN_NO_RESPONSE: no valid response received from the target, this
   * includes allocation or general failures preventing IO from being sent.
   *
   * SCSI_SCAN_TARGET_PRESENT: target responded, but no device is available
   * on the given LUN.
   *
   * SCSI_SCAN_LUN_PRESENT: target responded, and a device is available on a
   * given LUN.
   */
  #define SCSI_SCAN_NO_RESPONSE		0
  #define SCSI_SCAN_TARGET_PRESENT	1
  #define SCSI_SCAN_LUN_PRESENT		2
0ad78200b   Arjan van de Ven   [SCSI] Mark some ...
79
  static const char *scsi_null_device_strs = "nullnullnullnull";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
82
83
84
85
86
87
  
  #define MAX_SCSI_LUNS	512
  
  #ifdef CONFIG_SCSI_MULTI_LUN
  static unsigned int max_scsi_luns = MAX_SCSI_LUNS;
  #else
  static unsigned int max_scsi_luns = 1;
  #endif
10f4b89a0   Masatake YAMATO   [SCSI] Fix signne...
88
  module_param_named(max_luns, max_scsi_luns, uint, S_IRUGO|S_IWUSR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
90
  MODULE_PARM_DESC(max_luns,
  		 "last scsi LUN (should be between 1 and 2^32-1)");
21db1882f   Matthew Wilcox   [SCSI] Add Kconfi...
91
92
93
94
95
96
97
  #ifdef CONFIG_SCSI_SCAN_ASYNC
  #define SCSI_SCAN_TYPE_DEFAULT "async"
  #else
  #define SCSI_SCAN_TYPE_DEFAULT "sync"
  #endif
  
  static char scsi_scan_type[6] = SCSI_SCAN_TYPE_DEFAULT;
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
98
99
100
  
  module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO);
  MODULE_PARM_DESC(scan, "sync, async or none");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
105
106
107
108
  /*
   * max_scsi_report_luns: the maximum number of LUNS that will be
   * returned from the REPORT LUNS command. 8 times this value must
   * be allocated. In theory this could be up to an 8 byte value, but
   * in practice, the maximum number of LUNs suppored by any device
   * is about 16k.
   */
  static unsigned int max_scsi_report_luns = 511;
10f4b89a0   Masatake YAMATO   [SCSI] Fix signne...
109
  module_param_named(max_report_luns, max_scsi_report_luns, uint, S_IRUGO|S_IWUSR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
111
112
  MODULE_PARM_DESC(max_report_luns,
  		 "REPORT LUNS maximum number of LUNS received (should be"
  		 " between 1 and 16384)");
14faf12f7   Alan Stern   [SCSI] Increase d...
113
  static unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ + 18;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114

10f4b89a0   Masatake YAMATO   [SCSI] Fix signne...
115
  module_param_named(inq_timeout, scsi_inq_timeout, uint, S_IRUGO|S_IWUSR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
  MODULE_PARM_DESC(inq_timeout, 
  		 "Timeout (in seconds) waiting for devices to answer INQUIRY."
14faf12f7   Alan Stern   [SCSI] Increase d...
118
  		 " Default is 20. Some devices may need more; most need less.");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119

6b7f123f3   Matthew Wilcox   [SCSI] Fix async ...
120
  /* This lock protects only this list */
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
121
122
123
124
125
126
127
128
129
130
131
132
  static DEFINE_SPINLOCK(async_scan_lock);
  static LIST_HEAD(scanning_hosts);
  
  struct async_scan_data {
  	struct list_head list;
  	struct Scsi_Host *shost;
  	struct completion prev_finished;
  };
  
  /**
   * scsi_complete_async_scans - Wait for asynchronous scans to complete
   *
8bcc24127   Matthew Wilcox   [SCSI] Add missin...
133
134
135
136
   * When this function returns, any host which started scanning before
   * this function was called will have finished its scan.  Hosts which
   * started scanning after this function was called may or may not have
   * finished.
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
   */
  int scsi_complete_async_scans(void)
  {
  	struct async_scan_data *data;
  
  	do {
  		if (list_empty(&scanning_hosts))
  			return 0;
  		/* If we can't get memory immediately, that's OK.  Just
  		 * sleep a little.  Even if we never get memory, the async
  		 * scans will finish eventually.
  		 */
  		data = kmalloc(sizeof(*data), GFP_KERNEL);
  		if (!data)
  			msleep(1);
  	} while (!data);
  
  	data->shost = NULL;
  	init_completion(&data->prev_finished);
  
  	spin_lock(&async_scan_lock);
  	/* Check that there's still somebody else on the list */
  	if (list_empty(&scanning_hosts))
  		goto done;
  	list_add_tail(&data->list, &scanning_hosts);
  	spin_unlock(&async_scan_lock);
  
  	printk(KERN_INFO "scsi: waiting for bus probes to complete ...
  ");
  	wait_for_completion(&data->prev_finished);
  
  	spin_lock(&async_scan_lock);
  	list_del(&data->list);
8bcc24127   Matthew Wilcox   [SCSI] Add missin...
170
171
172
173
174
  	if (!list_empty(&scanning_hosts)) {
  		struct async_scan_data *next = list_entry(scanning_hosts.next,
  				struct async_scan_data, list);
  		complete(&next->prev_finished);
  	}
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
175
176
177
178
179
180
   done:
  	spin_unlock(&async_scan_lock);
  
  	kfree(data);
  	return 0;
  }
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
181
182
  /* Only exported for the benefit of scsi_wait_scan */
  EXPORT_SYMBOL_GPL(scsi_complete_async_scans);
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
183

f2f027c6e   Hugh Dickins   [SCSI] fix CONFIG...
184
185
186
187
188
189
190
191
  #ifndef MODULE
  /*
   * For async scanning we need to wait for all the scans to complete before
   * trying to mount the root fs.  Otherwise non-modular drivers may not be ready
   * yet.
   */
  late_initcall(scsi_complete_async_scans);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
  /**
   * scsi_unlock_floptical - unlock device via a special MODE SENSE command
392160335   James Bottomley   [SCSI] use scatte...
194
   * @sdev:	scsi device to send command to
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
196
197
   * @result:	area to store the result of the MODE SENSE
   *
   * Description:
392160335   James Bottomley   [SCSI] use scatte...
198
   *     Send a vendor specific MODE SENSE (not a MODE SELECT) command.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
200
   *     Called for BLIST_KEY devices.
   **/
392160335   James Bottomley   [SCSI] use scatte...
201
  static void scsi_unlock_floptical(struct scsi_device *sdev,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
203
204
205
206
207
208
209
210
211
  				  unsigned char *result)
  {
  	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
  
  	printk(KERN_NOTICE "scsi: unlocking floptical drive
  ");
  	scsi_cmd[0] = MODE_SENSE;
  	scsi_cmd[1] = 0;
  	scsi_cmd[2] = 0x2e;
  	scsi_cmd[3] = 0;
392160335   James Bottomley   [SCSI] use scatte...
212
  	scsi_cmd[4] = 0x2a;     /* size */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
  	scsi_cmd[5] = 0;
392160335   James Bottomley   [SCSI] use scatte...
214
  	scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, result, 0x2a, NULL,
f4f4e47e4   FUJITA Tomonori   [SCSI] add residu...
215
  			 SCSI_TIMEOUT, 3, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
217
218
  }
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219
   * scsi_alloc_sdev - allocate and setup a scsi_Device
eb44820c2   Rob Landley   [SCSI] Add Docume...
220
221
222
   * @starget: which target to allocate a &scsi_device for
   * @lun: which lun
   * @hostdata: usually NULL and set by ->slave_alloc instead
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
   *
   * Description:
   *     Allocate, initialize for io, and return a pointer to a scsi_Device.
   *     Stores the @shost, @channel, @id, and @lun in the scsi_Device, and
   *     adds scsi_Device to the appropriate list.
   *
   * Return value:
   *     scsi_Device pointer, or NULL on failure.
   **/
  static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
  					   unsigned int lun, void *hostdata)
  {
  	struct scsi_device *sdev;
  	int display_failure_msg = 1, ret;
  	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
a341cd0f6   Jeff Garzik   SCSI: add asynchr...
238
  	extern void scsi_evt_thread(struct work_struct *work);
9937a5e2f   Jens Axboe   scsi: remove perf...
239
  	extern void scsi_requeue_run_queue(struct work_struct *work);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240

24669f75a   Jes Sorensen   [SCSI] SCSI core ...
241
  	sdev = kzalloc(sizeof(*sdev) + shost->transportt->device_size,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
243
244
  		       GFP_ATOMIC);
  	if (!sdev)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
246
247
248
  	sdev->vendor = scsi_null_device_strs;
  	sdev->model = scsi_null_device_strs;
  	sdev->rev = scsi_null_device_strs;
  	sdev->host = shost;
4a84067db   Vasu Dev   [SCSI] add queue_...
249
  	sdev->queue_ramp_up_period = SCSI_DEFAULT_RAMP_UP_PERIOD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250
251
252
253
254
255
256
257
  	sdev->id = starget->id;
  	sdev->lun = lun;
  	sdev->channel = starget->channel;
  	sdev->sdev_state = SDEV_CREATED;
  	INIT_LIST_HEAD(&sdev->siblings);
  	INIT_LIST_HEAD(&sdev->same_target_siblings);
  	INIT_LIST_HEAD(&sdev->cmd_list);
  	INIT_LIST_HEAD(&sdev->starved_entry);
a341cd0f6   Jeff Garzik   SCSI: add asynchr...
258
  	INIT_LIST_HEAD(&sdev->event_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259
  	spin_lock_init(&sdev->list_lock);
a341cd0f6   Jeff Garzik   SCSI: add asynchr...
260
  	INIT_WORK(&sdev->event_work, scsi_evt_thread);
9937a5e2f   Jens Axboe   scsi: remove perf...
261
  	INIT_WORK(&sdev->requeue_work, scsi_requeue_run_queue);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  
  	sdev->sdev_gendev.parent = get_device(&starget->dev);
  	sdev->sdev_target = starget;
  
  	/* usually NULL and set by ->slave_alloc instead */
  	sdev->hostdata = hostdata;
  
  	/* if the device needs this changing, it may do so in the
  	 * slave_configure function */
  	sdev->max_device_blocked = SCSI_DEFAULT_DEVICE_BLOCKED;
  
  	/*
  	 * Some low level driver could use device->type
  	 */
  	sdev->type = -1;
  
  	/*
  	 * Assume that the device will have handshaking problems,
  	 * and then fix this field later if it turns out it
  	 * doesn't
  	 */
  	sdev->borken = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
285
286
287
288
  	sdev->request_queue = scsi_alloc_queue(sdev);
  	if (!sdev->request_queue) {
  		/* release fn is set up in scsi_sysfs_device_initialise, so
  		 * have to free and put manually here */
  		put_device(&starget->dev);
93f560898   Dave Jones   [SCSI] fix two le...
289
  		kfree(sdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
291
  		goto out;
  	}
09ac46c42   Tejun Heo   block: misc updat...
292
  	WARN_ON_ONCE(!blk_get_queue(sdev->request_queue));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
294
295
296
297
298
299
300
301
302
303
  	sdev->request_queue->queuedata = sdev;
  	scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
  
  	scsi_sysfs_device_initialize(sdev);
  
  	if (shost->hostt->slave_alloc) {
  		ret = shost->hostt->slave_alloc(sdev);
  		if (ret) {
  			/*
  			 * if LLDD reports slave not present, don't clutter
  			 * console with alloc failure messages
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
306
307
308
309
310
311
312
313
  			 */
  			if (ret == -ENXIO)
  				display_failure_msg = 0;
  			goto out_device_destroy;
  		}
  	}
  
  	return sdev;
  
  out_device_destroy:
4e6c82b36   James Bottomley   [SCSI] fix WARNIN...
314
  	__scsi_remove_device(sdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
316
  out:
  	if (display_failure_msg)
cadbd4a5e   Harvey Harrison   [SCSI] replace __...
317
  		printk(ALLOC_FAILURE_MSG, __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
319
  	return NULL;
  }
643eb2d93   James Bottomley   [SCSI] rework scs...
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  static void scsi_target_destroy(struct scsi_target *starget)
  {
  	struct device *dev = &starget->dev;
  	struct Scsi_Host *shost = dev_to_shost(dev->parent);
  	unsigned long flags;
  
  	transport_destroy_device(dev);
  	spin_lock_irqsave(shost->host_lock, flags);
  	if (shost->hostt->target_destroy)
  		shost->hostt->target_destroy(starget);
  	list_del_init(&starget->siblings);
  	spin_unlock_irqrestore(shost->host_lock, flags);
  	put_device(dev);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
335
336
337
  static void scsi_target_dev_release(struct device *dev)
  {
  	struct device *parent = dev->parent;
  	struct scsi_target *starget = to_scsi_target(dev);
a283bd37d   James Bottomley   [SCSI] Add target...
338

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
340
341
  	kfree(starget);
  	put_device(parent);
  }
453cd0f3f   Adrian Bunk   [SCSI] make struc...
342
  static struct device_type scsi_target_type = {
b0ed43360   Hannes Reinecke   [SCSI] add scsi_h...
343
344
345
  	.name =		"scsi_target",
  	.release =	scsi_target_dev_release,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
347
  int scsi_is_target_device(const struct device *dev)
  {
b0ed43360   Hannes Reinecke   [SCSI] add scsi_h...
348
  	return dev->type == &scsi_target_type;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  }
  EXPORT_SYMBOL(scsi_is_target_device);
  
  static struct scsi_target *__scsi_find_target(struct device *parent,
  					      int channel, uint id)
  {
  	struct scsi_target *starget, *found_starget = NULL;
  	struct Scsi_Host *shost = dev_to_shost(parent);
  	/*
  	 * Search for an existing target for this sdev.
  	 */
  	list_for_each_entry(starget, &shost->__targets, siblings) {
  		if (starget->id == id &&
  		    starget->channel == channel) {
  			found_starget = starget;
  			break;
  		}
  	}
  	if (found_starget)
  		get_device(&found_starget->dev);
  
  	return found_starget;
  }
884d25cc4   James Bottomley   [SCSI] Fix refcou...
372
373
374
375
376
377
378
379
380
381
382
383
  /**
   * scsi_alloc_target - allocate a new or find an existing target
   * @parent:	parent of the target (need not be a scsi host)
   * @channel:	target channel number (zero if no channels)
   * @id:		target id number
   *
   * Return an existing target if one exists, provided it hasn't already
   * gone into STARGET_DEL state, otherwise allocate a new target.
   *
   * The target is returned with an incremented reference, so the caller
   * is responsible for both reaping and doing a last put
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384
385
386
387
388
389
390
391
  static struct scsi_target *scsi_alloc_target(struct device *parent,
  					     int channel, uint id)
  {
  	struct Scsi_Host *shost = dev_to_shost(parent);
  	struct device *dev = NULL;
  	unsigned long flags;
  	const int size = sizeof(struct scsi_target)
  		+ shost->transportt->target_size;
5c44cd2af   James.Smart@Emulex.Com   [SCSI] fix target...
392
  	struct scsi_target *starget;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
  	struct scsi_target *found_target;
32f957925   Brian King   [SCSI] scsi: Hand...
394
  	int error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395

24669f75a   Jes Sorensen   [SCSI] SCSI core ...
396
  	starget = kzalloc(size, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
  	if (!starget) {
cadbd4a5e   Harvey Harrison   [SCSI] replace __...
398
399
  		printk(KERN_ERR "%s: allocation failure
  ", __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
400
401
  		return NULL;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
403
404
405
  	dev = &starget->dev;
  	device_initialize(dev);
  	starget->reap_ref = 1;
  	dev->parent = get_device(parent);
71610f55f   Kay Sievers   [SCSI] struct dev...
406
  	dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
b0ed43360   Hannes Reinecke   [SCSI] add scsi_h...
407
  	dev->bus = &scsi_bus_type;
b0ed43360   Hannes Reinecke   [SCSI] add scsi_h...
408
  	dev->type = &scsi_target_type;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409
410
  	starget->id = id;
  	starget->channel = channel;
f0c0a376d   Mike Christie   [SCSI] Add helper...
411
  	starget->can_queue = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412
413
  	INIT_LIST_HEAD(&starget->siblings);
  	INIT_LIST_HEAD(&starget->devices);
643eb2d93   James Bottomley   [SCSI] rework scs...
414
  	starget->state = STARGET_CREATED;
7c9d6f16f   Alan Stern   [SCSI] SCSI core:...
415
  	starget->scsi_level = SCSI_2;
c53a284f8   Edward Goggin   [SCSI] initialize...
416
  	starget->max_target_blocked = SCSI_DEFAULT_TARGET_BLOCKED;
ffedb4522   James Bottomley   [SCSI] fix scsi p...
417
   retry:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418
419
420
421
422
423
424
425
426
  	spin_lock_irqsave(shost->host_lock, flags);
  
  	found_target = __scsi_find_target(parent, channel, id);
  	if (found_target)
  		goto found;
  
  	list_add_tail(&starget->siblings, &shost->__targets);
  	spin_unlock_irqrestore(shost->host_lock, flags);
  	/* allocate and add */
a283bd37d   James Bottomley   [SCSI] Add target...
427
  	transport_setup_device(dev);
a283bd37d   James Bottomley   [SCSI] Add target...
428
  	if (shost->hostt->target_alloc) {
32f957925   Brian King   [SCSI] scsi: Hand...
429
  		error = shost->hostt->target_alloc(starget);
a283bd37d   James Bottomley   [SCSI] Add target...
430
431
432
433
434
435
  
  		if(error) {
  			dev_printk(KERN_ERR, dev, "target allocation failed, error %d
  ", error);
  			/* don't want scsi_target_reap to do the final
  			 * put because it will be under the host lock */
643eb2d93   James Bottomley   [SCSI] rework scs...
436
  			scsi_target_destroy(starget);
a283bd37d   James Bottomley   [SCSI] Add target...
437
438
439
  			return NULL;
  		}
  	}
884d25cc4   James Bottomley   [SCSI] Fix refcou...
440
  	get_device(dev);
a283bd37d   James Bottomley   [SCSI] Add target...
441

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
443
444
445
446
  	return starget;
  
   found:
  	found_target->reap_ref++;
  	spin_unlock_irqrestore(shost->host_lock, flags);
ffedb4522   James Bottomley   [SCSI] fix scsi p...
447
  	if (found_target->state != STARGET_DEL) {
12fb8c157   Alan Stern   [SCSI] don't kfre...
448
  		put_device(dev);
ffedb4522   James Bottomley   [SCSI] fix scsi p...
449
450
451
452
453
454
455
  		return found_target;
  	}
  	/* Unfortunately, we found a dying target; need to
  	 * wait until it's dead before we can get a new one */
  	put_device(&found_target->dev);
  	flush_scheduled_work();
  	goto retry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
  }
65f27f384   David Howells   WorkStruct: Pass ...
457
  static void scsi_target_reap_usercontext(struct work_struct *work)
65110b216   James Bottomley   [SCSI] fix wrong ...
458
  {
65f27f384   David Howells   WorkStruct: Pass ...
459
460
  	struct scsi_target *starget =
  		container_of(work, struct scsi_target, ew.work);
863a930a4   James Bottomley   [SCSI] fix scsi_r...
461

ffedb4522   James Bottomley   [SCSI] fix scsi p...
462
463
  	transport_remove_device(&starget->dev);
  	device_del(&starget->dev);
643eb2d93   James Bottomley   [SCSI] rework scs...
464
  	scsi_target_destroy(starget);
863a930a4   James Bottomley   [SCSI] fix scsi_r...
465
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
466
467
  /**
   * scsi_target_reap - check to see if target is in use and destroy if not
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
468
469
470
471
472
473
474
475
   * @starget: target to be checked
   *
   * This is used after removing a LUN or doing a last put of the target
   * it checks atomically that nothing is using the target and removes
   * it if so.
   */
  void scsi_target_reap(struct scsi_target *starget)
  {
ffedb4522   James Bottomley   [SCSI] fix scsi p...
476
477
  	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
  	unsigned long flags;
643eb2d93   James Bottomley   [SCSI] rework scs...
478
  	enum scsi_target_state state;
f9e8894ae   Alan Stern   [SCSI] fix race i...
479
  	int empty = 0;
ffedb4522   James Bottomley   [SCSI] fix scsi p...
480
481
  
  	spin_lock_irqsave(shost->host_lock, flags);
643eb2d93   James Bottomley   [SCSI] rework scs...
482
  	state = starget->state;
f9e8894ae   Alan Stern   [SCSI] fix race i...
483
484
485
486
  	if (--starget->reap_ref == 0 && list_empty(&starget->devices)) {
  		empty = 1;
  		starget->state = STARGET_DEL;
  	}
643eb2d93   James Bottomley   [SCSI] rework scs...
487
  	spin_unlock_irqrestore(shost->host_lock, flags);
ffedb4522   James Bottomley   [SCSI] fix scsi p...
488

643eb2d93   James Bottomley   [SCSI] rework scs...
489
  	if (!empty)
ffedb4522   James Bottomley   [SCSI] fix scsi p...
490
  		return;
643eb2d93   James Bottomley   [SCSI] rework scs...
491
  	BUG_ON(state == STARGET_DEL);
643eb2d93   James Bottomley   [SCSI] rework scs...
492
493
494
495
496
  	if (state == STARGET_CREATED)
  		scsi_target_destroy(starget);
  	else
  		execute_in_process_context(scsi_target_reap_usercontext,
  					   &starget->ew);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497
498
499
  }
  
  /**
e5b3cd429   Alan Stern   [SCSI] SCSI: sani...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
   * sanitize_inquiry_string - remove non-graphical chars from an INQUIRY result string
   * @s: INQUIRY result string to sanitize
   * @len: length of the string
   *
   * Description:
   *	The SCSI spec says that INQUIRY vendor, product, and revision
   *	strings must consist entirely of graphic ASCII characters,
   *	padded on the right with spaces.  Since not all devices obey
   *	this rule, we will replace non-graphic or non-ASCII characters
   *	with spaces.  Exception: a NUL character is interpreted as a
   *	string terminator, so all the following characters are set to
   *	spaces.
   **/
  static void sanitize_inquiry_string(unsigned char *s, int len)
  {
  	int terminated = 0;
  
  	for (; len > 0; (--len, ++s)) {
  		if (*s == 0)
  			terminated = 1;
  		if (terminated || *s < 0x20 || *s > 0x7e)
  			*s = ' ';
  	}
  }
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
   * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY
392160335   James Bottomley   [SCSI] use scatte...
527
   * @sdev:	scsi_device to probe
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
   * @inq_result:	area to store the INQUIRY result
392160335   James Bottomley   [SCSI] use scatte...
529
   * @result_len: len of inq_result
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
530
531
532
   * @bflags:	store any bflags found here
   *
   * Description:
392160335   James Bottomley   [SCSI] use scatte...
533
   *     Probe the lun associated with @req using a standard SCSI INQUIRY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
   *
392160335   James Bottomley   [SCSI] use scatte...
535
   *     If the INQUIRY is successful, zero is returned and the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
   *     INQUIRY data is in @inq_result; the scsi_level and INQUIRY length
f64a181d8   Christoph Hellwig   [SCSI] remove Scs...
537
   *     are copied to the scsi_device any flags value is stored in *@bflags.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538
   **/
e5b3cd429   Alan Stern   [SCSI] SCSI: sani...
539
  static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
392160335   James Bottomley   [SCSI] use scatte...
540
  			  int result_len, int *bflags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
543
544
  	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
  	int first_inquiry_len, try_inquiry_len, next_inquiry_len;
  	int response_len = 0;
392160335   James Bottomley   [SCSI] use scatte...
545
  	int pass, count, result;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
546
547
548
549
550
551
552
553
554
555
556
557
  	struct scsi_sense_hdr sshdr;
  
  	*bflags = 0;
  
  	/* Perform up to 3 passes.  The first pass uses a conservative
  	 * transfer length of 36 unless sdev->inquiry_len specifies a
  	 * different value. */
  	first_inquiry_len = sdev->inquiry_len ? sdev->inquiry_len : 36;
  	try_inquiry_len = first_inquiry_len;
  	pass = 1;
  
   next_pass:
9ccfc756a   James Bottomley   [SCSI] move the m...
558
559
560
561
  	SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
  				"scsi scan: INQUIRY pass %d length %d
  ",
  				pass, try_inquiry_len));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562
563
564
  
  	/* Each pass gets up to three chances to ignore Unit Attention */
  	for (count = 0; count < 3; ++count) {
5cd3bbfad   FUJITA Tomonori   [SCSI] retry with...
565
  		int resid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566
567
568
  		memset(scsi_cmd, 0, 6);
  		scsi_cmd[0] = INQUIRY;
  		scsi_cmd[4] = (unsigned char) try_inquiry_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
569
570
  
  		memset(inq_result, 0, try_inquiry_len);
392160335   James Bottomley   [SCSI] use scatte...
571
572
  
  		result = scsi_execute_req(sdev,  scsi_cmd, DMA_FROM_DEVICE,
ea73a9f23   James Bottomley   [SCSI] convert sd...
573
  					  inq_result, try_inquiry_len, &sshdr,
f4f4e47e4   FUJITA Tomonori   [SCSI] add residu...
574
  					  HZ / 2 + HZ * scsi_inq_timeout, 3,
5cd3bbfad   FUJITA Tomonori   [SCSI] retry with...
575
  					  &resid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
576
577
578
579
  
  		SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY %s "
  				"with code 0x%x
  ",
392160335   James Bottomley   [SCSI] use scatte...
580
  				result ? "failed" : "successful", result));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581

392160335   James Bottomley   [SCSI] use scatte...
582
  		if (result) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
583
584
585
586
587
588
  			/*
  			 * not-ready to ready transition [asc/ascq=0x28/0x0]
  			 * or power-on, reset [asc/ascq=0x29/0x0], continue.
  			 * INQUIRY should not yield UNIT_ATTENTION
  			 * but many buggy devices do so anyway. 
  			 */
392160335   James Bottomley   [SCSI] use scatte...
589
  			if ((driver_byte(result) & DRIVER_SENSE) &&
ea73a9f23   James Bottomley   [SCSI] convert sd...
590
  			    scsi_sense_valid(&sshdr)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591
592
593
594
595
596
  				if ((sshdr.sense_key == UNIT_ATTENTION) &&
  				    ((sshdr.asc == 0x28) ||
  				     (sshdr.asc == 0x29)) &&
  				    (sshdr.ascq == 0))
  					continue;
  			}
5cd3bbfad   FUJITA Tomonori   [SCSI] retry with...
597
598
599
600
601
602
603
604
  		} else {
  			/*
  			 * if nothing was transferred, we try
  			 * again. It's a workaround for some USB
  			 * devices.
  			 */
  			if (resid == try_inquiry_len)
  				continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
605
606
607
  		}
  		break;
  	}
392160335   James Bottomley   [SCSI] use scatte...
608
  	if (result == 0) {
e5b3cd429   Alan Stern   [SCSI] SCSI: sani...
609
610
611
612
613
  		sanitize_inquiry_string(&inq_result[8], 8);
  		sanitize_inquiry_string(&inq_result[16], 16);
  		sanitize_inquiry_string(&inq_result[32], 4);
  
  		response_len = inq_result[4] + 5;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
614
615
616
617
618
619
  		if (response_len > 255)
  			response_len = first_inquiry_len;	/* sanity */
  
  		/*
  		 * Get any flags for this device.
  		 *
f64a181d8   Christoph Hellwig   [SCSI] remove Scs...
620
621
  		 * XXX add a bflags to scsi_device, and replace the
  		 * corresponding bit fields in scsi_device, so bflags
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
  		 * need not be passed as an argument.
  		 */
  		*bflags = scsi_get_device_flags(sdev, &inq_result[8],
  				&inq_result[16]);
  
  		/* When the first pass succeeds we gain information about
  		 * what larger transfer lengths might work. */
  		if (pass == 1) {
  			if (BLIST_INQUIRY_36 & *bflags)
  				next_inquiry_len = 36;
  			else if (BLIST_INQUIRY_58 & *bflags)
  				next_inquiry_len = 58;
  			else if (sdev->inquiry_len)
  				next_inquiry_len = sdev->inquiry_len;
  			else
  				next_inquiry_len = response_len;
  
  			/* If more data is available perform the second pass */
  			if (next_inquiry_len > try_inquiry_len) {
  				try_inquiry_len = next_inquiry_len;
  				pass = 2;
  				goto next_pass;
  			}
  		}
  
  	} else if (pass == 2) {
  		printk(KERN_INFO "scsi scan: %d byte inquiry failed.  "
  				"Consider BLIST_INQUIRY_36 for this device
  ",
  				try_inquiry_len);
  
  		/* If this pass failed, the third pass goes back and transfers
  		 * the same amount as we successfully got in the first pass. */
  		try_inquiry_len = first_inquiry_len;
  		pass = 3;
  		goto next_pass;
  	}
  
  	/* If the last transfer attempt got an error, assume the
  	 * peripheral doesn't exist or is dead. */
392160335   James Bottomley   [SCSI] use scatte...
662
663
  	if (result)
  		return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
664
665
666
667
668
669
670
671
672
673
674
675
676
  
  	/* Don't report any more data than the device says is valid */
  	sdev->inquiry_len = min(try_inquiry_len, response_len);
  
  	/*
  	 * XXX Abort if the response length is less than 36? If less than
  	 * 32, the lookup of the device flags (above) could be invalid,
  	 * and it would be possible to take an incorrect action - we do
  	 * not want to hang because of a short INQUIRY. On the flip side,
  	 * if the device is spun down or becoming ready (and so it gives a
  	 * short INQUIRY), an abort here prevents any further use of the
  	 * device, including spin up.
  	 *
e423ee31d   Alan Stern   [SCSI] scsi_scan....
677
678
679
680
681
682
683
684
685
686
687
688
689
690
  	 * On the whole, the best approach seems to be to assume the first
  	 * 36 bytes are valid no matter what the device says.  That's
  	 * better than copying < 36 bytes to the inquiry-result buffer
  	 * and displaying garbage for the Vendor, Product, or Revision
  	 * strings.
  	 */
  	if (sdev->inquiry_len < 36) {
  		printk(KERN_INFO "scsi scan: INQUIRY result too short (%d),"
  				" using 36
  ", sdev->inquiry_len);
  		sdev->inquiry_len = 36;
  	}
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
  	 * Related to the above issue:
  	 *
  	 * XXX Devices (disk or all?) should be sent a TEST UNIT READY,
  	 * and if not ready, sent a START_STOP to start (maybe spin up) and
  	 * then send the INQUIRY again, since the INQUIRY can change after
  	 * a device is initialized.
  	 *
  	 * Ideally, start a device if explicitly asked to do so.  This
  	 * assumes that a device is spun up on power on, spun down on
  	 * request, and then spun up on request.
  	 */
  
  	/*
  	 * The scanning code needs to know the scsi_level, even if no
  	 * device is attached at LUN 0 (SCSI_SCAN_TARGET_PRESENT) so
  	 * non-zero LUNs can be scanned.
  	 */
  	sdev->scsi_level = inq_result[2] & 0x07;
  	if (sdev->scsi_level >= 2 ||
  	    (sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1))
  		sdev->scsi_level++;
6f3a20242   James Bottomley   [SCSI] allow REPO...
712
  	sdev->sdev_target->scsi_level = sdev->scsi_level;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
713

392160335   James Bottomley   [SCSI] use scatte...
714
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
715
716
717
  }
  
  /**
f64a181d8   Christoph Hellwig   [SCSI] remove Scs...
718
   * scsi_add_lun - allocate and fully initialze a scsi_device
6d877688e   Matthew Wilcox   [SCSI] Clean up s...
719
   * @sdev:	holds information to be stored in the new scsi_device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
720
721
   * @inq_result:	holds the result of a previous INQUIRY to the LUN
   * @bflags:	black/white list flag
6d877688e   Matthew Wilcox   [SCSI] Clean up s...
722
   * @async:	1 if this device is being scanned asynchronously
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
723
724
   *
   * Description:
6d877688e   Matthew Wilcox   [SCSI] Clean up s...
725
726
   *     Initialize the scsi_device @sdev.  Optionally set fields based
   *     on values in *@bflags.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727
728
   *
   * Return:
f64a181d8   Christoph Hellwig   [SCSI] remove Scs...
729
730
   *     SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
   *     SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
731
   **/
e5b3cd429   Alan Stern   [SCSI] SCSI: sani...
732
  static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
733
  		int *bflags, int async)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
734
  {
6f4267e3b   James Bottomley   [SCSI] Update the...
735
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
736
737
738
739
740
741
742
743
744
745
  	/*
  	 * XXX do not save the inquiry, since it can change underneath us,
  	 * save just vendor/model/rev.
  	 *
  	 * Rather than save it and have an ioctl that retrieves the saved
  	 * value, have an ioctl that executes the same INQUIRY code used
  	 * in scsi_probe_lun, let user level programs doing INQUIRY
  	 * scanning run at their own risk, or supply a user level program
  	 * that can correctly scan.
  	 */
09123d230   Alan Stern   [PATCH] SCSI core...
746
747
748
749
750
751
752
753
754
755
756
757
758
759
  
  	/*
  	 * Copy at least 36 bytes of INQUIRY data, so that we don't
  	 * dereference unallocated memory when accessing the Vendor,
  	 * Product, and Revision strings.  Badly behaved devices may set
  	 * the INQUIRY Additional Length byte to a small value, indicating
  	 * these strings are invalid, but often they contain plausible data
  	 * nonetheless.  It doesn't matter if the device sent < 36 bytes
  	 * total, since scsi_probe_lun() initializes inq_result with 0s.
  	 */
  	sdev->inquiry = kmemdup(inq_result,
  				max_t(size_t, sdev->inquiry_len, 36),
  				GFP_ATOMIC);
  	if (sdev->inquiry == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
760
  		return SCSI_SCAN_NO_RESPONSE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
761

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
762
763
764
765
766
  	sdev->vendor = (char *) (sdev->inquiry + 8);
  	sdev->model = (char *) (sdev->inquiry + 16);
  	sdev->rev = (char *) (sdev->inquiry + 32);
  
  	if (*bflags & BLIST_ISROM) {
6d877688e   Matthew Wilcox   [SCSI] Clean up s...
767
768
769
770
771
772
  		sdev->type = TYPE_ROM;
  		sdev->removable = 1;
  	} else {
  		sdev->type = (inq_result[0] & 0x1f);
  		sdev->removable = (inq_result[1] & 0x80) >> 7;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
773

6d877688e   Matthew Wilcox   [SCSI] Clean up s...
774
  	switch (sdev->type) {
ddaf6fc85   James Bottomley   [SCSI] scsi_scan:...
775
  	case TYPE_RBC:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
776
777
778
779
780
781
782
783
784
  	case TYPE_TAPE:
  	case TYPE_DISK:
  	case TYPE_PRINTER:
  	case TYPE_MOD:
  	case TYPE_PROCESSOR:
  	case TYPE_SCANNER:
  	case TYPE_MEDIUM_CHANGER:
  	case TYPE_ENCLOSURE:
  	case TYPE_COMM:
4d7db04a7   James Bottomley   [SCSI] add SCSI_U...
785
  	case TYPE_RAID:
82443a58d   Boaz Harrosh   [SCSI] add OSD_TYPE
786
  	case TYPE_OSD:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
787
788
  		sdev->writeable = 1;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
789
  	case TYPE_ROM:
ddaf6fc85   James Bottomley   [SCSI] scsi_scan:...
790
  	case TYPE_WORM:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
791
792
793
794
795
796
  		sdev->writeable = 0;
  		break;
  	default:
  		printk(KERN_INFO "scsi: unknown device type %d
  ", sdev->type);
  	}
6d877688e   Matthew Wilcox   [SCSI] Clean up s...
797
798
799
800
801
802
803
804
  	if (sdev->type == TYPE_RBC || sdev->type == TYPE_ROM) {
  		/* RBC and MMC devices can return SCSI-3 compliance and yet
  		 * still not support REPORT LUNS, so make them act as
  		 * BLIST_NOREPORTLUN unless BLIST_REPORTLUN2 is
  		 * specifically set */
  		if ((*bflags & BLIST_REPORTLUN2) == 0)
  			*bflags |= BLIST_NOREPORTLUN;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
806
807
808
809
810
811
812
813
  	/*
  	 * For a peripheral qualifier (PQ) value of 1 (001b), the SCSI
  	 * spec says: The device server is capable of supporting the
  	 * specified peripheral device type on this logical unit. However,
  	 * the physical device is not currently connected to this logical
  	 * unit.
  	 *
  	 * The above is vague, as it implies that we could treat 001 and
  	 * 011 the same. Stay compatible with previous code, and create a
f64a181d8   Christoph Hellwig   [SCSI] remove Scs...
814
  	 * scsi_device for a PQ of 1
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815
816
817
818
819
820
821
  	 *
  	 * Don't set the device offline here; rather let the upper
  	 * level drivers eval the PQ to decide whether they should
  	 * attach. So remove ((inq_result[0] >> 5) & 7) == 1 check.
  	 */ 
  
  	sdev->inq_periph_qual = (inq_result[0] >> 5) & 7;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822
823
  	sdev->lockable = sdev->removable;
  	sdev->soft_reset = (inq_result[7] & 1) && ((inq_result[3] & 7) == 2);
6d877688e   Matthew Wilcox   [SCSI] Clean up s...
824
825
  	if (sdev->scsi_level >= SCSI_3 ||
  			(sdev->inquiry_len > 56 && inq_result[56] & 0x04))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
826
827
828
829
830
  		sdev->ppr = 1;
  	if (inq_result[7] & 0x60)
  		sdev->wdtr = 1;
  	if (inq_result[7] & 0x10)
  		sdev->sdtr = 1;
19ac0db3e   James Bottomley   [SCSI] fix up sho...
831
  	sdev_printk(KERN_NOTICE, sdev, "%s %.8s %.16s %.4s PQ: %d "
4ff36718e   Matthew Wilcox   [SCSI] Improve in...
832
833
834
835
836
  			"ANSI: %d%s
  ", scsi_device_type(sdev->type),
  			sdev->vendor, sdev->model, sdev->rev,
  			sdev->inq_periph_qual, inq_result[2] & 0x07,
  			(inq_result[3] & 0x0f) == 1 ? " CCS" : "");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
837
838
839
  	if ((sdev->scsi_level >= SCSI_2) && (inq_result[7] & 2) &&
  	    !(*bflags & BLIST_NOTQ))
  		sdev->tagged_supported = 1;
6d877688e   Matthew Wilcox   [SCSI] Clean up s...
840

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
841
842
843
844
845
846
847
  	/*
  	 * Some devices (Texel CD ROM drives) have handshaking problems
  	 * when used with the Seagate controllers. borken is initialized
  	 * to 1, and then set it to 0 here.
  	 */
  	if ((*bflags & BLIST_BORKEN) == 0)
  		sdev->borken = 0;
6d877688e   Matthew Wilcox   [SCSI] Clean up s...
848
849
  	if (*bflags & BLIST_NO_ULD_ATTACH)
  		sdev->no_uld_attach = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
850
851
852
853
854
855
856
857
  	/*
  	 * Apparently some really broken devices (contrary to the SCSI
  	 * standards) need to be selected without asserting ATN
  	 */
  	if (*bflags & BLIST_SELECT_NO_ATN)
  		sdev->select_no_atn = 1;
  
  	/*
4d7db04a7   James Bottomley   [SCSI] add SCSI_U...
858
859
860
861
  	 * Maximum 512 sector transfer length
  	 * broken RA4x00 Compaq Disk Array
  	 */
  	if (*bflags & BLIST_MAX_512)
086fa5ff0   Martin K. Petersen   block: Rename blk...
862
  		blk_queue_max_hw_sectors(sdev->request_queue, 512);
4d7db04a7   James Bottomley   [SCSI] add SCSI_U...
863
864
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
865
866
867
868
869
870
871
  	 * Some devices may not want to have a start command automatically
  	 * issued when a device is added.
  	 */
  	if (*bflags & BLIST_NOSTARTONADD)
  		sdev->no_start_on_add = 1;
  
  	if (*bflags & BLIST_SINGLELUN)
25d7c363f   Tony Battersby   [SCSI] move singl...
872
  		scsi_target(sdev)->single_lun = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
873

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
874
875
876
877
878
879
880
881
882
883
884
885
886
  	sdev->use_10_for_rw = 1;
  
  	if (*bflags & BLIST_MS_SKIP_PAGE_08)
  		sdev->skip_ms_page_8 = 1;
  
  	if (*bflags & BLIST_MS_SKIP_PAGE_3F)
  		sdev->skip_ms_page_3f = 1;
  
  	if (*bflags & BLIST_USE_10_BYTE_MS)
  		sdev->use_10_for_ms = 1;
  
  	/* set the device running here so that slave configure
  	 * may do I/O */
6f4267e3b   James Bottomley   [SCSI] Update the...
887
888
889
890
891
892
893
894
895
896
897
898
  	ret = scsi_device_set_state(sdev, SDEV_RUNNING);
  	if (ret) {
  		ret = scsi_device_set_state(sdev, SDEV_BLOCK);
  
  		if (ret) {
  			sdev_printk(KERN_ERR, sdev,
  				    "in wrong state %s to complete scan
  ",
  				    scsi_device_state_name(sdev->sdev_state));
  			return SCSI_SCAN_NO_RESPONSE;
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
899
900
901
902
903
904
905
906
907
908
909
  
  	if (*bflags & BLIST_MS_192_BYTES_FOR_3F)
  		sdev->use_192_bytes_for_3f = 1;
  
  	if (*bflags & BLIST_NOT_LOCKABLE)
  		sdev->lockable = 0;
  
  	if (*bflags & BLIST_RETRY_HWERROR)
  		sdev->retry_hwerror = 1;
  
  	transport_configure_device(&sdev->sdev_gendev);
938050916   Christoph Hellwig   [SCSI] scsi: hand...
910
  	if (sdev->host->hostt->slave_configure) {
6f4267e3b   James Bottomley   [SCSI] Update the...
911
  		ret = sdev->host->hostt->slave_configure(sdev);
938050916   Christoph Hellwig   [SCSI] scsi: hand...
912
913
914
915
916
917
918
919
920
921
922
923
924
  		if (ret) {
  			/*
  			 * if LLDD reports slave not present, don't clutter
  			 * console with alloc failure messages
  			 */
  			if (ret != -ENXIO) {
  				sdev_printk(KERN_ERR, sdev,
  					"failed to configure device
  ");
  			}
  			return SCSI_SCAN_NO_RESPONSE;
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
925

4a84067db   Vasu Dev   [SCSI] add queue_...
926
  	sdev->max_queue_depth = sdev->queue_depth;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
927
928
929
930
931
  	/*
  	 * Ok, the device is now all set up, we can
  	 * register it and tell the rest of the kernel
  	 * about it.
  	 */
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
932
  	if (!async && scsi_sysfs_add_sdev(sdev) != 0)
b24b10334   Alan Stern   [PATCH] scsi_scan...
933
  		return SCSI_SCAN_NO_RESPONSE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
934
935
936
  
  	return SCSI_SCAN_LUN_PRESENT;
  }
c5f2e6404   Andrew Morton   [SCSI] scsi_scan....
937
  #ifdef CONFIG_SCSI_LOGGING
6c7154c97   Kurt Garloff   [SCSI] Better log...
938
  /** 
eb44820c2   Rob Landley   [SCSI] Add Docume...
939
   * scsi_inq_str - print INQUIRY data from min to max index, strip trailing whitespace
6c7154c97   Kurt Garloff   [SCSI] Better log...
940
941
942
943
944
   * @buf:   Output buffer with at least end-first+1 bytes of space
   * @inq:   Inquiry buffer (input)
   * @first: Offset of string into inq
   * @end:   Index after last character in inq
   */
c5f2e6404   Andrew Morton   [SCSI] scsi_scan....
945
  static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
6c7154c97   Kurt Garloff   [SCSI] Better log...
946
947
948
  				   unsigned first, unsigned end)
  {
  	unsigned term = 0, idx;
c5f2e6404   Andrew Morton   [SCSI] scsi_scan....
949
950
951
  
  	for (idx = 0; idx + first < end && idx + first < inq[4] + 5; idx++) {
  		if (inq[idx+first] > ' ') {
6c7154c97   Kurt Garloff   [SCSI] Better log...
952
953
954
955
956
957
958
959
960
  			buf[idx] = inq[idx+first];
  			term = idx+1;
  		} else {
  			buf[idx] = ' ';
  		}
  	}
  	buf[term] = 0;
  	return buf;
  }
c5f2e6404   Andrew Morton   [SCSI] scsi_scan....
961
  #endif
6f3a20242   James Bottomley   [SCSI] allow REPO...
962

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
963
964
965
966
  /**
   * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
   * @starget:	pointer to target device structure
   * @lun:	LUN of target device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
967
   * @bflagsp:	store bflags here if not NULL
eb44820c2   Rob Landley   [SCSI] Add Docume...
968
969
970
   * @sdevp:	probe the LUN corresponding to this scsi_device
   * @rescan:     if nonzero skip some code only needed on first scan
   * @hostdata:	passed to scsi_alloc_sdev()
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
971
972
973
974
975
976
   *
   * Description:
   *     Call scsi_probe_lun, if a LUN with an attached device is found,
   *     allocate and set it up by calling scsi_add_lun.
   *
   * Return:
f64a181d8   Christoph Hellwig   [SCSI] remove Scs...
977
   *     SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
978
979
   *     SCSI_SCAN_TARGET_PRESENT: target responded, but no device is
   *         attached at the LUN
f64a181d8   Christoph Hellwig   [SCSI] remove Scs...
980
   *     SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
981
982
983
984
985
986
987
   **/
  static int scsi_probe_and_add_lun(struct scsi_target *starget,
  				  uint lun, int *bflagsp,
  				  struct scsi_device **sdevp, int rescan,
  				  void *hostdata)
  {
  	struct scsi_device *sdev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
988
  	unsigned char *result;
392160335   James Bottomley   [SCSI] use scatte...
989
  	int bflags, res = SCSI_SCAN_NO_RESPONSE, result_len = 256;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
990
991
992
993
994
995
  	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
  
  	/*
  	 * The rescan flag is used as an optimization, the first scan of a
  	 * host adapter calls into here with rescan == 0.
  	 */
6f3a20242   James Bottomley   [SCSI] allow REPO...
996
997
  	sdev = scsi_device_lookup_by_target(starget, lun);
  	if (sdev) {
0f1d87a2a   James Bottomley   [SCSI] add inline...
998
  		if (rescan || !scsi_device_created(sdev)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
999
1000
1001
  			SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
  				"scsi scan: device exists on %s
  ",
71610f55f   Kay Sievers   [SCSI] struct dev...
1002
  				dev_name(&sdev->sdev_gendev)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
  			if (sdevp)
  				*sdevp = sdev;
  			else
  				scsi_device_put(sdev);
  
  			if (bflagsp)
  				*bflagsp = scsi_get_device_flags(sdev,
  								 sdev->vendor,
  								 sdev->model);
  			return SCSI_SCAN_LUN_PRESENT;
  		}
6f3a20242   James Bottomley   [SCSI] allow REPO...
1014
1015
1016
  		scsi_device_put(sdev);
  	} else
  		sdev = scsi_alloc_sdev(starget, lun, hostdata);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1017
1018
  	if (!sdev)
  		goto out;
392160335   James Bottomley   [SCSI] use scatte...
1019
1020
  
  	result = kmalloc(result_len, GFP_ATOMIC |
bc86120a8   Al Viro   [PATCH] SCSI GFP ...
1021
  			((shost->unchecked_isa_dma) ? __GFP_DMA : 0));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1022
  	if (!result)
392160335   James Bottomley   [SCSI] use scatte...
1023
  		goto out_free_sdev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1024

392160335   James Bottomley   [SCSI] use scatte...
1025
  	if (scsi_probe_lun(sdev, result, result_len, &bflags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1026
  		goto out_free_result;
4186ab197   Kurt Garloff   [SCSI] Try LUN 1 ...
1027
1028
  	if (bflagsp)
  		*bflagsp = bflags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1029
1030
1031
  	/*
  	 * result contains valid SCSI INQUIRY data.
  	 */
13f7e5acc   Kurt Garloff   [SCSI] BLIST_ATTA...
1032
  	if (((result[0] >> 5) == 3) && !(bflags & BLIST_ATTACH_PQ3)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
  		/*
  		 * For a Peripheral qualifier 3 (011b), the SCSI
  		 * spec says: The device server is not capable of
  		 * supporting a physical device on this logical
  		 * unit.
  		 *
  		 * For disks, this implies that there is no
  		 * logical disk configured at sdev->lun, but there
  		 * is a target id responding.
  		 */
6c7154c97   Kurt Garloff   [SCSI] Better log...
1043
1044
1045
1046
1047
  		SCSI_LOG_SCAN_BUS(2, sdev_printk(KERN_INFO, sdev, "scsi scan:"
  				   " peripheral qualifier of 3, device not"
  				   " added
  "))
  		if (lun == 0) {
c5f2e6404   Andrew Morton   [SCSI] scsi_scan....
1048
1049
1050
1051
1052
  			SCSI_LOG_SCAN_BUS(1, {
  				unsigned char vend[9];
  				unsigned char mod[17];
  
  				sdev_printk(KERN_INFO, sdev,
6c7154c97   Kurt Garloff   [SCSI] Better log...
1053
  					"scsi scan: consider passing scsi_mod."
3424a65d7   Kurt Garloff   [SCSI] scsi_scan ...
1054
1055
  					"dev_flags=%s:%s:0x240 or 0x1000240
  ",
6c7154c97   Kurt Garloff   [SCSI] Better log...
1056
  					scsi_inq_str(vend, result, 8, 16),
c5f2e6404   Andrew Morton   [SCSI] scsi_scan....
1057
1058
  					scsi_inq_str(mod, result, 16, 32));
  			});
643eb2d93   James Bottomley   [SCSI] rework scs...
1059

6c7154c97   Kurt Garloff   [SCSI] Better log...
1060
  		}
643eb2d93   James Bottomley   [SCSI] rework scs...
1061

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1062
1063
1064
  		res = SCSI_SCAN_TARGET_PRESENT;
  		goto out_free_result;
  	}
1bfc5d9d5   Alan Stern   [SCSI] Recognize ...
1065
  	/*
84961f28e   dave wysochanski   [SCSI] Don't add ...
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
  	 * Some targets may set slight variations of PQ and PDT to signal
  	 * that no LUN is present, so don't add sdev in these cases.
  	 * Two specific examples are:
  	 * 1) NetApp targets: return PQ=1, PDT=0x1f
  	 * 2) USB UFI: returns PDT=0x1f, with the PQ bits being "reserved"
  	 *    in the UFI 1.0 spec (we cannot rely on reserved bits).
  	 *
  	 * References:
  	 * 1) SCSI SPC-3, pp. 145-146
  	 * PQ=1: "A peripheral device having the specified peripheral
  	 * device type is not connected to this logical unit. However, the
  	 * device server is capable of supporting the specified peripheral
  	 * device type on this logical unit."
  	 * PDT=0x1f: "Unknown or no device type"
  	 * 2) USB UFI 1.0, p. 20
  	 * PDT=00h Direct-access device (floppy)
  	 * PDT=1Fh none (no FDD connected to the requested logical unit)
1bfc5d9d5   Alan Stern   [SCSI] Recognize ...
1083
  	 */
84961f28e   dave wysochanski   [SCSI] Don't add ...
1084
  	if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) &&
01b291bd6   James Bottomley   [SCSI] fix check ...
1085
1086
  	    (result[0] & 0x1f) == 0x1f &&
  	    !scsi_is_wlun(lun)) {
1bfc5d9d5   Alan Stern   [SCSI] Recognize ...
1087
1088
1089
1090
1091
1092
1093
  		SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
  					"scsi scan: peripheral device type"
  					" of 31, no device added
  "));
  		res = SCSI_SCAN_TARGET_PRESENT;
  		goto out_free_result;
  	}
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1094
  	res = scsi_add_lun(sdev, result, &bflags, shost->async_scan);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1095
1096
1097
  	if (res == SCSI_SCAN_LUN_PRESENT) {
  		if (bflags & BLIST_KEY) {
  			sdev->lockable = 0;
392160335   James Bottomley   [SCSI] use scatte...
1098
  			scsi_unlock_floptical(sdev, result);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1099
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1100
1101
1102
1103
  	}
  
   out_free_result:
  	kfree(result);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1104
1105
1106
   out_free_sdev:
  	if (res == SCSI_SCAN_LUN_PRESENT) {
  		if (sdevp) {
b70d37bf6   Alan Stern   [SCSI] Fix module...
1107
1108
1109
1110
1111
1112
  			if (scsi_device_get(sdev) == 0) {
  				*sdevp = sdev;
  			} else {
  				__scsi_remove_device(sdev);
  				res = SCSI_SCAN_NO_RESPONSE;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1113
  		}
6f3a20242   James Bottomley   [SCSI] allow REPO...
1114
  	} else
860dc7360   James Bottomley   [SCSI] fix async ...
1115
  		__scsi_remove_device(sdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1116
1117
1118
1119
1120
1121
1122
1123
   out:
  	return res;
  }
  
  /**
   * scsi_sequential_lun_scan - sequentially scan a SCSI target
   * @starget:	pointer to target structure to scan
   * @bflags:	black/white list flag for LUN 0
eb44820c2   Rob Landley   [SCSI] Add Docume...
1124
1125
   * @scsi_level: Which version of the standard does this device adhere to
   * @rescan:     passed to scsi_probe_add_lun()
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1126
1127
1128
1129
1130
1131
1132
1133
1134
   *
   * Description:
   *     Generally, scan from LUN 1 (LUN 0 is assumed to already have been
   *     scanned) to some maximum lun until a LUN is found with no device
   *     attached. Use the bflags to figure out any oddities.
   *
   *     Modifies sdevscan->lun.
   **/
  static void scsi_sequential_lun_scan(struct scsi_target *starget,
4186ab197   Kurt Garloff   [SCSI] Try LUN 1 ...
1135
  				     int bflags, int scsi_level, int rescan)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1136
1137
1138
1139
1140
  {
  	unsigned int sparse_lun, lun, max_dev_lun;
  	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
  
  	SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: Sequential scan of"
71610f55f   Kay Sievers   [SCSI] struct dev...
1141
1142
  				    "%s
  ", dev_name(&starget->dev)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
  
  	max_dev_lun = min(max_scsi_luns, shost->max_lun);
  	/*
  	 * If this device is known to support sparse multiple units,
  	 * override the other settings, and scan all of them. Normally,
  	 * SCSI-3 devices should be scanned via the REPORT LUNS.
  	 */
  	if (bflags & BLIST_SPARSELUN) {
  		max_dev_lun = shost->max_lun;
  		sparse_lun = 1;
  	} else
  		sparse_lun = 0;
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
  	 * If less than SCSI_1_CSS, and no special lun scaning, stop
  	 * scanning; this matches 2.4 behaviour, but could just be a bug
  	 * (to continue scanning a SCSI_1_CSS device).
  	 *
  	 * This test is broken.  We might not have any device on lun0 for
  	 * a sparselun device, and if that's the case then how would we
  	 * know the real scsi_level, eh?  It might make sense to just not
  	 * scan any SCSI_1 device for non-0 luns, but that check would best
  	 * go into scsi_alloc_sdev() and just have it return null when asked
  	 * to alloc an sdev for lun > 0 on an already found SCSI_1 device.
  	 *
  	if ((sdevscan->scsi_level < SCSI_1_CCS) &&
  	    ((bflags & (BLIST_FORCELUN | BLIST_SPARSELUN | BLIST_MAX5LUN))
  	     == 0))
  		return;
  	 */
  	/*
  	 * If this device is known to support multiple units, override
  	 * the other settings, and scan all of them.
  	 */
  	if (bflags & BLIST_FORCELUN)
  		max_dev_lun = shost->max_lun;
  	/*
  	 * REGAL CDC-4X: avoid hang after LUN 4
  	 */
  	if (bflags & BLIST_MAX5LUN)
  		max_dev_lun = min(5U, max_dev_lun);
  	/*
  	 * Do not scan SCSI-2 or lower device past LUN 7, unless
  	 * BLIST_LARGELUN.
  	 */
  	if (scsi_level < SCSI_3 && !(bflags & BLIST_LARGELUN))
  		max_dev_lun = min(8U, max_dev_lun);
  
  	/*
  	 * We have already scanned LUN 0, so start at LUN 1. Keep scanning
  	 * until we reach the max, or no LUN is found and we are not
  	 * sparse_lun.
  	 */
  	for (lun = 1; lun < max_dev_lun; ++lun)
  		if ((scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan,
  					    NULL) != SCSI_SCAN_LUN_PRESENT) &&
  		    !sparse_lun)
  			return;
  }
  
  /**
9f6aa5750   Randy Dunlap   scsi_scan.c: fix/...
1204
   * scsilun_to_int - convert a scsi_lun to an int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
   * @scsilun:	struct scsi_lun to be converted.
   *
   * Description:
   *     Convert @scsilun from a struct scsi_lun to a four byte host byte-ordered
   *     integer, and return the result. The caller must check for
   *     truncation before using this function.
   *
   * Notes:
   *     The struct scsi_lun is assumed to be four levels, with each level
   *     effectively containing a SCSI byte-ordered (big endian) short; the
   *     addressing bits of each level are ignored (the highest two bits).
   *     For a description of the LUN format, post SCSI-3 see the SCSI
   *     Architecture Model, for SCSI-3 see the SCSI Controller Commands.
   *
   *     Given a struct scsi_lun of: 0a 04 0b 03 00 00 00 00, this function returns
   *     the integer: 0x0b030a04
   **/
462b7859a   Christof Schmitt   [SCSI] zfcp: Repo...
1222
  int scsilun_to_int(struct scsi_lun *scsilun)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
  {
  	int i;
  	unsigned int lun;
  
  	lun = 0;
  	for (i = 0; i < sizeof(lun); i += 2)
  		lun = lun | (((scsilun->scsi_lun[i] << 8) |
  			      scsilun->scsi_lun[i + 1]) << (i * 8));
  	return lun;
  }
462b7859a   Christof Schmitt   [SCSI] zfcp: Repo...
1233
  EXPORT_SYMBOL(scsilun_to_int);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1234
1235
  
  /**
9f6aa5750   Randy Dunlap   scsi_scan.c: fix/...
1236
   * int_to_scsilun - reverts an int into a scsi_lun
eb44820c2   Rob Landley   [SCSI] Add Docume...
1237
   * @lun:        integer to be reverted
2f4701d82   James.Smart@Emulex.Com   [SCSI] add int_to...
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
   * @scsilun:	struct scsi_lun to be set.
   *
   * Description:
   *     Reverts the functionality of the scsilun_to_int, which packed
   *     an 8-byte lun value into an int. This routine unpacks the int
   *     back into the lun value.
   *     Note: the scsilun_to_int() routine does not truly handle all
   *     8bytes of the lun value. This functions restores only as much
   *     as was set by the routine.
   *
   * Notes:
   *     Given an integer : 0x0b030a04,  this function returns a
   *     scsi_lun of : struct scsi_lun of: 0a 04 0b 03 00 00 00 00
   *
   **/
  void int_to_scsilun(unsigned int lun, struct scsi_lun *scsilun)
  {
  	int i;
  
  	memset(scsilun->scsi_lun, 0, sizeof(scsilun->scsi_lun));
  
  	for (i = 0; i < sizeof(lun); i += 2) {
  		scsilun->scsi_lun[i] = (lun >> 8) & 0xFF;
  		scsilun->scsi_lun[i+1] = lun & 0xFF;
  		lun = lun >> 16;
  	}
  }
  EXPORT_SYMBOL(int_to_scsilun);
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1268
   * scsi_report_lun_scan - Scan using SCSI REPORT LUN results
eb44820c2   Rob Landley   [SCSI] Add Docume...
1269
1270
1271
   * @starget: which target
   * @bflags: Zero or a mix of BLIST_NOLUN, BLIST_REPORTLUN2, or BLIST_NOREPORTLUN
   * @rescan: nonzero if we can skip code only needed on first scan
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1272
1273
   *
   * Description:
eb44820c2   Rob Landley   [SCSI] Add Docume...
1274
1275
   *   Fast scanning for modern (SCSI-3) devices by sending a REPORT LUN command.
   *   Scan the resulting list of LUNs by calling scsi_probe_and_add_lun.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1276
   *
eb44820c2   Rob Landley   [SCSI] Add Docume...
1277
1278
1279
1280
   *   If BLINK_REPORTLUN2 is set, scan a target that supports more than 8
   *   LUNs even if it's older than SCSI-3.
   *   If BLIST_NOREPORTLUN is set, return 1 always.
   *   If BLIST_NOLUN is set, return 0 always.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1281
1282
1283
   *
   * Return:
   *     0: scan completed (or no memory, so further scanning is futile)
eb44820c2   Rob Landley   [SCSI] Add Docume...
1284
   *     1: could not scan with REPORT LUN
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1285
   **/
6f3a20242   James Bottomley   [SCSI] allow REPO...
1286
  static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1287
1288
1289
1290
1291
1292
1293
1294
  				int rescan)
  {
  	char devname[64];
  	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
  	unsigned int length;
  	unsigned int lun;
  	unsigned int num_luns;
  	unsigned int retries;
392160335   James Bottomley   [SCSI] use scatte...
1295
  	int result;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1296
  	struct scsi_lun *lunp, *lun_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1297
1298
  	u8 *data;
  	struct scsi_sense_hdr sshdr;
6f3a20242   James Bottomley   [SCSI] allow REPO...
1299
1300
  	struct scsi_device *sdev;
  	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
2ef891983   Alan Stern   [SCSI] Fix refcou...
1301
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1302
1303
1304
1305
1306
1307
  
  	/*
  	 * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set.
  	 * Also allow SCSI-2 if BLIST_REPORTLUN2 is set and host adapter does
  	 * support more than 8 LUNs.
  	 */
4d7db04a7   James Bottomley   [SCSI] add SCSI_U...
1308
1309
1310
1311
1312
1313
1314
  	if (bflags & BLIST_NOREPORTLUN)
  		return 1;
  	if (starget->scsi_level < SCSI_2 &&
  	    starget->scsi_level != SCSI_UNKNOWN)
  		return 1;
  	if (starget->scsi_level < SCSI_3 &&
  	    (!(bflags & BLIST_REPORTLUN2) || shost->max_lun <= 8))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1315
1316
1317
  		return 1;
  	if (bflags & BLIST_NOLUN)
  		return 0;
6f3a20242   James Bottomley   [SCSI] allow REPO...
1318
1319
1320
1321
  	if (!(sdev = scsi_device_lookup_by_target(starget, 0))) {
  		sdev = scsi_alloc_sdev(starget, 0, NULL);
  		if (!sdev)
  			return 0;
75f8ee8e0   Alan Stern   [SCSI] fix memory...
1322
1323
  		if (scsi_device_get(sdev)) {
  			__scsi_remove_device(sdev);
6f3a20242   James Bottomley   [SCSI] allow REPO...
1324
  			return 0;
75f8ee8e0   Alan Stern   [SCSI] fix memory...
1325
  		}
6f3a20242   James Bottomley   [SCSI] allow REPO...
1326
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1327
  	sprintf(devname, "host %d channel %d id %d",
6f3a20242   James Bottomley   [SCSI] allow REPO...
1328
  		shost->host_no, sdev->channel, sdev->id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
  
  	/*
  	 * Allocate enough to hold the header (the same size as one scsi_lun)
  	 * plus the max number of luns we are requesting.
  	 *
  	 * Reallocating and trying again (with the exact amount we need)
  	 * would be nice, but then we need to somehow limit the size
  	 * allocated based on the available memory and the limits of
  	 * kmalloc - we don't want a kmalloc() failure of a huge value to
  	 * prevent us from finding any LUNs on this target.
  	 */
  	length = (max_scsi_report_luns + 1) * sizeof(struct scsi_lun);
  	lun_data = kmalloc(length, GFP_ATOMIC |
  			   (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0));
6f3a20242   James Bottomley   [SCSI] allow REPO...
1343
  	if (!lun_data) {
cadbd4a5e   Harvey Harrison   [SCSI] replace __...
1344
  		printk(ALLOC_FAILURE_MSG, __func__);
392160335   James Bottomley   [SCSI] use scatte...
1345
  		goto out;
6f3a20242   James Bottomley   [SCSI] allow REPO...
1346
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
  
  	scsi_cmd[0] = REPORT_LUNS;
  
  	/*
  	 * bytes 1 - 5: reserved, set to zero.
  	 */
  	memset(&scsi_cmd[1], 0, 5);
  
  	/*
  	 * bytes 6 - 9: length of the command.
  	 */
  	scsi_cmd[6] = (unsigned char) (length >> 24) & 0xff;
  	scsi_cmd[7] = (unsigned char) (length >> 16) & 0xff;
  	scsi_cmd[8] = (unsigned char) (length >> 8) & 0xff;
  	scsi_cmd[9] = (unsigned char) length & 0xff;
  
  	scsi_cmd[10] = 0;	/* reserved */
  	scsi_cmd[11] = 0;	/* control */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
  
  	/*
  	 * We can get a UNIT ATTENTION, for example a power on/reset, so
  	 * retry a few times (like sd.c does for TEST UNIT READY).
  	 * Experience shows some combinations of adapter/devices get at
  	 * least two power on/resets.
  	 *
  	 * Illegal requests (for devices that do not support REPORT LUNS)
  	 * should come through as a check condition, and will not generate
  	 * a retry.
  	 */
  	for (retries = 0; retries < 3; retries++) {
  		SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: Sending"
  				" REPORT LUNS to %s (try %d)
  ", devname,
  				retries));
392160335   James Bottomley   [SCSI] use scatte...
1381

392160335   James Bottomley   [SCSI] use scatte...
1382
  		result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
ea73a9f23   James Bottomley   [SCSI] convert sd...
1383
  					  lun_data, length, &sshdr,
f4f4e47e4   FUJITA Tomonori   [SCSI] add residu...
1384
  					  SCSI_TIMEOUT + 4 * HZ, 3, NULL);
392160335   James Bottomley   [SCSI] use scatte...
1385

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1386
  		SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUNS"
392160335   James Bottomley   [SCSI] use scatte...
1387
1388
1389
1390
  				" %s (try %d) result 0x%x
  ", result
  				?  "failed" : "successful", retries, result));
  		if (result == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1391
  			break;
ea73a9f23   James Bottomley   [SCSI] convert sd...
1392
  		else if (scsi_sense_valid(&sshdr)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1393
1394
1395
1396
  			if (sshdr.sense_key != UNIT_ATTENTION)
  				break;
  		}
  	}
392160335   James Bottomley   [SCSI] use scatte...
1397
  	if (result) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1398
1399
1400
  		/*
  		 * The device probably does not support a REPORT LUN command
  		 */
2ef891983   Alan Stern   [SCSI] Fix refcou...
1401
1402
  		ret = 1;
  		goto out_err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1403
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
  
  	/*
  	 * Get the length from the first four bytes of lun_data.
  	 */
  	data = (u8 *) lun_data->scsi_lun;
  	length = ((data[0] << 24) | (data[1] << 16) |
  		  (data[2] << 8) | (data[3] << 0));
  
  	num_luns = (length / sizeof(struct scsi_lun));
  	if (num_luns > max_scsi_report_luns) {
  		printk(KERN_WARNING "scsi: On %s only %d (max_scsi_report_luns)"
  		       " of %d luns reported, try increasing"
  		       " max_scsi_report_luns.
  ", devname,
  		       max_scsi_report_luns, num_luns);
  		num_luns = max_scsi_report_luns;
  	}
3bf743e7c   Jeff Garzik   [SCSI] use {sdev,...
1421
1422
1423
  	SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
  		"scsi scan: REPORT LUN scan
  "));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
  
  	/*
  	 * Scan the luns in lun_data. The entry at offset 0 is really
  	 * the header, so start at 1 and go up to and including num_luns.
  	 */
  	for (lunp = &lun_data[1]; lunp <= &lun_data[num_luns]; lunp++) {
  		lun = scsilun_to_int(lunp);
  
  		/*
  		 * Check if the unused part of lunp is non-zero, and so
  		 * does not fit in lun.
  		 */
  		if (memcmp(&lunp->scsi_lun[sizeof(lun)], "\0\0\0\0", 4)) {
  			int i;
  
  			/*
  			 * Output an error displaying the LUN in byte order,
  			 * this differs from what linux would print for the
  			 * integer LUN value.
  			 */
  			printk(KERN_WARNING "scsi: %s lun 0x", devname);
  			data = (char *)lunp->scsi_lun;
  			for (i = 0; i < sizeof(struct scsi_lun); i++)
  				printk("%02x", data[i]);
  			printk(" has a LUN larger than currently supported.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
  		} else if (lun > sdev->host->max_lun) {
  			printk(KERN_WARNING "scsi: %s lun%d has a LUN larger"
  			       " than allowed by the host adapter
  ",
  			       devname, lun);
  		} else {
  			int res;
  
  			res = scsi_probe_and_add_lun(starget,
  				lun, NULL, NULL, rescan, NULL);
  			if (res == SCSI_SCAN_NO_RESPONSE) {
  				/*
  				 * Got some results, but now none, abort.
  				 */
3bf743e7c   Jeff Garzik   [SCSI] use {sdev,...
1464
1465
1466
1467
1468
  				sdev_printk(KERN_ERR, sdev,
  					"Unexpected response"
  				        " from lun %d while scanning, scan"
  				        " aborted
  ", lun);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1469
1470
1471
1472
  				break;
  			}
  		}
  	}
2ef891983   Alan Stern   [SCSI] Fix refcou...
1473
   out_err:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1474
  	kfree(lun_data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1475
   out:
6f3a20242   James Bottomley   [SCSI] allow REPO...
1476
  	scsi_device_put(sdev);
0f1d87a2a   James Bottomley   [SCSI] add inline...
1477
  	if (scsi_device_created(sdev))
6f3a20242   James Bottomley   [SCSI] allow REPO...
1478
1479
1480
  		/*
  		 * the sdev we used didn't appear in the report luns scan
  		 */
860dc7360   James Bottomley   [SCSI] fix async ...
1481
  		__scsi_remove_device(sdev);
2ef891983   Alan Stern   [SCSI] Fix refcou...
1482
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1483
1484
1485
1486
1487
  }
  
  struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
  				      uint id, uint lun, void *hostdata)
  {
a97a83a06   Matthew Wilcox   [SCSI] fix uninit...
1488
  	struct scsi_device *sdev = ERR_PTR(-ENODEV);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1489
  	struct device *parent = &shost->shost_gendev;
e02f3f592   Christoph Hellwig   [SCSI] remove tar...
1490
  	struct scsi_target *starget;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1491

938e2ac0b   Matthew Wilcox   [SCSI] Fix scsi_a...
1492
1493
  	if (strncmp(scsi_scan_type, "none", 4) == 0)
  		return ERR_PTR(-ENODEV);
e02f3f592   Christoph Hellwig   [SCSI] remove tar...
1494
  	starget = scsi_alloc_target(parent, channel, id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1495
1496
  	if (!starget)
  		return ERR_PTR(-ENOMEM);
bc4f24014   Alan Stern   [SCSI] implement ...
1497
  	scsi_autopm_get_target(starget);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1498

0b9506723   Arjan van de Ven   [SCSI] turn most ...
1499
  	mutex_lock(&shost->scan_mutex);
6b7f123f3   Matthew Wilcox   [SCSI] Fix async ...
1500
1501
  	if (!shost->async_scan)
  		scsi_complete_async_scans();
bc4f24014   Alan Stern   [SCSI] implement ...
1502
  	if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
a97a83a06   Matthew Wilcox   [SCSI] fix uninit...
1503
  		scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
bc4f24014   Alan Stern   [SCSI] implement ...
1504
1505
  		scsi_autopm_put_host(shost);
  	}
0b9506723   Arjan van de Ven   [SCSI] turn most ...
1506
  	mutex_unlock(&shost->scan_mutex);
bc4f24014   Alan Stern   [SCSI] implement ...
1507
  	scsi_autopm_put_target(starget);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1508
1509
1510
1511
1512
1513
  	scsi_target_reap(starget);
  	put_device(&starget->dev);
  
  	return sdev;
  }
  EXPORT_SYMBOL(__scsi_add_device);
146f7262e   James Bottomley   [SCSI] Alter the ...
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
  int scsi_add_device(struct Scsi_Host *host, uint channel,
  		    uint target, uint lun)
  {
  	struct scsi_device *sdev = 
  		__scsi_add_device(host, channel, target, lun, NULL);
  	if (IS_ERR(sdev))
  		return PTR_ERR(sdev);
  
  	scsi_device_put(sdev);
  	return 0;
  }
  EXPORT_SYMBOL(scsi_add_device);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
  void scsi_rescan_device(struct device *dev)
  {
  	struct scsi_driver *drv;
  	
  	if (!dev->driver)
  		return;
  
  	drv = to_scsi_driver(dev->driver);
  	if (try_module_get(drv->owner)) {
  		if (drv->rescan)
  			drv->rescan(dev);
  		module_put(drv->owner);
  	}
  }
  EXPORT_SYMBOL(scsi_rescan_device);
e517d3133   Alan Stern   [SCSI] add missin...
1541
1542
  static void __scsi_scan_target(struct device *parent, unsigned int channel,
  		unsigned int id, unsigned int lun, int rescan)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1543
1544
1545
1546
  {
  	struct Scsi_Host *shost = dev_to_shost(parent);
  	int bflags = 0;
  	int res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1547
1548
1549
1550
1551
1552
1553
  	struct scsi_target *starget;
  
  	if (shost->this_id == id)
  		/*
  		 * Don't scan the host adapter
  		 */
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1554
  	starget = scsi_alloc_target(parent, channel, id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1555
1556
  	if (!starget)
  		return;
bc4f24014   Alan Stern   [SCSI] implement ...
1557
  	scsi_autopm_get_target(starget);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1558

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
  	if (lun != SCAN_WILD_CARD) {
  		/*
  		 * Scan for a specific host/chan/id/lun.
  		 */
  		scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan, NULL);
  		goto out_reap;
  	}
  
  	/*
  	 * Scan LUN 0, if there is some response, scan further. Ideally, we
  	 * would not configure LUN 0 until all LUNs are scanned.
  	 */
6f3a20242   James Bottomley   [SCSI] allow REPO...
1571
1572
1573
  	res = scsi_probe_and_add_lun(starget, 0, &bflags, NULL, rescan, NULL);
  	if (res == SCSI_SCAN_LUN_PRESENT || res == SCSI_SCAN_TARGET_PRESENT) {
  		if (scsi_report_lun_scan(starget, bflags, rescan) != 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1574
1575
1576
1577
1578
  			/*
  			 * The REPORT LUN did not scan the target,
  			 * do a sequential scan.
  			 */
  			scsi_sequential_lun_scan(starget, bflags,
4186ab197   Kurt Garloff   [SCSI] Try LUN 1 ...
1579
  						 starget->scsi_level, rescan);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1580
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1581
1582
  
   out_reap:
bc4f24014   Alan Stern   [SCSI] implement ...
1583
  	scsi_autopm_put_target(starget);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1584
1585
1586
1587
1588
1589
  	/* now determine if the target has any children at all
  	 * and if not, nuke it */
  	scsi_target_reap(starget);
  
  	put_device(&starget->dev);
  }
e517d3133   Alan Stern   [SCSI] add missin...
1590
1591
  
  /**
e59e4a097   Randy Dunlap   docbook: fix scsi...
1592
   * scsi_scan_target - scan a target id, possibly including all LUNs on the target.
e517d3133   Alan Stern   [SCSI] add missin...
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
   * @parent:	host to scan
   * @channel:	channel to scan
   * @id:		target id to scan
   * @lun:	Specific LUN to scan or SCAN_WILD_CARD
   * @rescan:	passed to LUN scanning routines
   *
   * Description:
   *     Scan the target id on @parent, @channel, and @id. Scan at least LUN 0,
   *     and possibly all LUNs on the target id.
   *
   *     First try a REPORT LUN scan, if that does not scan the target, do a
   *     sequential scan of LUNs on the target id.
   **/
  void scsi_scan_target(struct device *parent, unsigned int channel,
  		      unsigned int id, unsigned int lun, int rescan)
  {
  	struct Scsi_Host *shost = dev_to_shost(parent);
93b45af5c   Matthew Wilcox   [SCSI] fix missin...
1610
1611
  	if (strncmp(scsi_scan_type, "none", 4) == 0)
  		return;
6b7f123f3   Matthew Wilcox   [SCSI] Fix async ...
1612
  	mutex_lock(&shost->scan_mutex);
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1613
1614
  	if (!shost->async_scan)
  		scsi_complete_async_scans();
bc4f24014   Alan Stern   [SCSI] implement ...
1615
  	if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
e517d3133   Alan Stern   [SCSI] add missin...
1616
  		__scsi_scan_target(parent, channel, id, lun, rescan);
bc4f24014   Alan Stern   [SCSI] implement ...
1617
1618
  		scsi_autopm_put_host(shost);
  	}
0b9506723   Arjan van de Ven   [SCSI] turn most ...
1619
  	mutex_unlock(&shost->scan_mutex);
e517d3133   Alan Stern   [SCSI] add missin...
1620
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
  EXPORT_SYMBOL(scsi_scan_target);
  
  static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
  			      unsigned int id, unsigned int lun, int rescan)
  {
  	uint order_id;
  
  	if (id == SCAN_WILD_CARD)
  		for (id = 0; id < shost->max_id; ++id) {
  			/*
  			 * XXX adapter drivers when possible (FCP, iSCSI)
  			 * could modify max_id to match the current max,
  			 * not the absolute max.
  			 *
  			 * XXX add a shost id iterator, so for example,
  			 * the FC ID can be the same as a target id
  			 * without a huge overhead of sparse id's.
  			 */
  			if (shost->reverse_ordering)
  				/*
  				 * Scan from high to low id.
  				 */
  				order_id = shost->max_id - id - 1;
  			else
  				order_id = id;
e517d3133   Alan Stern   [SCSI] add missin...
1646
1647
  			__scsi_scan_target(&shost->shost_gendev, channel,
  					order_id, lun, rescan);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1648
1649
  		}
  	else
e517d3133   Alan Stern   [SCSI] add missin...
1650
1651
  		__scsi_scan_target(&shost->shost_gendev, channel,
  				id, lun, rescan);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1652
1653
1654
1655
1656
  }
  
  int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
  			    unsigned int id, unsigned int lun, int rescan)
  {
3bf743e7c   Jeff Garzik   [SCSI] use {sdev,...
1657
1658
1659
  	SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost,
  		"%s: <%u:%u:%u>
  ",
cadbd4a5e   Harvey Harrison   [SCSI] replace __...
1660
  		__func__, channel, id, lun));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1661
1662
  
  	if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
091686d3b   Amit Arora   [SCSI] Return -EI...
1663
  	    ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1664
1665
  	    ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
  		return -EINVAL;
0b9506723   Arjan van de Ven   [SCSI] turn most ...
1666
  	mutex_lock(&shost->scan_mutex);
6b7f123f3   Matthew Wilcox   [SCSI] Fix async ...
1667
1668
  	if (!shost->async_scan)
  		scsi_complete_async_scans();
bc4f24014   Alan Stern   [SCSI] implement ...
1669
  	if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
82f29467a   Mike Anderson   [SCSI] host state...
1670
1671
1672
1673
1674
1675
  		if (channel == SCAN_WILD_CARD)
  			for (channel = 0; channel <= shost->max_channel;
  			     channel++)
  				scsi_scan_channel(shost, channel, id, lun,
  						  rescan);
  		else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1676
  			scsi_scan_channel(shost, channel, id, lun, rescan);
bc4f24014   Alan Stern   [SCSI] implement ...
1677
  		scsi_autopm_put_host(shost);
82f29467a   Mike Anderson   [SCSI] host state...
1678
  	}
0b9506723   Arjan van de Ven   [SCSI] turn most ...
1679
  	mutex_unlock(&shost->scan_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1680
1681
1682
  
  	return 0;
  }
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1683
1684
1685
1686
  static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
  {
  	struct scsi_device *sdev;
  	shost_for_each_device(sdev, shost) {
6b7f123f3   Matthew Wilcox   [SCSI] Fix async ...
1687
1688
  		if (!scsi_host_scan_allowed(shost) ||
  		    scsi_sysfs_add_sdev(sdev) != 0)
860dc7360   James Bottomley   [SCSI] fix async ...
1689
  			__scsi_remove_device(sdev);
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
  	}
  }
  
  /**
   * scsi_prep_async_scan - prepare for an async scan
   * @shost: the host which will be scanned
   * Returns: a cookie to be passed to scsi_finish_async_scan()
   *
   * Tells the midlayer this host is going to do an asynchronous scan.
   * It reserves the host's position in the scanning list and ensures
   * that other asynchronous scans started after this one won't affect the
   * ordering of the discovered devices.
   */
1aa8fab2a   Matthew Wilcox   [SCSI] Make scsi_...
1703
  static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1704
1705
  {
  	struct async_scan_data *data;
6b7f123f3   Matthew Wilcox   [SCSI] Fix async ...
1706
  	unsigned long flags;
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1707
1708
1709
1710
1711
  
  	if (strncmp(scsi_scan_type, "sync", 4) == 0)
  		return NULL;
  
  	if (shost->async_scan) {
cadbd4a5e   Harvey Harrison   [SCSI] replace __...
1712
  		printk("%s called twice for host %d", __func__,
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
  				shost->host_no);
  		dump_stack();
  		return NULL;
  	}
  
  	data = kmalloc(sizeof(*data), GFP_KERNEL);
  	if (!data)
  		goto err;
  	data->shost = scsi_host_get(shost);
  	if (!data->shost)
  		goto err;
  	init_completion(&data->prev_finished);
6b7f123f3   Matthew Wilcox   [SCSI] Fix async ...
1725
1726
  	mutex_lock(&shost->scan_mutex);
  	spin_lock_irqsave(shost->host_lock, flags);
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1727
  	shost->async_scan = 1;
6b7f123f3   Matthew Wilcox   [SCSI] Fix async ...
1728
1729
1730
1731
  	spin_unlock_irqrestore(shost->host_lock, flags);
  	mutex_unlock(&shost->scan_mutex);
  
  	spin_lock(&async_scan_lock);
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
  	if (list_empty(&scanning_hosts))
  		complete(&data->prev_finished);
  	list_add_tail(&data->list, &scanning_hosts);
  	spin_unlock(&async_scan_lock);
  
  	return data;
  
   err:
  	kfree(data);
  	return NULL;
  }
  
  /**
   * scsi_finish_async_scan - asynchronous scan has finished
   * @data: cookie returned from earlier call to scsi_prep_async_scan()
   *
   * All the devices currently attached to this host have been found.
   * This function announces all the devices it has found to the rest
   * of the system.
   */
1aa8fab2a   Matthew Wilcox   [SCSI] Make scsi_...
1752
  static void scsi_finish_async_scan(struct async_scan_data *data)
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1753
1754
  {
  	struct Scsi_Host *shost;
6b7f123f3   Matthew Wilcox   [SCSI] Fix async ...
1755
  	unsigned long flags;
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1756
1757
1758
1759
1760
  
  	if (!data)
  		return;
  
  	shost = data->shost;
6b7f123f3   Matthew Wilcox   [SCSI] Fix async ...
1761
1762
  
  	mutex_lock(&shost->scan_mutex);
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1763
  	if (!shost->async_scan) {
cadbd4a5e   Harvey Harrison   [SCSI] replace __...
1764
  		printk("%s called twice for host %d", __func__,
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1765
1766
  				shost->host_no);
  		dump_stack();
773e82f6c   Julia Lawall   [SCSI] scsi_scan....
1767
  		mutex_unlock(&shost->scan_mutex);
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1768
1769
1770
1771
1772
1773
  		return;
  	}
  
  	wait_for_completion(&data->prev_finished);
  
  	scsi_sysfs_add_devices(shost);
6b7f123f3   Matthew Wilcox   [SCSI] Fix async ...
1774
  	spin_lock_irqsave(shost->host_lock, flags);
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1775
  	shost->async_scan = 0;
6b7f123f3   Matthew Wilcox   [SCSI] Fix async ...
1776
1777
1778
1779
1780
  	spin_unlock_irqrestore(shost->host_lock, flags);
  
  	mutex_unlock(&shost->scan_mutex);
  
  	spin_lock(&async_scan_lock);
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
  	list_del(&data->list);
  	if (!list_empty(&scanning_hosts)) {
  		struct async_scan_data *next = list_entry(scanning_hosts.next,
  				struct async_scan_data, list);
  		complete(&next->prev_finished);
  	}
  	spin_unlock(&async_scan_lock);
  
  	scsi_host_put(shost);
  	kfree(data);
  }
1aa8fab2a   Matthew Wilcox   [SCSI] Make scsi_...
1792
  static void do_scsi_scan_host(struct Scsi_Host *shost)
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1793
  {
1aa8fab2a   Matthew Wilcox   [SCSI] Make scsi_...
1794
1795
1796
1797
1798
1799
1800
1801
1802
  	if (shost->hostt->scan_finished) {
  		unsigned long start = jiffies;
  		if (shost->hostt->scan_start)
  			shost->hostt->scan_start(shost);
  
  		while (!shost->hostt->scan_finished(shost, jiffies - start))
  			msleep(10);
  	} else {
  		scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1803
  				SCAN_WILD_CARD, 0);
1aa8fab2a   Matthew Wilcox   [SCSI] Make scsi_...
1804
1805
  	}
  }
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1806

1aa8fab2a   Matthew Wilcox   [SCSI] Make scsi_...
1807
1808
1809
  static int do_scan_async(void *_data)
  {
  	struct async_scan_data *data = _data;
bc4f24014   Alan Stern   [SCSI] implement ...
1810
1811
1812
  	struct Scsi_Host *shost = data->shost;
  
  	do_scsi_scan_host(shost);
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1813
  	scsi_finish_async_scan(data);
bc4f24014   Alan Stern   [SCSI] implement ...
1814
  	scsi_autopm_put_host(shost);
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1815
1816
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1817
1818
1819
1820
1821
1822
  /**
   * scsi_scan_host - scan the given adapter
   * @shost:	adapter to scan
   **/
  void scsi_scan_host(struct Scsi_Host *shost)
  {
a57b1fccd   Matthew Wilcox   [SCSI] scsi_scan:...
1823
  	struct task_struct *p;
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1824
1825
1826
1827
  	struct async_scan_data *data;
  
  	if (strncmp(scsi_scan_type, "none", 4) == 0)
  		return;
bc4f24014   Alan Stern   [SCSI] implement ...
1828
1829
  	if (scsi_autopm_get_host(shost) < 0)
  		return;
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1830
1831
1832
  
  	data = scsi_prep_async_scan(shost);
  	if (!data) {
1aa8fab2a   Matthew Wilcox   [SCSI] Make scsi_...
1833
  		do_scsi_scan_host(shost);
bc4f24014   Alan Stern   [SCSI] implement ...
1834
  		scsi_autopm_put_host(shost);
3e082a910   Matthew Wilcox   [SCSI] Add abilit...
1835
1836
  		return;
  	}
1aa8fab2a   Matthew Wilcox   [SCSI] Make scsi_...
1837

a57b1fccd   Matthew Wilcox   [SCSI] scsi_scan:...
1838
  	p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
801678c5a   Hirofumi Nakagawa   Remove duplicated...
1839
  	if (IS_ERR(p))
a57b1fccd   Matthew Wilcox   [SCSI] scsi_scan:...
1840
  		do_scan_async(data);
bc4f24014   Alan Stern   [SCSI] implement ...
1841
  	/* scsi_autopm_put_host(shost) is called in do_scan_async() */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1842
1843
  }
  EXPORT_SYMBOL(scsi_scan_host);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1844
1845
  void scsi_forget_host(struct Scsi_Host *shost)
  {
a64358db1   Alan Stern   [SCSI] SCSI scann...
1846
  	struct scsi_device *sdev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1847
  	unsigned long flags;
a64358db1   Alan Stern   [SCSI] SCSI scann...
1848
   restart:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1849
  	spin_lock_irqsave(shost->host_lock, flags);
a64358db1   Alan Stern   [SCSI] SCSI scann...
1850
1851
1852
  	list_for_each_entry(sdev, &shost->__devices, siblings) {
  		if (sdev->sdev_state == SDEV_DEL)
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1853
  		spin_unlock_irqrestore(shost->host_lock, flags);
a64358db1   Alan Stern   [SCSI] SCSI scann...
1854
1855
  		__scsi_remove_device(sdev);
  		goto restart;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1856
1857
1858
  	}
  	spin_unlock_irqrestore(shost->host_lock, flags);
  }
9f6aa5750   Randy Dunlap   scsi_scan.c: fix/...
1859
1860
1861
  /**
   * scsi_get_host_dev - Create a scsi_device that points to the host adapter itself
   * @shost: Host that needs a scsi_device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1862
1863
1864
   *
   * Lock status: None assumed.
   *
f64a181d8   Christoph Hellwig   [SCSI] remove Scs...
1865
   * Returns:     The scsi_device or NULL
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1866
1867
   *
   * Notes:
f64a181d8   Christoph Hellwig   [SCSI] remove Scs...
1868
   *	Attach a single scsi_device to the Scsi_Host - this should
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1869
1870
1871
1872
1873
   *	be made to look like a "pseudo-device" that points to the
   *	HA itself.
   *
   *	Note - this device is not accessible from any high-level
   *	drivers (including generics), which is probably not
9f6aa5750   Randy Dunlap   scsi_scan.c: fix/...
1874
   *	optimal.  We can add hooks later to attach.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1875
1876
1877
   */
  struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
  {
e517d3133   Alan Stern   [SCSI] add missin...
1878
  	struct scsi_device *sdev = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1879
  	struct scsi_target *starget;
0b9506723   Arjan van de Ven   [SCSI] turn most ...
1880
  	mutex_lock(&shost->scan_mutex);
e517d3133   Alan Stern   [SCSI] add missin...
1881
1882
  	if (!scsi_host_scan_allowed(shost))
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1883
1884
  	starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id);
  	if (!starget)
e517d3133   Alan Stern   [SCSI] add missin...
1885
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1886
1887
  
  	sdev = scsi_alloc_sdev(starget, 0, NULL);
d5469119f   Alan Stern   [SCSI] fix refcou...
1888
  	if (sdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1889
  		sdev->borken = 0;
d5469119f   Alan Stern   [SCSI] fix refcou...
1890
  	else
884d25cc4   James Bottomley   [SCSI] Fix refcou...
1891
  		scsi_target_reap(starget);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1892
  	put_device(&starget->dev);
e517d3133   Alan Stern   [SCSI] add missin...
1893
   out:
0b9506723   Arjan van de Ven   [SCSI] turn most ...
1894
  	mutex_unlock(&shost->scan_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1895
1896
1897
  	return sdev;
  }
  EXPORT_SYMBOL(scsi_get_host_dev);
9f6aa5750   Randy Dunlap   scsi_scan.c: fix/...
1898
1899
1900
  /**
   * scsi_free_host_dev - Free a scsi_device that points to the host adapter itself
   * @sdev: Host device to be freed
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1901
1902
1903
1904
   *
   * Lock status: None assumed.
   *
   * Returns:     Nothing
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1905
1906
1907
1908
   */
  void scsi_free_host_dev(struct scsi_device *sdev)
  {
  	BUG_ON(sdev->id != sdev->host->this_id);
860dc7360   James Bottomley   [SCSI] fix async ...
1909
  	__scsi_remove_device(sdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1910
1911
  }
  EXPORT_SYMBOL(scsi_free_host_dev);