changeset 14067:a847fb624ac7

3815 AHCI: Support for Marvell 88SE9128 Reviewed by: Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Reviewed by: Garrett D'Amore <garrett@damore.org>
author Marcel Telka <Marcel.Telka@nexenta.com>
date Mon, 24 Jun 2013 09:23:02 +0200
parents dac943a98583
children 2547a41b1162
files usr/src/uts/common/io/sata/adapters/ahci/ahci.c usr/src/uts/common/io/sata/impl/sata.c usr/src/uts/common/sys/sata/impl/sata.h usr/src/uts/common/sys/sata/sata_defs.h usr/src/uts/common/sys/sata/sata_hba.h
diffstat 5 files changed, 58 insertions(+), 73 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/sata/adapters/ahci/ahci.c	Fri Jun 21 16:28:00 2013 +0000
+++ b/usr/src/uts/common/io/sata/adapters/ahci/ahci.c	Mon Jun 24 09:23:02 2013 +0200
@@ -5192,8 +5192,8 @@
 {
 	ahci_addr_t pmult_addr;
 	uint32_t port_cmd_status;
-	uint32_t port_scontrol, port_sstatus, port_serror;
-	uint32_t port_intr_status, port_task_file;
+	uint32_t port_scontrol, port_sstatus;
+	uint32_t port_task_file;
 	uint32_t port_state;
 	uint8_t port = addrp->aa_port;
 
@@ -5237,6 +5237,10 @@
 	    port_cmd_status|AHCI_CMD_STATUS_FRE);
 
 	/*
+	 * The port enters P:StartComm state, and the HBA tells the link layer
+	 * to start communication, which involves sending COMRESET to the
+	 * device. And the HBA resets PxTFD.STS to 7Fh.
+	 *
 	 * Give time for COMRESET to percolate, according to the AHCI
 	 * spec, software shall wait at least 1 millisecond before
 	 * clearing PxSCTL.DET
@@ -5252,10 +5256,6 @@
 	    port_scontrol);
 
 	/*
-	 * The port enters P:StartComm state, and HBA tells link layer to
-	 * start communication, which involves sending COMRESET to device.
-	 * And the HBA resets PxTFD.STS to 7Fh.
-	 *
 	 * When a COMINIT is received from the device, then the port enters
 	 * P:ComInit state. And HBA sets PxTFD.STS to FFh or 80h. HBA sets
 	 * PxSSTS.DET to 1h to indicate a device is detected but communication
@@ -5267,7 +5267,7 @@
 	 * that the interface is in active state.
 	 */
 	loop_count = 0;
-	do {
+	for (;;) {
 		port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
 		    (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
 
@@ -5280,6 +5280,9 @@
 			SSTATUS_SET_DET(port_sstatus, SSTATUS_DET_NODEV);
 		}
 
+		if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM)
+			break;
+
 		if (loop_count++ > AHCI_POLLRATE_PORT_SSTATUS) {
 			/*
 			 * We are effectively timing out after 0.1 sec.
@@ -5289,15 +5292,14 @@
 
 		/* Wait for 10 millisec */
 		drv_usecwait(AHCI_10MS_USECS);
-	} while (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM);
+	}
 
 	AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
 	    "ahci_port_reset: 1st loop count: %d, "
 	    "port_sstatus = 0x%x port %d",
 	    loop_count, port_sstatus, port);
 
-	if ((SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) ||
-	    (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM)) {
+	if (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM) {
 		/*
 		 * Either the port is not active or there
 		 * is no device present.
@@ -5306,60 +5308,25 @@
 		return (AHCI_SUCCESS);
 	}
 
-	/* Now we can make sure there is a device connected to the port */
-	port_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
-	    (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port));
-	port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
-	    (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
-
-	/*
-	 * A COMINIT signal is supposed to be received
-	 * PxSERR.DIAG.X or PxIS.PCS should be set
-	 */
-	if (!(port_intr_status & AHCI_INTR_STATUS_PCS) &&
-	    !(port_serror & SERROR_EXCHANGED_ERR)) {
-		cmn_err(CE_WARN, "!ahci%d: ahci_port_reset port %d "
-		    "COMINIT signal from the device not received",
-		    instance, port);
-		AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_PSTATE_FAILED);
-		return (AHCI_FAILURE);
-	}
-
-	/*
-	 * According to the spec, when PxSCTL.DET is set to 0h, upon
-	 * receiving a COMINIT from the attached device, PxTFD.STS.BSY
-	 * shall be set to '1' by the HBA.
-	 *
-	 * However, we found JMicron JMB363 doesn't follow this, so
-	 * remove this check, and just print a debug message.
-	 */
-#if AHCI_DEBUG
-	port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
-	    (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
-	if (!(port_task_file & AHCI_TFD_STS_BSY)) {
-		AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_port_reset: "
-		    "port %d BSY bit is not set after COMINIT signal "
-		    "is received", port);
-	}
-#endif
-
-	/*
-	 * PxSERR.DIAG.X has to be cleared in order to update PxTFD with
-	 * the D2H FIS received by HBA.
-	 */
+	/* Clear port serror register for the port */
 	ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
 	    (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
-	    SERROR_EXCHANGED_ERR);
+	    AHCI_SERROR_CLEAR_ALL);
 
 	/*
 	 * Devices should return a FIS contains its signature to HBA after
-	 * COMINIT signal. Check whether a D2H FIS is received by polling
-	 * PxTFD.STS.ERR bit.
+	 * COMINIT signal. Check whether a D2H Register FIS is received by
+	 * polling PxTFD.STS.
 	 */
 	loop_count = 0;
