Skip to content

Commit 9d75665

Browse files
committed
nvme: mi: Convert AdminIoCqeStatus handling to deku bits
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
1 parent 2807f60 commit 9d75665

3 files changed

Lines changed: 55 additions & 73 deletions

File tree

src/nvme.rs

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55
pub mod mi;
66

7-
use deku::ctx::Endian;
7+
use deku::ctx::{BitSize, Endian, Order};
88
use deku::{DekuError, DekuRead, DekuWrite, deku_derive};
99
use flagset::flags;
1010
use log::debug;
@@ -43,48 +43,72 @@ flags! {
4343
}
4444

4545
// Base v2.1, 4.2.1, Figure 98
46+
//
47+
// Switch to LSB order because the packing of these fields is just messy,
48+
// largely thanks to the position of P. However, the SC / SCT ordering also
49+
// throws ergonomic deku representations straight out the window.
50+
#[derive(Debug, DekuRead, DekuWrite)]
51+
#[deku(bit_order = "lsb", ctx = "endian: Endian", endian = "endian")]
4652
struct AdminIoCqeStatus {
4753
cid: u16,
54+
#[deku(bits = 1)]
4855
p: bool,
49-
status: AdminIoCqeStatusType,
56+
#[deku(bits = 8)]
57+
sc: u8,
58+
#[deku(bits = 3)]
59+
sct: u8,
60+
#[deku(bits = 2)]
5061
crd: CommandRetryDelay,
62+
#[deku(bits = 1)]
5163
m: bool,
64+
#[deku(bits = 1)]
5265
dnr: bool,
5366
}
5467

55-
impl From<AdminIoCqeStatus> for u32 {
56-
fn from(value: AdminIoCqeStatus) -> Self {
57-
let dnr: u32 = value.dnr.into();
58-
let m: u32 = value.m.into();
59-
let crd: u32 = value.crd.id().into();
60-
debug_assert_eq!((crd & !3), 0);
61-
let sct: u32 = value.status.id().into();
62-
debug_assert_eq!((sct & !7), 0);
63-
let sc: u32 = match value.status {
64-
AdminIoCqeStatusType::GenericCommandStatus(s) => s.id(),
65-
AdminIoCqeStatusType::CommandSpecificStatus(v) => v,
68+
impl From<AdminIoCqeStatusType> for AdminIoCqeStatus {
69+
fn from(value: AdminIoCqeStatusType) -> Self {
70+
match value {
71+
AdminIoCqeStatusType::GenericCommandStatus(sts) => AdminIoCqeStatus {
72+
cid: 0,
73+
sc: sts as u8,
74+
p: true,
75+
dnr: sts != AdminIoCqeGenericCommandStatus::SuccessfulCompletion,
76+
m: false,
77+
crd: CommandRetryDelay::None,
78+
sct: value.id(),
79+
},
80+
AdminIoCqeStatusType::CommandSpecificStatus(sts) => AdminIoCqeStatus {
81+
cid: 0,
82+
sc: sts,
83+
p: true,
84+
dnr: true,
85+
m: false,
86+
crd: CommandRetryDelay::None,
87+
sct: value.id(),
88+
},
6689
AdminIoCqeStatusType::MediaAndDataIntegrityErrors => todo!(),
6790
AdminIoCqeStatusType::PathRelatedStatus => todo!(),
6891
AdminIoCqeStatusType::VendorSpecific => todo!(),
6992
}
70-
.into();
71-
debug_assert_eq!((sc & !0xff), 0);
72-
let p: u32 = value.p.into();
73-
let cid: u32 = value.cid.into();
74-
(dnr << 31) | (m << 30) | (crd << 28) | (sct << 25) | (sc << 17) | (p << 16) | cid
7593
}
7694
}
7795

7896
// Base v2.1, 4.2.3, Figure 100, CRD
79-
#[expect(dead_code)]
97+
#[derive(Debug, DekuRead, DekuWrite)]
98+
#[deku(
99+
bits = "bits.0",
100+
bit_order = "order",
101+
ctx = "endian: Endian, bits: BitSize, order: Order",
102+
endian = "endian",
103+
id_type = "u8"
104+
)]
80105
#[repr(u8)]
81106
enum CommandRetryDelay {
82107
None = 0x00,
83108
Time1 = 0x01,
84109
Time2 = 0x02,
85110
Time3 = 0x03,
86111
}
87-
unsafe impl Discriminant<u8> for CommandRetryDelay {}
88112

89113
// Base v2.1, 4.2.3, Figure 101
90114
#[derive(Clone, Copy, Debug, Eq, PartialEq)]

src/nvme/mi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,7 @@ struct AdminCommandResponseHeader {
10091009
#[deku(seek_from_start = "4")]
10101010
cqedw0: u32,
10111011
cqedw1: u32,
1012-
cqedw3: u32,
1012+
cqedw3: super::AdminIoCqeStatus,
10131013
}
10141014
impl Encode<16> for AdminCommandResponseHeader {}
10151015

src/nvme/mi/dev.rs

Lines changed: 10 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::{
2323
AdminIdentifyControllerResponse,
2424
AdminIdentifyNamespaceIdentificationDescriptorListResponse,
2525
AdminIdentifyNvmIdentifyNamespaceResponse, AdminIoCqeGenericCommandStatus,
26-
AdminIoCqeStatus, AdminIoCqeStatusType, AdminSanitizeConfiguration, ControllerListResponse,
26+
AdminIoCqeStatusType, AdminSanitizeConfiguration, ControllerListResponse,
2727
LidSupportedAndEffectsDataStructure, LidSupportedAndEffectsFlags, LogPageAttributes,
2828
NamespaceIdentifierType, SanitizeAction, SanitizeOperationStatus, SanitizeState,
2929
SanitizeStateInformation, SanitizeStatus, SanitizeStatusLogPageResponse,
@@ -971,16 +971,9 @@ where
971971
status: ResponseStatus::Success,
972972
cqedw0: 0,
973973
cqedw1: 0,
974-
cqedw3: AdminIoCqeStatus {
975-
cid: 0,
976-
p: true,
977-
status: AdminIoCqeStatusType::GenericCommandStatus(
978-
AdminIoCqeGenericCommandStatus::SuccessfulCompletion,
979-
),
980-
crd: crate::nvme::CommandRetryDelay::None,
981-
m: false,
982-
dnr: false,
983-
}
974+
cqedw3: AdminIoCqeStatusType::GenericCommandStatus(
975+
AdminIoCqeGenericCommandStatus::SuccessfulCompletion,
976+
)
984977
.into(),
985978
}
986979
.encode()?;
@@ -1003,15 +996,7 @@ where
1003996
status: ResponseStatus::Success,
1004997
cqedw0: 0,
1005998
cqedw1: 0,
1006-
cqedw3: AdminIoCqeStatus {
1007-
cid: 0,
1008-
p: true,
1009-
status,
1010-
crd: crate::nvme::CommandRetryDelay::None,
1011-
m: false,
1012-
dnr: true,
1013-
}
1014-
.into(),
999+
cqedw3: status.into(),
10151000
}
10161001
.encode()?;
10171002

