patch-2.4.0-test2 linux/drivers/sound/sound_core.c
Next file: linux/drivers/sound/soundcard.c
Previous file: linux/drivers/sound/sonicvibes.c
Back to the patch index
Back to the overall index
- Lines: 50
- Date:
Wed Jun 21 22:31:02 2000
- Orig file:
v2.4.0-test1/linux/drivers/sound/sound_core.c
- Orig date:
Wed Apr 26 16:34:08 2000
diff -u --recursive --new-file v2.4.0-test1/linux/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c
@@ -175,9 +175,9 @@
sprintf (name_buf, "%s", name);
else
sprintf (name_buf, "%s%d", name, (r - low) / SOUND_STEP);
- s->de = devfs_register (devfs_handle, name_buf, 0,
+ s->de = devfs_register (devfs_handle, name_buf,
DEVFS_FL_NONE, SOUND_MAJOR, s->unit_minor,
- S_IFCHR | mode, 0, 0, fops, NULL);
+ S_IFCHR | mode, fops, NULL);
return r;
}
@@ -456,6 +456,7 @@
static struct file_operations soundcore_fops=
{
+ owner: THIS_MODULE,
open: soundcore_open,
};
@@ -508,12 +509,25 @@
s = __look_for_unit(chain, unit);
}
if (s) {
- file->f_op=s->unit_fops;
+ /*
+ * We rely upon the fact that we can't be unloaded while the
+ * subdriver is there, so if ->open() is successful we can
+ * safely drop the reference counter and if it is not we can
+ * revert to old ->f_op. Ugly, indeed, but that's the cost of
+ * switching ->f_op in the first place.
+ */
+ int err = 0;
+ struct file_operations *old_fops = file->f_op;
+ file->f_op = fops_get(s->unit_fops);
spin_unlock(&sound_loader_lock);
if(file->f_op->open)
- return file->f_op->open(inode,file);
- else
- return 0;
+ err = file->f_op->open(inode,file);
+ if (err) {
+ fops_put(file->f_op);
+ file->f_op = fops_get(old_fops);
+ }
+ fops_put(old_fops);
+ return err;
}
spin_unlock(&sound_loader_lock);
return -ENODEV;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)