ide: factor out code removing port from hwgroup from ide_unregister()
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
This commit is contained in:
@@ -461,6 +461,41 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
|
|||||||
hwif->hwif_data = tmp_hwif->hwif_data;
|
hwif->hwif_data = tmp_hwif->hwif_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
|
||||||
|
{
|
||||||
|
ide_hwgroup_t *hwgroup = hwif->hwgroup;
|
||||||
|
|
||||||
|
spin_lock_irq(&ide_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);
|
||||||
|
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(&ide_lock);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ide_unregister - free an IDE interface
|
* ide_unregister - free an IDE interface
|
||||||
* @index: index of interface (will change soon to a pointer)
|
* @index: index of interface (will change soon to a pointer)
|
||||||
@@ -528,36 +563,8 @@ void ide_unregister(unsigned int index)
|
|||||||
if (irq_count == 1)
|
if (irq_count == 1)
|
||||||
free_irq(hwif->irq, hwgroup);
|
free_irq(hwif->irq, hwgroup);
|
||||||
|
|
||||||
spin_lock_irq(&ide_lock);
|
ide_remove_port_from_hwgroup(hwif);
|
||||||
/*
|
|
||||||
* Remove us from the hwgroup, and free
|
|
||||||
* the hwgroup if we were the only member
|
|
||||||
*/
|
|
||||||
if (hwif->next == hwif) {
|
|
||||||
BUG_ON(hwgroup->hwif != hwif);
|
|
||||||
kfree(hwgroup);
|
|
||||||
} else {
|
|
||||||
/* There is another interface in hwgroup.
|
|
||||||
* Unlink us, and set hwgroup->drive and ->hwif to
|
|
||||||
* something sane.
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* More messed up locking ... */
|
|
||||||
spin_unlock_irq(&ide_lock);
|
|
||||||
device_unregister(&hwif->gendev);
|
device_unregister(&hwif->gendev);
|
||||||
wait_for_completion(&hwif->gendev_rel_comp);
|
wait_for_completion(&hwif->gendev_rel_comp);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user