Let's don't check if data should be copied between dev handler's and target driver...
[mirror/scst/.git] / scst / src / scst_priv.h
1 /*
2  *  scst_priv.h
3  *
4  *  Copyright (C) 2004 - 2009 Vladislav Bolkhovitin <vst@vlnb.net>
5  *  Copyright (C) 2004 - 2005 Leonid Stoljar
6  *  Copyright (C) 2007 - 2009 ID7 Ltd.
7  *
8  *  This program is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU General Public License
10  *  as published by the Free Software Foundation, version 2
11  *  of the License.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  *  GNU General Public License for more details.
17  */
18
19 #ifndef __SCST_PRIV_H
20 #define __SCST_PRIV_H
21
22 #include <linux/types.h>
23
24 #include <scsi/scsi.h>
25 #include <scsi/scsi_cmnd.h>
26 #include <scsi/scsi_driver.h>
27 #include <scsi/scsi_device.h>
28 #include <scsi/scsi_host.h>
29
30 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
31 #include <scsi/scsi_request.h>
32 #endif
33
34 #define LOG_PREFIX "scst"
35
36 #include "scst_debug.h"
37
38 #ifdef CONFIG_SCST_PROC
39 void sgv_pool_destroy(struct sgv_pool *pool);
40 #endif
41
42 #define SCST_MAJOR              177
43
44 #define TRACE_RTRY              0x80000000
45 #define TRACE_SCSI_SERIALIZING  0x40000000
46 /** top being the edge away from the interupt */
47 #define TRACE_SND_TOP           0x20000000
48 #define TRACE_RCV_TOP           0x01000000
49 /** bottom being the edge toward the interupt */
50 #define TRACE_SND_BOT           0x08000000
51 #define TRACE_RCV_BOT           0x04000000
52
53 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
54 #define trace_flag scst_trace_flag
55 extern unsigned long scst_trace_flag;
56 #endif
57
58 #ifdef CONFIG_SCST_DEBUG
59
60 /* TRACE_MGMT_MINOR disabled to not confuse regular users */
61 #define SCST_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_PID | \
62         TRACE_LINE | TRACE_FUNCTION | TRACE_SPECIAL | TRACE_MGMT | \
63         /*TRACE_MGMT_MINOR |*/ TRACE_MGMT_DEBUG | TRACE_RTRY)
64
65 #define TRACE_RETRY(args...)    TRACE_DBG_FLAG(TRACE_RTRY, args)
66 #define TRACE_SN(args...)       TRACE_DBG_FLAG(TRACE_SCSI_SERIALIZING, args)
67 #define TRACE_SEND_TOP(args...) TRACE_DBG_FLAG(TRACE_SND_TOP, args)
68 #define TRACE_RECV_TOP(args...) TRACE_DBG_FLAG(TRACE_RCV_TOP, args)
69 #define TRACE_SEND_BOT(args...) TRACE_DBG_FLAG(TRACE_SND_BOT, args)
70 #define TRACE_RECV_BOT(args...) TRACE_DBG_FLAG(TRACE_RCV_BOT, args)
71
72 #else /* CONFIG_SCST_DEBUG */
73
74 # ifdef CONFIG_SCST_TRACING
75 #define SCST_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_MGMT | \
76         TRACE_SPECIAL)
77 # else
78 #define SCST_DEFAULT_LOG_FLAGS 0
79 # endif
80
81 #define TRACE_RETRY(args...)
82 #define TRACE_SN(args...)
83 #define TRACE_SEND_TOP(args...)
84 #define TRACE_RECV_TOP(args...)
85 #define TRACE_SEND_BOT(args...)
86 #define TRACE_RECV_BOT(args...)
87
88 #endif
89
90 /**
91  ** Bits for scst_flags
92  **/
93
94 /*
95  * Set if new commands initialization is being suspended for a while.
96  * Used to let TM commands execute while preparing the suspend, since
97  * RESET or ABORT could be necessary to free SCSI commands.
98  */
99 #define SCST_FLAG_SUSPENDING                 0
100
101 /* Set if new commands initialization is suspended for a while */
102 #define SCST_FLAG_SUSPENDED                  1
103
104 /**
105  ** Return codes for cmd state process functions. Codes are the same as
106  ** for SCST_EXEC_* to avoid translation to them and, hence, have better code.
107  **/
108 #define SCST_CMD_STATE_RES_CONT_NEXT         SCST_EXEC_COMPLETED
109 #define SCST_CMD_STATE_RES_CONT_SAME         SCST_EXEC_NOT_COMPLETED
110 #define SCST_CMD_STATE_RES_NEED_THREAD       SCST_EXEC_NEED_THREAD
111
112 /**
113  ** Maximum count of uncompleted commands that an initiator could
114  ** queue on any device. Then it will start getting TASK QUEUE FULL status.
115  **/
116 #define SCST_MAX_TGT_DEV_COMMANDS            48
117
118 /**
119  ** Maximum count of uncompleted commands that could be queued on any device.
120  ** Then initiators sending commands to this device will start getting
121  ** TASK QUEUE FULL status.
122  **/
123 #define SCST_MAX_DEV_COMMANDS                256
124
125 #define SCST_TGT_RETRY_TIMEOUT               (3/2*HZ)
126
127 extern unsigned int scst_max_dev_cmd_mem;
128
129 extern mempool_t *scst_mgmt_mempool;
130 extern mempool_t *scst_mgmt_stub_mempool;
131 extern mempool_t *scst_ua_mempool;
132 extern mempool_t *scst_sense_mempool;
133 extern mempool_t *scst_aen_mempool;
134
135 extern struct kmem_cache *scst_cmd_cachep;
136 extern struct kmem_cache *scst_sess_cachep;
137 extern struct kmem_cache *scst_tgtd_cachep;
138 extern struct kmem_cache *scst_acgd_cachep;
139
140 extern spinlock_t scst_main_lock;
141
142 extern struct scst_sgv_pools scst_sgv;
143
144 extern unsigned long scst_flags;
145 extern struct mutex scst_mutex;
146 extern atomic_t scst_cmd_count;
147 extern struct list_head scst_template_list;
148 extern struct list_head scst_dev_list;
149 extern struct list_head scst_dev_type_list;
150 extern wait_queue_head_t scst_dev_cmd_waitQ;
151
152 extern struct list_head scst_acg_list;
153 #ifdef CONFIG_SCST_PROC
154 extern struct scst_acg *scst_default_acg;
155 #endif
156
157 extern spinlock_t scst_init_lock;
158 extern struct list_head scst_init_cmd_list;
159 extern wait_queue_head_t scst_init_cmd_list_waitQ;
160 extern unsigned int scst_init_poll_cnt;
161
162 extern struct scst_cmd_lists scst_main_cmd_lists;
163
164 extern spinlock_t scst_mcmd_lock;
165 /* The following lists protected by scst_mcmd_lock */
166 extern struct list_head scst_active_mgmt_cmd_list;
167 extern struct list_head scst_delayed_mgmt_cmd_list;
168 extern wait_queue_head_t scst_mgmt_cmd_list_waitQ;
169
170 struct scst_tasklet {
171         spinlock_t tasklet_lock;
172         struct list_head tasklet_cmd_list;
173         struct tasklet_struct tasklet;
174 };
175 extern struct scst_tasklet scst_tasklets[NR_CPUS];
176
177 extern wait_queue_head_t scst_mgmt_waitQ;
178 extern spinlock_t scst_mgmt_lock;
179 extern struct list_head scst_sess_init_list;
180 extern struct list_head scst_sess_shut_list;
181
182 struct scst_cmd_thread_t {
183         struct task_struct *cmd_thread;
184         struct list_head thread_list_entry;
185 };
186
187 #if defined(SCST_IO_CONTEXT)
188
189 static inline bool scst_set_io_context(struct scst_cmd *cmd,
190         struct io_context **old)
191 {
192         bool res;
193
194         if (cmd->cmd_lists == &scst_main_cmd_lists) {
195                 EXTRACHECKS_BUG_ON(in_interrupt());
196                 /*
197                  * No need to call ioc_task_link(), because io_context
198                  * supposed to be cleared in the end of the caller function.
199                  */
200                 current->io_context = cmd->tgt_dev->tgt_dev_io_ctx;
201                 res = true;
202                 TRACE_DBG("io_context %p", cmd->tgt_dev->tgt_dev_io_ctx);
203         } else
204                 res = false;
205
206         return res;
207 }
208
209 static inline void scst_reset_io_context(struct scst_tgt_dev *tgt_dev,
210         struct io_context *old)
211 {
212         current->io_context = old;
213         TRACE_DBG("io_context %p reset", current->io_context);
214         return;
215 }
216
217 #else
218
219 static inline bool scst_set_io_context(struct scst_cmd *cmd,
220         struct io_context **old)
221 {
222         return false;
223 }
224 static inline void scst_reset_io_context(struct scst_tgt_dev *tgt_dev,
225         struct io_context *old) {}
226 static inline void __exit_io_context(struct io_context *ioc) {}
227 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
228 static inline struct io_context *ioc_task_link(struct io_context *ioc)
229 {
230         return NULL;
231 }
232 #endif
233
234 #endif
235
236 extern struct mutex scst_global_threads_mutex;
237 extern u32 scst_nr_global_threads;
238
239 extern int scst_global_threads_count(void);
240 extern int __scst_add_global_threads(int num);
241 extern void __scst_del_global_threads(int num);
242
243 extern struct scst_dev_type scst_null_devtype;
244
245 extern struct scst_cmd *__scst_check_deferred_commands(
246         struct scst_tgt_dev *tgt_dev);
247
248 /* Used to save the function call on the fast path */
249 static inline struct scst_cmd *scst_check_deferred_commands(
250         struct scst_tgt_dev *tgt_dev)
251 {
252         if (tgt_dev->def_cmd_count == 0)
253                 return NULL;
254         else
255                 return __scst_check_deferred_commands(tgt_dev);
256 }
257
258 static inline void scst_make_deferred_commands_active(
259         struct scst_tgt_dev *tgt_dev)
260 {
261         struct scst_cmd *c;
262
263         c = __scst_check_deferred_commands(tgt_dev);
264         if (c != NULL) {
265                 TRACE_SN("Adding cmd %p to active cmd list", c);
266                 spin_lock_irq(&c->cmd_lists->cmd_list_lock);
267                 list_add_tail(&c->cmd_list_entry,
268                         &c->cmd_lists->active_cmd_list);
269                 wake_up(&c->cmd_lists->cmd_list_waitQ);
270                 spin_unlock_irq(&c->cmd_lists->cmd_list_lock);
271         }
272
273         return;
274 }
275
276 void scst_inc_expected_sn(struct scst_tgt_dev *tgt_dev, atomic_t *slot);
277 int scst_check_hq_cmd(struct scst_cmd *cmd);
278
279 void scst_unblock_deferred(struct scst_tgt_dev *tgt_dev,
280         struct scst_cmd *cmd_sn);
281
282 void scst_on_hq_cmd_response(struct scst_cmd *cmd);
283 void scst_xmit_process_aborted_cmd(struct scst_cmd *cmd);
284
285 int scst_cmd_thread(void *arg);
286 void scst_cmd_tasklet(long p);
287 int scst_init_thread(void *arg);
288 int scst_tm_thread(void *arg);
289 int scst_global_mgmt_thread(void *arg);
290
291 int scst_add_dev_threads(struct scst_device *dev, int num);
292 void scst_del_dev_threads(struct scst_device *dev, int num);
293
294 int scst_queue_retry_cmd(struct scst_cmd *cmd, int finished_cmds);
295
296 static inline void scst_tgtt_cleanup(struct scst_tgt_template *tgtt) { }
297 static inline void scst_devt_cleanup(struct scst_dev_type *devt) { }
298
299 struct scst_tgt *scst_alloc_tgt(struct scst_tgt_template *tgtt);
300 void scst_free_tgt(struct scst_tgt *tgt);
301
302 int scst_alloc_device(gfp_t gfp_mask, struct scst_device **out_dev);
303 void scst_free_device(struct scst_device *dev);
304
305 struct scst_acg *scst_alloc_add_acg(const char *acg_name);
306 int scst_destroy_acg(struct scst_acg *acg);
307
308 struct scst_acg *scst_find_acg(const struct scst_session *sess);
309
310 void scst_check_reassign_sessions(void);
311
312 int scst_sess_alloc_tgt_devs(struct scst_session *sess);
313 void scst_sess_free_tgt_devs(struct scst_session *sess);
314 void scst_nexus_loss(struct scst_tgt_dev *tgt_dev, bool queue_UA);
315
316 int scst_acg_add_dev(struct scst_acg *acg, struct scst_device *dev,
317         uint64_t lun, int read_only, bool gen_scst_report_luns_changed);
318 int scst_acg_remove_dev(struct scst_acg *acg, struct scst_device *dev,
319         bool gen_scst_report_luns_changed);
320
321 void scst_acg_dev_destroy(struct scst_acg_dev *acg_dev);
322
323 int scst_acg_add_name(struct scst_acg *acg, const char *name);
324 int scst_acg_remove_name(struct scst_acg *acg, const char *name, bool reassign);
325 void __scst_acg_remove_acn(struct scst_acn *n);
326
327 int scst_prepare_request_sense(struct scst_cmd *orig_cmd);
328 int scst_finish_internal_cmd(struct scst_cmd *cmd);
329
330 void scst_store_sense(struct scst_cmd *cmd);
331
332 int scst_assign_dev_handler(struct scst_device *dev,
333         struct scst_dev_type *handler);
334
335 struct scst_session *scst_alloc_session(struct scst_tgt *tgt, gfp_t gfp_mask,
336         const char *initiator_name);
337 void scst_free_session(struct scst_session *sess);
338 void scst_release_session(struct scst_session *sess);
339 void scst_free_session_callback(struct scst_session *sess);
340
341 struct scst_cmd *scst_alloc_cmd(gfp_t gfp_mask);
342 void scst_free_cmd(struct scst_cmd *cmd);
343 static inline void scst_destroy_cmd(struct scst_cmd *cmd)
344 {
345         kmem_cache_free(scst_cmd_cachep, cmd);
346         return;
347 }
348
349 void scst_check_retries(struct scst_tgt *tgt);
350
351 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
352 int scst_alloc_request(struct scst_cmd *cmd);
353 void scst_release_request(struct scst_cmd *cmd);
354
355 static inline void scst_do_req(struct scsi_request *sreq,
356         const void *cmnd, void *buffer, unsigned bufflen,
357         void (*done)(struct scsi_cmnd *), int timeout, int retries)
358 {
359 #ifdef CONFIG_SCST_STRICT_SERIALIZING
360         scsi_do_req(sreq, cmnd, buffer, bufflen, done, timeout, retries);
361 #elif !defined(SCSI_EXEC_REQ_FIFO_DEFINED)
362         sBUG();
363 #else
364         scsi_do_req_fifo(sreq, cmnd, buffer, bufflen, done, timeout, retries);
365 #endif
366 }
367 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
368 static inline int scst_exec_req(struct scsi_device *sdev,
369         const unsigned char *cmd, int cmd_len, int data_direction,
370         struct scatterlist *sgl, unsigned bufflen, unsigned nents,
371         int timeout, int retries, void *privdata,
372         void (*done)(void *, char *, int, int), gfp_t gfp)
373 {
374 #if defined(CONFIG_SCST_STRICT_SERIALIZING)
375         return scsi_execute_async(sdev, cmd, cmd_len, data_direction, (void *)sgl,
376                     bufflen, nents, timeout, retries, privdata, done, gfp);
377 #elif !defined(SCSI_EXEC_REQ_FIFO_DEFINED)
378         WARN_ON(1);
379         return -1;
380 #else
381         return scsi_execute_async_fifo(sdev, cmd, cmd_len, data_direction,
382             (void *)sgl, bufflen, nents, timeout, retries, privdata, done, gfp);
383 #endif
384 }
385 #else /* i.e. LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) */
386 #if defined(SCSI_EXEC_REQ_FIFO_DEFINED)
387 int scst_scsi_exec_async(struct scst_cmd *cmd,
388         void (*done)(void *, char *, int, int));
389 #else
390 static inline int scst_scsi_exec_async(struct scst_cmd *cmd,
391         void (*done)(void *, char *, int, int))
392 {
393         WARN_ON_ONCE(1);
394         return -1;
395 }
396 #endif
397 #endif
398
399 int scst_alloc_space(struct scst_cmd *cmd);
400
401 int scst_lib_init(void);
402 void scst_lib_exit(void);
403
404 uint64_t scst_pack_lun(const uint64_t lun);
405 uint64_t scst_unpack_lun(const uint8_t *lun, int len);
406
407 struct scst_mgmt_cmd *scst_alloc_mgmt_cmd(gfp_t gfp_mask);
408 void scst_free_mgmt_cmd(struct scst_mgmt_cmd *mcmd);
409 void scst_done_cmd_mgmt(struct scst_cmd *cmd);
410
411 #ifdef CONFIG_SCST_PROC
412 /* /proc support */
413 int scst_proc_init_module(void);
414 void scst_proc_cleanup_module(void);
415 int scst_build_proc_target_dir_entries(struct scst_tgt_template *vtt);
416 void scst_cleanup_proc_target_dir_entries(struct scst_tgt_template *vtt);
417 int scst_build_proc_target_entries(struct scst_tgt *vtt);
418 void scst_cleanup_proc_target_entries(struct scst_tgt *vtt);
419 int scst_build_proc_dev_handler_dir_entries(struct scst_dev_type *dev_type);
420 void scst_cleanup_proc_dev_handler_dir_entries(struct scst_dev_type *dev_type);
421 #endif
422
423 /* sysfs support  */
424 #ifdef CONFIG_SCST_PROC
425 static inline int scst_sysfs_init(void)
426 {
427         return 0;
428 }
429 static inline void scst_sysfs_cleanup(void) { }
430
431 static inline int scst_create_tgtt_sysfs(struct scst_tgt_template *tgtt)
432 {
433         return 0;
434 }
435 static inline void scst_tgtt_sysfs_put(struct scst_tgt_template *tgtt)
436 {
437         scst_tgtt_cleanup(tgtt);
438 }
439
440 static inline int scst_create_tgt_sysfs(struct scst_tgt *tgt)
441 {
442         return 0;
443 }
444 static inline void scst_tgt_sysfs_put(struct scst_tgt *tgt)
445 {
446         scst_free_tgt(tgt);
447 }
448
449 static inline int scst_create_sess_sysfs(struct scst_session *sess)
450 {
451         return 0;
452 }
453 static inline void scst_sess_sysfs_put(struct scst_session *sess)
454 {
455         scst_release_session(sess);
456 }
457
458 static inline int scst_create_sgv_sysfs(struct sgv_pool *pool)
459 {
460         return 0;
461 }
462 static inline void scst_sgv_sysfs_put(struct sgv_pool *pool)
463 {
464         sgv_pool_destroy(pool);
465 }
466
467 static inline int scst_create_devt_sysfs(struct scst_dev_type *devt)
468 {
469         return 0;
470 }
471 static inline void scst_devt_sysfs_put(struct scst_dev_type *devt)
472 {
473         scst_devt_cleanup(devt);
474 }
475
476 static inline int scst_create_device_sysfs(struct scst_device *dev)
477 {
478         return 0;
479 }
480 static inline void scst_device_sysfs_put(struct scst_device *dev)
481 {
482         scst_free_device(dev);
483 }
484
485 static inline int scst_create_devt_dev_sysfs(struct scst_device *dev)
486 {
487         return 0;
488 }
489 static inline void scst_devt_dev_sysfs_put(struct scst_device *dev) { }
490
491 #else /* CONFIG_SCST_PROC */
492
493 int scst_sysfs_init(void);
494 void scst_sysfs_cleanup(void);
495 int scst_create_tgtt_sysfs(struct scst_tgt_template *tgtt);
496 void scst_tgtt_sysfs_put(struct scst_tgt_template *tgtt);
497 int scst_create_tgt_sysfs(struct scst_tgt *tgt);
498 void scst_tgt_sysfs_put(struct scst_tgt *tgt);
499 int scst_create_sess_sysfs(struct scst_session *sess);
500 void scst_sess_sysfs_put(struct scst_session *sess);
501 int scst_create_sgv_sysfs(struct sgv_pool *pool);
502 void scst_sgv_sysfs_put(struct sgv_pool *pool);
503 int scst_create_devt_sysfs(struct scst_dev_type *devt);
504 void scst_devt_sysfs_put(struct scst_dev_type *devt);
505 int scst_create_device_sysfs(struct scst_device *dev);
506 void scst_device_sysfs_put(struct scst_device *dev);
507 int scst_create_devt_dev_sysfs(struct scst_device *dev);
508 void scst_devt_dev_sysfs_put(struct scst_device *dev);
509
510 #endif /* CONFIG_SCST_PROC */
511
512 int scst_get_cdb_len(const uint8_t *cdb);
513
514 void __scst_dev_check_set_UA(struct scst_device *dev, struct scst_cmd *exclude,
515         const uint8_t *sense, int sense_len);
516 static inline void scst_dev_check_set_UA(struct scst_device *dev,
517         struct scst_cmd *exclude, const uint8_t *sense, int sense_len)
518 {
519         spin_lock_bh(&dev->dev_lock);
520         __scst_dev_check_set_UA(dev, exclude, sense, sense_len);
521         spin_unlock_bh(&dev->dev_lock);
522         return;
523 }
524 void scst_dev_check_set_local_UA(struct scst_device *dev,
525         struct scst_cmd *exclude, const uint8_t *sense, int sense_len);
526
527 #define SCST_SET_UA_FLAG_AT_HEAD        1
528 #define SCST_SET_UA_FLAG_GLOBAL         2
529
530 void scst_check_set_UA(struct scst_tgt_dev *tgt_dev,
531         const uint8_t *sense, int sense_len, int flags);
532 int scst_set_pending_UA(struct scst_cmd *cmd);
533
534 void scst_report_luns_changed(struct scst_acg *acg);
535
536 void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
537         int other_ini, int call_dev_task_mgmt_fn);
538 void scst_process_reset(struct scst_device *dev,
539         struct scst_session *originator, struct scst_cmd *exclude_cmd,
540         struct scst_mgmt_cmd *mcmd, bool setUA);
541
542 bool scst_is_ua_global(const uint8_t *sense, int len);
543 void scst_requeue_ua(struct scst_cmd *cmd);
544
545 void scst_gen_aen_or_ua(struct scst_tgt_dev *tgt_dev,
546         int key, int asc, int ascq);
547
548 static inline bool scst_is_implicit_hq(struct scst_cmd *cmd)
549 {
550         return (cmd->op_flags & SCST_IMPLICIT_HQ) != 0;
551 }
552
553 /*
554  * Some notes on devices "blocking". Blocking means that no
555  * commands will go from SCST to underlying SCSI device until it
556  * is unblocked. But we don't care about all commands that
557  * already on the device.
558  */
559
560 extern int scst_inc_on_dev_cmd(struct scst_cmd *cmd);
561
562 extern void __scst_block_dev(struct scst_device *dev);
563 extern void scst_block_dev_cmd(struct scst_cmd *cmd, int outstanding);
564 extern void scst_unblock_dev(struct scst_device *dev);
565 extern void scst_unblock_dev_cmd(struct scst_cmd *cmd);
566
567 /* No locks */
568 static inline void scst_dec_on_dev_cmd(struct scst_cmd *cmd)
569 {
570         struct scst_device *dev = cmd->dev;
571         bool unblock_dev = cmd->inc_blocking;
572
573         if (cmd->inc_blocking) {
574                 TRACE_MGMT_DBG("cmd %p (tag %llu): unblocking dev %p", cmd,
575                                (long long unsigned int)cmd->tag, cmd->dev);
576                 cmd->inc_blocking = 0;
577         }
578         cmd->dec_on_dev_needed = 0;
579
580         if (unblock_dev)
581                 scst_unblock_dev(dev);
582
583         atomic_dec(&dev->on_dev_count);
584         /* See comment in scst_block_dev() */
585         smp_mb__after_atomic_dec();
586
587         TRACE_DBG("New on_dev_count %d", atomic_read(&dev->on_dev_count));
588
589         sBUG_ON(atomic_read(&dev->on_dev_count) < 0);
590
591         if (unlikely(dev->block_count != 0))
592                 wake_up_all(&dev->on_dev_waitQ);
593
594         return;
595 }
596
597 static inline void __scst_get(int barrier)
598 {
599         atomic_inc(&scst_cmd_count);
600         TRACE_DBG("Incrementing scst_cmd_count(new value %d)",
601                 atomic_read(&scst_cmd_count));
602
603         /* See comment about smp_mb() in scst_suspend_activity() */
604         if (barrier)
605                 smp_mb__after_atomic_inc();
606 }
607
608 static inline void __scst_put(void)
609 {
610         int f;
611         f = atomic_dec_and_test(&scst_cmd_count);
612         /* See comment about smp_mb() in scst_suspend_activity() */
613         if (f && unlikely(test_bit(SCST_FLAG_SUSPENDED, &scst_flags))) {
614                 TRACE_MGMT_DBG("%s", "Waking up scst_dev_cmd_waitQ");
615                 wake_up_all(&scst_dev_cmd_waitQ);
616         }
617         TRACE_DBG("Decrementing scst_cmd_count(new value %d)",
618               atomic_read(&scst_cmd_count));
619 }
620
621 void scst_sched_session_free(struct scst_session *sess);
622
623 static inline void scst_sess_get(struct scst_session *sess)
624 {
625         atomic_inc(&sess->refcnt);
626         TRACE_DBG("Incrementing sess %p refcnt (new value %d)",
627                 sess, atomic_read(&sess->refcnt));
628 }
629
630 static inline void scst_sess_put(struct scst_session *sess)
631 {
632         TRACE_DBG("Decrementing sess %p refcnt (new value %d)",
633                 sess, atomic_read(&sess->refcnt)-1);
634         if (atomic_dec_and_test(&sess->refcnt))
635                 scst_sched_session_free(sess);
636 }
637
638 static inline void __scst_cmd_get(struct scst_cmd *cmd)
639 {
640         atomic_inc(&cmd->cmd_ref);
641         TRACE_DBG("Incrementing cmd %p ref (new value %d)",
642                 cmd, atomic_read(&cmd->cmd_ref));
643 }
644
645 static inline void __scst_cmd_put(struct scst_cmd *cmd)
646 {
647         TRACE_DBG("Decrementing cmd %p ref (new value %d)",
648                 cmd, atomic_read(&cmd->cmd_ref)-1);
649         if (atomic_dec_and_test(&cmd->cmd_ref))
650                 scst_free_cmd(cmd);
651 }
652
653 extern void scst_throttle_cmd(struct scst_cmd *cmd);
654 extern void scst_unthrottle_cmd(struct scst_cmd *cmd);
655
656 static inline void scst_check_restore_sg_buff(struct scst_cmd *cmd)
657 {
658         if (cmd->sg_buff_modified) {
659                 TRACE_MEM("cmd %p, sg %p, orig_sg_entry %d, "
660                         "orig_entry_len %d, orig_sg_cnt %d", cmd, cmd->sg,
661                         cmd->orig_sg_entry, cmd->orig_entry_len,
662                         cmd->orig_sg_cnt);
663                 cmd->sg[cmd->orig_sg_entry].length = cmd->orig_entry_len;
664                 cmd->sg_cnt = cmd->orig_sg_cnt;
665                 cmd->sg_buff_modified = 0;
666         }
667 }
668
669 #ifdef CONFIG_SCST_DEBUG_TM
670 extern void tm_dbg_check_released_cmds(void);
671 extern int tm_dbg_check_cmd(struct scst_cmd *cmd);
672 extern void tm_dbg_release_cmd(struct scst_cmd *cmd);
673 extern void tm_dbg_task_mgmt(struct scst_device *dev, const char *fn,
674         int force);
675 extern int tm_dbg_is_release(void);
676 #else
677 static inline void tm_dbg_check_released_cmds(void) {}
678 static inline int tm_dbg_check_cmd(struct scst_cmd *cmd)
679 {
680         return 0;
681 }
682 static inline void tm_dbg_release_cmd(struct scst_cmd *cmd) {}
683 static inline void tm_dbg_task_mgmt(struct scst_device *dev, const char *fn,
684         int force) {}
685 static inline int tm_dbg_is_release(void)
686 {
687         return 0;
688 }
689 #endif /* CONFIG_SCST_DEBUG_TM */
690
691 #ifdef CONFIG_SCST_DEBUG_SN
692 void scst_check_debug_sn(struct scst_cmd *cmd);
693 #else
694 static inline void scst_check_debug_sn(struct scst_cmd *cmd) {}
695 #endif
696
697 /*
698  * It deals with comparing 32 bit unsigned ints and worry about wraparound
699  * (automatic with unsigned arithmetic). Borrowed from net/tcp.h.
700  */
701 static inline int scst_sn_before(__u32 seq1, __u32 seq2)
702 {
703         return (__s32)(seq1-seq2) < 0;
704 }
705
706 #ifdef CONFIG_SCST_MEASURE_LATENCY
707
708 void scst_set_start_time(struct scst_cmd *cmd);
709 void scst_set_cur_start(struct scst_cmd *cmd);
710 void scst_set_parse_time(struct scst_cmd *cmd);
711 void scst_set_alloc_buf_time(struct scst_cmd *cmd);
712 void scst_set_restart_waiting_time(struct scst_cmd *cmd);
713 void scst_set_rdy_to_xfer_time(struct scst_cmd *cmd);
714 void scst_set_pre_exec_time(struct scst_cmd *cmd);
715 void scst_set_exec_time(struct scst_cmd *cmd);
716 void scst_set_dev_done_time(struct scst_cmd *cmd);
717 void scst_set_xmit_time(struct scst_cmd *cmd);
718 void scst_set_tgt_on_free_time(struct scst_cmd *cmd);
719 void scst_set_dev_on_free_time(struct scst_cmd *cmd);
720 void scst_update_lat_stats(struct scst_cmd *cmd);
721
722 #else
723
724 static inline void scst_set_start_time(struct scst_cmd *cmd) {}
725 static inline void scst_set_cur_start(struct scst_cmd *cmd) {}
726 static inline void scst_set_parse_time(struct scst_cmd *cmd) {}
727 static inline void scst_set_alloc_buf_time(struct scst_cmd *cmd) {}
728 static inline void scst_set_restart_waiting_time(struct scst_cmd *cmd) {}
729 static inline void scst_set_rdy_to_xfer_time(struct scst_cmd *cmd) {}
730 static inline void scst_set_pre_exec_time(struct scst_cmd *cmd) {}
731 static inline void scst_set_exec_time(struct scst_cmd *cmd) {}
732 static inline void scst_set_dev_done_time(struct scst_cmd *cmd) {}
733 static inline void scst_set_xmit_time(struct scst_cmd *cmd) {}
734 static inline void scst_set_tgt_on_free_time(struct scst_cmd *cmd) {}
735 static inline void scst_set_dev_on_free_time(struct scst_cmd *cmd) {}
736 static inline void scst_update_lat_stats(struct scst_cmd *cmd) {}
737
738 #endif /* CONFIG_SCST_MEASURE_LATENCY */
739
740 #endif /* __SCST_PRIV_H */