Skip to content

Commit 5d7fe5d

Browse files
committed
nvme: Convert Sanitize structures to deku bits, FlagSet
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
1 parent 964c327 commit 5d7fe5d

4 files changed

Lines changed: 69 additions & 100 deletions

File tree

src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,8 @@ pub struct Subsystem {
638638
nsids: u32,
639639
nss: heapless::Vec<Namespace, MAX_NAMESPACES>,
640640
health: SubsystemHealth,
641-
sanicap: nvme::SanitizeCapabilities,
641+
sanicap: FlagSet<nvme::SanitizeCapabilityFlags>,
642+
nodmmas: nvme::NoDeallocateModifiesMediaAfterSanitize,
642643
ssi: nvme::SanitizeStateInformation,
643644
sstat: nvme::SanitizeStatus,
644645
sconf: Option<nvme::AdminSanitizeConfiguration>,
@@ -665,7 +666,11 @@ impl Subsystem {
665666
sstat: Default::default(),
666667
sconf: None,
667668
ssi: Default::default(),
668-
sanicap: Default::default(),
669+
sanicap: nvme::SanitizeCapabilityFlags::Ces
670+
| nvme::SanitizeCapabilityFlags::Bes
671+
| nvme::SanitizeCapabilityFlags::Ows
672+
| nvme::SanitizeCapabilityFlags::Ndi,
673+
nodmmas: Default::default(),
669674
}
670675
}
671676

src/nvme.rs

