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