Move command into its own file.
This commit is contained in:
parent
4efeca661e
commit
e34540b77e
|
@ -0,0 +1,112 @@
|
||||||
|
use core::{
|
||||||
|
future::Future,
|
||||||
|
ops::Deref,
|
||||||
|
ops::DerefMut,
|
||||||
|
pin::Pin,
|
||||||
|
task::{Context, Poll, Waker},
|
||||||
|
};
|
||||||
|
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
use mammoth::{cap::Capability, sync::Mutex, syscall, zion::ZError};
|
||||||
|
|
||||||
|
use super::ahci_command::{HostToDeviceRegisterFis, SataCommand};
|
||||||
|
|
||||||
|
pub enum CommandStatus {
|
||||||
|
Empty,
|
||||||
|
NotSent,
|
||||||
|
Pending(Waker),
|
||||||
|
Complete,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CommandFuture {
|
||||||
|
status: Arc<Mutex<CommandStatus>>,
|
||||||
|
trigger: Box<dyn Fn() + Sync + Send>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommandFuture {
|
||||||
|
pub fn new(status: Arc<Mutex<CommandStatus>>, trigger: Box<dyn Fn() + Sync + Send>) -> Self {
|
||||||
|
Self { status, trigger }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for CommandFuture {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
*self.status.lock() = CommandStatus::Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Future for CommandFuture {
|
||||||
|
type Output = ();
|
||||||
|
|
||||||
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
let s = self.deref_mut();
|
||||||
|
let mut status = s.status.lock();
|
||||||
|
match status.deref() {
|
||||||
|
CommandStatus::NotSent => {
|
||||||
|
*status = CommandStatus::Pending(cx.waker().clone());
|
||||||
|
(s.trigger)();
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
CommandStatus::Pending(_) => Poll::Pending,
|
||||||
|
CommandStatus::Complete => Poll::Ready(()),
|
||||||
|
CommandStatus::Empty => panic!("Polling empty command slot"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Command {
|
||||||
|
pub command: SataCommand,
|
||||||
|
pub lba: u64,
|
||||||
|
pub sector_cnt: u16,
|
||||||
|
pub paddr: u64,
|
||||||
|
|
||||||
|
memory_region: Option<Capability>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command {
|
||||||
|
pub fn identify() -> Result<Self, ZError> {
|
||||||
|
let (memory_region, paddr) = syscall::memory_object_contiguous_physical(512)?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
command: SataCommand::IdentifyDevice,
|
||||||
|
lba: 0,
|
||||||
|
sector_cnt: 1,
|
||||||
|
paddr,
|
||||||
|
memory_region: Some(memory_region),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(lba: u64, lba_count: u16) -> Result<Self, ZError> {
|
||||||
|
let (memory_region, paddr) =
|
||||||
|
syscall::memory_object_contiguous_physical(512 * (lba_count as u64))?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
command: SataCommand::DmaReadExt,
|
||||||
|
lba,
|
||||||
|
sector_cnt: lba_count,
|
||||||
|
paddr,
|
||||||
|
memory_region: Some(memory_region),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_manual(lba: u64, lba_count: u16, paddr: u64) -> Self {
|
||||||
|
Self {
|
||||||
|
command: SataCommand::DmaReadExt,
|
||||||
|
lba,
|
||||||
|
sector_cnt: lba_count,
|
||||||
|
paddr: paddr,
|
||||||
|
memory_region: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release_mem_cap(&mut self) -> u64 {
|
||||||
|
self.memory_region.take().unwrap().release()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Command> for HostToDeviceRegisterFis {
|
||||||
|
fn from(val: &Command) -> Self {
|
||||||
|
HostToDeviceRegisterFis::new_command(val.command, val.lba, val.sector_cnt)
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ use mammoth::{
|
||||||
|
|
||||||
use crate::ahci::{
|
use crate::ahci::{
|
||||||
port::{AhciDeviceDetection, AhciInterfacePowerManagement},
|
port::{AhciDeviceDetection, AhciInterfacePowerManagement},
|
||||||
port_controller::Command,
|
Command,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{hba::AhciHba, port::AhciPortHba, port_controller::PortController};
|
use super::{hba::AhciHba, port::AhciPortHba, port_controller::PortController};
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
mod ahci_command;
|
mod ahci_command;
|
||||||
|
mod command;
|
||||||
mod controller;
|
mod controller;
|
||||||
mod hba;
|
mod hba;
|
||||||
mod port;
|
mod port;
|
||||||
mod port_controller;
|
mod port_controller;
|
||||||
|
|
||||||
|
pub use command::Command;
|
||||||
pub use controller::identify_ports;
|
pub use controller::identify_ports;
|
||||||
pub use controller::spawn_irq_thread;
|
pub use controller::spawn_irq_thread;
|
||||||
pub use controller::AhciController;
|
pub use controller::AhciController;
|
||||||
pub use port_controller::Command;
|
|
||||||
|
|
|
@ -1,124 +1,18 @@
|
||||||
use core::{
|
use core::array;
|
||||||
array,
|
use core::ops::Deref;
|
||||||
future::Future,
|
|
||||||
ops::Deref,
|
|
||||||
ops::DerefMut,
|
|
||||||
pin::Pin,
|
|
||||||
task::{Context, Poll, Waker},
|
|
||||||
};
|
|
||||||
|
|
||||||
use alloc::boxed::Box;
|
use alloc::{boxed::Box, sync::Arc};
|
||||||
use alloc::sync::Arc;
|
use mammoth::{mem, sync::Mutex, zion::ZError};
|
||||||
use mammoth::{cap::Capability, mem, sync::Mutex, syscall, zion::ZError};
|
|
||||||
|
|
||||||
use crate::ahci::port::AhciPortInterruptStatus;
|
use crate::ahci::port::AhciPortInterruptStatus;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ahci_command::{
|
ahci_command::{CommandList, CommandTable, FisType, HostToDeviceRegisterFis, ReceivedFis},
|
||||||
CommandList, CommandTable, FisType, HostToDeviceRegisterFis, ReceivedFis, SataCommand,
|
command::{CommandFuture, CommandStatus},
|
||||||
},
|
|
||||||
port::AhciPortHba,
|
port::AhciPortHba,
|
||||||
|
Command,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CommandStatus {
|
|
||||||
Empty,
|
|
||||||
NotSent,
|
|
||||||
Pending(Waker),
|
|
||||||
Complete,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CommandFuture {
|
|
||||||
status: Arc<Mutex<CommandStatus>>,
|
|
||||||
trigger: Box<dyn Fn() + Sync + Send>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CommandFuture {
|
|
||||||
fn new(status: Arc<Mutex<CommandStatus>>, trigger: Box<dyn Fn() + Sync + Send>) -> Self {
|
|
||||||
Self { status, trigger }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for CommandFuture {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
*self.status.lock() = CommandStatus::Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Future for CommandFuture {
|
|
||||||
type Output = ();
|
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
||||||
let s = self.deref_mut();
|
|
||||||
let mut status = s.status.lock();
|
|
||||||
match status.deref() {
|
|
||||||
CommandStatus::NotSent => {
|
|
||||||
*status = CommandStatus::Pending(cx.waker().clone());
|
|
||||||
(s.trigger)();
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
CommandStatus::Pending(_) => Poll::Pending,
|
|
||||||
CommandStatus::Complete => Poll::Ready(()),
|
|
||||||
CommandStatus::Empty => panic!("Polling empty command slot"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Command {
|
|
||||||
command: SataCommand,
|
|
||||||
lba: u64,
|
|
||||||
sector_cnt: u16,
|
|
||||||
paddr: u64,
|
|
||||||
|
|
||||||
memory_region: Option<Capability>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Command {
|
|
||||||
pub fn identify() -> Result<Self, ZError> {
|
|
||||||
let (memory_region, paddr) = syscall::memory_object_contiguous_physical(512)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
command: SataCommand::IdentifyDevice,
|
|
||||||
lba: 0,
|
|
||||||
sector_cnt: 1,
|
|
||||||
paddr,
|
|
||||||
memory_region: Some(memory_region),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read(lba: u64, lba_count: u16) -> Result<Self, ZError> {
|
|
||||||
let (memory_region, paddr) =
|
|
||||||
syscall::memory_object_contiguous_physical(512 * (lba_count as u64))?;
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
command: SataCommand::DmaReadExt,
|
|
||||||
lba,
|
|
||||||
sector_cnt: lba_count,
|
|
||||||
paddr,
|
|
||||||
memory_region: Some(memory_region),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_manual(lba: u64, lba_count: u16, paddr: u64) -> Self {
|
|
||||||
Self {
|
|
||||||
command: SataCommand::DmaReadExt,
|
|
||||||
lba,
|
|
||||||
sector_cnt: lba_count,
|
|
||||||
paddr: paddr,
|
|
||||||
memory_region: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn release_mem_cap(&mut self) -> u64 {
|
|
||||||
self.memory_region.take().unwrap().release()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&Command> for HostToDeviceRegisterFis {
|
|
||||||
fn from(val: &Command) -> Self {
|
|
||||||
HostToDeviceRegisterFis::new_command(val.command, val.lba, val.sector_cnt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CommandStructures {
|
struct CommandStructures {
|
||||||
command_list: &'static mut CommandList,
|
command_list: &'static mut CommandList,
|
||||||
received_fis: &'static mut ReceivedFis,
|
received_fis: &'static mut ReceivedFis,
|
||||||
|
|
Loading…
Reference in New Issue