ide: remove hwgroup->hwif and {drive,hwif}->next
* Add 'int port_count' field to ide_hwgroup_t to keep the track
of the number of ports in the hwgroup. Then update init_irq()
and ide_remove_port_from_hwgroup() to use it.
* Remove no longer needed hwgroup->hwif, {drive,hwif}->next,
ide_add_drive_to_hwgroup() and ide_remove_drive_from_hwgroup()
(hwgroup->drive now only denotes the currently active device
in the hwgroup).
* Update locking documentation in <linux/ide.h>.
While at it:
* Rename ->drive field in ide_hwgroup_t to ->cur_dev.
* Use __func__ in ide_timer_expiry().
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 2752509..68f3c87 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -918,27 +918,9 @@
return 0;
}
-static void ide_add_drive_to_hwgroup(ide_drive_t *drive)
-{
- ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
-
- spin_lock_irq(&hwgroup->lock);
- if (!hwgroup->drive) {
- /* first drive for hwgroup. */
- drive->next = drive;
- hwgroup->drive = drive;
- hwgroup->hwif = HWIF(hwgroup->drive);
- } else {
- drive->next = hwgroup->drive->next;
- hwgroup->drive->next = drive;
- }
- spin_unlock_irq(&hwgroup->lock);
-}
-
/*
* For any present drive:
* - allocate the block device queue
- * - link drive into the hwgroup
*/
static int ide_port_setup_devices(ide_hwif_t *hwif)
{
@@ -961,8 +943,6 @@
}
j++;
-
- ide_add_drive_to_hwgroup(drive);
}
mutex_unlock(&ide_cfg_mtx);
@@ -978,33 +958,9 @@
ide_ports[hwif->index] = NULL;
spin_lock_irq(&hwgroup->lock);
- /*
- * Remove us from the hwgroup, and free
- * the hwgroup if we were the only member
- */
- if (hwif->next == hwif) {
- BUG_ON(hwgroup->hwif != hwif);
+ /* Free the hwgroup if we were the only member. */
+ if (--hwgroup->port_count == 0)
kfree(hwgroup);
- } else {
- /* There is another interface in hwgroup.
- * Unlink us, and set hwgroup->drive and ->hwif to
- * something sane.
- */
- ide_hwif_t *g = hwgroup->hwif;
-
- while (g->next != hwif)
- g = g->next;
- g->next = hwif->next;
- if (hwgroup->hwif == hwif) {
- /* Chose a random hwif for hwgroup->hwif.
- * It's guaranteed that there are no drives
- * left in the hwgroup.
- */
- BUG_ON(hwgroup->drive != NULL);
- hwgroup->hwif = g;
- }
- BUG_ON(hwgroup->hwif == hwif);
- }
spin_unlock_irq(&hwgroup->lock);
}
@@ -1044,20 +1000,9 @@
if (match) {
hwgroup = match->hwgroup;
hwif->hwgroup = hwgroup;
- /*
- * Link us into the hwgroup.
- * This must be done early, do ensure that unexpected_intr
- * can find the hwif and prevent irq storms.
- * No drives are attached to the new hwif, choose_drive
- * can't do anything stupid (yet).
- * Add ourself as the 2nd entry to the hwgroup->hwif
- * linked list, the first entry is the hwif that owns
- * hwgroup->handler - do not change that.
- */
+
spin_lock_irq(&hwgroup->lock);
- hwif->next = hwgroup->hwif->next;
- hwgroup->hwif->next = hwif;
- BUG_ON(hwif->next == hwif);
+ hwgroup->port_count++;
spin_unlock_irq(&hwgroup->lock);
} else {
hwgroup = kmalloc_node(sizeof(*hwgroup), GFP_KERNEL|__GFP_ZERO,
@@ -1068,7 +1013,8 @@
spin_lock_init(&hwgroup->lock);
hwif->hwgroup = hwgroup;
- hwgroup->hwif = hwif->next = hwif;
+
+ hwgroup->port_count = 1;
init_timer(&hwgroup->timer);
hwgroup->timer.function = &ide_timer_expiry;
@@ -1191,29 +1137,6 @@
EXPORT_SYMBOL_GPL(ide_init_disk);
-static void ide_remove_drive_from_hwgroup(ide_drive_t *drive)
-{
- ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
-
- if (drive == drive->next) {
- /* special case: last drive from hwgroup. */
- BUG_ON(hwgroup->drive != drive);
- hwgroup->drive = NULL;
- } else {
- ide_drive_t *walk;
-
- walk = hwgroup->drive;
- while (walk->next != drive)
- walk = walk->next;
- walk->next = drive->next;
- if (hwgroup->drive == drive) {
- hwgroup->drive = drive->next;
- hwgroup->hwif = hwgroup->drive->hwif;
- }
- }
- BUG_ON(hwgroup->drive == drive);
-}
-
static void drive_release_dev (struct device *dev)
{
ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
@@ -1222,7 +1145,6 @@
ide_proc_unregister_device(drive);
spin_lock_irq(&hwgroup->lock);
- ide_remove_drive_from_hwgroup(drive);
kfree(drive->id);
drive->id = NULL;
drive->dev_flags &= ~IDE_DFLAG_PRESENT;