Blame view

include/scsi/scsi_device.h 12.9 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
  #ifndef _SCSI_SCSI_DEVICE_H
  #define _SCSI_SCSI_DEVICE_H
  
  #include <linux/device.h>
  #include <linux/list.h>
  #include <linux/spinlock.h>
ffedb4522   James Bottomley   [SCSI] fix scsi p...
7
  #include <linux/workqueue.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
  #include <asm/atomic.h>
  
  struct request_queue;
  struct scsi_cmnd;
e10fb91c4   James Bottomley   [SCSI] fix functi...
12
  struct scsi_lun;
ea73a9f23   James Bottomley   [SCSI] convert sd...
13
  struct scsi_sense_hdr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14

1cf72699c   James Bottomley   [SCSI] convert th...
15
16
17
18
19
20
21
22
  struct scsi_mode_data {
  	__u32	length;
  	__u16	block_descriptor_length;
  	__u8	medium_type;
  	__u8	device_specific;
  	__u8	header_length;
  	__u8	longlba:1;
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
  /*
   * sdev state: If you alter this, you also need to alter scsi_sysfs.c
   * (for the ascii descriptions) and the state model enforcer:
   * scsi_lib:scsi_device_set_state().
   */
  enum scsi_device_state {
  	SDEV_CREATED = 1,	/* device created but not added to sysfs
  				 * Only internal commands allowed (for inq) */
  	SDEV_RUNNING,		/* device properly configured
  				 * All commands allowed */
  	SDEV_CANCEL,		/* beginning to delete device
  				 * Only error handler commands allowed */
  	SDEV_DEL,		/* device deleted 
  				 * no commands allowed */
  	SDEV_QUIESCE,		/* Device quiescent.  No block commands
  				 * will be accepted, only specials (which
  				 * originate in the mid-layer) */
  	SDEV_OFFLINE,		/* Device offlined (by error handling or
  				 * user request */
  	SDEV_BLOCK,		/* Device blocked by scsi lld.  No scsi 
  				 * commands from user or midlayer should be issued
  				 * to the scsi lld. */
  };
  
  struct scsi_device {
  	struct Scsi_Host *host;
  	struct request_queue *request_queue;
  
  	/* the next two are protected by the host->host_lock */
  	struct list_head    siblings;   /* list of all devices on this host */
  	struct list_head    same_target_siblings; /* just the devices sharing same target id */
c2a9331c6   James Bottomley   updates for CFQ o...
54
  	/* this is now protected by the request_queue->queue_lock */
06f81ea8c   Tejun Heo   [PATCH] scsi: rem...
55
56
  	unsigned int device_busy;	/* commands actually active on
  					 * low-level. protected by queue_lock. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
  	spinlock_t list_lock;
  	struct list_head cmd_list;	/* queue of in use SCSI Command structures */
  	struct list_head starved_entry;
  	struct scsi_cmnd *current_cmnd;	/* currently active command */
  	unsigned short queue_depth;	/* How deep of a queue we want */
  	unsigned short last_queue_full_depth; /* These two are used by */
  	unsigned short last_queue_full_count; /* scsi_track_queue_full() */
  	unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same
  					   jiffie count on our counter, they
  					   could all be from the same event. */
  
  	unsigned int id, lun, channel;
  
  	unsigned int manufacturer;	/* Manufacturer of device, for using 
  					 * vendor-specific cmd's */
  	unsigned sector_size;	/* size in bytes */
  
  	void *hostdata;		/* available to low-level driver */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
76
77
78
79
  	char type;
  	char scsi_level;
  	char inq_periph_qual;	/* PQ from INQUIRY data */	
  	unsigned char inquiry_len;	/* valid bytes in 'inquiry' */
  	unsigned char * inquiry;	/* INQUIRY response data */
7f23e146a   James Bottomley   [SCSI] correct so...
80
81
82
  	const char * vendor;		/* [back_compat] point into 'inquiry' ... */
  	const char * model;		/* ... after scan; point to static string */
  	const char * rev;		/* ... "nullnullnullnull" before scan */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
  	unsigned char current_tag;	/* current tag */
  	struct scsi_target      *sdev_target;   /* used only for single_lun */
  
  	unsigned int	sdev_bflags; /* black/white flags as also found in
  				 * scsi_devinfo.[hc]. For now used only to
  				 * pass settings from slave_alloc to scsi
  				 * core. */
  	unsigned writeable:1;
  	unsigned removable:1;
  	unsigned changed:1;	/* Data invalid due to media change */
  	unsigned busy:1;	/* Used to prevent races */
  	unsigned lockable:1;	/* Able to prevent media removal */
  	unsigned locked:1;      /* Media removal disabled */
  	unsigned borken:1;	/* Tell the Seagate driver to be 
  				 * painfully slow on this device */
  	unsigned disconnect:1;	/* can disconnect */
  	unsigned soft_reset:1;	/* Uses soft reset option */
  	unsigned sdtr:1;	/* Device supports SDTR messages */
  	unsigned wdtr:1;	/* Device supports WDTR messages */
  	unsigned ppr:1;		/* Device supports PPR messages */
  	unsigned tagged_supported:1;	/* Supports SCSI-II tagged queuing */
  	unsigned simple_tags:1;	/* simple queue tag messages are enabled */
  	unsigned ordered_tags:1;/* ordered queue tag messages are enabled */
  	unsigned single_lun:1;	/* Indicates we should only allow I/O to
  				 * one of the luns for the device at a 
  				 * time. */
  	unsigned was_reset:1;	/* There was a bus reset on the bus for 
  				 * this device */
  	unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN
  				     * because we did a bus reset. */
  	unsigned use_10_for_rw:1; /* first try 10-byte read / write */
  	unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
  	unsigned skip_ms_page_8:1;	/* do not use MODE SENSE page 0x08 */
  	unsigned skip_ms_page_3f:1;	/* do not use MODE SENSE page 0x3f */
  	unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */
  	unsigned no_start_on_add:1;	/* do not issue start on add */
  	unsigned allow_restart:1; /* issue START_UNIT in error handler */
  	unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
  	unsigned select_no_atn:1;
  	unsigned fix_capacity:1;	/* READ_CAPACITY is too high by 1 */
  	unsigned retry_hwerror:1;	/* Retry HARDWARE_ERROR */
  
  	unsigned int device_blocked;	/* Device returned QUEUE_FULL. */
  
  	unsigned int max_device_blocked; /* what device_blocked counts down from  */
  #define SCSI_DEFAULT_DEVICE_BLOCKED	3
  
  	atomic_t iorequest_cnt;
  	atomic_t iodone_cnt;
  	atomic_t ioerr_cnt;
  
  	int timeout;
  
  	struct device		sdev_gendev;
  	struct class_device	sdev_classdev;
ffedb4522   James Bottomley   [SCSI] fix scsi p...
138
  	struct execute_work	ew; /* used to get process context on put */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
141
142
143
144
145
146
147
  	enum scsi_device_state sdev_state;
  	unsigned long		sdev_data[0];
  } __attribute__((aligned(sizeof(unsigned long))));
  #define	to_scsi_device(d)	\
  	container_of(d, struct scsi_device, sdev_gendev)
  #define	class_to_sdev(d)	\
  	container_of(d, struct scsi_device, sdev_classdev)
  #define transport_class_to_sdev(class_dev) \
  	to_scsi_device(class_dev->dev)
9ccfc756a   James Bottomley   [SCSI] move the m...
148
149
  #define sdev_printk(prefix, sdev, fmt, a...)	\
  	dev_printk(prefix, &(sdev)->sdev_gendev, fmt, ##a)
01d7b3b8d   Jeff Garzik   [SCSI] introduce ...
150
151
  #define scmd_printk(prefix, scmd, fmt, a...)	\
  	dev_printk(prefix, &(scmd)->device->sdev_gendev, fmt, ##a)
ffedb4522   James Bottomley   [SCSI] fix scsi p...
152
153
154
155
  enum scsi_target_state {
  	STARGET_RUNNING = 1,
  	STARGET_DEL,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
158
159
160
161
162
163
164
165
166
167
168
169
  /*
   * scsi_target: representation of a scsi target, for now, this is only
   * used for single_lun devices. If no one has active IO to the target,
   * starget_sdev_user is NULL, else it points to the active sdev.
   */
  struct scsi_target {
  	struct scsi_device	*starget_sdev_user;
  	struct list_head	siblings;
  	struct list_head	devices;
  	struct device		dev;
  	unsigned int		reap_ref; /* protected by the host lock */
  	unsigned int		channel;
  	unsigned int		id; /* target id ... replace
  				     * scsi_device.id eventually */
1bfc5d9d5   Alan Stern   [SCSI] Recognize ...
170
171
172
  	unsigned int		create:1; /* signal that it needs to be added */
  	unsigned int		pdt_1f_for_no_lun;	/* PDT = 0x1f */
  						/* means no lun present */
6f3a20242   James Bottomley   [SCSI] allow REPO...
173
  	char			scsi_level;
ffedb4522   James Bottomley   [SCSI] fix scsi p...
174
175
  	struct execute_work	ew;
  	enum scsi_target_state	state;
a283bd37d   James Bottomley   [SCSI] Add target...
176
177
178
  	void 			*hostdata; /* available to low-level driver */
  	unsigned long		starget_data[0]; /* for the transport */
  	/* starget_data must be the last element!!!! */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
180
181
182
183
184
185
186
187
  } __attribute__((aligned(sizeof(unsigned long))));
  
  #define to_scsi_target(d)	container_of(d, struct scsi_target, dev)
  static inline struct scsi_target *scsi_target(struct scsi_device *sdev)
  {
  	return to_scsi_target(sdev->sdev_gendev.parent);
  }
  #define transport_class_to_starget(class_dev) \
  	to_scsi_target(class_dev->dev)
9ccfc756a   James Bottomley   [SCSI] move the m...
188
189
  #define starget_printk(prefix, starget, fmt, a...)	\
  	dev_printk(prefix, &(starget)->dev, fmt, ##a)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
191
  extern struct scsi_device *__scsi_add_device(struct Scsi_Host *,
  		uint, uint, uint, void *hostdata);
146f7262e   James Bottomley   [SCSI] Alter the ...
192
193
  extern int scsi_add_device(struct Scsi_Host *host, uint channel,
  			   uint target, uint lun);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
  extern void scsi_remove_device(struct scsi_device *);
  extern int scsi_device_cancel(struct scsi_device *, int);
  
  extern int scsi_device_get(struct scsi_device *);
  extern void scsi_device_put(struct scsi_device *);
  extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *,
  					      uint, uint, uint);
  extern struct scsi_device *__scsi_device_lookup(struct Scsi_Host *,
  						uint, uint, uint);
  extern struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *,
  							uint);
  extern struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *,
  							  uint);
  extern void starget_for_each_device(struct scsi_target *, void *,
  		     void (*fn)(struct scsi_device *, void *));
  
  /* only exposed to implement shost_for_each_device */
  extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *,
  						  struct scsi_device *);
  
  /**
   * shost_for_each_device  -  iterate over all devices of a host
   * @sdev:	iterator
   * @host:	host whiches devices we want to iterate over
   *
   * This traverses over each devices of @shost.  The devices have
   * a reference that must be released by scsi_host_put when breaking
   * out of the loop.
   */
  #define shost_for_each_device(sdev, shost) \
  	for ((sdev) = __scsi_iterate_devices((shost), NULL); \
  	     (sdev); \
  	     (sdev) = __scsi_iterate_devices((shost), (sdev)))
  
  /**
   * __shost_for_each_device  -  iterate over all devices of a host (UNLOCKED)
   * @sdev:	iterator
   * @host:	host whiches devices we want to iterate over
   *
   * This traverses over each devices of @shost.  It does _not_ take a
   * reference on the scsi_device, thus it the whole loop must be protected
   * by shost->host_lock.
   *
   * Note:  The only reason why drivers would want to use this is because
   * they're need to access the device list in irq context.  Otherwise you
   * really want to use shost_for_each_device instead.
   */
  #define __shost_for_each_device(sdev, shost) \
  	list_for_each_entry((sdev), &((shost)->__devices), siblings)
  
  extern void scsi_adjust_queue_depth(struct scsi_device *, int, int);
  extern int scsi_track_queue_full(struct scsi_device *, int);
  
  extern int scsi_set_medium_removal(struct scsi_device *, char);
  
  extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
  			   unsigned char *buffer, int len, int timeout,
1cf72699c   James Bottomley   [SCSI] convert th...
251
  			   int retries, struct scsi_mode_data *data,
ea73a9f23   James Bottomley   [SCSI] convert sd...
252
  			   struct scsi_sense_hdr *);
