ahci_xgene: Fix the DMA state machine lockup for the ATA_CMD_PACKET PIO mode command.
authorSuman Tripathi <stripathi@apm.com>
Mon, 29 Dec 2014 03:22:47 +0000 (08:52 +0530)
committerTejun Heo <tj@kernel.org>
Mon, 5 Jan 2015 14:02:56 +0000 (09:02 -0500)
This patch addresses the issue with ATA_CMD_PACKET pio mode
command for enumeration and device detection with ATAPI devices.
The X-Gene AHCI controller has an errata in which it cannot clear
the BSY bit after the PIO setup FIS. The dma state machine enters
CMFatalErrorUpdate state and locks up.

Signed-off-by: Suman Tripathi <stripathi@apm.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
drivers/ata/ahci_xgene.c

index f190b92..cbcd208 100644 (file)
@@ -125,10 +125,11 @@ static int xgene_ahci_restart_engine(struct ata_port *ap)
  * xgene_ahci_qc_issue - Issue commands to the device
  * @qc: Command to issue
  *
- * Due to Hardware errata for IDENTIFY DEVICE command, the controller cannot
- * clear the BSY bit after receiving the PIO setup FIS. This results in the dma
- * state machine goes into the CMFatalErrorUpdate state and locks up. By
- * restarting the dma engine, it removes the controller out of lock up state.
+ * Due to Hardware errata for IDENTIFY DEVICE command and PACKET
+ * command of ATAPI protocol set, the controller cannot clear the BSY bit
+ * after receiving the PIO setup FIS. This results in the DMA state machine
+ * going into the CMFatalErrorUpdate state and locks up. By restarting the
+ * DMA engine, it removes the controller out of lock up state.
  */
 static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
 {
@@ -137,7 +138,8 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
        struct xgene_ahci_context *ctx = hpriv->plat_data;
        int rc = 0;
 
-       if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA))
+       if (unlikely((ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA) ||
+           (ctx->last_cmd[ap->port_no] == ATA_CMD_PACKET)))
                xgene_ahci_restart_engine(ap);
 
        rc = ahci_qc_issue(qc);