summaryrefslogtreecommitdiff
path: root/drivers/ata/ahci_xgene.c
diff options
context:
space:
mode:
authorSuman Tripathi <stripathi@apm.com>2014-12-29 08:52:47 +0530
committerTejun Heo <tj@kernel.org>2015-01-05 09:02:56 -0500
commit1102407bb714dcebb43f385335bcb72f6b8843bc (patch)
tree660b1ace45df70996de19cfdb7d8abca31fd7c69 /drivers/ata/ahci_xgene.c
parent5c0b8e0de76a86edb99e46612fd9d341b4c4fa0a (diff)
ahci_xgene: Fix the DMA state machine lockup for the ATA_CMD_PACKET PIO mode command.
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>
Diffstat (limited to 'drivers/ata/ahci_xgene.c')
-rw-r--r--drivers/ata/ahci_xgene.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
index f190b92786e4..cbcd20810355 100644
--- a/drivers/ata/ahci_xgene.c
+++ b/drivers/ata/ahci_xgene.c
@@ -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);