From 89b39d19886ae62cce0e40f8c74fe86924afaab4 Mon Sep 17 00:00:00 2001 From: Pavel Zakharov Date: Thu, 23 May 2019 11:02:49 -0400 Subject: [PATCH] DLPX-63519 ATA reads timeout after Azure update Reviewed at: http://reviews.delphix.com/r/48492/ --- .../uts/intel/io/dktp/controller/ata/ata_common.c | 14 +++++++++++++ usr/src/uts/intel/io/dktp/controller/ata/ata_dma.c | 23 ++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c b/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c index dcd0cbf8d3..d432609f6f 100644 --- a/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c +++ b/usr/src/uts/intel/io/dktp/controller/ata/ata_common.c @@ -24,6 +24,7 @@ * Use is subject to license terms. * * Copyright 2018 RackTop Systems. + * Copyright (c) 2019 by Delphix. All rights reserved. */ #include @@ -36,6 +37,7 @@ #include #include #include +#include #include "ata_common.h" #include "ata_disk.h" #include "atapi.h" @@ -180,6 +182,11 @@ char *ata_dev_DMA_sel_msg; 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 @@ _init(void) 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; diff --git a/usr/src/uts/intel/io/dktp/controller/ata/ata_dma.c b/usr/src/uts/intel/io/dktp/controller/ata/ata_dma.c index 5b7ed19407..6261b5ac1a 100644 --- a/usr/src/uts/intel/io/dktp/controller/ata/ata_dma.c +++ b/usr/src/uts/intel/io/dktp/controller/ata/ata_dma.c @@ -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 @@ ddi_dma_attr_t ata_prd_dma_attr = { 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 @@ ata_pciide_dma_start( */ 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)); -- 2.11.4.GIT