5baba830e   James Bottomley   [SCSI] add scsi_m...
253
254
255
256
257
  extern int scsi_mode_select(struct scsi_device *sdev, int pf, int sp,
  			    int modepage, unsigned char *buffer, int len,
  			    int timeout, int retries,
  			    struct scsi_mode_data *data,
  			    struct scsi_sense_hdr *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
258
259
260
261
262
263
264
265
266
267
268
269
270
271
  extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout,
  				int retries);
  extern int scsi_device_set_state(struct scsi_device *sdev,
  				 enum scsi_device_state state);
  extern int scsi_device_quiesce(struct scsi_device *sdev);
  extern void scsi_device_resume(struct scsi_device *sdev);
  extern void scsi_target_quiesce(struct scsi_target *);
  extern void scsi_target_resume(struct scsi_target *);
  extern void scsi_scan_target(struct device *parent, unsigned int channel,
  			     unsigned int id, unsigned int lun, int rescan);
  extern void scsi_target_reap(struct scsi_target *);
  extern void scsi_target_block(struct device *);
  extern void scsi_target_unblock(struct device *);
  extern void scsi_remove_target(struct device *);
2f4701d82   James.Smart@Emulex.Com   [SCSI] add int_to...
272
  extern void int_to_scsilun(unsigned int, struct scsi_lun *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
273
274
275
  extern const char *scsi_device_state_name(enum scsi_device_state);
  extern int scsi_is_sdev_device(const struct device *);
  extern int scsi_is_target_device(const struct device *);
33aa687db   James Bottomley   [SCSI] convert SP...
276
277
278
279
  extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
  			int data_direction, void *buffer, unsigned bufflen,
  			unsigned char *sense, int timeout, int retries,
  			int flag);
