1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-26 09:53:28 +04:00

Detach driver from the device in sys_map_pci_driver

This commit is contained in:
Jiajie Chen 2019-03-20 13:00:19 +08:00
parent 960ef2e1f8
commit a0d9a8b2de
9 changed files with 77 additions and 21 deletions

View File

@ -1,4 +1,5 @@
use alloc::sync::Arc;
use alloc::string::String;
use core::cmp::min;
use core::mem::{size_of};
use core::slice;
@ -107,6 +108,10 @@ impl Driver for VirtIOBlkDriver {
fn device_type(&self) -> DeviceType {
DeviceType::Block
}
fn get_id(&self) -> String {
format!("virtio_block")
}
}
impl BlockDevice for VirtIOBlkDriver {

View File

@ -3,8 +3,8 @@ use crate::drivers::{Driver, DRIVERS, NET_DRIVERS};
use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::sync::Arc;
use spin::Mutex;
use core::cmp::Ordering;
use spin::Mutex;
use x86_64::instructions::port::Port;
const PCI_VENDOR: u32 = 0x00;
@ -44,7 +44,6 @@ const PCI_BASE_ADDRESS_MEM_MASK: u32 = 0xfffffff0;
#[derive(Copy, Clone)]
pub struct PciTag(u32);
impl Ord for PciTag {
fn cmp(&self, other: &PciTag) -> Ordering {
self.0.cmp(&other.0)
@ -57,8 +56,7 @@ impl PartialOrd for PciTag {
}
}
impl Eq for PciTag {
}
impl Eq for PciTag {}
impl PartialEq for PciTag {
fn eq(&self, other: &PciTag) -> bool {
@ -296,23 +294,22 @@ pub fn init_driver(name: String, vid: u32, did: u32, tag: PciTag) {
// 82599ES 10-Gigabit SFI/SFP+ Network Connection
if let Some((addr, len)) = unsafe { tag.get_bar_mem(0) } {
let irq = unsafe { tag.enable() };
PCI_DRIVERS.lock()
PCI_DRIVERS
.lock()
.insert(tag, ixgbe::ixgbe_init(name, irq, addr, len));
}
}
}
}
pub fn detach_driver(bus: u32, dev: u32, func: u32) -> bool {
match PCI_DRIVERS.lock().remove(&PciTag::new(bus, dev, func)) {
pub fn detach_driver(tag: &PciTag) -> bool {
match PCI_DRIVERS.lock().remove(tag) {
Some(driver) => {
DRIVERS.write().retain(|dri| !Arc::ptr_eq(&driver, dri));
NET_DRIVERS.write().retain(|dri| !Arc::ptr_eq(&driver, dri));
DRIVERS.write().retain(|dri| dri.get_id() != driver.get_id());
NET_DRIVERS.write().retain(|dri| dri.get_id() != driver.get_id());
true
}
None => {
false
}
None => false,
}
}
@ -362,5 +359,6 @@ pub fn find_device(vendor: u32, product: u32) -> Option<PciTag> {
}
lazy_static! {
pub static ref PCI_DRIVERS: Arc<Mutex<BTreeMap<PciTag, Arc<Driver>>>> = Arc::new(Mutex::new(BTreeMap::new()));
pub static ref PCI_DRIVERS: Arc<Mutex<BTreeMap<PciTag, Arc<Driver>>>> =
Arc::new(Mutex::new(BTreeMap::new()));
}

View File

@ -1,4 +1,5 @@
use alloc::alloc::{GlobalAlloc, Layout};
use alloc::string::String;
use alloc::sync::Arc;
use core::slice;
@ -214,6 +215,10 @@ impl Driver for VirtIOGpuDriver {
fn device_type(&self) -> DeviceType {
DeviceType::Gpu
}
fn get_id(&self) -> String {
format!("virtio_gpu")
}
}
fn request(driver: &mut VirtIOGpu) {

View File

@ -172,6 +172,10 @@ impl Driver for VirtIOInputDriver {
fn device_type(&self) -> DeviceType {
DeviceType::Input
}
fn get_id(&self) -> String {
String::from("virtio_input")
}
}
pub fn virtio_input_init(node: &Node) {

View File

@ -6,7 +6,7 @@ use smoltcp::wire::{EthernetAddress, Ipv4Address};
use smoltcp::socket::SocketSet;
use spin::RwLock;
use crate::sync::{Condvar, MutexGuard, SpinNoIrq};
use crate::sync::Condvar;
use self::block::virtio_blk::VirtIOBlkDriver;
mod device_tree;
@ -39,6 +39,10 @@ pub trait Driver : Send + Sync {
// return the correspondent device type, see DeviceType
fn device_type(&self) -> DeviceType;
// get unique identifier for this device
// should be different for each instance
fn get_id(&self) -> String;
// Rust trait is still too restricted...
// network related drivers should implement these
// get mac address for this device

View File

@ -16,7 +16,6 @@ use rcore_memory::paging::PageTable;
use rcore_memory::PAGE_SIZE;
use smoltcp::iface::*;
use smoltcp::phy::{self, DeviceCapabilities};
use smoltcp::socket::*;
use smoltcp::time::Instant;
use smoltcp::wire::EthernetAddress;
use smoltcp::wire::*;
@ -123,6 +122,10 @@ impl Driver for E1000Interface {
DeviceType::Net
}
fn get_id(&self) -> String {
format!("e1000")
}
fn get_mac(&self) -> EthernetAddress {
self.iface.lock().ethernet_addr()
}

View File

@ -145,8 +145,9 @@ const IXGBE_EEC: usize = 0x10010 / 4;
pub struct IXGBEInterface {
iface: Mutex<EthernetInterface<'static, 'static, 'static, IXGBEDriver>>,
driver: IXGBEDriver,
name: String,
ifname: String,
irq: Option<u32>,
id: String,
}
impl Driver for IXGBEInterface {
@ -180,10 +181,10 @@ impl Driver for IXGBEInterface {
let status = ixgbe[IXGBE_LINKS].read();
if status & (1 << 7) != 0 {
// link up
info!("ixgbe: interface {} link up", &self.name);
info!("ixgbe: interface {} link up", &self.ifname);
} else {
// link down
info!("ixgbe: interface {} link down", &self.name);
info!("ixgbe: interface {} link down", &self.ifname);
}
}
if icr & (1 << 0) != 0 {
@ -217,12 +218,16 @@ impl Driver for IXGBEInterface {
DeviceType::Net
}
fn get_id(&self) -> String {
self.ifname.clone()
}
fn get_mac(&self) -> EthernetAddress {
self.iface.lock().ethernet_addr()
}
fn get_ifname(&self) -> String {
self.name.clone()
self.ifname.clone()
}
fn ipv4_address(&self) -> Option<Ipv4Address> {
@ -789,7 +794,8 @@ pub fn ixgbe_init(name: String, irq: Option<u32>, header: usize, size: usize) ->
let ixgbe_iface = IXGBEInterface {
iface: Mutex::new(iface),
driver: net_driver.clone(),
name,
ifname: name.clone(),
id: name,
irq,
};
@ -801,6 +807,28 @@ pub fn ixgbe_init(name: String, irq: Option<u32>, header: usize, size: usize) ->
impl Drop for IXGBE {
fn drop(&mut self) {
debug!("ixgbe: interface detaching");
if let None = active_table().get_entry(self.header) {
let mut current_addr = self.header;
while current_addr < self.header + self.size {
active_table().map_if_not_exists(current_addr, current_addr);
current_addr = current_addr + PAGE_SIZE;
}
}
let ixgbe = unsafe {
slice::from_raw_parts_mut(self.header as *mut Volatile<u32>, self.size / 4)
};
// 1. Disable interrupts.
ixgbe[IXGBE_EIMC].write(!0);
ixgbe[IXGBE_EIMC1].write(!0);
ixgbe[IXGBE_EIMC2].write(!0);
// 2. Issue a global reset.
// reset: LRST | RST
ixgbe[IXGBE_CTRL].write(1 << 3 | 1 << 26);
while ixgbe[IXGBE_CTRL].read() & (1 << 3 | 1 << 26) != 0 {}
unsafe {
HEAP_ALLOCATOR.dealloc(self.send_page as *mut u8, Layout::from_size_align(PAGE_SIZE, PAGE_SIZE).unwrap());
HEAP_ALLOCATOR.dealloc(self.recv_page as *mut u8, Layout::from_size_align(PAGE_SIZE, PAGE_SIZE).unwrap());

View File

@ -65,6 +65,10 @@ impl Driver for VirtIONetDriver {
DeviceType::Net
}
fn get_id(&self) -> String {
format!("virtio_net")
}
fn get_mac(&self) -> EthernetAddress {
self.0.lock().mac
}

View File

@ -9,11 +9,16 @@ use super::*;
pub fn sys_map_pci_device(vendor: usize, product: usize) -> SysResult {
use crate::drivers::bus::pci;
info!(
"map_pci_device: vendor: {}, product: {}",
"map_pci_device: vendor: {:x}, product: {:x}",
vendor, product
);
let tag = pci::find_device(vendor as u32, product as u32)
.ok_or(SysError::ENOENT)?;
if pci::detach_driver(&tag) {
info!("Kernel driver detached");
}
// Get BAR0 memory
let (base, len) = unsafe { tag.get_bar_mem(0) }
.ok_or(SysError::ENOENT)?;