Lines changed: 45 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ pub struct SanitizeStateInformation {
378378
struct SanitizeStatusLogPageResponse {
379379
sprog: u16,
380380
sstat: SanitizeStatus,
381-
scdw10: u32,
381+
scdw10: AdminSanitizeConfiguration,
382382
eto: u32,
383383
etbe: u32,
384384
etce: u32,
@@ -555,7 +555,14 @@ flags! {
555555
}
556556

557557
// Base v2.1, 5.1.13.2.1, Figure 312, SANICAP, NODMMAS
558-
#[derive(Clone, Copy, Debug, Default)]
558+
#[derive(Clone, Copy, Debug, Default, DekuRead, DekuWrite)]
559+
#[deku(
560+
bits = "bits.0",
561+
bit_order = "order",
562+
ctx = "endian: Endian, bits: BitSize, order: Order",
563+
endian = "endian",
564+
id_type = "u8"
565+
)]
559566
#[repr(u8)]
560567
pub enum NoDeallocateModifiesMediaAfterSanitize {
561568
Undefined = 0b00,
@@ -564,41 +571,26 @@ pub enum NoDeallocateModifiesMediaAfterSanitize {
564571
Modified = 0b10,
565572
Reserved = 0b11,
566573
}
567-
unsafe impl Discriminant<u8> for NoDeallocateModifiesMediaAfterSanitize {}
568574

569575
// Base v2.1, 5.1.13.2.1, Figure 312, SANICAP
570-
#[derive(Clone, Copy, Debug)]
571-
pub struct SanitizeCapabilities {
572-
ces: bool,
573-
bes: bool,
574-
ows: bool,
575-
vers: bool,
576-
ndi: bool,
577-
nodmmas: NoDeallocateModifiesMediaAfterSanitize,
578-
}
579-
580-
impl From<SanitizeCapabilities> for u32 {
581-
fn from(value: SanitizeCapabilities) -> Self {
582-
(((value.nodmmas.id() & 0b11) as u32) << 30)
583-
| ((value.ndi as u32) << 29)
584-
| ((value.vers as u32) << 3)
585-
| ((value.ows as u32) << 2)
586-
| ((value.bes as u32) << 1)
587-
| (value.ces as u32)
576+
flags! {
577+
pub enum SanitizeCapabilityFlags: u32 {
578+
Ces = 1 << 0,
579+
Bes = 1 << 1,
580+
Ows = 1 << 2,
581+
Vers = 1 << 3,
582+
Ndi = 1 << 29,
588583
}
589584
}
590585

591-
impl Default for SanitizeCapabilities {
592-
fn default() -> Self {
593-
Self {
594-
ces: true,
595-
bes: true,
596-
ows: true,
597-
vers: false,
598-
ndi: true,
599-
nodmmas: NoDeallocateModifiesMediaAfterSanitize::Unmodified,
600-
}
601-
}
586+
// Base v2.1, 5.1.13.2.1, Figure 312, SANICAP
587+
#[derive(Clone, Copy, Debug, DekuRead, DekuWrite)]
588+
#[deku(bit_order = "lsb", ctx = "endian: Endian", endian = "endian")]
589+
pub struct SanitizeCapabilities {
590+
#[deku(bits = 30)]
591+
caps: WireFlagSet<SanitizeCapabilityFlags>,
592+
#[deku(bits = 2)]
593+
nodmmas: NoDeallocateModifiesMediaAfterSanitize,
602594
}
603595

604596
// Base v2.1, 5.1.13.2.1, Figure 312, FNA
@@ -651,7 +643,7 @@ struct AdminIdentifyControllerResponse {
651643
fwug: u8,
652644
kas: u16,
653645
#[deku(seek_from_current = "6")]
654-
sanicap: u32,
646+
sanicap: SanitizeCapabilities,
655647
#[deku(seek_from_current = "54")]
656648
cqt: u16,
657649
#[deku(seek_from_current = "124")]
@@ -800,17 +792,23 @@ struct NvmNamespaceManagementCreate {
800792
}
801793

802794
// Base v2.1, 5.1.22, Figure 372, SANACT
803-
#[derive(Clone, Copy, Debug)]
795+
#[derive(Clone, Copy, Debug, Default, DekuRead, DekuWrite, Eq, PartialEq)]
796+
#[deku(
797+
bits = "bits.0",
798+
ctx = "endian: Endian, bits: BitSize",
799+
endian = "endian",
800+
id_type = "u8"
801+
)]
804802
#[repr(u8)]
805803
enum SanitizeAction {
804+
#[default]
806805
Reserved = 0x00,
807806
ExitFailureMode = 0x01,
808807
StartBlockErase = 0x02,
809808
StartOverwrite = 0x03,
810809
StartCryptoErase = 0x04,
811810
ExitMediaVerificationState = 0x05,
812811
}
813-
unsafe impl Discriminant<u8> for SanitizeAction {}
814812

815813
impl TryFrom<u32> for SanitizeAction {
816814
type Error = ();
@@ -829,40 +827,21 @@ impl TryFrom<u32> for SanitizeAction {
829827
}
830828

831829
// Base v2.1, 5.1.22, Figure 372
832-
#[derive(Clone, Copy, Debug)]
830+
#[derive(Clone, Copy, Debug, Default, DekuRead, DekuWrite, Eq, PartialEq)]
831+
#[deku(ctx = "endian: Endian", endian = "endian")]
833832
pub struct AdminSanitizeConfiguration {
834-
sanact: SanitizeAction,
835-
ause: bool,
833+
#[deku(bits = "4")]
836834
owpass: u8,
837-
oipbp: bool,
838-
ndas: bool,
835+
#[deku(bits = "1")]
836+
ause: bool,
837+
#[deku(bits = "3")]
838+
sanact: SanitizeAction,
839+
#[deku(bits = "1", pad_bits_before = "5")]
839840
emvs: bool,
840-
}
841-
842-
impl TryFrom<u32> for AdminSanitizeConfiguration {
843-
type Error = ();
844-
845-
fn try_from(value: u32) -> Result<Self, Self::Error> {
846-
Ok(Self {
847-
sanact: TryInto::try_into(value & 0x7)?,
848-
ause: ((value >> 3) & 1) == 1,
849-
owpass: ((value >> 4) & 0xf) as u8,
850-
oipbp: ((value >> 8) & 1) == 1,
851-
ndas: ((value >> 9) & 1) == 1,
852-
emvs: ((value >> 10) & 1) == 1,
853-
})
854-
}
855-
}
856-
857-
impl From<AdminSanitizeConfiguration> for u32 {
858-
fn from(value: AdminSanitizeConfiguration) -> Self {
859-
((value.emvs as u32) << 10)
860-
| ((value.ndas as u32) << 9)
861-
| ((value.oipbp as u32) << 8)
862-
| (((value.owpass & 0xf) as u32) << 4)
863-
| ((value.ause as u32) << 3)
864-
| value.sanact.id() as u32
865-
}
841+
#[deku(bits = "1")]
842+
ndas: bool,
843+
#[deku(bits = "1", pad_bytes_after = "2")]
844+
oipbp: bool,
866845
}
867846

868847
// Base v2.1, 5.1.25, Figure 385

src/nvme/mi.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use log::debug;
1010

1111
use crate::nvme::{
1212
AdminFormatNvmConfiguration, AdminNamespaceAttachmentSelect, AdminNamespaceManagementSelect,
13-
ControllerListRequest,
13+
AdminSanitizeConfiguration, ControllerListRequest,
1414
};
1515
use crate::wire::{WireFlagSet, WireVec};
1616
use crate::{CommandEffectError, Discriminant, Encode, MAX_CONTROLLERS};
@@ -997,7 +997,7 @@ struct AdminSanitizeRequest {
997997
dofst: u32,
998998
dlen: u32,
999999
#[deku(seek_from_current = "8")]
1000-
config: u32,
1000+
config: AdminSanitizeConfiguration,
10011001
#[deku(pad_bytes_after = "16")]
10021002
ovrpat: u32,
10031003
}

src/nvme/mi/dev.rs

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use mctp::{AsyncRespChannel, MsgIC};
1111
use crate::nvme::mi::{NvmSubsystemStatusFlags, PortCapabilityFlags};
1212
use crate::nvme::{
1313
ControllerAttributeFlags, ControllerMultipathIoNamespaceSharingCapabilityFlags,
14-
ManagementEndpointCapabilityFlags, NvmSubsystemReportFlags,
14+
ManagementEndpointCapabilityFlags, NvmSubsystemReportFlags, SanitizeCapabilityFlags,
1515
};
1616
use crate::{
1717
CommandEffect, CommandEffectError, Controller, ControllerError, ControllerType, Discriminant,
@@ -22,11 +22,10 @@ use crate::{
2222
AdminIdentifyCnsRequestType, AdminIdentifyControllerResponse,
2323
AdminIdentifyNamespaceIdentificationDescriptorListResponse,
2424
AdminIdentifyNvmIdentifyNamespaceResponse, AdminIoCqeGenericCommandStatus,
25-
AdminIoCqeStatusType, AdminSanitizeConfiguration, ControllerListResponse,
26-
LidSupportedAndEffectsDataStructure, LidSupportedAndEffectsFlags, LogPageAttributes,
27-
NamespaceIdentifierType, SanitizeAction, SanitizeOperationStatus, SanitizeState,
28-
SanitizeStateInformation, SanitizeStatus, SanitizeStatusLogPageResponse,
29-
SmartHealthInformationLogPageResponse,
25+
AdminIoCqeStatusType, ControllerListResponse, LidSupportedAndEffectsDataStructure,
26+
LidSupportedAndEffectsFlags, LogPageAttributes, NamespaceIdentifierType, SanitizeAction,
27+
SanitizeOperationStatus, SanitizeState, SanitizeStateInformation, SanitizeStatus,
28+
SanitizeStatusLogPageResponse, SmartHealthInformationLogPageResponse,
3029
mi::{
3130
AdminCommandRequestHeader, AdminCommandResponseHeader, AdminFormatNvmRequest,
3231
AdminNamespaceAttachmentRequest, AdminNamespaceManagementRequest, AdminSanitizeRequest,
@@ -1277,13 +1276,7 @@ impl RequestHandler for AdminGetLogPageRequest {
12771276
let sslpr = SanitizeStatusLogPageResponse {
12781277
sprog: u16::MAX,
12791278
sstat: subsys.sstat,
1280-
scdw10: {
1281-
if let Some(sconf) = subsys.sconf {
1282-
sconf.into()
1283-
} else {
1284-
0
1285-
}
1286-
},
1279+
scdw10: subsys.sconf.unwrap_or_default(),
12871280
eto: u32::MAX,
12881281
etbe: u32::MAX,
12891282
etce: u32::MAX,
@@ -1464,7 +1457,10 @@ impl RequestHandler for AdminIdentifyRequest {
14641457
msdbd: 0,
14651458
ofcs: 0,
14661459
apsta: 0,
1467-
sanicap: subsys.sanicap.into(),
1460+
sanicap: crate::nvme::SanitizeCapabilities {
1461+
caps: subsys.sanicap.into(),
1462+
nodmmas: subsys.nodmmas,
1463+
},
14681464
}
14691465
.encode()
14701466
.map_err(AdminIoCqeGenericCommandStatus::from)
@@ -1918,18 +1914,7 @@ impl RequestHandler for AdminSanitizeRequest {
19181914
return Err(ResponseStatus::InvalidCommandSize);
19191915
}
19201916

1921-
let Ok(config) = TryInto::<AdminSanitizeConfiguration>::try_into(self.config) else {
1922-
debug!("Invalid sanitize configuration: {}", self.config);
1923-
return admin_send_status(
1924-
resp,
1925-
AdminIoCqeStatusType::GenericCommandStatus(
1926-
AdminIoCqeGenericCommandStatus::InvalidFieldInCommand,
1927-
),
1928-
)
1929-
.await;
1930-
};
1931-
1932-
if subsys.sanicap.ndi && config.ndas {
1917+
if subsys.sanicap.contains(SanitizeCapabilityFlags::Ndi) && self.config.ndas {
19331918
debug!("Request for No-Deallocate After Sanitize when No-Deallocate is inhibited");
19341919
return admin_send_status(
19351920
resp,
@@ -1941,7 +1926,7 @@ impl RequestHandler for AdminSanitizeRequest {
19411926
}
19421927

19431928
// TODO: Implement action latency, progress state machine, error states
1944-
match config.sanact {
1929+
match self.config.sanact {
19451930
SanitizeAction::Reserved => Err(ResponseStatus::InvalidParameter),
19461931
SanitizeAction::ExitFailureMode | SanitizeAction::ExitMediaVerificationState => {
19471932
if subsys.ssi.sans != SanitizeState::Idle {
@@ -1960,7 +1945,7 @@ impl RequestHandler for AdminSanitizeRequest {
19601945
mvcncled: false,
19611946
gde: true,
19621947
};
1963-
subsys.sconf = Some(self.config.try_into()?);
1948+
subsys.sconf = Some(self.config);
19641949

19651950
admin_send_response_body(resp, &[]).await
19661951
}
@@ -1970,12 +1955,12 @@ impl RequestHandler for AdminSanitizeRequest {
19701955
fails: 0,
19711956
};
19721957
subsys.sstat = SanitizeStatus {
1973-
opc: config.owpass,
1958+
opc: self.config.owpass,
19741959
sos: SanitizeOperationStatus::Sanitized,
19751960
mvcncled: false,
19761961
gde: true,
19771962
};
1978-
subsys.sconf = Some(self.config.try_into()?);
1963+
subsys.sconf = Some(self.config);
19791964

19801965
admin_send_response_body(resp, &[]).await
19811966
}

0 commit comments

Comments
 (0)