aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-cd.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-02-25 14:28:24 -0500
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-02-25 14:28:24 -0500
commit8fed43684174b68f04d01d1210fd00536af790df (patch)
treedf8d5f87c68526267d0ae320173814ed3f417fd5 /drivers/ide/ide-cd.c
parentd3dd7107f4d843d0f01d0f77d49a7c5449130577 (diff)
ide: fix refcounting in device drivers
During host driver module removal del_gendisk() results in a final put on drive->gendev and freeing the drive by drive_release_dev(). Convert device drivers from using struct kref to use struct device so device driver's object holds reference on ->gendev and prevents drive from prematurely going away. Also fix ->remove methods to not erroneously drop reference on a host driver by using only put_device() instead of ide*_put(). Reported-by: Stanislaw Gruszka <stf_xl@wp.pl> Tested-by: Stanislaw Gruszka <stf_xl@wp.pl> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r--drivers/ide/ide-cd.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 690475b834de..ddfbea41d296 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -55,7 +55,7 @@
55 55
56static DEFINE_MUTEX(idecd_ref_mutex); 56static DEFINE_MUTEX(idecd_ref_mutex);
57 57
58static void ide_cd_release(struct kref *); 58static void ide_cd_release(struct device *);
59 59
60static struct cdrom_info *ide_cd_get(struct gendisk *disk) 60static struct cdrom_info *ide_cd_get(struct gendisk *disk)
61{ 61{
@@ -67,7 +67,7 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk)
67 if (ide_device_get(cd->drive)) 67 if (ide_device_get(cd->drive))
68 cd = NULL; 68 cd = NULL;
69 else 69 else
70 kref_get(&cd->kref); 70 get_device(&cd->dev);
71 71
72 } 72 }
73 mutex_unlock(&idecd_ref_mutex); 73 mutex_unlock(&idecd_ref_mutex);
@@ -79,7 +79,7 @@ static void ide_cd_put(struct cdrom_info *cd)
79 ide_drive_t *drive = cd->drive; 79 ide_drive_t *drive = cd->drive;
80 80
81 mutex_lock(&idecd_ref_mutex); 81 mutex_lock(&idecd_ref_mutex);
82 kref_put(&cd->kref, ide_cd_release); 82 put_device(&cd->dev);
83 ide_device_put(drive); 83 ide_device_put(drive);
84 mutex_unlock(&idecd_ref_mutex); 84 mutex_unlock(&idecd_ref_mutex);
85} 85}
@@ -1798,15 +1798,17 @@ static void ide_cd_remove(ide_drive_t *drive)
1798 ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); 1798 ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
1799 1799
1800 ide_proc_unregister_driver(drive, info->driver); 1800 ide_proc_unregister_driver(drive, info->driver);
1801 1801 device_del(&info->dev);
1802 del_gendisk(info->disk); 1802 del_gendisk(info->disk);
1803 1803
1804 ide_cd_put(info); 1804 mutex_lock(&idecd_ref_mutex);
1805 put_device(&info->dev);
1806 mutex_unlock(&idecd_ref_mutex);
1805} 1807}
1806 1808
1807static void ide_cd_release(struct kref *kref) 1809static void ide_cd_release(struct device *dev)
1808{ 1810{
1809 struct cdrom_info *info = to_ide_drv(kref, cdrom_info); 1811 struct cdrom_info *info = to_ide_drv(dev, cdrom_info);
1810 struct cdrom_device_info *devinfo = &info->devinfo; 1812 struct cdrom_device_info *devinfo = &info->devinfo;
1811 ide_drive_t *drive = info->drive; 1813 ide_drive_t *drive = info->drive;
1812 struct gendisk *g = info->disk; 1814 struct gendisk *g = info->disk;
@@ -2005,7 +2007,12 @@ static int ide_cd_probe(ide_drive_t *drive)
2005 2007
2006 ide_init_disk(g, drive); 2008 ide_init_disk(g, drive);
2007 2009
2008 kref_init(&info->kref); 2010 info->dev.parent = &drive->gendev;
2011 info->dev.release = ide_cd_release;
2012 dev_set_name(&info->dev, dev_name(&drive->gendev));
2013
2014 if (device_register(&info->dev))
2015 goto out_free_disk;
2009 2016
2010 info->drive = drive; 2017 info->drive = drive;
2011 info->driver = &ide_cdrom_driver; 2018 info->driver = &ide_cdrom_driver;
@@ -2019,7 +2026,7 @@ static int ide_cd_probe(ide_drive_t *drive)
2019 g->driverfs_dev = &drive->gendev; 2026 g->driverfs_dev = &drive->gendev;
2020 g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; 2027 g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
2021 if (ide_cdrom_setup(drive)) { 2028 if (ide_cdrom_setup(drive)) {
2022 ide_cd_release(&info->kref); 2029 put_device(&info->dev);
2023 goto failed; 2030 goto failed;
2024 } 2031 }
2025 2032
@@ -2029,6 +2036,8 @@ static int ide_cd_probe(ide_drive_t *drive)
2029 add_disk(g); 2036 add_disk(g);
2030 return 0; 2037 return 0;
2031 2038
2039out_free_disk:
2040 put_disk(g);
2032out_free_cd: 2041out_free_cd:
2033 kfree(info); 2042 kfree(info);
2034failed: 2043failed: