Do not throw pcid into background - this prevents ethernetd from exiting if it tries to open network: too early

This commit is contained in:
Jeremy Soller 2016-10-22 19:00:36 -06:00
parent 790c32b0bc
commit df2327b175

View file

@ -8,7 +8,6 @@ use std::env;
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::process::Command; use std::process::Command;
use std::thread;
use syscall::iopl; use syscall::iopl;
use config::Config; use config::Config;
@ -18,131 +17,129 @@ mod config;
mod pci; mod pci;
fn main() { fn main() {
thread::spawn(|| { let mut config = Config::default();
let mut config = Config::default();
let mut args = env::args().skip(1); let mut args = env::args().skip(1);
if let Some(config_path) = args.next() { if let Some(config_path) = args.next() {
if let Ok(mut config_file) = File::open(&config_path) { if let Ok(mut config_file) = File::open(&config_path) {
let mut config_data = String::new(); let mut config_data = String::new();
if let Ok(_) = config_file.read_to_string(&mut config_data) { if let Ok(_) = config_file.read_to_string(&mut config_data) {
config = toml::decode_str(&config_data).unwrap_or(Config::default()); config = toml::decode_str(&config_data).unwrap_or(Config::default());
}
} }
} }
}
unsafe { iopl(3).unwrap() }; unsafe { iopl(3).unwrap() };
println!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV"); println!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV");
let pci = Pci::new(); let pci = Pci::new();
for bus in pci.buses() { for bus in pci.buses() {
for dev in bus.devs() { for dev in bus.devs() {
for func in dev.funcs() { for func in dev.funcs() {
if let Some(header) = func.header() { if let Some(header) = func.header() {
print!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X}", print!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X}",
bus.num, dev.num, func.num, bus.num, dev.num, func.num,
header.vendor_id, header.device_id, header.vendor_id, header.device_id,
header.class, header.subclass, header.interface, header.revision); header.class, header.subclass, header.interface, header.revision);
let pci_class = PciClass::from(header.class); let pci_class = PciClass::from(header.class);
print!(" {:?}", pci_class); print!(" {:?}", pci_class);
match pci_class { match pci_class {
PciClass::Storage => match header.subclass { PciClass::Storage => match header.subclass {
0x01 => { 0x01 => {
print!(" IDE"); print!(" IDE");
},
0x06 => {
print!(" SATA");
},
_ => ()
}, },
PciClass::SerialBus => match header.subclass { 0x06 => {
0x03 => match header.interface { print!(" SATA");
0x00 => { },
print!(" UHCI"); _ => ()
}, },
0x10 => { PciClass::SerialBus => match header.subclass {
print!(" OHCI"); 0x03 => match header.interface {
}, 0x00 => {
0x20 => { print!(" UHCI");
print!(" EHCI"); },
}, 0x10 => {
0x30 => { print!(" OHCI");
print!(" XHCI"); },
}, 0x20 => {
_ => () print!(" EHCI");
},
0x30 => {
print!(" XHCI");
}, },
_ => () _ => ()
}, },
_ => () _ => ()
},
_ => ()
}
for i in 0..header.bars.len() {
match PciBar::from(header.bars[i]) {
PciBar::None => (),
PciBar::Memory(address) => print!(" {}={:>08X}", i, address),
PciBar::Port(address) => print!(" {}={:>04X}", i, address)
}
}
print!("\n");
for driver in config.drivers.iter() {
if let Some(class) = driver.class {
if class != header.class { continue; }
} }
for i in 0..header.bars.len() { if let Some(subclass) = driver.subclass {
match PciBar::from(header.bars[i]) { if subclass != header.subclass { continue; }
PciBar::None => (),
PciBar::Memory(address) => print!(" {}={:>08X}", i, address),
PciBar::Port(address) => print!(" {}={:>04X}", i, address)
}
} }
print!("\n"); if let Some(vendor) = driver.vendor {
if vendor != header.vendor_id { continue; }
}
for driver in config.drivers.iter() { if let Some(device) = driver.device {
if let Some(class) = driver.class { if device != header.device_id { continue; }
if class != header.class { continue; } }
if let Some(ref args) = driver.command {
// Enable bus mastering
unsafe {
let cmd = pci.read(bus.num, dev.num, func.num, 0x04);
pci.write(bus.num, dev.num, func.num, 0x04, cmd | 4);
} }
if let Some(subclass) = driver.subclass { let mut args = args.iter();
if subclass != header.subclass { continue; } if let Some(program) = args.next() {
} let mut command = Command::new(program);
for arg in args {
if let Some(vendor) = driver.vendor { let bar_arg = |i| -> String {
if vendor != header.vendor_id { continue; } match PciBar::from(header.bars[i]) {
} PciBar::None => String::new(),
PciBar::Memory(address) => format!("{:>08X}", address),
if let Some(device) = driver.device { PciBar::Port(address) => format!("{:>04X}", address)
if device != header.device_id { continue; } }
} };
let arg = match arg.as_str() {
if let Some(ref args) = driver.command { "$BAR0" => bar_arg(0),
// Enable bus mastering "$BAR1" => bar_arg(1),
unsafe { "$BAR2" => bar_arg(2),
let cmd = pci.read(bus.num, dev.num, func.num, 0x04); "$BAR3" => bar_arg(3),
pci.write(bus.num, dev.num, func.num, 0x04, cmd | 4); "$BAR4" => bar_arg(4),
"$BAR5" => bar_arg(5),
"$IRQ" => format!("{}", header.interrupt_line),
_ => arg.clone()
};
command.arg(&arg);
} }
let mut args = args.iter(); match command.spawn() {
if let Some(program) = args.next() { Ok(mut child) => match child.wait() {
let mut command = Command::new(program); Ok(_status) => (), //println!("pcid: waited for {}: {:?}", line, status.code()),
for arg in args { Err(err) => println!("pcid: failed to wait for {:?}: {}", command, err)
let bar_arg = |i| -> String { },
match PciBar::from(header.bars[i]) { Err(err) => println!("pcid: failed to execute {:?}: {}", command, err)
PciBar::None => String::new(),
PciBar::Memory(address) => format!("{:>08X}", address),
PciBar::Port(address) => format!("{:>04X}", address)
}
};
let arg = match arg.as_str() {
"$BAR0" => bar_arg(0),
"$BAR1" => bar_arg(1),
"$BAR2" => bar_arg(2),
"$BAR3" => bar_arg(3),
"$BAR4" => bar_arg(4),
"$BAR5" => bar_arg(5),
"$IRQ" => format!("{}", header.interrupt_line),
_ => arg.clone()
};
command.arg(&arg);
}
match command.spawn() {
Ok(mut child) => match child.wait() {
Ok(_status) => (), //println!("pcid: waited for {}: {:?}", line, status.code()),
Err(err) => println!("pcid: failed to wait for {:?}: {}", command, err)
},
Err(err) => println!("pcid: failed to execute {:?}: {}", command, err)
}
} }
} }
} }
@ -150,5 +147,5 @@ fn main() {
} }
} }
} }
}); }
} }