summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Ledford <dledford@flossy.devel.redhat.com>2002-11-17 05:02:31 -0500
committerDoug Ledford <dledford@flossy.devel.redhat.com>2002-11-17 05:02:31 -0500
commitfed60d4e14bed914be665d64ad219e87c7176777 (patch)
treea9e61e193bb5cbd6397a14008587fe47b0354baa
parent41977e4baf4612a0203b55d0712dbf3c54d57c35 (diff)
parent15018efce804af308abbf9eb0a43c0f84445c33e (diff)
Merge bk://linux.bkbits.net/linux-2.5
into flossy.devel.redhat.com:/usr/local/home/dledford/bk/linus-2.5
-rw-r--r--drivers/message/fusion/mptscsih.h4
-rw-r--r--drivers/scsi/NCR53C9x.c4
-rw-r--r--drivers/scsi/aic7xxx_old.c21
-rw-r--r--drivers/scsi/hosts.c10
-rw-r--r--drivers/scsi/hosts.h2
-rw-r--r--drivers/scsi/megaraid.c24
-rw-r--r--drivers/scsi/osst.c21
-rw-r--r--drivers/scsi/scsi.c110
-rw-r--r--drivers/scsi/sd.c18
-rw-r--r--drivers/scsi/sg.c35
-rw-r--r--drivers/scsi/sr.c12
-rw-r--r--drivers/scsi/st.c13
-rw-r--r--drivers/scsi/wd33c93.c2
13 files changed, 109 insertions, 167 deletions
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 6653cfafc023..b4ab49e7b959 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -230,8 +230,8 @@ extern int x_scsi_host_reset(Scsi_Cmnd *);
extern int x_scsi_old_abort(Scsi_Cmnd *);
extern int x_scsi_old_reset(Scsi_Cmnd *, unsigned int);
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28)
-extern int x_scsi_bios_param(Disk *, struct block_device *, int *);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)
+extern int x_scsi_bios_param(Scsi_Device *, struct block_device *, sector_t, int[]);
#else
extern int x_scsi_bios_param(Disk *, kdev_t, int *);
#endif
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
index f880e78f0454..d03997e184ea 100644
--- a/drivers/scsi/NCR53C9x.c
+++ b/drivers/scsi/NCR53C9x.c
@@ -732,9 +732,6 @@ void esp_initialize(struct NCR_ESP *esp)
/* Reset the thing before we try anything... */
esp_bootup_reset(esp, eregs);
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
esps_in_use++;
}
@@ -3638,7 +3635,6 @@ int init_module(void) { return 0; }
void cleanup_module(void) {}
void esp_release(void)
{
- MOD_DEC_USE_COUNT;
esps_in_use--;
esps_running = esps_in_use;
}
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index 42f55572c5a7..36d4198e6b1e 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -9310,7 +9310,8 @@ aic7xxx_detect(Scsi_Host_Template *template)
pci_write_config_dword(pdev, DEVCONFIG, devconfig);
#endif /* AIC7XXX_STRICT_PCI_SETUP */
- if(temp_p->base && check_region(temp_p->base, MAXREG - MINREG))
+ if(temp_p->base && !request_region(temp_p->base, MAXREG - MINREG,
+ "aic7xxx"))
{
printk("aic7xxx: <%s> at PCI %d/%d/%d\n",
board_names[aic_pdevs[i].board_name_index],
@@ -9389,12 +9390,6 @@ aic7xxx_detect(Scsi_Host_Template *template)
#endif
/*
- * Lock out other contenders for our i/o space.
- */
- if(temp_p->base)
- request_region(temp_p->base, MAXREG - MINREG, "aic7xxx");
-
- /*
* We HAVE to make sure the first pause_sequencer() and all other
* subsequent I/O that isn't PCI config space I/O takes place
* after the MMAPed I/O region is configured and tested. The
@@ -9742,7 +9737,7 @@ aic7xxx_detect(Scsi_Host_Template *template)
{
base = SLOTBASE(slot) + MINREG;
- if (check_region(base, MAXREG - MINREG))
+ if (!request_region(base, MAXREG - MINREG, "aic7xxx"))
{
/*
* Some other driver has staked a
@@ -9755,6 +9750,7 @@ aic7xxx_detect(Scsi_Host_Template *template)
type = aic7xxx_probe(slot, base + AHC_HID0, &flags);
if (type == -1)
{
+ release_region(base, MAXREG - MINREG);
slot++;
continue;
}
@@ -9762,13 +9758,10 @@ aic7xxx_detect(Scsi_Host_Template *template)
if (temp_p == NULL)
{
printk(KERN_WARNING "aic7xxx: Unable to allocate device space.\n");
+ release_region(base, MAXREG - MINREG);
slot++;
continue; /* back to the beginning of the while loop */
}
- /*
- * Lock out other contenders for our i/o space.
- */
- request_region(base, MAXREG - MINREG, "aic7xxx");
/*
* Pause the card preserving the IRQ type. Allow the operator
@@ -10972,6 +10965,10 @@ aic7xxx_reset(Scsi_Cmnd *cmd)
*
* Description:
* Return the disk geometry for the given SCSI device.
+ *
+ * Note:
+ * This function is broken for today's really large drives and needs
+ * fixed.
*-F*************************************************************************/
int
aic7xxx_biosparam(struct scsi_device *sdev, struct block_device *bdev,
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index f207c4b98e44..f1b7bd21157b 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -132,12 +132,6 @@ int scsi_remove_host(struct Scsi_Host *shost)
struct scsi_cmnd *scmd;
/*
- * Current policy is all shosts go away on unregister.
- */
- if (shost->hostt->module && GET_USE_COUNT(shost->hostt->module))
- return 1;
-
- /*
* FIXME Do ref counting. We force all of the devices offline to
* help prevent race conditions where other hosts/processors could
* try and get in and queue a command.
@@ -500,8 +494,6 @@ int scsi_register_host(Scsi_Host_Template *shost_tp)
cur_cnt = scsi_hosts_registered;
- MOD_INC_USE_COUNT;
-
/*
* The detect routine must carefully spinunlock/spinlock if it
* enables interrupts, since all interrupt handlers do spinlock as
@@ -585,8 +577,6 @@ int scsi_unregister_host(Scsi_Host_Template *shost_tp)
printk(KERN_INFO "scsi : %d host%s left.\n", scsi_hosts_registered,
(scsi_hosts_registered == 1) ? "" : "s");
- MOD_DEC_USE_COUNT;
-
unlock_kernel();
return 0;
diff --git a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
index 80314da8c44d..14c75af9dcc1 100644
--- a/drivers/scsi/hosts.h
+++ b/drivers/scsi/hosts.h
@@ -549,7 +549,7 @@ extern void scsi_mark_host_reset(struct Scsi_Host *);
struct Scsi_Device_Template
{
- struct Scsi_Device_Template * next;
+ struct list_head list;
const char * name;
const char * tag;
struct module * module; /* Used for loadable modules */
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 2cdeaf941341..a2f0cdf7b671 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -760,9 +760,8 @@ struct mega_hbas mega_hbas[MAX_CONTROLLERS];
/* For controller re-ordering */
static struct file_operations megadev_fops = {
- ioctl:megadev_ioctl_entry,
- open:megadev_open,
- release:megadev_close,
+ .owner = THIS_MODULE,
+ .ioctl = megadev_ioctl_entry,
};
/*
@@ -4333,15 +4332,6 @@ static void enq_scb_freelist (mega_host_config * megacfg, mega_scb * scb, int lo
}
}
-/*
- * Routines for the character/ioctl interface to the driver
- */
-static int megadev_open (struct inode *inode, struct file *filep)
-{
- MOD_INC_USE_COUNT;
- return 0; /* success */
-}
-
static int megadev_ioctl_entry (struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg)
{
@@ -4853,16 +4843,6 @@ megadev_doioctl (mega_host_config * megacfg, Scsi_Cmnd * sc)
}
static int
-megadev_close (struct inode *inode, struct file *filep)
-{
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
- return 0;
-}
-
-
-static int
mega_support_ext_cdb(mega_host_config *this_hba)
{
mega_mailbox *mboxpnt;
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 343467804a88..d013633cdaa0 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -163,6 +163,7 @@ static int osst_dev_max;
struct Scsi_Device_Template osst_template =
{
module: THIS_MODULE,
+ list: LIST_HEAD_INIT(osst_template.list),
name: "OnStream tape",
tag: "osst",
scsi_type: TYPE_TAPE,
@@ -4174,15 +4175,13 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
#endif
return (-EBUSY);
}
+
+ if (!try_module_get(STp->device->host->hostt->module))
+ return (-ENXIO);
+ STp->device->access_count++;
STp->in_use = 1;
STp->rew_at_close = (minor(inode->i_rdev) & 0x80) == 0;
- if (STp->device->host->hostt->module)
- __MOD_INC_USE_COUNT(STp->device->host->hostt->module);
- if (osst_template.module)
- __MOD_INC_USE_COUNT(osst_template.module);
- STp->device->access_count++;
-
if (mode != STp->current_mode) {
#if DEBUG
if (debugging)
@@ -4521,10 +4520,7 @@ err_out:
STp->header_ok = 0;
STp->device->access_count--;
- if (STp->device->host->hostt->module)
- __MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
- if (osst_template.module)
- __MOD_DEC_USE_COUNT(osst_template.module);
+ module_put(STp->device->host->hostt->module);
return retval;
}
@@ -4652,10 +4648,7 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp)
STp->in_use = 0;
STp->device->access_count--;
- if (STp->device->host->hostt->module)
- __MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
- if(osst_template.module)
- __MOD_DEC_USE_COUNT(osst_template.module);
+ module_put(STp->device->host->hostt->module);
return result;
}
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index a9488e8500c0..b26208e58c69 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -135,7 +135,7 @@ static struct softscsi_data softscsi_data[NR_CPUS] __cacheline_aligned;
/*
* List of all highlevel drivers.
*/
-static struct Scsi_Device_Template *scsi_devicelist;
+LIST_HEAD(scsi_devicelist);
static DECLARE_RWSEM(scsi_devicelist_mutex);
/*
@@ -1963,9 +1963,15 @@ void scsi_detect_device(struct scsi_device *sdev)
struct Scsi_Device_Template *sdt;
down_read(&scsi_devicelist_mutex);
- for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
- if (sdt->detect)
- (*sdt->detect)(sdev);
+ list_for_each_entry(sdt, &scsi_devicelist, list)
+ if (sdt->detect) {
+ if(try_module_get(sdt->module)) {
+ (*sdt->detect)(sdev);
+ module_put(sdt->module);
+ } else {
+ printk(KERN_WARNING "SCSI module %s not ready, skipping detection.\n", sdt->name);
+ }
+ }
up_read(&scsi_devicelist_mutex);
}
@@ -1974,14 +1980,20 @@ int scsi_attach_device(struct scsi_device *sdev)
struct Scsi_Device_Template *sdt;
down_read(&scsi_devicelist_mutex);
- for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
- if (sdt->attach)
+ list_for_each_entry(sdt, &scsi_devicelist, list)
+ if (sdt->attach) {
/*
* XXX check result when the upper level attach
* return values are fixed, and on failure goto
* fail.
*/
- (*sdt->attach) (sdev);
+ if(try_module_get(sdt->module)) {
+ (*sdt->attach)(sdev);
+ module_put(sdt->module);
+ } else {
+ printk(KERN_WARNING "SCSI module %s not ready, skipping attach.\n", sdt->name);
+ }
+ }
up_read(&scsi_devicelist_mutex);
return 0;
@@ -1997,9 +2009,15 @@ void scsi_detach_device(struct scsi_device *sdev)
struct Scsi_Device_Template *sdt;
down_read(&scsi_devicelist_mutex);
- for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
- if (sdt->detach)
- (*sdt->detach)(sdev);
+ list_for_each_entry(sdt, &scsi_devicelist, list)
+ if (sdt->detach) {
+ if(try_module_get(sdt->module)) {
+ (*sdt->detach)(sdev);
+ module_put(sdt->module);
+ } else {
+ printk(KERN_WARNING "SCSI module %s not ready, skipping detach.\n", sdt->name);
+ }
+ }
up_read(&scsi_devicelist_mutex);
}
@@ -2064,24 +2082,34 @@ void scsi_slave_detach(struct scsi_device *sdev)
/*
* This entry point should be called by a loadable module if it is trying
* add a high level scsi driver to the system.
+ *
+ * This entry point is called from the upper level module's module_init()
+ * routine. That implies that when this function is called, the
+ * scsi_mod module is locked down because of upper module layering and
+ * that the high level driver module is locked down by being in it's
+ * init routine. So, the *only* thing we have to do to protect adds
+ * we perform in this function is to make sure that all call's
+ * to the high level driver's attach() and detach() call in points, other
+ * than via scsi_register_device and scsi_unregister_device which are in
+ * the module_init and module_exit code respectively and therefore already
+ * locked down by the kernel module loader, are wrapped by try_module_get()
+ * and module_put() to avoid races on device adds and removes.
*/
int scsi_register_device(struct Scsi_Device_Template *tpnt)
{
Scsi_Device *SDpnt;
struct Scsi_Host *shpnt;
- int out_of_space = 0;
#ifdef CONFIG_KMOD
if (scsi_host_get_next(NULL) == NULL)
request_module("scsi_hostadapter");
#endif
- if (tpnt->next)
+ if (!list_empty(&tpnt->list))
return 1;
down_write(&scsi_devicelist_mutex);
- tpnt->next = scsi_devicelist;
- scsi_devicelist = tpnt;
+ list_add_tail(&tpnt->list, &scsi_devicelist);
up_write(&scsi_devicelist_mutex);
tpnt->scsi_driverfs_driver.name = (char *)tpnt->tag;
@@ -2120,13 +2148,6 @@ int scsi_register_device(struct Scsi_Device_Template *tpnt)
}
}
- MOD_INC_USE_COUNT;
-
- if (out_of_space) {
- scsi_unregister_device(tpnt); /* easiest way to clean up?? */
- return 1;
- }
-
return 0;
}
@@ -2134,16 +2155,7 @@ int scsi_unregister_device(struct Scsi_Device_Template *tpnt)
{
Scsi_Device *SDpnt;
struct Scsi_Host *shpnt;
- struct Scsi_Device_Template *spnt;
- struct Scsi_Device_Template *prev_spnt;
- lock_kernel();
- /*
- * If we are busy, this is not going to fly.
- */
- if (GET_USE_COUNT(tpnt->module) != 0)
- goto error_out;
-
driver_unregister(&tpnt->scsi_driverfs_driver);
/*
@@ -2162,28 +2174,14 @@ int scsi_unregister_device(struct Scsi_Device_Template *tpnt)
* Extract the template from the linked list.
*/
down_write(&scsi_devicelist_mutex);
- spnt = scsi_devicelist;
- prev_spnt = NULL;
- while (spnt != tpnt) {
- prev_spnt = spnt;
- spnt = spnt->next;
- }
- if (prev_spnt == NULL)
- scsi_devicelist = tpnt->next;
- else
- prev_spnt->next = spnt->next;
+ list_del(&tpnt->list);
up_write(&scsi_devicelist_mutex);
- MOD_DEC_USE_COUNT;
- unlock_kernel();
/*
* Final cleanup for the driver is done in the driver sources in the
* cleanup function.
*/
return 0;
-error_out:
- unlock_kernel();
- return -1;
}
#ifdef CONFIG_PROC_FS
@@ -2379,11 +2377,11 @@ static int __init init_scsi(void)
sgp->slab = kmem_cache_create(sgp->name, size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
if (!sgp->slab)
- panic("SCSI: can't init sg slab\n");
+ printk(KERN_ERR "SCSI: can't init sg slab %s\n", sgp->name);
sgp->pool = mempool_create(SG_MEMPOOL_SIZE, scsi_pool_alloc, scsi_pool_free, sgp->slab);
if (!sgp->pool)
- panic("SCSI: can't init sg mempool\n");
+ printk(KERN_ERR "SCSI: can't init sg mempool %s\n", sgp->name);
}
/*
@@ -2393,13 +2391,12 @@ static int __init init_scsi(void)
proc_scsi = proc_mkdir("scsi", 0);
if (!proc_scsi) {
printk (KERN_ERR "cannot init /proc/scsi\n");
- return -ENOMEM;
+ goto out_error;
}
generic = create_proc_info_entry ("scsi/scsi", 0, 0, scsi_proc_info);
if (!generic) {
printk (KERN_ERR "cannot init /proc/scsi/scsi\n");
- remove_proc_entry("scsi", 0);
- return -ENOMEM;
+ goto out_proc_error;
}
generic->write_proc = proc_scsi_gen_write;
#endif
@@ -2414,6 +2411,19 @@ static int __init init_scsi(void)
open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL);
return 0;
+#ifdef CONFIG_PROC_FS
+out_proc_error:
+ remove_proc_entry("scsi", 0);
+#endif
+out_error:
+ for (i = 0; i < SG_MEMPOOL_NR; i++) {
+ struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
+ mempool_destroy(sgp->pool);
+ kmem_cache_destroy(sgp->slab);
+ sgp->pool = NULL;
+ sgp->slab = NULL;
+ }
+ return -ENOMEM;
}
static void __exit exit_scsi(void)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 6bd61665cb3f..a9301982ac28 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -104,6 +104,7 @@ static struct notifier_block sd_notifier_block = {sd_notifier, NULL, 0};
static struct Scsi_Device_Template sd_template = {
.module = THIS_MODULE,
+ .list = LIST_HEAD_INIT(sd_template.list),
.name = "disk",
.tag = "sd",
.scsi_type = TYPE_DISK,
@@ -453,10 +454,8 @@ static int sd_open(struct inode *inode, struct file *filp)
* The following code can sleep.
* Module unloading must be prevented
*/
- if (sdp->host->hostt->module)
- __MOD_INC_USE_COUNT(sdp->host->hostt->module);
- if (sd_template.module)
- __MOD_INC_USE_COUNT(sd_template.module);
+ if(!try_module_get(sdp->host->hostt->module))
+ return -ENOMEM;
sdp->access_count++;
if (sdp->removable) {
@@ -498,10 +497,7 @@ static int sd_open(struct inode *inode, struct file *filp)
error_out:
sdp->access_count--;
- if (sdp->host->hostt->module)
- __MOD_DEC_USE_COUNT(sdp->host->hostt->module);
- if (sd_template.module)
- __MOD_DEC_USE_COUNT(sd_template.module);
+ module_put(sdp->host->hostt->module);
return retval;
}
@@ -536,10 +532,7 @@ static int sd_release(struct inode *inode, struct file *filp)
if (scsi_block_when_processing_errors(sdp))
scsi_set_medium_removal(sdp, SCSI_REMOVAL_ALLOW);
}
- if (sdp->host->hostt->module)
- __MOD_DEC_USE_COUNT(sdp->host->hostt->module);
- if (sd_template.module)
- __MOD_DEC_USE_COUNT(sd_template.module);
+ module_put(sdp->host->hostt->module);
return 0;
}
@@ -1241,6 +1234,7 @@ static int sd_attach(struct scsi_device * sdp)
gd->de = sdp->de;
gd->major = SD_MAJOR(dsk_nr>>4);
gd->first_minor = (dsk_nr & 15)<<4;
+ gd->minors = 16;
gd->fops = &sd_fops;
if (dsk_nr > 26)
sprintf(gd->disk_name, "sd%c%c",'a'+dsk_nr/26-1,'a'+dsk_nr%26);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 20e31bef7cca..daff0173be50 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -121,6 +121,7 @@ static rwlock_t sg_dev_arr_lock = RW_LOCK_UNLOCKED; /* Also used to lock
static struct Scsi_Device_Template sg_template = {
.module = THIS_MODULE,
+ .list = LIST_HEAD_INIT(sg_template.list),
.name = "generic",
.tag = "sg",
.scsi_type = 0xff,
@@ -261,8 +262,8 @@ sg_open(struct inode *inode, struct file *filp)
/* This driver's module count bumped by fops_get in <linux/fs.h> */
/* Prevent the device driver from vanishing while we sleep */
- if (sdp->device->host->hostt->module)
- __MOD_INC_USE_COUNT(sdp->device->host->hostt->module);
+ if (!try_module_get(sdp->device->host->hostt->module))
+ return -ENXIO;
sdp->device->access_count++;
if (!((flags & O_NONBLOCK) ||
@@ -317,8 +318,7 @@ sg_open(struct inode *inode, struct file *filp)
error_out:
sdp->device->access_count--;
- if ((!sdp->detached) && sdp->device->host->hostt->module)
- __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
+ module_put(sdp->device->host->hostt->module);
return retval;
}
@@ -336,9 +336,7 @@ sg_release(struct inode *inode, struct file *filp)
if (0 == sg_remove_sfp(sdp, sfp)) { /* Returns 1 when sdp gone */
if (!sdp->detached) {
sdp->device->access_count--;
- if (sdp->device->host->hostt->module)
- __MOD_DEC_USE_COUNT(sdp->device->host->hostt->
- module);
+ module_put(sdp->device->host->hostt->module);
}
sdp->exclude = 0;
wake_up_interruptible(&sdp->o_excl_wait);
@@ -1304,11 +1302,8 @@ sg_cmd_done(Scsi_Cmnd * SCpnt)
SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n"));
if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */
sdp->device->access_count--;
- if (sdp->device->host->hostt->module)
- __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
+ module_put(sdp->device->host->hostt->module);
}
- if (sg_template.module)
- __MOD_DEC_USE_COUNT(sg_template.module);
sfp = NULL;
}
} else if (srp && srp->orphan) {
@@ -1539,12 +1534,7 @@ sg_detach(Scsi_Device * scsidp)
}
if (sfp->closed) {
sdp->device->access_count--;
- if (sg_template.module)
- __MOD_DEC_USE_COUNT(sg_template.module);
- if (sdp->device->host->hostt->module)
- __MOD_DEC_USE_COUNT(
- sdp->device->host->
- hostt->module);
+ module_put(sdp->device->host->hostt->module);
__sg_remove_sfp(sdp, sfp);
} else {
delay = 1;
@@ -2530,13 +2520,12 @@ sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
}
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
} else {
- sfp->closed = 1; /* flag dirty state on this fd */
- sdp->device->access_count++;
/* MOD_INC's to inhibit unloading sg and associated adapter driver */
- if (sg_template.module)
- __MOD_INC_USE_COUNT(sg_template.module);
- if (sdp->device->host->hostt->module)
- __MOD_INC_USE_COUNT(sdp->device->host->hostt->module);
+ /* only bump the access_count if we actually succeeded in
+ * throwing another counter on the host module */
+ if(try_module_get(sdp->device->host->hostt->module))
+ sdp->device->access_count++;
+ sfp->closed = 1; /* flag dirty state on this fd */
SCSI_LOG_TIMEOUT(1, printk("sg_remove_sfp: worrisome, %d writes pending\n",
dirty));
}
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 8b1252ae2b3a..0354858a07fd 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -72,6 +72,7 @@ static int sr_init_command(struct scsi_cmnd *);
static struct Scsi_Device_Template sr_template = {
.module = THIS_MODULE,
+ .list = LIST_HEAD_INIT(sr_template.list),
.name = "cdrom",
.tag = "sr",
.scsi_type = TYPE_ROM,
@@ -130,10 +131,7 @@ static void sr_release(struct cdrom_device_info *cdi)
if (cd->device->sector_size > 2048)
sr_set_blocklength(cd, 2048);
cd->device->access_count--;
- if (cd->device->host->hostt->module)
- __MOD_DEC_USE_COUNT(cd->device->host->hostt->module);
- if (sr_template.module)
- __MOD_DEC_USE_COUNT(sr_template.module);
+ module_put(cd->device->host->hostt->module);
}
static struct cdrom_device_ops sr_dops = {
@@ -472,11 +470,9 @@ static int sr_open(struct cdrom_device_info *cdi, int purpose)
if (!scsi_block_when_processing_errors(cd->device)) {
return -ENXIO;
}
+ if(!try_module_get(cd->device->host->hostt->module))
+ return -ENXIO;
cd->device->access_count++;
- if (cd->device->host->hostt->module)
- __MOD_INC_USE_COUNT(cd->device->host->hostt->module);
- if (sr_template.module)
- __MOD_INC_USE_COUNT(sr_template.module);
/* If this device did not have media in the drive at boot time, then
* we would have been unable to get the sector size. Check to see if
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 8f45bb032658..ad121242ba54 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -175,6 +175,7 @@ static void st_detach(Scsi_Device *);
static struct Scsi_Device_Template st_template = {
.module = THIS_MODULE,
+ .list = LIST_HEAD_INIT(st_template.list),
.name = "tape",
.tag = "st",
.scsi_type = TYPE_TAPE,
@@ -992,13 +993,13 @@ static int st_open(struct inode *inode, struct file *filp)
DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
return (-EBUSY);
}
+ if(!try_module_get(STp->device->host->hostt->module))
+ return (-ENXIO);
+ STp->device->access_count++;
STp->in_use = 1;
write_unlock(&st_dev_arr_lock);
STp->rew_at_close = STp->autorew_dev = (minor(inode->i_rdev) & 0x80) == 0;
- if (STp->device->host->hostt->module)
- __MOD_INC_USE_COUNT(STp->device->host->hostt->module);
- STp->device->access_count++;
if (!scsi_block_when_processing_errors(STp->device)) {
retval = (-ENXIO);
@@ -1040,8 +1041,7 @@ static int st_open(struct inode *inode, struct file *filp)
normalize_buffer(STp->buffer);
STp->in_use = 0;
STp->device->access_count--;
- if (STp->device->host->hostt->module)
- __MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
+ module_put(STp->device->host->hostt->module);
return retval;
}
@@ -1175,8 +1175,7 @@ static int st_release(struct inode *inode, struct file *filp)
STp->in_use = 0;
write_unlock(&st_dev_arr_lock);
STp->device->access_count--;
- if (STp->device->host->hostt->module)
- __MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
+ module_put(STp->device->host->hostt->module);
return result;
}
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index 5ee05c8d2f6a..4ce9a4a76ec0 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -1853,7 +1853,6 @@ char buf[32];
printk("\n");
printk(" Version %s - %s, Compiled %s at %s\n",
WD33C93_VERSION,WD33C93_DATE,__DATE__,__TIME__);
- MOD_INC_USE_COUNT;
}
@@ -2031,7 +2030,6 @@ void cleanup_module(void) {}
#endif
void wd33c93_release(void)
{
- MOD_DEC_USE_COUNT;
}
MODULE_LICENSE("GPL");