Use redox-log in ahcid

parent abb47603
......@@ -26,7 +26,9 @@ dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"block-io-wrapper 0.1.0",
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"partitionlib 0.1.0 (git+https://gitlab.redox-os.org/redox-os/partitionlib.git)",
"redox-log 0.1.0 (git+https://gitlab.redox-os.org/redox-os/redox-log.git?tag=v0.1.0)",
"redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
]
......
......@@ -6,6 +6,8 @@ edition = "2018"
[dependencies]
bitflags = "1.2"
byteorder = "1.2"
log = "0.4"
partitionlib = { git = "https://gitlab.redox-os.org/redox-os/partitionlib.git" }
redox-log = { git = "https://gitlab.redox-os.org/redox-os/redox-log.git", tag = "v0.1.0" }
redox_syscall = "0.1"
block-io-wrapper = { path = "../block-io-wrapper" }
use log::{error, info, trace};
use std::mem::size_of;
use std::ops::DerefMut;
use std::{ptr, u32};
......@@ -127,7 +128,7 @@ impl HbaPort {
// Power on and spin up device
self.cmd.writef(1 << 2 | 1 << 1, true);
print!("{}", format!(" - AHCI init {:X}\n", self.cmd.read()));
info!(" - AHCI init {:X}", self.cmd.read());
}
pub unsafe fn identify(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma<HbaCmdTable>; 32]) -> Option<u64> {
......@@ -208,8 +209,8 @@ impl HbaPort {
48
};
print!("{}", format!(" + Serial: {} Firmware: {} Model: {} {}-bit LBA Size: {} MB\n",
serial.trim(), firmware.trim(), model.trim(), lba_bits, sectors / 2048));
info!(" + Serial: {} Firmware: {} Model: {} {}-bit LBA Size: {} MB",
serial.trim(), firmware.trim(), model.trim(), lba_bits, sectors / 2048);
Some(sectors * 512)
} else {
......@@ -218,7 +219,7 @@ impl HbaPort {
}
pub fn ata_dma(&mut self, block: u64, sectors: usize, write: bool, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma<HbaCmdTable>; 32], buf: &mut Dma<[u8; 256 * 512]>) -> Option<u32> {
// print!("{}", format!("AHCI {:X} DMA BLOCK: {:X} SECTORS: {} WRITE: {}\n", (self as *mut HbaPort) as usize, block, sectors, write));
trace!("AHCI {:X} DMA BLOCK: {:X} SECTORS: {} WRITE: {}", (self as *mut HbaPort) as usize, block, sectors, write);
assert!(sectors > 0 && sectors < 256);
......@@ -331,10 +332,10 @@ impl HbaPort {
self.stop();
if self.is.read() & HBA_PORT_IS_ERR != 0 {
print!("{}", format!("ERROR IS {:X} IE {:X} CMD {:X} TFD {:X}\nSSTS {:X} SCTL {:X} SERR {:X} SACT {:X}\nCI {:X} SNTF {:X} FBS {:X}\n",
error!("ERROR IS {:X} IE {:X} CMD {:X} TFD {:X}\nSSTS {:X} SCTL {:X} SERR {:X} SACT {:X}\nCI {:X} SNTF {:X} FBS {:X}",
self.is.read(), self.ie.read(), self.cmd.read(), self.tfd.read(),
self.ssts.read(), self.sctl.read(), self.serr.read(), self.sact.read(),
self.ci.read(), self.sntf.read(), self.fbs.read()));
self.ci.read(), self.sntf.read(), self.fbs.read());
self.is.write(u32::MAX);
Err(Error::new(EIO))
} else {
......@@ -371,9 +372,9 @@ impl HbaMem {
*/
self.ghc.write(1 << 31 | 1 << 1);
print!("{}", format!(" - AHCI CAP {:X} GHC {:X} IS {:X} PI {:X} VS {:X} CAP2 {:X} BOHC {:X}",
info!(" - AHCI CAP {:X} GHC {:X} IS {:X} PI {:X} VS {:X} CAP2 {:X} BOHC {:X}",
self.cap.read(), self.ghc.read(), self.is.read(), self.pi.read(),
self.vs.read(), self.cap2.read(), self.bohc.read()));
self.vs.read(), self.cap2.read(), self.bohc.read());
}
}
......
use log::{error, info};
use syscall::io::Io;
use syscall::error::Result;
......@@ -27,14 +28,14 @@ pub fn disks(base: usize, name: &str) -> (&'static mut HbaMem, Vec<Box<dyn Disk>
.filter_map(|i| {
let port = unsafe { &mut *hba_mem.ports.as_mut_ptr().add(i) };
let port_type = port.probe();
print!("{}", format!("{}-{}: {:?}\n", name, i, port_type));
info!("{}-{}: {:?}", name, i, port_type);
let disk: Option<Box<dyn Disk>> = match port_type {
HbaPortType::SATA => {
match DiskATA::new(i, port) {
Ok(disk) => Some(Box::new(disk)),
Err(err) => {
print!("{}", format!("{}: {}\n", i, err));
error!("{}: {}", i, err);
None
}
}
......@@ -43,7 +44,7 @@ pub fn disks(base: usize, name: &str) -> (&'static mut HbaMem, Vec<Box<dyn Disk>
match DiskATAPI::new(i, port) {
Ok(disk) => Some(Box::new(disk)),
Err(err) => {
print!("{}", format!("{}: {}\n", i, err));
error!("{}: {}", i, err);
None
}
}
......
......@@ -3,6 +3,8 @@
extern crate syscall;
extern crate byteorder;
use log::{error, info};
use redox_log::{OutputBuilder, RedoxLogger};
use std::{env, usize};
use std::fs::File;
use std::io::{ErrorKind, Read, Write};
......@@ -14,6 +16,50 @@ use crate::scheme::DiskScheme;
pub mod ahci;
pub mod scheme;
fn setup_logging() -> Option<&'static RedoxLogger> {
let mut logger = RedoxLogger::new()
.with_output(
OutputBuilder::stderr()
.with_filter(log::LevelFilter::Info) // limit global output to important info
.with_ansi_escape_codes()
.flush_on_newline(true)
.build()
);
#[cfg(target_os = "redox")]
match OutputBuilder::in_redox_logging_scheme("disk", "pcie", "ahci.log") {
Ok(b) => logger = logger.with_output(
// TODO: Add a configuration file for this
b.with_filter(log::LevelFilter::Info)
.flush_on_newline(true)
.build()
),
Err(error) => eprintln!("ahcid: failed to create ahci.log: {}", error),
}
#[cfg(target_os = "redox")]
match OutputBuilder::in_redox_logging_scheme("disk", "pcie", "ahci.ansi.log") {
Ok(b) => logger = logger.with_output(
b.with_filter(log::LevelFilter::Info)
.with_ansi_escape_codes()
.flush_on_newline(true)
.build()
),
Err(error) => eprintln!("ahcid: failed to create ahci.ansi.log: {}", error),
}
match logger.enable() {
Ok(logger_ref) => {
eprintln!("ahcid: enabled logger");
Some(logger_ref)
}
Err(error) => {
eprintln!("ahcid: failed to set default logger: {}", error);
None
}
}
}
fn main() {
let mut args = env::args().skip(1);
......@@ -29,120 +75,124 @@ fn main() {
let irq_str = args.next().expect("ahcid: no irq provided");
let irq = irq_str.parse::<u8>().expect("ahcid: failed to parse irq");
print!("{}", format!(" + AHCI {} on: {:X} size: {} IRQ: {}\n", name, bar, bar_size, irq));
// Daemonize
if unsafe { syscall::clone(0).unwrap() } == 0 {
let address = unsafe {
syscall::physmap(bar, bar_size, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)
.expect("ahcid: failed to map address")
};
{
let scheme_name = format!("disk/{}", name);
let socket_fd = syscall::open(
&format!(":{}", scheme_name),
syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK
).expect("ahcid: failed to create disk scheme");
let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) };
let irq_fd = syscall::open(
&format!("irq:{}", irq),
syscall::O_RDWR | syscall::O_NONBLOCK
).expect("ahcid: failed to open irq file");
let mut irq_file = unsafe { File::from_raw_fd(irq_fd as RawFd) };
let mut event_file = File::open("event:").expect("ahcid: failed to open event file");
syscall::setrens(0, 0).expect("ahcid: failed to enter null namespace");
event_file.write(&Event {
id: socket_fd,
flags: EVENT_READ,
data: 0
}).expect("ahcid: failed to event disk scheme");
event_file.write(&Event {
id: irq_fd,
flags: EVENT_READ,
data: 0
}).expect("ahcid: failed to event irq scheme");
let (hba_mem, disks) = ahci::disks(address, &name);
let mut scheme = DiskScheme::new(scheme_name, hba_mem, disks);
let mut mounted = true;
let mut todo = Vec::new();
while mounted {
let mut event = Event::default();
if event_file.read(&mut event).expect("ahcid: failed to read event file") == 0 {
break;
}
if event.id == socket_fd {
loop {
let mut packet = Packet::default();
match socket.read(&mut packet) {
Ok(0) => {
mounted = false;
break;
},
Ok(_) => (),
Err(err) => if err.kind() == ErrorKind::WouldBlock {
break;
} else {
panic!("ahcid: failed to read disk scheme: {}", err);
}
}
if unsafe { syscall::clone(0).unwrap() } != 0 {
return;
}
if let Some(a) = scheme.handle(&packet) {
packet.a = a;
socket.write(&mut packet).expect("ahcid: failed to write disk scheme");
let _logger_ref = setup_logging();
info!(" + AHCI {} on: {:X} size: {} IRQ: {}", name, bar, bar_size, irq);
let address = unsafe {
syscall::physmap(bar, bar_size, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)
.expect("ahcid: failed to map address")
};
{
let scheme_name = format!("disk/{}", name);
let socket_fd = syscall::open(
&format!(":{}", scheme_name),
syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK
).expect("ahcid: failed to create disk scheme");
let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) };
let irq_fd = syscall::open(
&format!("irq:{}", irq),
syscall::O_RDWR | syscall::O_NONBLOCK
).expect("ahcid: failed to open irq file");
let mut irq_file = unsafe { File::from_raw_fd(irq_fd as RawFd) };
let mut event_file = File::open("event:").expect("ahcid: failed to open event file");
syscall::setrens(0, 0).expect("ahcid: failed to enter null namespace");
event_file.write(&Event {
id: socket_fd,
flags: EVENT_READ,
data: 0
}).expect("ahcid: failed to event disk scheme");
event_file.write(&Event {
id: irq_fd,
flags: EVENT_READ,
data: 0
}).expect("ahcid: failed to event irq scheme");
let (hba_mem, disks) = ahci::disks(address, &name);
let mut scheme = DiskScheme::new(scheme_name, hba_mem, disks);
let mut mounted = true;
let mut todo = Vec::new();
while mounted {
let mut event = Event::default();
if event_file.read(&mut event).expect("ahcid: failed to read event file") == 0 {
break;
}
if event.id == socket_fd {
loop {
let mut packet = Packet::default();
match socket.read(&mut packet) {
Ok(0) => {
mounted = false;
break;
},
Ok(_) => (),
Err(err) => if err.kind() == ErrorKind::WouldBlock {
break;
} else {
todo.push(packet);
panic!("ahcid: failed to read disk scheme: {}", err);
}
}
} else if event.id == irq_fd {
let mut irq = [0; 8];
if irq_file.read(&mut irq).expect("ahcid: failed to read irq file") >= irq.len() {
if scheme.irq() {
irq_file.write(&irq).expect("ahcid: failed to write irq file");
// Handle todos in order to finish previous packets if possible
let mut i = 0;
while i < todo.len() {
if let Some(a) = scheme.handle(&todo[i]) {
let mut packet = todo.remove(i);
packet.a = a;
socket.write(&mut packet).expect("ahcid: failed to write disk scheme");
} else {
i += 1;
}
if let Some(a) = scheme.handle(&packet) {
packet.a = a;
socket.write(&mut packet).expect("ahcid: failed to write disk scheme");
} else {
todo.push(packet);
}
}
} else if event.id == irq_fd {
let mut irq = [0; 8];
if irq_file.read(&mut irq).expect("ahcid: failed to read irq file") >= irq.len() {
if scheme.irq() {
irq_file.write(&irq).expect("ahcid: failed to write irq file");
// Handle todos in order to finish previous packets if possible
let mut i = 0;
while i < todo.len() {
if let Some(a) = scheme.handle(&todo[i]) {
let mut packet = todo.remove(i);
packet.a = a;
socket.write(&mut packet).expect("ahcid: failed to write disk scheme");
} else {
i += 1;
}
}
}
} else {
println!("Unknown event {}", event.id);
}
} else {
error!("Unknown event {}", event.id);
}
// Handle todos to start new packets if possible
let mut i = 0;
while i < todo.len() {
if let Some(a) = scheme.handle(&todo[i]) {
let mut packet = todo.remove(i);
packet.a = a;
socket.write(&packet).expect("ahcid: failed to write disk scheme");
} else {
i += 1;
}
// Handle todos to start new packets if possible
let mut i = 0;
while i < todo.len() {
if let Some(a) = scheme.handle(&todo[i]) {
let mut packet = todo.remove(i);
packet.a = a;
socket.write(&packet).expect("ahcid: failed to write disk scheme");
} else {
i += 1;
}
}
if ! mounted {
for mut packet in todo.drain(..) {
packet.a = Error::mux(Err(Error::new(ENODEV)));
socket.write(&packet).expect("ahcid: failed to write disk scheme");
}
if ! mounted {
for mut packet in todo.drain(..) {
packet.a = Error::mux(Err(Error::new(ENODEV)));
socket.write(&packet).expect("ahcid: failed to write disk scheme");
}
}
}
unsafe { let _ = syscall::physunmap(address); }
}
unsafe { let _ = syscall::physunmap(address); }
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment