summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Telka <Marcel.Telka@nexenta.com>2013-06-24 09:23:02 +0200
committerRobert Mustacchi <rm@joyent.com>2013-06-24 15:12:05 -0700
commit257c04ecb24858f6d68020a41589306f554ea434 (patch)
tree987141cab380039f86ca4213d1e8e1800fa40a2c
parent9384cec630155c229c70dfb8a445c6ccf433045a (diff)
downloadillumos-joyent-257c04ecb24858f6d68020a41589306f554ea434.tar.gz
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>
-rw-r--r--usr/src/uts/common/io/sata/adapters/ahci/ahci.c98
-rw-r--r--usr/src/uts/common/io/sata/impl/sata.c18
-rw-r--r--usr/src/uts/common/sys/sata/impl/sata.h6
-rw-r--r--usr/src/uts/common/sys/sata/sata_defs.h4
-rw-r--r--usr/src/uts/common/sys/sata/sata_hba.h5
5 files changed, 58 insertions, 73 deletions
diff --git a/usr/src/uts/common/io/sata/adapters/ahci/ahci.c b/usr/src/uts/common/io/sata/adapters/ahci/ahci.c
index bea112d166..0ca0ff0144 100644
--- a/usr/src/uts/common/io/sata/adapters/ahci/ahci.c
+++ b/usr/src/uts/common/io/sata/adapters/ahci/ahci.c
@@ -5192,8 +5192,8 @@ ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
{
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 @@ ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
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 @@ ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
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 @@ ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
* 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 @@ ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
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 @@ ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
/* 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 @@ ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
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 @@ ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
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 @@ ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
/* 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, "
diff --git a/usr/src/uts/common/io/sata/impl/sata.c b/usr/src/uts/common/io/sata/impl/sata.c
index 90ff93a284..2bab576495 100644
--- a/usr/src/uts/common/io/sata/impl/sata.c
+++ b/usr/src/uts/common/io/sata/impl/sata.c
@@ -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 @@ sata_identify_device(sata_hba_inst_t *sata_hba_inst,
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 @@ sata_show_drive_info(sata_hba_inst_t *sata_hba_inst,
(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 @@ sata_cfgadm_state(sata_hba_inst_t *sata_hba_inst, int32_t port,
}
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 @@ sata_ioctl_get_ap_type(sata_hba_inst_t *sata_hba_inst,
ap_type = "tape";
break;
+ case SATA_DTYPE_ATAPIPROC:
+ ap_type = "processor";
+ break;
+
case SATA_DTYPE_PMULT:
ap_type = "sata-pmult";
break;
diff --git a/usr/src/uts/common/sys/sata/impl/sata.h b/usr/src/uts/common/sys/sata/impl/sata.h
index 39999011d9..5d03a0e696 100644
--- a/usr/src/uts/common/sys/sata/impl/sata.h
+++ b/usr/src/uts/common/sys/sata/impl/sata.h
@@ -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 @@ struct sata_cport_info {
* SATA_DTYPE_ATAPIDISK
* SATA_DTYPE_PMULT
* SATA_DTYPE_UNKNOWN
+ * SATA_DTYPE_ATAPIPROC
*/
uint32_t cport_dev_type;
union {
@@ -212,6 +216,7 @@ struct sata_drive_info {
* SATA_DTYPE_ATAPICD
* SATA_DTYPE_ATAPITAPE
* SATA_DTYPE_ATAPIDISK
+ * SATA_DTYPE_ATAPIPROC
*/
uint32_t satadrv_type;
@@ -304,6 +309,7 @@ struct sata_pmport_info {
* SATA_DTYPE_ATAPITAPE
* SATA_DTYPE_ATAPIDISK
* SATA_DTYPE_UNKNOWN
+ * SATA_DTYPE_ATAPIPROC
*/
uint32_t pmport_dev_type;
diff --git a/usr/src/uts/common/sys/sata/sata_defs.h b/usr/src/uts/common/sys/sata/sata_defs.h
index 47ad6edb41..9e803b9a23 100644
--- a/usr/src/uts/common/sys/sata/sata_defs.h
+++ b/usr/src/uts/common/sys/sata/sata_defs.h
@@ -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 @@ typedef struct sata_id {
#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 */
/*
diff --git a/usr/src/uts/common/sys/sata/sata_hba.h b/usr/src/uts/common/sys/sata/sata_hba.h
index 02a5e61f14..e1427bf6e9 100644
--- a/usr/src/uts/common/sys/sata/sata_hba.h
+++ b/usr/src/uts/common/sys/sata/sata_hba.h
@@ -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 @@ _NOTE(SCHEME_PROTECTS_DATA("unshared data", sata_device))
(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 */
/*