|
@@ -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;
|
|
|
}
|
|
|
|
|
|
+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
|
|
|
* @index: index of interface (will change soon to a pointer)
|
|
@@ -528,36 +563,8 @@ void ide_unregister(unsigned int index)
|
|
|
if (irq_count == 1)
|
|
|
free_irq(hwif->irq, 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.
|
|
|
- */
|
|
|
- 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);
|
|
|
- }
|
|
|
+ ide_remove_port_from_hwgroup(hwif);
|
|
|
|
|
|
- /* More messed up locking ... */
|
|
|
- spin_unlock_irq(&ide_lock);
|
|
|
device_unregister(&hwif->gendev);
|
|
|
wait_for_completion(&hwif->gendev_rel_comp);
|
|
|
|