Blame view

drivers/scsi/scsi.c 33.6 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  /*
   *  scsi.c Copyright (C) 1992 Drew Eckhardt
   *         Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale
   *         Copyright (C) 2002, 2003 Christoph Hellwig
   *
   *  generic mid-level SCSI driver
   *      Initial versions: Drew Eckhardt
   *      Subsequent revisions: Eric Youngdale
   *
   *  <drew@colorado.edu>
   *
   *  Bug correction thanks go to :
   *      Rik Faith <faith@cs.unc.edu>
   *      Tommy Thorn <tthorn>
   *      Thomas Wuensche <tw@fgb1.fgb.mw.tu-muenchen.de>
   *
   *  Modified by Eric Youngdale eric@andante.org or ericy@gnu.ai.mit.edu to
   *  add scatter-gather, multiple outstanding request, and other
   *  enhancements.
   *
   *  Native multichannel, wide scsi, /proc/scsi and hot plugging
   *  support added by Michael Neuffer <mike@i-connect.net>
   *
   *  Added request_module("scsi_hostadapter") for kerneld:
   *  (Put an "alias scsi_hostadapter your_hostadapter" in /etc/modprobe.conf)
   *  Bjorn Ekwall  <bj0rn@blox.se>
   *  (changed to kmod)
   *
   *  Major improvements to the timeout, abort, and reset processing,
   *  as well as performance modifications for large queue depths by
   *  Leonard N. Zubkoff <lnz@dandelion.com>
   *
   *  Converted cli() code to spinlocks, Ingo Molnar
   *
   *  Jiffies wrap fixes (host->resetting), 3 Dec 1998 Andrea Arcangeli
   *
   *  out_of_space hacks, D. Gilbert (dpg) 990608
   */
  
  #include <linux/module.h>
  #include <linux/moduleparam.h>
  #include <linux/kernel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
45
46
47
48
49
  #include <linux/timer.h>
  #include <linux/string.h>
  #include <linux/slab.h>
  #include <linux/blkdev.h>
  #include <linux/delay.h>
  #include <linux/init.h>
  #include <linux/completion.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
53
54
55
  #include <linux/unistd.h>
  #include <linux/spinlock.h>
  #include <linux/kmod.h>
  #include <linux/interrupt.h>
  #include <linux/notifier.h>
  #include <linux/cpu.h>
0b9506723   Arjan van de Ven   [SCSI] turn most ...
56
  #include <linux/mutex.h>
2955b47d2   Dan Williams   [SCSI] async: int...
57
  #include <linux/async.h>
3c6bdaeab   Martin K. Petersen   [SCSI] Add a repo...
58
  #include <asm/unaligned.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
63
  
  #include <scsi/scsi.h>
  #include <scsi/scsi_cmnd.h>
  #include <scsi/scsi_dbg.h>
  #include <scsi/scsi_device.h>
7b3d9545f   Linus Torvalds   Revert "scsi: rev...
64
  #include <scsi/scsi_driver.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
67
  #include <scsi/scsi_eh.h>
  #include <scsi/scsi_host.h>
  #include <scsi/scsi_tcq.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
70
  
  #include "scsi_priv.h"
  #include "scsi_logging.h"
bf8162354   Kei Tokunaga   [SCSI] add scsi t...
71
72
  #define CREATE_TRACE_POINTS
  #include <trace/events/scsi.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
74
75
  /*
   * Definitions and constants.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
79
80
81
82
83
   * Note - the initial logging level can be set here to log events at boot time.
   * After the system is up, you may enable logging via the /proc interface.
   */
  unsigned int scsi_logging_level;
  #if defined(CONFIG_SCSI_LOGGING)
  EXPORT_SYMBOL(scsi_logging_level);
  #endif
ea80dadec   James Bottomley   [SCSI] Fix sd_pro...
84
  /* sd, scsi core and power management need to coordinate flushing async actions */
2955b47d2   Dan Williams   [SCSI] async: int...
85
  ASYNC_DOMAIN(scsi_sd_probe_domain);
a7a20d103   Dan Williams   [SCSI] sd: limit ...
86
  EXPORT_SYMBOL(scsi_sd_probe_domain);
a7a20d103   Dan Williams   [SCSI] sd: limit ...
87

3c31b52f9   Dan Williams   scsi: async sd re...
88
89
90
91
92
93
94
95
  /*
   * Separate domain (from scsi_sd_probe_domain) to maximize the benefit of
   * asynchronous system resume operations.  It is marked 'exclusive' to avoid
   * being included in the async_synchronize_full() that is invoked by
   * dpm_resume()
   */
  ASYNC_DOMAIN_EXCLUSIVE(scsi_sd_pm_domain);
  EXPORT_SYMBOL(scsi_sd_pm_domain);
8a1cdc9ca   Matthew Wilcox   [PATCH] Revert AB...
96
97
98
99
  /* NB: These are exposed through /proc/scsi/scsi and form part of the ABI.
   * You may not alter any existing entry (although adding new ones is
   * encouraged once assigned by ANSI/INCITS T10
   */
4ff36718e   Matthew Wilcox   [SCSI] Improve in...
100
  static const char *const scsi_device_types[] = {
8a1cdc9ca   Matthew Wilcox   [PATCH] Revert AB...
101
102
  	"Direct-Access    ",
  	"Sequential-Access",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
104
105
  	"Printer          ",
  	"Processor        ",
  	"WORM             ",
8a1cdc9ca   Matthew Wilcox   [PATCH] Revert AB...
106
  	"CD-ROM           ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
  	"Scanner          ",
8a1cdc9ca   Matthew Wilcox   [PATCH] Revert AB...
108
109
  	"Optical Device   ",
  	"Medium Changer   ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
  	"Communications   ",
4ff36718e   Matthew Wilcox   [SCSI] Improve in...
111
112
  	"ASC IT8          ",
  	"ASC IT8          ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
  	"RAID             ",
  	"Enclosure        ",
8a1cdc9ca   Matthew Wilcox   [PATCH] Revert AB...
115
  	"Direct-Access-RBC",
4ff36718e   Matthew Wilcox   [SCSI] Improve in...
116
117
118
119
  	"Optical card     ",
  	"Bridge controller",
  	"Object storage   ",
  	"Automation/Drive ",
c6e4f191c   Christoph Hellwig   scsi: update scsi...
120
121
  	"Security Manager ",
  	"Direct-Access-ZBC",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
  };
4ff36718e   Matthew Wilcox   [SCSI] Improve in...
123

eb44820c2   Rob Landley   [SCSI] Add Docume...
124
125
126
127
  /**
   * scsi_device_type - Return 17 char string indicating device type.
   * @type: type number to look up
   */
4ff36718e   Matthew Wilcox   [SCSI] Improve in...
128
129
130
131
132
133
  const char * scsi_device_type(unsigned type)
  {
  	if (type == 0x1e)
  		return "Well-known LUN   ";
  	if (type == 0x1f)
  		return "No Device        ";
80c6e3c0b   Eric Sesterhenn   [SCSI] fix scsi_d...
134
  	if (type >= ARRAY_SIZE(scsi_device_types))
4ff36718e   Matthew Wilcox   [SCSI] Improve in...
135
136
137
138
139
  		return "Unknown          ";
  	return scsi_device_types[type];
  }
  
  EXPORT_SYMBOL(scsi_device_type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
  struct scsi_host_cmd_pool {
5b7f16804   James Bottomley   [SCSI] don't use ...
142
143
144
145
146
147
148
  	struct kmem_cache	*cmd_slab;
  	struct kmem_cache	*sense_slab;
  	unsigned int		users;
  	char			*cmd_name;
  	char			*sense_name;
  	unsigned int		slab_flags;
  	gfp_t			gfp_mask;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
151
  };
  
  static struct scsi_host_cmd_pool scsi_cmd_pool = {
5b7f16804   James Bottomley   [SCSI] don't use ...
152
153
  	.cmd_name	= "scsi_cmd_cache",
  	.sense_name	= "scsi_sense_cache",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
156
157
  	.slab_flags	= SLAB_HWCACHE_ALIGN,
  };
  
  static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
5b7f16804   James Bottomley   [SCSI] don't use ...
158
159
  	.cmd_name	= "scsi_cmd_cache(DMA)",
  	.sense_name	= "scsi_sense_cache(DMA)",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
  	.slab_flags	= SLAB_HWCACHE_ALIGN|SLAB_CACHE_DMA,
  	.gfp_mask	= __GFP_DMA,
  };
