diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-07-24 16:53:15 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-07-24 16:53:15 -0400 |
commit | 08da591e14cf87247ec09b17c350235157a92fc3 (patch) | |
tree | d00a02154071c7013c31bc8dd1d3c12c86d5daca /drivers/ide | |
parent | 6cdf6eb357c2681596b7b1672b92396ba82333d4 (diff) |
ide: add ide_device_{get,put}() helpers
* Add 'struct ide_host *host' field to ide_hwif_t and set it
in ide_host_alloc_all().
* Add ide_device_{get,put}() helpers loosely based on SCSI's
scsi_device_{get,put}() ones.
* Convert IDE device drivers to use ide_device_{get,put}().
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-cd.c | 12 | ||||
-rw-r--r-- | drivers/ide/ide-disk.c | 12 | ||||
-rw-r--r-- | drivers/ide/ide-floppy.c | 12 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 12 | ||||
-rw-r--r-- | drivers/ide/ide.c | 47 |
6 files changed, 85 insertions, 12 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 4e73aeee4053..8f253e5f26a8 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -57,23 +57,29 @@ static DEFINE_MUTEX(idecd_ref_mutex); | |||
57 | #define ide_cd_g(disk) \ | 57 | #define ide_cd_g(disk) \ |
58 | container_of((disk)->private_data, struct cdrom_info, driver) | 58 | container_of((disk)->private_data, struct cdrom_info, driver) |
59 | 59 | ||
60 | static void ide_cd_release(struct kref *); | ||
61 | |||
60 | static struct cdrom_info *ide_cd_get(struct gendisk *disk) | 62 | static struct cdrom_info *ide_cd_get(struct gendisk *disk) |
61 | { | 63 | { |
62 | struct cdrom_info *cd = NULL; | 64 | struct cdrom_info *cd = NULL; |
63 | 65 | ||
64 | mutex_lock(&idecd_ref_mutex); | 66 | mutex_lock(&idecd_ref_mutex); |
65 | cd = ide_cd_g(disk); | 67 | cd = ide_cd_g(disk); |
66 | if (cd) | 68 | if (cd) { |
67 | kref_get(&cd->kref); | 69 | kref_get(&cd->kref); |
70 | if (ide_device_get(cd->drive)) { | ||
71 | kref_put(&cd->kref, ide_cd_release); | ||
72 | cd = NULL; | ||
73 | } | ||
74 | } | ||
68 | mutex_unlock(&idecd_ref_mutex); | 75 | mutex_unlock(&idecd_ref_mutex); |
69 | return cd; | 76 | return cd; |
70 | } | 77 | } |
71 | 78 | ||
72 | static void ide_cd_release(struct kref *); | ||
73 | |||
74 | static void ide_cd_put(struct cdrom_info *cd) | 79 | static void ide_cd_put(struct cdrom_info *cd) |
75 | { | 80 | { |
76 | mutex_lock(&idecd_ref_mutex); | 81 | mutex_lock(&idecd_ref_mutex); |
82 | ide_device_put(cd->drive); | ||
77 | kref_put(&cd->kref, ide_cd_release); | 83 | kref_put(&cd->kref, ide_cd_release); |
78 | mutex_unlock(&idecd_ref_mutex); | 84 | mutex_unlock(&idecd_ref_mutex); |
79 | } | 85 | } |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index df5fe5756871..28d85b410f7c 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -56,23 +56,29 @@ static DEFINE_MUTEX(idedisk_ref_mutex); | |||
56 | #define ide_disk_g(disk) \ | 56 | #define ide_disk_g(disk) \ |
57 | container_of((disk)->private_data, struct ide_disk_obj, driver) | 57 | container_of((disk)->private_data, struct ide_disk_obj, driver) |
58 | 58 | ||
59 | static void ide_disk_release(struct kref *); | ||
60 | |||
59 | static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) | 61 | static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) |
60 | { | 62 | { |
61 | struct ide_disk_obj *idkp = NULL; | 63 | struct ide_disk_obj *idkp = NULL; |
62 | 64 | ||
63 | mutex_lock(&idedisk_ref_mutex); | 65 | mutex_lock(&idedisk_ref_mutex); |
64 | idkp = ide_disk_g(disk); | 66 | idkp = ide_disk_g(disk); |
65 | if (idkp) | 67 | if (idkp) { |
66 | kref_get(&idkp->kref); | 68 | kref_get(&idkp->kref); |
69 | if (ide_device_get(idkp->drive)) { | ||
70 | kref_put(&idkp->kref, ide_disk_release); | ||
71 | idkp = NULL; | ||
72 | } | ||
73 | } | ||
67 | mutex_unlock(&idedisk_ref_mutex); | 74 | mutex_unlock(&idedisk_ref_mutex); |
68 | return idkp; | 75 | return idkp; |
69 | } | 76 | } |
70 | 77 | ||
71 | static void ide_disk_release(struct kref *); | ||
72 | |||
73 | static void ide_disk_put(struct ide_disk_obj *idkp) | 78 | static void ide_disk_put(struct ide_disk_obj *idkp) |
74 | { | 79 | { |
75 | mutex_lock(&idedisk_ref_mutex); | 80 | mutex_lock(&idedisk_ref_mutex); |
81 | ide_device_put(idkp->drive); | ||
76 | kref_put(&idkp->kref, ide_disk_release); | 82 | kref_put(&idkp->kref, ide_disk_release); |
77 | mutex_unlock(&idedisk_ref_mutex); | 83 | mutex_unlock(&idedisk_ref_mutex); |
78 | } | 84 | } |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 3d8e6dd0f41e..ca11a26746f1 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -158,23 +158,29 @@ static DEFINE_MUTEX(idefloppy_ref_mutex); | |||
158 | #define ide_floppy_g(disk) \ | 158 | #define ide_floppy_g(disk) \ |
159 | container_of((disk)->private_data, struct ide_floppy_obj, driver) | 159 | container_of((disk)->private_data, struct ide_floppy_obj, driver) |
160 | 160 | ||
161 | static void idefloppy_cleanup_obj(struct kref *); | ||
162 | |||
161 | static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk) | 163 | static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk) |
162 | { | 164 | { |
163 | struct ide_floppy_obj *floppy = NULL; | 165 | struct ide_floppy_obj *floppy = NULL; |
164 | 166 | ||
165 | mutex_lock(&idefloppy_ref_mutex); | 167 | mutex_lock(&idefloppy_ref_mutex); |
166 | floppy = ide_floppy_g(disk); | 168 | floppy = ide_floppy_g(disk); |
167 | if (floppy) | 169 | if (floppy) { |
168 | kref_get(&floppy->kref); | 170 | kref_get(&floppy->kref); |
171 | if (ide_device_get(floppy->drive)) { | ||
172 | kref_put(&floppy->kref, idefloppy_cleanup_obj); | ||
173 | floppy = NULL; | ||
174 | } | ||
175 | } | ||
169 | mutex_unlock(&idefloppy_ref_mutex); | 176 | mutex_unlock(&idefloppy_ref_mutex); |
170 | return floppy; | 177 | return floppy; |
171 | } | 178 | } |
172 | 179 | ||
173 | static void idefloppy_cleanup_obj(struct kref *); | ||
174 | |||
175 | static void ide_floppy_put(struct ide_floppy_obj *floppy) | 180 | static void ide_floppy_put(struct ide_floppy_obj *floppy) |
176 | { | 181 | { |
177 | mutex_lock(&idefloppy_ref_mutex); | 182 | mutex_lock(&idefloppy_ref_mutex); |
183 | ide_device_put(floppy->drive); | ||
178 | kref_put(&floppy->kref, idefloppy_cleanup_obj); | 184 | kref_put(&floppy->kref, idefloppy_cleanup_obj); |
179 | mutex_unlock(&idefloppy_ref_mutex); | 185 | mutex_unlock(&idefloppy_ref_mutex); |
180 | } | 186 | } |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 890c15b1b3ae..9ab5892eaea1 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -1595,6 +1595,8 @@ struct ide_host *ide_host_alloc_all(const struct ide_port_info *d, | |||
1595 | 1595 | ||
1596 | ide_init_port_data(hwif, idx); | 1596 | ide_init_port_data(hwif, idx); |
1597 | 1597 | ||
1598 | hwif->host = host; | ||
1599 | |||
1598 | host->ports[i] = hwif; | 1600 | host->ports[i] = hwif; |
1599 | host->n_ports++; | 1601 | host->n_ports++; |
1600 | } | 1602 | } |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 6962ca4891a1..789f3428f072 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -322,23 +322,29 @@ static struct class *idetape_sysfs_class; | |||
322 | #define ide_tape_g(disk) \ | 322 | #define ide_tape_g(disk) \ |
323 | container_of((disk)->private_data, struct ide_tape_obj, driver) | 323 | container_of((disk)->private_data, struct ide_tape_obj, driver) |
324 | 324 | ||
325 | static void ide_tape_release(struct kref *); | ||
326 | |||
325 | static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) | 327 | static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) |
326 | { | 328 | { |
327 | struct ide_tape_obj *tape = NULL; | 329 | struct ide_tape_obj *tape = NULL; |
328 | 330 | ||
329 | mutex_lock(&idetape_ref_mutex); | 331 | mutex_lock(&idetape_ref_mutex); |
330 | tape = ide_tape_g(disk); | 332 | tape = ide_tape_g(disk); |
331 | if (tape) | 333 | if (tape) { |
332 | kref_get(&tape->kref); | 334 | kref_get(&tape->kref); |
335 | if (ide_device_get(tape->drive)) { | ||
336 | kref_put(&tape->kref, ide_tape_release); | ||
337 | tape = NULL; | ||
338 | } | ||
339 | } | ||
333 | mutex_unlock(&idetape_ref_mutex); | 340 | mutex_unlock(&idetape_ref_mutex); |
334 | return tape; | 341 | return tape; |
335 | } | 342 | } |
336 | 343 | ||
337 | static void ide_tape_release(struct kref *); | ||
338 | |||
339 | static void ide_tape_put(struct ide_tape_obj *tape) | 344 | static void ide_tape_put(struct ide_tape_obj *tape) |
340 | { | 345 | { |
341 | mutex_lock(&idetape_ref_mutex); | 346 | mutex_lock(&idetape_ref_mutex); |
347 | ide_device_put(tape->drive); | ||
342 | kref_put(&tape->kref, ide_tape_release); | 348 | kref_put(&tape->kref, ide_tape_release); |
343 | mutex_unlock(&idetape_ref_mutex); | 349 | mutex_unlock(&idetape_ref_mutex); |
344 | } | 350 | } |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 60f0ca66aa93..772451600e4d 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -618,6 +618,53 @@ set_val: | |||
618 | 618 | ||
619 | EXPORT_SYMBOL(generic_ide_ioctl); | 619 | EXPORT_SYMBOL(generic_ide_ioctl); |
620 | 620 | ||
621 | /** | ||
622 | * ide_device_get - get an additional reference to a ide_drive_t | ||
623 | * @drive: device to get a reference to | ||
624 | * | ||
625 | * Gets a reference to the ide_drive_t and increments the use count of the | ||
626 | * underlying LLDD module. | ||
627 | */ | ||
628 | int ide_device_get(ide_drive_t *drive) | ||
629 | { | ||
630 | struct device *host_dev; | ||
631 | struct module *module; | ||
632 | |||
633 | if (!get_device(&drive->gendev)) | ||
634 | return -ENXIO; | ||
635 | |||
636 | host_dev = drive->hwif->host->dev[0]; | ||
637 | module = host_dev ? host_dev->driver->owner : NULL; | ||
638 | |||
639 | if (module && !try_module_get(module)) { | ||
640 | put_device(&drive->gendev); | ||
641 | return -ENXIO; | ||
642 | } | ||
643 | |||
644 | return 0; | ||
645 | } | ||
646 | EXPORT_SYMBOL_GPL(ide_device_get); | ||
647 | |||
648 | /** | ||
649 | * ide_device_put - release a reference to a ide_drive_t | ||
650 | * @drive: device to release a reference on | ||
651 | * | ||
652 | * Release a reference to the ide_drive_t and decrements the use count of | ||
653 | * the underlying LLDD module. | ||
654 | */ | ||
655 | void ide_device_put(ide_drive_t *drive) | ||
656 | { | ||
657 | #ifdef CONFIG_MODULE_UNLOAD | ||
658 | struct device *host_dev = drive->hwif->host->dev[0]; | ||
659 | struct module *module = host_dev ? host_dev->driver->owner : NULL; | ||
660 | |||
661 | if (module) | ||
662 | module_put(module); | ||
663 | #endif | ||
664 | put_device(&drive->gendev); | ||
665 | } | ||
666 | EXPORT_SYMBOL_GPL(ide_device_put); | ||
667 | |||
621 | static int ide_bus_match(struct device *dev, struct device_driver *drv) | 668 | static int ide_bus_match(struct device *dev, struct device_driver *drv) |
622 | { | 669 | { |
623 | return 1; | 670 | return 1; |