nvme-0.2.2 has been yanked.
NVMe
A no-std compatible NVMe driver for embedded and operating system development.
Usage
You need create a allocator that implements the NvmeAllocator trait.
pub struct NvmeAllocator;
impl Allocator for NvmeAllocator {
unsafe fn allocate(&self, size: usize) -> usize {
DmaManager::allocate(size)
}
unsafe fn deallocate(&self, addr: usize) {
DmaManager::deallocate(addr);
}
fn translate(&self, addr: usize) -> usize {
DmaManager::translate_addr(addr)
}
}
Here is a complete example of a full routine that initializes the NVMe controller, identifies namespaces, and performs read/write operations.
pub fn nvme_test() -> Result<(), Box<dyn core::error::Error>> {
let controller = Device::init(virtual_address, Allocator)?;
let _controller_data = controller.controller_data();
let namespaces = controller.identify_namespaces(0)?;
let namespace = &namespaces[0];
let _disk_size = namespace.block_count * namespace.block_size;
let mut qpair = controller.create_io_queue_pair(namespacem, 64)?;
const TEST_LENGTH: usize = 524288;
let layout = Layout::from_size_align(TEST_LENGTH, 4096)?;
let read_buffer_ptr = unsafe { ALLOCATOR.alloc(layout) };
let read_buffer = unsafe { core::slice::from_raw_parts_mut(read_buffer_ptr, TEST_LENGTH) };
qpair.read(read_buffer.as_mut_ptr(), read_buffer.len(), 34)?;
let write_buffer_ptr = unsafe { ALLOCATOR.alloc(layout) };
let write_buffer = unsafe { core::slice::from_raw_parts_mut(write_buffer_ptr, TEST_LENGTH) };
for i in 0..TEST_LENGTH {
write_buffer[i] = (i % 256) as u8;
}
qpair.write(write_buffer.as_ptr(), write_buffer.len(), 34)?;
qpair.read(read_buffer.as_mut_ptr(), read_buffer.len(), 34)?;
for (i, (read, write)) in read_buffer.iter().zip(write_buffer.iter()).enumerate() {
if read != write {
eprintln!("Write test: Mismatch at index {i}: {read} != {write}");
break;
}
}
controller.delete_io_queue_pair(qpair)?;
Ok(())
}