0b9506723   Arjan van de Ven   [SCSI] turn most ...
163
  static DEFINE_MUTEX(host_cmd_pool_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164

eb44820c2   Rob Landley   [SCSI] Add Docume...
165
  /**
7c2833412   Christoph Hellwig   [SCSI] simplify c...
166
167
   * scsi_host_free_command - internal function to release a command
   * @shost:	host to free the command for
e507e30b8   James Bottomley   [SCSI] consolidat...
168
169
170
   * @cmd:	command to release
   *
   * the command must previously have been allocated by
7c2833412   Christoph Hellwig   [SCSI] simplify c...
171
   * scsi_host_alloc_command.
e507e30b8   James Bottomley   [SCSI] consolidat...
172
173
   */
  static void
7c2833412   Christoph Hellwig   [SCSI] simplify c...
174
  scsi_host_free_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
e507e30b8   James Bottomley   [SCSI] consolidat...
175
  {
7c2833412   Christoph Hellwig   [SCSI] simplify c...
176
  	struct scsi_host_cmd_pool *pool = shost->cmd_pool;
7027ad72a   Martin K. Petersen   [SCSI] Support de...
177
178
  	if (cmd->prot_sdb)
  		kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb);
e507e30b8   James Bottomley   [SCSI] consolidat...
179
180
181
182
183
  	kmem_cache_free(pool->sense_slab, cmd->sense_buffer);
  	kmem_cache_free(pool->cmd_slab, cmd);
  }
  
  /**
7027ad72a   Martin K. Petersen   [SCSI] Support de...
184
185
186
187
188
189
190
191
192
193
   * scsi_host_alloc_command - internal function to allocate command
   * @shost:	SCSI host whose pool to allocate from
   * @gfp_mask:	mask for the allocation
   *
   * Returns a fully allocated command with sense buffer and protection
   * data buffer (where applicable) or NULL on failure
   */
  static struct scsi_cmnd *
  scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask)
  {
7c2833412   Christoph Hellwig   [SCSI] simplify c...
194
  	struct scsi_host_cmd_pool *pool = shost->cmd_pool;
7027ad72a   Martin K. Petersen   [SCSI] Support de...
195
  	struct scsi_cmnd *cmd;
7c2833412   Christoph Hellwig   [SCSI] simplify c...
196
  	cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask | pool->gfp_mask);
7027ad72a   Martin K. Petersen   [SCSI] Support de...
197
  	if (!cmd)
7c2833412   Christoph Hellwig   [SCSI] simplify c...
198
199
200
201
202
203
  		goto fail;
  
  	cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab,
  					     gfp_mask | pool->gfp_mask);
  	if (!cmd->sense_buffer)
  		goto fail_free_cmd;
7027ad72a   Martin K. Petersen   [SCSI] Support de...
204
205
206
  
  	if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) {
  		cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp_mask);
7c2833412   Christoph Hellwig   [SCSI] simplify c...
207
208
  		if (!cmd->prot_sdb)
  			goto fail_free_sense;
7027ad72a   Martin K. Petersen   [SCSI] Support de...
209
210
211
  	}
  
  	return cmd;
7c2833412   Christoph Hellwig   [SCSI] simplify c...
212
213
214
215
216
217
218
  
  fail_free_sense:
  	kmem_cache_free(pool->sense_slab, cmd->sense_buffer);
  fail_free_cmd:
  	kmem_cache_free(pool->cmd_slab, cmd);
  fail:
  	return NULL;
7027ad72a   Martin K. Petersen   [SCSI] Support de...
219
220
221
  }
  
  /**
eb44820c2   Rob Landley   [SCSI] Add Docume...
222
223
224
225
226
227
228
   * __scsi_get_command - Allocate a struct scsi_cmnd
   * @shost: host to transmit command
   * @gfp_mask: allocation mask
   *
   * Description: allocate a struct scsi_cmd from host's slab, recycling from the
   *              host's free_list if necessary.
   */