@@ -1745,16 +1730,9 @@ impl RequestHandler for AdminNamespaceManagementRequest {
17451730
status: ResponseStatus::Success,
17461731
cqedw0: nsid.0,
17471732
cqedw1: 0,
1748-
cqedw3: AdminIoCqeStatus {
1749-
cid: 0,
1750-
p: true,
1751-
status: AdminIoCqeStatusType::GenericCommandStatus(
1752-
AdminIoCqeGenericCommandStatus::SuccessfulCompletion,
1753-
),
1754-
crd: crate::nvme::CommandRetryDelay::None,
1755-
m: false,
1756-
dnr: false,
1757-
}
1733+
cqedw3: AdminIoCqeStatusType::GenericCommandStatus(
1734+
AdminIoCqeGenericCommandStatus::SuccessfulCompletion,
1735+
)
17581736
.into(),
17591737
}
17601738
.encode()?;
@@ -1782,15 +1760,7 @@ impl RequestHandler for AdminNamespaceManagementRequest {
17821760
status: ResponseStatus::Success,
17831761
cqedw0: self.nsid, // TODO: Base v2.1, 5.1.21 unclear, test against hardware
17841762
cqedw1: 0,
1785-
cqedw3: AdminIoCqeStatus {
1786-
cid: 0,
1787-
p: true,
1788-
status,
1789-
crd: crate::nvme::CommandRetryDelay::None,
1790-
m: false,
1791-
dnr: res.is_err(),
1792-
}
1793-
.into(),
1763+
cqedw3: status.into(),
17941764
}
17951765
.encode()?;
17961766

@@ -1918,19 +1888,7 @@ impl RequestHandler for AdminNamespaceAttachmentRequest {
19181888
status: ResponseStatus::Success,
19191889
cqedw0: self.nsid,
19201890
cqedw1: 0,
1921-
cqedw3: AdminIoCqeStatus {
1922-
cid: 0,
1923-
p: true,
1924-
status,
1925-
crd: crate::nvme::CommandRetryDelay::None,
1926-
m: false,
1927-
dnr: {
1928-
AdminIoCqeStatusType::GenericCommandStatus(
1929-
AdminIoCqeGenericCommandStatus::SuccessfulCompletion,
1930-
) != status
1931-
},
1932-
}
1933-
.into(),
1891+
cqedw3: status.into(),
19341892
}
19351893
.encode()?;
19361894

0 commit comments

Comments
 (0)