summaryrefslogtreecommitdiffstats
path: root/hw/block
diff options
context:
space:
mode:
Diffstat (limited to 'hw/block')
-rw-r--r--hw/block/nvme.c45
-rw-r--r--hw/block/trace-events5
2 files changed, 26 insertions, 24 deletions
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index cedb4ad9ff..5ce21b7100 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1161,56 +1161,53 @@ static inline NvmeZone *nvme_get_zone_by_slba(NvmeNamespace *ns, uint64_t slba)
static uint16_t nvme_check_zone_state_for_write(NvmeZone *zone)
{
- uint16_t status;
+ uint64_t zslba = zone->d.zslba;
switch (nvme_get_zone_state(zone)) {
case NVME_ZONE_STATE_EMPTY:
case NVME_ZONE_STATE_IMPLICITLY_OPEN:
case NVME_ZONE_STATE_EXPLICITLY_OPEN:
case NVME_ZONE_STATE_CLOSED:
- status = NVME_SUCCESS;
- break;
+ return NVME_SUCCESS;
case NVME_ZONE_STATE_FULL:
- status = NVME_ZONE_FULL;
- break;
+ trace_pci_nvme_err_zone_is_full(zslba);
+ return NVME_ZONE_FULL;
case NVME_ZONE_STATE_OFFLINE:
- status = NVME_ZONE_OFFLINE;
- break;
+ trace_pci_nvme_err_zone_is_offline(zslba);
+ return NVME_ZONE_OFFLINE;
case NVME_ZONE_STATE_READ_ONLY:
- status = NVME_ZONE_READ_ONLY;
- break;
+ trace_pci_nvme_err_zone_is_read_only(zslba);
+ return NVME_ZONE_READ_ONLY;
default:
assert(false);
}
- return status;
+ return NVME_INTERNAL_DEV_ERROR;
}
static uint16_t nvme_check_zone_write(NvmeCtrl *n, NvmeNamespace *ns,
NvmeZone *zone, uint64_t slba,
uint32_t nlb)
{
+ uint64_t zcap = nvme_zone_wr_boundary(zone);
uint16_t status;
- if (unlikely((slba + nlb) > nvme_zone_wr_boundary(zone))) {
- status = NVME_ZONE_BOUNDARY_ERROR;
- } else {
- status = nvme_check_zone_state_for_write(zone);
+ status = nvme_check_zone_state_for_write(zone);
+ if (status) {
+ return status;
}
- if (status) {
- trace_pci_nvme_err_zone_write_not_ok(slba, nlb, status);
- } else {
- assert(nvme_wp_is_valid(zone));
+ if (unlikely(slba != zone->w_ptr)) {
+ trace_pci_nvme_err_write_not_at_wp(slba, zone->d.zslba, zone->w_ptr);
+ return NVME_ZONE_INVALID_WRITE;
+ }
- if (unlikely(slba != zone->w_ptr)) {
- trace_pci_nvme_err_write_not_at_wp(slba, zone->d.zslba,
- zone->w_ptr);
- status = NVME_ZONE_INVALID_WRITE;
- }
+ if (unlikely((slba + nlb) > zcap)) {
+ trace_pci_nvme_err_zone_boundary(slba, nlb, zcap);
+ return NVME_ZONE_BOUNDARY_ERROR;
}
- return status;
+ return NVME_SUCCESS;
}
static uint16_t nvme_check_zone_state_for_read(NvmeZone *zone)
diff --git a/hw/block/trace-events b/hw/block/trace-events
index 87ab6c5090..d32475c398 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -129,6 +129,11 @@ pci_nvme_err_unaligned_zone_cmd(uint8_t action, uint64_t slba, uint64_t zslba) "
pci_nvme_err_invalid_zone_state_transition(uint8_t action, uint64_t slba, uint8_t attrs) "action=0x%"PRIx8", slba=%"PRIu64", attrs=0x%"PRIx32""
pci_nvme_err_write_not_at_wp(uint64_t slba, uint64_t zone, uint64_t wp) "writing at slba=%"PRIu64", zone=%"PRIu64", but wp=%"PRIu64""
pci_nvme_err_append_not_at_start(uint64_t slba, uint64_t zone) "appending at slba=%"PRIu64", but zone=%"PRIu64""
+pci_nvme_err_zone_is_full(uint64_t zslba) "zslba 0x%"PRIx64""
+pci_nvme_err_zone_is_read_only(uint64_t zslba) "zslba 0x%"PRIx64""
+pci_nvme_err_zone_is_offline(uint64_t zslba) "zslba 0x%"PRIx64""
+pci_nvme_err_zone_boundary(uint64_t slba, uint32_t nlb, uint64_t zcap) "lba 0x%"PRIx64" nlb %"PRIu32" zcap 0x%"PRIx64""
+pci_nvme_err_zone_invalid_write(uint64_t slba, uint64_t wp) "lba 0x%"PRIx64" wp 0x%"PRIx64""
pci_nvme_err_zone_write_not_ok(uint64_t slba, uint32_t nlb, uint16_t status) "slba=%"PRIu64", nlb=%"PRIu32", status=0x%"PRIx16""
pci_nvme_err_zone_read_not_ok(uint64_t slba, uint32_t nlb, uint16_t status) "slba=%"PRIu64", nlb=%"PRIu32", status=0x%"PRIx16""
pci_nvme_err_append_too_large(uint64_t slba, uint32_t nlb, uint8_t zasl) "slba=%"PRIu64", nlb=%"PRIu32", zasl=%"PRIu8""