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