summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/common/io/sata/impl/sata.c80
-rw-r--r--usr/src/uts/common/sys/sata/impl/sata.h10
-rw-r--r--usr/src/uts/common/sys/sata/sata_defs.h10
3 files changed, 68 insertions, 32 deletions
diff --git a/usr/src/uts/common/io/sata/impl/sata.c b/usr/src/uts/common/io/sata/impl/sata.c
index 2a34a51795..a448589f1f 100644
--- a/usr/src/uts/common/io/sata/impl/sata.c
+++ b/usr/src/uts/common/io/sata/impl/sata.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -3123,7 +3123,7 @@ sata_scsi_getcap(struct scsi_address *ap, char *cap, int whom)
/* invalid address */
mutex_exit(&(SATA_CPORT_MUTEX(sata_hba_inst,
sata_device.satadev_addr.cport)));
- return (0);
+ return (-1);
}
switch (scsi_hba_lookup_capstr(cap)) {
@@ -3144,26 +3144,19 @@ sata_scsi_getcap(struct scsi_address *ap, char *cap, int whom)
* the way sd operates. Because of this reason we do not
* use it when available.
*/
-#if defined(_UNTAGGED_QING_SUPPORTED)
case SCSI_CAP_UNTAGGED_QING:
- if (SATA_QDEPTH(sata_hba_inst) > 1)
- rval = 1; /* Untagged queuing supported */
+ if (sdinfo->satadrv_features_enabled &
+ SATA_DEV_F_E_UNTAGGED_QING)
+ rval = 1; /* Untagged queuing available */
else
- rval = -1; /* Untagged queuing not supported */
+ rval = -1; /* Untagged queuing not available */
break;
-#endif
case SCSI_CAP_TAGGED_QING:
- /* This can TCQ or NCQ */
- if (sata_func_enable & SATA_ENABLE_QUEUING &&
- ((sdinfo->satadrv_features_support & SATA_DEV_F_TCQ &&
- SATA_FEATURES(sata_hba_inst) & SATA_CTLF_QCMD) ||
- (sata_func_enable & SATA_ENABLE_NCQ &&
- sdinfo->satadrv_features_support & SATA_DEV_F_NCQ &&
- SATA_FEATURES(sata_hba_inst) & SATA_CTLF_NCQ)))
- rval = 1; /* Tagged queuing supported */
+ if (sdinfo->satadrv_features_enabled & SATA_DEV_F_E_TAGGED_QING)
+ rval = 1; /* Tagged queuing available */
else
- rval = -1; /* Tagged queuing not supported */
+ rval = -1; /* Tagged queuing not available */
break;
case SCSI_CAP_DMA_MAX:
@@ -3188,19 +3181,14 @@ sata_scsi_getcap(struct scsi_address *ap, char *cap, int whom)
/*
* Implementation of scsi tran_setcap
- *
- * All supported capabilities are fixed/unchangeable.
- * Returns 0 for all supported capabilities and valid device, -1 otherwise.
*/
static int
sata_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom)
{
-#ifndef __lock_lint
- _NOTE(ARGUNUSED(value))
-#endif
sata_hba_inst_t *sata_hba_inst =
(sata_hba_inst_t *)(ap->a_hba_tran->tran_hba_private);
sata_device_t sata_device;
+ sata_drive_info_t *sdinfo;
int rval;
SATADBG2(SATA_DBG_SCSI_IF, sata_hba_inst,
@@ -3221,11 +3209,12 @@ sata_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom)
}
mutex_enter(&(SATA_CPORT_MUTEX(sata_hba_inst,
sata_device.satadev_addr.cport)));
- if (sata_get_device_info(sata_hba_inst, &sata_device) == NULL) {
+ if ((sdinfo = sata_get_device_info(sata_hba_inst, &sata_device))
+ == NULL) {
/* invalid address */
mutex_exit(&(SATA_CPORT_MUTEX(sata_hba_inst,
sata_device.satadev_addr.cport)));
- return (0);
+ return (-1);
}
mutex_exit(&(SATA_CPORT_MUTEX(sata_hba_inst,
sata_device.satadev_addr.cport)));
@@ -3233,15 +3222,48 @@ sata_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom)
switch (scsi_hba_lookup_capstr(cap)) {
case SCSI_CAP_ARQ:
case SCSI_CAP_SECTOR_SIZE:
- case SCSI_CAP_TAGGED_QING:
case SCSI_CAP_DMA_MAX:
case SCSI_CAP_INTERCONNECT_TYPE:
-#if defined(_UNTAGGED_QING_SUPPORTED)
+ rval = 0;
+ break;
case SCSI_CAP_UNTAGGED_QING:
- rval = 0; /* Capability cannot be changed */
+ if (SATA_QDEPTH(sata_hba_inst) > 1) {
+ rval = 1;
+ if (value == 1) {
+ sdinfo->satadrv_features_enabled |=
+ SATA_DEV_F_E_UNTAGGED_QING;
+ } else if (value == 0) {
+ sdinfo->satadrv_features_enabled &=
+ ~SATA_DEV_F_E_UNTAGGED_QING;
+ } else {
+ rval = -1;
+ }
+ } else {
+ rval = 0;
+ }
+ break;
+ case SCSI_CAP_TAGGED_QING:
+ /* This can TCQ or NCQ */
+ if (sata_func_enable & SATA_ENABLE_QUEUING &&
+ ((sdinfo->satadrv_features_support & SATA_DEV_F_TCQ &&
+ SATA_FEATURES(sata_hba_inst) & SATA_CTLF_QCMD) ||
+ (sata_func_enable & SATA_ENABLE_NCQ &&
+ sdinfo->satadrv_features_support & SATA_DEV_F_NCQ &&
+ SATA_FEATURES(sata_hba_inst) & SATA_CTLF_NCQ))) {
+ rval = 1;
+ if (value == 1) {
+ sdinfo->satadrv_features_enabled |=
+ SATA_DEV_F_E_TAGGED_QING;
+ } else if (value == 0) {
+ sdinfo->satadrv_features_enabled &=
+ ~SATA_DEV_F_E_TAGGED_QING;
+ } else {
+ rval = -1;
+ }
+ } else {
+ rval = 0;
+ }
break;
-#endif
-
default:
rval = -1;
break;
diff --git a/usr/src/uts/common/sys/sata/impl/sata.h b/usr/src/uts/common/sys/sata/impl/sata.h
index 4534e4a466..d7171e700e 100644
--- a/usr/src/uts/common/sys/sata/impl/sata.h
+++ b/usr/src/uts/common/sys/sata/impl/sata.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -210,7 +210,7 @@ struct sata_drive_info {
uint16_t satadrv_features_support; /* drive features support */
uint16_t satadrv_queue_depth; /* drive queue depth */
uint16_t satadrv_settings; /* drive settings flags */
- uint16_t satadrv_pad2; /* struct alignment pad */
+ uint16_t satadrv_features_enabled; /* drive features enabled */
uint64_t satadrv_capacity; /* drive capacity */
sata_id_t satadrv_id; /* Device Identify Data */
struct sata_drive_stats satadrv_stats; /* drive statistics */
@@ -327,6 +327,12 @@ typedef struct sata_pmport_info sata_pmport_info_t;
#define SATA_DEV_F_TCQ 0x40 /* Non NCQ tagged queuing */
/*
+ * Device features enabled (satadrv_features_enabled)
+ */
+#define SATA_DEV_F_E_TAGGED_QING 0x01 /* Tagged queuing enabled */
+#define SATA_DEV_F_E_UNTAGGED_QING 0x02 /* Untagged queuing enabled */
+
+/*
* Drive settings flags (satdrv_settings)
*/
#define SATA_DEV_READ_AHEAD 0x0001 /* Read Ahead enabled */
diff --git a/usr/src/uts/common/sys/sata/sata_defs.h b/usr/src/uts/common/sys/sata/sata_defs.h
index a75ede0858..3f2ca32dd9 100644
--- a/usr/src/uts/common/sys/sata/sata_defs.h
+++ b/usr/src/uts/common/sys/sata/sata_defs.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -357,6 +357,14 @@ typedef struct sata_id {
/* SATA Features Enabled (word 79) - not used */
/*
+ * Generic NCQ related defines
+ */
+
+#define NQ 0x80 /* Not a queued cmd - tag not valid */
+#define NCQ_TAG_MASK 0x1f /* NCQ command tag mask */
+#define FIS_TYPE_REG_H2D 0x27 /* Reg FIS - Host to Device */
+#define FIS_CMD_UPDATE 0x80
+/*
* Status bits from AT_STATUS register
*/
#define SATA_STATUS_BSY 0x80 /* controller busy */