4 * Copyright (C) 2004-2006 Vladislav Bolkhovitin <vst@vlnb.net>
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
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.
18 #include <linux/module.h>
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>
30 #include "scst_debug.h"
32 #include "scst_priv.h"
35 #include "scst_debug.c"
37 #if defined(DEBUG) || defined(TRACING)
38 unsigned long trace_flag = SCST_DEFAULT_LOG_FLAGS;
42 * All targets, devices and dev_types management is done under
45 DECLARE_MUTEX(scst_mutex);
48 DECLARE_WAIT_QUEUE_HEAD(scst_dev_cmd_waitQ);
49 LIST_HEAD(scst_dev_wait_sess_list);
51 LIST_HEAD(scst_template_list);
52 LIST_HEAD(scst_dev_list);
53 LIST_HEAD(scst_dev_type_list);
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;
63 LIST_HEAD(scst_acg_list);
64 struct scst_acg *scst_default_acg;
66 kmem_cache_t *scst_cmd_cachep;
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];
77 struct scst_sgv_pools scst_sgv;
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);
84 DECLARE_WAIT_QUEUE_HEAD(scst_mgmt_waitQ);
85 spinlock_t scst_mgmt_lock = SPIN_LOCK_UNLOCKED;
86 LIST_HEAD(scst_sess_mgmt_list);
88 struct semaphore *scst_shutdown_mutex = NULL;
91 atomic_t scst_threads_count = ATOMIC_INIT(0);
92 int scst_shut_threads_count;
94 static int suspend_count;
96 int scst_virt_dev_last_id = 1; /* protected by scst_mutex */
99 * This buffer and lock are intended to avoid memory allocation, which
100 * could fail in improper places.
102 spinlock_t scst_temp_UA_lock = SPIN_LOCK_UNLOCKED;
103 uint8_t scst_temp_UA[SCSI_SENSE_BUFFERSIZE];
105 module_param_named(scst_threads, scst_threads, int, 0);
106 MODULE_PARM_DESC(scst_threads, "SCSI target threads count");
108 int scst_register_target_template(struct scst_tgt_template *vtt)
111 struct scst_tgt_template *t;
115 INIT_LIST_HEAD(&vtt->tgt_list);
118 PRINT_ERROR_PR("Target driver %s doesn't have a "
119 "detect() method.", vtt->name);
125 PRINT_ERROR_PR("Target driver %s doesn't have a "
126 "release() method.", vtt->name);
131 if (!vtt->xmit_response) {
132 PRINT_ERROR_PR("Target driver %s doesn't have a "
133 "xmit_response() method.", vtt->name);
138 if (!vtt->rdy_to_xfer) {
139 PRINT_ERROR_PR("Target driver %s doesn't have a "
140 "rdy_to_xfer() method.", vtt->name);
145 if (!vtt->on_free_cmd) {
146 PRINT_ERROR_PR("Target driver %s doesn't have a "
147 "on_free_cmd() method.", vtt->name);
152 if (!vtt->no_proc_entry) {
153 res = scst_build_proc_target_dir_entries(vtt);
159 if (down_interruptible(&scst_mutex) != 0)
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",
169 /* That's OK to drop it. The race doesn't matter */
172 TRACE_DBG("%s", "Calling target driver's detect()");
173 res = vtt->detect(vtt);
174 TRACE_DBG("Target driver's detect() returned %d", res);
176 PRINT_ERROR_PR("%s", "The detect() routine failed");
182 list_add_tail(&vtt->scst_template_list_entry, &scst_template_list);
192 scst_cleanup_proc_target_dir_entries(vtt);
196 void scst_unregister_target_template(struct scst_tgt_template *vtt)
198 struct scst_tgt *tgt;
202 if (down_interruptible(&scst_mutex) != 0)
206 list_for_each_entry(tgt, &vtt->tgt_list, tgt_list_entry) {
208 scst_unregister(tgt);
212 list_del(&vtt->scst_template_list_entry);
215 scst_cleanup_proc_target_dir_entries(vtt);
222 struct scst_tgt *scst_register(struct scst_tgt_template *vtt)
224 struct scst_tgt *tgt;
228 tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
229 TRACE_MEM("kzalloc(GFP_KERNEL) for tgt (%zd): %p",
232 TRACE(TRACE_OUT_OF_MEM, "%s", "kzalloc() failed");
236 INIT_LIST_HEAD(&tgt->sess_list);
237 init_waitqueue_head(&tgt->unreg_waitQ);
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;
249 if (scst_build_proc_target_entries(tgt) < 0) {
254 list_add_tail(&tgt->tgt_list_entry, &vtt->tgt_list);
263 TRACE_MEM("kfree() for tgt %p", tgt);
268 static inline int test_sess_list(struct scst_tgt *tgt)
272 res = list_empty(&tgt->sess_list);
277 void scst_unregister(struct scst_tgt *tgt)
279 struct scst_session *sess;
283 TRACE_DBG("%s", "Calling target driver's release()");
284 tgt->tgtt->release(tgt);
285 TRACE_DBG("%s", "Target driver's release() returned");
288 list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) {
289 BUG_ON(!sess->shutting_down);
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");
298 list_del(&tgt->tgt_list_entry);
301 scst_cleanup_proc_target_entries(tgt);
303 del_timer_sync(&tgt->retry_timer);
305 TRACE_MEM("kfree for tgt: %p", tgt);
312 /* scst_mutex supposed to be held */
313 void __scst_suspend_activity(void)
318 if (suspend_count > 1)
321 set_bit(SCST_FLAG_SUSPENDED, &scst_flags);
322 smp_mb__after_set_bit();
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");
334 void scst_suspend_activity(void)
337 __scst_suspend_activity();
340 /* scst_mutex supposed to be held */
341 void __scst_resume_activity(void)
343 struct scst_session *sess, *tsess;
348 if (suspend_count > 0)
351 clear_bit(SCST_FLAG_SUSPENDED, &scst_flags);
352 smp_mb__after_clear_bit();
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)
359 list_del(&sess->dev_wait_sess_list_entry);
361 spin_unlock_irq(&scst_list_lock);
363 wake_up_all(&scst_list_waitQ);
364 wake_up_all(&scst_mgmt_cmd_list_waitQ);
371 void scst_resume_activity(void)
373 __scst_resume_activity();
377 /* Called under scst_mutex */
378 static int scst_register_device(struct scsi_device *scsidp)
381 struct scst_device *dev;
382 struct scst_dev_type *dt;
386 dev = scst_alloc_device(GFP_KERNEL);
392 dev->rq_disk = alloc_disk(1);
393 if (dev->rq_disk == NULL) {
395 scst_free_device(dev);
398 dev->rq_disk->major = SCST_MAJOR;
400 dev->scsi_dev = scsidp;
402 list_add_tail(&dev->dev_list_entry, &scst_dev_list);
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);
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);
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);
431 put_disk(dev->rq_disk);
433 list_del(&dev->dev_list_entry);
434 scst_assign_dev_handler(dev, NULL);
438 /* Called under scst_mutex */
439 static void scst_unregister_device(struct scsi_device *scsidp)
441 struct scst_device *d, *dev = NULL;
442 struct scst_acg_dev *acg_dev, *aa;
446 __scst_suspend_activity();
448 list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
449 if (d->scsi_dev == scsidp) {
451 TRACE_DBG("Target device %p found", dev);
457 PRINT_ERROR_PR("%s", "Target device not found");
461 list_del(&dev->dev_list_entry);
463 list_for_each_entry_safe(acg_dev, aa, &dev->dev_acg_dev_list,
464 dev_acg_dev_list_entry)
466 scst_acg_remove_dev(acg_dev->acg, dev);
469 scst_assign_dev_handler(dev, NULL);
471 put_disk(dev->rq_disk);
472 scst_free_device(dev);
475 __scst_resume_activity();
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);
485 int scst_register_virtual_device(struct scst_dev_type *dev_handler,
486 const char *dev_name)
488 int res = -EINVAL, rc;
489 struct scst_device *dev = NULL;
493 if (dev_handler == NULL) {
494 PRINT_ERROR_PR("%s: valid device handler must be supplied",
500 if (dev_name == NULL) {
501 PRINT_ERROR_PR("%s: device name must be non-NULL", __FUNCTION__);
506 dev = scst_alloc_device(GFP_KERNEL);
512 dev->scsi_dev = NULL;
513 dev->virt_name = dev_name;
515 if (down_interruptible(&scst_mutex) != 0) {
520 dev->virt_id = scst_virt_dev_last_id++;
522 list_add_tail(&dev->dev_list_entry, &scst_dev_list);
526 rc = scst_assign_dev_handler(dev, dev_handler);
536 PRINT_INFO_PR("Attached SCSI target mid-level to virtual "
537 "device %s (id %d)", dev_name, dev->virt_id);
540 PRINT_INFO_PR("Failed to attach SCSI target mid-level to "
541 "virtual device %s", dev_name);
548 list_del(&dev->dev_list_entry);
552 scst_free_device(dev);
556 void scst_unregister_virtual_device(int id)
558 struct scst_device *d, *dev = NULL;
559 struct scst_acg_dev *acg_dev, *aa;
563 if (down_interruptible(&scst_mutex) != 0)
566 __scst_suspend_activity();
568 list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
569 if (d->virt_id == id) {
571 TRACE_DBG("Target device %p found", dev);
577 PRINT_ERROR_PR("%s", "Target device not found");
581 list_del(&dev->dev_list_entry);
583 list_for_each_entry_safe(acg_dev, aa, &dev->dev_acg_dev_list,
584 dev_acg_dev_list_entry)
586 scst_acg_remove_dev(acg_dev->acg, dev);
589 scst_assign_dev_handler(dev, NULL);
591 PRINT_INFO_PR("Detached SCSI target mid-level from virtual device %s "
592 "(id %d)", dev->virt_name, dev->virt_id);
594 scst_free_device(dev);
597 __scst_resume_activity();
606 int scst_register_dev_driver(struct scst_dev_type *dev_type)
608 struct scst_dev_type *dt;
609 struct scst_device *dev;
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);
622 if (down_interruptible(&scst_mutex) != 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);
637 res = scst_build_proc_dev_handler_dir_entries(dev_type);
642 list_add_tail(&dev_type->dev_type_list_entry, &scst_dev_type_list);
647 __scst_suspend_activity();
648 list_for_each_entry(dev, &scst_dev_list, dev_list_entry) {
649 if (dev->scsi_dev == NULL)
651 if (dev->scsi_dev->type == dev_type->type)
652 scst_assign_dev_handler(dev, dev_type);
654 __scst_resume_activity();
660 PRINT_INFO_PR("Device handler %s for type %d loaded "
661 "successfully", dev_type->name, dev_type->type);
669 void scst_unregister_dev_driver(struct scst_dev_type *dev_type)
671 struct scst_device *dev;
675 if (down_interruptible(&scst_mutex) != 0)
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);
685 __scst_resume_activity();
687 list_del(&dev_type->dev_type_list_entry);
691 scst_cleanup_proc_dev_handler_dir_entries(dev_type);
693 PRINT_INFO_PR("Device handler %s for type %d unloaded",
694 dev_type->name, dev_type->type);
701 int scst_register_virtual_dev_driver(struct scst_dev_type *dev_type)
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);
714 res = scst_build_proc_dev_handler_dir_entries(dev_type);
719 PRINT_INFO_PR("Device handler %s for type %d loaded "
720 "successfully", dev_type->name, dev_type->type);
727 void scst_unregister_virtual_dev_driver(struct scst_dev_type *dev_type)
731 scst_cleanup_proc_dev_handler_dir_entries(dev_type);
733 PRINT_INFO_PR("Device handler %s for type %d unloaded",
734 dev_type->name, dev_type->type);
740 /* scst_mutex supposed to be held */
741 int scst_assign_dev_handler(struct scst_device *dev,
742 struct scst_dev_type *handler)
745 struct scst_tgt_dev *tgt_dev;
746 LIST_HEAD(attached_tgt_devs);
750 if (dev->handler == handler)
753 __scst_suspend_activity();
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)
759 TRACE_DBG("Calling dev handler's detach_tgt(%p)",
761 dev->handler->detach_tgt(tgt_dev);
762 TRACE_DBG("%s", "Dev handler's detach_tgt() returned");
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");
772 dev->handler = handler;
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);
779 PRINT_ERROR_PR("New device handler's %s attach() "
780 "failed: %d", handler->name, res);
785 if (handler && handler->attach_tgt) {
786 list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
787 dev_tgt_dev_list_entry)
789 TRACE_DBG("Calling dev handler's attach_tgt(%p)",
791 res = handler->attach_tgt(tgt_dev);
792 TRACE_DBG("%s", "Dev handler's attach_tgt() returned");
794 PRINT_ERROR_PR("Device handler's %s attach_tgt() "
795 "failed: %d", handler->name, res);
796 goto out_err_detach_tgt;
798 list_add_tail(&tgt_dev->extra_tgt_dev_list_entry,
806 __scst_resume_activity();
813 if (handler && handler->detach_tgt) {
814 list_for_each_entry(tgt_dev, &attached_tgt_devs,
815 extra_tgt_dev_list_entry)
817 TRACE_DBG("Calling handler's detach_tgt(%p)",
819 handler->detach_tgt(tgt_dev);
820 TRACE_DBG("%s", "Handler's detach_tgt() returned");
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");
831 int scst_add_threads(int num)
837 for (i = 0; i < num; i++) {
838 res = kernel_thread(scst_cmd_thread, 0, SCST_THREAD_FLAGS);
840 PRINT_ERROR_PR("kernel_thread() failed: %d", res);
843 atomic_inc(&scst_threads_count);
854 scst_del_threads(i-1);
858 void scst_del_threads(int num)
862 spin_lock_irq(&scst_list_lock);
863 scst_shut_threads_count += num;
864 spin_unlock_irq(&scst_list_lock);
866 wake_up_nr(&scst_list_waitQ, num);
872 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
873 static int scst_add(struct class_device *cdev)
875 static int scst_add(struct class_device *cdev, struct class_interface *intf)
878 struct scsi_device *scsidp;
883 scsidp = to_scsi_device(cdev->dev);
886 res = scst_register_device(scsidp);
893 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
894 static void scst_remove(struct class_device *cdev)
896 static void scst_remove(struct class_device *cdev, struct class_interface *intf)
899 struct scsi_device *scsidp;
903 scsidp = to_scsi_device(cdev->dev);
906 scst_unregister_device(scsidp);
913 static struct class_interface scst_interface = {
915 .remove = scst_remove,
918 static inline int get_cpus_count(void)
921 return cpus_weight(cpu_online_map);
927 static int __init init_scst(void)
930 struct scst_cmd *cmd;
931 struct scsi_request *req;
935 BUILD_BUG_ON(sizeof(cmd->sense_buffer) != sizeof(req->sr_sense_buffer));
937 scst_num_cpus = get_cpus_count();
939 /* ToDo: register_cpu_notifier() */
941 if (scst_threads == 0)
942 scst_threads = scst_num_cpus;
944 if (scst_threads < scst_num_cpus) {
945 PRINT_ERROR_PR("%s", "scst_threads can not be less than "
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, \
956 if (p == NULL) { res = -ENOMEM; goto o; } \
959 INIT_CACHEP(scst_mgmt_cachep, SCST_MGMT_CMD_CACHE_STRING,
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);
972 scst_mgmt_mempool = mempool_create(10, mempool_alloc_slab,
973 mempool_free_slab, scst_mgmt_cachep);
974 if (scst_mgmt_mempool == NULL) {
976 goto out_destroy_acg_cache;
979 scst_ua_mempool = mempool_create(25, mempool_alloc_slab,
980 mempool_free_slab, scst_ua_cachep);
981 if (scst_ua_mempool == NULL) {
983 goto out_destroy_mgmt_mempool;
986 res = scst_sgv_pools_init(&scst_sgv);
988 goto out_destroy_ua_mempool;
990 scst_default_acg = scst_alloc_add_acg(SCST_DEFAULT_ACG_NAME);
991 if (scst_default_acg == NULL) {
993 goto out_destroy_sgv_pool;
996 res = scsi_register_interface(&scst_interface);
1000 scst_scsi_op_list_init();
1002 res = scst_proc_init_module();
1004 goto out_unreg_interface;
1006 TRACE_DBG("%d CPUs found, starting %d threads", scst_num_cpus,
1009 for (i = 0; i < scst_threads; i++) {
1010 res = kernel_thread(scst_cmd_thread, NULL, SCST_THREAD_FLAGS);
1012 PRINT_ERROR_PR("kernel_thread() failed: %d", res);
1013 goto out_thread_free;
1015 atomic_inc(&scst_threads_count);
1018 for (i = 0; i < sizeof(scst_tasklets) / sizeof(scst_tasklets[0]); i++)
1019 tasklet_init(&scst_tasklets[i], (void *)scst_cmd_tasklet, 0);
1021 res = kernel_thread(scst_mgmt_cmd_thread, NULL, SCST_THREAD_FLAGS);
1023 PRINT_ERROR_PR("kernel_thread() for mcmd failed: %d", res);
1024 goto out_thread_free;
1026 atomic_inc(&scst_threads_count);
1028 res = kernel_thread(scst_mgmt_thread, NULL, SCST_THREAD_FLAGS);
1030 PRINT_ERROR_PR("kernel_thread() for mgmt failed: %d", res);
1031 goto out_thread_free;
1033 atomic_inc(&scst_threads_count);
1035 PRINT_INFO_PR("SCST version %s loaded successfully",
1036 SCST_VERSION_STRING);
1039 TRACE_EXIT_RES(res);
1043 if (atomic_read(&scst_threads_count)) {
1044 DECLARE_MUTEX_LOCKED(shm);
1045 scst_shutdown_mutex = &shm;
1047 set_bit(SCST_FLAG_SHUTDOWN, &scst_flags);
1049 wake_up_all(&scst_list_waitQ);
1050 wake_up_all(&scst_mgmt_cmd_list_waitQ);
1051 wake_up_all(&scst_mgmt_waitQ);
1053 TRACE_DBG("Waiting for %d threads to complete",
1054 atomic_read(&scst_threads_count));
1058 scst_proc_cleanup_module();
1060 out_unreg_interface:
1061 scsi_unregister_interface(&scst_interface);
1064 scst_destroy_acg(scst_default_acg);
1066 out_destroy_sgv_pool:
1067 scst_sgv_pools_deinit(&scst_sgv);
1069 out_destroy_ua_mempool:
1070 mempool_destroy(scst_ua_mempool);
1072 out_destroy_mgmt_mempool:
1073 mempool_destroy(scst_mgmt_mempool);
1075 out_destroy_acg_cache:
1076 kmem_cache_destroy(scst_acgd_cachep);
1078 out_destroy_tgt_cache:
1079 kmem_cache_destroy(scst_tgtd_cachep);
1081 out_destroy_sess_cache:
1082 kmem_cache_destroy(scst_sess_cachep);
1084 out_destroy_cmd_cache:
1085 kmem_cache_destroy(scst_cmd_cachep);
1087 out_destroy_ua_cache:
1088 kmem_cache_destroy(scst_ua_cachep);
1090 out_destroy_mgmt_cache:
1091 kmem_cache_destroy(scst_mgmt_cachep);
1095 static void __exit exit_scst(void)
1097 DECLARE_MUTEX_LOCKED(shm);
1101 /* ToDo: unregister_cpu_notifier() */
1103 scst_shutdown_mutex = &shm;
1105 set_bit(SCST_FLAG_SHUTDOWN, &scst_flags);
1107 wake_up_all(&scst_list_waitQ);
1108 wake_up_all(&scst_mgmt_cmd_list_waitQ);
1109 wake_up_all(&scst_mgmt_waitQ);
1111 if (atomic_read(&scst_threads_count)) {
1112 TRACE_DBG("Waiting for %d threads to complete",
1113 atomic_read(&scst_threads_count));
1117 * Wait for one sec. to allow the thread(s) actually exit,
1118 * otherwise we can get Oops. Any better way?
1121 unsigned long t = jiffies;
1122 TRACE_DBG("%s", "Waiting 1 sec...");
1123 while((jiffies - t) < HZ)
1128 scst_proc_cleanup_module();
1129 scsi_unregister_interface(&scst_interface);
1130 scst_destroy_acg(scst_default_acg);
1132 scst_sgv_pools_deinit(&scst_sgv);
1134 #define DEINIT_CACHEP(p, s) do { \
1135 if (kmem_cache_destroy(p)) { \
1136 PRINT_INFO_PR("kmem_cache_destroy of %s returned an "\
1142 mempool_destroy(scst_mgmt_mempool);
1143 mempool_destroy(scst_ua_mempool);
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);
1152 PRINT_INFO_PR("%s", "SCST unloaded");
1159 * Device Handler Side (i.e. scst_fileio)
1161 EXPORT_SYMBOL(scst_register_dev_driver);
1162 EXPORT_SYMBOL(scst_unregister_dev_driver);
1163 EXPORT_SYMBOL(scst_register);
1164 EXPORT_SYMBOL(scst_unregister);
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);
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);
1177 * Target Driver Side (i.e. HBA)
1179 EXPORT_SYMBOL(scst_register_session);
1180 EXPORT_SYMBOL(scst_unregister_session);
1182 EXPORT_SYMBOL(scst_register_target_template);
1183 EXPORT_SYMBOL(scst_unregister_target_template);
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);
1192 EXPORT_SYMBOL(scst_find_cmd);
1193 EXPORT_SYMBOL(scst_find_cmd_by_tag);
1198 EXPORT_SYMBOL(scst_suspend_activity);
1199 EXPORT_SYMBOL(scst_resume_activity);
1201 EXPORT_SYMBOL(scst_add_threads);
1202 EXPORT_SYMBOL(scst_del_threads);
1204 #if defined(DEBUG) || defined(TRACING)
1205 EXPORT_SYMBOL(scst_proc_log_entry_read);
1206 EXPORT_SYMBOL(scst_proc_log_entry_write);
1209 EXPORT_SYMBOL(__scst_get_buf);
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);
1219 EXPORT_SYMBOL(scst_random);
1222 module_init(init_scst);
1223 module_exit(exit_scst);
1225 MODULE_AUTHOR("Vladislav Bolkhovitin & Leonid Stoljar");
1226 MODULE_LICENSE("GPL");
1227 MODULE_DESCRIPTION("SCSI target core");
1228 MODULE_VERSION(SCST_VERSION_STRING);