-	do {
-		/* Wait for 10 millisec */
-		drv_usecwait(AHCI_10MS_USECS);
+	for (;;) {
+		port_task_file =
+		    ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
+		    (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
+
+		if ((port_task_file & (AHCI_TFD_STS_BSY | AHCI_TFD_STS_DRQ |
+		    AHCI_TFD_STS_ERR)) == 0)
+			break;
 
 		if (loop_count++ > AHCI_POLLRATE_PORT_TFD_ERROR) {
 			/*
@@ -5371,7 +5338,8 @@
 			    instance, port);
 
 			AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_port_reset: "
-			    "port %d PxTFD.STS.ERR is not set, we need another "
+			    "port %d: some or all of BSY, DRQ and ERR in "
+			    "PxTFD.STS are not clear. We need another "
 			    "software reset.", port);
 
 			/* Clear port serror register for the port */
@@ -5393,19 +5361,7 @@
 
 		/* Wait for 10 millisec */
 		drv_usecwait(AHCI_10MS_USECS);
-
-		/*
-		 * The Error bit '1' means COMRESET is finished successfully
-		 * The device hardware has been initialized and the power-up
-		 * diagnostics successfully completed. The device requests
-		 * that the Transport layer transmit a Register - D2H FIS to
-		 * the host. (SATA spec 11.5, v2.6)
-		 */
-		port_task_file =
-		    ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
-		    (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
-	} while (((port_task_file & AHCI_TFD_ERR_MASK)
-	    >> AHCI_TFD_ERR_SHIFT) != AHCI_TFD_ERR_SGS);
+	}
 
 	AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
 	    "ahci_port_reset: 2nd loop count: %d, "
--- a/usr/src/uts/common/io/sata/impl/sata.c	Fri Jun 21 16:28:00 2013 +0000
+++ b/usr/src/uts/common/io/sata/impl/sata.c	Mon Jun 24 09:23:02 2013 +0200
@@ -23,7 +23,7 @@
  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
@@ -12603,6 +12603,9 @@
 		case SATA_ATAPI_DIRACC_DEV:
 			sdinfo->satadrv_type = SATA_DTYPE_ATAPIDISK;
 			break;
+		case SATA_ATAPI_PROC_DEV:
+			sdinfo->satadrv_type = SATA_DTYPE_ATAPIPROC;
+			break;
 		default:
 			sdinfo->satadrv_type = SATA_DTYPE_UNKNOWN;
 		}
@@ -12706,6 +12709,10 @@
 		(void) sprintf(msg_buf, "SATA disk (ATAPI) device at");
 		break;
 
+	case SATA_DTYPE_ATAPIPROC:
+		(void) sprintf(msg_buf, "SATA processor (ATAPI) device at");
+		break;
+
 	case SATA_DTYPE_UNKNOWN:
 		(void) sprintf(msg_buf,
 		    "Unsupported SATA device type (cfg 0x%x) at ",
@@ -15991,6 +15998,11 @@
 		}
 		break;
 	}
+	case SATA_DTYPE_ATAPIPROC:
+		ap_state->ap_rstate = AP_RSTATE_CONNECTED;
+		ap_state->ap_ostate = AP_OSTATE_UNCONFIGURED;
+		ap_state->ap_condition = AP_COND_OK;
+		break;
 	default:
 		ap_state->ap_rstate = AP_RSTATE_CONNECTED;
 		ap_state->ap_ostate = AP_OSTATE_UNCONFIGURED;
@@ -16093,6 +16105,10 @@
 		ap_type = "tape";
 		break;
 
+	case SATA_DTYPE_ATAPIPROC:
+		ap_type = "processor";
+		break;
+
 	case SATA_DTYPE_PMULT:
 		ap_type = "sata-pmult";
 		break;
--- a/usr/src/uts/common/sys/sata/impl/sata.h	Fri Jun 21 16:28:00 2013 +0000
+++ b/usr/src/uts/common/sys/sata/impl/sata.h	Mon Jun 24 09:23:02 2013 +0200
@@ -23,6 +23,9 @@
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ */
 
 #ifndef _SATA_H
 #define	_SATA_H
@@ -157,6 +160,7 @@
 						 * SATA_DTYPE_ATAPIDISK
 						 * SATA_DTYPE_PMULT
 						 * SATA_DTYPE_UNKNOWN
+						 * SATA_DTYPE_ATAPIPROC
 						 */
 	uint32_t		cport_dev_type;
 	union {
@@ -212,6 +216,7 @@
 						 * SATA_DTYPE_ATAPICD
 						 * SATA_DTYPE_ATAPITAPE
 						 * SATA_DTYPE_ATAPIDISK
+						 * SATA_DTYPE_ATAPIPROC
 						 */
 	uint32_t	satadrv_type;
 
@@ -304,6 +309,7 @@
 						 * SATA_DTYPE_ATAPITAPE
 						 * SATA_DTYPE_ATAPIDISK
 						 * SATA_DTYPE_UNKNOWN
+						 * SATA_DTYPE_ATAPIPROC
 						 */
 	uint32_t	pmport_dev_type;
 
--- a/usr/src/uts/common/sys/sata/sata_defs.h	Fri Jun 21 16:28:00 2013 +0000
+++ b/usr/src/uts/common/sys/sata/sata_defs.h	Mon Jun 24 09:23:02 2013 +0200
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef _SATA_DEFS_H
@@ -367,10 +368,11 @@
 #define	SATA_ATAPI_ID_DRQ_TYPE	0x0060	/* DRQ asserted in 3ms after pkt */
 #define	SATA_ATAPI_ID_DRQ_INTR	0x0020  /* Obsolete in ATA/ATAPI 7 */
 
-#define	SATA_ATAPI_ID_DEV_TYPE	0x0f00	/* device type/command set mask */
+#define	SATA_ATAPI_ID_DEV_TYPE	0x1f00	/* device type/command set mask */
 #define	SATA_ATAPI_ID_DEV_SHFT	8
 #define	SATA_ATAPI_DIRACC_DEV	0x0000	/* Direct Access device */
 #define	SATA_ATAPI_SQACC_DEV	0x0100  /* Sequential access dev (tape ?) */
+#define	SATA_ATAPI_PROC_DEV	0x0300	/* Processor device */
 #define	SATA_ATAPI_CDROM_DEV	0x0500  /* CD_ROM device */
 
 /*
--- a/usr/src/uts/common/sys/sata/sata_hba.h	Fri Jun 21 16:28:00 2013 +0000
+++ b/usr/src/uts/common/sys/sata/sata_hba.h	Mon Jun 24 09:23:02 2013 +0200
@@ -23,6 +23,9 @@
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ */
 
 #ifndef _SATA_HBA_H
 #define	_SATA_HBA_H
@@ -224,6 +227,8 @@
 	(SATA_DTYPE_ATAPI|0x08)			/* ATAPI disk */
 #define	SATA_DTYPE_PMULT		0x10	/* Port Multiplier */
 #define	SATA_DTYPE_UNKNOWN		0x20	/* Device attached, unkown */
+#define	SATA_DTYPE_ATAPIPROC	\
+	(SATA_DTYPE_ATAPI|0x80)			/* ATAPI processor */
 
 
 /*