1/* 2 * Copyright (C) 2003 Christoph Hellwig. 3 * Released under GPL v2. 4 * 5 * Support for old-style host templates. 6 * 7 * NOTE: Do not use this for new drivers ever. 8 */ 9 10#include <linux/init.h> 11#include <linux/kernel.h> 12#include <linux/module.h> 13 14#include <scsi/scsi_host.h> 15 16 17static int __init init_this_scsi_driver(void) 18{ 19 struct scsi_host_template *sht = &driver_template; 20 struct Scsi_Host *shost; 21 struct list_head *l; 22 int error; 23 24 if (!sht->release) { 25 printk(KERN_ERR 26 "scsi HBA driver %s didn't set a release method.\n", 27 sht->name); 28 return -EINVAL; 29 } 30 31 sht->module = THIS_MODULE; 32 INIT_LIST_HEAD(&sht->legacy_hosts); 33 34 sht->detect(sht); 35 if (list_empty(&sht->legacy_hosts)) 36 return -ENODEV; 37 38 list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) { 39 error = scsi_add_host(shost, NULL); 40 if (error) 41 goto fail; 42 scsi_scan_host(shost); 43 } 44 return 0; 45 fail: 46 l = &shost->sht_legacy_list; 47 while ((l = l->prev) != &sht->legacy_hosts) 48 scsi_remove_host(list_entry(l, struct Scsi_Host, sht_legacy_list)); 49 return error; 50} 51 52static void __exit exit_this_scsi_driver(void) 53{ 54 struct scsi_host_template *sht = &driver_template; 55 struct Scsi_Host *shost, *s; 56 57 list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) 58 scsi_remove_host(shost); 59 list_for_each_entry_safe(shost, s, &sht->legacy_hosts, sht_legacy_list) 60 sht->release(shost); 61 62 if (list_empty(&sht->legacy_hosts)) 63 return; 64 65 printk(KERN_WARNING "%s did not call scsi_unregister\n", sht->name); 66 dump_stack(); 67 68 list_for_each_entry_safe(shost, s, &sht->legacy_hosts, sht_legacy_list) 69 scsi_unregister(shost); 70} 71 72module_init(init_this_scsi_driver); 73module_exit(exit_this_scsi_driver); 74