diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-01-06 19:20:49 +0300 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-01-06 19:20:49 +0300 |
commit | efe0397eef544ac4bcca23d39aa8d5db154952e0 (patch) | |
tree | 25418872f1a813d3fd15237dad67797d93aa8ad3 /drivers/ide | |
parent | ae86afaee6a1c77c7a06d81dcc3bf872204d3bec (diff) | |
download | linux-efe0397eef544ac4bcca23d39aa8d5db154952e0.tar.xz |
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>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-io.c | 12 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 90 |
2 files changed, 12 insertions, 90 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 1fc739f44154..4ce793c05629 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -742,12 +742,12 @@ repeat: * set nIEN for previous port, drives in the * quirk_list may not like intr setups/cleanups */ - if (prev_port && hwgroup->drive->quirk_list == 0) + if (prev_port && hwgroup->cur_dev->quirk_list == 0) prev_port->tp_ops->set_irq(prev_port, 0); hwif->host->cur_port = hwif; } - hwgroup->drive = drive; + hwgroup->cur_dev = drive; drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); spin_unlock_irq(&hwgroup->lock); @@ -913,9 +913,9 @@ void ide_timer_expiry (unsigned long data) * Either way, we don't really want to complain about anything. */ } else { - drive = hwgroup->drive; + drive = hwgroup->cur_dev; if (!drive) { - printk(KERN_ERR "ide_timer_expiry: hwgroup->drive was NULL\n"); + printk(KERN_ERR "%s: ->cur_dev was NULL\n", __func__); hwgroup->handler = NULL; } else { ide_hwif_t *hwif; @@ -1033,7 +1033,7 @@ static void unexpected_intr(int irq, ide_hwif_t *hwif) * places * * hwif is the interface in the group currently performing - * a command. hwgroup->drive is the drive and hwgroup->handler is + * a command. hwgroup->cur_dev is the drive and hwgroup->handler is * the IRQ handler to call. As we issue a command the handlers * step through multiple states, reassigning the handler to the * next step in the process. Unlike a smart SCSI controller IDE @@ -1105,7 +1105,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) goto out; } - drive = hwgroup->drive; + drive = hwgroup->cur_dev; if (!drive) { /* * This should NEVER happen, and there isn't much diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 2752509531b7..68f3c87b8284 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -918,27 +918,9 @@ static int ide_init_queue(ide_drive_t *drive) 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 @@ static int ide_port_setup_devices(ide_hwif_t *hwif) } j++; - - ide_add_drive_to_hwgroup(drive); } mutex_unlock(&ide_cfg_mtx); @@ -978,33 +958,9 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) 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 @@ static int init_irq (ide_hwif_t *hwif) 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 @@ static int init_irq (ide_hwif_t *hwif) 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 @@ void ide_init_disk(struct gendisk *disk, ide_drive_t *drive) 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 @@ static void drive_release_dev (struct device *dev) 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; |