Skip to content

Commit

Permalink
NVMe: Use bitstruct for defining/manipulating controller "registers" …
Browse files Browse the repository at this point in the history
…and other structures. (#45)

Pulled in the [`bitstruct`](https://github.com/dancrossnyc/rust-bitstruct) crate to define the controller register structures. Now instead of one-off fields we've added in an ad-hoc way, we can manipulate the corresponding registers in a way that follows directly from the spec. Makes manipulating the parts we need a lot more clear than twiddling the individual bits. Also fixed a few spots where I got it wrong previously.

As a new example, the last commit also adds a first stab at handling shutdown notifications (aka linux won't hang a bit anymore during shutdown as the driver fruitlessly spun waiting for us to say we finished with shutdown processing).
  • Loading branch information
luqmana committed Sep 7, 2021
1 parent bc0661e commit c77c43a
Show file tree
Hide file tree
Showing 5 changed files with 447 additions and 128 deletions.
1 change: 1 addition & 0 deletions propolis/Cargo.toml
Expand Up @@ -13,6 +13,7 @@ edition = "2018"
# See https://github.com/rust-lang/libc/pull/2383
libc = { git = "https://github.com/rust-lang/libc.git", rev = "796459785" }
bitflags = "1.2"
bitstruct = "0.1"
byteorder = "1"
lazy_static = "1.4"
num_enum = "0.5"
Expand Down
15 changes: 1 addition & 14 deletions propolis/src/hw/nvme/admin.rs
Expand Up @@ -138,25 +138,12 @@ impl NvmeCtrl {
_ => cmds::Completion::generic_err(STS_INVALID_NS),
},
IDENT_CNS_CONTROLLER => {
let ident = bits::IdentifyController {
vid: self.vendor_id,
ssvid: self.vendor_id,
// TODO: fill out serial number
// TODO: move to const somewhere
ieee: [0xA8, 0x40, 0x25], // Oxide OUI
sqes: size_of::<bits::RawSubmission>() as u8,
cqes: size_of::<bits::RawCompletion>() as u8,
nn: self.num_ns(),
// bit 0 indicates volatile write cache is present
vwc: 1,
..Default::default()
};
assert!(size_of::<bits::IdentifyController>() <= PAGE_SIZE);
let buf = cmd
.data(ctx.mctx.memctx())
.next()
.expect("missing prp entry for ident response");
assert!(ctx.mctx.memctx().write(buf.0, &ident));
assert!(ctx.mctx.memctx().write(buf.0, &self.ident));
cmds::Completion::success()
}
// We currently present NVMe version 1.0 in which CNS is a 1-bit field
Expand Down

0 comments on commit c77c43a

Please sign in to comment.