nvme: print available power states

Change-Id: I0e092211e8cd411e199439e4bc250aaa4488e7ae
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9136
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Jérôme Duval
2025-03-19 18:29:50 +00:00
parent 41f477706a
commit 0890cb4057
2 changed files with 52 additions and 3 deletions
@@ -860,7 +860,7 @@ struct nvme_power_state {
/*
* bit 24: max power scale.
*/
uint8_t mps : 1;
uint8_t mxps : 1;
/*
* bit 25: non-operational state.
@@ -902,8 +902,37 @@ struct nvme_power_state {
uint8_t rwl : 5;
uint8_t reserved6 : 3;
uint8_t reserved7[16];
/*
* bits 143:128: idle power.
*/
uint16_t idlp;
uint8_t reserved7 : 6;
/*
* bits 151:150: idle power scale.
*/
uint8_t ips : 2;
uint8_t reserved8;
/*
* bits 175:160: active power.
*/
uint16_t actp;
/*
* bits 178:176: active power workload.
*/
uint8_t apw : 3;
uint8_t reserved9 : 3;
/*
* bits 183:182: active power scale.
*/
uint8_t aps : 2;
uint8_t reserved10[9];
};
nvme_static_assert(sizeof(struct nvme_power_state) == 32, "Incorrect size");
@@ -265,6 +265,26 @@ nvme_disk_init_device(void* _info, void** _cookie)
((microseconds / 100) << 8) | threshold, 0, NULL);
}
if (info->ctrlr->feature_supported[NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION]) {
// dump power states
struct nvme_ctrlr_data cdata;
struct nvme_register_data rdata;
if (nvme_ctrlr_data(info->ctrlr, &cdata, &rdata) == 0
&& cdata.npss > 0 && cdata.npss < 31) {
TRACE_ALWAYS("\tpower states: %u\n", cdata.npss);
for (uint8 i = 0; i <= cdata.npss; i++) {
struct nvme_power_state *psd = &cdata.psd[i];
TRACE_ALWAYS("\tps %u: mp:%fW %soperational enlat:%u exlat:%u rrt:%u rrl:%u\n",
i, psd->mp / (psd->mxps == 0 ? 100.0 : 10000.0),
psd->nops ? "non-" : "", psd->enlat, psd->exlat, psd->rrt, psd->rrl);
TRACE_ALWAYS("\trwt:%u rwl:%u idlp:%fW actp:%fW apw:%u\n", psd->rwt, psd->rwl,
psd->idlp / (psd->ips == 2 ? 100.0 : (psd->ips == 1 ? 10000.0 : 1.0)),
psd->actp / (psd->aps == 2 ? 100.0 : (psd->aps == 1 ? 10000.0 : 1.0)),
psd->apw);
}
}
}
// allocate qpairs
uint32 try_qpairs = cstat.io_qpairs;
try_qpairs = min_c(try_qpairs, NVME_MAX_QPAIRS);
@@ -496,7 +516,7 @@ ior_next_sge(nvme_io_request* request, uint64_t* address, uint32_t* length)
*address = request->iovecs[index].address + request->iovec_offset;
*length = request->iovecs[index].size - request->iovec_offset;
TRACE("IOV %d (+ " B_PRIu32 "): 0x%" B_PRIx64 ", %" B_PRIu32 "\n",
TRACE("IOV %d (+ %" B_PRIu32 "): 0x%" B_PRIx64 ", %" B_PRIu32 "\n",
request->iovec_i, request->iovec_offset, *address, *length);
request->iovec_i++;