changeset 20646:ead1145e9408

DLPX-63519 ATA reads timeout after Azure update Reviewed at: http://reviews.delphix.com/r/48492/
author Pavel Zakharov <pavel.zakharov@delphix.com>
date Thu, 23 May 2019 11:02:49 -0400
parents 8c00cd328527
children 266b66b83681
files usr/src/uts/intel/io/dktp/controller/ata/ata_common.c usr/src/uts/intel/io/dktp/controller/ata/ata_dma.c
diffstat 2 files changed, 35 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c	Mon Nov 04 14:46:57 2019 +0200
+++ b/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c	Thu May 23 11:02:49 2019 -0400
@@ -24,6 +24,7 @@
  * Use is subject to license terms.
  *
  * Copyright 2018 RackTop Systems.
+ * Copyright (c) 2019 by Delphix. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -36,6 +37,7 @@
 #include <sys/uio.h>
 #include <sys/cred.h>
 #include <sys/cpu.h>
+#include <sys/x86_archext.h>
 #include "ata_common.h"
 #include "ata_disk.h"
 #include "atapi.h"
@@ -180,6 +182,11 @@
 static	struct bus_ops	 ata_bus_ops;
 static	struct bus_ops	*scsa_bus_ops_p;
 
+/*
+ * ATA workaround for Azure bug
+ */
+boolean_t ata_azure_workaround = B_FALSE;
+
 /* ARGSUSED */
 static int
 ata_open(dev_t *devp, int flag, int otyp, cred_t *cred_p)
@@ -391,6 +398,13 @@
 		return (err);
 	}
 
+	/*
+	 * See comment in function ata_pciide_dma_start() of ata_dma.c for
+	 * more details.
+	 */
+	if (get_hwenv() & HW_MICROSOFT)
+		ata_azure_workaround = B_TRUE;
+
 	/* save pointer to SCSA provided bus_ops struct */
 	scsa_bus_ops_p = ata_ops.devo_bus_ops;
 
--- a/usr/src/uts/intel/io/dktp/controller/ata/ata_dma.c	Mon Nov 04 14:46:57 2019 +0200
+++ b/usr/src/uts/intel/io/dktp/controller/ata/ata_dma.c	Thu May 23 11:02:49 2019 -0400
@@ -22,6 +22,7 @@
 /*
  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright (c) 2019 by Delphix. All rights reserved.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -96,6 +97,8 @@
 
 size_t	prd_size = sizeof (prde_t) * ATA_DMA_NSEGS;
 
+extern boolean_t ata_azure_workaround;
+
 int
 ata_pciide_alloc(
 	dev_info_t *dip,
@@ -236,8 +239,24 @@
 	 */
 	tmp = ddi_get8(bmhandle, (uchar_t *)bmaddr + PCIIDE_BMICX_REG);
 	tmp &= PCIIDE_BMICX_MASK;
-	ddi_put8(bmhandle, (uchar_t *)bmaddr + PCIIDE_BMICX_REG,
-		(tmp |  direction));
+
+	/*
+	 * After Hyper-V update 14393-10.0-0-0.295, ATA dma stopped
+	 * working. Referring to Section 2.1 (Bus Master IDE Command Register)
+	 * of the IDE specification from http://www.bswd.com/idems100.pdf:
+	 *
+	 * Writing only the direction bit first with bit 0 (start/stop bit)
+	 * set to Zero, results in a side effect of the Bus master DMA
+	 * controller losing all state information, which the new Hyper-V
+	 * update adheres to strictly and hence results in DMA not working.
+	 *
+	 * It is unclear if this fix could negatively impact existing
+	 * hardware, so it is gated under a flag.
+	 */
+	if (!ata_azure_workaround) {
+		ddi_put8(bmhandle, (uchar_t *)bmaddr + PCIIDE_BMICX_REG,
+			(tmp |  direction));
+	}
 
 	ddi_put8(bmhandle, (uchar_t *)bmaddr + PCIIDE_BMICX_REG,
 		(tmp | PCIIDE_BMICX_SSBM_E | direction));