diff options
author | Marcel Telka <Marcel.Telka@nexenta.com> | 2013-06-24 09:23:02 +0200 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2013-06-24 15:12:05 -0700 |
commit | 257c04ecb24858f6d68020a41589306f554ea434 (patch) | |
tree | 987141cab380039f86ca4213d1e8e1800fa40a2c | |
parent | 9384cec630155c229c70dfb8a445c6ccf433045a (diff) | |
download | illumos-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.c | 98 | ||||
-rw-r--r-- | usr/src/uts/common/io/sata/impl/sata.c | 18 | ||||
-rw-r--r-- | usr/src/uts/common/sys/sata/impl/sata.h | 6 | ||||
-rw-r--r-- | usr/src/uts/common/sys/sata/sata_defs.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/sys/sata/sata_hba.h | 5 |
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 */ /* |