Page MenuHomeFreeBSD

D32688.diff
No OneTemporary

D32688.diff

Index: usr.sbin/bhyve/pci_nvme.c
===================================================================
--- usr.sbin/bhyve/pci_nvme.c
+++ usr.sbin/bhyve/pci_nvme.c
@@ -242,14 +242,37 @@
struct nvme_completion *);
struct nvme_feature_obj {
- uint32_t cdw11;
+ void *data;
nvme_feature_cb set;
nvme_feature_cb get;
bool namespace_specific;
};
+#define NVME_NUM_OF_TEMP_SENSOR 9
+
+struct nvme_feature_temperature_threshold_data {
+ uint16_t temp_thres[NVME_NUM_OF_TEMP_SENSOR][2];
+} temp_thres_data;
+
#define NVME_FID_MAX (NVME_FEAT_ENDURANCE_GROUP_EVENT_CONFIGURATION + 1)
+#define NVME_FEAT_TEMPERATURE_THRESHOLD_THSEL_SHIFT (20)
+#define NVME_FEAT_TEMPERATURE_THRESHOLD_THSEL_MASK (0x3)
+#define NVME_FEAT_TEMPERATURE_THRESHOLD_TMPSEL_SHIFT (16)
+#define NVME_FEAT_TEMPERATURE_THRESHOLD_TMPSEL_MASK (0xF)
+#define NVME_FEAT_TEMPERATURE_THRESHOLD_TMPTH_SHIFT (0)
+#define NVME_FEAT_TEMPERATURE_THRESHOLD_TMPTH_MASK (0xFFFF)
+
+#define NVME_FEAT_TEMPERATURE_THRESHOLD_THSEL(x) \
+ (((x) >> NVME_FEAT_TEMPERATURE_THRESHOLD_THSEL_SHIFT) & \
+ NVME_FEAT_TEMPERATURE_THRESHOLD_THSEL_MASK)
+#define NVME_FEAT_TEMPERATURE_THRESHOLD_TMPSEL(x) \
+ (((x) >> NVME_FEAT_TEMPERATURE_THRESHOLD_TMPSEL_SHIFT) & \
+ NVME_FEAT_TEMPERATURE_THRESHOLD_TMPSEL_MASK)
+#define NVME_FEAT_TEMPERATURE_THRESHOLD_TMPTH(x) \
+ (((x) >> NVME_FEAT_TEMPERATURE_THRESHOLD_TMPTH_SHIFT) & \
+ NVME_FEAT_TEMPERATURE_THRESHOLD_TMPTH_MASK)
+
struct pci_nvme_aer {
STAILQ_ENTRY(pci_nvme_aer) link;
uint16_t cid; /* Command ID of the submitted AER */
@@ -351,6 +374,14 @@
struct nvme_feature_obj *,
struct nvme_command *,
struct nvme_completion *);
+static void nvme_feature_temperature_threshold_set(struct pci_nvme_softc *,
+ struct nvme_feature_obj *,
+ struct nvme_command *,
+ struct nvme_completion *);
+static void nvme_feature_temperature_threshold_get(struct pci_nvme_softc *,
+ struct nvme_feature_obj *,
+ struct nvme_command *,
+ struct nvme_completion *);
static void nvme_feature_num_queues(struct pci_nvme_softc *,
struct nvme_feature_obj *,
struct nvme_command *,
@@ -614,11 +645,25 @@
static void
pci_nvme_init_features(struct pci_nvme_softc *sc)
{
+ uint8_t i;
sc->feat[0].set = nvme_feature_invalid_cb;
sc->feat[0].get = nvme_feature_invalid_cb;
sc->feat[NVME_FEAT_LBA_RANGE_TYPE].namespace_specific = true;
+ sc->feat[NVME_FEAT_TEMPERATURE_THRESHOLD].set =
+ nvme_feature_temperature_threshold_set;
+ sc->feat[NVME_FEAT_TEMPERATURE_THRESHOLD].get =
+ nvme_feature_temperature_threshold_get;
+
+ temp_thres_data.temp_thres[0][0] = sc->ctrldata.wctemp;
+ temp_thres_data.temp_thres[0][1] = sc->ctrldata.wctemp - 100;
+ for (i = 1; i < NVME_NUM_OF_TEMP_SENSOR; i++) {
+ temp_thres_data.temp_thres[i][0] = 0xFFFF;
+ temp_thres_data.temp_thres[i][1] = 0x0;
+ }
+ sc->feat[NVME_FEAT_TEMPERATURE_THRESHOLD].data = &temp_thres_data;
+
sc->feat[NVME_FEAT_ERROR_RECOVERY].namespace_specific = true;
sc->feat[NVME_FEAT_NUMBER_OF_QUEUES].set = nvme_feature_num_queues;
sc->feat[NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION].set =
@@ -1326,6 +1371,77 @@
}
+static void
+nvme_feature_temperature_threshold_set(struct pci_nvme_softc *sc,
+ struct nvme_feature_obj *feat,
+ struct nvme_command *command,
+ struct nvme_completion *compl)
+{
+ uint8_t thsel;
+ uint8_t tmpsel;
+ uint16_t tmpth;
+ uint8_t s, e, i;
+ struct nvme_feature_temperature_threshold_data *data =
+ (struct nvme_feature_temperature_threshold_data *)feat->data;
+
+ DPRINTF("%s: CDW11 0x%x", __func__, command->cdw11);
+
+ thsel = NVME_FEAT_TEMPERATURE_THRESHOLD_THSEL(command->cdw11);
+ tmpsel = NVME_FEAT_TEMPERATURE_THRESHOLD_TMPSEL(command->cdw11);
+ tmpth = NVME_FEAT_TEMPERATURE_THRESHOLD_TMPTH(command->cdw11);
+
+ DPRINTF("%s: THSEL: 0x%x TMPSEL: 0x%x TMPTH 0x%x", __func__, thsel, tmpsel, tmpth);
+
+ if (tmpsel > NVME_NUM_OF_TEMP_SENSOR - 1 &&
+ tmpsel != NVME_FEAT_TEMPERATURE_THRESHOLD_TMPSEL_MASK ) {
+ pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
+ return;
+ };
+
+ if (thsel > 1) {
+ pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
+ return;
+ };
+
+ s = e = tmpsel;
+ if (tmpsel == NVME_FEAT_TEMPERATURE_THRESHOLD_TMPSEL_MASK) {
+ s = 0;
+ e = NVME_NUM_OF_TEMP_SENSOR - 1;
+ }
+
+ for ( i = s; i <= e; i++ )
+ data->temp_thres[i][thsel] = tmpth;
+}
+
+static void
+nvme_feature_temperature_threshold_get(struct pci_nvme_softc *sc,
+ struct nvme_feature_obj *feat,
+ struct nvme_command *command,
+ struct nvme_completion *compl)
+{
+ uint8_t thsel;
+ uint8_t tmpsel;
+ struct nvme_feature_temperature_threshold_data *data =
+ (struct nvme_feature_temperature_threshold_data *)feat->data;
+
+ thsel = NVME_FEAT_TEMPERATURE_THRESHOLD_THSEL(command->cdw11);
+ tmpsel = NVME_FEAT_TEMPERATURE_THRESHOLD_TMPSEL(command->cdw11);
+
+ DPRINTF("%s: THSEL: 0x%x TMPSEL: 0x%x", __func__, thsel, tmpsel);
+
+ if (tmpsel > NVME_NUM_OF_TEMP_SENSOR - 1) {
+ pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
+ return;
+ };
+
+ if (thsel > 1) {
+ pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
+ return;
+ };
+
+ compl->cdw0 = data->temp_thres[tmpsel][thsel];
+}
+
static void
nvme_feature_num_queues(struct pci_nvme_softc *sc,
struct nvme_feature_obj *feat,
@@ -1406,9 +1522,6 @@
if (feat->set)
feat->set(sc, feat, command, compl);
- if (compl->status == NVME_SC_SUCCESS)
- feat->cdw11 = command->cdw11;
-
return (0);
}
@@ -1435,10 +1548,6 @@
feat->get(sc, feat, command, compl);
}
- if (compl->status == NVME_SC_SUCCESS) {
- compl->cdw0 = feat->cdw11;
- }
-
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 1, 2:26 PM (5 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28388842
Default Alt Text
D32688.diff (5 KB)

Event Timeline