Add disk scheme (mostly finished)
This commit is contained in:
parent
ba83ca3939
commit
67278f9442
|
@ -4,13 +4,18 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
extern crate io;
|
extern crate io;
|
||||||
|
extern crate spin;
|
||||||
extern crate syscall;
|
extern crate syscall;
|
||||||
|
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{Read, Write};
|
||||||
use std::{env, thread, usize};
|
use std::{env, thread, usize};
|
||||||
|
use syscall::{iopl, physmap, physunmap, MAP_WRITE, Packet, Scheme};
|
||||||
|
|
||||||
use syscall::{iopl, physmap, physunmap, MAP_WRITE};
|
use scheme::DiskScheme;
|
||||||
|
|
||||||
pub mod ahci;
|
pub mod ahci;
|
||||||
|
pub mod scheme;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut args = env::args().skip(1);
|
let mut args = env::args().skip(1);
|
||||||
|
@ -29,25 +34,13 @@ fn main() {
|
||||||
|
|
||||||
let address = unsafe { physmap(bar, 4096, MAP_WRITE).expect("ahcid: failed to map address") };
|
let address = unsafe { physmap(bar, 4096, MAP_WRITE).expect("ahcid: failed to map address") };
|
||||||
{
|
{
|
||||||
let mut disks = ahci::disks(address, irq);
|
let mut socket = File::create(":disk").expect("ahcid: failed to create disk scheme");
|
||||||
for mut disk in disks.iter_mut() {
|
let scheme = DiskScheme::new(ahci::disks(address, irq));
|
||||||
let mut sector = [0; 512];
|
|
||||||
println!("Read disk {} size {} MB", disk.id(), disk.size()/1024/1024);
|
|
||||||
match disk.read(0, &mut sector) {
|
|
||||||
Ok(count) => {
|
|
||||||
println!("{}", count);
|
|
||||||
for i in 0..512 {
|
|
||||||
print!("{:X} ", sector[i]);
|
|
||||||
}
|
|
||||||
println!("");
|
|
||||||
},
|
|
||||||
Err(err) => {
|
|
||||||
println!("{}", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loop {
|
loop {
|
||||||
let _ = syscall::sched_yield();
|
let mut packet = Packet::default();
|
||||||
|
socket.read(&mut packet).expect("ahcid: failed to read disk scheme");
|
||||||
|
scheme.handle(&mut packet);
|
||||||
|
socket.write(&mut packet).expect("ahcid: failed to read disk scheme");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe { let _ = physunmap(address); }
|
unsafe { let _ = physunmap(address); }
|
||||||
|
|
85
drivers/ahcid/src/scheme.rs
Normal file
85
drivers/ahcid/src/scheme.rs
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
use std::{cmp, str};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
use spin::Mutex;
|
||||||
|
use syscall::{Error, EBADF, EINVAL, ENOENT, Result, Scheme, SEEK_CUR, SEEK_END, SEEK_SET};
|
||||||
|
|
||||||
|
use ahci::disk::Disk;
|
||||||
|
|
||||||
|
pub struct DiskScheme {
|
||||||
|
disks: Box<[Arc<Mutex<Disk>>]>,
|
||||||
|
handles: Mutex<BTreeMap<usize, (Arc<Mutex<Disk>>, usize)>>,
|
||||||
|
next_id: AtomicUsize
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DiskScheme {
|
||||||
|
pub fn new(disks: Vec<Disk>) -> DiskScheme {
|
||||||
|
let mut disk_arcs = vec![];
|
||||||
|
for disk in disks {
|
||||||
|
disk_arcs.push(Arc::new(Mutex::new(disk)));
|
||||||
|
}
|
||||||
|
|
||||||
|
DiskScheme {
|
||||||
|
disks: disk_arcs.into_boxed_slice(),
|
||||||
|
handles: Mutex::new(BTreeMap::new()),
|
||||||
|
next_id: AtomicUsize::new(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Scheme for DiskScheme {
|
||||||
|
fn open(&self, path: &[u8], _flags: usize) -> Result<usize> {
|
||||||
|
let path_str = str::from_utf8(path).or(Err(Error::new(ENOENT)))?;
|
||||||
|
|
||||||
|
let i = path_str.parse::<usize>().or(Err(Error::new(ENOENT)))?;
|
||||||
|
|
||||||
|
if let Some(disk) = self.disks.get(i) {
|
||||||
|
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
||||||
|
self.handles.lock().insert(id, (disk.clone(), 0));
|
||||||
|
Ok(id)
|
||||||
|
} else {
|
||||||
|
Err(Error::new(ENOENT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||||
|
let mut handles = self.handles.lock();
|
||||||
|
let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||||
|
|
||||||
|
let mut disk = handle.0.lock();
|
||||||
|
let count = disk.read((handle.1 as u64)/512, buf)?;
|
||||||
|
handle.1 += count;
|
||||||
|
Ok(count)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
|
||||||
|
let mut handles = self.handles.lock();
|
||||||
|
let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||||
|
|
||||||
|
let mut disk = handle.0.lock();
|
||||||
|
let count = disk.write((handle.1 as u64)/512, buf)?;
|
||||||
|
handle.1 += count;
|
||||||
|
Ok(count)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn seek(&self, id: usize, pos: usize, whence: usize) -> Result<usize> {
|
||||||
|
let mut handles = self.handles.lock();
|
||||||
|
let mut handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||||
|
|
||||||
|
let len = handle.0.lock().size() as usize;
|
||||||
|
handle.1 = match whence {
|
||||||
|
SEEK_SET => cmp::min(len, pos),
|
||||||
|
SEEK_CUR => cmp::max(0, cmp::min(len as isize, handle.1 as isize + pos as isize)) as usize,
|
||||||
|
SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize,
|
||||||
|
_ => return Err(Error::new(EINVAL))
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(handle.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close(&self, id: usize) -> Result<usize> {
|
||||||
|
let mut handles = self.handles.lock();
|
||||||
|
handles.remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue