Update to work on 2.6.20 + minor fix
[mirror/scst/.git] / scst / src / scst.c
1 /*
2  *  scst.c
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 #include <linux/module.h>
19
20 #include <linux/init.h>
21 #include <linux/kernel.h>
22 #include <linux/errno.h>
23 #include <linux/list.h>
24 #include <linux/spinlock.h>
25 #include <linux/slab.h>
26 #include <linux/sched.h>
27 #include <asm/unistd.h>
28 #include <asm/string.h>
29 #include <linux/kthread.h>
30
31 #include "scsi_tgt.h"
32 #include "scst_priv.h"
33 #include "scst_mem.h"
34
35 #if defined(DEBUG) || defined(TRACING)
36 unsigned long scst_trace_flag = SCST_DEFAULT_LOG_FLAGS;
37 #endif
38
39 /*
40  * All targets, devices and dev_types management is done under
41  * this mutex.
42  */
43 DECLARE_MUTEX(scst_mutex);
44
45 DECLARE_WAIT_QUEUE_HEAD(scst_dev_cmd_waitQ);
46 LIST_HEAD(scst_dev_wait_sess_list);
47
48 LIST_HEAD(scst_template_list);
49 LIST_HEAD(scst_dev_list);
50 LIST_HEAD(scst_dev_type_list);
51
52 struct kmem_cache *scst_mgmt_cachep;
53 mempool_t *scst_mgmt_mempool;
54 struct kmem_cache *scst_ua_cachep;
55 mempool_t *scst_ua_mempool;
56 struct kmem_cache *scst_tgtd_cachep;
57 struct kmem_cache *scst_sess_cachep;
58 struct kmem_cache *scst_acgd_cachep;
59
60 LIST_HEAD(scst_acg_list);
61 struct scst_acg *scst_default_acg;
62
63 struct kmem_cache *scst_cmd_cachep;
64
65 unsigned long scst_flags;
66 atomic_t scst_cmd_count = ATOMIC_INIT(0);
67 spinlock_t scst_list_lock = SPIN_LOCK_UNLOCKED;
68 LIST_HEAD(scst_active_cmd_list);
69 LIST_HEAD(scst_init_cmd_list);
70 LIST_HEAD(scst_cmd_list);
71 DECLARE_WAIT_QUEUE_HEAD(scst_list_waitQ);
72
73 spinlock_t scst_cmd_mem_lock = SPIN_LOCK_UNLOCKED;
74 unsigned long scst_cur_cmd_mem, scst_cur_max_cmd_mem;
75
76 struct tasklet_struct scst_tasklets[NR_CPUS];
77
78 struct scst_sgv_pools scst_sgv;
79
80 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
81 DECLARE_WORK(scst_cmd_mem_work, scst_cmd_mem_work_fn, 0);
82 #else
83 DECLARE_DELAYED_WORK(scst_cmd_mem_work, scst_cmd_mem_work_fn);
84 #endif
85
86 unsigned long scst_max_cmd_mem;
87
88 LIST_HEAD(scst_mgmt_cmd_list);
89 LIST_HEAD(scst_active_mgmt_cmd_list);
90 LIST_HEAD(scst_delayed_mgmt_cmd_list);
91 DECLARE_WAIT_QUEUE_HEAD(scst_mgmt_cmd_list_waitQ);
92
93 DECLARE_WAIT_QUEUE_HEAD(scst_mgmt_waitQ);
94 spinlock_t scst_mgmt_lock = SPIN_LOCK_UNLOCKED;
95 LIST_HEAD(scst_sess_mgmt_list);
96
97 static int scst_threads;
98 struct scst_threads_info_t scst_threads_info;
99
100 static int suspend_count;
101
102 int scst_virt_dev_last_id = 1; /* protected by scst_mutex */
103
104 /* 
105  * This buffer and lock are intended to avoid memory allocation, which
106  * could fail in improper places.
107  */
108 spinlock_t scst_temp_UA_lock = SPIN_LOCK_UNLOCKED;
109 uint8_t scst_temp_UA[SCSI_SENSE_BUFFERSIZE];
110
111 module_param_named(scst_threads, scst_threads, int, 0);
112 MODULE_PARM_DESC(scst_threads, "SCSI target threads count");
113
114 module_param_named(scst_max_cmd_mem, scst_max_cmd_mem, long, 0);
115 MODULE_PARM_DESC(scst_max_cmd_mem, "Maximum memory allowed to be consumed by "
116         "the SCST commands at any given time in Mb");
117
118 int scst_register_target_template(struct scst_tgt_template *vtt)
119 {
120         int res = 0;
121         struct scst_tgt_template *t;
122         static DECLARE_MUTEX(m);
123
124         TRACE_ENTRY();
125
126         INIT_LIST_HEAD(&vtt->tgt_list);
127
128         if (!vtt->detect) {
129                 PRINT_ERROR_PR("Target driver %s doesn't have a "
130                         "detect() method.", vtt->name);
131                 res = -EINVAL;
132                 goto out_err;
133         }
134         
135         if (!vtt->release) {
136                 PRINT_ERROR_PR("Target driver %s doesn't have a "
137                         "release() method.", vtt->name);
138                 res = -EINVAL;
139                 goto out_err;
140         }
141
142         if (!vtt->xmit_response) {
143                 PRINT_ERROR_PR("Target driver %s doesn't have a "
144                         "xmit_response() method.", vtt->name);
145                 res = -EINVAL;
146                 goto out_err;
147         }
148
149         if (!vtt->no_proc_entry) {
150                 res = scst_build_proc_target_dir_entries(vtt);
151                 if (res < 0)
152                         goto out_err;
153         }
154
155         if (down_interruptible(&m) != 0)
156                 goto out_err;
157
158         if (down_interruptible(&scst_mutex) != 0)
159                 goto out_m_up;
160         list_for_each_entry(t, &scst_template_list, scst_template_list_entry) {
161                 if (strcmp(t->name, vtt->name) == 0) {
162                         PRINT_ERROR_PR("Target driver %s already registered",
163                                 vtt->name);
164                         up(&scst_mutex);
165                         goto out_cleanup;
166                 }
167         }
168         up(&scst_mutex);
169
170         TRACE_DBG("%s", "Calling target driver's detect()");
171         res = vtt->detect(vtt);
172         TRACE_DBG("Target driver's detect() returned %d", res);
173         if (res < 0) {
174                 PRINT_ERROR_PR("%s", "The detect() routine failed");
175                 res = -EINVAL;
176                 goto out_cleanup;
177         }
178
179         down(&scst_mutex);
180         list_add_tail(&vtt->scst_template_list_entry, &scst_template_list);
181         up(&scst_mutex);
182
183         res = 0;
184
185         PRINT_INFO_PR("Target template %s registered successfully", vtt->name);
186
187         up(&m);
188
189 out:
190         TRACE_EXIT_RES(res);
191         return res;
192
193 out_m_up:
194         up(&m);
195
196 out_cleanup:
197         scst_cleanup_proc_target_dir_entries(vtt);
198
199 out_err:
200         PRINT_ERROR_PR("Failed to register target template %s", vtt->name);
201         goto out;
202 }
203
204 void scst_unregister_target_template(struct scst_tgt_template *vtt)
205 {
206         struct scst_tgt *tgt;
207         struct scst_tgt_template *t;
208         int found = 0;
209
210         TRACE_ENTRY();
211
212         down(&scst_mutex);
213
214         list_for_each_entry(t, &scst_template_list, scst_template_list_entry) {
215                 if (strcmp(t->name, vtt->name) == 0) {
216                         found = 1;
217                         break;
218                 }
219         }
220         if (!found) {
221                 PRINT_ERROR_PR("Target driver %s isn't registered", vtt->name);
222                 goto out_up;
223         }
224
225 restart:
226         list_for_each_entry(tgt, &vtt->tgt_list, tgt_list_entry) {
227                 up(&scst_mutex);
228                 scst_unregister(tgt);
229                 down(&scst_mutex);
230                 goto restart;
231         }
232         list_del(&vtt->scst_template_list_entry);
233
234         PRINT_INFO_PR("Target template %s unregistered successfully", vtt->name);
235
236 out_up:
237         up(&scst_mutex);
238
239         scst_cleanup_proc_target_dir_entries(vtt);
240
241         TRACE_EXIT();
242         return;
243 }
244
245 struct scst_tgt *scst_register(struct scst_tgt_template *vtt)
246 {
247         struct scst_tgt *tgt;
248
249         TRACE_ENTRY();
250
251         tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
252         if (tgt == NULL) {
253                 TRACE(TRACE_OUT_OF_MEM, "%s", "kzalloc() failed");
254                 goto out_err;
255         }
256
257         INIT_LIST_HEAD(&tgt->sess_list);
258         init_waitqueue_head(&tgt->unreg_waitQ);
259         tgt->tgtt = vtt;
260         tgt->sg_tablesize = vtt->sg_tablesize;
261         spin_lock_init(&tgt->tgt_lock);
262         INIT_LIST_HEAD(&tgt->retry_cmd_list);
263         atomic_set(&tgt->finished_cmds, 0);
264         init_timer(&tgt->retry_timer);
265         tgt->retry_timer.data = (unsigned long)tgt;
266         tgt->retry_timer.function = scst_tgt_retry_timer_fn;
267
268         down(&scst_mutex);
269
270         if (scst_build_proc_target_entries(tgt) < 0) {
271                 kfree(tgt);
272                 tgt = NULL;
273                 goto out_up;
274         } else
275                 list_add_tail(&tgt->tgt_list_entry, &vtt->tgt_list);
276
277         up(&scst_mutex);
278
279         PRINT_INFO_PR("Target for template %s registered successfully",
280                 vtt->name);
281
282 out:
283         TRACE_EXIT();
284         return tgt;
285
286 out_up:
287         up(&scst_mutex);
288
289 out_err:
290         PRINT_ERROR_PR("Failed to register target for template %s", vtt->name);
291         goto out;
292 }
293
294 static inline int test_sess_list(struct scst_tgt *tgt)
295 {
296         int res;
297         down(&scst_mutex);
298         res = list_empty(&tgt->sess_list);
299         up(&scst_mutex);
300         return res;
301 }
302
303 void scst_unregister(struct scst_tgt *tgt)
304 {
305         struct scst_session *sess;
306         struct scst_tgt_template *vtt = tgt->tgtt;
307
308         TRACE_ENTRY();
309
310         TRACE_DBG("%s", "Calling target driver's release()");
311         tgt->tgtt->release(tgt);
312         TRACE_DBG("%s", "Target driver's release() returned");
313
314         down(&scst_mutex);
315         list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) {
316                 sBUG_ON(!sess->shutting_down);
317         }
318         up(&scst_mutex);
319
320         TRACE_DBG("%s", "Waiting for sessions shutdown");
321         wait_event(tgt->unreg_waitQ, test_sess_list(tgt));
322         TRACE_DBG("%s", "wait_event() returned");
323
324         down(&scst_mutex);
325         list_del(&tgt->tgt_list_entry);
326         up(&scst_mutex);
327
328         scst_cleanup_proc_target_entries(tgt);
329
330         del_timer_sync(&tgt->retry_timer);
331
332         kfree(tgt);
333
334         PRINT_INFO_PR("Target for template %s unregistered successfully",
335                 vtt->name);
336
337         TRACE_EXIT();
338         return;
339 }
340
341 /* scst_mutex supposed to be held */
342 void __scst_suspend_activity(void)
343 {
344         TRACE_ENTRY();
345
346         suspend_count++;
347         if (suspend_count > 1)
348                 goto out;
349
350         set_bit(SCST_FLAG_SUSPENDED, &scst_flags);
351         smp_mb__after_set_bit();
352
353         TRACE_DBG("Waiting for all %d active commands to complete",
354               atomic_read(&scst_cmd_count));
355         wait_event(scst_dev_cmd_waitQ, atomic_read(&scst_cmd_count) == 0);
356         TRACE_DBG("%s", "wait_event() returned");
357
358 out:
359         TRACE_EXIT();
360         return;
361 }
362
363 void scst_suspend_activity(void)
364 {
365         down(&scst_mutex);
366         __scst_suspend_activity();
367 }
368
369 /* scst_mutex supposed to be held */
370 void __scst_resume_activity(void)
371 {
372         struct scst_session *sess, *tsess;
373
374         TRACE_ENTRY();
375
376         suspend_count--;
377         if (suspend_count > 0)
378                 goto out;
379
380         clear_bit(SCST_FLAG_SUSPENDED, &scst_flags);
381         smp_mb__after_clear_bit();
382
383         spin_lock_irq(&scst_list_lock);
384         list_for_each_entry_safe(sess, tsess, &scst_dev_wait_sess_list,
385                             dev_wait_sess_list_entry) 
386         {
387                 sess->waiting = 0;
388                 list_del(&sess->dev_wait_sess_list_entry);
389         }
390         spin_unlock_irq(&scst_list_lock);
391
392         wake_up_all(&scst_list_waitQ);
393         wake_up_all(&scst_mgmt_cmd_list_waitQ);
394
395 out:
396         TRACE_EXIT();
397         return;
398 }
399
400 void scst_resume_activity(void)
401 {
402         __scst_resume_activity();
403         up(&scst_mutex);
404 }
405
406 /* Called under scst_mutex */
407 static int scst_register_device(struct scsi_device *scsidp)
408 {
409         int res = 0;
410         struct scst_device *dev;
411         struct scst_dev_type *dt;
412
413         TRACE_ENTRY();
414
415         dev = scst_alloc_device(GFP_KERNEL);
416         if (dev == NULL) {
417                 res = -ENOMEM;
418                 goto out;
419         }
420         
421         dev->rq_disk = alloc_disk(1);
422         if (dev->rq_disk == NULL) {
423                 res = -ENOMEM;
424                 goto out_free_dev;
425         }
426         dev->rq_disk->major = SCST_MAJOR;
427
428         dev->scsi_dev = scsidp;
429
430         list_add_tail(&dev->dev_list_entry, &scst_dev_list);
431         
432         list_for_each_entry(dt, &scst_dev_type_list, dev_type_list_entry) {
433                 if (dt->type == scsidp->type) {
434                         res = scst_assign_dev_handler(dev, dt);
435                         if (res != 0)
436                                 goto out_free;
437                         break;
438                 }
439         }
440
441 out:
442         if (res == 0) {
443                 PRINT_INFO_PR("Attached SCSI target mid-level at "
444                     "scsi%d, channel %d, id %d, lun %d, type %d", 
445                     scsidp->host->host_no, scsidp->channel, scsidp->id, 
446                     scsidp->lun, scsidp->type);
447         } 
448         else {
449                 PRINT_ERROR_PR("Failed to attach SCSI target mid-level "
450                     "at scsi%d, channel %d, id %d, lun %d, type %d", 
451                     scsidp->host->host_no, scsidp->channel, scsidp->id, 
452                     scsidp->lun, scsidp->type);
453         }
454
455         TRACE_EXIT_RES(res);
456         return res;
457
458 out_free:
459         list_del(&dev->dev_list_entry);
460         put_disk(dev->rq_disk);
461
462 out_free_dev:
463         scst_free_device(dev);
464         goto out;
465 }
466
467 /* Called under scst_mutex */
468 static void scst_unregister_device(struct scsi_device *scsidp)
469 {
470         struct scst_device *d, *dev = NULL;
471         struct scst_acg_dev *acg_dev, *aa;
472
473         TRACE_ENTRY();
474         
475         __scst_suspend_activity();
476
477         list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
478                 if (d->scsi_dev == scsidp) {
479                         dev = d;
480                         TRACE_DBG("Target device %p found", dev);
481                         break;
482                 }
483         }
484         if (dev == NULL) {
485                 PRINT_ERROR_PR("%s", "Target device not found");
486                 goto out_unblock;
487         }
488
489         list_del(&dev->dev_list_entry);
490         
491         list_for_each_entry_safe(acg_dev, aa, &dev->dev_acg_dev_list,
492                                  dev_acg_dev_list_entry) 
493         {
494                 scst_acg_remove_dev(acg_dev->acg, dev);
495         }
496
497         scst_assign_dev_handler(dev, NULL);
498
499         put_disk(dev->rq_disk);
500         scst_free_device(dev);
501
502         PRINT_INFO_PR("Detached SCSI target mid-level from scsi%d, channel %d, "
503                 "id %d, lun %d, type %d", scsidp->host->host_no,
504                 scsidp->channel, scsidp->id, scsidp->lun, scsidp->type);
505
506 out_unblock:
507         __scst_resume_activity();
508
509         TRACE_EXIT();
510         return;
511 }
512
513 int scst_register_virtual_device(struct scst_dev_type *dev_handler, 
514         const char *dev_name)
515 {
516         int res = -EINVAL, rc;
517         struct scst_device *dev = NULL;
518
519         TRACE_ENTRY();
520         
521         if (dev_handler == NULL) {
522                 PRINT_ERROR_PR("%s: valid device handler must be supplied", 
523                         __FUNCTION__);
524                 res = -EINVAL;
525                 goto out;
526         }
527         
528         if (dev_name == NULL) {
529                 PRINT_ERROR_PR("%s: device name must be non-NULL", __FUNCTION__);
530                 res = -EINVAL;
531                 goto out;
532         }
533
534         dev = scst_alloc_device(GFP_KERNEL);
535         if (dev == NULL) {
536                 res = -ENOMEM;
537                 goto out;
538         }
539
540         dev->scsi_dev = NULL;
541         dev->virt_name = dev_name;
542
543         if (down_interruptible(&scst_mutex) != 0) {
544                 res = -EINTR;
545                 goto out_free_dev;
546         }
547
548         dev->virt_id = scst_virt_dev_last_id++;
549
550         list_add_tail(&dev->dev_list_entry, &scst_dev_list);
551
552         res = dev->virt_id;
553
554         rc = scst_assign_dev_handler(dev, dev_handler);
555         if (rc != 0) {
556                 res = rc;
557                 goto out_free_del;
558         }
559         
560         up(&scst_mutex);
561
562 out:
563         if (res > 0) {
564                 PRINT_INFO_PR("Attached SCSI target mid-level to virtual "
565                     "device %s (id %d)", dev_name, dev->virt_id);
566         } 
567         else {
568                 PRINT_INFO_PR("Failed to attach SCSI target mid-level to "
569                     "virtual device %s", dev_name);
570         }
571
572         TRACE_EXIT_RES(res);
573         return res;
574
575 out_free_del:
576         list_del(&dev->dev_list_entry);
577         up(&scst_mutex);
578
579 out_free_dev:
580         scst_free_device(dev);
581         goto out;
582 }
583
584 void scst_unregister_virtual_device(int id)
585 {
586         struct scst_device *d, *dev = NULL;
587         struct scst_acg_dev *acg_dev, *aa;
588
589         TRACE_ENTRY();
590
591         down(&scst_mutex);
592
593         __scst_suspend_activity();
594
595         list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
596                 if (d->virt_id == id) {
597                         dev = d;
598                         TRACE_DBG("Target device %p found", dev);
599                         break;
600                 }
601         }
602         if (dev == NULL) {
603                 PRINT_ERROR_PR("%s", "Target device not found");
604                 goto out_unblock;
605         }
606
607         list_del(&dev->dev_list_entry);
608         
609         list_for_each_entry_safe(acg_dev, aa, &dev->dev_acg_dev_list,
610                                  dev_acg_dev_list_entry) 
611         {
612                 scst_acg_remove_dev(acg_dev->acg, dev);
613         }
614
615         scst_assign_dev_handler(dev, NULL);
616
617         PRINT_INFO_PR("Detached SCSI target mid-level from virtual device %s "
618                 "(id %d)", dev->virt_name, dev->virt_id);
619
620         scst_free_device(dev);
621
622 out_unblock:
623         __scst_resume_activity();
624
625         up(&scst_mutex);
626
627         TRACE_EXIT();
628         return;
629 }
630
631 int scst_register_dev_driver(struct scst_dev_type *dev_type)
632 {
633         struct scst_dev_type *dt;
634         struct scst_device *dev;
635         int res = 0;
636         int exist;
637
638         TRACE_ENTRY();
639
640         if (dev_type->parse == NULL) {
641                 PRINT_ERROR_PR("scst dev_type driver %s doesn't have a "
642                         "parse() method.", dev_type->name);
643                 res = -EINVAL;
644                 goto out_err;
645         }
646
647 #ifdef FILEIO_ONLY
648         if (dev_type->exec == NULL) {
649                 PRINT_ERROR_PR("Pass-through dev handlers (handler %s) not "
650                         "supported. Recompile SCST with undefined FILEIO_ONLY",
651                         dev_type->name);
652                 res = -EINVAL;
653                 goto out_err;
654         }
655 #endif
656
657         if (down_interruptible(&scst_mutex) != 0) {
658                 res = -EINTR;
659                 goto out_err;
660         }
661
662         exist = 0;
663         list_for_each_entry(dt, &scst_dev_type_list, dev_type_list_entry) {
664                 if (strcmp(dt->name, dev_type->name) == 0) {
665                         PRINT_ERROR_PR("Device type handler %s already exist",
666                                 dt->name);
667                         exist = 1;
668                         break;
669                 }
670         }
671         if (exist)
672                 goto out_up;
673
674         res = scst_build_proc_dev_handler_dir_entries(dev_type);
675         if (res < 0) {
676                 goto out_up;
677         }
678
679         list_add_tail(&dev_type->dev_type_list_entry, &scst_dev_type_list);
680
681         __scst_suspend_activity();
682         list_for_each_entry(dev, &scst_dev_list, dev_list_entry) {
683                 if ((dev->scsi_dev == NULL) || (dev->handler != NULL))
684                         continue;
685                 if (dev->scsi_dev->type == dev_type->type)
686                         scst_assign_dev_handler(dev, dev_type);
687         }
688         __scst_resume_activity();
689
690         up(&scst_mutex);
691
692         if (res == 0) {
693                 PRINT_INFO_PR("Device handler %s for type %d registered "
694                         "successfully", dev_type->name, dev_type->type);
695         }
696
697 out:
698         TRACE_EXIT_RES(res);
699         return res;
700
701 out_up:
702         up(&scst_mutex);
703
704 out_err:
705         PRINT_ERROR_PR("Failed to register device handler %s for type %d",
706                 dev_type->name, dev_type->type);
707         goto out;
708 }
709
710 void scst_unregister_dev_driver(struct scst_dev_type *dev_type)
711 {
712         struct scst_device *dev;
713         struct scst_dev_type *dt;
714         int found = 0;
715
716         TRACE_ENTRY();
717
718         down(&scst_mutex);
719
720         list_for_each_entry(dt, &scst_dev_type_list, dev_type_list_entry) {
721                 if (strcmp(dt->name, dev_type->name) == 0) {
722                         found = 1;
723                         break;
724                 }
725         }
726         if (!found) {
727                 PRINT_ERROR_PR("Dev handler %s isn't registered",
728                         dev_type->name);
729                 goto out_up;
730         }
731
732         __scst_suspend_activity();
733         list_for_each_entry(dev, &scst_dev_list, dev_list_entry) {
734                 if (dev->handler == dev_type) {
735                         scst_assign_dev_handler(dev, NULL);
736                         TRACE_DBG("Dev handler removed from device %p", dev);
737                 }
738         }
739         __scst_resume_activity();
740
741         list_del(&dev_type->dev_type_list_entry);
742
743         up(&scst_mutex);
744
745         scst_cleanup_proc_dev_handler_dir_entries(dev_type);
746
747         PRINT_INFO_PR("Device handler %s for type %d unloaded",
748                    dev_type->name, dev_type->type);
749
750 out:
751         TRACE_EXIT();
752         return;
753
754 out_up:
755         up(&scst_mutex);
756         goto out;
757 }
758
759 int scst_register_virtual_dev_driver(struct scst_dev_type *dev_type)
760 {
761         int res = 0;
762
763         TRACE_ENTRY();
764
765         if (dev_type->parse == NULL) {
766                 PRINT_ERROR_PR("scst dev_type driver %s doesn't have a "
767                         "parse() method.", dev_type->name);
768                 res = -EINVAL;
769                 goto out_err;
770         }
771
772         res = scst_build_proc_dev_handler_dir_entries(dev_type);
773         if (res < 0)
774                 goto out_err;
775         
776         PRINT_INFO_PR("Virtuel device handler %s for type %d registered "
777                 "successfully", dev_type->name, dev_type->type);
778
779 out:
780         TRACE_EXIT_RES(res);
781         return res;
782
783 out_err:
784         PRINT_ERROR_PR("Failed to register virtual device handler %s for "
785                 "type %d", dev_type->name, dev_type->type);
786         goto out;
787 }
788
789 void scst_unregister_virtual_dev_driver(struct scst_dev_type *dev_type)
790 {
791         TRACE_ENTRY();
792
793         scst_cleanup_proc_dev_handler_dir_entries(dev_type);
794
795         PRINT_INFO_PR("Device handler %s for type %d unloaded",
796                    dev_type->name, dev_type->type);
797
798         TRACE_EXIT();
799         return;
800 }
801
802 /* scst_mutex supposed to be held */
803 int scst_assign_dev_handler(struct scst_device *dev, 
804         struct scst_dev_type *handler)
805 {
806         int res = 0;
807         struct scst_tgt_dev *tgt_dev;
808         LIST_HEAD(attached_tgt_devs);
809         
810         TRACE_ENTRY();
811         
812         if (dev->handler == handler)
813                 goto out;
814         
815         __scst_suspend_activity();
816
817         if (dev->handler && dev->handler->detach_tgt) {
818                 list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, 
819                         dev_tgt_dev_list_entry) 
820                 {
821                         TRACE_DBG("Calling dev handler's detach_tgt(%p)",
822                                 tgt_dev);
823                         dev->handler->detach_tgt(tgt_dev);
824                         TRACE_DBG("%s", "Dev handler's detach_tgt() returned");
825                 }
826         }
827
828         if (dev->handler && dev->handler->detach) {
829                 TRACE_DBG("%s", "Calling dev handler's detach()");
830                 dev->handler->detach(dev);
831                 TRACE_DBG("%s", "Old handler's detach() returned");
832         }
833
834         dev->handler = handler;
835
836         if (handler && handler->attach) {
837                 TRACE_DBG("Calling new dev handler's attach(%p)", dev);
838                 res = handler->attach(dev);
839                 TRACE_DBG("New dev handler's attach() returned %d", res);
840                 if (res != 0) {
841                         PRINT_ERROR_PR("New device handler's %s attach() "
842                                 "failed: %d", handler->name, res);
843                 }
844                 goto out_resume;
845         }
846         
847         if (handler && handler->attach_tgt) {
848                 list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, 
849                         dev_tgt_dev_list_entry) 
850                 {
851                         TRACE_DBG("Calling dev handler's attach_tgt(%p)",
852                                 tgt_dev);
853                         res = handler->attach_tgt(tgt_dev);
854                         TRACE_DBG("%s", "Dev handler's attach_tgt() returned");
855                         if (res != 0) {
856                                 PRINT_ERROR_PR("Device handler's %s attach_tgt() "
857                                     "failed: %d", handler->name, res);
858                                 goto out_err_detach_tgt;
859                         }
860                         list_add_tail(&tgt_dev->extra_tgt_dev_list_entry,
861                                 &attached_tgt_devs);
862                 }
863         }
864         
865 out_resume:
866         if (res != 0)
867                 dev->handler = NULL;
868         __scst_resume_activity();
869         
870 out:
871         TRACE_EXIT_RES(res);
872         return res;
873
874 out_err_detach_tgt:
875         if (handler && handler->detach_tgt) {
876                 list_for_each_entry(tgt_dev, &attached_tgt_devs,
877                                  extra_tgt_dev_list_entry) 
878                 {
879                         TRACE_DBG("Calling handler's detach_tgt(%p)",
880                                 tgt_dev);
881                         handler->detach_tgt(tgt_dev);
882                         TRACE_DBG("%s", "Handler's detach_tgt() returned");
883                 }
884         }
885         if (handler && handler->detach) {
886                 TRACE_DBG("%s", "Calling handler's detach()");
887                 handler->detach(dev);
888                 TRACE_DBG("%s", "Hhandler's detach() returned");
889         }
890         goto out_resume;
891 }
892
893 int scst_cmd_threads_count(void)
894 {
895         int i;
896
897         /* Just to lower the race window, when user can get just changed value */
898         down(&scst_threads_info.cmd_threads_mutex);
899         i = scst_threads_info.nr_cmd_threads;
900         up(&scst_threads_info.cmd_threads_mutex);
901         return i;
902 }
903
904 static void scst_threads_info_init(void)
905 {
906         memset(&scst_threads_info, 0, sizeof(scst_threads_info));
907         init_MUTEX(&scst_threads_info.cmd_threads_mutex);
908         INIT_LIST_HEAD(&scst_threads_info.cmd_threads_list);
909 }
910
911 /* scst_threads_info.cmd_threads_mutex supposed to be held */
912 void __scst_del_cmd_threads(int num)
913 {
914         struct scst_cmd_thread_t *ct, *tmp;
915         int i;
916
917         TRACE_ENTRY();
918
919         i = scst_threads_info.nr_cmd_threads;
920         if (num <= 0 || num > i) {
921                 PRINT_ERROR_PR("can not del %d cmd threads from %d", num, i);
922                 return;
923         }
924
925         list_for_each_entry_safe(ct, tmp, &scst_threads_info.cmd_threads_list,
926                                 thread_list_entry) {
927                 int res;
928
929                 res = kthread_stop(ct->cmd_thread);
930                 if (res < 0) {
931                         TRACE_MGMT_DBG("kthread_stop() failed: %d", res);
932                 }
933                 list_del(&ct->thread_list_entry);
934                 kfree(ct);
935                 scst_threads_info.nr_cmd_threads--;
936                 --num;
937                 if (num == 0)
938                         break;
939         }
940
941         TRACE_EXIT();
942         return;
943 }
944
945 /* scst_threads_info.cmd_threads_mutex supposed to be held */
946 int __scst_add_cmd_threads(int num)
947 {
948         int res = 0, i;
949         static int scst_thread_num = 0;
950         
951         TRACE_ENTRY();
952
953         for (i = 0; i < num; i++) {
954                 struct scst_cmd_thread_t *thr;
955
956                 thr = kmalloc(sizeof(*thr), GFP_KERNEL);
957                 if (!thr) {
958                         res = -ENOMEM;
959                         PRINT_ERROR_PR("fail to allocate thr %d", res);
960                         goto out_error;
961                 }
962                 thr->cmd_thread = kthread_run(scst_cmd_thread, 0, "scsi_tgt%d",
963                         scst_thread_num++);
964                 if (IS_ERR(thr->cmd_thread)) {
965                         res = PTR_ERR(thr->cmd_thread);
966                         PRINT_ERROR_PR("kthread_create() failed: %d", res);
967                         kfree(thr);
968                         goto out_error;
969                 }
970                 list_add(&thr->thread_list_entry,
971                         &scst_threads_info.cmd_threads_list);
972                 scst_threads_info.nr_cmd_threads++;
973         }
974         res = 0;
975
976 out:
977         TRACE_EXIT_RES(res);
978         return res;
979
980 out_error:
981         if (i > 0)
982                 __scst_del_cmd_threads(i - 1);
983         goto out;
984 }
985
986 int scst_add_cmd_threads(int num)
987 {
988         int res;
989
990         TRACE_ENTRY();
991
992         down(&scst_threads_info.cmd_threads_mutex);
993         res = __scst_add_cmd_threads(num);
994         up(&scst_threads_info.cmd_threads_mutex);
995
996         TRACE_EXIT_RES(res);
997         return res;
998 }
999
1000 void scst_del_cmd_threads(int num)
1001 {
1002         TRACE_ENTRY();
1003
1004         down(&scst_threads_info.cmd_threads_mutex);
1005         __scst_del_cmd_threads(num);
1006         up(&scst_threads_info.cmd_threads_mutex);
1007
1008         TRACE_EXIT();
1009         return;
1010 }
1011
1012 static void scst_stop_all_threads(void)
1013 {
1014         TRACE_ENTRY();
1015
1016         down(&scst_threads_info.cmd_threads_mutex);
1017         __scst_del_cmd_threads(scst_threads_info.nr_cmd_threads);
1018         if (scst_threads_info.mgmt_cmd_thread)
1019                 kthread_stop(scst_threads_info.mgmt_cmd_thread);
1020         if (scst_threads_info.mgmt_thread)
1021                 kthread_stop(scst_threads_info.mgmt_thread);
1022         up(&scst_threads_info.cmd_threads_mutex);
1023
1024         TRACE_EXIT();
1025         return;
1026 }
1027
1028 static int scst_start_all_threads(int num)
1029 {
1030         int res;
1031
1032         TRACE_ENTRY();
1033
1034         down(&scst_threads_info.cmd_threads_mutex);             
1035         res = __scst_add_cmd_threads(num);
1036         if (res < 0)
1037                 goto out;
1038
1039         scst_threads_info.mgmt_cmd_thread = kthread_run(scst_mgmt_cmd_thread,
1040                 NULL, "scsi_tgt_mc");
1041         if (IS_ERR(scst_threads_info.mgmt_cmd_thread)) {
1042                 res = PTR_ERR(scst_threads_info.mgmt_cmd_thread);
1043                 PRINT_ERROR_PR("kthread_create() for mcmd failed: %d", res);
1044                 scst_threads_info.mgmt_cmd_thread = NULL;
1045                 goto out;
1046         }
1047
1048         scst_threads_info.mgmt_thread = kthread_run(scst_mgmt_thread,
1049                 NULL, "scsi_tgt_mgmt");
1050         if (IS_ERR(scst_threads_info.mgmt_thread)) {
1051                 res = PTR_ERR(scst_threads_info.mgmt_thread);
1052                 PRINT_ERROR_PR("kthread_create() for mgmt failed: %d", res);
1053                 scst_threads_info.mgmt_thread = NULL;
1054                 goto out;
1055         }
1056
1057 out:
1058         up(&scst_threads_info.cmd_threads_mutex);
1059         TRACE_EXIT_RES(res);
1060         return res;     
1061 }
1062
1063 void scst_get(void)
1064 {
1065         scst_inc_cmd_count();
1066 }
1067
1068 void scst_put(void)
1069 {
1070         scst_dec_cmd_count();
1071 }
1072
1073 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
1074 static int scst_add(struct class_device *cdev)
1075 #else
1076 static int scst_add(struct class_device *cdev, struct class_interface *intf)
1077 #endif
1078 {
1079         struct scsi_device *scsidp;
1080         int res = 0;
1081
1082         TRACE_ENTRY();
1083         
1084         scsidp = to_scsi_device(cdev->dev);
1085         
1086         down(&scst_mutex);
1087         res = scst_register_device(scsidp);
1088         up(&scst_mutex);
1089
1090         TRACE_EXIT();
1091         return res;
1092 }
1093
1094 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
1095 static void scst_remove(struct class_device *cdev)
1096 #else
1097 static void scst_remove(struct class_device *cdev, struct class_interface *intf)
1098 #endif
1099 {
1100         struct scsi_device *scsidp;
1101
1102         TRACE_ENTRY();
1103
1104         scsidp = to_scsi_device(cdev->dev);
1105
1106         down(&scst_mutex);
1107         scst_unregister_device(scsidp);
1108         up(&scst_mutex);
1109
1110         TRACE_EXIT();
1111         return;
1112 }
1113
1114 static struct class_interface scst_interface = {
1115         .add = scst_add,
1116         .remove = scst_remove,
1117 };
1118
1119 static int __init init_scst(void)
1120 {
1121         int res = 0, i;
1122         struct scst_cmd *cmd;
1123         int scst_num_cpus;
1124
1125         TRACE_ENTRY();
1126
1127 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
1128         {
1129                 struct scsi_request *req;
1130                 BUILD_BUG_ON(sizeof(cmd->sense_buffer) !=
1131                         sizeof(req->sr_sense_buffer));
1132         }
1133 #else
1134         {
1135                 struct scsi_sense_hdr *shdr;
1136                 BUILD_BUG_ON((sizeof(cmd->sense_buffer) < sizeof(*shdr)) &&
1137                         (sizeof(cmd->sense_buffer) >= SCSI_SENSE_BUFFERSIZE));
1138         }
1139 #endif
1140
1141         scst_num_cpus = num_online_cpus();
1142
1143         /* ToDo: register_cpu_notifier() */
1144         
1145         if (scst_threads == 0)
1146                 scst_threads = scst_num_cpus;
1147                 
1148         if (scst_threads < scst_num_cpus) {
1149                 PRINT_ERROR_PR("%s", "scst_threads can not be less than "
1150                         "CPUs count");
1151                 scst_threads = scst_num_cpus;
1152         }
1153
1154         scst_threads_info_init();
1155
1156 #define INIT_CACHEP(p, s, t, o) do {                                    \
1157                 p = kmem_cache_create(s, sizeof(struct t), 0,           \
1158                                       SCST_SLAB_FLAGS, NULL, NULL);     \
1159                 TRACE_MEM("Slab create: %s at %p size %zd", s, p,       \
1160                           sizeof(struct t));                            \
1161                 if (p == NULL) { res = -ENOMEM; goto o; }               \
1162         } while (0)
1163           
1164         INIT_CACHEP(scst_mgmt_cachep, SCST_MGMT_CMD_CACHE_STRING, 
1165                     scst_mgmt_cmd, out);
1166         INIT_CACHEP(scst_ua_cachep, SCST_UA_CACHE_STRING, 
1167                     scst_tgt_dev_UA, out_destroy_mgmt_cache);
1168         INIT_CACHEP(scst_cmd_cachep,  SCST_CMD_CACHE_STRING, 
1169                     scst_cmd, out_destroy_ua_cache);
1170         INIT_CACHEP(scst_sess_cachep, SCST_SESSION_CACHE_STRING,
1171                     scst_session, out_destroy_cmd_cache);
1172         INIT_CACHEP(scst_tgtd_cachep, SCST_TGT_DEV_CACHE_STRING,
1173                     scst_tgt_dev, out_destroy_sess_cache);
1174         INIT_CACHEP(scst_acgd_cachep, SCST_ACG_DEV_CACHE_STRING,
1175                     scst_acg_dev, out_destroy_tgt_cache);
1176
1177         scst_mgmt_mempool = mempool_create(10, mempool_alloc_slab,
1178                 mempool_free_slab, scst_mgmt_cachep);
1179         if (scst_mgmt_mempool == NULL) {
1180                 res = -ENOMEM;
1181                 goto out_destroy_acg_cache;
1182         }
1183
1184         scst_ua_mempool = mempool_create(25, mempool_alloc_slab,
1185                 mempool_free_slab, scst_ua_cachep);
1186         if (scst_ua_mempool == NULL) {
1187                 res = -ENOMEM;
1188                 goto out_destroy_mgmt_mempool;
1189         }
1190
1191         res = scst_sgv_pools_init(&scst_sgv);
1192         if (res != 0)
1193                 goto out_destroy_ua_mempool;
1194
1195         scst_default_acg = scst_alloc_add_acg(SCST_DEFAULT_ACG_NAME);
1196         if (scst_default_acg == NULL) {
1197                 res = -ENOMEM;
1198                 goto out_destroy_sgv_pool;
1199         }
1200         
1201         res = scsi_register_interface(&scst_interface);
1202         if (res != 0)
1203                 goto out_free_acg;
1204
1205         scst_scsi_op_list_init();
1206
1207         for (i = 0; i < sizeof(scst_tasklets)/sizeof(scst_tasklets[0]); i++)
1208                 tasklet_init(&scst_tasklets[i], (void *)scst_cmd_tasklet, 0);
1209
1210         TRACE_DBG("%d CPUs found, starting %d threads", scst_num_cpus,
1211                 scst_threads);
1212
1213         res = scst_start_all_threads(scst_threads);
1214         if (res < 0)
1215                 goto out_thread_free;
1216
1217         res = scst_proc_init_module();
1218         if (res != 0)
1219                 goto out_thread_free;
1220
1221         if (scst_max_cmd_mem == 0) {
1222                 struct sysinfo si;
1223                 si_meminfo(&si);
1224 #if BITS_PER_LONG == 32
1225                 scst_max_cmd_mem = min(((uint64_t)si.totalram << PAGE_SHIFT) >> 2,
1226                                         (uint64_t)1 << 30);
1227 #else
1228                 scst_max_cmd_mem = (si.totalram << PAGE_SHIFT) >> 2;
1229 #endif
1230         } else
1231                 scst_max_cmd_mem <<= 20;
1232
1233         scst_cur_max_cmd_mem = scst_max_cmd_mem;
1234
1235         PRINT_INFO_PR("SCST version %s loaded successfully (max mem for "
1236                 "commands %ld Mb)", SCST_VERSION_STRING, scst_max_cmd_mem >> 20);
1237
1238 out:
1239         TRACE_EXIT_RES(res);
1240         return res;
1241
1242 out_thread_free:
1243         scst_stop_all_threads();
1244
1245         scsi_unregister_interface(&scst_interface);
1246
1247 out_free_acg:
1248         scst_destroy_acg(scst_default_acg);
1249
1250 out_destroy_sgv_pool:
1251         scst_sgv_pools_deinit(&scst_sgv);
1252
1253 out_destroy_ua_mempool:
1254         mempool_destroy(scst_ua_mempool);
1255
1256 out_destroy_mgmt_mempool:
1257         mempool_destroy(scst_mgmt_mempool);
1258
1259 out_destroy_acg_cache:
1260         kmem_cache_destroy(scst_acgd_cachep);
1261
1262 out_destroy_tgt_cache:
1263         kmem_cache_destroy(scst_tgtd_cachep);
1264
1265 out_destroy_sess_cache:
1266         kmem_cache_destroy(scst_sess_cachep);
1267
1268 out_destroy_cmd_cache:
1269         kmem_cache_destroy(scst_cmd_cachep);
1270
1271 out_destroy_ua_cache:
1272         kmem_cache_destroy(scst_ua_cachep);
1273
1274 out_destroy_mgmt_cache:
1275         kmem_cache_destroy(scst_mgmt_cachep);
1276         goto out;
1277 }
1278
1279 static void __exit exit_scst(void)
1280 {
1281 #ifdef CONFIG_LOCKDEP
1282         static /* To hide the lockdep's warning about non-static key */
1283 #endif
1284         DECLARE_MUTEX_LOCKED(shm);
1285
1286         TRACE_ENTRY();
1287         
1288         /* ToDo: unregister_cpu_notifier() */
1289
1290         if (test_bit(SCST_FLAG_CMD_MEM_WORK_SCHEDULED, &scst_flags)) {
1291                 cancel_delayed_work(&scst_cmd_mem_work);
1292                 flush_scheduled_work();
1293         }
1294
1295         scst_proc_cleanup_module();
1296
1297         scst_stop_all_threads();
1298
1299         scsi_unregister_interface(&scst_interface);
1300         scst_destroy_acg(scst_default_acg);
1301
1302         scst_sgv_pools_deinit(&scst_sgv);
1303
1304 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
1305 #define DEINIT_CACHEP(p, s) do {                        \
1306                 if (kmem_cache_destroy(p)) {            \
1307                         PRINT_INFO_PR("kmem_cache_destroy of %s returned an "\
1308                                 "error", s);            \
1309                 }                                       \
1310                 p = NULL;                               \
1311         } while (0)
1312 #else
1313 #define DEINIT_CACHEP(p, s) do {                        \
1314                 kmem_cache_destroy(p);                  \
1315                 p = NULL;                               \
1316         } while (0)
1317 #endif
1318
1319         mempool_destroy(scst_mgmt_mempool);
1320         mempool_destroy(scst_ua_mempool);
1321
1322         DEINIT_CACHEP(scst_mgmt_cachep, SCST_MGMT_CMD_CACHE_STRING);
1323         DEINIT_CACHEP(scst_ua_cachep, SCST_UA_CACHE_STRING);
1324         DEINIT_CACHEP(scst_cmd_cachep, SCST_CMD_CACHE_STRING);
1325         DEINIT_CACHEP(scst_sess_cachep, SCST_SESSION_CACHE_STRING);
1326         DEINIT_CACHEP(scst_tgtd_cachep, SCST_TGT_DEV_CACHE_STRING);
1327         DEINIT_CACHEP(scst_acgd_cachep, SCST_ACG_DEV_CACHE_STRING);
1328
1329         PRINT_INFO_PR("%s", "SCST unloaded");
1330
1331         TRACE_EXIT();
1332         return;
1333 }
1334
1335 /*
1336  * Device Handler Side (i.e. scst_fileio)
1337  */
1338 EXPORT_SYMBOL(scst_register_dev_driver);
1339 EXPORT_SYMBOL(scst_unregister_dev_driver);
1340 EXPORT_SYMBOL(scst_register);
1341 EXPORT_SYMBOL(scst_unregister);
1342
1343 EXPORT_SYMBOL(scst_register_virtual_device);
1344 EXPORT_SYMBOL(scst_unregister_virtual_device);
1345 EXPORT_SYMBOL(scst_register_virtual_dev_driver);
1346 EXPORT_SYMBOL(scst_unregister_virtual_dev_driver);
1347
1348 EXPORT_SYMBOL(scst_set_busy);
1349 EXPORT_SYMBOL(scst_set_cmd_error_status);
1350 EXPORT_SYMBOL(scst_set_cmd_error);
1351 EXPORT_SYMBOL(scst_set_resp_data_len);
1352
1353 /*
1354  * Target Driver Side (i.e. HBA)
1355  */
1356 EXPORT_SYMBOL(scst_register_session);
1357 EXPORT_SYMBOL(scst_unregister_session);
1358
1359 EXPORT_SYMBOL(scst_register_target_template);
1360 EXPORT_SYMBOL(scst_unregister_target_template);
1361
1362 EXPORT_SYMBOL(scst_cmd_init_done);
1363 EXPORT_SYMBOL(scst_tgt_cmd_done);
1364 EXPORT_SYMBOL(scst_restart_cmd);
1365 EXPORT_SYMBOL(scst_rx_cmd);
1366 EXPORT_SYMBOL(scst_rx_data);
1367 EXPORT_SYMBOL(scst_rx_mgmt_fn_tag);
1368 EXPORT_SYMBOL(scst_rx_mgmt_fn_lun);
1369
1370 EXPORT_SYMBOL(scst_find_cmd);
1371 EXPORT_SYMBOL(scst_find_cmd_by_tag);
1372
1373 /*
1374  * Global Commands
1375  */
1376 EXPORT_SYMBOL(scst_suspend_activity);
1377 EXPORT_SYMBOL(scst_resume_activity);
1378
1379 EXPORT_SYMBOL(scst_add_cmd_threads);
1380 EXPORT_SYMBOL(scst_del_cmd_threads);
1381
1382 #if defined(DEBUG) || defined(TRACING)
1383 EXPORT_SYMBOL(scst_proc_log_entry_read);
1384 EXPORT_SYMBOL(scst_proc_log_entry_write);
1385 #endif
1386
1387 EXPORT_SYMBOL(scst_create_proc_entry);
1388 EXPORT_SYMBOL(scst_single_seq_open);
1389
1390 EXPORT_SYMBOL(__scst_get_buf);
1391 EXPORT_SYMBOL(scst_check_mem);
1392 EXPORT_SYMBOL(scst_get);
1393 EXPORT_SYMBOL(scst_put);
1394
1395 EXPORT_SYMBOL(scst_alloc);
1396 EXPORT_SYMBOL(scst_free);
1397
1398 /*
1399  * Other Commands
1400  */
1401 EXPORT_SYMBOL(scst_get_cdb_info);
1402 EXPORT_SYMBOL(scst_cmd_get_tgt_priv_lock);
1403 EXPORT_SYMBOL(scst_cmd_set_tgt_priv_lock);
1404
1405 #ifdef DEBUG
1406 EXPORT_SYMBOL(scst_random);
1407 #endif
1408
1409 module_init(init_scst);
1410 module_exit(exit_scst);
1411
1412 MODULE_AUTHOR("Vladislav Bolkhovitin & Leonid Stoljar");
1413 MODULE_LICENSE("GPL");
1414 MODULE_DESCRIPTION("SCSI target core");
1415 MODULE_VERSION(SCST_VERSION_STRING);