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