ata: libata-core: Fix port and device removal
[linux-2.6-microblaze.git] / drivers / ata / libata-core.c
index 732f3d0..8e35afe 100644 (file)
@@ -5948,11 +5948,30 @@ static void ata_port_detach(struct ata_port *ap)
        struct ata_link *link;
        struct ata_device *dev;
 
-       /* tell EH we're leaving & flush EH */
+       /* Wait for any ongoing EH */
+       ata_port_wait_eh(ap);
+
+       mutex_lock(&ap->scsi_scan_mutex);
        spin_lock_irqsave(ap->lock, flags);
+
+       /* Remove scsi devices */
+       ata_for_each_link(link, ap, HOST_FIRST) {
+               ata_for_each_dev(dev, link, ALL) {
+                       if (dev->sdev) {
+                               spin_unlock_irqrestore(ap->lock, flags);
+                               scsi_remove_device(dev->sdev);
+                               spin_lock_irqsave(ap->lock, flags);
+                               dev->sdev = NULL;
+                       }
+               }
+       }
+
+       /* Tell EH to disable all devices */
        ap->pflags |= ATA_PFLAG_UNLOADING;
        ata_port_schedule_eh(ap);
+
        spin_unlock_irqrestore(ap->lock, flags);
+       mutex_unlock(&ap->scsi_scan_mutex);
 
        /* wait till EH commits suicide */
        ata_port_wait_eh(ap);