Commit ad82a127 authored by Doug Ledford's avatar Doug Ledford

Update high level scsi drivers to use struct list_head in templates

Update scsi.c for struct list_head in upper layer templates
Update scsi.c for new module loader semantics
parent ae3c7c33
...@@ -549,7 +549,7 @@ extern void scsi_mark_host_reset(struct Scsi_Host *); ...@@ -549,7 +549,7 @@ extern void scsi_mark_host_reset(struct Scsi_Host *);
struct Scsi_Device_Template struct Scsi_Device_Template
{ {
struct Scsi_Device_Template * next; struct list_head list;
const char * name; const char * name;
const char * tag; const char * tag;
struct module * module; /* Used for loadable modules */ struct module * module; /* Used for loadable modules */
......
...@@ -163,6 +163,7 @@ static int osst_dev_max; ...@@ -163,6 +163,7 @@ static int osst_dev_max;
struct Scsi_Device_Template osst_template = struct Scsi_Device_Template osst_template =
{ {
module: THIS_MODULE, module: THIS_MODULE,
list: LIST_HEAD_INIT(osst_template.list),
name: "OnStream tape", name: "OnStream tape",
tag: "osst", tag: "osst",
scsi_type: TYPE_TAPE, scsi_type: TYPE_TAPE,
...@@ -4174,15 +4175,13 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) ...@@ -4174,15 +4175,13 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
#endif #endif
return (-EBUSY); return (-EBUSY);
} }
if (!try_module_get(STp->device->host->hostt->module))
return (-ENXIO);
STp->device->access_count++;
STp->in_use = 1; STp->in_use = 1;
STp->rew_at_close = (minor(inode->i_rdev) & 0x80) == 0; 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 (mode != STp->current_mode) {
#if DEBUG #if DEBUG
if (debugging) if (debugging)
...@@ -4521,10 +4520,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) ...@@ -4521,10 +4520,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
STp->header_ok = 0; STp->header_ok = 0;
STp->device->access_count--; STp->device->access_count--;
if (STp->device->host->hostt->module) module_put(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);
return retval; return retval;
} }
...@@ -4652,10 +4648,7 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp) ...@@ -4652,10 +4648,7 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp)
STp->in_use = 0; STp->in_use = 0;
STp->device->access_count--; STp->device->access_count--;
if (STp->device->host->hostt->module) module_put(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);
return result; return result;
} }
......
...@@ -135,7 +135,7 @@ static struct softscsi_data softscsi_data[NR_CPUS] __cacheline_aligned; ...@@ -135,7 +135,7 @@ static struct softscsi_data softscsi_data[NR_CPUS] __cacheline_aligned;
/* /*
* List of all highlevel drivers. * List of all highlevel drivers.
*/ */
static struct Scsi_Device_Template *scsi_devicelist; LIST_HEAD(scsi_devicelist);
static DECLARE_RWSEM(scsi_devicelist_mutex); static DECLARE_RWSEM(scsi_devicelist_mutex);
/* /*
...@@ -1963,9 +1963,15 @@ void scsi_detect_device(struct scsi_device *sdev) ...@@ -1963,9 +1963,15 @@ void scsi_detect_device(struct scsi_device *sdev)
struct Scsi_Device_Template *sdt; struct Scsi_Device_Template *sdt;
down_read(&scsi_devicelist_mutex); down_read(&scsi_devicelist_mutex);
for (sdt = scsi_devicelist; sdt; sdt = sdt->next) list_for_each_entry(sdt, &scsi_devicelist, list)
if (sdt->detect) if (sdt->detect) {
(*sdt->detect)(sdev); 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); up_read(&scsi_devicelist_mutex);
} }
...@@ -1974,14 +1980,20 @@ int scsi_attach_device(struct scsi_device *sdev) ...@@ -1974,14 +1980,20 @@ int scsi_attach_device(struct scsi_device *sdev)
struct Scsi_Device_Template *sdt; struct Scsi_Device_Template *sdt;
down_read(&scsi_devicelist_mutex); down_read(&scsi_devicelist_mutex);
for (sdt = scsi_devicelist; sdt; sdt = sdt->next) list_for_each_entry(sdt, &scsi_devicelist, list)
if (sdt->attach) if (sdt->attach) {
/* /*
* XXX check result when the upper level attach * XXX check result when the upper level attach
* return values are fixed, and on failure goto * return values are fixed, and on failure goto
* fail. * 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); up_read(&scsi_devicelist_mutex);
return 0; return 0;
...@@ -1997,9 +2009,15 @@ void scsi_detach_device(struct scsi_device *sdev) ...@@ -1997,9 +2009,15 @@ void scsi_detach_device(struct scsi_device *sdev)
struct Scsi_Device_Template *sdt; struct Scsi_Device_Template *sdt;
down_read(&scsi_devicelist_mutex); down_read(&scsi_devicelist_mutex);
for (sdt = scsi_devicelist; sdt; sdt = sdt->next) list_for_each_entry(sdt, &scsi_devicelist, list)
if (sdt->detach) if (sdt->detach) {
(*sdt->detach)(sdev); 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); up_read(&scsi_devicelist_mutex);
} }
...@@ -2064,24 +2082,34 @@ void scsi_slave_detach(struct scsi_device *sdev) ...@@ -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 * This entry point should be called by a loadable module if it is trying
* add a high level scsi driver to the system. * 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) int scsi_register_device(struct Scsi_Device_Template *tpnt)
{ {
Scsi_Device *SDpnt; Scsi_Device *SDpnt;
struct Scsi_Host *shpnt; struct Scsi_Host *shpnt;
int out_of_space = 0;
#ifdef CONFIG_KMOD #ifdef CONFIG_KMOD
if (scsi_host_get_next(NULL) == NULL) if (scsi_host_get_next(NULL) == NULL)
request_module("scsi_hostadapter"); request_module("scsi_hostadapter");
#endif #endif
if (tpnt->next) if (!list_empty(&tpnt->list))
return 1; return 1;
down_write(&scsi_devicelist_mutex); down_write(&scsi_devicelist_mutex);
tpnt->next = scsi_devicelist; list_add_tail(&tpnt->list, &scsi_devicelist);
scsi_devicelist = tpnt;
up_write(&scsi_devicelist_mutex); up_write(&scsi_devicelist_mutex);
tpnt->scsi_driverfs_driver.name = (char *)tpnt->tag; tpnt->scsi_driverfs_driver.name = (char *)tpnt->tag;
...@@ -2120,13 +2148,6 @@ int scsi_register_device(struct Scsi_Device_Template *tpnt) ...@@ -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; return 0;
} }
...@@ -2134,16 +2155,7 @@ int scsi_unregister_device(struct Scsi_Device_Template *tpnt) ...@@ -2134,16 +2155,7 @@ int scsi_unregister_device(struct Scsi_Device_Template *tpnt)
{ {
Scsi_Device *SDpnt; Scsi_Device *SDpnt;
struct Scsi_Host *shpnt; 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); driver_unregister(&tpnt->scsi_driverfs_driver);
/* /*
...@@ -2162,28 +2174,14 @@ int scsi_unregister_device(struct Scsi_Device_Template *tpnt) ...@@ -2162,28 +2174,14 @@ int scsi_unregister_device(struct Scsi_Device_Template *tpnt)
* Extract the template from the linked list. * Extract the template from the linked list.
*/ */
down_write(&scsi_devicelist_mutex); down_write(&scsi_devicelist_mutex);
spnt = scsi_devicelist; list_del(&tpnt->list);
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;
up_write(&scsi_devicelist_mutex); up_write(&scsi_devicelist_mutex);
MOD_DEC_USE_COUNT;
unlock_kernel();
/* /*
* Final cleanup for the driver is done in the driver sources in the * Final cleanup for the driver is done in the driver sources in the
* cleanup function. * cleanup function.
*/ */
return 0; return 0;
error_out:
unlock_kernel();
return -1;
} }
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
......
...@@ -104,6 +104,7 @@ static struct notifier_block sd_notifier_block = {sd_notifier, NULL, 0}; ...@@ -104,6 +104,7 @@ static struct notifier_block sd_notifier_block = {sd_notifier, NULL, 0};
static struct Scsi_Device_Template sd_template = { static struct Scsi_Device_Template sd_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.list = LIST_HEAD_INIT(sd_template.list),
.name = "disk", .name = "disk",
.tag = "sd", .tag = "sd",
.scsi_type = TYPE_DISK, .scsi_type = TYPE_DISK,
...@@ -453,10 +454,8 @@ static int sd_open(struct inode *inode, struct file *filp) ...@@ -453,10 +454,8 @@ static int sd_open(struct inode *inode, struct file *filp)
* The following code can sleep. * The following code can sleep.
* Module unloading must be prevented * Module unloading must be prevented
*/ */
if (sdp->host->hostt->module) if(!try_module_get(sdp->host->hostt->module))
__MOD_INC_USE_COUNT(sdp->host->hostt->module); return -ENOMEM;
if (sd_template.module)
__MOD_INC_USE_COUNT(sd_template.module);
sdp->access_count++; sdp->access_count++;
if (sdp->removable) { if (sdp->removable) {
...@@ -498,10 +497,7 @@ static int sd_open(struct inode *inode, struct file *filp) ...@@ -498,10 +497,7 @@ static int sd_open(struct inode *inode, struct file *filp)
error_out: error_out:
sdp->access_count--; sdp->access_count--;
if (sdp->host->hostt->module) module_put(sdp->host->hostt->module);
__MOD_DEC_USE_COUNT(sdp->host->hostt->module);
if (sd_template.module)
__MOD_DEC_USE_COUNT(sd_template.module);
return retval; return retval;
} }
...@@ -536,10 +532,7 @@ static int sd_release(struct inode *inode, struct file *filp) ...@@ -536,10 +532,7 @@ static int sd_release(struct inode *inode, struct file *filp)
if (scsi_block_when_processing_errors(sdp)) if (scsi_block_when_processing_errors(sdp))
scsi_set_medium_removal(sdp, SCSI_REMOVAL_ALLOW); scsi_set_medium_removal(sdp, SCSI_REMOVAL_ALLOW);
} }
if (sdp->host->hostt->module) module_put(sdp->host->hostt->module);
__MOD_DEC_USE_COUNT(sdp->host->hostt->module);
if (sd_template.module)
__MOD_DEC_USE_COUNT(sd_template.module);
return 0; return 0;
} }
...@@ -1241,6 +1234,7 @@ static int sd_attach(struct scsi_device * sdp) ...@@ -1241,6 +1234,7 @@ static int sd_attach(struct scsi_device * sdp)
gd->de = sdp->de; gd->de = sdp->de;
gd->major = SD_MAJOR(dsk_nr>>4); gd->major = SD_MAJOR(dsk_nr>>4);
gd->first_minor = (dsk_nr & 15)<<4; gd->first_minor = (dsk_nr & 15)<<4;
gd->minors = 16;
gd->fops = &sd_fops; gd->fops = &sd_fops;
if (dsk_nr > 26) if (dsk_nr > 26)
sprintf(gd->disk_name, "sd%c%c",'a'+dsk_nr/26-1,'a'+dsk_nr%26); sprintf(gd->disk_name, "sd%c%c",'a'+dsk_nr/26-1,'a'+dsk_nr%26);
......
...@@ -121,6 +121,7 @@ static rwlock_t sg_dev_arr_lock = RW_LOCK_UNLOCKED; /* Also used to lock ...@@ -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 = { static struct Scsi_Device_Template sg_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.list = LIST_HEAD_INIT(sg_template.list),
.name = "generic", .name = "generic",
.tag = "sg", .tag = "sg",
.scsi_type = 0xff, .scsi_type = 0xff,
...@@ -261,8 +262,8 @@ sg_open(struct inode *inode, struct file *filp) ...@@ -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> */ /* This driver's module count bumped by fops_get in <linux/fs.h> */
/* Prevent the device driver from vanishing while we sleep */ /* Prevent the device driver from vanishing while we sleep */
if (sdp->device->host->hostt->module) if (!try_module_get(sdp->device->host->hostt->module))
__MOD_INC_USE_COUNT(sdp->device->host->hostt->module); return -ENXIO;
sdp->device->access_count++; sdp->device->access_count++;
if (!((flags & O_NONBLOCK) || if (!((flags & O_NONBLOCK) ||
...@@ -317,8 +318,7 @@ sg_open(struct inode *inode, struct file *filp) ...@@ -317,8 +318,7 @@ sg_open(struct inode *inode, struct file *filp)
error_out: error_out:
sdp->device->access_count--; sdp->device->access_count--;
if ((!sdp->detached) && sdp->device->host->hostt->module) module_put(sdp->device->host->hostt->module);
__MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
return retval; return retval;
} }
...@@ -336,9 +336,7 @@ sg_release(struct inode *inode, struct file *filp) ...@@ -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 (0 == sg_remove_sfp(sdp, sfp)) { /* Returns 1 when sdp gone */
if (!sdp->detached) { if (!sdp->detached) {
sdp->device->access_count--; sdp->device->access_count--;
if (sdp->device->host->hostt->module) module_put(sdp->device->host->hostt->module);
__MOD_DEC_USE_COUNT(sdp->device->host->hostt->
module);
} }
sdp->exclude = 0; sdp->exclude = 0;
wake_up_interruptible(&sdp->o_excl_wait); wake_up_interruptible(&sdp->o_excl_wait);
...@@ -1304,11 +1302,8 @@ sg_cmd_done(Scsi_Cmnd * SCpnt) ...@@ -1304,11 +1302,8 @@ sg_cmd_done(Scsi_Cmnd * SCpnt)
SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n")); SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n"));
if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */ if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */
sdp->device->access_count--; sdp->device->access_count--;
if (sdp->device->host->hostt->module) module_put(sdp->device->host->hostt->module);
__MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
} }
if (sg_template.module)
__MOD_DEC_USE_COUNT(sg_template.module);
sfp = NULL; sfp = NULL;
} }
} else if (srp && srp->orphan) { } else if (srp && srp->orphan) {
...@@ -1539,12 +1534,7 @@ sg_detach(Scsi_Device * scsidp) ...@@ -1539,12 +1534,7 @@ sg_detach(Scsi_Device * scsidp)
} }
if (sfp->closed) { if (sfp->closed) {
sdp->device->access_count--; sdp->device->access_count--;
if (sg_template.module) module_put(sdp->device->host->hostt->module);
__MOD_DEC_USE_COUNT(sg_template.module);
if (sdp->device->host->hostt->module)
__MOD_DEC_USE_COUNT(
sdp->device->host->
hostt->module);
__sg_remove_sfp(sdp, sfp); __sg_remove_sfp(sdp, sfp);
} else { } else {
delay = 1; delay = 1;
...@@ -2530,13 +2520,12 @@ sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp) ...@@ -2530,13 +2520,12 @@ sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
} }
write_unlock_irqrestore(&sg_dev_arr_lock, iflags); write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
} else { } 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 */ /* MOD_INC's to inhibit unloading sg and associated adapter driver */
if (sg_template.module) /* only bump the access_count if we actually succeeded in
__MOD_INC_USE_COUNT(sg_template.module); * throwing another counter on the host module */
if (sdp->device->host->hostt->module) if(try_module_get(sdp->device->host->hostt->module))
__MOD_INC_USE_COUNT(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", SCSI_LOG_TIMEOUT(1, printk("sg_remove_sfp: worrisome, %d writes pending\n",
dirty)); dirty));
} }
......
...@@ -72,6 +72,7 @@ static int sr_init_command(struct scsi_cmnd *); ...@@ -72,6 +72,7 @@ static int sr_init_command(struct scsi_cmnd *);
static struct Scsi_Device_Template sr_template = { static struct Scsi_Device_Template sr_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.list = LIST_HEAD_INIT(sr_template.list),
.name = "cdrom", .name = "cdrom",
.tag = "sr", .tag = "sr",
.scsi_type = TYPE_ROM, .scsi_type = TYPE_ROM,
...@@ -130,10 +131,7 @@ static void sr_release(struct cdrom_device_info *cdi) ...@@ -130,10 +131,7 @@ static void sr_release(struct cdrom_device_info *cdi)
if (cd->device->sector_size > 2048) if (cd->device->sector_size > 2048)
sr_set_blocklength(cd, 2048); sr_set_blocklength(cd, 2048);
cd->device->access_count--; cd->device->access_count--;
if (cd->device->host->hostt->module) module_put(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);
} }
static struct cdrom_device_ops sr_dops = { static struct cdrom_device_ops sr_dops = {
...@@ -472,11 +470,9 @@ static int sr_open(struct cdrom_device_info *cdi, int purpose) ...@@ -472,11 +470,9 @@ static int sr_open(struct cdrom_device_info *cdi, int purpose)
if (!scsi_block_when_processing_errors(cd->device)) { if (!scsi_block_when_processing_errors(cd->device)) {
return -ENXIO; return -ENXIO;
} }
if(!try_module_get(cd->device->host->hostt->module))
return -ENXIO;
cd->device->access_count++; 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 /* 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 * we would have been unable to get the sector size. Check to see if
......
...@@ -175,6 +175,7 @@ static void st_detach(Scsi_Device *); ...@@ -175,6 +175,7 @@ static void st_detach(Scsi_Device *);
static struct Scsi_Device_Template st_template = { static struct Scsi_Device_Template st_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.list = LIST_HEAD_INIT(st_template.list),
.name = "tape", .name = "tape",
.tag = "st", .tag = "st",
.scsi_type = TYPE_TAPE, .scsi_type = TYPE_TAPE,
...@@ -992,13 +993,13 @@ static int st_open(struct inode *inode, struct file *filp) ...@@ -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); ) DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
return (-EBUSY); return (-EBUSY);
} }
if(!try_module_get(STp->device->host->hostt->module))
return (-ENXIO);
STp->device->access_count++;
STp->in_use = 1; STp->in_use = 1;
write_unlock(&st_dev_arr_lock); write_unlock(&st_dev_arr_lock);
STp->rew_at_close = STp->autorew_dev = (minor(inode->i_rdev) & 0x80) == 0; 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)) { if (!scsi_block_when_processing_errors(STp->device)) {
retval = (-ENXIO); retval = (-ENXIO);
...@@ -1040,8 +1041,7 @@ static int st_open(struct inode *inode, struct file *filp) ...@@ -1040,8 +1041,7 @@ static int st_open(struct inode *inode, struct file *filp)
normalize_buffer(STp->buffer); normalize_buffer(STp->buffer);
STp->in_use = 0; STp->in_use = 0;
STp->device->access_count--; STp->device->access_count--;
if (STp->device->host->hostt->module) module_put(STp->device->host->hostt->module);
__MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
return retval; return retval;
} }
...@@ -1175,8 +1175,7 @@ static int st_release(struct inode *inode, struct file *filp) ...@@ -1175,8 +1175,7 @@ static int st_release(struct inode *inode, struct file *filp)
STp->in_use = 0; STp->in_use = 0;
write_unlock(&st_dev_arr_lock); write_unlock(&st_dev_arr_lock);
STp->device->access_count--; STp->device->access_count--;
if (STp->device->host->hostt->module) module_put(STp->device->host->hostt->module);
__MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
return result; return result;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment