Commit 4ffc562a authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz Committed by Linus Torvalds

[PATCH] ide_unregister() fixes

From Benjamin Herrenschmidt <benh@kernel.crashing.org>.

- avoid device list corruption and scheduling at interrupt time
  (more work needed on proper locking)
- make sure "hold" flag and ide_dma_queued_* ops are properly
  transferred from old to new interface
parent aaba5e8c
...@@ -689,8 +689,8 @@ void ide_unregister (unsigned int index) ...@@ -689,8 +689,8 @@ void ide_unregister (unsigned int index)
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
destroy_proc_ide_drives(hwif); destroy_proc_ide_drives(hwif);
#endif #endif
hwgroup = hwif->hwgroup;
hwgroup = hwif->hwgroup;
/* /*
* free the irq if we were the only hwif using it * free the irq if we were the only hwif using it
*/ */
...@@ -745,7 +745,11 @@ void ide_unregister (unsigned int index) ...@@ -745,7 +745,11 @@ void ide_unregister (unsigned int index)
drive->id = NULL; drive->id = NULL;
} }
drive->present = 0; drive->present = 0;
/* Messed up locking ... */
spin_unlock_irq(&ide_lock);
blk_cleanup_queue(drive->queue); blk_cleanup_queue(drive->queue);
device_unregister(&drive->gendev);
spin_lock_irq(&ide_lock);
drive->queue = NULL; drive->queue = NULL;
} }
if (hwif->next == hwif) { if (hwif->next == hwif) {
...@@ -771,6 +775,11 @@ void ide_unregister (unsigned int index) ...@@ -771,6 +775,11 @@ void ide_unregister (unsigned int index)
BUG_ON(hwgroup->hwif == hwif); BUG_ON(hwgroup->hwif == hwif);
} }
/* More messed up locking ... */
spin_unlock_irq(&ide_lock);
device_unregister(&hwif->gendev);
spin_lock_irq(&ide_lock);
#if !defined(CONFIG_DMA_NONPCI) #if !defined(CONFIG_DMA_NONPCI)
if (hwif->dma_base) { if (hwif->dma_base) {
(void) ide_release_dma(hwif); (void) ide_release_dma(hwif);
...@@ -795,6 +804,7 @@ void ide_unregister (unsigned int index) ...@@ -795,6 +804,7 @@ void ide_unregister (unsigned int index)
put_disk(disk); put_disk(disk);
} }
unregister_blkdev(hwif->major, hwif->name); unregister_blkdev(hwif->major, hwif->name);
old_hwif = *hwif; old_hwif = *hwif;
init_hwif_data(index); /* restore hwif data to pristine status */ init_hwif_data(index); /* restore hwif data to pristine status */
hwif->hwgroup = old_hwif.hwgroup; hwif->hwgroup = old_hwif.hwgroup;
...@@ -813,6 +823,7 @@ void ide_unregister (unsigned int index) ...@@ -813,6 +823,7 @@ void ide_unregister (unsigned int index)
hwif->swdma_mask = old_hwif.swdma_mask; hwif->swdma_mask = old_hwif.swdma_mask;
hwif->chipset = old_hwif.chipset; hwif->chipset = old_hwif.chipset;
hwif->hold = old_hwif.hold;
#ifdef CONFIG_BLK_DEV_IDEPCI #ifdef CONFIG_BLK_DEV_IDEPCI
hwif->pci_dev = old_hwif.pci_dev; hwif->pci_dev = old_hwif.pci_dev;
...@@ -865,6 +876,13 @@ void ide_unregister (unsigned int index) ...@@ -865,6 +876,13 @@ void ide_unregister (unsigned int index)
hwif->ide_dma_retune = old_hwif.ide_dma_retune; hwif->ide_dma_retune = old_hwif.ide_dma_retune;
hwif->ide_dma_lostirq = old_hwif.ide_dma_lostirq; hwif->ide_dma_lostirq = old_hwif.ide_dma_lostirq;
hwif->ide_dma_timeout = old_hwif.ide_dma_timeout; hwif->ide_dma_timeout = old_hwif.ide_dma_timeout;
hwif->ide_dma_queued_on = old_hwif.ide_dma_queued_on;
hwif->ide_dma_queued_off = old_hwif.ide_dma_queued_off;
#ifdef CONFIG_BLK_DEV_IDE_TCQ
hwif->ide_dma_queued_read = old_hwif.ide_dma_queued_read;
hwif->ide_dma_queued_write = old_hwif.ide_dma_queued_write;
hwif->ide_dma_queued_start = old_hwif.ide_dma_queued_start;
#endif
#endif #endif
#if 0 #if 0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment