8a4355b915c6eeeb6a0a4578f3e1279c49f68f27
[mirror/scst/.git] / scst / src / scst_priv.h
1 /*
2  *  scst_priv.h
3  *  
4  *  Copyright (C) 2004-2006 Vladislav Bolkhovitin <vst@vlnb.net>
5  *                 and Leonid Stoljar
6  *  
7  *  This program is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU General Public License
9  *  as published by the Free Software Foundation, version 2
10  *  of the License.
11  * 
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  *  GNU General Public License for more details.
16  */
17
18 #ifndef __SCST_PRIV_H
19 #define __SCST_PRIV_H
20
21 #include <linux/types.h>
22
23 #include <scsi/scsi.h>
24 #include <scsi/scsi_cmnd.h>
25 #include <scsi/scsi_driver.h>
26 #include <scsi/scsi_device.h>
27 #include <scsi/scsi_request.h>
28 #include <scsi/scsi_host.h>
29
30 #define SCST_MAJOR              177
31
32 #define TRACE_RETRY             0x80000000
33 #define TRACE_SCSI_SERIALIZING  0x40000000
34 #define TRACE_SEND_TOP          0x20000000 /** top being the edge away from the interupt */
35 #define TRACE_RECV_TOP          0x01000000 
36 #define TRACE_SEND_BOT          0x08000000 /** bottom being the edge toward the interupt */
37 #define TRACE_RECV_BOT          0x04000000
38
39 #define LOG_PREFIX "scst"
40
41 #ifdef DEBUG
42 /*#define SCST_DEFAULT_LOG_FLAGS (TRACE_ALL & ~TRACE_MEMORY & ~TRACE_BUFF \
43          & ~TRACE_FUNCTION)
44 #define SCST_DEFAULT_LOG_FLAGS (TRACE_ALL & ~TRACE_MEMORY & ~TRACE_BUFF & \
45         ~TRACE_SCSI & ~TRACE_SCSI_SERIALIZING & ~TRACE_DEBUG)
46 */
47 #define SCST_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_PID | \
48         TRACE_FUNCTION | TRACE_SPECIAL | TRACE_MGMT | TRACE_MGMT_DEBUG | \
49         TRACE_RETRY)
50 #else
51 # ifdef TRACING
52 #define SCST_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_PID | \
53         TRACE_SPECIAL)
54 # else
55 #define SCST_DEFAULT_LOG_FLAGS 0
56 # endif
57 #endif
58
59 /**
60  ** Bits for scst_flags 
61  **/
62
63 /* Set if new commands initialization should be suspended for a while */
64 #define SCST_FLAG_SUSPENDED                  0
65
66 /*
67  * If set, SCST's threads exit immediately not performing any
68  * sessions' shutdown tasks, therefore at this point all the sessions
69  * must be already down.
70  */
71 #define SCST_FLAG_SHUTDOWN                   1
72
73 /* Set if a TM command is being performed */
74 #define SCST_FLAG_TM_ACTIVE                  2
75
76 /** 
77  ** Return codes for cmd state process functions 
78  **/
79 #define SCST_CMD_STATE_RES_CONT_SAME         0
80 #define SCST_CMD_STATE_RES_CONT_NEXT         1
81 #define SCST_CMD_STATE_RES_NEED_THREAD       2
82 #define SCST_CMD_STATE_RES_RESTART           3
83
84 /** Name of the "default" security group **/
85 #define SCST_DEFAULT_ACG_NAME                "Default"
86
87 /**
88  ** Maximum count of uncompleted commands that an initiator could 
89  ** queue on any device. Then it will take TASK QUEUE FULL status.
90  **/
91 #define SCST_MAX_DEVICE_COMMANDS           128
92
93 #define SCST_THREAD_FLAGS                  CLONE_KERNEL
94
95 #define SCST_TGT_RETRY_TIMEOUT             (3/2*HZ)
96
97 static inline int scst_get_context(void) {
98         /* Be overinsured */
99         return (in_atomic() || in_interrupt()) ? SCST_CONTEXT_DIRECT_ATOMIC :
100                                                  SCST_CONTEXT_DIRECT;
101 }
102
103 #define SCST_MGMT_CMD_CACHE_STRING "scst_mgmt_cmd"
104 extern kmem_cache_t *scst_mgmt_cachep;
105 extern mempool_t *scst_mgmt_mempool;
106
107 #define SCST_UA_CACHE_STRING "scst_ua"
108 extern kmem_cache_t *scst_ua_cachep;
109 extern mempool_t *scst_ua_mempool;
110
111 #define SCST_CMD_CACHE_STRING "scst_cmd"
112 extern kmem_cache_t *scst_cmd_cachep;
113
114 #define SCST_SESSION_CACHE_STRING "scst_session"
115 extern kmem_cache_t *scst_sess_cachep;
116
117 #define SCST_TGT_DEV_CACHE_STRING "scst_tgt_dev"
118 extern kmem_cache_t *scst_tgtd_cachep;
119
120 #define SCST_ACG_DEV_CACHE_STRING "scst_acg_dev"
121 extern kmem_cache_t *scst_acgd_cachep;
122
123 extern struct scst_sgv_pools scst_sgv;
124
125 extern int scst_num_cpus;
126 extern unsigned long scst_flags;
127 extern struct semaphore scst_mutex;
128 extern atomic_t scst_cmd_count;
129 extern spinlock_t scst_list_lock;
130 extern struct list_head scst_dev_wait_sess_list; /* protected by scst_list_lock */
131 extern struct list_head scst_template_list; /* protected by scst_mutex */
132 extern struct list_head scst_dev_list; /* protected by scst_mutex */
133 extern struct list_head scst_dev_type_list; /* protected by scst_mutex */
134 extern wait_queue_head_t scst_dev_cmd_waitQ;
135
136 extern struct list_head scst_acg_list;
137 extern struct scst_acg *scst_default_acg;
138
139 /* The following lists protected by scst_list_lock */
140 extern struct list_head scst_active_cmd_list;
141 extern struct list_head scst_init_cmd_list;
142 extern struct list_head scst_cmd_list;
143
144 extern struct list_head scst_mgmt_cmd_list;
145 extern struct list_head scst_active_mgmt_cmd_list;
146 extern struct list_head scst_delayed_mgmt_cmd_list;
147
148 extern struct tasklet_struct scst_tasklets[NR_CPUS];
149 extern wait_queue_head_t scst_list_waitQ;
150
151 extern wait_queue_head_t scst_mgmt_cmd_list_waitQ;
152
153 extern wait_queue_head_t scst_mgmt_waitQ;
154 extern spinlock_t scst_mgmt_lock;
155 extern struct list_head scst_sess_mgmt_list;
156
157 extern int scst_threads;
158 extern int scst_shut_threads_count;
159 extern atomic_t scst_threads_count;
160 extern int scst_thread_num;
161
162 extern struct semaphore *scst_shutdown_mutex;
163
164 extern spinlock_t scst_temp_UA_lock;
165 extern uint8_t scst_temp_UA[SCSI_SENSE_BUFFERSIZE];
166
167 extern struct scst_cmd *__scst_check_deferred_commands(
168         struct scst_tgt_dev *tgt_dev, int expected_sn);
169
170 /* Used to save the function call on th fast path */
171 static inline struct scst_cmd *scst_check_deferred_commands(
172         struct scst_tgt_dev *tgt_dev, int expected_sn)
173 {
174         if (tgt_dev->def_cmd_count == 0)
175                 return NULL;
176         else
177                 return __scst_check_deferred_commands(tgt_dev, expected_sn);
178 }
179
180 static inline int __scst_inc_expected_sn(struct scst_tgt_dev *tgt_dev)
181 {
182         /*
183          * No locks is needed, because only one thread at time can 
184          * call it (serialized by sn). Also it is supposed that there
185          * could not be half-incremented halves.
186          */
187
188         typeof(tgt_dev->expected_sn) e;
189
190         e = tgt_dev->expected_sn;
191         tgt_dev->expected_sn++;
192         smp_mb(); /* write must be before def_cmd_count read */
193         e++;
194         TRACE(TRACE_DEBUG/*TRACE_SCSI_SERIALIZING*/, "Next expected_sn: %d", e);
195         return e;
196 }
197
198 void scst_inc_expected_sn_unblock(struct scst_tgt_dev *tgt_dev,
199         struct scst_cmd *cmd_sn, int locked);
200
201 int scst_cmd_thread(void *arg);
202 void scst_cmd_tasklet(long p);
203 int scst_mgmt_cmd_thread(void *arg);
204 int scst_mgmt_thread(void *arg);
205
206 struct scst_device *scst_alloc_device(int gfp_mask);
207 void scst_free_device(struct scst_device *tgt_dev);
208
209 struct scst_acg *scst_alloc_add_acg(const char *acg_name);
210 int scst_destroy_acg(struct scst_acg *acg);
211
212 int scst_sess_alloc_tgt_devs(struct scst_session *sess);
213 void scst_sess_free_tgt_devs(struct scst_session *sess);
214 void scst_reset_tgt_dev(struct scst_tgt_dev *tgt_dev, int nexus_loss);
215
216 int scst_acg_add_dev(struct scst_acg *acg, struct scst_device *dev, lun_t lun,
217         int read_only);
218 int scst_acg_remove_dev(struct scst_acg *acg, struct scst_device *dev);
219
220 int scst_acg_add_name(struct scst_acg *acg, const char *name);
221 int scst_acg_remove_name(struct scst_acg *acg, const char *name);
222
223 int scst_assign_dev_handler(struct scst_device *dev, 
224         struct scst_dev_type *handler);
225
226 struct scst_session *scst_alloc_session(struct scst_tgt *tgt, int gfp_mask,
227         const char *initiator_name);
228 void scst_free_session(struct scst_session *sess);
229 void scst_free_session_callback(struct scst_session *sess);
230
231 struct scst_cmd *scst_alloc_cmd(int gfp_mask);
232 void scst_free_cmd(struct scst_cmd *cmd);
233 static inline void scst_destroy_cmd(struct scst_cmd *cmd)
234 {
235         TRACE_MEM("kfree for cmd: %p", cmd);
236         kmem_cache_free(scst_cmd_cachep, cmd);
237         return;
238 }
239
240 void scst_check_retries(struct scst_tgt *tgt, int processible_env);
241 void scst_tgt_retry_timer_fn(unsigned long arg);
242
243 int scst_alloc_request(struct scst_cmd *cmd);
244 void scst_release_request(struct scst_cmd *cmd);
245
246 static inline void scst_do_req(struct scsi_request *sreq, 
247         const void *cmnd, void *buffer, unsigned bufflen, 
248         void (*done)(struct scsi_cmnd *), int timeout, int retries)
249 {
250 #ifdef STRICT_SERIALIZING
251         scsi_do_req(sreq, cmnd, buffer, bufflen, done, timeout, retries);
252 #else
253         scsi_do_req_fifo(sreq, cmnd, buffer, bufflen, done, timeout, retries);
254 #endif
255 }
256 int scst_alloc_space(struct scst_cmd *cmd);
257 void scst_release_space(struct scst_cmd *cmd);
258 void scst_scsi_op_list_init(void);
259
260 lun_t scst_unpack_lun(const uint8_t *lun, int len);
261
262 struct scst_cmd *__scst_find_cmd_by_tag(struct scst_session *sess, 
263         uint32_t tag);
264
265 struct scst_mgmt_cmd *scst_alloc_mgmt_cmd(int gfp_mask);
266 void scst_free_mgmt_cmd(struct scst_mgmt_cmd *mcmd, int del);
267
268 /* /proc support */
269 int scst_proc_init_module(void);
270 void scst_proc_cleanup_module(void);
271 int scst_build_proc_target_dir_entries(struct scst_tgt_template *vtt);
272 void scst_cleanup_proc_target_dir_entries(struct scst_tgt_template *vtt);
273 int scst_build_proc_target_entries(struct scst_tgt *vtt);
274 void scst_cleanup_proc_target_entries(struct scst_tgt *vtt);
275 int scst_build_proc_dev_handler_dir_entries(struct scst_dev_type *dev_type);
276 void scst_cleanup_proc_dev_handler_dir_entries(struct scst_dev_type *dev_type);
277
278 int scst_get_cdb_len(const uint8_t *cdb);
279
280 void __scst_process_UA(struct scst_device *dev, struct scst_cmd *exclude,
281         const uint8_t *sense, int sense_len, int internal);
282 static inline void scst_process_UA(struct scst_device *dev,
283         struct scst_cmd *exclude, const uint8_t *sense, int sense_len,
284         int internal)
285 {
286         spin_lock_bh(&dev->dev_lock);
287         __scst_process_UA(dev, exclude, sense, sense_len, internal);
288         spin_unlock_bh(&dev->dev_lock);
289         return;
290 }
291 void scst_alloc_set_UA(struct scst_tgt_dev *tgt_dev, const uint8_t *sense,
292         int sense_len);
293 void scst_check_set_UA(struct scst_tgt_dev *tgt_dev,
294         const uint8_t *sense, int sense_len);
295 int scst_set_pending_UA(struct scst_cmd *cmd);
296 void scst_free_all_UA(struct scst_tgt_dev *tgt_dev);
297
298 void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
299         int other_ini, int call_dev_task_mgmt_fn);
300 void scst_process_reset(struct scst_device *dev,
301         struct scst_session *originator, struct scst_cmd *exclude_cmd,
302         struct scst_mgmt_cmd *mcmd);
303
304 static inline int scst_is_ua_command(struct scst_cmd *cmd)
305 {
306         return ((cmd->cdb[0] != INQUIRY) && 
307                 (cmd->cdb[0] != REQUEST_SENSE) &&
308                 (cmd->cdb[0] != REPORT_LUNS));
309 }
310
311 /*
312  * Returns 1, if cmd's CDB is locally handled by SCST and 0 otherwise.
313  * Dev handlers parse() and dev_done() not called for such commands.
314  */
315 static inline int scst_is_cmd_local(struct scst_cmd *cmd)
316 {
317         int res = 0;
318         switch (cmd->cdb[0]) {
319         case REPORT_LUNS:
320                 res = 1;
321         }
322         return res;
323 }
324
325 /*
326  * Some notes on devices "blocking". Blocking means that no
327  * commands will go from SCST to underlying SCSI device until it 
328  * is unblocked. But we don't care about all commands that 
329  * already on the device.
330  */
331
332 extern int scst_inc_on_dev_cmd(struct scst_cmd *cmd);
333 extern void scst_unblock_cmds(struct scst_device *dev);
334
335 static inline void __scst_block_dev(struct scst_device *dev)
336 {
337         dev->block_count++;
338         smp_mb();
339         TRACE_MGMT_DBG("Device BLOCK(%d), dev %p", dev->block_count, dev);
340 }
341
342 static inline void scst_block_dev(struct scst_device *dev, 
343         unsigned int outstanding)
344 {
345         spin_lock_bh(&dev->dev_lock);
346         __scst_block_dev(dev);
347         spin_unlock_bh(&dev->dev_lock);
348
349         TRACE_MGMT_DBG("Waiting during blocking outstanding %d (on_dev_count "
350                 "%d)", outstanding, atomic_read(&dev->on_dev_count));
351         wait_event(dev->on_dev_waitQ, 
352                 atomic_read(&dev->on_dev_count) <= outstanding);
353         TRACE_MGMT_DBG("%s", "wait_event() returned");
354 }
355
356 static inline void scst_unblock_dev(struct scst_device *dev)
357 {
358         spin_lock_bh(&dev->dev_lock);
359         TRACE_MGMT_DBG("Device UNBLOCK(%d), dev %p",
360                 dev->block_count-1, dev);
361         if (--dev->block_count == 0)
362                 scst_unblock_cmds(dev);
363         spin_unlock_bh(&dev->dev_lock);
364 }
365
366 static inline void scst_dec_on_dev_cmd(struct scst_cmd *cmd)
367 {
368         if (cmd->blocking) {
369                 TRACE_MGMT_DBG("cmd %p (tag %d): unblocking dev %p", cmd,
370                         cmd->tag, cmd->dev);
371                 cmd->blocking = 0;
372                 scst_unblock_dev(cmd->dev);
373         }
374         atomic_dec(&cmd->dev->on_dev_count);
375         smp_mb__after_atomic_dec();
376         if (unlikely(cmd->dev->block_count != 0))
377                 wake_up_all(&cmd->dev->on_dev_waitQ);
378 }
379
380 static inline void scst_inc_cmd_count(void)
381 {
382         atomic_inc(&scst_cmd_count);
383         smp_mb__after_atomic_inc();
384         TRACE_DBG("Incrementing scst_cmd_count(%d)",
385               atomic_read(&scst_cmd_count));
386 }
387
388 static inline void scst_dec_cmd_count(void)
389 {
390         int f;
391         f = atomic_dec_and_test(&scst_cmd_count);
392         smp_mb__after_atomic_dec();
393         if (f && unlikely(test_bit(SCST_FLAG_SUSPENDED, &scst_flags)))
394                 wake_up_all(&scst_dev_cmd_waitQ);
395         TRACE_DBG("Decrementing scst_cmd_count(%d)",
396               atomic_read(&scst_cmd_count));
397 }
398
399 void scst_sched_session_free(struct scst_session *sess);
400
401 static inline void scst_sess_get(struct scst_session *sess)
402 {
403         atomic_inc(&sess->refcnt);
404 }
405
406 static inline void scst_sess_put(struct scst_session *sess)
407 {
408         if (atomic_dec_and_test(&sess->refcnt))
409                 scst_sched_session_free(sess);
410 }
411
412 void __scst_suspend_activity(void);
413 void __scst_resume_activity(void);
414
415 extern void scst_throttle_cmd(struct scst_cmd *cmd);
416 extern void scst_unthrottle_cmd(struct scst_cmd *cmd);
417
418 static inline void scst_set_sense(uint8_t *buffer, int len, int key,
419         int asc, int ascq)
420 {
421         memset(buffer, 0, len);
422         buffer[0] = 0x70;       /* Error Code                   */
423         buffer[2] = key;        /* Sense Key                    */
424         buffer[7] = 0x0a;       /* Additional Sense Length      */
425         buffer[12] = asc;       /* ASC                          */
426         buffer[13] = ascq;      /* ASCQ                         */
427         TRACE_BUFFER("Sense set", buffer, len);
428         return;
429 }
430
431 static inline void scst_check_restore_sg_buff(struct scst_cmd *cmd)
432 {
433         if (cmd->sg_buff_modified) {
434                 cmd->sg[cmd->orig_sg_entry].length = cmd->orig_entry_len;
435                 cmd->sg_cnt = cmd->orig_sg_cnt;
436         }
437 }
438
439 #ifdef DEBUG_TM
440 extern void tm_dbg_init_tgt_dev(struct scst_tgt_dev *tgt_dev,
441         struct scst_acg_dev *acg_dev);
442 extern void tm_dbg_deinit_tgt_dev(struct scst_tgt_dev *tgt_dev);
443 extern void tm_dbg_check_released_cmds(void);
444 extern int tm_dbg_check_cmd(struct scst_cmd *cmd);
445 extern void tm_dbg_release_cmd(struct scst_cmd *cmd);
446 extern void tm_dbg_task_mgmt(const char *fn);
447 extern int tm_dbg_is_release(void);
448 #else
449 static inline void tm_dbg_init_tgt_dev(struct scst_tgt_dev *tgt_dev,
450         struct scst_acg_dev *acg_dev) {}
451 static inline void tm_dbg_deinit_tgt_dev(struct scst_tgt_dev *tgt_dev) {}
452 static inline void tm_dbg_check_released_cmds(void) {}
453 static inline int tm_dbg_check_cmd(struct scst_cmd *cmd)
454 {
455         return 0;
456 }
457 static inline void tm_dbg_release_cmd(struct scst_cmd *cmd) {}
458 static inline void tm_dbg_task_mgmt(const char *fn) {}
459 static inline int tm_dbg_is_release(void)
460 {
461         return 0;
462 }
463 #endif /* DEBUG_TM */
464
465 #endif /* __SCST_PRIV_H */