]> err.no Git - linux-2.6/blobdiff - drivers/ata/ahci.c
sata_sil24: implement PORT_RST
[linux-2.6] / drivers / ata / ahci.c
index cf3404467cebecafb55724d07470b5019956d703..b615390b6b8a0fc7c52d4bc09060562f3f490a5c 100644 (file)
@@ -827,8 +827,14 @@ static int ahci_reset_controller(struct ata_host *host)
        void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
        u32 tmp;
 
-       /* global controller reset */
+       /* we must be in AHCI mode, before using anything
+        * AHCI-specific, such as HOST_RESET.
+        */
        tmp = readl(mmio + HOST_CTL);
+       if (!(tmp & HOST_AHCI_EN))
+               writel(tmp | HOST_AHCI_EN, mmio + HOST_CTL);
+
+       /* global controller reset */
        if ((tmp & HOST_RESET) == 0) {
                writel(tmp | HOST_RESET, mmio + HOST_CTL);
                readl(mmio + HOST_CTL); /* flush */
@@ -1356,27 +1362,17 @@ static void ahci_port_intr(struct ata_port *ap)
        }
 
        if (status & PORT_IRQ_SDB_FIS) {
-               /*
-                * if this is an ATAPI device with AN turned on,
-                * then we should interrogate the device to
-                * determine the cause of the interrupt
-                *
-                * for AN - this we should check the SDB FIS
-                * and find the I and N bits set
+               /* If the 'N' bit in word 0 of the FIS is set, we just
+                * received asynchronous notification.  Tell libata
+                * about it.  Note that as the SDB FIS itself is
+                * accessible, SNotification can be emulated by the
+                * driver but don't bother for the time being.
                 */
                const __le32 *f = pp->rx_fis + RX_FIS_SDB;
                u32 f0 = le32_to_cpu(f[0]);
 
-               /* check the 'N' bit in word 0 of the FIS */
-               if (f0 & (1 << 15)) {
-                       int port_addr = ((f0 & 0x00000f00) >> 8);
-                       struct ata_device *adev;
-                       if (port_addr < ATA_MAX_DEVICES) {
-                               adev = &ap->link.device[port_addr];
-                               if (adev->flags & ATA_DFLAG_AN)
-                                       ata_scsi_media_change_notify(adev);
-                       }
-               }
+               if (f0 & (1 << 15))
+                       sata_async_notification(ap);
        }
 
        if (ap->link.sactive)