4fd0c87562d030e80eca036718b7eba7d4151fd0
[mirror/scst/.git] / scst / src / scst_priv.h
1 /*
2  *  scst_priv.h
3  *  
4  *  Copyright (C) 2004-2007 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_host.h>
28
29 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
30 #include <scsi/scsi_request.h>
31 #endif
32
33 #define LOG_PREFIX "scst"
34
35 #include "scst_debug.h"
36
37 #define SCST_MAJOR              177
38
39 #define TRACE_RTRY              0x80000000
40 #define TRACE_SCSI_SERIALIZING  0x40000000
41 #define TRACE_SND_TOP           0x20000000 /** top being the edge away from the interupt */
42 #define TRACE_RCV_TOP           0x01000000 
43 #define TRACE_SND_BOT           0x08000000 /** bottom being the edge toward the interupt */
44 #define TRACE_RCV_BOT           0x04000000
45
46 #if defined(DEBUG) || defined(TRACING)
47 #define trace_flag scst_trace_flag
48 extern unsigned long scst_trace_flag;
49 #endif
50
51 #ifdef DEBUG
52 /*#define SCST_DEFAULT_LOG_FLAGS (TRACE_ALL & ~TRACE_MEMORY & ~TRACE_BUFF \
53          & ~TRACE_FUNCTION)
54 #define SCST_DEFAULT_LOG_FLAGS (TRACE_ALL & ~TRACE_MEMORY & ~TRACE_BUFF & \
55         ~TRACE_SCSI & ~TRACE_SCSI_SERIALIZING & ~TRACE_DEBUG)
56 */
57 #define SCST_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_PID | \
58         TRACE_LINE | TRACE_FUNCTION | TRACE_SPECIAL | TRACE_MGMT | \
59         TRACE_MGMT_MINOR | TRACE_MGMT_DEBUG | TRACE_RTRY)
60
61 #define TRACE_RETRY(args...)            __TRACE(TRACE_RTRY, args)
62 #define TRACE_SN(args...)               __TRACE(TRACE_SCSI_SERIALIZING, args)
63 #define TRACE_SEND_TOP(args...)         __TRACE(TRACE_SND_TOP, args)
64 #define TRACE_RECV_TOP(args...)         __TRACE(TRACE_RCV_TOP, args)
65 #define TRACE_SEND_BOT(args...)         __TRACE(TRACE_SND_BOT, args)
66 #define TRACE_RECV_BOT(args...)         __TRACE(TRACE_RCV_BOT, args)
67
68 #else /* DEBUG */
69
70 # ifdef TRACING
71 #define SCST_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_SPECIAL)
72 # else
73 #define SCST_DEFAULT_LOG_FLAGS 0
74 # endif
75
76 #define TRACE_RETRY(args...)
77 #define TRACE_SN(args...)
78 #define TRACE_SEND_TOP(args...)
79 #define TRACE_RECV_TOP(args...)
80 #define TRACE_SEND_BOT(args...)
81 #define TRACE_RECV_BOT(args...)
82
83 #endif
84
85 /**
86  ** Bits for scst_flags 
87  **/
88
89 /* 
90  * Set if new commands initialization is being suspended for a while.
91  * Used to let TM commands execute while preparing the suspend, since
92  * RESET or ABORT could be necessary to free SCSI commands.
93  */
94 #define SCST_FLAG_SUSPENDING                 0
95
96 /* Set if new commands initialization is suspended for a while */
97 #define SCST_FLAG_SUSPENDED                  1
98
99 /** 
100  ** Return codes for cmd state process functions 
101  **/
102 #define SCST_CMD_STATE_RES_CONT_SAME         0
103 #define SCST_CMD_STATE_RES_CONT_NEXT         1
104 #define SCST_CMD_STATE_RES_NEED_THREAD       2
105
106 /** Name of the "default" security group **/
107 #define SCST_DEFAULT_ACG_NAME                "Default"
108
109 /**
110  ** Maximum count of uncompleted commands that an initiator could 
111  ** queue on any device. Then it will start getting TASK QUEUE FULL status.
112  **/
113 #define SCST_MAX_TGT_DEV_COMMANDS            48
114
115 /**
116  ** Maximum count of uncompleted commands that could be queued on any device.
117  ** Then initiators sending commands to this device will start getting
118  ** TASK QUEUE FULL status.
119  **/
120 #define SCST_MAX_DEV_COMMANDS                256
121
122 #define SCST_TGT_RETRY_TIMEOUT               (3/2*HZ)
123 #define SCST_CMD_MEM_TIMEOUT                 (120*HZ)
124
125 static inline int scst_get_context(void)
126 {
127         if (in_irq())
128                 return SCST_CONTEXT_TASKLET;
129         if (irqs_disabled())
130                 return SCST_CONTEXT_THREAD;
131         if (in_softirq() || in_atomic())
132                 return SCST_CONTEXT_DIRECT_ATOMIC;
133         return SCST_CONTEXT_DIRECT;
134 }
135
136 extern unsigned long scst_max_cmd_mem;
137
138 extern mempool_t *scst_mgmt_mempool;
139 extern mempool_t *scst_mgmt_stub_mempool;
140 extern mempool_t *scst_ua_mempool;
141 extern mempool_t *scst_sense_mempool;
142
143 extern struct kmem_cache *scst_cmd_cachep;
144 extern struct kmem_cache *scst_sess_cachep;
145 extern struct kmem_cache *scst_tgtd_cachep;
146 extern struct kmem_cache *scst_acgd_cachep;
147
148 extern spinlock_t scst_main_lock;
149
150 extern struct scst_sgv_pools scst_sgv;
151
152 extern unsigned long scst_flags;
153 extern struct mutex scst_mutex;
154 extern atomic_t scst_cmd_count;
155 extern struct list_head scst_template_list; /* protected by scst_mutex */
156 extern struct list_head scst_dev_list; /* protected by scst_mutex */
157 extern struct list_head scst_dev_type_list; /* protected by scst_mutex */
158 extern wait_queue_head_t scst_dev_cmd_waitQ;
159
160 extern struct mutex scst_suspend_mutex;
161 extern struct list_head scst_cmd_lists_list; /* protected by scst_suspend_mutex */
162
163 extern struct list_head scst_acg_list;
164 extern struct scst_acg *scst_default_acg;
165
166 extern spinlock_t scst_init_lock;
167 extern struct list_head scst_init_cmd_list;
168 extern wait_queue_head_t scst_init_cmd_list_waitQ;
169 extern unsigned int scst_init_poll_cnt;
170
171 extern struct scst_cmd_lists scst_main_cmd_lists;
172
173 extern spinlock_t scst_mcmd_lock;
174 /* The following lists protected by scst_mcmd_lock */
175 extern struct list_head scst_active_mgmt_cmd_list;
176 extern struct list_head scst_delayed_mgmt_cmd_list;
177 extern wait_queue_head_t scst_mgmt_cmd_list_waitQ;
178
179 struct scst_tasklet
180 {
181         spinlock_t tasklet_lock;
182         struct list_head tasklet_cmd_list;
183         struct tasklet_struct tasklet;
184 };
185 extern struct scst_tasklet scst_tasklets[NR_CPUS];
186
187 extern wait_queue_head_t scst_mgmt_waitQ;
188 extern spinlock_t scst_mgmt_lock;
189 extern struct list_head scst_sess_init_list;
190 extern struct list_head scst_sess_shut_list;
191
192 struct scst_cmd_thread_t {
193         struct task_struct *cmd_thread;
194         struct list_head thread_list_entry;
195 };
196
197 struct scst_threads_info_t {
198         struct mutex cmd_threads_mutex;
199         u32 nr_cmd_threads;
200         struct list_head cmd_threads_list;
201         struct task_struct *init_cmd_thread;
202         struct task_struct *mgmt_thread;
203         struct task_struct *mgmt_cmd_thread;
204 };
205
206 extern struct scst_threads_info_t scst_threads_info;
207 extern int scst_cmd_threads_count(void);
208 extern int __scst_add_cmd_threads(int num);
209 extern void __scst_del_cmd_threads(int num);
210
211 extern spinlock_t scst_temp_UA_lock;
212 extern uint8_t scst_temp_UA[SCST_SENSE_BUFFERSIZE];
213
214 extern struct scst_dev_type scst_null_devtype;
215
216 extern struct scst_cmd *__scst_check_deferred_commands(
217         struct scst_tgt_dev *tgt_dev);
218
219 /* Used to save the function call on the fast path */
220 static inline struct scst_cmd *scst_check_deferred_commands(
221         struct scst_tgt_dev *tgt_dev)
222 {
223         if (tgt_dev->def_cmd_count == 0)
224                 return NULL;
225         else
226                 return __scst_check_deferred_commands(tgt_dev);
227 }
228
229 static inline void scst_make_deferred_commands_active(
230         struct scst_tgt_dev *tgt_dev, struct scst_cmd *curr_cmd)
231 {
232         struct scst_cmd *c;
233
234         c = __scst_check_deferred_commands(tgt_dev);
235         if (c != NULL) {
236                 TRACE_SN("Adding cmd %p to active cmd list", c);
237
238                 EXTRACHECKS_BUG_ON(c->cmd_lists != curr_cmd->cmd_lists);
239
240                 spin_lock_irq(&c->cmd_lists->cmd_list_lock);
241                 list_add_tail(&c->cmd_list_entry,
242                         &c->cmd_lists->active_cmd_list);
243 #if 0 /* temp. ToDo */
244                 if (!curr_cmd->context_processable || curr_cmd->long_xmit)
245 #endif
246                         wake_up(&c->cmd_lists->cmd_list_waitQ);
247                 spin_unlock_irq(&c->cmd_lists->cmd_list_lock);
248         }
249
250         return;
251 }
252
253 void scst_inc_expected_sn(struct scst_tgt_dev *tgt_dev, atomic_t *slot);
254 int scst_check_hq_cmd(struct scst_cmd *cmd);
255
256 void scst_unblock_deferred(struct scst_tgt_dev *tgt_dev,
257         struct scst_cmd *cmd_sn);
258
259 void scst_on_hq_cmd_response(struct scst_cmd *cmd);
260 void scst_xmit_process_aborted_cmd(struct scst_cmd *cmd);
261
262 int scst_cmd_thread(void *arg);
263 void scst_cmd_tasklet(long p);
264 int scst_init_cmd_thread(void *arg);
265 int scst_mgmt_cmd_thread(void *arg);
266 int scst_mgmt_thread(void *arg);
267
268 int scst_add_dev_threads(struct scst_device *dev, int num);
269 void scst_del_dev_threads(struct scst_device *dev, int num);
270
271 int scst_alloc_device(int gfp_mask, struct scst_device **out_dev);
272 void scst_free_device(struct scst_device *tgt_dev);
273
274 struct scst_acg *scst_alloc_add_acg(const char *acg_name);
275 int scst_destroy_acg(struct scst_acg *acg);
276 int scst_proc_group_add_tree(struct scst_acg *acg, const char *name);
277 void scst_proc_del_acg_tree(struct proc_dir_entry *acg_proc_root,
278         const char *name);
279
280 int scst_sess_alloc_tgt_devs(struct scst_session *sess);
281 void scst_sess_free_tgt_devs(struct scst_session *sess);
282 void scst_nexus_loss(struct scst_tgt_dev *tgt_dev);
283
284 int scst_acg_add_dev(struct scst_acg *acg, struct scst_device *dev, lun_t lun,
285         int read_only);
286 int scst_acg_remove_dev(struct scst_acg *acg, struct scst_device *dev);
287
288 int scst_acg_add_name(struct scst_acg *acg, const char *name);
289 int scst_acg_remove_name(struct scst_acg *acg, const char *name);
290
291 struct scst_cmd *scst_create_prepare_internal_cmd(
292         struct scst_cmd *orig_cmd, int bufsize);
293 void scst_free_internal_cmd(struct scst_cmd *cmd);
294 int scst_prepare_request_sense(struct scst_cmd *orig_cmd);
295 struct scst_cmd *scst_complete_request_sense(struct scst_cmd *cmd);
296
297 int scst_assign_dev_handler(struct scst_device *dev, 
298         struct scst_dev_type *handler);
299
300 struct scst_session *scst_alloc_session(struct scst_tgt *tgt, int gfp_mask,
301         const char *initiator_name);
302 void scst_free_session(struct scst_session *sess);
303 void scst_free_session_callback(struct scst_session *sess);
304
305 struct scst_cmd *scst_alloc_cmd(int gfp_mask);
306 void scst_free_cmd(struct scst_cmd *cmd);
307 static inline void scst_destroy_cmd(struct scst_cmd *cmd)
308 {
309         kmem_cache_free(scst_cmd_cachep, cmd);
310         return;
311 }
312
313 void scst_proccess_redirect_cmd(struct scst_cmd *cmd, int context,
314         int check_retries);
315 void scst_check_retries(struct scst_tgt *tgt);
316 void scst_tgt_retry_timer_fn(unsigned long arg);
317
318 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
319 int scst_alloc_request(struct scst_cmd *cmd);
320 void scst_release_request(struct scst_cmd *cmd);
321
322 static inline void scst_do_req(struct scsi_request *sreq, 
323         const void *cmnd, void *buffer, unsigned bufflen, 
324         void (*done)(struct scsi_cmnd *), int timeout, int retries)
325 {
326     #ifdef STRICT_SERIALIZING
327         scsi_do_req(sreq, cmnd, buffer, bufflen, done, timeout, retries);
328     #elif !defined(SCSI_EXEC_REQ_FIFO_DEFINED)
329         sBUG();
330     #else
331         scsi_do_req_fifo(sreq, cmnd, buffer, bufflen, done, timeout, retries);
332     #endif
333 }
334 #else
335 static inline int scst_exec_req(struct scsi_device *sdev,
336         const unsigned char *cmd, int cmd_len, int data_direction,
337         void *buffer, unsigned bufflen, int use_sg, int timeout, int retries,
338         void *privdata, void (*done)(void *, char *, int, int), gfp_t gfp)
339 {
340     #ifdef STRICT_SERIALIZING
341         return scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer,
342                 bufflen, use_sg, timeout, retries, privdata, done, gfp);
343     #elif !defined(SCSI_EXEC_REQ_FIFO_DEFINED)
344         sBUG();
345         return -1;
346     #else
347         return scsi_execute_async_fifo(sdev, cmd, cmd_len, data_direction,
348                 buffer, bufflen, use_sg, timeout, retries, privdata, done, gfp);
349     #endif
350 }
351 #endif
352
353 int scst_alloc_space(struct scst_cmd *cmd);
354 void scst_release_space(struct scst_cmd *cmd);
355 void scst_scsi_op_list_init(void);
356
357 lun_t scst_unpack_lun(const uint8_t *lun, int len);
358
359 struct scst_cmd *__scst_find_cmd_by_tag(struct scst_session *sess, 
360         uint64_t tag);
361
362 struct scst_mgmt_cmd *scst_alloc_mgmt_cmd(int gfp_mask);
363 void scst_free_mgmt_cmd(struct scst_mgmt_cmd *mcmd);
364 void scst_done_cmd_mgmt(struct scst_cmd *cmd);
365
366 /* /proc support */
367 int scst_proc_init_module(void);
368 void scst_proc_cleanup_module(void);
369 int scst_build_proc_target_dir_entries(struct scst_tgt_template *vtt);
370 void scst_cleanup_proc_target_dir_entries(struct scst_tgt_template *vtt);
371 int scst_build_proc_target_entries(struct scst_tgt *vtt);
372 void scst_cleanup_proc_target_entries(struct scst_tgt *vtt);
373 int scst_build_proc_dev_handler_dir_entries(struct scst_dev_type *dev_type);
374 void scst_cleanup_proc_dev_handler_dir_entries(struct scst_dev_type *dev_type);
375
376 int scst_get_cdb_len(const uint8_t *cdb);
377
378 void __scst_dev_check_set_UA(struct scst_device *dev, struct scst_cmd *exclude,
379         const uint8_t *sense, int sense_len);
380 static inline void scst_dev_check_set_UA(struct scst_device *dev,
381         struct scst_cmd *exclude, const uint8_t *sense, int sense_len)
382 {
383         spin_lock_bh(&dev->dev_lock);
384         __scst_dev_check_set_UA(dev, exclude, sense, sense_len);
385         spin_unlock_bh(&dev->dev_lock);
386         return;
387 }
388 void scst_dev_check_set_local_UA(struct scst_device *dev,
389         struct scst_cmd *exclude, const uint8_t *sense, int sense_len);
390
391 void scst_check_set_UA(struct scst_tgt_dev *tgt_dev,
392         const uint8_t *sense, int sense_len, int head);
393 void scst_alloc_set_UA(struct scst_tgt_dev *tgt_dev, const uint8_t *sense,
394         int sense_len, int head);
395 void scst_free_all_UA(struct scst_tgt_dev *tgt_dev);
396 int scst_set_pending_UA(struct scst_cmd *cmd);
397
398 void scst_abort_cmd(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd,
399         int other_ini, int call_dev_task_mgmt_fn);
400 void scst_process_reset(struct scst_device *dev,
401         struct scst_session *originator, struct scst_cmd *exclude_cmd,
402         struct scst_mgmt_cmd *mcmd);
403
404 static inline int scst_is_ua_command(struct scst_cmd *cmd)
405 {
406         return ((cmd->cdb[0] != INQUIRY) && 
407                 (cmd->cdb[0] != REQUEST_SENSE) &&
408                 (cmd->cdb[0] != REPORT_LUNS));
409 }
410
411 static inline int scst_is_implicit_hq(struct scst_cmd *cmd)
412 {
413         return ((cmd->cdb[0] == INQUIRY) ||
414                 (cmd->cdb[0] == REPORT_LUNS) ||
415                 ((cmd->dev->type == TYPE_DISK) &&
416                    ((cmd->cdb[0] == READ_CAPACITY) ||
417                     ((cmd->cdb[0] == SERVICE_ACTION_IN) &&
418                        ((cmd->cdb[1] & 0x1f) == SAI_READ_CAPACITY_16)))));
419 }
420
421 /*
422  * Some notes on devices "blocking". Blocking means that no
423  * commands will go from SCST to underlying SCSI device until it 
424  * is unblocked. But we don't care about all commands that 
425  * already on the device.
426  */
427
428 extern int scst_inc_on_dev_cmd(struct scst_cmd *cmd);
429 extern void scst_unblock_cmds(struct scst_device *dev);
430
431 extern void __scst_block_dev(struct scst_device *dev);
432 extern void scst_block_dev(struct scst_device *dev, int outstanding);
433 extern void scst_block_dev_cmd(struct scst_cmd *cmd, int outstanding);
434 extern void scst_unblock_dev(struct scst_device *dev);
435 extern void scst_unblock_dev_cmd(struct scst_cmd *cmd);
436
437 static inline void __scst_dec_on_dev_cmd(struct scst_device *dev,
438         int unblock_dev)
439 {
440         if (unblock_dev)
441                 scst_unblock_dev(dev);
442         atomic_dec(&dev->on_dev_count);
443         smp_mb__after_atomic_dec();
444         TRACE_DBG("New on_dev_count %d", atomic_read(&dev->on_dev_count));
445         sBUG_ON(atomic_read(&dev->on_dev_count) < 0);
446         if (unlikely(dev->block_count != 0))
447                 wake_up_all(&dev->on_dev_waitQ);
448 }
449
450 static inline int scst_pre_dec_on_dev_cmd(struct scst_cmd *cmd)
451 {
452         int cmd_blocking = cmd->inc_blocking;
453         if (cmd_blocking) {
454                 TRACE_MGMT_DBG("cmd %p (tag %llu): unblocking dev %p", cmd,
455                         cmd->tag, cmd->dev);
456                 cmd->inc_blocking = 0;
457         }
458         cmd->dec_on_dev_needed = 0;
459         return cmd_blocking;
460 }
461
462 static inline void scst_dec_on_dev_cmd(struct scst_cmd *cmd)
463 {
464         int cmd_blocking = scst_pre_dec_on_dev_cmd(cmd);
465         __scst_dec_on_dev_cmd(cmd->dev, cmd_blocking);
466 }
467
468 static inline void __scst_get(int barrier)
469 {
470         atomic_inc(&scst_cmd_count);
471         TRACE_DBG("Incrementing scst_cmd_count(%d)",
472                 atomic_read(&scst_cmd_count));
473
474         if (barrier)
475                 smp_mb__after_atomic_inc();
476 }
477
478 static inline void __scst_put(void)
479 {
480         int f;
481         f = atomic_dec_and_test(&scst_cmd_count);
482         if (f && unlikely(test_bit(SCST_FLAG_SUSPENDED, &scst_flags))) {
483                 TRACE_MGMT_DBG("%s", "Waking up scst_dev_cmd_waitQ");
484                 wake_up_all(&scst_dev_cmd_waitQ);
485         }
486         TRACE_DBG("Decrementing scst_cmd_count(%d)",
487               atomic_read(&scst_cmd_count));
488 }
489
490 void scst_sched_session_free(struct scst_session *sess);
491
492 static inline void scst_sess_get(struct scst_session *sess)
493 {
494         atomic_inc(&sess->refcnt);
495 }
496
497 static inline void scst_sess_put(struct scst_session *sess)
498 {
499         if (atomic_dec_and_test(&sess->refcnt))
500                 scst_sched_session_free(sess);
501 }
502
503 static inline void __scst_cmd_get(struct scst_cmd *cmd)
504 {
505         atomic_inc(&cmd->cmd_ref);
506 }
507
508 static inline void __scst_cmd_put(struct scst_cmd *cmd)
509 {
510         if (atomic_dec_and_test(&cmd->cmd_ref))
511                 scst_free_cmd(cmd);
512 }
513
514 extern void scst_throttle_cmd(struct scst_cmd *cmd);
515 extern void scst_unthrottle_cmd(struct scst_cmd *cmd);
516
517 static inline void scst_check_restore_sg_buff(struct scst_cmd *cmd)
518 {
519         if (cmd->sg_buff_modified) {
520                 TRACE_MEM("cmd %p, sg %p, orig_sg_entry %d, "
521                         "orig_entry_len %d, orig_sg_cnt %d", cmd, cmd->sg,
522                         cmd->orig_sg_entry, cmd->orig_entry_len,
523                         cmd->orig_sg_cnt);
524                 cmd->sg[cmd->orig_sg_entry].length = cmd->orig_entry_len;
525                 cmd->sg_cnt = cmd->orig_sg_cnt;
526         }
527 }
528
529 #ifdef DEBUG_TM
530 extern void tm_dbg_init_tgt_dev(struct scst_tgt_dev *tgt_dev,
531         struct scst_acg_dev *acg_dev);
532 extern void tm_dbg_deinit_tgt_dev(struct scst_tgt_dev *tgt_dev);
533 extern void tm_dbg_check_released_cmds(void);
534 extern int tm_dbg_check_cmd(struct scst_cmd *cmd);
535 extern void tm_dbg_release_cmd(struct scst_cmd *cmd);
536 extern void tm_dbg_task_mgmt(struct scst_device *dev, const char *fn,
537         int force);
538 extern int tm_dbg_is_release(void);
539 #else
540 static inline void tm_dbg_init_tgt_dev(struct scst_tgt_dev *tgt_dev,
541         struct scst_acg_dev *acg_dev) {}
542 static inline void tm_dbg_deinit_tgt_dev(struct scst_tgt_dev *tgt_dev) {}
543 static inline void tm_dbg_check_released_cmds(void) {}
544 static inline int tm_dbg_check_cmd(struct scst_cmd *cmd)
545 {
546         return 0;
547 }
548 static inline void tm_dbg_release_cmd(struct scst_cmd *cmd) {}
549 static inline void tm_dbg_task_mgmt(struct scst_device *dev, const char *fn,
550         int force) {}
551 static inline int tm_dbg_is_release(void)
552 {
553         return 0;
554 }
555 #endif /* DEBUG_TM */
556
557 #ifdef DEBUG_SN
558 void scst_check_debug_sn(struct scst_cmd *cmd);
559 #else
560 static inline void scst_check_debug_sn(struct scst_cmd *cmd) {}
561 #endif
562
563 /*
564  * It deals with comparing 32 bit unsigned ints and worry about wraparound
565  * (automatic with unsigned arithmetic). Borrowed from net/tcp.h.
566  */
567 static inline int scst_sn_before(__u32 seq1, __u32 seq2)
568 {
569         return (__s32)(seq1-seq2) < 0;
570 }
571
572 #endif /* __SCST_PRIV_H */