f1bea55d5   Christoph Hellwig   scsi: remove vari...
229
230
  static struct scsi_cmnd *
  __scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
  {
b4c2554d4   Martin K. Petersen   [SCSI] Fix protec...
232
  	struct scsi_cmnd *cmd = scsi_host_alloc_command(shost, gfp_mask);
164fc5dcd   Hugh Dickins   scsi: fix sense_s...
233

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
235
236
237
238
239
240
241
242
243
  	if (unlikely(!cmd)) {
  		unsigned long flags;
  
  		spin_lock_irqsave(&shost->free_list_lock, flags);
  		if (likely(!list_empty(&shost->free_list))) {
  			cmd = list_entry(shost->free_list.next,
  					 struct scsi_cmnd, list);
  			list_del_init(&cmd->list);
  		}
  		spin_unlock_irqrestore(&shost->free_list_lock, flags);
de25deb18   FUJITA Tomonori   [SCSI] use dynami...
244
245
  
  		if (cmd) {
b4c2554d4   Martin K. Petersen   [SCSI] Fix protec...
246
  			void *buf, *prot;
de25deb18   FUJITA Tomonori   [SCSI] use dynami...
247
  			buf = cmd->sense_buffer;
b4c2554d4   Martin K. Petersen   [SCSI] Fix protec...
248
  			prot = cmd->prot_sdb;
de25deb18   FUJITA Tomonori   [SCSI] use dynami...
249
  			memset(cmd, 0, sizeof(*cmd));
b4c2554d4   Martin K. Petersen   [SCSI] Fix protec...
250

de25deb18   FUJITA Tomonori   [SCSI] use dynami...
251
  			cmd->sense_buffer = buf;
b4c2554d4   Martin K. Petersen   [SCSI] Fix protec...
252
  			cmd->prot_sdb = prot;
de25deb18   FUJITA Tomonori   [SCSI] use dynami...
253
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
255
256
257
  	}
  
  	return cmd;
  }
eb44820c2   Rob Landley   [SCSI] Add Docume...
258
259
260
261
  /**
   * scsi_get_command - Allocate and setup a scsi command block
   * @dev: parent scsi device
   * @gfp_mask: allocator flags
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
264
   *
   * Returns:	The allocated scsi command structure.
   */
c53033f6b   Al Viro   [PATCH] gfp_t: dr...
265
  struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
  {
047963368   Christoph Hellwig   [SCSI] do not man...
267
268
  	struct scsi_cmnd *cmd = __scsi_get_command(dev->host, gfp_mask);
  	unsigned long flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269

047963368   Christoph Hellwig   [SCSI] do not man...
270
  	if (unlikely(cmd == NULL))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
  		return NULL;
047963368   Christoph Hellwig   [SCSI] do not man...
272
273
274
275
276
277
278
  	cmd->device = dev;
  	INIT_LIST_HEAD(&cmd->list);
  	INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler);
  	spin_lock_irqsave(&dev->list_lock, flags);
  	list_add_tail(&cmd->list, &dev->cmd_list);
  	spin_unlock_irqrestore(&dev->list_lock, flags);
  	cmd->jiffies_at_alloc = jiffies;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
  	return cmd;
b58d91547   FUJITA Tomonori   [SCSI] export scs...
280
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281

eb44820c2   Rob Landley   [SCSI] Add Docume...
282
283
284
285
  /**
   * __scsi_put_command - Free a struct scsi_cmnd
   * @shost: dev->host
   * @cmd: Command to free
eb44820c2   Rob Landley   [SCSI] Add Docume...
286
   */
f1bea55d5   Christoph Hellwig   scsi: remove vari...
287
  static void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
b58d91547   FUJITA Tomonori   [SCSI] export scs...
288
289
  {
  	unsigned long flags;
b58d91547   FUJITA Tomonori   [SCSI] export scs...
290
  	if (unlikely(list_empty(&shost->free_list))) {
44b93b59d   Christoph Hellwig   [SCSI] avoid usel...
291
292
293
294
295
296
  		spin_lock_irqsave(&shost->free_list_lock, flags);
  		if (list_empty(&shost->free_list)) {
  			list_add(&cmd->list, &shost->free_list);
  			cmd = NULL;
  		}
  		spin_unlock_irqrestore(&shost->free_list_lock, flags);
b58d91547   FUJITA Tomonori   [SCSI] export scs...
297
  	}
b58d91547   FUJITA Tomonori   [SCSI] export scs...
298

e507e30b8   James Bottomley   [SCSI] consolidat...
299
  	if (likely(cmd != NULL))
7c2833412   Christoph Hellwig   [SCSI] simplify c...
300
  		scsi_host_free_command(shost, cmd);
b58d91547   FUJITA Tomonori   [SCSI] export scs...
301
  }
b58d91547   FUJITA Tomonori   [SCSI] export scs...
302

eb44820c2   Rob Landley   [SCSI] Add Docume...
303
304
305
  /**
   * scsi_put_command - Free a scsi command block
   * @cmd: command block to free
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
307
308
309
310
311
312
   *
   * Returns:	Nothing.
   *
   * Notes:	The command must not belong to any lists.
   */
  void scsi_put_command(struct scsi_cmnd *cmd)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313
  	unsigned long flags;
b58d91547   FUJITA Tomonori   [SCSI] export scs...
314

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
316
317
318
  	/* serious error if the command hasn't come from a device list */
  	spin_lock_irqsave(&cmd->device->list_lock, flags);
  	BUG_ON(list_empty(&cmd->list));
  	list_del_init(&cmd->list);
b58d91547   FUJITA Tomonori   [SCSI] export scs...
319
  	spin_unlock_irqrestore(&cmd->device->list_lock, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320

fcc95a763   Bart Van Assche   scsi: remove two ...
321
  	BUG_ON(delayed_work_pending(&cmd->abort_work));
e494f6a72   Hannes Reinecke   [SCSI] improved e...
322

047963368   Christoph Hellwig   [SCSI] do not man...
323
  	__scsi_put_command(cmd->device->host, cmd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
325

89d9a5679   Christoph Hellwig   [SCSI] add suppor...
326
327
  static struct scsi_host_cmd_pool *
  scsi_find_host_cmd_pool(struct Scsi_Host *shost)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
  {
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
  	if (shost->hostt->cmd_size)
  		return shost->hostt->cmd_pool;
  	if (shost->unchecked_isa_dma)
  		return &scsi_cmd_dma_pool;
  	return &scsi_cmd_pool;
  }
  
  static void
  scsi_free_host_cmd_pool(struct scsi_host_cmd_pool *pool)
  {
  	kfree(pool->sense_name);
  	kfree(pool->cmd_name);
  	kfree(pool);
  }
  
  static struct scsi_host_cmd_pool *
  scsi_alloc_host_cmd_pool(struct Scsi_Host *shost)
  {
  	struct scsi_host_template *hostt = shost->hostt;
  	struct scsi_host_cmd_pool *pool;
  
  	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
  	if (!pool)
  		return NULL;
884ffee01   James Bottomley   scsi: use short d...
353
354
  	pool->cmd_name = kasprintf(GFP_KERNEL, "%s_cmd", hostt->proc_name);
  	pool->sense_name = kasprintf(GFP_KERNEL, "%s_sense", hostt->proc_name);
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
355
356
357
358
359
360
361
362
363
364
  	if (!pool->cmd_name || !pool->sense_name) {
  		scsi_free_host_cmd_pool(pool);
  		return NULL;
  	}
  
  	pool->slab_flags = SLAB_HWCACHE_ALIGN;
  	if (shost->unchecked_isa_dma) {
  		pool->slab_flags |= SLAB_CACHE_DMA;
  		pool->gfp_mask = __GFP_DMA;
  	}
f6105c080   Juergen Gross   [SCSI] save comma...
365
366
367
  
  	if (hostt->cmd_size)
  		hostt->cmd_pool = pool;
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
368
369
370
371
372
373
374
  	return pool;
  }
  
  static struct scsi_host_cmd_pool *
  scsi_get_host_cmd_pool(struct Scsi_Host *shost)
  {
  	struct scsi_host_template *hostt = shost->hostt;
1c353f7d6   James Bottomley   [SCSI] export com...
375
  	struct scsi_host_cmd_pool *retval = NULL, *pool;
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
376
  	size_t cmd_size = sizeof(struct scsi_cmnd) + hostt->cmd_size;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
378
  	/*
  	 * Select a command slab for this host and create it if not
eb44820c2   Rob Landley   [SCSI] Add Docume...
379
  	 * yet existent.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
  	 */
0b9506723   Arjan van de Ven   [SCSI] turn most ...
381
  	mutex_lock(&host_cmd_pool_mutex);
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
382
383
384
385
386
387
  	pool = scsi_find_host_cmd_pool(shost);
  	if (!pool) {
  		pool = scsi_alloc_host_cmd_pool(shost);
  		if (!pool)
  			goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
  	if (!pool->users) {
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
389
  		pool->cmd_slab = kmem_cache_create(pool->cmd_name, cmd_size, 0,
5b7f16804   James Bottomley   [SCSI] don't use ...
390
391
  						   pool->slab_flags, NULL);
  		if (!pool->cmd_slab)
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
392
  			goto out_free_pool;
5b7f16804   James Bottomley   [SCSI] don't use ...
393
394
395
396
  
  		pool->sense_slab = kmem_cache_create(pool->sense_name,
  						     SCSI_SENSE_BUFFERSIZE, 0,
  						     pool->slab_flags, NULL);
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
397
398
  		if (!pool->sense_slab)
  			goto out_free_slab;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
400
401
  	}
  
  	pool->users++;
1c353f7d6   James Bottomley   [SCSI] export com...
402
  	retval = pool;
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
403
  out:
0b9506723   Arjan van de Ven   [SCSI] turn most ...
404
  	mutex_unlock(&host_cmd_pool_mutex);
1c353f7d6   James Bottomley   [SCSI] export com...
405
  	return retval;
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
406
407
408
409
  
  out_free_slab:
  	kmem_cache_destroy(pool->cmd_slab);
  out_free_pool:
f6105c080   Juergen Gross   [SCSI] save comma...
410
  	if (hostt->cmd_size) {
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
411
  		scsi_free_host_cmd_pool(pool);
f6105c080   Juergen Gross   [SCSI] save comma...
412
413
  		hostt->cmd_pool = NULL;
  	}
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
414
  	goto out;
1c353f7d6   James Bottomley   [SCSI] export com...
415
  }
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
416
  static void scsi_put_host_cmd_pool(struct Scsi_Host *shost)
1c353f7d6   James Bottomley   [SCSI] export com...
417
  {
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
418
  	struct scsi_host_template *hostt = shost->hostt;
1c353f7d6   James Bottomley   [SCSI] export com...
419
  	struct scsi_host_cmd_pool *pool;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420

1c353f7d6   James Bottomley   [SCSI] export com...
421
  	mutex_lock(&host_cmd_pool_mutex);
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
422
  	pool = scsi_find_host_cmd_pool(shost);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
  	/*
1c353f7d6   James Bottomley   [SCSI] export com...
424
425
426
  	 * This may happen if a driver has a mismatched get and put
  	 * of the command pool; the driver should be implicated in
  	 * the stack trace
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
  	 */
1c353f7d6   James Bottomley   [SCSI] export com...
428
  	BUG_ON(pool->users == 0);
de25deb18   FUJITA Tomonori   [SCSI] use dynami...
429

5b7f16804   James Bottomley   [SCSI] don't use ...
430
431
432
  	if (!--pool->users) {
  		kmem_cache_destroy(pool->cmd_slab);
  		kmem_cache_destroy(pool->sense_slab);
f6105c080   Juergen Gross   [SCSI] save comma...
433
  		if (hostt->cmd_size) {
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
434
  			scsi_free_host_cmd_pool(pool);
f6105c080   Juergen Gross   [SCSI] save comma...
435
436
  			hostt->cmd_pool = NULL;
  		}
5b7f16804   James Bottomley   [SCSI] don't use ...
437
  	}
0b9506723   Arjan van de Ven   [SCSI] turn most ...
438
  	mutex_unlock(&host_cmd_pool_mutex);
1c353f7d6   James Bottomley   [SCSI] export com...
439
440
441
  }
  
  /**
1c353f7d6   James Bottomley   [SCSI] export com...
442
443
444
445
446
447
448
449
450
451
452
   * scsi_setup_command_freelist - Setup the command freelist for a scsi host.
   * @shost: host to allocate the freelist for.
   *
   * Description: The command freelist protects against system-wide out of memory
   * deadlock by preallocating one SCSI command structure for each host, so the
   * system can always write to a swap file on a device associated with that host.
   *
   * Returns:	Nothing.
   */
  int scsi_setup_command_freelist(struct Scsi_Host *shost)
  {
1c353f7d6   James Bottomley   [SCSI] export com...
453
  	const gfp_t gfp_mask = shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL;
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
454
  	struct scsi_cmnd *cmd;
1c353f7d6   James Bottomley   [SCSI] export com...
455
456
457
  
  	spin_lock_init(&shost->free_list_lock);
  	INIT_LIST_HEAD(&shost->free_list);
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
458
  	shost->cmd_pool = scsi_get_host_cmd_pool(shost);
1c353f7d6   James Bottomley   [SCSI] export com...
459
460
461
462
463
464
  	if (!shost->cmd_pool)
  		return -ENOMEM;
  
  	/*
  	 * Get one backup command for this host.
  	 */
7027ad72a   Martin K. Petersen   [SCSI] Support de...
465
  	cmd = scsi_host_alloc_command(shost, gfp_mask);
1c353f7d6   James Bottomley   [SCSI] export com...
466
  	if (!cmd) {
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
467
  		scsi_put_host_cmd_pool(shost);
61d7416a2   Alan D. Brunelle   [SCSI] bug fix fo...
468
  		shost->cmd_pool = NULL;
1c353f7d6   James Bottomley   [SCSI] export com...
469
470
471
472
  		return -ENOMEM;
  	}
  	list_add(&cmd->list, &shost->free_list);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
473
  }
eb44820c2   Rob Landley   [SCSI] Add Docume...
474
475
476
  /**
   * scsi_destroy_command_freelist - Release the command freelist for a scsi host.
   * @shost: host whose freelist is going to be destroyed
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
478
479
   */
  void scsi_destroy_command_freelist(struct Scsi_Host *shost)
  {
61d7416a2   Alan D. Brunelle   [SCSI] bug fix fo...
480
481
482
483
484
485
  	/*
  	 * If cmd_pool is NULL the free list was not initialized, so
  	 * do not attempt to release resources.
  	 */
  	if (!shost->cmd_pool)
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
486
487
488
489
490
  	while (!list_empty(&shost->free_list)) {
  		struct scsi_cmnd *cmd;
  
  		cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list);
  		list_del_init(&cmd->list);
7c2833412   Christoph Hellwig   [SCSI] simplify c...
491
  		scsi_host_free_command(shost, cmd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
  	}
1c353f7d6   James Bottomley   [SCSI] export com...
493
  	shost->cmd_pool = NULL;
89d9a5679   Christoph Hellwig   [SCSI] add suppor...
494
  	scsi_put_host_cmd_pool(shost);
de25deb18   FUJITA Tomonori   [SCSI] use dynami...
495
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
496
497
498
499
  #ifdef CONFIG_SCSI_LOGGING
  void scsi_log_send(struct scsi_cmnd *cmd)
  {
  	unsigned int level;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
500
501
502
503
504
505
  
  	/*
  	 * If ML QUEUE log level is greater than or equal to:
  	 *
  	 * 1: nothing (match completion)
  	 *
c11c004b1   Hannes Reinecke   scsi: simplify sc...
506
  	 * 2: log opcode + command of all commands + cmd address
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
  	 *
c11c004b1   Hannes Reinecke   scsi: simplify sc...
508
  	 * 3: same as 2
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509
510
511
512
513
514
515
  	 *
  	 * 4: same as 3 plus dump extra junk
  	 */
  	if (unlikely(scsi_logging_level)) {
  		level = SCSI_LOG_LEVEL(SCSI_LOG_MLQUEUE_SHIFT,
  				       SCSI_LOG_MLQUEUE_BITS);
  		if (level > 1) {
c11c004b1   Hannes Reinecke   scsi: simplify sc...
516
517
518
  			scmd_printk(KERN_INFO, cmd,
  				    "Send: scmd 0x%p
  ", cmd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
519
520
521
  			scsi_print_command(cmd);
  			if (level > 3) {
  				printk(KERN_INFO "buffer = 0x%p, bufflen = %d,"
7b3d9545f   Linus Torvalds   Revert "scsi: rev...
522
523
  				       " queuecommand 0x%p
  ",
a73e45b3d   Boaz Harrosh   [SCSI] scsi.c: co...
524
  					scsi_sglist(cmd), scsi_bufflen(cmd),
a4d04a4cd   Martin K. Petersen   [SCSI] Make error...
525
  					cmd->device->host->hostt->queuecommand);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
527
528
529
530
531
532
533
534
  
  			}
  		}
  	}
  }
  
  void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
  {
  	unsigned int level;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
535
536
537
538
539
540
541
542
543
  
  	/*
  	 * If ML COMPLETE log level is greater than or equal to:
  	 *
  	 * 1: log disposition, result, opcode + command, and conditionally
  	 * sense data for failures or non SUCCESS dispositions.
  	 *
  	 * 2: same as 1 but for all command completions.
  	 *
c11c004b1   Hannes Reinecke   scsi: simplify sc...
544
  	 * 3: same as 2
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
545
546
547
548
549
550
551
552
  	 *
  	 * 4: same as 3 plus dump extra junk
  	 */
  	if (unlikely(scsi_logging_level)) {
  		level = SCSI_LOG_LEVEL(SCSI_LOG_MLCOMPLETE_SHIFT,
  				       SCSI_LOG_MLCOMPLETE_BITS);
  		if (((level > 0) && (cmd->result || disposition != SUCCESS)) ||
  		    (level > 1)) {
c11c004b1   Hannes Reinecke   scsi: simplify sc...
553
  			scsi_print_result(cmd, "Done: ", disposition);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
554
  			scsi_print_command(cmd);
a4d04a4cd   Martin K. Petersen   [SCSI] Make error...
555
  			if (status_byte(cmd->result) & CHECK_CONDITION)
d811b848e   Hannes Reinecke   scsi: use sdev as...
556
  				scsi_print_sense(cmd);
a4d04a4cd   Martin K. Petersen   [SCSI] Make error...
557
558
559
560
  			if (level > 3)
  				scmd_printk(KERN_INFO, cmd,
  					    "scsi host busy %d failed %d
  ",
746650160   Christoph Hellwig   scsi: convert hos...
561
  					    atomic_read(&cmd->device->host->host_busy),
a4d04a4cd   Martin K. Petersen   [SCSI] Make error...
562
  					    cmd->device->host->host_failed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
564
565
566
  		}
  	}
  }
  #endif
eb44820c2   Rob Landley   [SCSI] Add Docume...
567
568
569
570
571
572
  /**
   * scsi_cmd_get_serial - Assign a serial number to a command
   * @host: the scsi host
   * @cmd: command to assign serial number to
   *
   * Description: a serial number identifies a request for error recovery
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573
574
   * and debugging purposes.  Protected by the Host_Lock of host.
   */
f281233d3   Jeff Garzik   SCSI host lock pu...
575
  void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
576
577
578
579
  {
  	cmd->serial_number = host->cmd_serial_number++;
  	if (cmd->serial_number == 0) 
  		cmd->serial_number = host->cmd_serial_number++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
580
  }
f281233d3   Jeff Garzik   SCSI host lock pu...
581
  EXPORT_SYMBOL(scsi_cmd_get_serial);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
582

eb44820c2   Rob Landley   [SCSI] Add Docume...
583
  /**
eb44820c2   Rob Landley   [SCSI] Add Docume...
584
585
   * scsi_finish_command - cleanup and pass command back to upper layer
   * @cmd: the command
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
586
   *
eb44820c2   Rob Landley   [SCSI] Add Docume...
587
   * Description: Pass command off to upper layer for finishing of I/O
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
588
589
590
591
592
593
   *              request, waking processes that are waiting on results,
   *              etc.
   */
  void scsi_finish_command(struct scsi_cmnd *cmd)
  {
  	struct scsi_device *sdev = cmd->device;
f0c0a376d   Mike Christie   [SCSI] Add helper...
594
  	struct scsi_target *starget = scsi_target(sdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
  	struct Scsi_Host *shost = sdev->host;
7b3d9545f   Linus Torvalds   Revert "scsi: rev...
596
597
  	struct scsi_driver *drv;
  	unsigned int good_bytes;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
599
  
  	scsi_device_unbusy(sdev);
cd9070c9c   Christoph Hellwig   scsi: fix the {ho...
600
601
602
603
604
605
606
607
608
609
  	/*
  	 * Clear the flags that say that the device/target/host is no longer
  	 * capable of accepting new commands.
  	 */
  	if (atomic_read(&shost->host_blocked))
  		atomic_set(&shost->host_blocked, 0);
  	if (atomic_read(&starget->target_blocked))
  		atomic_set(&starget->target_blocked, 0);
  	if (atomic_read(&sdev->device_blocked))
  		atomic_set(&sdev->device_blocked, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
610
611
612
613
614
615
616
  
  	/*
  	 * If we have valid sense information, then some kind of recovery
  	 * must have taken place.  Make a note of this.
  	 */
  	if (SCSI_SENSE_VALID(cmd))
  		cmd->result |= (DRIVER_SENSE << 24);
3bf743e7c   Jeff Garzik   [SCSI] use {sdev,...
617
618
619
620
  	SCSI_LOG_MLCOMPLETE(4, sdev_printk(KERN_INFO, sdev,
  				"Notifying upper driver of completion "
  				"(result %x)
  ", cmd->result));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
621

f18573abc   FUJITA Tomonori   block: move the p...
622
  	good_bytes = scsi_bufflen(cmd);
7b3d9545f   Linus Torvalds   Revert "scsi: rev...
623
          if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) {
427e59f09   James Bottomley   [SCSI] make use o...
624
  		int old_good_bytes = good_bytes;
7b3d9545f   Linus Torvalds   Revert "scsi: rev...
625
626
627
  		drv = scsi_cmd_to_driver(cmd);
  		if (drv->done)
  			good_bytes = drv->done(cmd);
427e59f09   James Bottomley   [SCSI] make use o...
628
629
630
631
632
633
634
635
  		/*
  		 * USB may not give sense identifying bad sector and
  		 * simply return a residue instead, so subtract off the
  		 * residue if drv->done() error processing indicates no
  		 * change to the completion length.
  		 */
  		if (good_bytes == old_good_bytes)
  			good_bytes -= scsi_get_resid(cmd);
7b3d9545f   Linus Torvalds   Revert "scsi: rev...
636
637
  	}
  	scsi_io_completion(cmd, good_bytes);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
639

eb44820c2   Rob Landley   [SCSI] Add Docume...
640
  /**
db5ed4dfd   Christoph Hellwig   scsi: drop reason...
641
   * scsi_change_queue_depth - change a device's queue depth
eb44820c2   Rob Landley   [SCSI] Add Docume...
642
   * @sdev: SCSI Device in question
db5ed4dfd   Christoph Hellwig   scsi: drop reason...
643
   * @depth: number of commands allowed to be queued to the driver
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
   *
db5ed4dfd   Christoph Hellwig   scsi: drop reason...
645
   * Sets the device queue depth and returns the new value.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
   */
db5ed4dfd   Christoph Hellwig   scsi: drop reason...
647
  int scsi_change_queue_depth(struct scsi_device *sdev, int depth)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
648
649
  {
  	unsigned long flags;
db5ed4dfd   Christoph Hellwig   scsi: drop reason...
650
651
  	if (depth <= 0)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652
653
  
  	spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
885ace9e2   Mike Christie   [SCSI] fix shared...
654
655
656
657
658
659
660
661
662
  	/*
  	 * Check to see if the queue is managed by the block layer.
  	 * If it is, and we fail to adjust the depth, exit.
  	 *
  	 * Do not resize the tag map if it is a host wide share bqt,
  	 * because the size should be the hosts's can_queue. If there
  	 * is more IO than the LLD's can_queue (so there are not enuogh
  	 * tags) request_fn's host queue ready check will handle it.
  	 */
d285203cf   Christoph Hellwig   scsi: add support...
663
  	if (!shost_use_blk_mq(sdev->host) && !sdev->host->bqt) {
885ace9e2   Mike Christie   [SCSI] fix shared...
664
  		if (blk_queue_tagged(sdev->request_queue) &&
db5ed4dfd   Christoph Hellwig   scsi: drop reason...
665
666
  		    blk_queue_resize_tags(sdev->request_queue, depth) != 0)
  			goto out_unlock;
885ace9e2   Mike Christie   [SCSI] fix shared...
667
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668

db5ed4dfd   Christoph Hellwig   scsi: drop reason...
669
670
  	sdev->queue_depth = depth;
  out_unlock:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
671
  	spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
db5ed4dfd   Christoph Hellwig   scsi: drop reason...
672
673
  out:
  	return sdev->queue_depth;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
  }
db5ed4dfd   Christoph Hellwig   scsi: drop reason...
675
  EXPORT_SYMBOL(scsi_change_queue_depth);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
676

eb44820c2   Rob Landley   [SCSI] Add Docume...
677
678
679
680
681
  /**
   * scsi_track_queue_full - track QUEUE_FULL events to adjust queue depth
   * @sdev: SCSI Device in question
   * @depth: Current number of outstanding SCSI commands on this device,
   *         not counting the one returned as QUEUE_FULL.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
682
   *
eb44820c2   Rob Landley   [SCSI] Add Docume...
683
   * Description:	This function will track successive QUEUE_FULL events on a
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
684
685
686
   * 		specific SCSI device to determine if and when there is a
   * 		need to adjust the queue depth on the device.
   *
eb44820c2   Rob Landley   [SCSI] Add Docume...
687
   * Returns:	0 - No change needed, >0 - Adjust queue depth to this new depth,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
688
689
690
691
692
693
694
695
696
697
   * 		-1 - Drop back to untagged operation using host->cmd_per_lun
   * 			as the untagged command depth
   *
   * Lock Status:	None held on entry
   *
   * Notes:	Low level drivers may call this at any time and we will do
   * 		"The Right Thing."  We are interrupt context safe.
   */
  int scsi_track_queue_full(struct scsi_device *sdev, int depth)
  {
4a84067db   Vasu Dev   [SCSI] add queue_...
698
699
700
701
702
703
704
  
  	/*
  	 * Don't let QUEUE_FULLs on the same
  	 * jiffies count, they could all be from
  	 * same event.
  	 */
  	if ((jiffies >> 4) == (sdev->last_queue_full_time >> 4))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
705
  		return 0;
4a84067db   Vasu Dev   [SCSI] add queue_...
706
  	sdev->last_queue_full_time = jiffies;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
707
708
709
710
711
712
713
714
715
  	if (sdev->last_queue_full_depth != depth) {
  		sdev->last_queue_full_count = 1;
  		sdev->last_queue_full_depth = depth;
  	} else {
  		sdev->last_queue_full_count++;
  	}
  
  	if (sdev->last_queue_full_count <= 10)
  		return 0;
609aa22f3   Christoph Hellwig   scsi: remove orde...
716

db5ed4dfd   Christoph Hellwig   scsi: drop reason...
717
  	return scsi_change_queue_depth(sdev, depth);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
718
719
720
721
  }
  EXPORT_SYMBOL(scsi_track_queue_full);
  
  /**
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
722
723
724
725
726
727
728
729
730
   * scsi_vpd_inquiry - Request a device provide us with a VPD page
   * @sdev: The device to ask
   * @buffer: Where to put the result
   * @page: Which Vital Product Data to return
   * @len: The length of the buffer
   *
   * This is an internal helper function.  You probably want to use
   * scsi_get_vpd_page instead.
   *
bc8945df3   Hannes Reinecke   [SCSI] Return VPD...
731
   * Returns size of the vpd page on success or a negative error number.
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
732
733
734
735
736
737
   */
  static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
  							u8 page, unsigned len)
  {
  	int result;
  	unsigned char cmd[16];
bc8945df3   Hannes Reinecke   [SCSI] Return VPD...
738
739
  	if (len < 4)
  		return -EINVAL;
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
740
741
742
743
744
745
746
747
748
749
750
751
  	cmd[0] = INQUIRY;
  	cmd[1] = 1;		/* EVPD */
  	cmd[2] = page;
  	cmd[3] = len >> 8;
  	cmd[4] = len & 0xff;
  	cmd[5] = 0;		/* Control byte */
  
  	/*
  	 * I'm not convinced we need to try quite this hard to get VPD, but
  	 * all the existing users tried this hard.
  	 */
  	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
95a3639e2   James Bottomley   [SCSI] fix bugs i...
752
  				  len, NULL, 30 * HZ, 3, NULL);
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
753
  	if (result)
bc8945df3   Hannes Reinecke   [SCSI] Return VPD...
754
  		return -EIO;
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
755
756
757
758
  
  	/* Sanity check that we got the page back that we asked for */
  	if (buffer[1] != page)
  		return -EIO;
bc8945df3   Hannes Reinecke   [SCSI] Return VPD...
759
  	return get_unaligned_be16(&buffer[2]) + 4;
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
760
761
762
763
764
765
  }
  
  /**
   * scsi_get_vpd_page - Get Vital Product Data from a SCSI device
   * @sdev: The device to ask
   * @page: Which Vital Product Data to return
786f8ba2e   Randy Dunlap   scsi.c: add missi...
766
767
   * @buf: where to store the VPD
   * @buf_len: number of bytes in the VPD buffer area
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
768
769
770
771
772
773
774
775
   *
   * SCSI devices may optionally supply Vital Product Data.  Each 'page'
   * of VPD is defined in the appropriate SCSI document (eg SPC, SBC).
   * If the device supports this VPD page, this routine returns a pointer
   * to a buffer containing the data from that page.  The caller is
   * responsible for calling kfree() on this pointer when it is no longer
   * needed.  If we cannot retrieve the VPD page this routine returns %NULL.
   */
e3deec090   James Bottomley   [SCSI] eliminate ...
776
777
  int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf,
  		      int buf_len)
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
778
779
  {
  	int i, result;
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
780

7562523e8   Martin K. Petersen   [SCSI] Don't atte...
781
782
  	if (sdev->skip_vpd_pages)
  		goto fail;
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
783
  	/* Ask for all the pages supported by this device */
e3deec090   James Bottomley   [SCSI] eliminate ...
784
  	result = scsi_vpd_inquiry(sdev, buf, 0, buf_len);
bc8945df3   Hannes Reinecke   [SCSI] Return VPD...
785
  	if (result < 4)
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
786
787
788
789
  		goto fail;
  
  	/* If the user actually wanted this page, we can skip the rest */
  	if (page == 0)
16d3ea26f   Martin K. Petersen   [SCSI] Fix VPD in...
790
  		return 0;
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
791

bc8945df3   Hannes Reinecke   [SCSI] Return VPD...
792
793
  	for (i = 4; i < min(result, buf_len); i++)
  		if (buf[i] == page)
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
794
  			goto found;
e3deec090   James Bottomley   [SCSI] eliminate ...
795

bc8945df3   Hannes Reinecke   [SCSI] Return VPD...
796
  	if (i < result && i >= buf_len)
e3deec090   James Bottomley   [SCSI] eliminate ...
797
798
  		/* ran off the end of the buffer, give us benefit of doubt */
  		goto found;
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
799
800
801
802
  	/* The device claims it doesn't support the requested page */
  	goto fail;
  
   found:
e3deec090   James Bottomley   [SCSI] eliminate ...
803
  	result = scsi_vpd_inquiry(sdev, buf, page, buf_len);
bc8945df3   Hannes Reinecke   [SCSI] Return VPD...
804
  	if (result < 0)
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
805
  		goto fail;
e3deec090   James Bottomley   [SCSI] eliminate ...
806
  	return 0;
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
807
808
  
   fail:
e3deec090   James Bottomley   [SCSI] eliminate ...
809
  	return -EINVAL;
881a256d8   Matthew Wilcox   [SCSI] Add VPD he...
810
811
812
813
  }
  EXPORT_SYMBOL_GPL(scsi_get_vpd_page);
  
  /**
b3ae8780b   Hannes Reinecke   [SCSI] Add EVPD p...
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
   * scsi_attach_vpd - Attach Vital Product Data to a SCSI device structure
   * @sdev: The device to ask
   *
   * Attach the 'Device Identification' VPD page (0x83) and the
   * 'Unit Serial Number' VPD page (0x80) to a SCSI device
   * structure. This information can be used to identify the device
   * uniquely.
   */
  void scsi_attach_vpd(struct scsi_device *sdev)
  {
  	int result, i;
  	int vpd_len = SCSI_VPD_PG_LEN;
  	int pg80_supported = 0;
  	int pg83_supported = 0;
  	unsigned char *vpd_buf;
  
  	if (sdev->skip_vpd_pages)
  		return;
  retry_pg0:
  	vpd_buf = kmalloc(vpd_len, GFP_KERNEL);
  	if (!vpd_buf)
  		return;
  
  	/* Ask for all the pages supported by this device */
  	result = scsi_vpd_inquiry(sdev, vpd_buf, 0, vpd_len);
  	if (result < 0) {
  		kfree(vpd_buf);
  		return;
  	}
  	if (result > vpd_len) {
  		vpd_len = result;
  		kfree(vpd_buf);
  		goto retry_pg0;
  	}
  
  	for (i = 4; i < result; i++) {
  		if (vpd_buf[i] == 0x80)
  			pg80_supported = 1;
  		if (vpd_buf[i] == 0x83)
  			pg83_supported = 1;
  	}
  	kfree(vpd_buf);
  	vpd_len = SCSI_VPD_PG_LEN;
  
  	if (pg80_supported) {
  retry_pg80:
  		vpd_buf = kmalloc(vpd_len, GFP_KERNEL);
  		if (!vpd_buf)
  			return;
  
  		result = scsi_vpd_inquiry(sdev, vpd_buf, 0x80, vpd_len);
  		if (result < 0) {
  			kfree(vpd_buf);
  			return;
  		}
  		if (result > vpd_len) {
  			vpd_len = result;
  			kfree(vpd_buf);
  			goto retry_pg80;
  		}
  		sdev->vpd_pg80_len = result;
  		sdev->vpd_pg80 = vpd_buf;
  		vpd_len = SCSI_VPD_PG_LEN;
  	}
  
  	if (pg83_supported) {
  retry_pg83:
  		vpd_buf = kmalloc(vpd_len, GFP_KERNEL);
  		if (!vpd_buf)
  			return;
  
  		result = scsi_vpd_inquiry(sdev, vpd_buf, 0x83, vpd_len);
  		if (result < 0) {
  			kfree(vpd_buf);
  			return;
  		}
  		if (result > vpd_len) {
  			vpd_len = result;
  			kfree(vpd_buf);
  			goto retry_pg83;
  		}
  		sdev->vpd_pg83_len = result;
  		sdev->vpd_pg83 = vpd_buf;
  	}
  }
  
  /**
3c6bdaeab   Martin K. Petersen   [SCSI] Add a repo...
901
902
903
904
905
906
907
   * scsi_report_opcode - Find out if a given command opcode is supported
   * @sdev:	scsi device to query
   * @buffer:	scratch buffer (must be at least 20 bytes long)
   * @len:	length of buffer
   * @opcode:	opcode for command to look up
   *
   * Uses the REPORT SUPPORTED OPERATION CODES to look up the given
66c28f971   Martin K. Petersen   [SCSI] sd: Update...
908
909
   * opcode. Returns -EINVAL if RSOC fails, 0 if the command opcode is
   * unsupported and 1 if the device claims to support the command.
3c6bdaeab   Martin K. Petersen   [SCSI] Add a repo...
910
911
912
913
914
915
916
917
918
   */
  int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
  		       unsigned int len, unsigned char opcode)
  {
  	unsigned char cmd[16];
  	struct scsi_sense_hdr sshdr;
  	int result;
  
  	if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3)
66c28f971   Martin K. Petersen   [SCSI] sd: Update...
919
  		return -EINVAL;
3c6bdaeab   Martin K. Petersen   [SCSI] Add a repo...
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
  
  	memset(cmd, 0, 16);
  	cmd[0] = MAINTENANCE_IN;
  	cmd[1] = MI_REPORT_SUPPORTED_OPERATION_CODES;
  	cmd[2] = 1;		/* One command format */
  	cmd[3] = opcode;
  	put_unaligned_be32(len, &cmd[6]);
  	memset(buffer, 0, len);
  
  	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
  				  &sshdr, 30 * HZ, 3, NULL);
  
  	if (result && scsi_sense_valid(&sshdr) &&
  	    sshdr.sense_key == ILLEGAL_REQUEST &&
  	    (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00)
66c28f971   Martin K. Petersen   [SCSI] sd: Update...
935
  		return -EINVAL;
3c6bdaeab   Martin K. Petersen   [SCSI] Add a repo...
936
937
938
939
940
941
942
943
944
  
  	if ((buffer[1] & 3) == 3) /* Command supported */
  		return 1;
  
  	return 0;
  }
  EXPORT_SYMBOL(scsi_report_opcode);
  
  /**
eb44820c2   Rob Landley   [SCSI] Add Docume...
945
   * scsi_device_get  -  get an additional reference to a scsi_device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
946
947
   * @sdev:	device to get a reference to
   *
eb44820c2   Rob Landley   [SCSI] Add Docume...
948
   * Description: Gets a reference to the scsi_device and increments the use count
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
949
950
951
952
953
   * of the underlying LLDD module.  You must hold host_lock of the
   * parent Scsi_Host or already have a reference when calling this.
   */
  int scsi_device_get(struct scsi_device *sdev)
  {
85b6c720b   James Bottomley   [SCSI] sd: fix ca...
954
  	if (sdev->sdev_state == SDEV_DEL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
955
956
957
  		return -ENXIO;
  	if (!get_device(&sdev->sdev_gendev))
  		return -ENXIO;
dc4515ea2   Rusty Russell   scsi: always incr...
958
  	/* We can fail try_module_get if we're doing SCSI operations
85b6c720b   James Bottomley   [SCSI] sd: fix ca...
959
  	 * from module exit (like cache flush) */
dc4515ea2   Rusty Russell   scsi: always incr...
960
  	__module_get(sdev->host->hostt->module);
85b6c720b   James Bottomley   [SCSI] sd: fix ca...
961

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
962
963
964
965
966
967
968
969
  	return 0;
  }
  EXPORT_SYMBOL(scsi_device_get);
  
  /**
   * scsi_device_put  -  release a reference to a scsi_device
   * @sdev:	device to release a reference on.
   *
eb44820c2   Rob Landley   [SCSI] Add Docume...
970
971
   * Description: Release a reference to the scsi_device and decrements the use
   * count of the underlying LLDD module.  The device is freed once the last
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
972
973
974
975
   * user vanishes.
   */
  void scsi_device_put(struct scsi_device *sdev)
  {
dc4515ea2   Rusty Russell   scsi: always incr...
976
  	module_put(sdev->host->hostt->module);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
977
978
979
  	put_device(&sdev->sdev_gendev);
  }
  EXPORT_SYMBOL(scsi_device_put);
eb44820c2   Rob Landley   [SCSI] Add Docume...
980
  /* helper for shost_for_each_device, see that for documentation */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
  struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *shost,
  					   struct scsi_device *prev)
  {
  	struct list_head *list = (prev ? &prev->siblings : &shost->__devices);
  	struct scsi_device *next = NULL;
  	unsigned long flags;
  
  	spin_lock_irqsave(shost->host_lock, flags);
  	while (list->next != &shost->__devices) {
  		next = list_entry(list->next, struct scsi_device, siblings);
  		/* skip devices that we can't get a reference to */
  		if (!scsi_device_get(next))
  			break;
  		next = NULL;
  		list = list->next;
  	}
  	spin_unlock_irqrestore(shost->host_lock, flags);
  
  	if (prev)
  		scsi_device_put(prev);
  	return next;
  }
  EXPORT_SYMBOL(__scsi_iterate_devices);
  
  /**
   * starget_for_each_device  -  helper to walk all devices of a target
   * @starget:	target whose devices we want to iterate over.
eb44820c2   Rob Landley   [SCSI] Add Docume...
1008
1009
   * @data:	Opaque passed to each function call.
   * @fn:		Function to call on each device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1010
   *
522939d45   Maciej W. Rozycki   esp_scsi: fix res...
1011
   * This traverses over each device of @starget.  The devices have
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1012
1013
1014
   * a reference that must be released by scsi_host_put when breaking
   * out of the loop.
   */
522939d45   Maciej W. Rozycki   esp_scsi: fix res...
1015
  void starget_for_each_device(struct scsi_target *starget, void *data,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
  		     void (*fn)(struct scsi_device *, void *))
  {
  	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
  	struct scsi_device *sdev;
  
  	shost_for_each_device(sdev, shost) {
  		if ((sdev->channel == starget->channel) &&
  		    (sdev->id == starget->id))
  			fn(sdev, data);
  	}
  }
  EXPORT_SYMBOL(starget_for_each_device);
  
  /**
14f501a4b   Randy Dunlap   [SCSI] kernel-doc...
1030
   * __starget_for_each_device - helper to walk all devices of a target (UNLOCKED)
522939d45   Maciej W. Rozycki   esp_scsi: fix res...
1031
   * @starget:	target whose devices we want to iterate over.
14f501a4b   Randy Dunlap   [SCSI] kernel-doc...
1032
1033
   * @data:	parameter for callback @fn()
   * @fn:		callback function that is invoked for each device
522939d45   Maciej W. Rozycki   esp_scsi: fix res...
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
   *
   * This traverses over each device of @starget.  It does _not_
   * take a reference on the scsi_device, so the whole loop must be
   * protected by shost->host_lock.
   *
   * Note:  The only reason why drivers would want to use this is because
   * they need to access the device list in irq context.  Otherwise you
   * really want to use starget_for_each_device instead.
   **/
  void __starget_for_each_device(struct scsi_target *starget, void *data,
  			       void (*fn)(struct scsi_device *, void *))
  {
  	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
  	struct scsi_device *sdev;
  
  	__shost_for_each_device(sdev, shost) {
  		if ((sdev->channel == starget->channel) &&
  		    (sdev->id == starget->id))
  			fn(sdev, data);
  	}
  }
  EXPORT_SYMBOL(__starget_for_each_device);
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1058
1059
1060
1061
   * __scsi_device_lookup_by_target - find a device given the target (UNLOCKED)
   * @starget:	SCSI target pointer
   * @lun:	SCSI Logical Unit Number
   *
eb44820c2   Rob Landley   [SCSI] Add Docume...
1062
1063
   * Description: Looks up the scsi_device with the specified @lun for a given
   * @starget.  The returned scsi_device does not have an additional
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1064
   * reference.  You must hold the host's host_lock over this call and
32aeef605   Hannes Reinecke   [SCSI] Skip delet...
1065
1066
   * any access to the returned scsi_device. A scsi_device in state
   * SDEV_DEL is skipped.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1067
   *
dc8875e10   Randy Dunlap   [SCSI] docbook an...
1068
   * Note:  The only reason why drivers should use this is because
eb44820c2   Rob Landley   [SCSI] Add Docume...
1069
   * they need to access the device list in irq context.  Otherwise you
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1070
1071
1072
   * really want to use scsi_device_lookup_by_target instead.
   **/
  struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *starget,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1073
  						   u64 lun)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1074
1075
1076
1077
  {
  	struct scsi_device *sdev;
  
  	list_for_each_entry(sdev, &starget->devices, same_target_siblings) {
32aeef605   Hannes Reinecke   [SCSI] Skip delet...
1078
1079
  		if (sdev->sdev_state == SDEV_DEL)
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
  		if (sdev->lun ==lun)
  			return sdev;
  	}
  
  	return NULL;
  }
  EXPORT_SYMBOL(__scsi_device_lookup_by_target);
  
  /**
   * scsi_device_lookup_by_target - find a device given the target
   * @starget:	SCSI target pointer
   * @lun:	SCSI Logical Unit Number
   *
477e608c0   Bartlomiej Zolnierkiewicz   [SCSI] fix docume...
1093
1094
   * Description: Looks up the scsi_device with the specified @lun for a given
   * @starget.  The returned scsi_device has an additional reference that
eb44820c2   Rob Landley   [SCSI] Add Docume...
1095
   * needs to be released with scsi_device_put once you're done with it.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1096
1097
   **/
  struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *starget,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1098
  						 u64 lun)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
  {
  	struct scsi_device *sdev;
  	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
  	unsigned long flags;
  
  	spin_lock_irqsave(shost->host_lock, flags);
  	sdev = __scsi_device_lookup_by_target(starget, lun);
  	if (sdev && scsi_device_get(sdev))
  		sdev = NULL;
  	spin_unlock_irqrestore(shost->host_lock, flags);
  
  	return sdev;
  }
  EXPORT_SYMBOL(scsi_device_lookup_by_target);
  
  /**
eb44820c2   Rob Landley   [SCSI] Add Docume...
1115
   * __scsi_device_lookup - find a device given the host (UNLOCKED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1116
1117
   * @shost:	SCSI host pointer
   * @channel:	SCSI channel (zero if only one channel)
eb44820c2   Rob Landley   [SCSI] Add Docume...
1118
   * @id:		SCSI target number (physical unit number)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1119
1120
   * @lun:	SCSI Logical Unit Number
   *
eb44820c2   Rob Landley   [SCSI] Add Docume...
1121
1122
1123
1124
   * Description: Looks up the scsi_device with the specified @channel, @id, @lun
   * for a given host. The returned scsi_device does not have an additional
   * reference.  You must hold the host's host_lock over this call and any access
   * to the returned scsi_device.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1125
1126
   *
   * Note:  The only reason why drivers would want to use this is because
eb44820c2   Rob Landley   [SCSI] Add Docume...
1127
   * they need to access the device list in irq context.  Otherwise you
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1128
1129
1130
   * really want to use scsi_device_lookup instead.
   **/
  struct scsi_device *__scsi_device_lookup(struct Scsi_Host *shost,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1131
  		uint channel, uint id, u64 lun)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
  {
  	struct scsi_device *sdev;
  
  	list_for_each_entry(sdev, &shost->__devices, siblings) {
  		if (sdev->channel == channel && sdev->id == id &&
  				sdev->lun ==lun)
  			return sdev;
  	}
  
  	return NULL;
  }
  EXPORT_SYMBOL(__scsi_device_lookup);
  
  /**
   * scsi_device_lookup - find a device given the host
   * @shost:	SCSI host pointer
   * @channel:	SCSI channel (zero if only one channel)
   * @id:		SCSI target number (physical unit number)
   * @lun:	SCSI Logical Unit Number
   *
eb44820c2   Rob Landley   [SCSI] Add Docume...
1152
1153
1154
   * Description: Looks up the scsi_device with the specified @channel, @id, @lun
   * for a given host.  The returned scsi_device has an additional reference that
   * needs to be released with scsi_device_put once you're done with it.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1155
1156
   **/
  struct scsi_device *scsi_device_lookup(struct Scsi_Host *shost,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1157
  		uint channel, uint id, u64 lun)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
  {
  	struct scsi_device *sdev;
  	unsigned long flags;
  
  	spin_lock_irqsave(shost->host_lock, flags);
  	sdev = __scsi_device_lookup(shost, channel, id, lun);
  	if (sdev && scsi_device_get(sdev))
  		sdev = NULL;
  	spin_unlock_irqrestore(shost->host_lock, flags);
  
  	return sdev;
  }
  EXPORT_SYMBOL(scsi_device_lookup);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1171
1172
1173
1174
1175
  MODULE_DESCRIPTION("SCSI core");
  MODULE_LICENSE("GPL");
  
  module_param(scsi_logging_level, int, S_IRUGO|S_IWUSR);
  MODULE_PARM_DESC(scsi_logging_level, "a bit mask of logging levels");
24c20f105   Christoph Hellwig   scsi: add a CONFI...
1176
1177
1178
  #ifdef CONFIG_SCSI_MQ_DEFAULT
  bool scsi_use_blk_mq = true;
  #else
d285203cf   Christoph Hellwig   scsi: add support...
1179
  bool scsi_use_blk_mq = false;
24c20f105   Christoph Hellwig   scsi: add a CONFI...
1180
  #endif
d285203cf   Christoph Hellwig   scsi: add support...
1181
  module_param_named(use_blk_mq, scsi_use_blk_mq, bool, S_IWUSR | S_IRUGO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1182
1183
  static int __init init_scsi(void)
  {
9bf09c238   Jens Axboe   [PATCH] SCSI: scs...
1184
  	int error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
  
  	error = scsi_init_queue();
  	if (error)
  		return error;
  	error = scsi_init_procfs();
  	if (error)
  		goto cleanup_queue;
  	error = scsi_init_devinfo();
  	if (error)
  		goto cleanup_procfs;
  	error = scsi_init_hosts();
  	if (error)
  		goto cleanup_devlist;
  	error = scsi_init_sysctl();
  	if (error)
  		goto cleanup_hosts;
  	error = scsi_sysfs_register();
  	if (error)
  		goto cleanup_sysctl;
84314fd47   James Smart   [SCSI] SCSI and F...
1204
  	scsi_netlink_init();
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
1222
1223
1224
1225
1226
  	printk(KERN_NOTICE "SCSI subsystem initialized
  ");
  	return 0;
  
  cleanup_sysctl:
  	scsi_exit_sysctl();
  cleanup_hosts:
  	scsi_exit_hosts();
  cleanup_devlist:
  	scsi_exit_devinfo();
  cleanup_procfs:
  	scsi_exit_procfs();
  cleanup_queue:
  	scsi_exit_queue();
  	printk(KERN_ERR "SCSI subsystem failed to initialize, error = %d
  ",
  	       -error);
  	return error;
  }
  
  static void __exit exit_scsi(void)
  {
84314fd47   James Smart   [SCSI] SCSI and F...
1227
  	scsi_netlink_exit();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1228
1229
1230
1231
  	scsi_sysfs_unregister();
  	scsi_exit_sysctl();
  	scsi_exit_hosts();
  	scsi_exit_devinfo();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1232
1233
  	scsi_exit_procfs();
  	scsi_exit_queue();
a4683487f   Dan Williams   [SCSI] async: mak...
1234
  	async_unregister_domain(&scsi_sd_probe_domain);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1235
1236
1237
1238
  }
  
  subsys_initcall(init_scsi);
  module_exit(exit_scsi);