ea73a9f23   James Bottomley   [SCSI] convert sd...
280
281
282
  extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
  			    int data_direction, void *buffer, unsigned bufflen,
  			    struct scsi_sense_hdr *, int timeout, int retries);
6e68af666   Mike Christie   [SCSI] Convert SC...
283
  extern int scsi_execute_async(struct scsi_device *sdev,
bb1d1073a   Brian King   [SCSI] Prevent sc...
284
  			      const unsigned char *cmd, int cmd_len, int data_direction,
6e68af666   Mike Christie   [SCSI] Convert SC...
285
286
287
288
  			      void *buffer, unsigned bufflen, int use_sg,
  			      int timeout, int retries, void *privdata,
  			      void (*done)(void *, char *, int, int),
  			      gfp_t gfp);
33aa687db   James Bottomley   [SCSI] convert SP...
289

e28482c5b   James Bottomley   [SCSI] add scsi_r...
290
291
292
293
  static inline void scsi_device_reprobe(struct scsi_device *sdev)
  {
  	device_reprobe(&sdev->sdev_gendev);
  }
01d7b3b8d   Jeff Garzik   [SCSI] introduce ...
294
295
296
297
298
299
300
301
302
303
304
305
  static inline unsigned int sdev_channel(struct scsi_device *sdev)
  {
  	return sdev->channel;
  }
  
  static inline unsigned int sdev_id(struct scsi_device *sdev)
  {
  	return sdev->id;
  }
  
  #define scmd_id(scmd) sdev_id((scmd)->device)
  #define scmd_channel(scmd) sdev_channel((scmd)->device)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
  static inline int scsi_device_online(struct scsi_device *sdev)
  {
  	return sdev->sdev_state != SDEV_OFFLINE;
  }
  
  /* accessor functions for the SCSI parameters */
  static inline int scsi_device_sync(struct scsi_device *sdev)
  {
  	return sdev->sdtr;
  }
  static inline int scsi_device_wide(struct scsi_device *sdev)
  {
  	return sdev->wdtr;
  }
  static inline int scsi_device_dt(struct scsi_device *sdev)
  {
  	return sdev->ppr;
  }
  static inline int scsi_device_dt_only(struct scsi_device *sdev)
  {
  	if (sdev->inquiry_len < 57)
  		return 0;
  	return (sdev->inquiry[56] & 0x0c) == 0x04;
  }
  static inline int scsi_device_ius(struct scsi_device *sdev)
  {
  	if (sdev->inquiry_len < 57)
  		return 0;
  	return sdev->inquiry[56] & 0x01;
  }
  static inline int scsi_device_qas(struct scsi_device *sdev)
  {
  	if (sdev->inquiry_len < 57)
  		return 0;
  	return sdev->inquiry[56] & 0x02;
  }
  #endif /* _SCSI_SCSI_DEVICE_H */