diff usr/src/uts/common/io/sata/impl/sata.c @ 11351:3f9ad5952518

6908813 ahci timeouts experienced on Toshiba M10's with TEAC DV-W28S-RT DVD drives
author ying tian - Beijing China <Ying.Tian@Sun.COM>
date Fri, 18 Dec 2009 13:04:52 +0800
parents 5e56af24ae09
children 1f1cf000a9eb
line wrap: on
line diff
--- a/usr/src/uts/common/io/sata/impl/sata.c	Fri Dec 18 11:22:10 2009 +0800
+++ b/usr/src/uts/common/io/sata/impl/sata.c	Fri Dec 18 13:04:52 2009 +0800
@@ -13062,7 +13062,7 @@
 	sata_pkt_t *spkt;
 	sata_cmd_t *scmd;
 	sata_pkt_txlate_t *spx;
-	int mode;
+	int i, mode;
 	uint8_t subcmd;
 	int rval = SATA_SUCCESS;
 
@@ -13088,14 +13088,26 @@
 #endif
 
 		/*
-		 * We're still going to set DMA mode whatever is selected
-		 * by default
+		 * For disk, we're still going to set DMA mode whatever is
+		 * selected by default
 		 *
 		 * We saw an old maxtor sata drive will select Ultra DMA and
 		 * Multi-Word DMA simultaneouly by default, which is going
 		 * to cause DMA command timed out, so we need to select DMA
 		 * mode even when it's already done by default
 		 */
+		if (sdinfo->satadrv_type != SATA_DTYPE_ATADISK) {
+
+			/* Find UDMA mode currently selected */
+			for (i = 6; i >= 0; --i) {
+				if (sdinfo->satadrv_id.ai_ultradma &
+				    (1 << (i + 8)))
+					break;
+			}
+			if (i >= mode)
+				/* Nothing to do */
+				return (SATA_SUCCESS);
+		}
 
 		subcmd = SATAC_TRANSFER_MODE_ULTRA_DMA;
 
@@ -13107,14 +13119,26 @@
 		}
 
 		/*
-		 * We're still going to set DMA mode whatever is selected
-		 * by default
+		 * For disk, We're still going to set DMA mode whatever is
+		 * selected by default
 		 *
 		 * We saw an old maxtor sata drive will select Ultra DMA and
 		 * Multi-Word DMA simultaneouly by default, which is going
 		 * to cause DMA command timed out, so we need to select DMA
 		 * mode even when it's already done by default
 		 */
+		if (sdinfo->satadrv_type != SATA_DTYPE_ATADISK) {
+
+			/* Find highest MultiWord DMA mode selected */
+			for (i = 2; i >= 0; --i) {
+				if (sdinfo->satadrv_id.ai_dworddma &
+				    (1 << (i + 8)))
+					break;
+			}
+			if (i >= mode)
+				/* Nothing to do */
+				return (SATA_SUCCESS);
+		}
 
 		subcmd = SATAC_TRANSFER_MODE_MULTI_WORD_DMA;
 	} else