diff --git a/acpid/src/acpi/dmar/mod.rs b/acpid/src/acpi/dmar/mod.rs index f89eae95f2..b6a350d44f 100644 --- a/acpid/src/acpi/dmar/mod.rs +++ b/acpid/src/acpi/dmar/mod.rs @@ -26,7 +26,6 @@ pub struct DmarStruct { pub host_addr_width: u8, pub flags: u8, pub _rsvd: [u8; 10], - // This header is followed by N remapping structures. } unsafe impl plain::Plain for DmarStruct {} @@ -84,16 +83,23 @@ impl Dmar { log::debug!("GCMD: {:X}", drhd.gl_cmd.read()); log::debug!("GSTS: {:X}", drhd.gl_sts.read()); log::debug!("RT: {:X}", drhd.root_table.read()); - }, - _ => () + } + _ => (), } } } fn new(sdt: Sdt) -> Option { - assert_eq!(sdt.signature, *b"DMAR", "signature already checked against `DMAR`"); + assert_eq!( + sdt.signature, *b"DMAR", + "signature already checked against `DMAR`" + ); if sdt.length() < mem::size_of::() { - log::error!("The DMAR table was too small ({} B < {} B).", sdt.length(), mem::size_of::()); + log::error!( + "The DMAR table was too small ({} B < {} B).", + sdt.length(), + mem::size_of::() + ); return None; } // No need to check alignment for #[repr(packed)] structs. @@ -102,7 +108,9 @@ impl Dmar { } pub fn iter(&self) -> DmarIter<'_> { - DmarIter(DmarRawIter { bytes: self.remmapping_structs_area() }) + DmarIter(DmarRawIter { + bytes: self.remmapping_structs_area(), + }) } } @@ -128,7 +136,6 @@ pub struct DeviceScopeHeader { pub _rsvd: u16, pub enumeration_id: u8, pub start_bus_num: u8, - // The variable-sized path comes after. } unsafe impl plain::Plain for DeviceScopeHeader {} @@ -196,8 +203,7 @@ impl DmarDrhd { pub fn map(&self) -> DrhdPage { let base = usize::try_from(self.base).expect("expected u64 to fit within usize"); - DrhdPage::map(base) - .expect("failed to map DRHD registers") + DrhdPage::map(base).expect("failed to map DRHD registers") } } impl Deref for DmarDrhd { @@ -227,7 +233,6 @@ pub struct DmarRmrrHeader { pub segment: u16, pub base: u64, pub limit: u64, - // The device scopes come after. } unsafe impl plain::Plain for DmarRmrrHeader {} @@ -269,7 +274,6 @@ pub struct DmarAtsrHeader { flags: u8, _rsv: u8, segment: u16, - // The device scopes come after. } unsafe impl plain::Plain for DmarAtsrHeader {} @@ -334,7 +338,6 @@ pub struct DmarAnddHeader { pub _rsv: [u8; 3], pub acpi_dev: u8, - // The device scopes come after. } unsafe impl plain::Plain for DmarAnddHeader {} @@ -377,7 +380,6 @@ pub struct DmarSatcHeader { pub flags: u8, pub _rsvd: u8, pub seg_num: u16, - // The device scopes come after. } unsafe impl plain::Plain for DmarSatcHeader {} @@ -467,8 +469,10 @@ impl<'sdt> Iterator for DmarRawIter<'sdt> { }; let remainder = &self.bytes[4..]; - let type_bytes = <[u8; 2]>::try_from(type_bytes).expect("expected a 2-byte slice to be convertible to [u8; 2]"); - let len_bytes = <[u8; 2]>::try_from(type_bytes).expect("expected a 2-byte slice to be convertible to [u8; 2]"); + let type_bytes = <[u8; 2]>::try_from(type_bytes) + .expect("expected a 2-byte slice to be convertible to [u8; 2]"); + let len_bytes = <[u8; 2]>::try_from(type_bytes) + .expect("expected a 2-byte slice to be convertible to [u8; 2]"); let ty = u16::from_ne_bytes(type_bytes); let len = u16::from_ne_bytes(len_bytes); @@ -500,7 +504,11 @@ impl Iterator for DmarIter<'_> { let entry_type = match EntryType::from_u16(raw_type) { Some(ty) => ty, None => { - log::warn!("Encountered invalid entry type {} (length {})", raw_type, raw.len()); + log::warn!( + "Encountered invalid entry type {} (length {})", + raw_type, + raw.len() + ); return Some(DmarEntry::Unknown(raw_type)); } }; diff --git a/acpid/src/aml_physmem.rs b/acpid/src/aml_physmem.rs index e8f82d5f4c..8f39880279 100644 --- a/acpid/src/aml_physmem.rs +++ b/acpid/src/aml_physmem.rs @@ -1,10 +1,10 @@ +use common::io::{Io, Pio}; use num_traits::PrimInt; use rustc_hash::FxHashMap; use std::fmt::LowerHex; use std::mem::size_of; use std::sync::{Arc, Mutex}; use syscall::PAGE_SIZE; -use common::io::{Io, Pio}; const PAGE_MASK: usize = !(PAGE_SIZE - 1); const OFFSET_MASK: usize = PAGE_SIZE - 1; @@ -17,8 +17,13 @@ struct MappedPage { impl MappedPage { fn new(phys_page: usize) -> std::io::Result { let virt_page = unsafe { - common::physmap(phys_page, PAGE_SIZE, common::Prot::RO, common::MemoryType::default()) - .map_err(|error| std::io::Error::from_raw_os_error(error.errno()))? + common::physmap( + phys_page, + PAGE_SIZE, + common::Prot::RO, + common::MemoryType::default(), + ) + .map_err(|error| std::io::Error::from_raw_os_error(error.errno()))? } as usize; Ok(Self { phys_page, diff --git a/audio/ac97d/src/device.rs b/audio/ac97d/src/device.rs index 1892d34fda..de182de2ba 100644 --- a/audio/ac97d/src/device.rs +++ b/audio/ac97d/src/device.rs @@ -1,276 +1,300 @@ #![allow(dead_code)] -use std::mem; use std::collections::BTreeMap; +use std::mem; use std::sync::atomic::{AtomicUsize, Ordering}; -use syscall::error::{Error, EACCES, EBADF, Result, EINVAL, ENOENT}; use common::io::Pio; +use syscall::error::{Error, Result, EACCES, EBADF, EINVAL, ENOENT}; use syscall::scheme::SchemeBlockMut; -use common::{dma::Dma, io::{Io, Mmio}}; +use common::{ + dma::Dma, + io::{Io, Mmio}, +}; use spin::Mutex; const NUM_SUB_BUFFS: usize = 32; const SUB_BUFF_SIZE: usize = 2048; enum Handle { - Todo, + Todo, } #[allow(dead_code)] struct MixerRegs { - /* 0x00 */ reset: Pio, - /* 0x02 */ master_volume: Pio, - /* 0x04 */ aux_out_volume: Pio, - /* 0x06 */ mono_volume: Pio, - /* 0x08 */ master_tone: Pio, - /* 0x0A */ pc_beep_volume: Pio, - /* 0x0C */ phone_volume: Pio, - /* 0x0E */ mic_volume: Pio, - /* 0x10 */ line_in_volume: Pio, - /* 0x12 */ cd_volume: Pio, - /* 0x14 */ video_volume: Pio, - /* 0x16 */ aux_in_volume: Pio, - /* 0x18 */ pcm_out_volume: Pio, - /* 0x1A */ record_select: Pio, - /* 0x1C */ record_gain: Pio, - /* 0x1E */ record_gain_mic: Pio, - /* 0x20 */ general_purpose: Pio, - /* 0x22 */ control_3d: Pio, - /* 0x24 */ audio_int_paging: Pio, - /* 0x26 */ powerdown: Pio, - /* 0x28 */ extended_id: Pio, - /* 0x2A */ extended_ctrl: Pio, - /* 0x2C */ vra_pcm_front: Pio, + /* 0x00 */ reset: Pio, + /* 0x02 */ master_volume: Pio, + /* 0x04 */ aux_out_volume: Pio, + /* 0x06 */ mono_volume: Pio, + /* 0x08 */ master_tone: Pio, + /* 0x0A */ pc_beep_volume: Pio, + /* 0x0C */ phone_volume: Pio, + /* 0x0E */ mic_volume: Pio, + /* 0x10 */ line_in_volume: Pio, + /* 0x12 */ cd_volume: Pio, + /* 0x14 */ video_volume: Pio, + /* 0x16 */ aux_in_volume: Pio, + /* 0x18 */ pcm_out_volume: Pio, + /* 0x1A */ record_select: Pio, + /* 0x1C */ record_gain: Pio, + /* 0x1E */ record_gain_mic: Pio, + /* 0x20 */ general_purpose: Pio, + /* 0x22 */ control_3d: Pio, + /* 0x24 */ audio_int_paging: Pio, + /* 0x26 */ powerdown: Pio, + /* 0x28 */ extended_id: Pio, + /* 0x2A */ extended_ctrl: Pio, + /* 0x2C */ vra_pcm_front: Pio, } impl MixerRegs { - fn new(bar0: u16) -> Self { - Self { - reset: Pio::new(bar0 + 0x00), - master_volume: Pio::new(bar0 + 0x02), - aux_out_volume: Pio::new(bar0 + 0x04), - mono_volume: Pio::new(bar0 + 0x06), - master_tone: Pio::new(bar0 + 0x08), - pc_beep_volume: Pio::new(bar0 + 0x0A), - phone_volume: Pio::new(bar0 + 0x0C), - mic_volume: Pio::new(bar0 + 0x0E), - line_in_volume: Pio::new(bar0 + 0x10), - cd_volume: Pio::new(bar0 + 0x12), - video_volume: Pio::new(bar0 + 0x14), - aux_in_volume: Pio::new(bar0 + 0x16), - pcm_out_volume: Pio::new(bar0 + 0x18), - record_select: Pio::new(bar0 + 0x1A), - record_gain: Pio::new(bar0 + 0x1C), - record_gain_mic: Pio::new(bar0 + 0x1E), - general_purpose: Pio::new(bar0 + 0x20), - control_3d: Pio::new(bar0 + 0x22), - audio_int_paging: Pio::new(bar0 + 0x24), - powerdown: Pio::new(bar0 + 0x26), - extended_id: Pio::new(bar0 + 0x28), - extended_ctrl: Pio::new(bar0 + 0x2A), - vra_pcm_front: Pio::new(bar0 + 0x2C), - } - } + fn new(bar0: u16) -> Self { + Self { + reset: Pio::new(bar0 + 0x00), + master_volume: Pio::new(bar0 + 0x02), + aux_out_volume: Pio::new(bar0 + 0x04), + mono_volume: Pio::new(bar0 + 0x06), + master_tone: Pio::new(bar0 + 0x08), + pc_beep_volume: Pio::new(bar0 + 0x0A), + phone_volume: Pio::new(bar0 + 0x0C), + mic_volume: Pio::new(bar0 + 0x0E), + line_in_volume: Pio::new(bar0 + 0x10), + cd_volume: Pio::new(bar0 + 0x12), + video_volume: Pio::new(bar0 + 0x14), + aux_in_volume: Pio::new(bar0 + 0x16), + pcm_out_volume: Pio::new(bar0 + 0x18), + record_select: Pio::new(bar0 + 0x1A), + record_gain: Pio::new(bar0 + 0x1C), + record_gain_mic: Pio::new(bar0 + 0x1E), + general_purpose: Pio::new(bar0 + 0x20), + control_3d: Pio::new(bar0 + 0x22), + audio_int_paging: Pio::new(bar0 + 0x24), + powerdown: Pio::new(bar0 + 0x26), + extended_id: Pio::new(bar0 + 0x28), + extended_ctrl: Pio::new(bar0 + 0x2A), + vra_pcm_front: Pio::new(bar0 + 0x2C), + } + } } #[allow(dead_code)] struct BusBoxRegs { - /// Buffer descriptor list base address - /* 0x00 */ bdbar: Pio, - /// Current index value - /* 0x04 */ civ: Pio, - /// Last valid index - /* 0x05 */ lvi: Pio, - /// Status - /* 0x06 */ sr: Pio, - /// Position in current buffer - /* 0x08 */ picb: Pio, - /// Prefetched index value - /* 0x0A */ piv: Pio, - /// Control - /* 0x0B */ cr: Pio, + /// Buffer descriptor list base address + /* 0x00 */ + bdbar: Pio, + /// Current index value + /* 0x04 */ + civ: Pio, + /// Last valid index + /* 0x05 */ + lvi: Pio, + /// Status + /* 0x06 */ + sr: Pio, + /// Position in current buffer + /* 0x08 */ + picb: Pio, + /// Prefetched index value + /* 0x0A */ + piv: Pio, + /// Control + /* 0x0B */ + cr: Pio, } impl BusBoxRegs { - fn new(base: u16) -> Self { - Self { - bdbar: Pio::new(base + 0x00), - civ: Pio::new(base + 0x04), - lvi: Pio::new(base + 0x05), - sr: Pio::new(base + 0x06), - picb: Pio::new(base + 0x08), - piv: Pio::new(base + 0x0A), - cr: Pio::new(base + 0x0B), - } - } + fn new(base: u16) -> Self { + Self { + bdbar: Pio::new(base + 0x00), + civ: Pio::new(base + 0x04), + lvi: Pio::new(base + 0x05), + sr: Pio::new(base + 0x06), + picb: Pio::new(base + 0x08), + piv: Pio::new(base + 0x0A), + cr: Pio::new(base + 0x0B), + } + } } #[allow(dead_code)] struct BusRegs { - /// PCM in register box - /* 0x00 */ pi: BusBoxRegs, - /// PCM out register box - /* 0x10 */ po: BusBoxRegs, - /// Microphone register box - /* 0x20 */ mc: BusBoxRegs, + /// PCM in register box + /* 0x00 */ + pi: BusBoxRegs, + /// PCM out register box + /* 0x10 */ + po: BusBoxRegs, + /// Microphone register box + /* 0x20 */ + mc: BusBoxRegs, } impl BusRegs { - fn new(bar1: u16) -> Self { - Self { - pi: BusBoxRegs::new(bar1 + 0x00), - po: BusBoxRegs::new(bar1 + 0x10), - mc: BusBoxRegs::new(bar1 + 0x20), - } - } + fn new(bar1: u16) -> Self { + Self { + pi: BusBoxRegs::new(bar1 + 0x00), + po: BusBoxRegs::new(bar1 + 0x10), + mc: BusBoxRegs::new(bar1 + 0x20), + } + } } #[repr(packed)] pub struct BufferDescriptor { - /* 0x00 */ addr: Mmio, - /* 0x04 */ samples: Mmio, - /* 0x06 */ flags: Mmio, + /* 0x00 */ addr: Mmio, + /* 0x04 */ samples: Mmio, + /* 0x06 */ flags: Mmio, } pub struct Ac97 { - mixer: MixerRegs, - bus: BusRegs, - bdl: Dma<[BufferDescriptor; NUM_SUB_BUFFS]>, + mixer: MixerRegs, + bus: BusRegs, + bdl: Dma<[BufferDescriptor; NUM_SUB_BUFFS]>, buf: Dma<[u8; NUM_SUB_BUFFS * SUB_BUFF_SIZE]>, - handles: Mutex>, - next_id: AtomicUsize, + handles: Mutex>, + next_id: AtomicUsize, } impl Ac97 { - pub unsafe fn new(bar0: u16, bar1: u16) -> Result { - let mut module = Ac97 { - mixer: MixerRegs::new(bar0), - bus: BusRegs::new(bar1), + pub unsafe fn new(bar0: u16, bar1: u16) -> Result { + let mut module = Ac97 { + mixer: MixerRegs::new(bar0), + bus: BusRegs::new(bar1), bdl: Dma::zeroed( //TODO: PhysBox::new_in_32bit_space(bdl_size)? - )?.assume_init(), + )? + .assume_init(), buf: Dma::zeroed( //TODO: PhysBox::new_in_32bit_space(buf_size)? - )?.assume_init(), - handles: Mutex::new(BTreeMap::new()), - next_id: AtomicUsize::new(0), - }; + )? + .assume_init(), + handles: Mutex::new(BTreeMap::new()), + next_id: AtomicUsize::new(0), + }; - module.init()?; + module.init()?; - Ok(module) - } + Ok(module) + } - fn init(&mut self) -> Result<()> { - //TODO: support other sample rates, or just the default of 48000 Hz - { - // Check if VRA is supported - if ! self.mixer.extended_id.readf(1 << 0) { - println!("ac97d: VRA not supported and is currently required"); - return Err(Error::new(ENOENT)); - } + fn init(&mut self) -> Result<()> { + //TODO: support other sample rates, or just the default of 48000 Hz + { + // Check if VRA is supported + if !self.mixer.extended_id.readf(1 << 0) { + println!("ac97d: VRA not supported and is currently required"); + return Err(Error::new(ENOENT)); + } - // Enable VRA - self.mixer.extended_ctrl.writef(1 << 0, true); + // Enable VRA + self.mixer.extended_ctrl.writef(1 << 0, true); - // Attempt to set sample rate for PCM front to 44100 Hz - let desired_sample_rate = 44100; - self.mixer.vra_pcm_front.write(desired_sample_rate); + // Attempt to set sample rate for PCM front to 44100 Hz + let desired_sample_rate = 44100; + self.mixer.vra_pcm_front.write(desired_sample_rate); - // Read back real sample rate - let real_sample_rate = self.mixer.vra_pcm_front.read(); - println!("ac97d: set sample rate to {}", real_sample_rate); + // Read back real sample rate + let real_sample_rate = self.mixer.vra_pcm_front.read(); + println!("ac97d: set sample rate to {}", real_sample_rate); - // Error if we cannot set the sample rate as desired - if real_sample_rate != desired_sample_rate { - println!("ac97d: sample rate is {} but only {} is supported", real_sample_rate, desired_sample_rate); - return Err(Error::new(ENOENT)); - } - } + // Error if we cannot set the sample rate as desired + if real_sample_rate != desired_sample_rate { + println!( + "ac97d: sample rate is {} but only {} is supported", + real_sample_rate, desired_sample_rate + ); + return Err(Error::new(ENOENT)); + } + } - // Ensure PCM out is stopped - self.bus.po.cr.writef(1, false); + // Ensure PCM out is stopped + self.bus.po.cr.writef(1, false); - // Reset PCM out - self.bus.po.cr.writef(1 << 1, true); - while self.bus.po.cr.readf(1 << 1) { - // Spinning on resetting PCM out - //TODO: relax - } + // Reset PCM out + self.bus.po.cr.writef(1 << 1, true); + while self.bus.po.cr.readf(1 << 1) { + // Spinning on resetting PCM out + //TODO: relax + } - // Initialize BDL for PCM out - for i in 0..NUM_SUB_BUFFS { - self.bdl[i].addr.write((self.buf.physical() + i * SUB_BUFF_SIZE) as u32); - self.bdl[i].samples.write((SUB_BUFF_SIZE / 2 /* Each sample is i16 or 2 bytes */) as u16); - self.bdl[i].flags.write(1 << 15 /* Interrupt on completion */); - } - self.bus.po.bdbar.write(self.bdl.physical() as u32); + // Initialize BDL for PCM out + for i in 0..NUM_SUB_BUFFS { + self.bdl[i] + .addr + .write((self.buf.physical() + i * SUB_BUFF_SIZE) as u32); + self.bdl[i] + .samples + .write((SUB_BUFF_SIZE / 2/* Each sample is i16 or 2 bytes */) as u16); + self.bdl[i] + .flags + .write(1 << 15 /* Interrupt on completion */); + } + self.bus.po.bdbar.write(self.bdl.physical() as u32); - // Enable interrupt on completion - self.bus.po.cr.writef(1 << 4, true); + // Enable interrupt on completion + self.bus.po.cr.writef(1 << 4, true); - // Start bus master - self.bus.po.cr.writef(1 << 0, true); + // Start bus master + self.bus.po.cr.writef(1 << 0, true); - // Set master volume to 0 db (loudest output, DANGER!) - self.mixer.master_volume.write(0); + // Set master volume to 0 db (loudest output, DANGER!) + self.mixer.master_volume.write(0); - // Set PCM output volume to 0 db (medium) - self.mixer.pcm_out_volume.write(0x808); + // Set PCM output volume to 0 db (medium) + self.mixer.pcm_out_volume.write(0x808); - Ok(()) - } + Ok(()) + } - pub fn irq(&mut self) -> bool { - let ints = self.bus.po.sr.read() & 0b11100; - if ints != 0 { - self.bus.po.sr.write(ints); - true - } else { - false - } - } + pub fn irq(&mut self) -> bool { + let ints = self.bus.po.sr.read() & 0b11100; + if ints != 0 { + self.bus.po.sr.write(ints); + true + } else { + false + } + } } impl SchemeBlockMut for Ac97 { - fn open(&mut self, _path: &str, _flags: usize, uid: u32, _gid: u32) -> Result> { - if uid == 0 { - let id = self.next_id.fetch_add(1, Ordering::SeqCst); - self.handles.lock().insert(id, Handle::Todo); - Ok(Some(id)) - } else { - Err(Error::new(EACCES)) - } - } + fn open(&mut self, _path: &str, _flags: usize, uid: u32, _gid: u32) -> Result> { + if uid == 0 { + let id = self.next_id.fetch_add(1, Ordering::SeqCst); + self.handles.lock().insert(id, Handle::Todo); + Ok(Some(id)) + } else { + Err(Error::new(EACCES)) + } + } - fn write(&mut self, id: usize, buf: &[u8]) -> Result> { - { - let mut handles = self.handles.lock(); - let _handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; - } + fn write(&mut self, id: usize, buf: &[u8]) -> Result> { + { + let mut handles = self.handles.lock(); + let _handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; + } - if buf.len() != SUB_BUFF_SIZE { - return Err(Error::new(EINVAL)); - } + if buf.len() != SUB_BUFF_SIZE { + return Err(Error::new(EINVAL)); + } - let civ = self.bus.po.civ.read() as usize; - let mut lvi = self.bus.po.lvi.read() as usize; - if lvi == (civ + 3) % NUM_SUB_BUFFS { - // Block if we already are 3 buffers ahead - Ok(None) - } else { - // Fill next buffer - lvi = (lvi + 1) % NUM_SUB_BUFFS; - for i in 0..SUB_BUFF_SIZE { - self.buf[lvi * SUB_BUFF_SIZE + i] = buf[i]; - } - self.bus.po.lvi.write(lvi as u8); + let civ = self.bus.po.civ.read() as usize; + let mut lvi = self.bus.po.lvi.read() as usize; + if lvi == (civ + 3) % NUM_SUB_BUFFS { + // Block if we already are 3 buffers ahead + Ok(None) + } else { + // Fill next buffer + lvi = (lvi + 1) % NUM_SUB_BUFFS; + for i in 0..SUB_BUFF_SIZE { + self.buf[lvi * SUB_BUFF_SIZE + i] = buf[i]; + } + self.bus.po.lvi.write(lvi as u8); - Ok(Some(SUB_BUFF_SIZE)) - } - } + Ok(Some(SUB_BUFF_SIZE)) + } + } fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result> { let mut handles = self.handles.lock(); @@ -285,8 +309,11 @@ impl SchemeBlockMut for Ac97 { Ok(Some(i)) } - fn close(&mut self, id: usize) -> Result> { - let mut handles = self.handles.lock(); - handles.remove(&id).ok_or(Error::new(EBADF)).and(Ok(Some(0))) - } + fn close(&mut self, id: usize) -> Result> { + let mut handles = self.handles.lock(); + handles + .remove(&id) + .ok_or(Error::new(EBADF)) + .and(Ok(Some(0))) + } } diff --git a/audio/ac97d/src/main.rs b/audio/ac97d/src/main.rs index 05cd1a0df9..3b848481fe 100644 --- a/audio/ac97d/src/main.rs +++ b/audio/ac97d/src/main.rs @@ -1,14 +1,14 @@ //#![deny(warnings)] extern crate bitflags; +extern crate event; extern crate spin; extern crate syscall; -extern crate event; -use std::fs::File; -use std::io::{ErrorKind, Read, Write, Result}; -use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use std::cell::RefCell; +use std::fs::File; +use std::io::{ErrorKind, Read, Result, Write}; +use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use std::sync::Arc; use std::usize; @@ -30,7 +30,10 @@ fn main() { let bar0 = pci_config.func.bars[0].expect_port(); let bar1 = pci_config.func.bars[1].expect_port(); - let irq = pci_config.func.legacy_interrupt_line.expect("ac97d: no legacy interrupts supported"); + let irq = pci_config + .func + .legacy_interrupt_line + .expect("ac97d: no legacy interrupts supported"); println!(" + ac97 {}", pci_config.func.display()); @@ -44,12 +47,19 @@ fn main() { log::LevelFilter::Info, ); - common::acquire_port_io_rights().expect("ac97d: failed to set I/O privilege level to Ring 3"); + common::acquire_port_io_rights() + .expect("ac97d: failed to set I/O privilege level to Ring 3"); let mut irq_file = irq.irq_handle("ac97d"); - let mut device = unsafe { device::Ac97::new(bar0, bar1).expect("ac97d: failed to allocate device") }; - let socket_fd = libredox::call::open(":audiohw", flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, 0).expect("ac97d: failed to create hda scheme"); + let mut device = + unsafe { device::Ac97::new(bar0, bar1).expect("ac97d: failed to allocate device") }; + let socket_fd = libredox::call::open( + ":audiohw", + flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, + 0, + ) + .expect("ac97d: failed to create hda scheme"); let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) }; user_data! { @@ -59,9 +69,18 @@ fn main() { } } - let mut event_queue = EventQueue::::new().expect("ac97d: Could not create event queue."); - event_queue.subscribe(irq_file.as_raw_fd() as usize, Source::Irq, event::EventFlags::READ).unwrap(); - event_queue.subscribe(socket_fd, Source::Scheme, event::EventFlags::READ).unwrap(); + let mut event_queue = + EventQueue::::new().expect("ac97d: Could not create event queue."); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); + event_queue + .subscribe(socket_fd, Source::Scheme, event::EventFlags::READ) + .unwrap(); daemon.ready().expect("ac97d: failed to signal readiness"); @@ -70,7 +89,10 @@ fn main() { let mut todo = Vec::::new(); let all = [Source::Irq, Source::Scheme]; - 'events: for event in all.into_iter().chain(event_queue.map(|e| e.expect("ac97d: failed to get next event").user_data)) { + 'events: for event in all + .into_iter() + .chain(event_queue.map(|e| e.expect("ac97d: failed to get next event").user_data)) + { match event { Source::Irq => { let mut irq = [0; 8]; @@ -91,11 +113,11 @@ fn main() { } /* - let next_read = device_irq.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + let next_read = device_irq.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ } } Source::Scheme => { @@ -104,10 +126,12 @@ fn main() { match socket.read(&mut packet) { Ok(0) => break 'events, Ok(_) => (), - Err(err) => if err.kind() == ErrorKind::WouldBlock { - break; - } else { - panic!("ac97d: failed to read socket: {err}"); + Err(err) => { + if err.kind() == ErrorKind::WouldBlock { + break; + } else { + panic!("ac97d: failed to read socket: {err}"); + } } } @@ -120,15 +144,16 @@ fn main() { } /* - let next_read = device.borrow().next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + let next_read = device.borrow().next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ } } } std::process::exit(0); - }).expect("ac97d: failed to daemonize"); + }) + .expect("ac97d: failed to daemonize"); } diff --git a/audio/ihdad/src/hda/cmdbuff.rs b/audio/ihdad/src/hda/cmdbuff.rs index 93e771d01c..aec6c2dde7 100644 --- a/audio/ihdad/src/hda/cmdbuff.rs +++ b/audio/ihdad/src/hda/cmdbuff.rs @@ -177,8 +177,7 @@ impl Corb { fn send_command(&mut self, cmd: u32) { // wait for the commands to finish while (self.regs.corbwp.read() & 0xff) != (self.regs.corbrp.read() & 0xff) {} - let write_pos: usize = - ((self.regs.corbwp.read() as usize & 0xFF) + 1) % self.corb_count; + let write_pos: usize = ((self.regs.corbwp.read() as usize & 0xFF) + 1) % self.corb_count; unsafe { *self.corb_base.offset(write_pos as isize) = cmd; } @@ -348,15 +347,20 @@ pub struct CommandBuffer { } impl CommandBuffer { - pub fn new( - regs_addr: usize, - mut cmd_buff: Dma<[u8; 0x1000]>, - ) -> CommandBuffer { - let corb = Corb::new(regs_addr + CORB_OFFSET, cmd_buff.physical(), cmd_buff.as_mut_ptr().cast()); + pub fn new(regs_addr: usize, mut cmd_buff: Dma<[u8; 0x1000]>) -> CommandBuffer { + let corb = Corb::new( + regs_addr + CORB_OFFSET, + cmd_buff.physical(), + cmd_buff.as_mut_ptr().cast(), + ); let rirb = Rirb::new( regs_addr + RIRB_OFFSET, cmd_buff.physical() + CORB_BUFF_MAX_SIZE, - cmd_buff.as_mut_ptr().cast::().wrapping_add(CORB_BUFF_MAX_SIZE).cast(), + cmd_buff + .as_mut_ptr() + .cast::() + .wrapping_add(CORB_BUFF_MAX_SIZE) + .cast(), ); let icmd = ImmediateCommand::new(regs_addr + ICMD_OFFSET); diff --git a/audio/ihdad/src/hda/device.rs b/audio/ihdad/src/hda/device.rs index 86847d3a00..13b1bb7e73 100755 --- a/audio/ihdad/src/hda/device.rs +++ b/audio/ihdad/src/hda/device.rs @@ -1,41 +1,41 @@ #![allow(dead_code)] use std::cmp; +use std::collections::BTreeMap; use std::collections::HashMap; use std::fmt::Write; use std::str; -use std::collections::BTreeMap; use std::sync::atomic::{AtomicUsize, Ordering}; use common::dma::Dma; -use common::io::{Mmio, Io}; -use syscall::error::{Error, EACCES, EBADF, Result, EINVAL}; -use syscall::flag::{SEEK_SET, SEEK_CUR, SEEK_END}; +use common::io::{Io, Mmio}; +use syscall::error::{Error, Result, EACCES, EBADF, EINVAL}; +use syscall::flag::{SEEK_CUR, SEEK_END, SEEK_SET}; use syscall::scheme::SchemeBlockMut; use spin::Mutex; -use super::BufferDescriptorListEntry; use super::common::*; -use super::StreamDescriptorRegs; -use super::StreamBuffer; use super::BitsPerSample; +use super::BufferDescriptorListEntry; use super::CommandBuffer; use super::HDANode; use super::OutputStream; +use super::StreamBuffer; +use super::StreamDescriptorRegs; // GCTL - Global Control -const CRST: u32 = 1 << 0; // 1 bit +const CRST: u32 = 1 << 0; // 1 bit const FNCTRL: u32 = 1 << 1; // 1 bit -const UNSOL: u32 = 1 << 8; // 1 bit +const UNSOL: u32 = 1 << 8; // 1 bit // CORBCTL -const CMEIE: u8 = 1 << 0; // 1 bit +const CMEIE: u8 = 1 << 0; // 1 bit const CORBRUN: u8 = 1 << 1; // 1 bit // CORBSIZE -const CORBSZCAP: (u8,u8) = (4, 4); -const CORBSIZE: (u8,u8) = (0, 2); +const CORBSZCAP: (u8, u8) = (4, 4); +const CORBSIZE: (u8, u8) = (0, 2); // CORBRP const CORBRPRST: u16 = 1 << 15; @@ -44,12 +44,12 @@ const CORBRPRST: u16 = 1 << 15; const RIRBWPRST: u16 = 1 << 15; // RIRBCTL -const RINTCTL: u8 = 1 << 0; // 1 bit +const RINTCTL: u8 = 1 << 0; // 1 bit const RIRBDMAEN: u8 = 1 << 1; // 1 bit // ICS -const ICB: u16 = 1 << 0; -const IRV: u16 = 1 << 1; +const ICB: u16 = 1 << 0; +const IRV: u16 = 1 << 1; // CORB and RIRB offset @@ -59,922 +59,984 @@ const NUM_SUB_BUFFS: usize = 32; const SUB_BUFF_SIZE: usize = 2048; enum Handle { - Todo, - Pcmout(usize, usize, usize), // Card, index, block_ptr - Pcmin(usize, usize, usize), // Card, index, block_ptr - StrBuf(Vec,usize), + Todo, + Pcmout(usize, usize, usize), // Card, index, block_ptr + Pcmin(usize, usize, usize), // Card, index, block_ptr + StrBuf(Vec, usize), } #[repr(packed)] #[allow(dead_code)] struct Regs { - gcap: Mmio, - vmin: Mmio, - vmaj: Mmio, - outpay: Mmio, - inpay: Mmio, - gctl: Mmio, - wakeen: Mmio, - statests: Mmio, - gsts: Mmio, - rsvd0: [Mmio; 6], - outstrmpay: Mmio, - instrmpay: Mmio, - rsvd1: [Mmio; 4], - intctl: Mmio, - intsts: Mmio, - rsvd2: [Mmio; 8], - walclk: Mmio, - rsvd3: Mmio, - ssync: Mmio, - rsvd4: Mmio, + gcap: Mmio, + vmin: Mmio, + vmaj: Mmio, + outpay: Mmio, + inpay: Mmio, + gctl: Mmio, + wakeen: Mmio, + statests: Mmio, + gsts: Mmio, + rsvd0: [Mmio; 6], + outstrmpay: Mmio, + instrmpay: Mmio, + rsvd1: [Mmio; 4], + intctl: Mmio, + intsts: Mmio, + rsvd2: [Mmio; 8], + walclk: Mmio, + rsvd3: Mmio, + ssync: Mmio, + rsvd4: Mmio, - corblbase: Mmio, - corbubase: Mmio, - corbwp: Mmio, - corbrp: Mmio, - corbctl: Mmio, - corbsts: Mmio, - corbsize: Mmio, - rsvd5: Mmio, + corblbase: Mmio, + corbubase: Mmio, + corbwp: Mmio, + corbrp: Mmio, + corbctl: Mmio, + corbsts: Mmio, + corbsize: Mmio, + rsvd5: Mmio, - rirblbase: Mmio, - rirbubase: Mmio, - rirbwp: Mmio, - rintcnt: Mmio, - rirbctl: Mmio, - rirbsts: Mmio, - rirbsize: Mmio, - rsvd6: Mmio, + rirblbase: Mmio, + rirbubase: Mmio, + rirbwp: Mmio, + rintcnt: Mmio, + rirbctl: Mmio, + rirbsts: Mmio, + rirbsize: Mmio, + rsvd6: Mmio, - icoi: Mmio, - irii: Mmio, - ics: Mmio, - rsvd7: [Mmio; 6], + icoi: Mmio, + irii: Mmio, + ics: Mmio, + rsvd7: [Mmio; 6], - dplbase: Mmio, // 0x70 - dpubase: Mmio, // 0x74 + dplbase: Mmio, // 0x70 + dpubase: Mmio, // 0x74 } pub struct IntelHDA { - vend_prod: u32, + vend_prod: u32, - base: usize, - regs: &'static mut Regs, + base: usize, + regs: &'static mut Regs, - //corb_rirb_base_phys: usize, + //corb_rirb_base_phys: usize, + cmd: CommandBuffer, - cmd: CommandBuffer, + codecs: Vec, - codecs: Vec, + outputs: Vec, + inputs: Vec, - outputs: Vec, - inputs: Vec, + widget_map: HashMap, - widget_map: HashMap, + output_pins: Vec, + input_pins: Vec, - output_pins: Vec, - input_pins: Vec, + beep_addr: WidgetAddr, - beep_addr: WidgetAddr, + buff_desc: Dma<[BufferDescriptorListEntry; 256]>, - buff_desc: Dma<[BufferDescriptorListEntry; 256]>, + output_streams: Vec, - output_streams: Vec, + buffs: Vec>, - buffs: Vec>, - - int_counter: usize, - handles: Mutex>, - next_id: AtomicUsize, + int_counter: usize, + handles: Mutex>, + next_id: AtomicUsize, } impl IntelHDA { - pub unsafe fn new(base: usize, vend_prod:u32) -> Result { - let regs = &mut *(base as *mut Regs); + pub unsafe fn new(base: usize, vend_prod: u32) -> Result { + let regs = &mut *(base as *mut Regs); - let buff_desc = Dma::<[BufferDescriptorListEntry; 256]>::zeroed() - .expect("Could not allocate physical memory for buffer descriptor list.") - .assume_init(); + let buff_desc = Dma::<[BufferDescriptorListEntry; 256]>::zeroed() + .expect("Could not allocate physical memory for buffer descriptor list.") + .assume_init(); - log::debug!("Virt: {:016X}, Phys: {:016X}", buff_desc.as_ptr() as usize, buff_desc.physical()); + log::debug!( + "Virt: {:016X}, Phys: {:016X}", + buff_desc.as_ptr() as usize, + buff_desc.physical() + ); - let cmd_buff = Dma::<[u8; 0x1000]>::zeroed() - .expect("Could not allocate physical memory for CORB and RIRB.") - .assume_init(); + let cmd_buff = Dma::<[u8; 0x1000]>::zeroed() + .expect("Could not allocate physical memory for CORB and RIRB.") + .assume_init(); - log::debug!("Virt: {:016X}, Phys: {:016X}", cmd_buff.as_ptr() as usize, cmd_buff.physical()); - let mut module = IntelHDA { - vend_prod, - base, - regs, + log::debug!( + "Virt: {:016X}, Phys: {:016X}", + cmd_buff.as_ptr() as usize, + cmd_buff.physical() + ); + let mut module = IntelHDA { + vend_prod, + base, + regs, - cmd: CommandBuffer::new(base + COMMAND_BUFFER_OFFSET, cmd_buff), + cmd: CommandBuffer::new(base + COMMAND_BUFFER_OFFSET, cmd_buff), - beep_addr: (0,0), + beep_addr: (0, 0), - widget_map: HashMap::::new(), + widget_map: HashMap::::new(), - codecs: Vec::::new(), + codecs: Vec::::new(), - outputs: Vec::::new(), - inputs: Vec::::new(), + outputs: Vec::::new(), + inputs: Vec::::new(), - output_pins: Vec::::new(), - input_pins: Vec::::new(), + output_pins: Vec::::new(), + input_pins: Vec::::new(), - buff_desc, + buff_desc, - output_streams: Vec::::new(), + output_streams: Vec::::new(), - buffs: Vec::>::new(), + buffs: Vec::>::new(), - int_counter: 0, - handles: Mutex::new(BTreeMap::new()), - next_id: AtomicUsize::new(0), - }; + int_counter: 0, + handles: Mutex::new(BTreeMap::new()), + next_id: AtomicUsize::new(0), + }; - module.init(); + module.init(); - module.info(); - module.enumerate(); + module.info(); + module.enumerate(); - module.configure(); - log::info!("IHDA: Initialization finished."); - Ok(module) + module.configure(); + log::info!("IHDA: Initialization finished."); + Ok(module) + } - } + pub fn init(&mut self) -> bool { + self.reset_controller(); - pub fn init(&mut self) -> bool { - self.reset_controller(); + let use_immediate_command_interface = match self.vend_prod { + 0x8086_2668 => false, + _ => true, + }; - let use_immediate_command_interface = match self.vend_prod { + self.cmd.init(use_immediate_command_interface); + self.init_interrupts(); - 0x8086_2668 => false, - _ => true, - }; + true + } - self.cmd.init(use_immediate_command_interface); - self.init_interrupts(); + pub fn init_interrupts(&mut self) { + // TODO: provide a function to enable certain interrupts + // This just enables the first output stream interupt and the global interrupt - true - } + let iss = self.num_input_streams(); + self.regs + .intctl + .write((1 << 31) | /* (1 << 30) |*/ (1 << iss)); + } - pub fn init_interrupts(&mut self) { - // TODO: provide a function to enable certain interrupts - // This just enables the first output stream interupt and the global interrupt + pub fn irq(&mut self) -> bool { + self.int_counter += 1; - let iss = self.num_input_streams(); - self.regs.intctl.write((1 << 31) | /* (1 << 30) |*/ (1 << iss)); - } + self.handle_interrupts() + } - pub fn irq(&mut self) -> bool { - self.int_counter += 1; + pub fn int_count(&self) -> usize { + self.int_counter + } - self.handle_interrupts() - } + pub fn read_node(&mut self, addr: WidgetAddr) -> HDANode { + let mut node = HDANode::new(); + let mut temp: u64; - pub fn int_count(&self) -> usize { - self.int_counter - } + node.addr = addr; - pub fn read_node(&mut self, addr: WidgetAddr) -> HDANode { - let mut node = HDANode::new(); - let mut temp:u64; + temp = self.cmd.cmd12(addr, 0xF00, 0x04); - node.addr = addr; + node.subnode_count = (temp & 0xff) as u16; + node.subnode_start = ((temp >> 16) & 0xff) as u16; - temp = self.cmd.cmd12( addr, 0xF00, 0x04); + if addr == (0, 0) { + return node; + } + temp = self.cmd.cmd12(addr, 0xF00, 0x04); - node.subnode_count = (temp & 0xff) as u16; - node.subnode_start = ((temp >> 16) & 0xff) as u16; + node.function_group_type = (temp & 0xff) as u8; - if addr == (0,0) { - return node; - } - temp = self.cmd.cmd12(addr, 0xF00, 0x04); + temp = self.cmd.cmd12(addr, 0xF00, 0x09); + node.capabilities = temp as u32; - node.function_group_type = (temp & 0xff) as u8; + temp = self.cmd.cmd12(addr, 0xF00, 0x0E); - temp = self.cmd.cmd12(addr, 0xF00, 0x09); - node.capabilities = temp as u32; + node.conn_list_len = (temp & 0xFF) as u8; - temp = self.cmd.cmd12(addr, 0xF00, 0x0E); + node.connections = self.node_get_connection_list(&node); - node.conn_list_len = (temp & 0xFF) as u8; + node.connection_default = self.cmd.cmd12(addr, 0xF01, 0x00) as u8; - node.connections = self.node_get_connection_list(&node); + node.config_default = self.cmd.cmd12(addr, 0xF1C, 0x00) as u32; - node.connection_default = self.cmd.cmd12(addr, 0xF01, 0x00) as u8; + node + } - node.config_default = self.cmd.cmd12(addr, 0xF1C, 0x00) as u32; + pub fn node_get_connection_list(&mut self, node: &HDANode) -> Vec { + let len_field: u8 = (self.cmd.cmd12(node.addr, 0xF00, 0x0E) & 0xFF) as u8; - node - } + // Highest bit is if addresses are represented in longer notation + // lower 7 is actual count - pub fn node_get_connection_list(&mut self, node: &HDANode) -> Vec { - let len_field: u8 = (self.cmd.cmd12(node.addr, 0xF00, 0x0E) & 0xFF) as u8; + let count: u8 = len_field & 0x7F; + let use_long_addr: bool = (len_field >> 7) & 0x1 == 1; - // Highest bit is if addresses are represented in longer notation - // lower 7 is actual count + let mut current: u8 = 0; - let count:u8 = len_field & 0x7F; - let use_long_addr: bool = (len_field >> 7) & 0x1 == 1; + let mut list = Vec::::new(); - let mut current: u8 = 0; + while current < count { + let response: u32 = (self.cmd.cmd12(node.addr, 0xF02, current) & 0xFFFFFFFF) as u32; + + if use_long_addr { + for i in 0..2 { + let addr_field = ((response >> (16 * i)) & 0xFFFF) as u16; + let addr = addr_field & 0x7FFF; + + if addr == 0 { + break; + } + + if (addr_field >> 15) & 0x1 == 0x1 { + for i in list.pop().unwrap().1..(addr + 1) { + list.push((node.addr.0, i)); + } + } else { + list.push((node.addr.0, addr)); + } + } + } else { + for i in 0..4 { + let addr_field = ((response >> (8 * i)) & 0xff) as u16; + let addr = addr_field & 0x7F; + + if addr == 0 { + break; + } + + if (addr_field >> 7) & 0x1 == 0x1 { + for i in list.pop().unwrap().1..(addr + 1) { + list.push((node.addr.0, i)); + } + } else { + list.push((node.addr.0, addr)); + } + } + } + + current = list.len() as u8; + } + + list + } + + pub fn enumerate(&mut self) { + self.output_pins.clear(); + self.input_pins.clear(); + + let codec: u8 = 0; + + let root = self.read_node((codec, 0)); + + log::debug!("{}", root); + + let root_count = root.subnode_count; + let root_start = root.subnode_start; + + //FIXME: So basically the way this is set up is to only support one codec and hopes the first one is an audio + for i in 0..root_count { + let afg = self.read_node((codec, root_start + i)); + log::debug!("{}", afg); + let afg_count = afg.subnode_count; + let afg_start = afg.subnode_start; + + for j in 0..afg_count { + let mut widget = self.read_node((codec, afg_start + j)); + widget.is_widget = true; + match widget.widget_type() { + HDAWidgetType::AudioOutput => self.outputs.push(widget.addr), + HDAWidgetType::AudioInput => self.inputs.push(widget.addr), + HDAWidgetType::BeepGenerator => self.beep_addr = widget.addr, + HDAWidgetType::PinComplex => { + let config = widget.configuration_default(); + if config.is_output() { + self.output_pins.push(widget.addr); + } else if config.is_input() { + self.input_pins.push(widget.addr); + } + } + _ => {} + } + + log::debug!("{}", widget); + self.widget_map.insert(widget.addr(), widget); + } + } + } + + pub fn find_best_output_pin(&mut self) -> Option { + let outs = &self.output_pins; + if outs.len() == 0 { + None + } else if outs.len() == 1 { + Some(outs[0]) + } else { + //TODO: change output based on "unsolicited response" interrupts + // Check for devices in this order: Headphone, Speaker, Line Out + for supported_device in &[DefaultDevice::HPOut, DefaultDevice::Speaker] { + for &out in outs { + let widget = self.widget_map.get(&out).unwrap(); + let cd = widget.configuration_default(); + if cd.sequence() == 0 && &cd.default_device() == supported_device { + // Check for jack detect bit + let pin_caps = self.cmd.cmd12(widget.addr, 0xF00, 0x0C); + if pin_caps & (1 << 2) != 0 { + // Check for presence + let pin_sense = self.cmd.cmd12(widget.addr, 0xF09, 0); + if pin_sense & (1 << 31) == 0 { + // Skip if nothing is plugged in + continue; + } + } + return Some(out); + } + } + } + + None + } + } + + pub fn find_path_to_dac(&self, addr: WidgetAddr) -> Option> { + let widget = self.widget_map.get(&addr).unwrap(); + if widget.widget_type() == HDAWidgetType::AudioOutput { + Some(vec![addr]) + } else { + let connection = widget.connections.get(widget.connection_default as usize)?; + let mut path = self.find_path_to_dac(*connection)?; + path.insert(0, addr); + Some(path) + } + } + + /* + Here we update the buffers and split them into 128 byte sub chunks + because each BufferDescriptorList needs to be 128 byte aligned, + this makes it so each of the streams can have up to 128/16 (8) buffer descriptors + */ + /* + Vec of a Vec was doing something weird and causing the driver to hang. + So now we have a set of variables instead. + + + Fixed? + */ + + pub fn update_sound_buffers(&mut self) { + /* + for i in 0..self.buffs.len(){ + for j in 0.. min(self.buffs[i].len(), 128/16 ) { + self.buff_desc[i * 128/16 + j].set_address(self.buffs[i][j].phys()); + self.buff_desc[i * 128/16 + j].set_length(self.buffs[i][j].length() as u32); + self.buff_desc[i * 128/16 + j].set_interrupt_on_complete(true); + } + }*/ + + let r = self.get_output_stream_descriptor(0).unwrap(); + + self.output_streams + .push(OutputStream::new(NUM_SUB_BUFFS, SUB_BUFF_SIZE, r)); + + let o = self.output_streams.get_mut(0).unwrap(); + + for i in 0..NUM_SUB_BUFFS { + self.buff_desc[i].set_address((o.phys() + o.block_size() * i) as u64); + self.buff_desc[i].set_length(o.block_size() as u32); + self.buff_desc[i].set_interrupt_on_complete(true); + } + } + + pub fn configure(&mut self) { + let outpin = self.find_best_output_pin().expect("IHDA: No output pins?!"); + + log::debug!("Best pin: {:01X}:{:02X}", outpin.0, outpin.1); + + let path = self.find_path_to_dac(outpin).unwrap(); + + let dac = *path.last().unwrap(); + let pin = *path.first().unwrap(); + + log::debug!("Path to DAC: {:X?}", path); + + // Set power state 0 (on) for all widgets in path + for &addr in &path { + self.set_power_state(addr, 0); + } + + // Pin enable (0x80 = headphone amp enable, 0x40 = output enable) + self.cmd.cmd12(pin, 0x707, 0xC0); + + // EAPD enable + self.cmd.cmd12(pin, 0x70C, 2); + + // Set DAC stream and channel + self.set_stream_channel(dac, 1, 0); + + self.update_sound_buffers(); + + log::debug!( + "Supported Formats: {:08X}", + self.get_supported_formats((0, 0x1)) + ); + log::debug!("Capabilities: {:08X}", self.get_capabilities(path[0])); + + // Create output stream + let output = self.get_output_stream_descriptor(0).unwrap(); + output.set_address(self.buff_desc.physical()); + output.set_pcm_format(&super::SR_44_1, BitsPerSample::Bits16, 2); + output.set_cyclic_buffer_length((NUM_SUB_BUFFS * SUB_BUFF_SIZE) as u32); // number of bytes + output.set_stream_number(1); + output.set_last_valid_index((NUM_SUB_BUFFS - 1) as u16); + output.set_interrupt_on_completion(true); + + // Set DAC converter format + self.set_converter_format(dac, &super::SR_44_1, BitsPerSample::Bits16, 2); + + // Get DAC converter format + //TODO: should validate? + self.cmd.cmd12(dac, 0xA00, 0); + + // Unmute and set gain to 0db for input and output amplifiers on all widgets in path + for &addr in &path { + // Read widget capabilities + let caps = self.cmd.cmd12(addr, 0xF00, 0x09); - let mut list = Vec::::new(); + //TODO: do we need to set any other indexes? + let left = true; + let right = true; + let index = 0; + let mute = false; - while current < count { + // Check for input amp + if (caps & (1 << 1)) != 0 { + // Read input capabilities + let in_caps = self.cmd.cmd12(addr, 0xF00, 0x0D); + let in_gain = (in_caps & 0x7f) as u8; + // Set input gain + let output = false; + let input = true; + self.set_amplifier_gain_mute( + addr, output, input, left, right, index, mute, in_gain, + ); + log::debug!("Set {:X?} input gain to 0x{:X}", addr, in_gain); + } - let response: u32 = (self.cmd.cmd12(node.addr, 0xF02, current) & 0xFFFFFFFF) as u32; + // Check for output amp + if (caps & (1 << 2)) != 0 { + // Read output capabilities + let out_caps = self.cmd.cmd12(addr, 0xF00, 0x12); + let out_gain = (out_caps & 0x7f) as u8; + // Set output gain + let output = true; + let input = false; + self.set_amplifier_gain_mute( + addr, output, input, left, right, index, mute, out_gain, + ); + log::debug!("Set {:X?} output gain to 0x{:X}", addr, out_gain); + } + } - if use_long_addr { - for i in 0..2 { - let addr_field = ((response >> (16 * i)) & 0xFFFF) as u16; - let addr = addr_field & 0x7FFF; + //TODO: implement hda-verb? - if addr == 0 { break; } + output.run(); + log::debug!("Waiting for output 0 to start running..."); + while output.control() & (1 << 1) == 0 { + //TODO: relax + } - if (addr_field >> 15) & 0x1 == 0x1 { - for i in list.pop().unwrap().1 .. (addr + 1) { - list.push((node.addr.0, i)); - } - } else { - list.push((node.addr.0, addr)); - } - } - - } else { - for i in 0..4 { - let addr_field = ((response >> (8 * i)) & 0xff) as u16; - let addr = addr_field & 0x7F; - - if addr == 0 { break; } - - if (addr_field >> 7) & 0x1 == 0x1 { - for i in list.pop().unwrap().1 .. (addr + 1) { - list.push((node.addr.0, i)); - } - } else { - list.push((node.addr.0, addr)); - } - } - } - - current = list.len() as u8; - } - - list - } - - pub fn enumerate(&mut self) { - self.output_pins.clear(); - self.input_pins.clear(); - - let codec:u8 = 0; - - let root = self.read_node((codec,0)); - - log::debug!("{}", root); - - let root_count = root.subnode_count; - let root_start = root.subnode_start; - - //FIXME: So basically the way this is set up is to only support one codec and hopes the first one is an audio - for i in 0..root_count { - let afg = self.read_node((codec, root_start + i)); - log::debug!("{}", afg); - let afg_count = afg.subnode_count; - let afg_start = afg.subnode_start; - - for j in 0..afg_count { - let mut widget = self.read_node((codec, afg_start + j)); - widget.is_widget = true; - match widget.widget_type() { - HDAWidgetType::AudioOutput => {self.outputs.push(widget.addr)}, - HDAWidgetType::AudioInput => {self.inputs.push(widget.addr)}, - HDAWidgetType::BeepGenerator => {self.beep_addr = widget.addr }, - HDAWidgetType::PinComplex => { - let config = widget.configuration_default(); - if config.is_output() { - self.output_pins.push(widget.addr); - } else if config.is_input() { - self.input_pins.push(widget.addr); - } - }, - _ => {}, - } - - log::debug!("{}", widget); - self.widget_map.insert(widget.addr(), widget); - } - } - } - - pub fn find_best_output_pin(&mut self) -> Option{ - let outs = &self.output_pins; - if outs.len() == 0 { - None - } else if outs.len() == 1 { - Some(outs[0]) - } else { - //TODO: change output based on "unsolicited response" interrupts - // Check for devices in this order: Headphone, Speaker, Line Out - for supported_device in &[ - DefaultDevice::HPOut, - DefaultDevice::Speaker, - ] { - for &out in outs { - let widget = self.widget_map.get(&out).unwrap(); - let cd = widget.configuration_default(); - if cd.sequence() == 0 && &cd.default_device() == supported_device { - // Check for jack detect bit - let pin_caps = self.cmd.cmd12(widget.addr, 0xF00, 0x0C); - if pin_caps & (1 << 2) != 0 { - // Check for presence - let pin_sense = self.cmd.cmd12(widget.addr, 0xF09, 0); - if pin_sense & (1 << 31) == 0 { - // Skip if nothing is plugged in - continue; - } - } - return Some(out); - } - } - } - - None - } - } - - pub fn find_path_to_dac(&self, addr: WidgetAddr) -> Option>{ - let widget = self.widget_map.get(&addr).unwrap(); - if widget.widget_type() == HDAWidgetType::AudioOutput { - Some(vec![addr]) - } else { - let connection = widget.connections.get(widget.connection_default as usize)?; - let mut path = self.find_path_to_dac(*connection)?; - path.insert(0, addr); - Some(path) - } - } - - /* - Here we update the buffers and split them into 128 byte sub chunks - because each BufferDescriptorList needs to be 128 byte aligned, - this makes it so each of the streams can have up to 128/16 (8) buffer descriptors - */ - /* - Vec of a Vec was doing something weird and causing the driver to hang. - So now we have a set of variables instead. - - - Fixed? - */ - - pub fn update_sound_buffers(&mut self) { - /* - for i in 0..self.buffs.len(){ - for j in 0.. min(self.buffs[i].len(), 128/16 ) { - self.buff_desc[i * 128/16 + j].set_address(self.buffs[i][j].phys()); - self.buff_desc[i * 128/16 + j].set_length(self.buffs[i][j].length() as u32); - self.buff_desc[i * 128/16 + j].set_interrupt_on_complete(true); - } - }*/ - - let r = self.get_output_stream_descriptor(0).unwrap(); - - self.output_streams.push(OutputStream::new(NUM_SUB_BUFFS, SUB_BUFF_SIZE, r)); - - let o = self.output_streams.get_mut(0).unwrap(); - - for i in 0..NUM_SUB_BUFFS { - self.buff_desc[i].set_address((o.phys() + o.block_size() * i) as u64); - self.buff_desc[i].set_length(o.block_size() as u32); - self.buff_desc[i].set_interrupt_on_complete(true); - } - } - - pub fn configure(&mut self) { - let outpin = self.find_best_output_pin().expect("IHDA: No output pins?!"); - - log::debug!("Best pin: {:01X}:{:02X}", outpin.0, outpin.1); - - let path = self.find_path_to_dac(outpin).unwrap(); - - let dac = *path.last().unwrap(); - let pin = *path.first().unwrap(); - - log::debug!("Path to DAC: {:X?}", path); - - // Set power state 0 (on) for all widgets in path - for &addr in &path { - self.set_power_state(addr, 0); - } - - // Pin enable (0x80 = headphone amp enable, 0x40 = output enable) - self.cmd.cmd12(pin, 0x707, 0xC0); - - // EAPD enable - self.cmd.cmd12(pin, 0x70C, 2); - - // Set DAC stream and channel - self.set_stream_channel(dac, 1, 0); - - self.update_sound_buffers(); - - log::debug!("Supported Formats: {:08X}", self.get_supported_formats((0,0x1))); - log::debug!("Capabilities: {:08X}", self.get_capabilities(path[0])); - - // Create output stream - let output = self.get_output_stream_descriptor(0).unwrap(); - output.set_address(self.buff_desc.physical()); - output.set_pcm_format(&super::SR_44_1, BitsPerSample::Bits16, 2); - output.set_cyclic_buffer_length((NUM_SUB_BUFFS * SUB_BUFF_SIZE) as u32); // number of bytes - output.set_stream_number(1); - output.set_last_valid_index((NUM_SUB_BUFFS - 1) as u16); - output.set_interrupt_on_completion(true); - - // Set DAC converter format - self.set_converter_format(dac, &super::SR_44_1, BitsPerSample::Bits16, 2); - - // Get DAC converter format - //TODO: should validate? - self.cmd.cmd12(dac, 0xA00, 0); - - // Unmute and set gain to 0db for input and output amplifiers on all widgets in path - for &addr in &path { - // Read widget capabilities - let caps = self.cmd.cmd12(addr, 0xF00, 0x09); - - //TODO: do we need to set any other indexes? - let left = true; - let right = true; - let index = 0; - let mute = false; - - // Check for input amp - if (caps & (1 << 1)) != 0 { - // Read input capabilities - let in_caps = self.cmd.cmd12(addr, 0xF00, 0x0D); - let in_gain = (in_caps & 0x7f) as u8; - // Set input gain - let output = false; - let input = true; - self.set_amplifier_gain_mute(addr, output, input, left, right, index, mute, in_gain); - log::debug!("Set {:X?} input gain to 0x{:X}", addr, in_gain); - } - - // Check for output amp - if (caps & (1 << 2)) != 0 { - // Read output capabilities - let out_caps = self.cmd.cmd12(addr, 0xF00, 0x12); - let out_gain = (out_caps & 0x7f) as u8; - // Set output gain - let output = true; - let input = false; - self.set_amplifier_gain_mute(addr, output, input, left, right, index, mute, out_gain); - log::debug!("Set {:X?} output gain to 0x{:X}", addr, out_gain); - } - } - - //TODO: implement hda-verb? - - output.run(); - log::debug!("Waiting for output 0 to start running..."); - while output.control() & (1 << 1) == 0 { - //TODO: relax - } - - log::debug!("Output 0 CONTROL {:#X} STATUS {:#X} POS {:#X}", output.control(), output.status(), output.link_position()); - } - /* - - pub fn configure_vbox(&mut self) { - - let outpin = self.find_best_output_pin().expect("IHDA: No output pins?!"); - - log::debug!("Best pin: {:01X}:{:02X}", outpin.0, outpin.1); - - let path = self.find_path_to_dac(outpin).unwrap(); - log::debug!("Path to DAC: {:X?}", path); - - // Pin enable - self.cmd.cmd12((0,0xC), 0x707, 0x40); - - - // EAPD enable - self.cmd.cmd12((0,0xC), 0x70C, 2); - - self.set_stream_channel((0,0x3), 1, 0); - - self.update_sound_buffers(); - - - log::debug!("Supported Formats: {:08X}", self.get_supported_formats((0,0x1))); - log::debug!("Capabilities: {:08X}", self.get_capabilities((0,0x1))); - - let output = self.get_output_stream_descriptor(0).unwrap(); - - output.set_address(self.buff_desc_phys); - - output.set_pcm_format(&super::SR_44_1, BitsPerSample::Bits16, 2); - output.set_cyclic_buffer_length((NUM_SUB_BUFFS * SUB_BUFF_SIZE) as u32); - output.set_stream_number(1); - output.set_last_valid_index((NUM_SUB_BUFFS - 1) as u16); - output.set_interrupt_on_completion(true); - - - self.set_power_state((0,0x3), 0); // Power state 0 is fully on - self.set_converter_format((0,0x3), &super::SR_44_1, BitsPerSample::Bits16, 2); - - - self.cmd.cmd12((0,0x3), 0xA00, 0); - - // Unmute and set gain for pin complex and DAC - self.set_amplifier_gain_mute((0,0x3), true, true, true, true, 0, false, 0x7f); - self.set_amplifier_gain_mute((0,0xC), true, true, true, true, 0, false, 0x7f); - - output.run(); - - self.beep(1); - - } - - */ - - pub fn dump_codec(&self, codec:u8) -> String { - let mut string = String::new(); - - for (_, widget) in self.widget_map.iter() { - let _ = writeln!(string, "{}", widget); - } - - string - } - - // BEEP!! - pub fn beep(&mut self, div:u8) { - let addr = self.beep_addr; - if addr != (0,0) { - let _ = self.cmd.cmd12(addr, 0xF0A, div); - } - } - - pub fn read_beep(&mut self) -> u8 { - let addr = self.beep_addr; - if addr != (0,0) { - self.cmd.cmd12(addr, 0x70A, 0) as u8 - }else{ - 0 - } - } - - pub fn reset_controller(&mut self) -> bool { - self.regs.statests.write(0xFFFF); - - // 3.3.7 - self.regs.gctl.writef(CRST, false); - loop { - if ! self.regs.gctl.readf(CRST) { - break; - } - } - self.regs.gctl.writef(CRST, true); - loop { - if self.regs.gctl.readf(CRST) { - break; - } - } - - let mut ticks:u32 = 0; - while self.regs.statests.read() == 0 { - ticks += 1; - if ticks > 10000 { break;} - - } - - let statests = self.regs.statests.read(); - log::debug!("Statests: {:04X}", statests); - - for i in 0..15 { - if (statests >> i) & 0x1 == 1 { - self.codecs.push(i as CodecAddr); - } - } - true - - } - - pub fn num_output_streams(&self) -> usize{ - let gcap = self.regs.gcap.read(); - ((gcap >> 12) & 0xF) as usize - } - - pub fn num_input_streams(&self) -> usize{ - let gcap = self.regs.gcap.read(); - ((gcap >> 8) & 0xF) as usize - } - - pub fn num_bidirectional_streams(&self) -> usize{ - let gcap = self.regs.gcap.read(); - ((gcap >> 3) & 0xF) as usize - } - - pub fn num_serial_data_out(&self) -> usize{ - let gcap = self.regs.gcap.read(); - ((gcap >> 1) & 0x3) as usize - } - - pub fn info(&self) { - log::info!("Intel HD Audio Version {}.{}", self.regs.vmaj.read(), self.regs.vmin.read()); - log::debug!("IHDA: Input Streams: {}", self.num_input_streams()); - log::debug!("IHDA: Output Streams: {}", self.num_output_streams()); - log::debug!("IHDA: Bidirectional Streams: {}", self.num_bidirectional_streams()); - log::debug!("IHDA: Serial Data Outputs: {}", self.num_serial_data_out()); - log::debug!("IHDA: 64-Bit: {}", self.regs.gcap.read() & 1 == 1); - } - - fn get_input_stream_descriptor(&self, index: usize) -> Option<&'static mut StreamDescriptorRegs> { - unsafe { - if index < self.num_input_streams() { - Some(&mut *((self.base + 0x80 + index * 0x20) as *mut StreamDescriptorRegs)) - }else{ - None - } - } - } - - fn get_output_stream_descriptor(&self, index: usize) -> Option<&'static mut StreamDescriptorRegs> { - unsafe { - if index < self.num_output_streams() { - Some(&mut *((self.base + 0x80 + - self.num_input_streams() * 0x20 + - index * 0x20) as *mut StreamDescriptorRegs)) - }else{ - None - } - } - } - - - fn get_bidirectional_stream_descriptor(&self, index: usize) -> Option<&'static mut StreamDescriptorRegs> { - unsafe { - if index < self.num_bidirectional_streams() { - Some(&mut *((self.base + 0x80 + - self.num_input_streams() * 0x20 + - self.num_output_streams() * 0x20 + - index * 0x20) as *mut StreamDescriptorRegs)) - }else{ - None - } - } - } - - fn set_dma_position_buff_addr(&mut self, addr: u64) { - let addr_val = addr & !0x7F; - self.regs.dplbase.write((addr_val & 0xFFFFFFFF) as u32); - self.regs.dpubase.write((addr_val >> 32) as u32); - } - - - fn set_stream_channel(&mut self, addr: WidgetAddr, stream: u8, channel:u8) { - let val = ((stream & 0xF) << 4) | (channel & 0xF); - self.cmd.cmd12(addr, 0x706, val); - } - - fn set_power_state(&mut self, addr:WidgetAddr, state:u8) { - self.cmd.cmd12(addr, 0x705, state & 0xF) as u32; - } - - fn get_supported_formats(&mut self, addr: WidgetAddr) -> u32 { - self.cmd.cmd12(addr, 0xF00, 0x0A) as u32 - } - - fn get_capabilities(&mut self, addr: WidgetAddr) -> u32 { - self.cmd.cmd12(addr, 0xF00, 0x09) as u32 - } - - fn set_converter_format(&mut self, addr:WidgetAddr, sr: &super::SampleRate, bps: BitsPerSample, channels:u8) { - let fmt = super::format_to_u16(sr, bps, channels); - self.cmd.cmd4(addr, 0x2, fmt); - } - - fn set_amplifier_gain_mute(&mut self, addr: WidgetAddr, output:bool, input:bool, left:bool, right:bool, index:u8, mute:bool, gain: u8) { - let mut payload: u16 = 0; - - if output { payload |= 1 << 15; } - if input { payload |= 1 << 14; } - if left { payload |= 1 << 13; } - if right { payload |= 1 << 12; } - if mute { payload |= 1 << 7; } - payload |= ((index as u16) & 0x0F) << 8; - payload |= (gain as u16) & 0x7F; - - self.cmd.cmd4(addr, 0x3, payload); - } - - pub fn write_to_output(&mut self, index:u8, buf: &[u8]) -> Result> { - let output = self.get_output_stream_descriptor(index as usize).unwrap(); - let os = self.output_streams.get_mut(index as usize).unwrap(); - - //let sample_size:usize = output.sample_size(); - let open_block = (output.link_position() as usize) / os.block_size(); - - //log::trace!("Status: {:02X} Pos: {:08X} Output CTL: {:06X}", output.status(), output.link_position(), output.control()); - - if os.current_block() == (open_block + 3) % NUM_SUB_BUFFS { - // Block if we already are 3 buffers ahead - Ok(None) - } else { - os.write_block(buf).map(|count| Some(count)) - } - } - - pub fn handle_interrupts(&mut self) -> bool { - let intsts = self.regs.intsts.read(); - if ((intsts >> 31) & 1) == 1 { // Global Interrupt Status - if ((intsts >> 30) & 1) == 1 { // Controller Interrupt Status - self.handle_controller_interrupt(); - } - - let sis = intsts & 0x3FFFFFFF; - if sis != 0 { - self.handle_stream_interrupts(sis); - } - } - intsts != 0 - } - - pub fn handle_controller_interrupt(&mut self) { - - } - - pub fn handle_stream_interrupts(&mut self, sis: u32) { - let iss = self.num_input_streams(); - let oss = self.num_output_streams(); - let bss = self.num_bidirectional_streams(); - - for i in 0..iss { - if ((sis >> i) & 1 ) == 1 { - let input = self.get_input_stream_descriptor(i).unwrap(); - input.clear_interrupts(); - } - } - - for i in 0..oss { - if ((sis >> (i + iss)) & 1 ) == 1 { - let output = self.get_output_stream_descriptor(i).unwrap(); - output.clear_interrupts(); - } - } - - for i in 0..bss { - if ((sis >> (i + iss + oss)) & 1 ) == 1 { - let bid = self.get_bidirectional_stream_descriptor(i).unwrap(); - bid.clear_interrupts(); - } - } - } - - fn validate_path(&mut self, path: &Vec<&str>) -> bool { - log::debug!("Path: {:?}", path); - let mut it = path.iter(); - match it.next() { - Some(card_str) if (*card_str).starts_with("card") => { - match usize::from_str_radix(&(*card_str)[4..], 10) { - Ok(card_num) => { - log::debug!("Card# {}", card_num); - match it.next() { - Some(codec_str) if (*codec_str).starts_with("codec#") => { - match usize::from_str_radix(&(*codec_str)[6..], 10) { - Ok(_codec_num) => { - //let id = self.next_id.fetch_add(1, Ordering::SeqCst); - //self.handles.lock().insert(id, Handle::Disk(disk.clone(), 0)); - true - - }, - _ => false, - } - }, - Some(pcmout_str) if (*pcmout_str).starts_with("pcmout") => { - match usize::from_str_radix(&(*pcmout_str)[6..], 10) { - Ok(pcmout_num) => { - log::debug!("pcmout {}", pcmout_num); - true - }, - _ => false, - } - }, - Some(pcmin_str) if (*pcmin_str).starts_with("pcmin") => { - match usize::from_str_radix(&(*pcmin_str)[6..], 10) { - Ok(pcmin_num) => { - log::debug!("pcmin {}", pcmin_num); - true - }, - _ => false, - } - }, - _ => false, - } - }, - _ => false, - } - }, - Some(cards_str) if *cards_str == "cards" => { - true - }, - _ => false, - } - } + log::debug!( + "Output 0 CONTROL {:#X} STATUS {:#X} POS {:#X}", + output.control(), + output.status(), + output.link_position() + ); + } + /* + + pub fn configure_vbox(&mut self) { + + let outpin = self.find_best_output_pin().expect("IHDA: No output pins?!"); + + log::debug!("Best pin: {:01X}:{:02X}", outpin.0, outpin.1); + + let path = self.find_path_to_dac(outpin).unwrap(); + log::debug!("Path to DAC: {:X?}", path); + + // Pin enable + self.cmd.cmd12((0,0xC), 0x707, 0x40); + + + // EAPD enable + self.cmd.cmd12((0,0xC), 0x70C, 2); + + self.set_stream_channel((0,0x3), 1, 0); + + self.update_sound_buffers(); + + + log::debug!("Supported Formats: {:08X}", self.get_supported_formats((0,0x1))); + log::debug!("Capabilities: {:08X}", self.get_capabilities((0,0x1))); + + let output = self.get_output_stream_descriptor(0).unwrap(); + + output.set_address(self.buff_desc_phys); + + output.set_pcm_format(&super::SR_44_1, BitsPerSample::Bits16, 2); + output.set_cyclic_buffer_length((NUM_SUB_BUFFS * SUB_BUFF_SIZE) as u32); + output.set_stream_number(1); + output.set_last_valid_index((NUM_SUB_BUFFS - 1) as u16); + output.set_interrupt_on_completion(true); + + + self.set_power_state((0,0x3), 0); // Power state 0 is fully on + self.set_converter_format((0,0x3), &super::SR_44_1, BitsPerSample::Bits16, 2); + + + self.cmd.cmd12((0,0x3), 0xA00, 0); + + // Unmute and set gain for pin complex and DAC + self.set_amplifier_gain_mute((0,0x3), true, true, true, true, 0, false, 0x7f); + self.set_amplifier_gain_mute((0,0xC), true, true, true, true, 0, false, 0x7f); + + output.run(); + + self.beep(1); + + } + + */ + + pub fn dump_codec(&self, codec: u8) -> String { + let mut string = String::new(); + + for (_, widget) in self.widget_map.iter() { + let _ = writeln!(string, "{}", widget); + } + + string + } + + // BEEP!! + pub fn beep(&mut self, div: u8) { + let addr = self.beep_addr; + if addr != (0, 0) { + let _ = self.cmd.cmd12(addr, 0xF0A, div); + } + } + + pub fn read_beep(&mut self) -> u8 { + let addr = self.beep_addr; + if addr != (0, 0) { + self.cmd.cmd12(addr, 0x70A, 0) as u8 + } else { + 0 + } + } + + pub fn reset_controller(&mut self) -> bool { + self.regs.statests.write(0xFFFF); + + // 3.3.7 + self.regs.gctl.writef(CRST, false); + loop { + if !self.regs.gctl.readf(CRST) { + break; + } + } + self.regs.gctl.writef(CRST, true); + loop { + if self.regs.gctl.readf(CRST) { + break; + } + } + + let mut ticks: u32 = 0; + while self.regs.statests.read() == 0 { + ticks += 1; + if ticks > 10000 { + break; + } + } + + let statests = self.regs.statests.read(); + log::debug!("Statests: {:04X}", statests); + + for i in 0..15 { + if (statests >> i) & 0x1 == 1 { + self.codecs.push(i as CodecAddr); + } + } + true + } + + pub fn num_output_streams(&self) -> usize { + let gcap = self.regs.gcap.read(); + ((gcap >> 12) & 0xF) as usize + } + + pub fn num_input_streams(&self) -> usize { + let gcap = self.regs.gcap.read(); + ((gcap >> 8) & 0xF) as usize + } + + pub fn num_bidirectional_streams(&self) -> usize { + let gcap = self.regs.gcap.read(); + ((gcap >> 3) & 0xF) as usize + } + + pub fn num_serial_data_out(&self) -> usize { + let gcap = self.regs.gcap.read(); + ((gcap >> 1) & 0x3) as usize + } + + pub fn info(&self) { + log::info!( + "Intel HD Audio Version {}.{}", + self.regs.vmaj.read(), + self.regs.vmin.read() + ); + log::debug!("IHDA: Input Streams: {}", self.num_input_streams()); + log::debug!("IHDA: Output Streams: {}", self.num_output_streams()); + log::debug!( + "IHDA: Bidirectional Streams: {}", + self.num_bidirectional_streams() + ); + log::debug!("IHDA: Serial Data Outputs: {}", self.num_serial_data_out()); + log::debug!("IHDA: 64-Bit: {}", self.regs.gcap.read() & 1 == 1); + } + + fn get_input_stream_descriptor( + &self, + index: usize, + ) -> Option<&'static mut StreamDescriptorRegs> { + unsafe { + if index < self.num_input_streams() { + Some(&mut *((self.base + 0x80 + index * 0x20) as *mut StreamDescriptorRegs)) + } else { + None + } + } + } + + fn get_output_stream_descriptor( + &self, + index: usize, + ) -> Option<&'static mut StreamDescriptorRegs> { + unsafe { + if index < self.num_output_streams() { + Some( + &mut *((self.base + 0x80 + self.num_input_streams() * 0x20 + index * 0x20) + as *mut StreamDescriptorRegs), + ) + } else { + None + } + } + } + + fn get_bidirectional_stream_descriptor( + &self, + index: usize, + ) -> Option<&'static mut StreamDescriptorRegs> { + unsafe { + if index < self.num_bidirectional_streams() { + Some( + &mut *((self.base + + 0x80 + + self.num_input_streams() * 0x20 + + self.num_output_streams() * 0x20 + + index * 0x20) as *mut StreamDescriptorRegs), + ) + } else { + None + } + } + } + + fn set_dma_position_buff_addr(&mut self, addr: u64) { + let addr_val = addr & !0x7F; + self.regs.dplbase.write((addr_val & 0xFFFFFFFF) as u32); + self.regs.dpubase.write((addr_val >> 32) as u32); + } + + fn set_stream_channel(&mut self, addr: WidgetAddr, stream: u8, channel: u8) { + let val = ((stream & 0xF) << 4) | (channel & 0xF); + self.cmd.cmd12(addr, 0x706, val); + } + + fn set_power_state(&mut self, addr: WidgetAddr, state: u8) { + self.cmd.cmd12(addr, 0x705, state & 0xF) as u32; + } + + fn get_supported_formats(&mut self, addr: WidgetAddr) -> u32 { + self.cmd.cmd12(addr, 0xF00, 0x0A) as u32 + } + + fn get_capabilities(&mut self, addr: WidgetAddr) -> u32 { + self.cmd.cmd12(addr, 0xF00, 0x09) as u32 + } + + fn set_converter_format( + &mut self, + addr: WidgetAddr, + sr: &super::SampleRate, + bps: BitsPerSample, + channels: u8, + ) { + let fmt = super::format_to_u16(sr, bps, channels); + self.cmd.cmd4(addr, 0x2, fmt); + } + + fn set_amplifier_gain_mute( + &mut self, + addr: WidgetAddr, + output: bool, + input: bool, + left: bool, + right: bool, + index: u8, + mute: bool, + gain: u8, + ) { + let mut payload: u16 = 0; + + if output { + payload |= 1 << 15; + } + if input { + payload |= 1 << 14; + } + if left { + payload |= 1 << 13; + } + if right { + payload |= 1 << 12; + } + if mute { + payload |= 1 << 7; + } + payload |= ((index as u16) & 0x0F) << 8; + payload |= (gain as u16) & 0x7F; + + self.cmd.cmd4(addr, 0x3, payload); + } + + pub fn write_to_output(&mut self, index: u8, buf: &[u8]) -> Result> { + let output = self.get_output_stream_descriptor(index as usize).unwrap(); + let os = self.output_streams.get_mut(index as usize).unwrap(); + + //let sample_size:usize = output.sample_size(); + let open_block = (output.link_position() as usize) / os.block_size(); + + //log::trace!("Status: {:02X} Pos: {:08X} Output CTL: {:06X}", output.status(), output.link_position(), output.control()); + + if os.current_block() == (open_block + 3) % NUM_SUB_BUFFS { + // Block if we already are 3 buffers ahead + Ok(None) + } else { + os.write_block(buf).map(|count| Some(count)) + } + } + + pub fn handle_interrupts(&mut self) -> bool { + let intsts = self.regs.intsts.read(); + if ((intsts >> 31) & 1) == 1 { + // Global Interrupt Status + if ((intsts >> 30) & 1) == 1 { + // Controller Interrupt Status + self.handle_controller_interrupt(); + } + + let sis = intsts & 0x3FFFFFFF; + if sis != 0 { + self.handle_stream_interrupts(sis); + } + } + intsts != 0 + } + + pub fn handle_controller_interrupt(&mut self) {} + + pub fn handle_stream_interrupts(&mut self, sis: u32) { + let iss = self.num_input_streams(); + let oss = self.num_output_streams(); + let bss = self.num_bidirectional_streams(); + + for i in 0..iss { + if ((sis >> i) & 1) == 1 { + let input = self.get_input_stream_descriptor(i).unwrap(); + input.clear_interrupts(); + } + } + + for i in 0..oss { + if ((sis >> (i + iss)) & 1) == 1 { + let output = self.get_output_stream_descriptor(i).unwrap(); + output.clear_interrupts(); + } + } + + for i in 0..bss { + if ((sis >> (i + iss + oss)) & 1) == 1 { + let bid = self.get_bidirectional_stream_descriptor(i).unwrap(); + bid.clear_interrupts(); + } + } + } + + fn validate_path(&mut self, path: &Vec<&str>) -> bool { + log::debug!("Path: {:?}", path); + let mut it = path.iter(); + match it.next() { + Some(card_str) if (*card_str).starts_with("card") => { + match usize::from_str_radix(&(*card_str)[4..], 10) { + Ok(card_num) => { + log::debug!("Card# {}", card_num); + match it.next() { + Some(codec_str) if (*codec_str).starts_with("codec#") => { + match usize::from_str_radix(&(*codec_str)[6..], 10) { + Ok(_codec_num) => { + //let id = self.next_id.fetch_add(1, Ordering::SeqCst); + //self.handles.lock().insert(id, Handle::Disk(disk.clone(), 0)); + true + } + _ => false, + } + } + Some(pcmout_str) if (*pcmout_str).starts_with("pcmout") => { + match usize::from_str_radix(&(*pcmout_str)[6..], 10) { + Ok(pcmout_num) => { + log::debug!("pcmout {}", pcmout_num); + true + } + _ => false, + } + } + Some(pcmin_str) if (*pcmin_str).starts_with("pcmin") => { + match usize::from_str_radix(&(*pcmin_str)[6..], 10) { + Ok(pcmin_num) => { + log::debug!("pcmin {}", pcmin_num); + true + } + _ => false, + } + } + _ => false, + } + } + _ => false, + } + } + Some(cards_str) if *cards_str == "cards" => true, + _ => false, + } + } } - impl Drop for IntelHDA { - fn drop(&mut self) { - log::info!("IHDA: Deallocating IHDA driver."); - - } + fn drop(&mut self) { + log::info!("IHDA: Deallocating IHDA driver."); + } } impl SchemeBlockMut for IntelHDA { - fn open(&mut self, path: &str, _flags: usize, uid: u32, _gid: u32) -> Result> { - //let path: Vec<&str>; - /* - match str::from_utf8(_path) { - Ok(p) => { - path = p.split("/").collect(); - if !self.validate_path(&path) { - return Err(Error::new(EINVAL)); + fn open(&mut self, path: &str, _flags: usize, uid: u32, _gid: u32) -> Result> { + //let path: Vec<&str>; + /* + match str::from_utf8(_path) { + Ok(p) => { + path = p.split("/").collect(); + if !self.validate_path(&path) { + return Err(Error::new(EINVAL)); - }, - Err(_) => {return Err(Error::new(EINVAL));}, - }*/ + }, + Err(_) => {return Err(Error::new(EINVAL));}, + }*/ - // TODO: - if uid == 0 { - let handle = match path.trim_matches('/') { - //TODO: allow multiple codecs - "codec" => Handle::StrBuf(self.dump_codec(0).into_bytes(), 0), - _ => Handle::Todo, - }; - let id = self.next_id.fetch_add(1, Ordering::SeqCst); - self.handles.lock().insert(id, handle); - Ok(Some(id)) - } else { - Err(Error::new(EACCES)) - } - } + // TODO: + if uid == 0 { + let handle = match path.trim_matches('/') { + //TODO: allow multiple codecs + "codec" => Handle::StrBuf(self.dump_codec(0).into_bytes(), 0), + _ => Handle::Todo, + }; + let id = self.next_id.fetch_add(1, Ordering::SeqCst); + self.handles.lock().insert(id, handle); + Ok(Some(id)) + } else { + Err(Error::new(EACCES)) + } + } - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result> { + fn read(&mut self, id: usize, buf: &mut [u8]) -> Result> { let mut handles = self.handles.lock(); match *handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::StrBuf(ref strbuf, ref mut size) => { - let mut i = 0; - while i < buf.len() && *size < strbuf.len() { - buf[i] = strbuf[*size]; - i += 1; - *size += 1; - } - Ok(Some(i)) - }, - _ => Err(Error::new(EBADF)), - } - } - - fn write(&mut self, id: usize, buf: &[u8]) -> Result> { - let index = { - let mut handles = self.handles.lock(); - match handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::Todo => 0, - _ => return Err(Error::new(EBADF)), - } - }; - - //log::info!("Int count: {}", self.int_counter); - - self.write_to_output(index, buf) - } - - fn seek(&mut self, id: usize, pos: isize, whence: usize) -> Result> { - let pos = pos as usize; - let mut handles = self.handles.lock(); - match *handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::StrBuf(ref mut strbuf, ref mut size) => { - let len = strbuf.len() as usize; - *size = match whence { - SEEK_SET => cmp::min(len, pos), - SEEK_CUR => cmp::max(0, cmp::min(len as isize, *size 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(Some(*size as isize)) - }, - - _ => Err(Error::new(EINVAL)), + Handle::StrBuf(ref strbuf, ref mut size) => { + let mut i = 0; + while i < buf.len() && *size < strbuf.len() { + buf[i] = strbuf[*size]; + i += 1; + *size += 1; + } + Ok(Some(i)) + } + _ => Err(Error::new(EBADF)), } - } + } + + fn write(&mut self, id: usize, buf: &[u8]) -> Result> { + let index = { + let mut handles = self.handles.lock(); + match handles.get_mut(&id).ok_or(Error::new(EBADF))? { + Handle::Todo => 0, + _ => return Err(Error::new(EBADF)), + } + }; + + //log::info!("Int count: {}", self.int_counter); + + self.write_to_output(index, buf) + } + + fn seek(&mut self, id: usize, pos: isize, whence: usize) -> Result> { + let pos = pos as usize; + let mut handles = self.handles.lock(); + match *handles.get_mut(&id).ok_or(Error::new(EBADF))? { + Handle::StrBuf(ref mut strbuf, ref mut size) => { + let len = strbuf.len() as usize; + *size = match whence { + SEEK_SET => cmp::min(len, pos), + SEEK_CUR => { + cmp::max(0, cmp::min(len as isize, *size 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(Some(*size as isize)) + } + + _ => Err(Error::new(EINVAL)), + } + } fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result> { let mut handles = self.handles.lock(); @@ -989,8 +1051,11 @@ impl SchemeBlockMut for IntelHDA { Ok(Some(i)) } - fn close(&mut self, id: usize) -> Result> { - let mut handles = self.handles.lock(); - handles.remove(&id).ok_or(Error::new(EBADF)).and(Ok(Some(0))) - } + fn close(&mut self, id: usize) -> Result> { + let mut handles = self.handles.lock(); + handles + .remove(&id) + .ok_or(Error::new(EBADF)) + .and(Ok(Some(0))) + } } diff --git a/audio/ihdad/src/hda/mod.rs b/audio/ihdad/src/hda/mod.rs index 36b40d3fa3..7f01daf8ca 100644 --- a/audio/ihdad/src/hda/mod.rs +++ b/audio/ihdad/src/hda/mod.rs @@ -1,17 +1,16 @@ #![allow(dead_code)] -pub mod device; -pub mod stream; -pub mod common; -pub mod node; pub mod cmdbuff; +pub mod common; +pub mod device; +pub mod node; +pub mod stream; -pub use self::stream::*; pub use self::node::*; - +pub use self::stream::*; pub use self::cmdbuff::*; -pub use self::stream::StreamDescriptorRegs; -pub use self::stream::BufferDescriptorListEntry; -pub use self::stream::BitsPerSample; -pub use self::stream::StreamBuffer; pub use self::device::IntelHDA; +pub use self::stream::BitsPerSample; +pub use self::stream::BufferDescriptorListEntry; +pub use self::stream::StreamBuffer; +pub use self::stream::StreamDescriptorRegs; diff --git a/audio/ihdad/src/hda/node.rs b/audio/ihdad/src/hda/node.rs index 223170b2e8..06c5121fd7 100644 --- a/audio/ihdad/src/hda/node.rs +++ b/audio/ihdad/src/hda/node.rs @@ -1,108 +1,108 @@ -use std::{mem, fmt}; use super::common::*; +use std::{fmt, mem}; #[derive(Clone)] pub struct HDANode { - pub addr: WidgetAddr, + pub addr: WidgetAddr, - // 0x4 - pub subnode_count: u16, - pub subnode_start: u16, + // 0x4 + pub subnode_count: u16, + pub subnode_start: u16, - // 0x5 - pub function_group_type: u8, + // 0x5 + pub function_group_type: u8, - // 0x9 - pub capabilities: u32, + // 0x9 + pub capabilities: u32, - // 0xE - pub conn_list_len: u8, + // 0xE + pub conn_list_len: u8, - pub connections: Vec, + pub connections: Vec, - pub connection_default: u8, + pub connection_default: u8, - pub is_widget: bool, + pub is_widget: bool, - pub config_default: u32, + pub config_default: u32, } impl HDANode { - pub fn new() -> HDANode { - HDANode { - addr: (0,0), - subnode_count: 0, - subnode_start: 0, - function_group_type: 0, - capabilities: 0, - conn_list_len: 0, + pub fn new() -> HDANode { + HDANode { + addr: (0, 0), + subnode_count: 0, + subnode_start: 0, + function_group_type: 0, + capabilities: 0, + conn_list_len: 0, - config_default: 0, - is_widget: false, - connections: Vec::::new(), - connection_default: 0, - } - } + config_default: 0, + is_widget: false, + connections: Vec::::new(), + connection_default: 0, + } + } - pub fn widget_type(&self) -> HDAWidgetType { - unsafe { mem::transmute( ((self.capabilities >> 20) & 0xF) as u8 )} + pub fn widget_type(&self) -> HDAWidgetType { + unsafe { mem::transmute(((self.capabilities >> 20) & 0xF) as u8) } + } - } + pub fn device_default(&self) -> Option { + if self.widget_type() != HDAWidgetType::PinComplex { + None + } else { + Some(unsafe { mem::transmute(((self.config_default >> 20) & 0xF) as u8) }) + } + } - pub fn device_default(&self) -> Option { - if self.widget_type() != HDAWidgetType::PinComplex { - None - } else { - Some(unsafe { mem::transmute( ((self.config_default >> 20) & 0xF) as u8 )} ) - } - } + pub fn configuration_default(&self) -> ConfigurationDefault { + ConfigurationDefault::from_u32(self.config_default) + } - pub fn configuration_default(&self) -> ConfigurationDefault { - ConfigurationDefault::from_u32(self.config_default) - } - - pub fn addr(&self) -> WidgetAddr { - self.addr - } + pub fn addr(&self) -> WidgetAddr { + self.addr + } } impl fmt::Display for HDANode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.addr == (0,0) { - write!(f, "Addr: {:02X}:{:02X}, Root Node.", self.addr.0, self.addr.1) - } else if self.is_widget { - match self.widget_type() { - HDAWidgetType::PinComplex => write!( - f, - "Addr: {:02X}:{:02X}, Type: {:?}: {:?}, Inputs: {}/{}: {:X?}.", - self.addr.0, - self.addr.1, - self.widget_type(), - self.device_default().unwrap(), - self.connection_default, - self.conn_list_len, - self.connections - ), - _ => write!( - f, - "Addr: {:02X}:{:02X}, Type: {:?}, Inputs: {}/{}: {:X?}.", - self.addr.0, - self.addr.1, - self.widget_type(), - self.connection_default, - self.conn_list_len, - self.connections - ), - } - } else { - write!( - f, - "Addr: {:02X}:{:02X}, AFG: {}, Widget count {}.", - self.addr.0, - self.addr.1, - self.function_group_type, - self.subnode_count - ) - } + if self.addr == (0, 0) { + write!( + f, + "Addr: {:02X}:{:02X}, Root Node.", + self.addr.0, self.addr.1 + ) + } else if self.is_widget { + match self.widget_type() { + HDAWidgetType::PinComplex => write!( + f, + "Addr: {:02X}:{:02X}, Type: {:?}: {:?}, Inputs: {}/{}: {:X?}.", + self.addr.0, + self.addr.1, + self.widget_type(), + self.device_default().unwrap(), + self.connection_default, + self.conn_list_len, + self.connections + ), + _ => write!( + f, + "Addr: {:02X}:{:02X}, Type: {:?}, Inputs: {}/{}: {:X?}.", + self.addr.0, + self.addr.1, + self.widget_type(), + self.connection_default, + self.conn_list_len, + self.connections + ), + } + } else { + write!( + f, + "Addr: {:02X}:{:02X}, AFG: {}, Widget count {}.", + self.addr.0, self.addr.1, self.function_group_type, self.subnode_count + ) + } } } diff --git a/audio/ihdad/src/hda/stream.rs b/audio/ihdad/src/hda/stream.rs index 49fb4dd2f7..dfc72abc8d 100644 --- a/audio/ihdad/src/hda/stream.rs +++ b/audio/ihdad/src/hda/stream.rs @@ -1,353 +1,388 @@ use common::dma::Dma; -use common::io::{Mmio, Io}; -use syscall::PAGE_SIZE; -use syscall::error::{Error, EIO, Result}; -use std::result; +use common::io::{Io, Mmio}; use std::cmp::min; -use std::ptr::copy_nonoverlapping; use std::ptr; +use std::ptr::copy_nonoverlapping; +use std::result; +use syscall::error::{Error, Result, EIO}; +use syscall::PAGE_SIZE; extern crate syscall; pub enum BaseRate { - BR44_1, - BR48, + BR44_1, + BR48, } - pub struct SampleRate { - base: BaseRate, - mult: u16, - div: u16, + base: BaseRate, + mult: u16, + div: u16, } use self::BaseRate::{BR44_1, BR48}; -pub const SR_8: SampleRate = SampleRate {base: BR48 , mult: 1, div: 6}; -pub const SR_11_025: SampleRate = SampleRate {base: BR44_1, mult: 1, div: 4}; -pub const SR_16: SampleRate = SampleRate {base: BR48 , mult: 1, div: 3}; -pub const SR_22_05: SampleRate = SampleRate {base: BR44_1, mult: 1, div: 2}; -pub const SR_32: SampleRate = SampleRate {base: BR48 , mult: 2, div: 3}; - -pub const SR_44_1: SampleRate = SampleRate {base: BR44_1, mult: 1, div: 1}; -pub const SR_48: SampleRate = SampleRate {base: BR48 , mult: 1, div: 1}; -pub const SR_88_1: SampleRate = SampleRate {base: BR44_1, mult: 2, div: 1}; -pub const SR_96: SampleRate = SampleRate {base: BR48 , mult: 2, div: 1}; -pub const SR_176_4: SampleRate = SampleRate {base: BR44_1, mult: 4, div: 1}; -pub const SR_192: SampleRate = SampleRate {base: BR48 , mult: 4, div: 1}; - - - +pub const SR_8: SampleRate = SampleRate { + base: BR48, + mult: 1, + div: 6, +}; +pub const SR_11_025: SampleRate = SampleRate { + base: BR44_1, + mult: 1, + div: 4, +}; +pub const SR_16: SampleRate = SampleRate { + base: BR48, + mult: 1, + div: 3, +}; +pub const SR_22_05: SampleRate = SampleRate { + base: BR44_1, + mult: 1, + div: 2, +}; +pub const SR_32: SampleRate = SampleRate { + base: BR48, + mult: 2, + div: 3, +}; +pub const SR_44_1: SampleRate = SampleRate { + base: BR44_1, + mult: 1, + div: 1, +}; +pub const SR_48: SampleRate = SampleRate { + base: BR48, + mult: 1, + div: 1, +}; +pub const SR_88_1: SampleRate = SampleRate { + base: BR44_1, + mult: 2, + div: 1, +}; +pub const SR_96: SampleRate = SampleRate { + base: BR48, + mult: 2, + div: 1, +}; +pub const SR_176_4: SampleRate = SampleRate { + base: BR44_1, + mult: 4, + div: 1, +}; +pub const SR_192: SampleRate = SampleRate { + base: BR48, + mult: 4, + div: 1, +}; #[repr(u8)] pub enum BitsPerSample { - Bits8 = 0, - Bits16 = 1, - Bits20 = 2, - Bits24 = 3, - Bits32 = 4, + Bits8 = 0, + Bits16 = 1, + Bits20 = 2, + Bits24 = 3, + Bits32 = 4, } +pub fn format_to_u16(sr: &SampleRate, bps: BitsPerSample, channels: u8) -> u16 { + // 3.3.41 + let base: u16 = match sr.base { + BaseRate::BR44_1 => 1 << 14, + BaseRate::BR48 => 0, + }; -pub fn format_to_u16(sr: &SampleRate, bps: BitsPerSample, channels:u8) -> u16{ + let mult = ((sr.mult - 1) & 0x7) << 11; + let div = ((sr.div - 1) & 0x7) << 8; - // 3.3.41 + let bits = (bps as u16) << 4; - let base:u16 = match sr.base { - BaseRate::BR44_1 => { 1 << 14}, - BaseRate::BR48 => { 0 }, - }; + let chan = ((channels - 1) & 0xF) as u16; - let mult = ((sr.mult - 1) & 0x7) << 11; - - let div = ((sr.div - 1) & 0x7) << 8; - - let bits = (bps as u16) << 4; - - let chan = ((channels - 1) & 0xF) as u16; - - let val:u16 = base | mult | div | bits | chan; - - val + let val: u16 = base | mult | div | bits | chan; + val } - #[repr(packed)] pub struct StreamDescriptorRegs { - ctrl_lo: Mmio, - ctrl_hi: Mmio, - status: Mmio, - link_pos: Mmio, - buff_length: Mmio, - last_valid_index: Mmio, - resv1: Mmio, - fifo_size_: Mmio, - format: Mmio, - resv2: Mmio, - buff_desc_list_lo: Mmio, - buff_desc_list_hi: Mmio, - + ctrl_lo: Mmio, + ctrl_hi: Mmio, + status: Mmio, + link_pos: Mmio, + buff_length: Mmio, + last_valid_index: Mmio, + resv1: Mmio, + fifo_size_: Mmio, + format: Mmio, + resv2: Mmio, + buff_desc_list_lo: Mmio, + buff_desc_list_hi: Mmio, } - impl StreamDescriptorRegs { - pub fn status(&self) -> u8 { - self.status.read() - } + pub fn status(&self) -> u8 { + self.status.read() + } - pub fn set_status(&mut self, status: u8){ - self.status.write(status); - } + pub fn set_status(&mut self, status: u8) { + self.status.write(status); + } - pub fn control(&self) -> u32 { - let mut ctrl = self.ctrl_lo.read() as u32; - ctrl |= (self.ctrl_hi.read() as u32) << 16; - ctrl - } + pub fn control(&self) -> u32 { + let mut ctrl = self.ctrl_lo.read() as u32; + ctrl |= (self.ctrl_hi.read() as u32) << 16; + ctrl + } - pub fn set_control(&mut self, control:u32) { - self.ctrl_lo.write((control & 0xFFFF) as u16); - self.ctrl_hi.write(((control >> 16) & 0xFF) as u8); - } + pub fn set_control(&mut self, control: u32) { + self.ctrl_lo.write((control & 0xFFFF) as u16); + self.ctrl_hi.write(((control >> 16) & 0xFF) as u8); + } - pub fn set_pcm_format(&mut self, sr: &SampleRate, bps: BitsPerSample, channels:u8) { + pub fn set_pcm_format(&mut self, sr: &SampleRate, bps: BitsPerSample, channels: u8) { + // 3.3.41 + let val = format_to_u16(sr, bps, channels); + self.format.write(val); + } - // 3.3.41 + pub fn fifo_size(&self) -> u16 { + self.fifo_size_.read() + } - let val = format_to_u16(sr,bps,channels); - self.format.write(val); + pub fn set_cyclic_buffer_length(&mut self, length: u32) { + self.buff_length.write(length); + } - } + pub fn cyclic_buffer_length(&self) -> u32 { + self.buff_length.read() + } - pub fn fifo_size(&self) -> u16 { - self.fifo_size_.read() - } + pub fn run(&mut self) { + let val = self.control() | (1 << 1); + self.set_control(val); + } - pub fn set_cyclic_buffer_length(&mut self, length: u32) { - self.buff_length.write(length); - } + pub fn stop(&mut self) { + let val = self.control() & !(1 << 1); + self.set_control(val); + } - pub fn cyclic_buffer_length(&self) -> u32 { - self.buff_length.read() - } + pub fn stream_number(&self) -> u8 { + ((self.control() >> 20) & 0xF) as u8 + } - pub fn run(&mut self) { - let val = self.control() | (1 << 1); - self.set_control(val); - } + pub fn set_stream_number(&mut self, stream_number: u8) { + let val = (self.control() & 0x00FFFF) | (((stream_number & 0xF) as u32) << 20); + self.set_control(val); + } - pub fn stop(&mut self) { - let val = self.control() & !(1 << 1); - self.set_control(val); - } + pub fn set_address(&mut self, addr: usize) { + self.buff_desc_list_lo.write((addr & 0xFFFFFFFF) as u32); + self.buff_desc_list_hi + .write((((addr as u64) >> 32) & 0xFFFFFFFF) as u32); + } - pub fn stream_number(&self) -> u8 { - ((self.control() >> 20) & 0xF) as u8 - } + pub fn set_last_valid_index(&mut self, index: u16) { + self.last_valid_index.write(index); + } - pub fn set_stream_number(&mut self, stream_number: u8) { - let val = (self.control() & 0x00FFFF ) | (((stream_number & 0xF ) as u32) << 20); - self.set_control(val); - } + pub fn link_position(&self) -> u32 { + self.link_pos.read() + } - pub fn set_address(&mut self, addr: usize) { - self.buff_desc_list_lo.write( (addr & 0xFFFFFFFF) as u32); - self.buff_desc_list_hi.write( ( ((addr as u64) >> 32) & 0xFFFFFFFF) as u32); - } + pub fn set_interrupt_on_completion(&mut self, enable: bool) { + let mut ctrl = self.control(); + if enable { + ctrl |= 1 << 2; + } else { + ctrl &= !(1 << 2); + } + self.set_control(ctrl); + } - pub fn set_last_valid_index(&mut self, index:u16) { - self.last_valid_index.write(index); - } - - pub fn link_position(&self) -> u32 { - self.link_pos.read() - } - - pub fn set_interrupt_on_completion(&mut self, enable:bool) { - let mut ctrl = self.control(); - if enable { - ctrl |= 1 << 2; - } else { - ctrl &= !(1 << 2); - } - self.set_control(ctrl); - } - - pub fn buffer_complete(&self) -> bool { - self.status.readf(1 << 2) - } - - pub fn clear_interrupts(&mut self) { - self.status.write(0x7 << 2); - } - - // get sample size in bytes - pub fn sample_size(&self) -> usize { - let format = self.format.read(); - let chan = (format & 0xF) as usize; - let bits = ((format >> 4) & 0xF) as usize; - match bits { - 0 => 1 * (chan + 1), - 1 => 2 * (chan + 1), - _ => 4 * (chan + 1), - } - } + pub fn buffer_complete(&self) -> bool { + self.status.readf(1 << 2) + } + pub fn clear_interrupts(&mut self) { + self.status.write(0x7 << 2); + } + // get sample size in bytes + pub fn sample_size(&self) -> usize { + let format = self.format.read(); + let chan = (format & 0xF) as usize; + let bits = ((format >> 4) & 0xF) as usize; + match bits { + 0 => 1 * (chan + 1), + 1 => 2 * (chan + 1), + _ => 4 * (chan + 1), + } + } } pub struct OutputStream { - buff: StreamBuffer, + buff: StreamBuffer, - desc_regs: &'static mut StreamDescriptorRegs, + desc_regs: &'static mut StreamDescriptorRegs, } - impl OutputStream { - pub fn new(block_count: usize, block_length: usize, regs: &'static mut StreamDescriptorRegs) -> OutputStream { - OutputStream { - buff: StreamBuffer::new(block_length, block_count).unwrap(), + pub fn new( + block_count: usize, + block_length: usize, + regs: &'static mut StreamDescriptorRegs, + ) -> OutputStream { + OutputStream { + buff: StreamBuffer::new(block_length, block_count).unwrap(), - desc_regs: regs, - } - } + desc_regs: regs, + } + } - pub fn write_block(&mut self, buf: &[u8]) -> Result { - self.buff.write_block(buf) - } + pub fn write_block(&mut self, buf: &[u8]) -> Result { + self.buff.write_block(buf) + } - pub fn block_size(&self) -> usize { - self.buff.block_size() - } + pub fn block_size(&self) -> usize { + self.buff.block_size() + } - pub fn block_count(&self) -> usize { - self.buff.block_count() - } + pub fn block_count(&self) -> usize { + self.buff.block_count() + } - pub fn current_block(&self) -> usize { - self.buff.current_block() - } + pub fn current_block(&self) -> usize { + self.buff.current_block() + } - pub fn addr(&self) -> usize { - self.buff.addr() - } + pub fn addr(&self) -> usize { + self.buff.addr() + } - pub fn phys(&self) -> usize { - self.buff.phys() - } + pub fn phys(&self) -> usize { + self.buff.phys() + } } - - - #[repr(packed)] pub struct BufferDescriptorListEntry { - addr_low: Mmio, - addr_high: Mmio, - len: Mmio, - ioc_resv: Mmio, + addr_low: Mmio, + addr_high: Mmio, + len: Mmio, + ioc_resv: Mmio, } impl BufferDescriptorListEntry { - pub fn address(&self) -> u64 { - (self.addr_low.read() as u64) | - ((self.addr_high.read() as u64) << 32) - } + pub fn address(&self) -> u64 { + (self.addr_low.read() as u64) | ((self.addr_high.read() as u64) << 32) + } - pub fn set_address(&mut self, addr: u64) { - self.addr_low.write(addr as u32); - self.addr_high.write((addr >> 32) as u32); - } + pub fn set_address(&mut self, addr: u64) { + self.addr_low.write(addr as u32); + self.addr_high.write((addr >> 32) as u32); + } - pub fn length(&self) -> u32 { - self.len.read() - } + pub fn length(&self) -> u32 { + self.len.read() + } - pub fn set_length(&mut self, length: u32) { - self.len.write(length) - } + pub fn set_length(&mut self, length: u32) { + self.len.write(length) + } - pub fn interrupt_on_completion(&self) -> bool { - (self.ioc_resv.read() & 0x1) == 0x1 - } + pub fn interrupt_on_completion(&self) -> bool { + (self.ioc_resv.read() & 0x1) == 0x1 + } - pub fn set_interrupt_on_complete(&mut self, ioc: bool) { - self.ioc_resv.writef(1, ioc); - } + pub fn set_interrupt_on_complete(&mut self, ioc: bool) { + self.ioc_resv.writef(1, ioc); + } } pub struct StreamBuffer { - mem: Dma<[u8]>, + mem: Dma<[u8]>, - block_cnt: usize, - block_len: usize, + block_cnt: usize, + block_len: usize, - cur_pos: usize, + cur_pos: usize, } impl StreamBuffer { - pub fn new(block_length: usize, block_count: usize) -> result::Result { - let page_aligned_size = (block_length * block_count).next_multiple_of(PAGE_SIZE); - let mem = unsafe { Dma::zeroed_slice(page_aligned_size).map_err(|_| "Could not allocate physical memory for buffer.")?.assume_init() }; + pub fn new( + block_length: usize, + block_count: usize, + ) -> result::Result { + let page_aligned_size = (block_length * block_count).next_multiple_of(PAGE_SIZE); + let mem = unsafe { + Dma::zeroed_slice(page_aligned_size) + .map_err(|_| "Could not allocate physical memory for buffer.")? + .assume_init() + }; - Ok(StreamBuffer { - mem, - block_len: block_length, - block_cnt: block_count, - cur_pos: 0, - }) - } + Ok(StreamBuffer { + mem, + block_len: block_length, + block_cnt: block_count, + cur_pos: 0, + }) + } - pub fn length(&self) -> usize { - self.block_len * self.block_cnt - } + pub fn length(&self) -> usize { + self.block_len * self.block_cnt + } - pub fn addr(&self) -> usize { - self.mem.as_ptr() as usize - } + pub fn addr(&self) -> usize { + self.mem.as_ptr() as usize + } - pub fn phys(&self) -> usize { - self.mem.physical() - } + pub fn phys(&self) -> usize { + self.mem.physical() + } - pub fn block_size(&self) -> usize { - self.block_len - } + pub fn block_size(&self) -> usize { + self.block_len + } - pub fn block_count(&self) -> usize { - self.block_cnt - } + pub fn block_count(&self) -> usize { + self.block_cnt + } - pub fn current_block(&self) -> usize { - self.cur_pos - } + pub fn current_block(&self) -> usize { + self.cur_pos + } - pub fn write_block(&mut self, buf: &[u8]) -> Result { - if buf.len() != self.block_size() { - return Err(Error::new(EIO)) - } - let len = min(self.block_size(), buf.len()); + pub fn write_block(&mut self, buf: &[u8]) -> Result { + if buf.len() != self.block_size() { + return Err(Error::new(EIO)); + } + let len = min(self.block_size(), buf.len()); + //log::trace!("Phys: {:X} Virt: {:X} Offset: {:X} Len: {:X}", self.phys(), self.addr(), self.current_block() * self.block_size(), len); + unsafe { + copy_nonoverlapping( + buf.as_ptr(), + (self.addr() + self.current_block() * self.block_size()) as *mut u8, + len, + ); + } - //log::trace!("Phys: {:X} Virt: {:X} Offset: {:X} Len: {:X}", self.phys(), self.addr(), self.current_block() * self.block_size(), len); - unsafe { - copy_nonoverlapping(buf.as_ptr(), (self.addr() + self.current_block() * self.block_size()) as * mut u8, len); - } + self.cur_pos += 1; + self.cur_pos %= self.block_count(); - self.cur_pos += 1; - self.cur_pos %= self.block_count(); - - Ok(len) - - } + Ok(len) + } } impl Drop for StreamBuffer { - fn drop(&mut self) { - log::debug!("IHDA: Deallocating buffer."); - } + fn drop(&mut self) { + log::debug!("IHDA: Deallocating buffer."); + } } diff --git a/audio/ihdad/src/main.rs b/audio/ihdad/src/main.rs index 9fd2c779fb..e79ee9a18f 100755 --- a/audio/ihdad/src/main.rs +++ b/audio/ihdad/src/main.rs @@ -2,46 +2,53 @@ #![feature(int_roundings)] extern crate bitflags; +extern crate event; extern crate spin; extern crate syscall; -extern crate event; -use std::usize; -use std::fs::File; -use std::io::{ErrorKind, Read, Write, Result}; -use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use libredox::flag; -use syscall::{Packet, SchemeBlockMut, EventFlags}; use std::cell::RefCell; +use std::fs::File; +use std::io::{ErrorKind, Read, Result, Write}; +use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use std::sync::Arc; +use std::usize; +use syscall::{EventFlags, Packet, SchemeBlockMut}; use event::{user_data, EventQueue}; -use pcid_interface::{MsiSetFeatureInfo, PciFunctionHandle, PciFeature, PciFeatureInfo, SetFeatureInfo}; #[cfg(target_arch = "x86_64")] use pcid_interface::irq_helpers::allocate_single_interrupt_vector_for_msi; use pcid_interface::irq_helpers::read_bsp_apic_id; +use pcid_interface::{ + MsiSetFeatureInfo, PciFeature, PciFeatureInfo, PciFunctionHandle, SetFeatureInfo, +}; pub mod hda; /* - VEND:PROD - Virtualbox 8086:2668 - QEMU ICH9 8086:293E - 82801H ICH8 8086:284B - */ +VEND:PROD +Virtualbox 8086:2668 +QEMU ICH9 8086:293E +82801H ICH8 8086:284B +*/ #[cfg(target_arch = "x86_64")] fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> File { let pci_config = pcid_handle.config(); - let all_pci_features = pcid_handle.fetch_all_features().expect("ihdad: failed to fetch pci features"); + let all_pci_features = pcid_handle + .fetch_all_features() + .expect("ihdad: failed to fetch pci features"); log::debug!("PCI FEATURES: {:?}", all_pci_features); let has_msi = all_pci_features.iter().any(|feature| feature.is_msi()); let has_msix = all_pci_features.iter().any(|feature| feature.is_msix()); if has_msi && !has_msix { - let capability = match pcid_handle.feature_info(PciFeature::Msi).expect("ihdad: failed to retrieve the MSI capability structure from pcid") { + let capability = match pcid_handle + .feature_info(PciFeature::Msi) + .expect("ihdad: failed to retrieve the MSI capability structure from pcid") + { PciFeatureInfo::Msi(s) => s, PciFeatureInfo::MsiX(_) => panic!(), }; @@ -51,16 +58,21 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> File { // pcid_interface, so that this can be shared between nvmed, xhcid, ixgebd, etc.. let destination_id = read_bsp_apic_id().expect("ihdad: failed to read BSP apic id"); - let (msg_addr_and_data, interrupt_handle) = allocate_single_interrupt_vector_for_msi(destination_id); + let (msg_addr_and_data, interrupt_handle) = + allocate_single_interrupt_vector_for_msi(destination_id); let set_feature_info = MsiSetFeatureInfo { multi_message_enable: Some(0), message_address_and_data: Some(msg_addr_and_data), mask_bits: None, }; - pcid_handle.set_feature_info(SetFeatureInfo::Msi(set_feature_info)).expect("ihdad: failed to set feature info"); + pcid_handle + .set_feature_info(SetFeatureInfo::Msi(set_feature_info)) + .expect("ihdad: failed to set feature info"); - pcid_handle.enable_feature(PciFeature::Msi).expect("ihdad: failed to enable MSI"); + pcid_handle + .enable_feature(PciFeature::Msi) + .expect("ihdad: failed to enable MSI"); log::debug!("Enabled MSI"); interrupt_handle @@ -96,7 +108,8 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { log::LevelFilter::Info, ); - let mut pcid_handle = PciFunctionHandle::connect_default().expect("ihdad: failed to setup channel to pcid"); + let mut pcid_handle = + PciFunctionHandle::connect_default().expect("ihdad: failed to setup channel to pcid"); let pci_config = pcid_handle.config(); @@ -105,7 +118,9 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { log::info!(" + IHDA {}", pci_config.func.display()); - let address = unsafe { pcid_handle.map_bar(0).expect("ihdad") }.ptr.as_ptr() as usize; + let address = unsafe { pcid_handle.map_bar(0).expect("ihdad") } + .ptr + .as_ptr() as usize; //TODO: MSI-X let mut irq_file = get_int_method(&mut pcid_handle); @@ -121,13 +136,29 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { } } - let mut event_queue = EventQueue::::new().expect("ihdad: Could not create event queue."); - let mut device = unsafe { hda::IntelHDA::new(address, vend_prod).expect("ihdad: failed to allocate device") }; - let socket_fd = libredox::call::open(":audiohw", flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, 0).expect("ihdad: failed to create hda scheme"); + let mut event_queue = + EventQueue::::new().expect("ihdad: Could not create event queue."); + let mut device = unsafe { + hda::IntelHDA::new(address, vend_prod).expect("ihdad: failed to allocate device") + }; + let socket_fd = libredox::call::open( + ":audiohw", + flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, + 0, + ) + .expect("ihdad: failed to create hda scheme"); let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) }; - event_queue.subscribe(socket_fd, Source::Scheme, event::EventFlags::READ).unwrap(); - event_queue.subscribe(irq_file.as_raw_fd() as usize, Source::Irq, event::EventFlags::READ).unwrap(); + event_queue + .subscribe(socket_fd, Source::Scheme, event::EventFlags::READ) + .unwrap(); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); daemon.ready().expect("ihdad: failed to signal readiness"); @@ -137,7 +168,10 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let all = [Source::Irq, Source::Scheme]; - 'events: for event in all.into_iter().chain(event_queue.map(|e| e.expect("failed to get next event").user_data)) { + 'events: for event in all + .into_iter() + .chain(event_queue.map(|e| e.expect("failed to get next event").user_data)) + { match event { Source::Irq => { let mut irq = [0; 8]; @@ -158,11 +192,11 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { } /* - let next_read = device_irq.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + let next_read = device_irq.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ } } Source::Scheme => { @@ -171,10 +205,12 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { match socket.read(&mut packet) { Ok(0) => break 'events, Ok(_) => (), - Err(err) => if err.kind() == ErrorKind::WouldBlock { - break; - } else { - panic!("ihdad: failed to read from socket: {err}"); + Err(err) => { + if err.kind() == ErrorKind::WouldBlock { + break; + } else { + panic!("ihdad: failed to read from socket: {err}"); + } } } @@ -187,11 +223,11 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { } /* - let next_read = device.borrow().next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + let next_read = device.borrow().next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ } } } diff --git a/audio/pcspkrd/src/main.rs b/audio/pcspkrd/src/main.rs index 75957745c3..d021257710 100644 --- a/audio/pcspkrd/src/main.rs +++ b/audio/pcspkrd/src/main.rs @@ -41,5 +41,6 @@ fn main() { .write(&packet) .expect("pcspkrd: failed to write responses to pcspkr scheme"); } - }).expect("pcspkrd: failed to daemonize"); + }) + .expect("pcspkrd: failed to daemonize"); } diff --git a/audio/sb16d/src/device.rs b/audio/sb16d/src/device.rs index 47cf231f5a..36a6e94b8c 100644 --- a/audio/sb16d/src/device.rs +++ b/audio/sb16d/src/device.rs @@ -1,12 +1,12 @@ #![allow(dead_code)] -use std::{thread, time}; use std::collections::BTreeMap; use std::sync::atomic::{AtomicUsize, Ordering}; +use std::{thread, time}; -use common::io::{Pio, Io, ReadOnly, WriteOnly}; +use common::io::{Io, Pio, ReadOnly, WriteOnly}; -use syscall::error::{Error, EACCES, EBADF, Result, ENODEV}; +use syscall::error::{Error, Result, EACCES, EBADF, ENODEV}; use syscall::scheme::SchemeBlockMut; use spin::Mutex; @@ -68,7 +68,7 @@ impl Sb16 { fn dsp_read(&mut self) -> Result { // Bit 7 must be 1 before data can be sent - while ! self.dsp_read_status.readf(1 << 7) { + while !self.dsp_read_status.readf(1 << 7) { //TODO: timeout! std::thread::yield_now(); } @@ -212,6 +212,9 @@ impl SchemeBlockMut for Sb16 { fn close(&mut self, id: usize) -> Result> { let mut handles = self.handles.lock(); - handles.remove(&id).ok_or(Error::new(EBADF)).and(Ok(Some(0))) + handles + .remove(&id) + .ok_or(Error::new(EBADF)) + .and(Ok(Some(0))) } } diff --git a/audio/sb16d/src/main.rs b/audio/sb16d/src/main.rs index ff7333a626..dfa863a7e1 100644 --- a/audio/sb16d/src/main.rs +++ b/audio/sb16d/src/main.rs @@ -1,8 +1,8 @@ //#![deny(warnings)] -use std::{env, usize}; use libredox::errno::{EAGAIN, EWOULDBLOCK}; use libredox::{flag, Fd}; +use std::{env, usize}; use syscall::{Packet, SchemeBlockMut}; use event::{user_data, EventQueue}; @@ -29,12 +29,19 @@ fn main() { common::acquire_port_io_rights().expect("sb16d: failed to acquire port IO rights"); - let mut device = unsafe { device::Sb16::new(addr).expect("sb16d: failed to allocate device") }; - let socket = Fd::open(":audiohw", flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, 0).expect("sb16d: failed to create hda scheme"); + let mut device = + unsafe { device::Sb16::new(addr).expect("sb16d: failed to allocate device") }; + let socket = Fd::open( + ":audiohw", + flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, + 0, + ) + .expect("sb16d: failed to create hda scheme"); //TODO: error on multiple IRQs? let irq_file = match device.irqs.first() { - Some(irq) => Fd::open(&format!("/scheme/irq/{}", irq), flag::O_RDWR, 0).expect("sb16d: failed to open IRQ file"), + Some(irq) => Fd::open(&format!("/scheme/irq/{}", irq), flag::O_RDWR, 0) + .expect("sb16d: failed to open IRQ file"), None => panic!("sb16d: no IRQs found"), }; user_data! { @@ -44,9 +51,14 @@ fn main() { } } - let event_queue = EventQueue::::new().expect("sb16d: Could not create event queue."); - event_queue.subscribe(irq_file.raw(), Source::Irq, event::EventFlags::READ).unwrap(); - event_queue.subscribe(socket.raw(), Source::Scheme, event::EventFlags::READ).unwrap(); + let event_queue = + EventQueue::::new().expect("sb16d: Could not create event queue."); + event_queue + .subscribe(irq_file.raw(), Source::Irq, event::EventFlags::READ) + .unwrap(); + event_queue + .subscribe(socket.raw(), Source::Scheme, event::EventFlags::READ) + .unwrap(); daemon.ready().expect("sb16d: failed to signal readiness"); @@ -56,7 +68,10 @@ fn main() { let all = [Source::Irq, Source::Scheme]; - 'events: for event in all.into_iter().chain(event_queue.map(|e| e.expect("sb16d: failed to get next event").user_data)) { + 'events: for event in all + .into_iter() + .chain(event_queue.map(|e| e.expect("sb16d: failed to get next event").user_data)) + { match event { Source::Irq => { let mut irq = [0; 8]; @@ -70,7 +85,9 @@ fn main() { if let Some(a) = device.handle(&mut todo[i]) { let mut packet = todo.remove(i); packet.a = a; - socket.write(&packet).expect("sb16d: failed to write to socket"); + socket + .write(&packet) + .expect("sb16d: failed to write to socket"); } else { i += 1; } @@ -84,30 +101,33 @@ fn main() { */ } } - Source::Scheme => { - loop { - let mut packet = Packet::default(); - match socket.read(&mut packet) { - Ok(0) => break 'events, - Ok(_) => (), - Err(err) => if err.errno() == EWOULDBLOCK || err.errno() == EAGAIN { + Source::Scheme => loop { + let mut packet = Packet::default(); + match socket.read(&mut packet) { + Ok(0) => break 'events, + Ok(_) => (), + Err(err) => { + if err.errno() == EWOULDBLOCK || err.errno() == EAGAIN { break; } else { panic!("sb16d: failed to read from scheme socket"); } } - - if let Some(a) = device.handle(&mut packet) { - packet.a = a; - socket.write(&packet).expect("sb16d: failed to write to scheme socket"); - } else { - todo.push(packet); - } } - } + + if let Some(a) = device.handle(&mut packet) { + packet.a = a; + socket + .write(&packet) + .expect("sb16d: failed to write to scheme socket"); + } else { + todo.push(packet); + } + }, } } std::process::exit(0); - }).expect("sb16d: failed to daemonize"); + }) + .expect("sb16d: failed to daemonize"); } diff --git a/common/src/io/mmio.rs b/common/src/io/mmio.rs index c20cf52716..6b21b66ed5 100644 --- a/common/src/io/mmio.rs +++ b/common/src/io/mmio.rs @@ -35,7 +35,11 @@ impl Mmio { #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] impl Io for Mmio where - T: Copy + PartialEq + core::ops::BitAnd + core::ops::BitOr + core::ops::Not, + T: Copy + + PartialEq + + core::ops::BitAnd + + core::ops::BitOr + + core::ops::Not, { type Value = T; diff --git a/net/alxd/src/device/mod.rs b/net/alxd/src/device/mod.rs index baac6fc89d..64415b1887 100644 --- a/net/alxd/src/device/mod.rs +++ b/net/alxd/src/device/mod.rs @@ -1,9 +1,9 @@ -use std::{ptr, thread, time}; use std::convert::TryInto; +use std::{ptr, thread, time}; -use syscall::error::{Error, EACCES, EINVAL, EIO, EWOULDBLOCK, Result}; -use syscall::flag::{EventFlags, O_NONBLOCK}; use common::io::{Io, Mmio}; +use syscall::error::{Error, Result, EACCES, EINVAL, EIO, EWOULDBLOCK}; +use syscall::flag::{EventFlags, O_NONBLOCK}; use syscall::scheme; use common::dma::Dma; @@ -48,61 +48,48 @@ const CAP_MTQ: u32 = 1 << 8; /* support Multi-RX-Q */ const CAP_MRQ: u32 = 1 << 9; -const ISR_MISC: u32 = - ISR_PCIE_LNKDOWN | - ISR_DMAW | - ISR_DMAR | - ISR_SMB | - ISR_MANU | - ISR_TIMER; +const ISR_MISC: u32 = ISR_PCIE_LNKDOWN | ISR_DMAW | ISR_DMAR | ISR_SMB | ISR_MANU | ISR_TIMER; -const ISR_FATAL: u32 = - ISR_PCIE_LNKDOWN | - ISR_DMAW | - ISR_DMAR; +const ISR_FATAL: u32 = ISR_PCIE_LNKDOWN | ISR_DMAW | ISR_DMAR; -const ISR_ALERT: u32 = - ISR_RXF_OV | - ISR_TXF_UR | - ISR_RFD_UR; +const ISR_ALERT: u32 = ISR_RXF_OV | ISR_TXF_UR | ISR_RFD_UR; -const ISR_ALL_QUEUES: u32 = - ISR_TX_Q0 | - ISR_TX_Q1 | - ISR_TX_Q2 | - ISR_TX_Q3 | - ISR_RX_Q0 | - ISR_RX_Q1 | - ISR_RX_Q2 | - ISR_RX_Q3 | - ISR_RX_Q4 | - ISR_RX_Q5 | - ISR_RX_Q6 | - ISR_RX_Q7; +const ISR_ALL_QUEUES: u32 = ISR_TX_Q0 + | ISR_TX_Q1 + | ISR_TX_Q2 + | ISR_TX_Q3 + | ISR_RX_Q0 + | ISR_RX_Q1 + | ISR_RX_Q2 + | ISR_RX_Q3 + | ISR_RX_Q4 + | ISR_RX_Q5 + | ISR_RX_Q6 + | ISR_RX_Q7; -const PCI_COMMAND_IO: u16 = 0x1; /* Enable response in I/O space */ -const PCI_COMMAND_MEMORY: u16 = 0x2; /* Enable response in Memory space */ -const PCI_COMMAND_MASTER: u16 = 0x4; /* Enable bus mastering */ -const PCI_COMMAND_SPECIAL: u16 = 0x8; /* Enable response to special cycles */ -const PCI_COMMAND_INVALIDATE: u16 = 0x10; /* Use memory write and invalidate */ -const PCI_COMMAND_VGA_PALETTE: u16 = 0x20; /* Enable palette snooping */ -const PCI_COMMAND_PARITY: u16 = 0x40; /* Enable parity checking */ -const PCI_COMMAND_WAIT: u16 = 0x80; /* Enable address/data stepping */ -const PCI_COMMAND_SERR: u16 = 0x100; /* Enable SERR */ -const PCI_COMMAND_FAST_BACK: u16 = 0x200; /* Enable back-to-back writes */ -const PCI_COMMAND_INTX_DISABLE: u16 = 0x400;/* INTx Emulation Disable */ +const PCI_COMMAND_IO: u16 = 0x1; /* Enable response in I/O space */ +const PCI_COMMAND_MEMORY: u16 = 0x2; /* Enable response in Memory space */ +const PCI_COMMAND_MASTER: u16 = 0x4; /* Enable bus mastering */ +const PCI_COMMAND_SPECIAL: u16 = 0x8; /* Enable response to special cycles */ +const PCI_COMMAND_INVALIDATE: u16 = 0x10; /* Use memory write and invalidate */ +const PCI_COMMAND_VGA_PALETTE: u16 = 0x20; /* Enable palette snooping */ +const PCI_COMMAND_PARITY: u16 = 0x40; /* Enable parity checking */ +const PCI_COMMAND_WAIT: u16 = 0x80; /* Enable address/data stepping */ +const PCI_COMMAND_SERR: u16 = 0x100; /* Enable SERR */ +const PCI_COMMAND_FAST_BACK: u16 = 0x200; /* Enable back-to-back writes */ +const PCI_COMMAND_INTX_DISABLE: u16 = 0x400; /* INTx Emulation Disable */ /// MII basic mode control register const MII_BMCR: u16 = 0x00; - const BMCR_FULLDPLX: u16 = 0x0100; - const BMCR_ANRESTART: u16 = 0x0200; - const BMCR_ANENABLE: u16 = 0x1000; - const BMCR_SPEED100: u16 = 0x2000; - const BMCR_RESET: u16 = 0x8000; +const BMCR_FULLDPLX: u16 = 0x0100; +const BMCR_ANRESTART: u16 = 0x0200; +const BMCR_ANENABLE: u16 = 0x1000; +const BMCR_SPEED100: u16 = 0x2000; +const BMCR_RESET: u16 = 0x8000; /// MII basic mode status register const MII_BMSR: u16 = 0x01; - const BMSR_LSTATUS: u16 = 0x0004; +const BMSR_LSTATUS: u16 = 0x0004; /// MII advertisement register const MII_ADVERTISE: u16 = 0x04; @@ -122,46 +109,46 @@ const ADVERTISED_Autoneg: u32 = 1 << 6; const ADVERTISED_Pause: u32 = 1 << 13; const ADVERTISED_Asym_Pause: u32 = 1 << 14; -const ADVERTISE_CSMA: u32 = 0x0001; /* Only selector supported */ -const ADVERTISE_10HALF: u32 = 0x0020; /* Try for 10mbps half-duplex */ -const ADVERTISE_1000XFULL: u32 = 0x0020; /* Try for 1000BASE-X full-duplex */ -const ADVERTISE_10FULL: u32 = 0x0040; /* Try for 10mbps full-duplex */ -const ADVERTISE_1000XHALF: u32 = 0x0040; /* Try for 1000BASE-X half-duplex */ -const ADVERTISE_100HALF: u32 = 0x0080; /* Try for 100mbps half-duplex */ -const ADVERTISE_1000XPAUSE: u32 = 0x0080; /* Try for 1000BASE-X pause */ -const ADVERTISE_100FULL: u32 = 0x0100; /* Try for 100mbps full-duplex */ -const ADVERTISE_1000XPSE_ASYM: u32 = 0x0100; /* Try for 1000BASE-X asym pause */ -const ADVERTISE_100BASE4: u32 = 0x0200; /* Try for 100mbps 4k packets */ -const ADVERTISE_PAUSE_CAP: u32 = 0x0400; /* Try for pause */ -const ADVERTISE_PAUSE_ASYM: u32 = 0x0800; /* Try for asymetric pause */ +const ADVERTISE_CSMA: u32 = 0x0001; /* Only selector supported */ +const ADVERTISE_10HALF: u32 = 0x0020; /* Try for 10mbps half-duplex */ +const ADVERTISE_1000XFULL: u32 = 0x0020; /* Try for 1000BASE-X full-duplex */ +const ADVERTISE_10FULL: u32 = 0x0040; /* Try for 10mbps full-duplex */ +const ADVERTISE_1000XHALF: u32 = 0x0040; /* Try for 1000BASE-X half-duplex */ +const ADVERTISE_100HALF: u32 = 0x0080; /* Try for 100mbps half-duplex */ +const ADVERTISE_1000XPAUSE: u32 = 0x0080; /* Try for 1000BASE-X pause */ +const ADVERTISE_100FULL: u32 = 0x0100; /* Try for 100mbps full-duplex */ +const ADVERTISE_1000XPSE_ASYM: u32 = 0x0100; /* Try for 1000BASE-X asym pause */ +const ADVERTISE_100BASE4: u32 = 0x0200; /* Try for 100mbps 4k packets */ +const ADVERTISE_PAUSE_CAP: u32 = 0x0400; /* Try for pause */ +const ADVERTISE_PAUSE_ASYM: u32 = 0x0800; /* Try for asymetric pause */ const ADVERTISE_1000HALF: u32 = 0x0100; const ADVERTISE_1000FULL: u32 = 0x0200; macro_rules! FIELD_GETX { - ($x:expr, $name:ident) => (( + ($x:expr, $name:ident) => { ((($x) >> concat_idents!($name, _SHIFT)) & concat_idents!($name, _MASK)) - )) + }; } macro_rules! FIELDX { - ($name:ident, $v:expr) => (( - ((($v) as u32) & concat_idents!($name, _MASK)) << concat_idents!($name, _SHIFT) - )) + ($name:ident, $v:expr) => { + (((($v) as u32) & concat_idents!($name, _MASK)) << concat_idents!($name, _SHIFT)) + }; } macro_rules! FIELD_SETS { ($x:expr, $name:ident, $v:expr) => {{ ($x) = (($x) & !(concat_idents!($name, _MASK) << concat_idents!($name, _SHIFT))) - | (((($v) as u16) & concat_idents!($name, _MASK)) << concat_idents!($name, _SHIFT)) - }} + | (((($v) as u16) & concat_idents!($name, _MASK)) << concat_idents!($name, _SHIFT)) + }}; } macro_rules! FIELD_SET32 { ($x:expr, $name:ident, $v:expr) => {{ ($x) = (($x) & !(concat_idents!($name, _MASK) << concat_idents!($name, _SHIFT))) - | (((($v) as u32) & concat_idents!($name, _MASK)) << concat_idents!($name, _SHIFT)) - }} + | (((($v) as u32) & concat_idents!($name, _MASK)) << concat_idents!($name, _SHIFT)) + }}; } fn udelay(micros: u32) { @@ -316,22 +303,22 @@ impl Alx { link_speed: 0, link_duplex: 0, - adv_cfg: ADVERTISED_Autoneg | - ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_1000baseT_Full, + adv_cfg: ADVERTISED_Autoneg + | ADVERTISED_10baseT_Half + | ADVERTISED_10baseT_Full + | ADVERTISED_100baseT_Full + | ADVERTISED_100baseT_Half + | ADVERTISED_1000baseT_Full, flowctrl: FC_ANEG | FC_RX | FC_TX, - rx_ctrl: MAC_CTRL_WOLSPED_SWEN | - MAC_CTRL_MHASH_ALG_HI5B | - MAC_CTRL_BRD_EN | - MAC_CTRL_PCRCE | - MAC_CTRL_CRCE | - MAC_CTRL_RXFC_EN | - MAC_CTRL_TXFC_EN | - FIELDX!(MAC_CTRL_PRMBLEN, 7), + rx_ctrl: MAC_CTRL_WOLSPED_SWEN + | MAC_CTRL_MHASH_ALG_HI5B + | MAC_CTRL_BRD_EN + | MAC_CTRL_PCRCE + | MAC_CTRL_CRCE + | MAC_CTRL_RXFC_EN + | MAC_CTRL_TXFC_EN + | FIELDX!(MAC_CTRL_PRMBLEN, 7), lnk_patch: false, hib_patch: false, @@ -358,72 +345,75 @@ impl Alx { } unsafe fn handle_intr_misc(&mut self, intr: u32) -> bool { - if (intr & ISR_FATAL > 0) { + if (intr & ISR_FATAL > 0) { println!("intr-fatal: {:X}", intr); self.flag |= FLAG_TASK_RESET; self.task(); - return true; - } - - if (intr & ISR_ALERT > 0) { - println!("interrupt alert: {:X}", intr); + return true; } - if (intr & ISR_SMB > 0) { - self.flag |= FLAG_TASK_UPDATE_SMB; - self.task(); - } + if (intr & ISR_ALERT > 0) { + println!("interrupt alert: {:X}", intr); + } - if (intr & ISR_PHY > 0) { - /* suppress PHY interrupt, because the source - * is from PHY internal. only the internal status - * is cleared, the interrupt status could be cleared. - */ - self.imask &= !ISR_PHY; + if (intr & ISR_SMB > 0) { + self.flag |= FLAG_TASK_UPDATE_SMB; + self.task(); + } + + if (intr & ISR_PHY > 0) { + /* suppress PHY interrupt, because the source + * is from PHY internal. only the internal status + * is cleared, the interrupt status could be cleared. + */ + self.imask &= !ISR_PHY; let imask = self.imask; self.write(IMR, imask); self.flag |= FLAG_TASK_CHK_LINK; self.task(); - } + } - return false; + return false; } unsafe fn intr_1(&mut self, mut intr: u32) -> bool { - /* ACK interrupt */ - println!("ACK interrupt: {:X}", intr | ISR_DIS); - self.write(ISR, intr | ISR_DIS); - intr &= self.imask; + /* ACK interrupt */ + println!("ACK interrupt: {:X}", intr | ISR_DIS); + self.write(ISR, intr | ISR_DIS); + intr &= self.imask; - if (self.handle_intr_misc(intr)) { - return true; + if (self.handle_intr_misc(intr)) { + return true; } - if (intr & (ISR_TX_Q0 | ISR_RX_Q0) > 0) { + if (intr & (ISR_TX_Q0 | ISR_RX_Q0) > 0) { println!("TX | RX"); - //TODO: napi_schedule(&adpt->qnapi[0]->napi); - /* mask rx/tx interrupt, enable them when napi complete */ - self.imask &= !ISR_ALL_QUEUES; + //TODO: napi_schedule(&adpt->qnapi[0]->napi); + /* mask rx/tx interrupt, enable them when napi complete */ + self.imask &= !ISR_ALL_QUEUES; let imask = self.imask; - self.write(IMR, imask); - } + self.write(IMR, imask); + } - self.write(ISR, 0); + self.write(ISR, 0); - return true; + return true; } pub unsafe fn intr_legacy(&mut self) -> bool { - /* read interrupt status */ - let intr = self.read(ISR); - if (intr & ISR_DIS > 0 || intr & self.imask == 0) { - let mask = self.read(IMR); - println!("seems a wild interrupt, intr={:X}, imask={:X}, mask={:X}", intr, self.imask, mask); + /* read interrupt status */ + let intr = self.read(ISR); + if (intr & ISR_DIS > 0 || intr & self.imask == 0) { + let mask = self.read(IMR); + println!( + "seems a wild interrupt, intr={:X}, imask={:X}, mask={:X}", + intr, self.imask, mask + ); - return false; - } + return false; + } - return self.intr_1(intr); + return self.intr_1(intr); } pub fn next_read(&self) -> usize { @@ -459,46 +449,46 @@ impl Alx { unsafe fn wait_mdio_idle(&mut self) -> bool { let mut val: u32; - let mut i: u32 = 0; + let mut i: u32 = 0; - while (i < MDIO_MAX_AC_TO) { - val = self.read(MDIO); - if (val & MDIO_BUSY == 0) { - break; + while (i < MDIO_MAX_AC_TO) { + val = self.read(MDIO); + if (val & MDIO_BUSY == 0) { + break; } - udelay(10); + udelay(10); i += 1; - } - return i != MDIO_MAX_AC_TO; + } + return i != MDIO_MAX_AC_TO; } unsafe fn stop_phy_polling(&mut self) { if (!self.is_fpga) { - return; + return; } - self.write(MDIO, 0); - self.wait_mdio_idle(); + self.write(MDIO, 0); + self.wait_mdio_idle(); } unsafe fn start_phy_polling(&mut self, clk_sel: u16) { let mut val: u32; - if (!self.is_fpga) { - return; + if (!self.is_fpga) { + return; } - val = MDIO_SPRES_PRMBL | - FIELDX!(MDIO_CLK_SEL, clk_sel) | - FIELDX!(MDIO_REG, 1) | - MDIO_START | - MDIO_OP_READ; - self.write(MDIO, val); - self.wait_mdio_idle(); - val |= MDIO_AUTO_POLLING; - val &= !MDIO_START; - self.write(MDIO, val); - udelay(30); + val = MDIO_SPRES_PRMBL + | FIELDX!(MDIO_CLK_SEL, clk_sel) + | FIELDX!(MDIO_REG, 1) + | MDIO_START + | MDIO_OP_READ; + self.write(MDIO, val); + self.wait_mdio_idle(); + val |= MDIO_AUTO_POLLING; + val &= !MDIO_START; + self.write(MDIO, val); + udelay(30); } unsafe fn read_phy_core(&mut self, ext: bool, dev: u8, reg: u16, phy_data: &mut u16) -> usize { @@ -506,43 +496,46 @@ impl Alx { let clk_sel: u16; let err: usize; - self.stop_phy_polling(); + self.stop_phy_polling(); - *phy_data = 0; + *phy_data = 0; - /* use slow clock when it's in hibernation status */ - clk_sel = if !self.link_up { MDIO_CLK_SEL_25MD128 } else { MDIO_CLK_SEL_25MD4 }; - - if (ext) { - val = FIELDX!(MDIO_EXTN_DEVAD, dev) | - FIELDX!(MDIO_EXTN_REG, reg); - self.write(MDIO_EXTN, val); - - val = MDIO_SPRES_PRMBL | - FIELDX!(MDIO_CLK_SEL, clk_sel) | - MDIO_START | - MDIO_MODE_EXT | - MDIO_OP_READ; - } else { - val = MDIO_SPRES_PRMBL | - FIELDX!(MDIO_CLK_SEL, clk_sel) | - FIELDX!(MDIO_REG, reg) | - MDIO_START | - MDIO_OP_READ; - } - self.write(MDIO, val); - - if (! self.wait_mdio_idle()) { - err = ERR_MIIBUSY; + /* use slow clock when it's in hibernation status */ + clk_sel = if !self.link_up { + MDIO_CLK_SEL_25MD128 } else { - val = self.read(MDIO); - *phy_data = FIELD_GETX!(val, MDIO_DATA) as u16; - err = 0; - } + MDIO_CLK_SEL_25MD4 + }; - self.start_phy_polling(clk_sel); + if (ext) { + val = FIELDX!(MDIO_EXTN_DEVAD, dev) | FIELDX!(MDIO_EXTN_REG, reg); + self.write(MDIO_EXTN, val); - return err; + val = MDIO_SPRES_PRMBL + | FIELDX!(MDIO_CLK_SEL, clk_sel) + | MDIO_START + | MDIO_MODE_EXT + | MDIO_OP_READ; + } else { + val = MDIO_SPRES_PRMBL + | FIELDX!(MDIO_CLK_SEL, clk_sel) + | FIELDX!(MDIO_REG, reg) + | MDIO_START + | MDIO_OP_READ; + } + self.write(MDIO, val); + + if (!self.wait_mdio_idle()) { + err = ERR_MIIBUSY; + } else { + val = self.read(MDIO); + *phy_data = FIELD_GETX!(val, MDIO_DATA) as u16; + err = 0; + } + + self.start_phy_polling(clk_sel); + + return err; } unsafe fn write_phy_core(&mut self, ext: bool, dev: u8, reg: u16, phy_data: u16) -> usize { @@ -550,41 +543,44 @@ impl Alx { let clk_sel: u16; let mut err: usize = 0; - self.stop_phy_polling(); + self.stop_phy_polling(); - /* use slow clock when it's in hibernation status */ - clk_sel = if ! self.link_up { MDIO_CLK_SEL_25MD128 } else { MDIO_CLK_SEL_25MD4 }; + /* use slow clock when it's in hibernation status */ + clk_sel = if !self.link_up { + MDIO_CLK_SEL_25MD128 + } else { + MDIO_CLK_SEL_25MD4 + }; - if (ext) { - val = FIELDX!(MDIO_EXTN_DEVAD, dev) | - FIELDX!(MDIO_EXTN_REG, reg); - self.write(MDIO_EXTN, val); + if (ext) { + val = FIELDX!(MDIO_EXTN_DEVAD, dev) | FIELDX!(MDIO_EXTN_REG, reg); + self.write(MDIO_EXTN, val); - val = MDIO_SPRES_PRMBL | - FIELDX!(MDIO_CLK_SEL, clk_sel) | - FIELDX!(MDIO_DATA, phy_data) | - MDIO_START | - MDIO_MODE_EXT; - } else { - val = MDIO_SPRES_PRMBL | - FIELDX!(MDIO_CLK_SEL, clk_sel) | - FIELDX!(MDIO_REG, reg) | - FIELDX!(MDIO_DATA, phy_data) | - MDIO_START; - } - self.write(MDIO, val); + val = MDIO_SPRES_PRMBL + | FIELDX!(MDIO_CLK_SEL, clk_sel) + | FIELDX!(MDIO_DATA, phy_data) + | MDIO_START + | MDIO_MODE_EXT; + } else { + val = MDIO_SPRES_PRMBL + | FIELDX!(MDIO_CLK_SEL, clk_sel) + | FIELDX!(MDIO_REG, reg) + | FIELDX!(MDIO_DATA, phy_data) + | MDIO_START; + } + self.write(MDIO, val); - if ! self.wait_mdio_idle() { - err = ERR_MIIBUSY; + if !self.wait_mdio_idle() { + err = ERR_MIIBUSY; } - self.start_phy_polling(clk_sel); + self.start_phy_polling(clk_sel); - return err; + return err; } unsafe fn read_phy_reg(&mut self, reg: u16, phy_data: &mut u16) -> usize { - self.read_phy_core(false, 0, reg, phy_data) + self.read_phy_core(false, 0, reg, phy_data) } unsafe fn write_phy_reg(&mut self, reg: u16, phy_data: u16) -> usize { @@ -592,7 +588,7 @@ impl Alx { } unsafe fn read_phy_ext(&mut self, dev: u8, reg: u16, data: &mut u16) -> usize { - self.read_phy_core(true, dev, reg, data) + self.read_phy_core(true, dev, reg, data) } unsafe fn write_phy_ext(&mut self, dev: u8, reg: u16, data: u16) -> usize { @@ -601,109 +597,102 @@ impl Alx { unsafe fn read_phy_dbg(&mut self, reg: u16, data: &mut u16) -> usize { let err = self.write_phy_reg(MII_DBG_ADDR, reg); - if (err > 0) { - return err; + if (err > 0) { + return err; } self.read_phy_reg(MII_DBG_DATA, data) } unsafe fn write_phy_dbg(&mut self, reg: u16, data: u16) -> usize { - let err = self.write_phy_reg(MII_DBG_ADDR, reg); - if (err > 0) { - return err; - } + let err = self.write_phy_reg(MII_DBG_ADDR, reg); + if (err > 0) { + return err; + } - self.write_phy_reg(MII_DBG_DATA, data) + self.write_phy_reg(MII_DBG_DATA, data) } unsafe fn enable_aspm(&mut self, l0s_en: bool, l1_en: bool) { let mut pmctrl: u32; - let rev: u8 = self.revid(); + let rev: u8 = self.revid(); - pmctrl = self.read(PMCTRL); + pmctrl = self.read(PMCTRL); - FIELD_SET32!(pmctrl, PMCTRL_LCKDET_TIMER, PMCTRL_LCKDET_TIMER_DEF); - pmctrl |= PMCTRL_RCVR_WT_1US | - PMCTRL_L1_CLKSW_EN | - PMCTRL_L1_SRDSRX_PWD ; - FIELD_SET32!(pmctrl, PMCTRL_L1REQ_TO, PMCTRL_L1REG_TO_DEF); - FIELD_SET32!(pmctrl, PMCTRL_L1_TIMER, PMCTRL_L1_TIMER_16US); - pmctrl &= !(PMCTRL_L1_SRDS_EN | - PMCTRL_L1_SRDSPLL_EN | - PMCTRL_L1_BUFSRX_EN | - PMCTRL_SADLY_EN | - PMCTRL_HOTRST_WTEN| - PMCTRL_L0S_EN | - PMCTRL_L1_EN | - PMCTRL_ASPM_FCEN | - PMCTRL_TXL1_AFTER_L0S | - PMCTRL_RXL1_AFTER_L0S - ); - if ((rev == REV_A0 || rev == REV_A1) && self.with_cr()) { - pmctrl |= PMCTRL_L1_SRDS_EN | PMCTRL_L1_SRDSPLL_EN; + FIELD_SET32!(pmctrl, PMCTRL_LCKDET_TIMER, PMCTRL_LCKDET_TIMER_DEF); + pmctrl |= PMCTRL_RCVR_WT_1US | PMCTRL_L1_CLKSW_EN | PMCTRL_L1_SRDSRX_PWD; + FIELD_SET32!(pmctrl, PMCTRL_L1REQ_TO, PMCTRL_L1REG_TO_DEF); + FIELD_SET32!(pmctrl, PMCTRL_L1_TIMER, PMCTRL_L1_TIMER_16US); + pmctrl &= !(PMCTRL_L1_SRDS_EN + | PMCTRL_L1_SRDSPLL_EN + | PMCTRL_L1_BUFSRX_EN + | PMCTRL_SADLY_EN + | PMCTRL_HOTRST_WTEN + | PMCTRL_L0S_EN + | PMCTRL_L1_EN + | PMCTRL_ASPM_FCEN + | PMCTRL_TXL1_AFTER_L0S + | PMCTRL_RXL1_AFTER_L0S); + if ((rev == REV_A0 || rev == REV_A1) && self.with_cr()) { + pmctrl |= PMCTRL_L1_SRDS_EN | PMCTRL_L1_SRDSPLL_EN; } - if (l0s_en) { - pmctrl |= (PMCTRL_L0S_EN | PMCTRL_ASPM_FCEN); + if (l0s_en) { + pmctrl |= (PMCTRL_L0S_EN | PMCTRL_ASPM_FCEN); } - if (l1_en) { - pmctrl |= (PMCTRL_L1_EN | PMCTRL_ASPM_FCEN); + if (l1_en) { + pmctrl |= (PMCTRL_L1_EN | PMCTRL_ASPM_FCEN); } - self.write(PMCTRL, pmctrl); + self.write(PMCTRL, pmctrl); } unsafe fn reset_pcie(&mut self) { let mut val: u32; - let rev: u8 = self.revid(); + let rev: u8 = self.revid(); - /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */ + /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */ let mut val16 = ptr::read((self.base + 4) as *const u16); - if (val16 & (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO) == 0 - || val16 & PCI_COMMAND_INTX_DISABLE > 0) { + if (val16 & (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO) == 0 + || val16 & PCI_COMMAND_INTX_DISABLE > 0) + { println!("Fix PCI_COMMAND_INTX_DISABLE"); - val16 = (val16 | (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO)) & !PCI_COMMAND_INTX_DISABLE; + val16 = (val16 | (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO)) + & !PCI_COMMAND_INTX_DISABLE; ptr::write((self.base + 4) as *mut u16, val16); - } + } - /* clear WoL setting/status */ - val = self.read(WOL0); - self.write(WOL0, 0); + /* clear WoL setting/status */ + val = self.read(WOL0); + self.write(WOL0, 0); - /* deflt val of PDLL D3PLLOFF */ - val = self.read(PDLL_TRNS1); - self.write(PDLL_TRNS1, val & !PDLL_TRNS1_D3PLLOFF_EN); + /* deflt val of PDLL D3PLLOFF */ + val = self.read(PDLL_TRNS1); + self.write(PDLL_TRNS1, val & !PDLL_TRNS1_D3PLLOFF_EN); - /* mask some pcie error bits */ - val = self.read(UE_SVRT); - val &= !(UE_SVRT_DLPROTERR | UE_SVRT_FCPROTERR); - self.write(UE_SVRT, val); + /* mask some pcie error bits */ + val = self.read(UE_SVRT); + val &= !(UE_SVRT_DLPROTERR | UE_SVRT_FCPROTERR); + self.write(UE_SVRT, val); - /* wol 25M & pclk */ - val = self.read(MASTER); - if ((rev == REV_A0 || rev == REV_A1) && self.with_cr()) { - if ((val & MASTER_WAKEN_25M) == 0 || - (val & MASTER_PCLKSEL_SRDS) == 0) { - self.write(MASTER, - val | MASTER_PCLKSEL_SRDS | - MASTER_WAKEN_25M); - } - } else { - if ((val & MASTER_WAKEN_25M) == 0 || - (val & MASTER_PCLKSEL_SRDS) != 0) { - self.write(MASTER, - (val & !MASTER_PCLKSEL_SRDS) | - MASTER_WAKEN_25M); - } - } + /* wol 25M & pclk */ + val = self.read(MASTER); + if ((rev == REV_A0 || rev == REV_A1) && self.with_cr()) { + if ((val & MASTER_WAKEN_25M) == 0 || (val & MASTER_PCLKSEL_SRDS) == 0) { + self.write(MASTER, val | MASTER_PCLKSEL_SRDS | MASTER_WAKEN_25M); + } + } else { + if ((val & MASTER_WAKEN_25M) == 0 || (val & MASTER_PCLKSEL_SRDS) != 0) { + self.write(MASTER, (val & !MASTER_PCLKSEL_SRDS) | MASTER_WAKEN_25M); + } + } - /* ASPM setting */ + /* ASPM setting */ let l0s_en = self.cap & CAP_L0S > 0; let l1_en = self.cap & CAP_L1 > 0; - self.enable_aspm(l0s_en, l1_en); + self.enable_aspm(l0s_en, l1_en); - udelay(10); + udelay(10); } unsafe fn reset_phy(&mut self) { @@ -711,117 +700,126 @@ impl Alx { let mut val: u32; let mut phy_val: u16 = 0; - /* (DSP)reset PHY core */ - val = self.read(PHY_CTRL); - val &= !(PHY_CTRL_DSPRST_OUT | PHY_CTRL_IDDQ | - PHY_CTRL_GATE_25M | PHY_CTRL_POWER_DOWN | - PHY_CTRL_CLS); - val |= PHY_CTRL_RST_ANALOG; + /* (DSP)reset PHY core */ + val = self.read(PHY_CTRL); + val &= !(PHY_CTRL_DSPRST_OUT + | PHY_CTRL_IDDQ + | PHY_CTRL_GATE_25M + | PHY_CTRL_POWER_DOWN + | PHY_CTRL_CLS); + val |= PHY_CTRL_RST_ANALOG; - if (! self.hib_patch) { - val |= (PHY_CTRL_HIB_PULSE | PHY_CTRL_HIB_EN); - } else { - val &= !(PHY_CTRL_HIB_PULSE | PHY_CTRL_HIB_EN); + if (!self.hib_patch) { + val |= (PHY_CTRL_HIB_PULSE | PHY_CTRL_HIB_EN); + } else { + val &= !(PHY_CTRL_HIB_PULSE | PHY_CTRL_HIB_EN); } - self.write(PHY_CTRL, val); - udelay(10); - self.write(PHY_CTRL, val | PHY_CTRL_DSPRST_OUT); + self.write(PHY_CTRL, val); + udelay(10); + self.write(PHY_CTRL, val | PHY_CTRL_DSPRST_OUT); - /* delay 800us */ + /* delay 800us */ i = 0; - while (i < PHY_CTRL_DSPRST_TO) { - udelay(10); + while (i < PHY_CTRL_DSPRST_TO) { + udelay(10); i += 1; } - if ! self.is_fpga { - /* phy power saving & hib */ - if (! self.hib_patch) { - self.write_phy_dbg(MIIDBG_LEGCYPS, LEGCYPS_DEF); - self.write_phy_dbg(MIIDBG_SYSMODCTRL, - SYSMODCTRL_IECHOADJ_DEF); - self.write_phy_ext(MIIEXT_PCS, MIIEXT_VDRVBIAS, VDRVBIAS_DEF); - } else { - self.write_phy_dbg(MIIDBG_LEGCYPS, - LEGCYPS_DEF & !LEGCYPS_EN); - self.write_phy_dbg(MIIDBG_HIBNEG, HIBNEG_NOHIB); - self.write_phy_dbg(MIIDBG_GREENCFG, GREENCFG_DEF); - } + if !self.is_fpga { + /* phy power saving & hib */ + if (!self.hib_patch) { + self.write_phy_dbg(MIIDBG_LEGCYPS, LEGCYPS_DEF); + self.write_phy_dbg(MIIDBG_SYSMODCTRL, SYSMODCTRL_IECHOADJ_DEF); + self.write_phy_ext(MIIEXT_PCS, MIIEXT_VDRVBIAS, VDRVBIAS_DEF); + } else { + self.write_phy_dbg(MIIDBG_LEGCYPS, LEGCYPS_DEF & !LEGCYPS_EN); + self.write_phy_dbg(MIIDBG_HIBNEG, HIBNEG_NOHIB); + self.write_phy_dbg(MIIDBG_GREENCFG, GREENCFG_DEF); + } - /* EEE advertisement */ - if (self.cap & CAP_AZ > 0) { + /* EEE advertisement */ + if (self.cap & CAP_AZ > 0) { let eeeadv = if self.cap & CAP_GIGA > 0 { LOCAL_EEEADV_1000BT | LOCAL_EEEADV_100BT } else { LOCAL_EEEADV_100BT }; - self.write_phy_ext(MIIEXT_ANEG, MIIEXT_LOCAL_EEEADV, eeeadv); - /* half amplify */ - self.write_phy_dbg(MIIDBG_AZ_ANADECT, - AZ_ANADECT_DEF); - } else { - val = self.read(LPI_CTRL); - self.write(LPI_CTRL, val & (!LPI_CTRL_EN)); - self.write_phy_ext(MIIEXT_ANEG, - MIIEXT_LOCAL_EEEADV, 0); - } + self.write_phy_ext(MIIEXT_ANEG, MIIEXT_LOCAL_EEEADV, eeeadv); + /* half amplify */ + self.write_phy_dbg(MIIDBG_AZ_ANADECT, AZ_ANADECT_DEF); + } else { + val = self.read(LPI_CTRL); + self.write(LPI_CTRL, val & (!LPI_CTRL_EN)); + self.write_phy_ext(MIIEXT_ANEG, MIIEXT_LOCAL_EEEADV, 0); + } - /* phy power saving */ - self.write_phy_dbg(MIIDBG_TST10BTCFG, TST10BTCFG_DEF); - self.write_phy_dbg(MIIDBG_SRDSYSMOD, SRDSYSMOD_DEF); - self.write_phy_dbg(MIIDBG_TST100BTCFG, TST100BTCFG_DEF); - self.write_phy_dbg(MIIDBG_ANACTRL, ANACTRL_DEF); - self.read_phy_dbg(MIIDBG_GREENCFG2, &mut phy_val); - self.write_phy_dbg(MIIDBG_GREENCFG2, phy_val & (!GREENCFG2_GATE_DFSE_EN)); - /* rtl8139c, 120m issue */ - self.write_phy_ext(MIIEXT_ANEG, MIIEXT_NLP78, MIIEXT_NLP78_120M_DEF); - self.write_phy_ext(MIIEXT_ANEG, MIIEXT_S3DIG10, MIIEXT_S3DIG10_DEF); + /* phy power saving */ + self.write_phy_dbg(MIIDBG_TST10BTCFG, TST10BTCFG_DEF); + self.write_phy_dbg(MIIDBG_SRDSYSMOD, SRDSYSMOD_DEF); + self.write_phy_dbg(MIIDBG_TST100BTCFG, TST100BTCFG_DEF); + self.write_phy_dbg(MIIDBG_ANACTRL, ANACTRL_DEF); + self.read_phy_dbg(MIIDBG_GREENCFG2, &mut phy_val); + self.write_phy_dbg(MIIDBG_GREENCFG2, phy_val & (!GREENCFG2_GATE_DFSE_EN)); + /* rtl8139c, 120m issue */ + self.write_phy_ext(MIIEXT_ANEG, MIIEXT_NLP78, MIIEXT_NLP78_120M_DEF); + self.write_phy_ext(MIIEXT_ANEG, MIIEXT_S3DIG10, MIIEXT_S3DIG10_DEF); - if (self.lnk_patch) { - /* Turn off half amplitude */ - self.read_phy_ext(MIIEXT_PCS, MIIEXT_CLDCTRL3, &mut phy_val); - self.write_phy_ext(MIIEXT_PCS, MIIEXT_CLDCTRL3, phy_val | CLDCTRL3_BP_CABLE1TH_DET_GT); - /* Turn off Green feature */ - self.read_phy_dbg(MIIDBG_GREENCFG2, &mut phy_val); - self.write_phy_dbg(MIIDBG_GREENCFG2, phy_val | GREENCFG2_BP_GREEN); - /* Turn off half Bias */ - self.read_phy_ext(MIIEXT_PCS, MIIEXT_CLDCTRL5, &mut phy_val); - self.write_phy_ext(MIIEXT_PCS, MIIEXT_CLDCTRL5, phy_val | CLDCTRL5_BP_VD_HLFBIAS); - } + if (self.lnk_patch) { + /* Turn off half amplitude */ + self.read_phy_ext(MIIEXT_PCS, MIIEXT_CLDCTRL3, &mut phy_val); + self.write_phy_ext( + MIIEXT_PCS, + MIIEXT_CLDCTRL3, + phy_val | CLDCTRL3_BP_CABLE1TH_DET_GT, + ); + /* Turn off Green feature */ + self.read_phy_dbg(MIIDBG_GREENCFG2, &mut phy_val); + self.write_phy_dbg(MIIDBG_GREENCFG2, phy_val | GREENCFG2_BP_GREEN); + /* Turn off half Bias */ + self.read_phy_ext(MIIEXT_PCS, MIIEXT_CLDCTRL5, &mut phy_val); + self.write_phy_ext( + MIIEXT_PCS, + MIIEXT_CLDCTRL5, + phy_val | CLDCTRL5_BP_VD_HLFBIAS, + ); + } } - /* set phy interrupt mask */ - self.write_phy_reg(MII_IER, IER_LINK_UP | IER_LINK_DOWN); + /* set phy interrupt mask */ + self.write_phy_reg(MII_IER, IER_LINK_UP | IER_LINK_DOWN); } - unsafe fn stop_mac(&mut self) -> usize { let txq: u32; let rxq: u32; let mut val: u32; let mut i: u32; - rxq = self.read(RXQ0); - self.write(RXQ0, rxq & (!RXQ0_EN)); - txq = self.read(TXQ0); - self.write(TXQ0, txq & (!TXQ0_EN)); + rxq = self.read(RXQ0); + self.write(RXQ0, rxq & (!RXQ0_EN)); + txq = self.read(TXQ0); + self.write(TXQ0, txq & (!TXQ0_EN)); - udelay(40); + udelay(40); - self.rx_ctrl &= !(MAC_CTRL_RX_EN | MAC_CTRL_TX_EN); - self.write(MAC_CTRL, self.rx_ctrl); + self.rx_ctrl &= !(MAC_CTRL_RX_EN | MAC_CTRL_TX_EN); + self.write(MAC_CTRL, self.rx_ctrl); i = 0; - while i < DMA_MAC_RST_TO { - val = self.read(MAC_STS); - if (val & MAC_STS_IDLE == 0) { - break; + while i < DMA_MAC_RST_TO { + val = self.read(MAC_STS); + if (val & MAC_STS_IDLE == 0) { + break; } - udelay(10); + udelay(10); i += 1; - } + } - return if (DMA_MAC_RST_TO == i) { ERR_RSTMAC as usize } else { 0 }; + return if (DMA_MAC_RST_TO == i) { + ERR_RSTMAC as usize + } else { + 0 + }; } unsafe fn start_mac(&mut self) { @@ -829,66 +827,69 @@ impl Alx { let txq: u32; let rxq: u32; - rxq = self.read(RXQ0); - self.write(RXQ0, rxq | RXQ0_EN); - txq = self.read(TXQ0); - self.write(TXQ0, txq | TXQ0_EN); + rxq = self.read(RXQ0); + self.write(RXQ0, rxq | RXQ0_EN); + txq = self.read(TXQ0); + self.write(TXQ0, txq | TXQ0_EN); - mac = self.rx_ctrl; - if (self.link_duplex == FULL_DUPLEX) { - mac |= MAC_CTRL_FULLD; - } else { - mac &= !MAC_CTRL_FULLD; - } - FIELD_SET32!(mac, MAC_CTRL_SPEED, if self.link_speed == 1000 { - MAC_CTRL_SPEED_1000 + mac = self.rx_ctrl; + if (self.link_duplex == FULL_DUPLEX) { + mac |= MAC_CTRL_FULLD; } else { - MAC_CTRL_SPEED_10_100 - }); - mac |= MAC_CTRL_TX_EN | MAC_CTRL_RX_EN; - self.rx_ctrl = mac; - self.write(MAC_CTRL, mac); + mac &= !MAC_CTRL_FULLD; + } + FIELD_SET32!( + mac, + MAC_CTRL_SPEED, + if self.link_speed == 1000 { + MAC_CTRL_SPEED_1000 + } else { + MAC_CTRL_SPEED_10_100 + } + ); + mac |= MAC_CTRL_TX_EN | MAC_CTRL_RX_EN; + self.rx_ctrl = mac; + self.write(MAC_CTRL, mac); } unsafe fn reset_osc(&mut self, rev: u8) { let mut val: u32; let mut val2: u32; - /* clear Internal OSC settings, switching OSC by hw itself */ - val = self.read(MISC3); - self.write(MISC3, - (val & !MISC3_25M_BY_SW) | MISC3_25M_NOTO_INTNL); + /* clear Internal OSC settings, switching OSC by hw itself */ + val = self.read(MISC3); + self.write(MISC3, (val & !MISC3_25M_BY_SW) | MISC3_25M_NOTO_INTNL); - /* 25M clk from chipset may be unstable 1s after de-assert of - * PERST, driver need re-calibrate before enter Sleep for WoL - */ - val = self.read(MISC); - if (rev >= REV_B0) { - /* restore over current protection def-val, - * this val could be reset by MAC-RST - */ - FIELD_SET32!(val, MISC_PSW_OCP, MISC_PSW_OCP_DEF); - /* a 0->1 change will update the internal val of osc */ - val &= !MISC_INTNLOSC_OPEN; - self.write(MISC, val); - self.write(MISC, val | MISC_INTNLOSC_OPEN); - /* hw will automatically dis OSC after cab. */ - val2 = self.read(MSIC2); - val2 &= !MSIC2_CALB_START; - self.write(MSIC2, val2); - self.write(MSIC2, val2 | MSIC2_CALB_START); - } else { - val &= !MISC_INTNLOSC_OPEN; - /* disable isoloate for A0 */ - if ((rev == REV_A0 || rev == REV_A1)) { - val &= !MISC_ISO_EN; + /* 25M clk from chipset may be unstable 1s after de-assert of + * PERST, driver need re-calibrate before enter Sleep for WoL + */ + val = self.read(MISC); + if (rev >= REV_B0) { + /* restore over current protection def-val, + * this val could be reset by MAC-RST + */ + FIELD_SET32!(val, MISC_PSW_OCP, MISC_PSW_OCP_DEF); + /* a 0->1 change will update the internal val of osc */ + val &= !MISC_INTNLOSC_OPEN; + self.write(MISC, val); + self.write(MISC, val | MISC_INTNLOSC_OPEN); + /* hw will automatically dis OSC after cab. */ + val2 = self.read(MSIC2); + val2 &= !MSIC2_CALB_START; + self.write(MSIC2, val2); + self.write(MSIC2, val2 | MSIC2_CALB_START); + } else { + val &= !MISC_INTNLOSC_OPEN; + /* disable isoloate for A0 */ + if (rev == REV_A0 || rev == REV_A1) { + val &= !MISC_ISO_EN; } - self.write(MISC, val | MISC_INTNLOSC_OPEN); - self.write(MISC, val); - } + self.write(MISC, val | MISC_INTNLOSC_OPEN); + self.write(MISC, val); + } - udelay(20); + udelay(20); } unsafe fn reset_mac(&mut self) -> usize { @@ -899,213 +900,210 @@ impl Alx { let rev: u8; let a_cr: bool; - pmctrl = 0; - rev = self.revid(); - a_cr = (rev == REV_A0 || rev == REV_A1) && self.with_cr(); + pmctrl = 0; + rev = self.revid(); + a_cr = (rev == REV_A0 || rev == REV_A1) && self.with_cr(); - /* disable all interrupts, RXQ/TXQ */ - self.write(MSIX_MASK, 0xFFFFFFFF); - self.write(IMR, 0); - self.write(ISR, ISR_DIS); + /* disable all interrupts, RXQ/TXQ */ + self.write(MSIX_MASK, 0xFFFFFFFF); + self.write(IMR, 0); + self.write(ISR, ISR_DIS); - ret = self.stop_mac(); - if (ret > 0) { - return ret; + ret = self.stop_mac(); + if (ret > 0) { + return ret; } - /* mac reset workaroud */ - self.write(RFD_PIDX, 1); + /* mac reset workaroud */ + self.write(RFD_PIDX, 1); - /* dis l0s/l1 before mac reset */ - if (a_cr) { - pmctrl = self.read(PMCTRL); - if ((pmctrl & (PMCTRL_L1_EN | PMCTRL_L0S_EN)) != 0) { - self.write(PMCTRL, pmctrl & !(PMCTRL_L1_EN | PMCTRL_L0S_EN)); - } - } + /* dis l0s/l1 before mac reset */ + if (a_cr) { + pmctrl = self.read(PMCTRL); + if ((pmctrl & (PMCTRL_L1_EN | PMCTRL_L0S_EN)) != 0) { + self.write(PMCTRL, pmctrl & !(PMCTRL_L1_EN | PMCTRL_L0S_EN)); + } + } - /* reset whole mac safely */ - val = self.read(MASTER); - self.write(MASTER, val | MASTER_DMA_MAC_RST | MASTER_OOB_DIS); + /* reset whole mac safely */ + val = self.read(MASTER); + self.write(MASTER, val | MASTER_DMA_MAC_RST | MASTER_OOB_DIS); - /* make sure it's real idle */ - udelay(10); + /* make sure it's real idle */ + udelay(10); i = 0; - while (i < DMA_MAC_RST_TO) { - val = self.read(RFD_PIDX); - if (val == 0) { - break; - } - udelay(10); - i += 1; - } while (i < DMA_MAC_RST_TO) { - val = self.read(MASTER); - if ((val & MASTER_DMA_MAC_RST) == 0) { - break; + val = self.read(RFD_PIDX); + if (val == 0) { + break; } - udelay(10); + udelay(10); i += 1; - } - if (i == DMA_MAC_RST_TO) { - return ERR_RSTMAC; } - udelay(10); - - if (a_cr) { - /* set MASTER_PCLKSEL_SRDS (affect by soft-rst, PERST) */ - self.write(MASTER, val | MASTER_PCLKSEL_SRDS); - /* resoter l0s / l1 */ - if (pmctrl & (PMCTRL_L1_EN | PMCTRL_L0S_EN) > 0) { - self.write(PMCTRL, pmctrl); + while (i < DMA_MAC_RST_TO) { + val = self.read(MASTER); + if ((val & MASTER_DMA_MAC_RST) == 0) { + break; } - } - - self.reset_osc(rev); - /* clear Internal OSC settings, switching OSC by hw itself, - * disable isoloate for A version - */ - val = self.read(MISC3); - self.write(MISC3, (val & !MISC3_25M_BY_SW) | MISC3_25M_NOTO_INTNL); - val = self.read(MISC); - val &= !MISC_INTNLOSC_OPEN; - if ((rev == REV_A0 || rev == REV_A1)) { - val &= !MISC_ISO_EN; + udelay(10); + i += 1; } - self.write(MISC, val); - udelay(20); + if (i == DMA_MAC_RST_TO) { + return ERR_RSTMAC; + } + udelay(10); - /* driver control speed/duplex, hash-alg */ - self.write(MAC_CTRL, self.rx_ctrl); - - /* clk sw */ - val = self.read(SERDES); - self.write(SERDES, - val | SERDES_MACCLK_SLWDWN | SERDES_PHYCLK_SLWDWN); - - /* mac reset cause MDIO ctrl restore non-polling status */ - if (self.is_fpga) { - self.start_phy_polling(MDIO_CLK_SEL_25MD128); + if (a_cr) { + /* set MASTER_PCLKSEL_SRDS (affect by soft-rst, PERST) */ + self.write(MASTER, val | MASTER_PCLKSEL_SRDS); + /* resoter l0s / l1 */ + if (pmctrl & (PMCTRL_L1_EN | PMCTRL_L0S_EN) > 0) { + self.write(PMCTRL, pmctrl); + } } + self.reset_osc(rev); + /* clear Internal OSC settings, switching OSC by hw itself, + * disable isoloate for A version + */ + val = self.read(MISC3); + self.write(MISC3, (val & !MISC3_25M_BY_SW) | MISC3_25M_NOTO_INTNL); + val = self.read(MISC); + val &= !MISC_INTNLOSC_OPEN; + if (rev == REV_A0 || rev == REV_A1) { + val &= !MISC_ISO_EN; + } + self.write(MISC, val); + udelay(20); - return ret; + /* driver control speed/duplex, hash-alg */ + self.write(MAC_CTRL, self.rx_ctrl); + + /* clk sw */ + val = self.read(SERDES); + self.write(SERDES, val | SERDES_MACCLK_SLWDWN | SERDES_PHYCLK_SLWDWN); + + /* mac reset cause MDIO ctrl restore non-polling status */ + if (self.is_fpga) { + self.start_phy_polling(MDIO_CLK_SEL_25MD128); + } + + return ret; } unsafe fn ethadv_to_hw_cfg(&self, ethadv_cfg: u32) -> u32 { - let mut cfg: u32 = 0; + let mut cfg: u32 = 0; - if (ethadv_cfg & ADVERTISED_Autoneg > 0) { - cfg |= DRV_PHY_AUTO; - if (ethadv_cfg & ADVERTISED_10baseT_Half > 0) { - cfg |= DRV_PHY_10; + if (ethadv_cfg & ADVERTISED_Autoneg > 0) { + cfg |= DRV_PHY_AUTO; + if (ethadv_cfg & ADVERTISED_10baseT_Half > 0) { + cfg |= DRV_PHY_10; } - if (ethadv_cfg & ADVERTISED_10baseT_Full > 0) { - cfg |= DRV_PHY_10 | DRV_PHY_DUPLEX; + if (ethadv_cfg & ADVERTISED_10baseT_Full > 0) { + cfg |= DRV_PHY_10 | DRV_PHY_DUPLEX; } - if (ethadv_cfg & ADVERTISED_100baseT_Half > 0) { - cfg |= DRV_PHY_100; + if (ethadv_cfg & ADVERTISED_100baseT_Half > 0) { + cfg |= DRV_PHY_100; } - if (ethadv_cfg & ADVERTISED_100baseT_Full > 0) { - cfg |= DRV_PHY_100 | DRV_PHY_DUPLEX; + if (ethadv_cfg & ADVERTISED_100baseT_Full > 0) { + cfg |= DRV_PHY_100 | DRV_PHY_DUPLEX; } - if (ethadv_cfg & ADVERTISED_1000baseT_Half > 0) { - cfg |= DRV_PHY_1000; + if (ethadv_cfg & ADVERTISED_1000baseT_Half > 0) { + cfg |= DRV_PHY_1000; } - if (ethadv_cfg & ADVERTISED_1000baseT_Full > 0) { - cfg |= DRV_PHY_100 | DRV_PHY_DUPLEX; + if (ethadv_cfg & ADVERTISED_1000baseT_Full > 0) { + cfg |= DRV_PHY_100 | DRV_PHY_DUPLEX; } - if (ethadv_cfg & ADVERTISED_Pause > 0) { - cfg |= ADVERTISE_PAUSE_CAP; + if (ethadv_cfg & ADVERTISED_Pause > 0) { + cfg |= ADVERTISE_PAUSE_CAP; } - if (ethadv_cfg & ADVERTISED_Asym_Pause > 0) { - cfg |= ADVERTISE_PAUSE_ASYM; + if (ethadv_cfg & ADVERTISED_Asym_Pause > 0) { + cfg |= ADVERTISE_PAUSE_ASYM; } - if (self.cap & CAP_AZ > 0) { - cfg |= DRV_PHY_EEE; + if (self.cap & CAP_AZ > 0) { + cfg |= DRV_PHY_EEE; } - } else { - match (ethadv_cfg) { - ADVERTISED_10baseT_Half => { - cfg |= DRV_PHY_10; - }, - ADVERTISED_100baseT_Half => { - cfg |= DRV_PHY_100; - }, - ADVERTISED_10baseT_Full => { - cfg |= DRV_PHY_10 | DRV_PHY_DUPLEX; - }, - ADVERTISED_100baseT_Full => { - cfg |= DRV_PHY_100 | DRV_PHY_DUPLEX; - }, - _ => () - } - } + } else { + match (ethadv_cfg) { + ADVERTISED_10baseT_Half => { + cfg |= DRV_PHY_10; + } + ADVERTISED_100baseT_Half => { + cfg |= DRV_PHY_100; + } + ADVERTISED_10baseT_Full => { + cfg |= DRV_PHY_10 | DRV_PHY_DUPLEX; + } + ADVERTISED_100baseT_Full => { + cfg |= DRV_PHY_100 | DRV_PHY_DUPLEX; + } + _ => (), + } + } - return cfg; + return cfg; } unsafe fn setup_speed_duplex(&mut self, ethadv: u32, flowctrl: u8) -> usize { let mut adv: u32; let mut giga: u16; let mut cr: u16; - let mut val: u32; - let mut err: usize = 0; + let mut val: u32; + let mut err: usize = 0; - /* clear flag */ - self.write_phy_reg(MII_DBG_ADDR, 0); - val = self.read(DRV); - FIELD_SET32!(val, DRV_PHY, 0); + /* clear flag */ + self.write_phy_reg(MII_DBG_ADDR, 0); + val = self.read(DRV); + FIELD_SET32!(val, DRV_PHY, 0); - if (ethadv & ADVERTISED_Autoneg > 0) { - adv = ADVERTISE_CSMA; - adv |= ethtool_adv_to_mii_adv_t(ethadv); + if (ethadv & ADVERTISED_Autoneg > 0) { + adv = ADVERTISE_CSMA; + adv |= ethtool_adv_to_mii_adv_t(ethadv); - if (flowctrl & FC_ANEG == FC_ANEG) { - if (flowctrl & FC_RX > 0) { - adv |= ADVERTISED_Pause; - if (flowctrl & FC_TX == 0) { - adv |= ADVERTISED_Asym_Pause; + if (flowctrl & FC_ANEG == FC_ANEG) { + if (flowctrl & FC_RX > 0) { + adv |= ADVERTISED_Pause; + if (flowctrl & FC_TX == 0) { + adv |= ADVERTISED_Asym_Pause; } - } else if (flowctrl & FC_TX > 0) { - adv |= ADVERTISED_Asym_Pause; + } else if (flowctrl & FC_TX > 0) { + adv |= ADVERTISED_Asym_Pause; } - } - giga = 0; - if (self.cap & CAP_GIGA > 0) { - giga = ethtool_adv_to_mii_ctrl1000_t(ethadv) as u16; + } + giga = 0; + if (self.cap & CAP_GIGA > 0) { + giga = ethtool_adv_to_mii_ctrl1000_t(ethadv) as u16; } - cr = BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART; + cr = BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART; - if (self.write_phy_reg(MII_ADVERTISE, adv as u16) > 0 || - self.write_phy_reg(MII_CTRL1000, giga) > 0 || - self.write_phy_reg(MII_BMCR, cr) > 0) { - err = ERR_MIIBUSY; + if (self.write_phy_reg(MII_ADVERTISE, adv as u16) > 0 + || self.write_phy_reg(MII_CTRL1000, giga) > 0 + || self.write_phy_reg(MII_BMCR, cr) > 0) + { + err = ERR_MIIBUSY; } - } else { - cr = BMCR_RESET; - if (ethadv == ADVERTISED_100baseT_Half || - ethadv == ADVERTISED_100baseT_Full) { - cr |= BMCR_SPEED100; + } else { + cr = BMCR_RESET; + if (ethadv == ADVERTISED_100baseT_Half || ethadv == ADVERTISED_100baseT_Full) { + cr |= BMCR_SPEED100; } - if (ethadv == ADVERTISED_10baseT_Full || - ethadv == ADVERTISED_100baseT_Full) { - cr |= BMCR_FULLDPLX; + if (ethadv == ADVERTISED_10baseT_Full || ethadv == ADVERTISED_100baseT_Full) { + cr |= BMCR_FULLDPLX; } - err = self.write_phy_reg(MII_BMCR, cr); - } + err = self.write_phy_reg(MII_BMCR, cr); + } - if (err == 0) { - self.write_phy_reg(MII_DBG_ADDR, PHY_INITED); - /* save config to HW */ - val |= self.ethadv_to_hw_cfg(ethadv); - } + if (err == 0) { + self.write_phy_reg(MII_DBG_ADDR, PHY_INITED); + /* save config to HW */ + val |= self.ethadv_to_hw_cfg(ethadv); + } - self.write(DRV, val); + self.write(DRV, val); - return err; + return err; } unsafe fn get_perm_macaddr(&mut self) -> [u8; 6] { @@ -1117,55 +1115,59 @@ impl Alx { (mac_low >> 16) as u8, (mac_low >> 24) as u8, mac_high as u8, - (mac_high >> 8) as u8 + (mac_high >> 8) as u8, ] } unsafe fn get_phy_link(&mut self, link_up: &mut bool, speed: &mut u16) -> usize { let mut bmsr: u16 = 0; let mut giga: u16 = 0; - let mut err: usize; + let mut err: usize; - err = self.read_phy_reg(MII_BMSR, &mut bmsr); - err = self.read_phy_reg(MII_BMSR, &mut bmsr); - if (err > 0) { - return err; - } - - if (bmsr & BMSR_LSTATUS == 0) { - *link_up = false; - return err; - } - - *link_up = true; - - /* speed/duplex result is saved in PHY Specific Status Register */ - err = self.read_phy_reg(MII_GIGA_PSSR, &mut giga); - if (err > 0) { + err = self.read_phy_reg(MII_BMSR, &mut bmsr); + err = self.read_phy_reg(MII_BMSR, &mut bmsr); + if (err > 0) { return err; } - if (giga & GIGA_PSSR_SPD_DPLX_RESOLVED == 0) { + if (bmsr & BMSR_LSTATUS == 0) { + *link_up = false; + return err; + } + + *link_up = true; + + /* speed/duplex result is saved in PHY Specific Status Register */ + err = self.read_phy_reg(MII_GIGA_PSSR, &mut giga); + if (err > 0) { + return err; + } + + if (giga & GIGA_PSSR_SPD_DPLX_RESOLVED == 0) { println!("PHY SPD/DPLX unresolved: {:X}", giga); - err = (-EINVAL) as usize; + err = (-EINVAL) as usize; } else { - match (giga & GIGA_PSSR_SPEED) { - GIGA_PSSR_1000MBS => *speed = SPEED_1000, - GIGA_PSSR_100MBS => *speed = SPEED_100, - GIGA_PSSR_10MBS => *speed = SPEED_10, - _ => { + match (giga & GIGA_PSSR_SPEED) { + GIGA_PSSR_1000MBS => *speed = SPEED_1000, + GIGA_PSSR_100MBS => *speed = SPEED_100, + GIGA_PSSR_10MBS => *speed = SPEED_10, + _ => { println!("PHY SPD/DPLX unresolved: {:X}", giga); - err = (-EINVAL) as usize; + err = (-EINVAL) as usize; } - } - *speed += if (giga & GIGA_PSSR_DPLX > 0) { FULL_DUPLEX as u16 } else { HALF_DUPLEX as u16 }; + } + *speed += if (giga & GIGA_PSSR_DPLX > 0) { + FULL_DUPLEX as u16 + } else { + HALF_DUPLEX as u16 + }; } - return err; + return err; } fn show_speed(&self, speed: u16) { - let desc = if speed == SPEED_1000 + FULL_DUPLEX as u16 { + let desc = if speed == SPEED_1000 + FULL_DUPLEX as u16 { "1 Gbps Full" } else if speed == SPEED_100 + FULL_DUPLEX as u16 { "100 Mbps Full" @@ -1189,188 +1191,185 @@ impl Alx { let val16: u16; let chip_rev = self.revid(); - /* mac address */ - //TODO alx_set_macaddr(hw, self.mac_addr); + /* mac address */ + //TODO alx_set_macaddr(hw, self.mac_addr); - /* clk gating */ - self.write(CLK_GATE, CLK_GATE_ALL_A0); + /* clk gating */ + self.write(CLK_GATE, CLK_GATE_ALL_A0); - /* idle timeout to switch clk_125M */ - if (chip_rev >= REV_B0) { - self.write(IDLE_DECISN_TIMER, - IDLE_DECISN_TIMER_DEF); - } - - /* stats refresh timeout */ - self.write(SMB_TIMER, self.smb_timer * 500); - - /* intr moduration */ - val = self.read(MASTER); - val = val | MASTER_IRQMOD2_EN | - MASTER_IRQMOD1_EN | - MASTER_SYSALVTIMER_EN; - self.write(MASTER, val); - self.write(IRQ_MODU_TIMER, - FIELDX!(IRQ_MODU_TIMER1, self.imt >> 1)); - /* intr re-trig timeout */ - self.write(INT_RETRIG, INT_RETRIG_TO); - /* tpd threshold to trig int */ - self.write(TINT_TPD_THRSHLD, self.ith_tpd); - self.write(TINT_TIMER, self.imt as u32); - - /* mtu, 8:fcs+vlan */ - raw_mtu = (self.mtu + ETH_HLEN) as u32; - self.write(MTU, raw_mtu + 8); - if (raw_mtu > MTU_JUMBO_TH) { - self.rx_ctrl &= !MAC_CTRL_FAST_PAUSE; + /* idle timeout to switch clk_125M */ + if (chip_rev >= REV_B0) { + self.write(IDLE_DECISN_TIMER, IDLE_DECISN_TIMER_DEF); } - /* txq */ - if ((raw_mtu + 8) < TXQ1_JUMBO_TSO_TH) { - val = (raw_mtu + 8 + 7) >> 3; + /* stats refresh timeout */ + self.write(SMB_TIMER, self.smb_timer * 500); + + /* intr moduration */ + val = self.read(MASTER); + val = val | MASTER_IRQMOD2_EN | MASTER_IRQMOD1_EN | MASTER_SYSALVTIMER_EN; + self.write(MASTER, val); + self.write(IRQ_MODU_TIMER, FIELDX!(IRQ_MODU_TIMER1, self.imt >> 1)); + /* intr re-trig timeout */ + self.write(INT_RETRIG, INT_RETRIG_TO); + /* tpd threshold to trig int */ + self.write(TINT_TPD_THRSHLD, self.ith_tpd); + self.write(TINT_TIMER, self.imt as u32); + + /* mtu, 8:fcs+vlan */ + raw_mtu = (self.mtu + ETH_HLEN) as u32; + self.write(MTU, raw_mtu + 8); + if (raw_mtu > MTU_JUMBO_TH) { + self.rx_ctrl &= !MAC_CTRL_FAST_PAUSE; + } + + /* txq */ + if ((raw_mtu + 8) < TXQ1_JUMBO_TSO_TH) { + val = (raw_mtu + 8 + 7) >> 3; } else { - val = TXQ1_JUMBO_TSO_TH >> 3; + val = TXQ1_JUMBO_TSO_TH >> 3; } - self.write(TXQ1, val | TXQ1_ERRLGPKT_DROP_EN); + self.write(TXQ1, val | TXQ1_ERRLGPKT_DROP_EN); /* TODO - max_payload = alx_get_readrq(hw) >> 8; - /* - * if BIOS had changed the default dma read max length, - * restore it to default value - */ - if (max_payload < DEV_CTRL_MAXRRS_MIN) - alx_set_readrq(hw, 128 << DEV_CTRL_MAXRRS_MIN); + max_payload = alx_get_readrq(hw) >> 8; + /* + * if BIOS had changed the default dma read max length, + * restore it to default value + */ + if (max_payload < DEV_CTRL_MAXRRS_MIN) + alx_set_readrq(hw, 128 << DEV_CTRL_MAXRRS_MIN); */ max_payload = 128 << DEV_CTRL_MAXRRS_MIN; - val = FIELDX!(TXQ0_TPD_BURSTPREF, TXQ_TPD_BURSTPREF_DEF) | - TXQ0_MODE_ENHANCE | - TXQ0_LSO_8023_EN | - TXQ0_SUPT_IPOPT | - FIELDX!(TXQ0_TXF_BURST_PREF, TXQ_TXF_BURST_PREF_DEF); - self.write(TXQ0, val); - val = FIELDX!(HQTPD_Q1_NUMPREF, TXQ_TPD_BURSTPREF_DEF) | - FIELDX!(HQTPD_Q2_NUMPREF, TXQ_TPD_BURSTPREF_DEF) | - FIELDX!(HQTPD_Q3_NUMPREF, TXQ_TPD_BURSTPREF_DEF) | - HQTPD_BURST_EN; - self.write(HQTPD, val); + val = FIELDX!(TXQ0_TPD_BURSTPREF, TXQ_TPD_BURSTPREF_DEF) + | TXQ0_MODE_ENHANCE + | TXQ0_LSO_8023_EN + | TXQ0_SUPT_IPOPT + | FIELDX!(TXQ0_TXF_BURST_PREF, TXQ_TXF_BURST_PREF_DEF); + self.write(TXQ0, val); + val = FIELDX!(HQTPD_Q1_NUMPREF, TXQ_TPD_BURSTPREF_DEF) + | FIELDX!(HQTPD_Q2_NUMPREF, TXQ_TPD_BURSTPREF_DEF) + | FIELDX!(HQTPD_Q3_NUMPREF, TXQ_TPD_BURSTPREF_DEF) + | HQTPD_BURST_EN; + self.write(HQTPD, val); - /* rxq, flow control */ - val = self.read(SRAM5); - val = FIELD_GETX!(val, SRAM_RXF_LEN) << 3; - if (val > SRAM_RXF_LEN_8K) { - val16 = (MTU_STD_ALGN >> 3) as u16; - val = (val - RXQ2_RXF_FLOW_CTRL_RSVD) >> 3; - } else { - val16 = (MTU_STD_ALGN >> 3) as u16; - val = (val - MTU_STD_ALGN) >> 3; - } - self.write(RXQ2, - FIELDX!(RXQ2_RXF_XOFF_THRESH, val16) | - FIELDX!(RXQ2_RXF_XON_THRESH, val)); - val = FIELDX!(RXQ0_NUM_RFD_PREF, RXQ0_NUM_RFD_PREF_DEF) | - FIELDX!(RXQ0_RSS_MODE, RXQ0_RSS_MODE_DIS) | - FIELDX!(RXQ0_IDT_TBL_SIZE, RXQ0_IDT_TBL_SIZE_DEF) | - RXQ0_RSS_HSTYP_ALL | - RXQ0_RSS_HASH_EN | - RXQ0_IPV6_PARSE_EN; - if (self.cap & CAP_GIGA > 0) { - FIELD_SET32!(val, RXQ0_ASPM_THRESH, RXQ0_ASPM_THRESH_100M); - } - self.write(RXQ0, val); + /* rxq, flow control */ + val = self.read(SRAM5); + val = FIELD_GETX!(val, SRAM_RXF_LEN) << 3; + if (val > SRAM_RXF_LEN_8K) { + val16 = (MTU_STD_ALGN >> 3) as u16; + val = (val - RXQ2_RXF_FLOW_CTRL_RSVD) >> 3; + } else { + val16 = (MTU_STD_ALGN >> 3) as u16; + val = (val - MTU_STD_ALGN) >> 3; + } + self.write( + RXQ2, + FIELDX!(RXQ2_RXF_XOFF_THRESH, val16) | FIELDX!(RXQ2_RXF_XON_THRESH, val), + ); + val = FIELDX!(RXQ0_NUM_RFD_PREF, RXQ0_NUM_RFD_PREF_DEF) + | FIELDX!(RXQ0_RSS_MODE, RXQ0_RSS_MODE_DIS) + | FIELDX!(RXQ0_IDT_TBL_SIZE, RXQ0_IDT_TBL_SIZE_DEF) + | RXQ0_RSS_HSTYP_ALL + | RXQ0_RSS_HASH_EN + | RXQ0_IPV6_PARSE_EN; + if (self.cap & CAP_GIGA > 0) { + FIELD_SET32!(val, RXQ0_ASPM_THRESH, RXQ0_ASPM_THRESH_100M); + } + self.write(RXQ0, val); - /* DMA */ - val = self.read(DMA); - val = FIELDX!(DMA_RORDER_MODE, DMA_RORDER_MODE_OUT) | - DMA_RREQ_PRI_DATA | - FIELDX!(DMA_RREQ_BLEN, max_payload) | - FIELDX!(DMA_WDLY_CNT, DMA_WDLY_CNT_DEF) | - FIELDX!(DMA_RDLY_CNT, DMA_RDLY_CNT_DEF) | - FIELDX!(DMA_RCHNL_SEL, self.dma_chnl - 1); - self.write(DMA, val); + /* DMA */ + val = self.read(DMA); + val = FIELDX!(DMA_RORDER_MODE, DMA_RORDER_MODE_OUT) + | DMA_RREQ_PRI_DATA + | FIELDX!(DMA_RREQ_BLEN, max_payload) + | FIELDX!(DMA_WDLY_CNT, DMA_WDLY_CNT_DEF) + | FIELDX!(DMA_RDLY_CNT, DMA_RDLY_CNT_DEF) + | FIELDX!(DMA_RCHNL_SEL, self.dma_chnl - 1); + self.write(DMA, val); - /* multi-tx-q weight */ - if (self.cap & CAP_MTQ > 0) { - val = FIELDX!(WRR_PRI, self.wrr_ctrl) | - FIELDX!(WRR_PRI0, self.wrr[0]) | - FIELDX!(WRR_PRI1, self.wrr[1]) | - FIELDX!(WRR_PRI2, self.wrr[2]) | - FIELDX!(WRR_PRI3, self.wrr[3]); - self.write(WRR, val); - } + /* multi-tx-q weight */ + if (self.cap & CAP_MTQ > 0) { + val = FIELDX!(WRR_PRI, self.wrr_ctrl) + | FIELDX!(WRR_PRI0, self.wrr[0]) + | FIELDX!(WRR_PRI1, self.wrr[1]) + | FIELDX!(WRR_PRI2, self.wrr[2]) + | FIELDX!(WRR_PRI3, self.wrr[3]); + self.write(WRR, val); + } } unsafe fn set_rx_mode(&mut self) { /* TODO struct alx_adapter *adpt = netdev_priv(netdev); - struct alx_hw *hw = &adpt->hw; - struct netdev_hw_addr *ha; + struct alx_hw *hw = &adpt->hw; + struct netdev_hw_addr *ha; - /* comoute mc addresses' hash value ,and put it into hash table */ - netdev_for_each_mc_addr(ha, netdev) - alx_add_mc_addr(hw, ha->addr); + /* comoute mc addresses' hash value ,and put it into hash table */ + netdev_for_each_mc_addr(ha, netdev) + alx_add_mc_addr(hw, ha->addr); */ - self.write(HASH_TBL0, self.mc_hash[0]); - self.write(HASH_TBL1, self.mc_hash[1]); + self.write(HASH_TBL0, self.mc_hash[0]); + self.write(HASH_TBL1, self.mc_hash[1]); - /* check for Promiscuous and All Multicast modes */ - self.rx_ctrl &= !(MAC_CTRL_MULTIALL_EN | MAC_CTRL_PROMISC_EN); + /* check for Promiscuous and All Multicast modes */ + self.rx_ctrl &= !(MAC_CTRL_MULTIALL_EN | MAC_CTRL_PROMISC_EN); /* TODO - if (netdev->flags & IFF_PROMISC) { - self.rx_ctrl |= MAC_CTRL_PROMISC_EN; + if (netdev->flags & IFF_PROMISC) { + self.rx_ctrl |= MAC_CTRL_PROMISC_EN; } - if (netdev->flags & IFF_ALLMULTI) { - self.rx_ctrl |= MAC_CTRL_MULTIALL_EN; + if (netdev->flags & IFF_ALLMULTI) { + self.rx_ctrl |= MAC_CTRL_MULTIALL_EN; } */ - self.write(MAC_CTRL, self.rx_ctrl); + self.write(MAC_CTRL, self.rx_ctrl); } unsafe fn set_vlan_mode(&mut self, vlan_rx: bool) { if (vlan_rx) { - self.rx_ctrl |= MAC_CTRL_VLANSTRIP; + self.rx_ctrl |= MAC_CTRL_VLANSTRIP; } else { - self.rx_ctrl &= !MAC_CTRL_VLANSTRIP; + self.rx_ctrl &= !MAC_CTRL_VLANSTRIP; } - self.write(MAC_CTRL, self.rx_ctrl); + self.write(MAC_CTRL, self.rx_ctrl); } unsafe fn configure_rss(&mut self, en: bool) { let mut ctrl: u32; - ctrl = self.read(RXQ0); + ctrl = self.read(RXQ0); - if (en) { + if (en) { unimplemented!(); /* - for (i = 0; i < sizeof(self.rss_key); i++) { - /* rss key should be saved in chip with - * reversed order. - */ - int j = sizeof(self.rss_key) - i - 1; + for (i = 0; i < sizeof(self.rss_key); i++) { + /* rss key should be saved in chip with + * reversed order. + */ + int j = sizeof(self.rss_key) - i - 1; - MEM_W8(hw, RSS_KEY0 + j, self.rss_key[i]); - } + MEM_W8(hw, RSS_KEY0 + j, self.rss_key[i]); + } - for (i = 0; i < ARRAY_SIZE(self.rss_idt); i++) - self.write(RSS_IDT_TBL0 + i * 4, - self.rss_idt[i]); + for (i = 0; i < ARRAY_SIZE(self.rss_idt); i++) + self.write(RSS_IDT_TBL0 + i * 4, + self.rss_idt[i]); - FIELD_SET32(ctrl, RXQ0_RSS_HSTYP, self.rss_hash_type); - FIELD_SET32(ctrl, RXQ0_RSS_MODE, RXQ0_RSS_MODE_MQMI); - FIELD_SET32(ctrl, RXQ0_IDT_TBL_SIZE, self.rss_idt_size); - ctrl |= RXQ0_RSS_HASH_EN; + FIELD_SET32(ctrl, RXQ0_RSS_HSTYP, self.rss_hash_type); + FIELD_SET32(ctrl, RXQ0_RSS_MODE, RXQ0_RSS_MODE_MQMI); + FIELD_SET32(ctrl, RXQ0_IDT_TBL_SIZE, self.rss_idt_size); + ctrl |= RXQ0_RSS_HASH_EN; */ - } else { - ctrl &= !RXQ0_RSS_HASH_EN; - } + } else { + ctrl &= !RXQ0_RSS_HASH_EN; + } - self.write(RXQ0, ctrl); + self.write(RXQ0, ctrl); } unsafe fn configure(&mut self) { @@ -1381,89 +1380,86 @@ impl Alx { } unsafe fn irq_enable(&mut self) { - self.write(ISR, 0); + self.write(ISR, 0); let imask = self.imask; self.write(IMR, imask); } unsafe fn irq_disable(&mut self) { self.write(ISR, ISR_DIS); - self.write(IMR, 0); + self.write(IMR, 0); } unsafe fn clear_phy_intr(&mut self) -> usize { - let mut isr: u16 = 0; - self.read_phy_reg(MII_ISR, &mut isr) + let mut isr: u16 = 0; + self.read_phy_reg(MII_ISR, &mut isr) } unsafe fn post_phy_link(&mut self, speed: u16, az_en: bool) { let mut phy_val: u16 = 0; let len: u16; let agc: u16; - let revid: u8 = self.revid(); - let adj_th: bool; + let revid: u8 = self.revid(); + let adj_th: bool; - if (revid != REV_B0 && - revid != REV_A1 && - revid != REV_A0) { - return; - } - adj_th = if (revid == REV_B0) { true } else { false }; + if (revid != REV_B0 && revid != REV_A1 && revid != REV_A0) { + return; + } + adj_th = if (revid == REV_B0) { true } else { false }; - /* 1000BT/AZ, wrong cable length */ - if (speed != SPEED_0) { - self.read_phy_ext(MIIEXT_PCS, MIIEXT_CLDCTRL6, &mut phy_val); - len = FIELD_GETX!(phy_val, CLDCTRL6_CAB_LEN); - self.read_phy_dbg(MIIDBG_AGC, &mut phy_val); - agc = FIELD_GETX!(phy_val, AGC_2_VGA); + /* 1000BT/AZ, wrong cable length */ + if (speed != SPEED_0) { + self.read_phy_ext(MIIEXT_PCS, MIIEXT_CLDCTRL6, &mut phy_val); + len = FIELD_GETX!(phy_val, CLDCTRL6_CAB_LEN); + self.read_phy_dbg(MIIDBG_AGC, &mut phy_val); + agc = FIELD_GETX!(phy_val, AGC_2_VGA); - if ((speed == SPEED_1000 && - (len > CLDCTRL6_CAB_LEN_SHORT1G || - (0 == len && agc > AGC_LONG1G_LIMT))) || - (speed == SPEED_100 && - (len > CLDCTRL6_CAB_LEN_SHORT100M || - (0 == len && agc > AGC_LONG100M_LIMT)))) { - self.write_phy_dbg(MIIDBG_AZ_ANADECT, AZ_ANADECT_LONG); - self.read_phy_ext(MIIEXT_ANEG, MIIEXT_AFE, &mut phy_val); - self.write_phy_ext(MIIEXT_ANEG, MIIEXT_AFE, phy_val | AFE_10BT_100M_TH); - } else { - self.write_phy_dbg(MIIDBG_AZ_ANADECT, AZ_ANADECT_DEF); - self.read_phy_ext(MIIEXT_ANEG, MIIEXT_AFE, &mut phy_val); - self.write_phy_ext(MIIEXT_ANEG, MIIEXT_AFE, phy_val & !AFE_10BT_100M_TH); - } + if ((speed == SPEED_1000 + && (len > CLDCTRL6_CAB_LEN_SHORT1G || (0 == len && agc > AGC_LONG1G_LIMT))) + || (speed == SPEED_100 + && (len > CLDCTRL6_CAB_LEN_SHORT100M || (0 == len && agc > AGC_LONG100M_LIMT)))) + { + self.write_phy_dbg(MIIDBG_AZ_ANADECT, AZ_ANADECT_LONG); + self.read_phy_ext(MIIEXT_ANEG, MIIEXT_AFE, &mut phy_val); + self.write_phy_ext(MIIEXT_ANEG, MIIEXT_AFE, phy_val | AFE_10BT_100M_TH); + } else { + self.write_phy_dbg(MIIDBG_AZ_ANADECT, AZ_ANADECT_DEF); + self.read_phy_ext(MIIEXT_ANEG, MIIEXT_AFE, &mut phy_val); + self.write_phy_ext(MIIEXT_ANEG, MIIEXT_AFE, phy_val & !AFE_10BT_100M_TH); + } - /* threashold adjust */ - if (adj_th && self.lnk_patch) { - if (speed == SPEED_100) { - self.write_phy_dbg(MIIDBG_MSE16DB, MSE16DB_UP); - } else if (speed == SPEED_1000) { - /* - * Giga link threshold, raise the tolerance of - * noise 50% - */ - self.read_phy_dbg(MIIDBG_MSE20DB, &mut phy_val); - FIELD_SETS!(phy_val, MSE20DB_TH, MSE20DB_TH_HI); - self.write_phy_dbg(MIIDBG_MSE20DB, phy_val); - } - } - /* phy link-down in 1000BT/AZ mode */ - if (az_en && revid == REV_B0 && speed == SPEED_1000) { - self.write_phy_dbg(MIIDBG_SRDSYSMOD, SRDSYSMOD_DEF & !SRDSYSMOD_DEEMP_EN); - } - } else { - self.read_phy_ext(MIIEXT_ANEG, MIIEXT_AFE, &mut phy_val); - self.write_phy_ext(MIIEXT_ANEG, MIIEXT_AFE, phy_val & !AFE_10BT_100M_TH); + /* threashold adjust */ + if (adj_th && self.lnk_patch) { + if (speed == SPEED_100) { + self.write_phy_dbg(MIIDBG_MSE16DB, MSE16DB_UP); + } else if (speed == SPEED_1000) { + /* + * Giga link threshold, raise the tolerance of + * noise 50% + */ + self.read_phy_dbg(MIIDBG_MSE20DB, &mut phy_val); + FIELD_SETS!(phy_val, MSE20DB_TH, MSE20DB_TH_HI); + self.write_phy_dbg(MIIDBG_MSE20DB, phy_val); + } + } + /* phy link-down in 1000BT/AZ mode */ + if (az_en && revid == REV_B0 && speed == SPEED_1000) { + self.write_phy_dbg(MIIDBG_SRDSYSMOD, SRDSYSMOD_DEF & !SRDSYSMOD_DEEMP_EN); + } + } else { + self.read_phy_ext(MIIEXT_ANEG, MIIEXT_AFE, &mut phy_val); + self.write_phy_ext(MIIEXT_ANEG, MIIEXT_AFE, phy_val & !AFE_10BT_100M_TH); - if (adj_th && self.lnk_patch) { - self.write_phy_dbg(MIIDBG_MSE16DB, MSE16DB_DOWN); - self.read_phy_dbg(MIIDBG_MSE20DB, &mut phy_val); - FIELD_SETS!(phy_val, MSE20DB_TH, MSE20DB_TH_DEF); - self.write_phy_dbg(MIIDBG_MSE20DB, phy_val); - } - if (az_en && revid == REV_B0) { - self.write_phy_dbg(MIIDBG_SRDSYSMOD, SRDSYSMOD_DEF); - } - } + if (adj_th && self.lnk_patch) { + self.write_phy_dbg(MIIDBG_MSE16DB, MSE16DB_DOWN); + self.read_phy_dbg(MIIDBG_MSE20DB, &mut phy_val); + FIELD_SETS!(phy_val, MSE20DB_TH, MSE20DB_TH_DEF); + self.write_phy_dbg(MIIDBG_MSE20DB, phy_val); + } + if (az_en && revid == REV_B0) { + self.write_phy_dbg(MIIDBG_SRDSYSMOD, SRDSYSMOD_DEF); + } + } } unsafe fn task(&mut self) { @@ -1502,25 +1498,25 @@ impl Alx { unsafe fn activate(&mut self) { /* hardware setting lost, restore it */ self.init_ring_ptrs(); - self.configure(); + self.configure(); self.flag &= !FLAG_HALT; - /* clear old interrupts */ + /* clear old interrupts */ self.write(ISR, !ISR_DIS); - self.irq_enable(); + self.irq_enable(); self.flag |= FLAG_TASK_CHK_LINK; self.task(); } unsafe fn reinit(&mut self) { - if self.flag & FLAG_HALT > 0 { - return; + if self.flag & FLAG_HALT > 0 { + return; } - self.halt(); - self.activate(); + self.halt(); + self.activate(); } unsafe fn init_ring_ptrs(&mut self) { @@ -1530,8 +1526,12 @@ impl Alx { // RFD ring for i in 0..self.rfd_ring.len() { - self.rfd_ring[i].addr_low.write(self.rfd_buffer[i].physical() as u32); - self.rfd_ring[i].addr_high.write(((self.rfd_buffer[i].physical() as u64) >> 32) as u32); + self.rfd_ring[i] + .addr_low + .write(self.rfd_buffer[i].physical() as u32); + self.rfd_ring[i] + .addr_high + .write(((self.rfd_buffer[i].physical() as u64) >> 32) as u32); } self.write(RFD_ADDR_LO, self.rfd_ring.physical() as u32); self.write(RFD_RING_SZ, self.rfd_ring.len() as u32); @@ -1555,104 +1555,104 @@ impl Alx { unsafe fn check_link(&mut self) { let mut speed: u16 = SPEED_0; let old_speed: u16; - let mut link_up: bool = false; + let mut link_up: bool = false; let old_link_up: bool; - let mut err: usize; + let mut err: usize; - if (self.flag & FLAG_HALT > 0) { - return; + if (self.flag & FLAG_HALT > 0) { + return; } macro_rules! goto_out { () => { if (err > 0) { self.flag |= FLAG_TASK_RESET; - self.task(); - } + self.task(); + } return; - } + }; } - /* clear PHY internal interrupt status, - * otherwise the Main interrupt status will be asserted - * for ever. - */ + /* clear PHY internal interrupt status, + * otherwise the Main interrupt status will be asserted + * for ever. + */ self.clear_phy_intr(); - err = self.get_phy_link(&mut link_up, &mut speed); - if (err > 0) { + err = self.get_phy_link(&mut link_up, &mut speed); + if (err > 0) { goto_out!(); } - /* open interrutp mask */ - self.imask |= ISR_PHY; + /* open interrutp mask */ + self.imask |= ISR_PHY; let imask = self.imask; - self.write(IMR, imask); + self.write(IMR, imask); - if (!link_up && !self.link_up) { - goto_out!(); + if (!link_up && !self.link_up) { + goto_out!(); } - old_speed = self.link_speed + self.link_duplex as u16; - old_link_up = self.link_up; + old_speed = self.link_speed + self.link_duplex as u16; + old_link_up = self.link_up; - if (link_up) { - /* same speed ? */ - if (old_link_up && old_speed == speed) { - goto_out!(); + if (link_up) { + /* same speed ? */ + if (old_link_up && old_speed == speed) { + goto_out!(); } - self.show_speed(speed); - self.link_duplex = (speed % 10) as u8; - self.link_speed = speed - self.link_duplex as u16; - self.link_up = true; + self.show_speed(speed); + self.link_duplex = (speed % 10) as u8; + self.link_speed = speed - self.link_duplex as u16; + self.link_up = true; let link_speed = self.link_speed; let az_en = self.cap & CAP_AZ > 0; - self.post_phy_link(link_speed, az_en); + self.post_phy_link(link_speed, az_en); let l0s_en = self.cap & CAP_L0S > 0; let l1_en = self.cap & CAP_L1 > 0; - self.enable_aspm(l0s_en, l1_en); - self.start_mac(); + self.enable_aspm(l0s_en, l1_en); + self.start_mac(); - /* link kept, just speed changed */ - if (old_link_up) { - goto_out!(); + /* link kept, just speed changed */ + if (old_link_up) { + goto_out!(); } - /* link changed from 'down' to 'up' */ - // TODO self.netif_start(); - goto_out!(); - } + /* link changed from 'down' to 'up' */ + // TODO self.netif_start(); + goto_out!(); + } - /* link changed from 'up' to 'down' */ - // TODO self.netif_stop(); - self.link_up = false; - self.link_speed = SPEED_0; - println!("NIC Link Down"); - err = self.reset_mac(); - if (err > 0) { - println!("linkdown:reset_mac fail {}", err); - err = (-EIO) as usize; - goto_out!(); - } - self.irq_disable(); + /* link changed from 'up' to 'down' */ + // TODO self.netif_stop(); + self.link_up = false; + self.link_speed = SPEED_0; + println!("NIC Link Down"); + err = self.reset_mac(); + if (err > 0) { + println!("linkdown:reset_mac fail {}", err); + err = (-EIO) as usize; + goto_out!(); + } + self.irq_disable(); - /* reset-mac cause all settings on HW lost, - * following steps restore all of them and - * refresh whole RX/TX rings - */ - self.init_ring_ptrs(); + /* reset-mac cause all settings on HW lost, + * following steps restore all of them and + * refresh whole RX/TX rings + */ + self.init_ring_ptrs(); - self.configure(); + self.configure(); let l1_en = self.cap & CAP_L1 > 0; - self.enable_aspm(false, l1_en); + self.enable_aspm(false, l1_en); let cap_az = self.cap & CAP_AZ > 0; - self.post_phy_link(SPEED_0, cap_az); + self.post_phy_link(SPEED_0, cap_az); - self.irq_enable(); + self.irq_enable(); - goto_out!(); + goto_out!(); } unsafe fn get_phy_info(&mut self) -> bool { @@ -1660,22 +1660,22 @@ impl Alx { let mut devs1: u16 = 0; let mut devs2: u16 = 0; - if (self.read_phy_reg(MII_PHYSID1, &mut self.phy_id[0]) > 0 || - self.read_phy_reg(MII_PHYSID2, &mut self.phy_id[1]) > 0) { - return false; + if (self.read_phy_reg(MII_PHYSID1, &mut self.phy_id[0]) > 0 || + self.read_phy_reg(MII_PHYSID2, &mut self.phy_id[1]) > 0) { + return false; } - /* since we haven't PMA/PMD status2 register, we can't - * use mdio45_probe function for prtad and mmds. - * use fixed MMD3 to get mmds. - */ - if (self.read_phy_ext(3, MDIO_DEVS1, &devs1) || - self.read_phy_ext(3, MDIO_DEVS2, &devs2)) { - return false; + /* since we haven't PMA/PMD status2 register, we can't + * use mdio45_probe function for prtad and mmds. + * use fixed MMD3 to get mmds. + */ + if (self.read_phy_ext(3, MDIO_DEVS1, &devs1) || + self.read_phy_ext(3, MDIO_DEVS2, &devs2)) { + return false; } - self.mdio.mmds = devs1 | devs2 << 16; + self.mdio.mmds = devs1 | devs2 << 16; - return true; + return true; */ return true; } @@ -1704,9 +1704,12 @@ impl Alx { } let mac = self.get_perm_macaddr(); - println!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + println!( + " - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] + ); - if ! self.get_phy_info() { + if !self.get_phy_info() { println!(" - Identify PHY failed"); return Err(Error::new(EIO)); } @@ -1727,28 +1730,28 @@ impl Alx { macro_rules! goto_out { () => {{ - self.free_all_ring_resources(); - self.disable_advanced_intr(); - return err; - }} + self.free_all_ring_resources(); + self.disable_advanced_intr(); + return err; + }}; } - /* allocate all memory resources */ - self.init_ring_ptrs(); + /* allocate all memory resources */ + self.init_ring_ptrs(); - /* make hardware ready before allocate interrupt */ - self.configure(); + /* make hardware ready before allocate interrupt */ + self.configure(); self.flag &= !FLAG_HALT; - /* clear old interrupts */ + /* clear old interrupts */ self.write(ISR, !ISR_DIS); - self.irq_enable(); + self.irq_enable(); self.flag |= FLAG_TASK_CHK_LINK; - self.task(); - return 0; + self.task(); + return 0; } unsafe fn init(&mut self) -> Result<()> { @@ -1773,10 +1776,10 @@ impl Alx { self.dma_chnl = if self.revid() >= REV_B0 { 4 } else { 2 }; } - println!(" - ID: {:>04X}:{:>04X} SUB: {:>04X}:{:>04X} REV: {:>02X}", - self.vendor_id, self.device_id, - self.subven_id, self.subdev_id, - self.revision); + println!( + " - ID: {:>04X}:{:>04X} SUB: {:>04X}:{:>04X} REV: {:>02X}", + self.vendor_id, self.device_id, self.subven_id, self.subdev_id, self.revision + ); self.probe()?; @@ -1800,7 +1803,7 @@ impl scheme::SchemeMut for Alx { } fn dup(&mut self, id: usize, buf: &[u8]) -> Result { - if ! buf.is_empty() { + if !buf.is_empty() { return Err(Error::new(EINVAL)); } diff --git a/net/alxd/src/device/regs.rs b/net/alxd/src/device/regs.rs index fed2169067..774c1aca48 100644 --- a/net/alxd/src/device/regs.rs +++ b/net/alxd/src/device/regs.rs @@ -421,10 +421,7 @@ pub const PHY_CTRL_RTL_MODE: u32 = 1 << 1; /* bit0: out of dsp RST state */ pub const PHY_CTRL_DSPRST_OUT: u32 = 1 << 0; pub const PHY_CTRL_DSPRST_TO: u32 = 80; -pub const PHY_CTRL_CLS: u32 = - PHY_CTRL_LED_MODE | - PHY_CTRL_100AB_EN | - PHY_CTRL_PLL_ON; +pub const PHY_CTRL_CLS: u32 = PHY_CTRL_LED_MODE | PHY_CTRL_100AB_EN | PHY_CTRL_PLL_ON; pub const MAC_STS: u32 = 0x1410; pub const MAC_STS_SFORCE_MASK: u32 = 0xF; @@ -439,10 +436,7 @@ pub const MAC_STS_RXQ_BUSY: u32 = 1 << 2; pub const MAC_STS_TXMAC_BUSY: u32 = 1 << 1; pub const MAC_STS_RXMAC_BUSY: u32 = 1 << 0; pub const MAC_STS_IDLE: u32 = - MAC_STS_TXQ_BUSY | - MAC_STS_RXQ_BUSY | - MAC_STS_TXMAC_BUSY | - MAC_STS_RXMAC_BUSY; + MAC_STS_TXQ_BUSY | MAC_STS_RXQ_BUSY | MAC_STS_TXMAC_BUSY | MAC_STS_RXMAC_BUSY; pub const MDIO: u32 = 0x1414; pub const MDIO_MODE_EXT: u32 = 1 << 30; @@ -876,7 +870,7 @@ pub const SRAM_RXF_HEAD_ADDR_SHIFT: u32 = 0; pub const SRAM5: u32 = 0x1524; pub const SRAM_RXF_LEN_MASK: u32 = 0xFFF; pub const SRAM_RXF_LEN_SHIFT: u32 = 0; -pub const SRAM_RXF_LEN_8K: u32 = (8*1024); +pub const SRAM_RXF_LEN_8K: u32 = (8 * 1024); pub const SRAM6: u32 = 0x1528; pub const SRAM_TXF_TAIL_ADDR_MASK: u32 = 0xFFF; @@ -955,7 +949,7 @@ pub const TXQ1_ERRLGPKT_DROP_EN: u32 = 1 << 11; /* bit[9:0]:: u32 = 8bytes unit */ pub const TXQ1_JUMBO_TSOTHR_MASK: u32 = 0x7FF; pub const TXQ1_JUMBO_TSOTHR_SHIFT: u32 = 0; -pub const TXQ1_JUMBO_TSO_TH: u32 = (7*1024); +pub const TXQ1_JUMBO_TSO_TH: u32 = (7 * 1024); /* L1 entrance control */ pub const TXQ2: u32 = 0x1598; @@ -990,11 +984,10 @@ pub const RXQ0_RSS_HSTYP_IPV6_TCP_EN: u32 = 1 << 5; pub const RXQ0_RSS_HSTYP_IPV6_EN: u32 = 1 << 4; pub const RXQ0_RSS_HSTYP_IPV4_TCP_EN: u32 = 1 << 3; pub const RXQ0_RSS_HSTYP_IPV4_EN: u32 = 1 << 2; -pub const RXQ0_RSS_HSTYP_ALL: u32 = - RXQ0_RSS_HSTYP_IPV6_TCP_EN | - RXQ0_RSS_HSTYP_IPV4_TCP_EN | - RXQ0_RSS_HSTYP_IPV6_EN | - RXQ0_RSS_HSTYP_IPV4_EN; +pub const RXQ0_RSS_HSTYP_ALL: u32 = RXQ0_RSS_HSTYP_IPV6_TCP_EN + | RXQ0_RSS_HSTYP_IPV4_TCP_EN + | RXQ0_RSS_HSTYP_IPV6_EN + | RXQ0_RSS_HSTYP_IPV4_EN; pub const RXQ0_ASPM_THRESH_MASK: u32 = 0x3; pub const RXQ0_ASPM_THRESH_SHIFT: u32 = 0; pub const RXQ0_ASPM_THRESH_NO: u32 = 0; @@ -1223,7 +1216,6 @@ pub const INT_DEASST_TIMER: u32 = 0x1614; pub const PATTERN_MASK: u32 = 0x1620; pub const PATTERN_MASK_LEN: u32 = 128; - pub const FLT1_SRC_IP0: u32 = 0x1A00; pub const FLT1_SRC_IP1: u32 = 0x1A04; pub const FLT1_SRC_IP2: u32 = 0x1A08; @@ -1392,12 +1384,7 @@ pub const CLK_GATE_TXQ: u32 = 1 << 2; pub const CLK_GATE_DMAR: u32 = 1 << 1; pub const CLK_GATE_DMAW: u32 = 1 << 0; pub const CLK_GATE_ALL_A0: u32 = - CLK_GATE_RXMAC | - CLK_GATE_TXMAC | - CLK_GATE_RXQ | - CLK_GATE_TXQ | - CLK_GATE_DMAR | - CLK_GATE_DMAW; + CLK_GATE_RXMAC | CLK_GATE_TXMAC | CLK_GATE_RXQ | CLK_GATE_TXQ | CLK_GATE_DMAR | CLK_GATE_DMAW; pub const CLK_GATE_ALL_B0: u32 = CLK_GATE_ALL_A0; /* PORST affect */ @@ -1834,7 +1821,6 @@ pub const CR_DMA_CTRL_WEARLY_EN: u32 = 1 << 8; pub const CR_DMA_CTRL_RXTH_MASK: u32 = 0xF; pub const CR_DMA_CTRL_WTH_MASK: u32 = 0xF; - pub const EFUSE_BIST: u32 = 0x1934; pub const EFUSE_BIST_COL_MASK: u32 = 0x3F; pub const EFUSE_BIST_COL_SHIFT: u32 = 24; @@ -1988,7 +1974,6 @@ pub const IO_MDIO: u32 = 0x38; /* same as reg140C */ pub const IO_PHY_CTRL: u32 = 0x3C; - /********************* PHY regs definition ***************************/ /* Autoneg Advertisement Register */ @@ -2043,7 +2028,6 @@ pub const CDTC_EN: u16 = 1; pub const CDTC_PAIR_MASK: u16 = 0x3; pub const CDTC_PAIR_SHIFT: u16 = 8; - /* Cable-Detect-Test Status Register */ pub const MII_CDTS: u16 = 0x1C; pub const CDTS_STATUS_MASK: u16 = 0x3; @@ -2080,7 +2064,6 @@ pub const ANACTRL_MANUSWON_BW3_4M: u16 = 0x0002; pub const ANACTRL_RESTART_CAL: u16 = 0x0001; pub const ANACTRL_DEF: u16 = 0x02EF; - pub const MIIDBG_SYSMODCTRL: u16 = 0x04; pub const SYSMODCTRL_IECHOADJ_PFMH_PHY: u16 = 0x8000; pub const SYSMODCTRL_IECHOADJ_BIASGEN: u16 = 0x4000; @@ -2100,7 +2083,6 @@ pub const SYSMODCTRL_IECHOADJ_VDLANSW: u16 = 0x0001; /* en half bias */ pub const SYSMODCTRL_IECHOADJ_DEF: u16 = 0xBB8B; - pub const MIIDBG_SRDSYSMOD: u16 = 0x05; pub const SRDSYSMOD_LCKDET_EN: u16 = 0x2000; pub const SRDSYSMOD_PLL_EN: u16 = 0x0800; @@ -2114,7 +2096,6 @@ pub const SRDSYSMOD_CDR_ADC_VLTG: u16 = 0x0002; pub const SRDSYSMOD_CDR_DAC_1MA: u16 = 0x0001; pub const SRDSYSMOD_DEF: u16 = 0x2C46; - pub const MIIDBG_HIBNEG: u16 = 0x0B; pub const HIBNEG_PSHIB_EN: u16 = 0x8000; pub const HIBNEG_WAKE_BOTH: u16 = 0x4000; @@ -2204,7 +2185,6 @@ pub const MIIDBG_GREENCFG2: u16 = 0x3D; pub const GREENCFG2_BP_GREEN: u16 = 0x8000; pub const GREENCFG2_GATE_DFSE_EN: u16 = 0x0080; - /***************************** extension **************************************/ /******* dev 3 *********/ @@ -2292,4 +2272,4 @@ pub const MIIEXT_NLP56_DEF: u16 = 0x1010; pub const MIIEXT_NLP78: u16 = 0x8027; /* for: u16 = 160m */ pub const MIIEXT_NLP78_160M_DEF: u16 = 0x8D05; -pub const MIIEXT_NLP78_120M_DEF : u16 = 0x8A05; +pub const MIIEXT_NLP78_120M_DEF: u16 = 0x8A05; diff --git a/net/alxd/src/main.rs b/net/alxd/src/main.rs index e6c54024aa..f87d256dba 100644 --- a/net/alxd/src/main.rs +++ b/net/alxd/src/main.rs @@ -6,16 +6,16 @@ extern crate event; extern crate syscall; -use std::{env, iter}; use std::fs::File; use std::io::{Read, Write}; use std::os::fd::AsRawFd; use std::os::unix::io::{FromRawFd, RawFd}; +use std::{env, iter}; use event::{user_data, EventQueue}; use libredox::flag; -use syscall::{Packet, SchemeMut}; use syscall::error::EWOULDBLOCK; +use syscall::{Packet, SchemeMut}; pub mod device; @@ -35,16 +35,31 @@ fn main() { // Daemonize redox_daemon::Daemon::new(move |daemon| { - let socket_fd = libredox::call::open(":network", flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, 0).expect("alxd: failed to create network scheme"); + let socket_fd = libredox::call::open( + ":network", + flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, + 0, + ) + .expect("alxd: failed to create network scheme"); let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) }; daemon.ready().expect("alxd: failed to signal readiness"); - let mut irq_file = File::open(format!("/scheme/irq/{}", irq)).expect("alxd: failed to open IRQ file"); + let mut irq_file = + File::open(format!("/scheme/irq/{}", irq)).expect("alxd: failed to open IRQ file"); - let address = unsafe { common::physmap(bar, 128*1024, common::Prot::RW, common::MemoryType::Uncacheable).expect("alxd: failed to map address") as usize }; + let address = unsafe { + common::physmap( + bar, + 128 * 1024, + common::Prot::RW, + common::MemoryType::Uncacheable, + ) + .expect("alxd: failed to map address") as usize + }; { - let mut device = unsafe { device::Alx::new(address).expect("alxd: failed to allocate device") }; + let mut device = + unsafe { device::Alx::new(address).expect("alxd: failed to allocate device") }; user_data! { enum Source { @@ -53,15 +68,26 @@ fn main() { } } - let event_queue = EventQueue::::new().expect("alxd: failed to create event queue"); - event_queue.subscribe(irq_file.as_raw_fd() as usize, Source::Irq, event::EventFlags::READ).unwrap(); - event_queue.subscribe(socket_fd, Source::Scheme, event::EventFlags::READ).unwrap(); + let event_queue = + EventQueue::::new().expect("alxd: failed to create event queue"); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); + event_queue + .subscribe(socket_fd, Source::Scheme, event::EventFlags::READ) + .unwrap(); libredox::call::setrens(0, 0).expect("alxd: failed to enter null namespace"); let mut todo = Vec::::new(); - for event in iter::once(Source::Scheme).chain(event_queue.map(|e| e.expect("alxd: failed to get next event").user_data)) { + for event in iter::once(Source::Scheme) + .chain(event_queue.map(|e| e.expect("alxd: failed to get next event").user_data)) + { match event { Source::Irq => { let mut irq = [0; 8]; @@ -77,7 +103,9 @@ fn main() { todo[i].a = a; i += 1; } else { - socket.write(&mut todo[i]).expect("alxd: failed to write to socket"); + socket + .write(&mut todo[i]) + .expect("alxd: failed to write to socket"); todo.remove(i); } } @@ -93,7 +121,11 @@ fn main() { Source::Scheme => { loop { let mut packet = Packet::default(); - if socket.read(&mut packet).expect("alxd: failed read from socket") == 0 { + if socket + .read(&mut packet) + .expect("alxd: failed read from socket") + == 0 + { break; } @@ -103,7 +135,9 @@ fn main() { packet.a = a; todo.push(packet); } else { - socket.write(&mut packet).expect("alxd: failed to write to socket"); + socket + .write(&mut packet) + .expect("alxd: failed to write to socket"); } } @@ -119,5 +153,6 @@ fn main() { } } std::process::exit(0); - }).expect("alxd: failed to daemonize"); + }) + .expect("alxd: failed to daemonize"); } diff --git a/net/e1000d/src/main.rs b/net/e1000d/src/main.rs index 1ed1608237..ca506185c3 100644 --- a/net/e1000d/src/main.rs +++ b/net/e1000d/src/main.rs @@ -49,9 +49,19 @@ fn main() { let mut event_queue = EventQueue::::new().expect("e1000d: failed to create event queue"); - event_queue.subscribe(irq_file.as_raw_fd() as usize, Source::Irq, event::EventFlags::READ) + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) .expect("e1000d: failed to subscribe to IRQ fd"); - event_queue.subscribe(scheme.event_handle() as usize, Source::Scheme, event::EventFlags::READ) + event_queue + .subscribe( + scheme.event_handle() as usize, + Source::Scheme, + event::EventFlags::READ, + ) .expect("e1000d: failed to subscribe to scheme fd"); libredox::call::setrens(0, 0).expect("e1000d: failed to enter null namespace"); diff --git a/net/ixgbed/src/device.rs b/net/ixgbed/src/device.rs index a61441bca3..0d59b46d34 100644 --- a/net/ixgbed/src/device.rs +++ b/net/ixgbed/src/device.rs @@ -55,8 +55,8 @@ impl NetworkAdapter for Intel8259x { let i = cmp::min(buf.len(), data.len()); buf[..i].copy_from_slice(&data[..i]); - desc.read.pkt_addr = self.receive_buffer[self.receive_index].physical() as u64; - desc.read.hdr_addr = 0; + desc.read.pkt_addr = self.receive_buffer[self.receive_index].physical() as u64; + desc.read.hdr_addr = 0; self.write_reg(IXGBE_RDT(0), self.receive_index as u32); self.receive_index = wrap_ring(self.receive_index, self.receive_ring.len()); @@ -103,14 +103,14 @@ impl NetworkAdapter for Intel8259x { let i = cmp::min(buf.len(), data.len()); data[..i].copy_from_slice(&buf[..i]); - desc.read.cmd_type_len = IXGBE_ADVTXD_DCMD_EOP - | IXGBE_ADVTXD_DCMD_RS - | IXGBE_ADVTXD_DCMD_IFCS - | IXGBE_ADVTXD_DCMD_DEXT - | IXGBE_ADVTXD_DTYP_DATA - | buf.len() as u32; + desc.read.cmd_type_len = IXGBE_ADVTXD_DCMD_EOP + | IXGBE_ADVTXD_DCMD_RS + | IXGBE_ADVTXD_DCMD_IFCS + | IXGBE_ADVTXD_DCMD_DEXT + | IXGBE_ADVTXD_DTYP_DATA + | buf.len() as u32; - desc.read.olinfo_status = (buf.len() as u32) << IXGBE_ADVTXD_PAYLEN_SHIFT; + desc.read.olinfo_status = (buf.len() as u32) << IXGBE_ADVTXD_PAYLEN_SHIFT; self.transmit_index = wrap_ring(self.transmit_index, self.transmit_ring.len()); self.transmit_ring_free -= 1; @@ -290,7 +290,10 @@ impl Intel8259x { self.wait_write_reg(IXGBE_EEC, IXGBE_EEC_ARD); // section 4.6.3 - wait for dma initialization done - self.wait_write_reg(IXGBE_RDRXCTL, IXGBE_RDRXCTL_DMAIDONE | IXGBE_RDRXCTL_RESERVED_BITS); + self.wait_write_reg( + IXGBE_RDRXCTL, + IXGBE_RDRXCTL_DMAIDONE | IXGBE_RDRXCTL_RESERVED_BITS, + ); // section 4.6.4 - initialize link (auto negotiation) self.init_link(); @@ -361,7 +364,10 @@ impl Intel8259x { self.write_reg(IXGBE_RDBAL(i), self.receive_ring.physical() as u32); - self.write_reg(IXGBE_RDBAH(i), ((self.receive_ring.physical() as u64) >> 32) as u32); + self.write_reg( + IXGBE_RDBAH(i), + ((self.receive_ring.physical() as u64) >> 32) as u32, + ); self.write_reg( IXGBE_RDLEN(i), (self.receive_ring.len() * mem::size_of::()) as u32, @@ -407,7 +413,10 @@ impl Intel8259x { // section 7.1.9 - setup descriptor ring self.write_reg(IXGBE_TDBAL(i), self.transmit_ring.physical() as u32); - self.write_reg(IXGBE_TDBAH(i), ((self.transmit_ring.physical() as u64) >> 32) as u32); + self.write_reg( + IXGBE_TDBAH(i), + ((self.transmit_ring.physical() as u64) >> 32) as u32, + ); self.write_reg( IXGBE_TDLEN(i), (self.transmit_ring.len() * mem::size_of::()) as u32, diff --git a/net/ixgbed/src/main.rs b/net/ixgbed/src/main.rs index 8382823230..cd4090c319 100644 --- a/net/ixgbed/src/main.rs +++ b/net/ixgbed/src/main.rs @@ -47,9 +47,22 @@ fn main() { } } - let mut event_queue = EventQueue::::new().expect("ixgbed: Could not create event queue."); - event_queue.subscribe(irq_file.as_raw_fd() as usize, Source::Irq, event::EventFlags::READ).unwrap(); - event_queue.subscribe(scheme.event_handle() as usize, Source::Scheme, event::EventFlags::READ).unwrap(); + let mut event_queue = + EventQueue::::new().expect("ixgbed: Could not create event queue."); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); + event_queue + .subscribe( + scheme.event_handle() as usize, + Source::Scheme, + event::EventFlags::READ, + ) + .unwrap(); libredox::call::setrens(0, 0).expect("ixgbed: failed to enter null namespace"); diff --git a/net/rtl8139d/src/device.rs b/net/rtl8139d/src/device.rs index d67a1b3078..43ce16d26c 100644 --- a/net/rtl8139d/src/device.rs +++ b/net/rtl8139d/src/device.rs @@ -1,11 +1,11 @@ -use std::mem; use std::convert::TryInto; +use std::mem; use driver_network::NetworkAdapter; -use syscall::error::{Error, EIO, EMSGSIZE, Result}; +use syscall::error::{Error, Result, EIO, EMSGSIZE}; -use common::io::{Mmio, Io, ReadOnly}; use common::dma::Dma; +use common::io::{Io, Mmio, ReadOnly}; const RX_BUFFER_SIZE: usize = 64 * 1024; @@ -135,16 +135,11 @@ impl NetworkAdapter for Rtl8139 { self.next_read() } - fn read_packet(&mut self, buf: &mut [u8]) -> Result> { if !self.regs.cr.readf(CR_BUFE) { - let rxsts = - (self.rx(0) as u16) | - (self.rx(1) as u16) << 8; + let rxsts = (self.rx(0) as u16) | (self.rx(1) as u16) << 8; - let size_with_crc = - (self.rx(2) as usize) | - (self.rx(3) as usize) << 8; + let size_with_crc = (self.rx(2) as usize) | (self.rx(3) as usize) << 8; let res = if (rxsts & RXSTS_ROK) == RXSTS_ROK { let mut i = 0; @@ -159,7 +154,8 @@ impl NetworkAdapter for Rtl8139 { Err(Error::new(EIO)) }; - self.receive_i = (self.receive_i + 4 + size_with_crc).next_multiple_of(4) % RX_BUFFER_SIZE; + self.receive_i = + (self.receive_i + 4 + size_with_crc).next_multiple_of(4) % RX_BUFFER_SIZE; let capr = self.receive_i.wrapping_sub(16) as u16; self.regs.capr.write(capr); @@ -243,13 +239,9 @@ impl Rtl8139 { pub fn next_read(&self) -> usize { if !self.regs.cr.readf(CR_BUFE) { - let rxsts = - (self.rx(0) as u16) | - (self.rx(1) as u16) << 8; + let rxsts = (self.rx(0) as u16) | (self.rx(1) as u16) << 8; - let size_with_crc = - (self.rx(2) as usize) | - (self.rx(3) as usize) << 8; + let size_with_crc = (self.rx(2) as usize) | (self.rx(3) as usize) << 8; if (rxsts & RXSTS_ROK) == RXSTS_ROK { size_with_crc.saturating_sub(4) @@ -264,13 +256,18 @@ impl Rtl8139 { pub unsafe fn init(&mut self) { let mac_low = self.regs.mac[0].read(); let mac_high = self.regs.mac[1].read(); - let mac = [mac_low as u8, - (mac_low >> 8) as u8, - (mac_low >> 16) as u8, - (mac_low >> 24) as u8, - mac_high as u8, - (mac_high >> 8) as u8]; - println!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + let mac = [ + mac_low as u8, + (mac_low >> 8) as u8, + (mac_low >> 16) as u8, + (mac_low >> 24) as u8, + mac_high as u8, + (mac_high >> 8) as u8, + ]; + println!( + " - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] + ); self.mac_address = mac; // Reset - this will disable tx and rx, reinitialize FIFOs, and set the system buffer pointer to the initial value @@ -282,13 +279,17 @@ impl Rtl8139 { // Set up rx buffer println!(" - Receive buffer"); - self.regs.rbstart.write(self.receive_buffer.physical() as u32); + self.regs + .rbstart + .write(self.receive_buffer.physical() as u32); println!(" - Interrupt mask"); self.regs.imr.write(IMR_TOK | IMR_ROK); println!(" - Receive configuration"); - self.regs.rcr.write(RCR_RBLEN_64K | RCR_AB | RCR_AM | RCR_APM | RCR_AAP); + self.regs + .rcr + .write(RCR_RBLEN_64K | RCR_AB | RCR_AM | RCR_APM | RCR_AAP); println!(" - Enable RX and TX"); self.regs.cr.writef(CR_RE | CR_TE, true); diff --git a/net/rtl8139d/src/main.rs b/net/rtl8139d/src/main.rs index 4f85e1b96f..c6db719c9d 100644 --- a/net/rtl8139d/src/main.rs +++ b/net/rtl8139d/src/main.rs @@ -53,14 +53,19 @@ impl MappedMsixRegs { fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> File { let pci_config = pcid_handle.config(); - let all_pci_features = pcid_handle.fetch_all_features().expect("rtl8139d: failed to fetch pci features"); + let all_pci_features = pcid_handle + .fetch_all_features() + .expect("rtl8139d: failed to fetch pci features"); log::info!("PCI FEATURES: {:?}", all_pci_features); let has_msi = all_pci_features.iter().any(|feature| feature.is_msi()); let has_msix = all_pci_features.iter().any(|feature| feature.is_msix()); if has_msi && !has_msix { - let capability = match pcid_handle.feature_info(PciFeature::Msi).expect("rtl8139d: failed to retrieve the MSI capability structure from pcid") { + let capability = match pcid_handle + .feature_info(PciFeature::Msi) + .expect("rtl8139d: failed to retrieve the MSI capability structure from pcid") + { PciFeatureInfo::Msi(s) => s, PciFeatureInfo::MsiX(_) => panic!(), }; @@ -70,21 +75,29 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> File { // pcid_interface, so that this can be shared between nvmed, xhcid, ixgebd, etc.. let destination_id = read_bsp_apic_id().expect("rtl8139d: failed to read BSP apic id"); - let (msg_addr_and_data, interrupt_handle) = allocate_single_interrupt_vector_for_msi(destination_id); + let (msg_addr_and_data, interrupt_handle) = + allocate_single_interrupt_vector_for_msi(destination_id); let set_feature_info = MsiSetFeatureInfo { multi_message_enable: Some(0), message_address_and_data: Some(msg_addr_and_data), mask_bits: None, }; - pcid_handle.set_feature_info(SetFeatureInfo::Msi(set_feature_info)).expect("rtl8139d: failed to set feature info"); + pcid_handle + .set_feature_info(SetFeatureInfo::Msi(set_feature_info)) + .expect("rtl8139d: failed to set feature info"); - pcid_handle.enable_feature(PciFeature::Msi).expect("rtl8139d: failed to enable MSI"); + pcid_handle + .enable_feature(PciFeature::Msi) + .expect("rtl8139d: failed to enable MSI"); log::info!("Enabled MSI"); interrupt_handle } else if has_msix { - let msix_info = match pcid_handle.feature_info(PciFeature::MsiX).expect("rtl8139d: failed to retrieve the MSI-X capability structure from pcid") { + let msix_info = match pcid_handle + .feature_info(PciFeature::MsiX) + .expect("rtl8139d: failed to retrieve the MSI-X capability structure from pcid") + { PciFeatureInfo::Msi(_) => panic!(), PciFeatureInfo::MsiX(s) => s, }; @@ -94,7 +107,8 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> File { .ptr .as_ptr() as usize; - let virt_table_base = (bar_address + msix_info.table_offset as usize) as *mut MsixTableEntry; + let virt_table_base = + (bar_address + msix_info.table_offset as usize) as *mut MsixTableEntry; let mut info = MappedMsixRegs { virt_table_base: NonNull::new(virt_table_base).unwrap(), @@ -119,7 +133,9 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> File { interrupt_handle }; - pcid_handle.enable_feature(PciFeature::MsiX).expect("rtl8139d: failed to enable MSI-X"); + pcid_handle + .enable_feature(PciFeature::MsiX) + .expect("rtl8139d: failed to enable MSI-X"); log::info!("Enabled MSI-X"); method @@ -148,14 +164,12 @@ fn find_bar(pci_config: &SubdriverArguments) -> Option<(usize, usize)> { // RTL8139 uses BAR2, RTL8169 uses BAR1, search in that order for &barnum in &[2, 1] { match pci_config.func.bars[barnum] { - pcid_interface::PciBar::Memory32 { addr, size } => return Some(( - addr.try_into().unwrap(), - size.try_into().unwrap() - )), - pcid_interface::PciBar::Memory64 { addr, size } => return Some(( - addr.try_into().unwrap(), - size.try_into().unwrap() - )), + pcid_interface::PciBar::Memory32 { addr, size } => { + return Some((addr.try_into().unwrap(), size.try_into().unwrap())) + } + pcid_interface::PciBar::Memory64 { addr, size } => { + return Some((addr.try_into().unwrap(), size.try_into().unwrap())) + } other => log::warn!("BAR {} is {:?} instead of memory BAR", barnum, other), } } @@ -171,7 +185,8 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { log::LevelFilter::Info, ); - let mut pcid_handle = PciFunctionHandle::connect_default().expect("rtl8139d: failed to setup channel to pcid"); + let mut pcid_handle = + PciFunctionHandle::connect_default().expect("rtl8139d: failed to setup channel to pcid"); let pci_config = pcid_handle.config(); @@ -182,8 +197,13 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { log::info!(" + RTL8139 {}", pci_config.func.display()); let address = unsafe { - common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable) - .expect("rtl8139d: failed to map address") as usize + common::physmap( + bar_ptr, + bar_size, + common::Prot::RW, + common::MemoryType::Uncacheable, + ) + .expect("rtl8139d: failed to map address") as usize }; //TODO: MSI-X @@ -201,9 +221,22 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { } } - let mut event_queue = EventQueue::::new().expect("rtl8139d: Could not create event queue."); - event_queue.subscribe(irq_file.as_raw_fd() as usize, Source::Irq, event::EventFlags::READ).unwrap(); - event_queue.subscribe(scheme.event_handle() as usize, Source::Scheme, event::EventFlags::READ).unwrap(); + let mut event_queue = + EventQueue::::new().expect("rtl8139d: Could not create event queue."); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); + event_queue + .subscribe( + scheme.event_handle() as usize, + Source::Scheme, + event::EventFlags::READ, + ) + .unwrap(); libredox::call::setrens(0, 0).expect("rtl8139d: failed to enter null namespace"); diff --git a/net/rtl8168d/src/device.rs b/net/rtl8168d/src/device.rs index b2aef1889e..c813f06b80 100644 --- a/net/rtl8168d/src/device.rs +++ b/net/rtl8168d/src/device.rs @@ -1,9 +1,9 @@ -use std::mem; use std::convert::TryInto; +use std::mem; +use common::io::{Io, Mmio, ReadOnly}; use driver_network::NetworkAdapter; use syscall::error::{Error, Result, EMSGSIZE}; -use common::io::{Mmio, Io, ReadOnly}; use common::dma::Dma; @@ -89,14 +89,13 @@ impl NetworkAdapter for Rtl8168 { self.next_read() } - fn read_packet(&mut self, buf: &mut [u8]) -> Result> { if self.receive_i >= self.receive_ring.len() { self.receive_i = 0; } let rd = &mut self.receive_ring[self.receive_i]; - if ! rd.ctrl.readf(OWN) { + if !rd.ctrl.readf(OWN) { let rd_len = rd.ctrl.read() & 0x3FFF; let data = &self.receive_buffer[self.receive_i]; @@ -125,7 +124,7 @@ impl NetworkAdapter for Rtl8168 { } let td = &mut self.transmit_ring[self.transmit_i]; - if ! td.ctrl.readf(OWN) { + if !td.ctrl.readf(OWN) { let data = &mut self.transmit_buffer[self.transmit_i]; if buf.len() > data.len() { @@ -214,7 +213,7 @@ impl Rtl8168 { } let rd = &self.receive_ring[receive_i]; - if ! rd.ctrl.readf(OWN) { + if !rd.ctrl.readf(OWN) { (rd.ctrl.read() & 0x3FFF) as usize } else { 0 @@ -224,13 +223,18 @@ impl Rtl8168 { pub unsafe fn init(&mut self) { let mac_low = self.regs.mac[0].read(); let mac_high = self.regs.mac[1].read(); - let mac = [mac_low as u8, - (mac_low >> 8) as u8, - (mac_low >> 16) as u8, - (mac_low >> 24) as u8, - mac_high as u8, - (mac_high >> 8) as u8]; - println!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + let mac = [ + mac_low as u8, + (mac_low >> 8) as u8, + (mac_low >> 16) as u8, + (mac_low >> 24) as u8, + mac_high as u8, + (mac_high >> 8) as u8, + ]; + println!( + " - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] + ); self.mac_address = mac; // Reset - this will disable tx and rx, reinitialize FIFOs, and set the system buffer pointer to the initial value @@ -256,8 +260,12 @@ impl Rtl8168 { // Set up normal priority tx buffers println!(" - Transmit buffers (normal priority)"); for i in 0..self.transmit_ring.len() { - self.transmit_ring[i].buffer_low.write(self.transmit_buffer[i].physical() as u32); - self.transmit_ring[i].buffer_high.write((self.transmit_buffer[i].physical() as u64 >> 32) as u32); + self.transmit_ring[i] + .buffer_low + .write(self.transmit_buffer[i].physical() as u32); + self.transmit_ring[i] + .buffer_high + .write((self.transmit_buffer[i].physical() as u64 >> 32) as u32); } if let Some(td) = self.transmit_ring.last_mut() { td.ctrl.writef(EOR, true); @@ -266,8 +274,12 @@ impl Rtl8168 { // Set up high priority tx buffers println!(" - Transmit buffers (high priority)"); for i in 0..self.transmit_ring_h.len() { - self.transmit_ring_h[i].buffer_low.write(self.transmit_buffer_h[i].physical() as u32); - self.transmit_ring_h[i].buffer_high.write((self.transmit_buffer_h[i].physical() as u64 >> 32) as u32); + self.transmit_ring_h[i] + .buffer_low + .write(self.transmit_buffer_h[i].physical() as u32); + self.transmit_ring_h[i] + .buffer_high + .write((self.transmit_buffer_h[i].physical() as u64 >> 32) as u32); } if let Some(td) = self.transmit_ring_h.last_mut() { td.ctrl.writef(EOR, true); @@ -306,7 +318,9 @@ impl Rtl8168 { self.regs.isr.write(isr); // Interrupt on tx error (bit 3), tx ok (bit 2), rx error(bit 1), and rx ok (bit 0) - self.regs.imr.write(1 << 15 | 1 << 14 | 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1); + self.regs.imr.write( + 1 << 15 | 1 << 14 | 1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 1 | 1, + ); // Set TX config self.regs.tcr.write(0b11 << 24 | 0b111 << 8); diff --git a/net/rtl8168d/src/main.rs b/net/rtl8168d/src/main.rs index cdccf38c7b..49ebc8491c 100644 --- a/net/rtl8168d/src/main.rs +++ b/net/rtl8168d/src/main.rs @@ -8,11 +8,14 @@ use std::rc::Rc; use driver_network::NetworkScheme; use event::{user_data, EventQueue}; -use pcid_interface::{MsiSetFeatureInfo, PciFunctionHandle, PciFeature, PciFeatureInfo, SetFeatureInfo, SubdriverArguments}; #[cfg(target_arch = "x86_64")] use pcid_interface::irq_helpers::allocate_single_interrupt_vector_for_msi; use pcid_interface::irq_helpers::read_bsp_apic_id; use pcid_interface::msi::{MsixInfo, MsixTableEntry}; +use pcid_interface::{ + MsiSetFeatureInfo, PciFeature, PciFeatureInfo, PciFunctionHandle, SetFeatureInfo, + SubdriverArguments, +}; use syscall::EventFlags; pub mod device; @@ -48,14 +51,19 @@ impl MappedMsixRegs { fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> File { let pci_config = pcid_handle.config(); - let all_pci_features = pcid_handle.fetch_all_features().expect("rtl8168d: failed to fetch pci features"); + let all_pci_features = pcid_handle + .fetch_all_features() + .expect("rtl8168d: failed to fetch pci features"); log::info!("PCI FEATURES: {:?}", all_pci_features); let has_msi = all_pci_features.iter().any(|feature| feature.is_msi()); let has_msix = all_pci_features.iter().any(|feature| feature.is_msix()); if has_msi && !has_msix { - let capability = match pcid_handle.feature_info(PciFeature::Msi).expect("rtl8168d: failed to retrieve the MSI capability structure from pcid") { + let capability = match pcid_handle + .feature_info(PciFeature::Msi) + .expect("rtl8168d: failed to retrieve the MSI capability structure from pcid") + { PciFeatureInfo::Msi(s) => s, PciFeatureInfo::MsiX(_) => panic!(), }; @@ -65,21 +73,29 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> File { // pcid_interface, so that this can be shared between nvmed, xhcid, ixgebd, etc.. let destination_id = read_bsp_apic_id().expect("rtl8168d: failed to read BSP apic id"); - let (msg_addr_and_data, interrupt_handle) = allocate_single_interrupt_vector_for_msi(destination_id); + let (msg_addr_and_data, interrupt_handle) = + allocate_single_interrupt_vector_for_msi(destination_id); let set_feature_info = MsiSetFeatureInfo { multi_message_enable: Some(0), message_address_and_data: Some(msg_addr_and_data), mask_bits: None, }; - pcid_handle.set_feature_info(SetFeatureInfo::Msi(set_feature_info)).expect("rtl8168d: failed to set feature info"); + pcid_handle + .set_feature_info(SetFeatureInfo::Msi(set_feature_info)) + .expect("rtl8168d: failed to set feature info"); - pcid_handle.enable_feature(PciFeature::Msi).expect("rtl8168d: failed to enable MSI"); + pcid_handle + .enable_feature(PciFeature::Msi) + .expect("rtl8168d: failed to enable MSI"); log::info!("Enabled MSI"); interrupt_handle } else if has_msix { - let msix_info = match pcid_handle.feature_info(PciFeature::MsiX).expect("rtl8168d: failed to retrieve the MSI-X capability structure from pcid") { + let msix_info = match pcid_handle + .feature_info(PciFeature::MsiX) + .expect("rtl8168d: failed to retrieve the MSI-X capability structure from pcid") + { PciFeatureInfo::Msi(_) => panic!(), PciFeatureInfo::MsiX(s) => s, }; @@ -89,7 +105,8 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> File { .ptr .as_ptr() as usize; - let virt_table_base = (bar_address + msix_info.table_offset as usize) as *mut MsixTableEntry; + let virt_table_base = + (bar_address + msix_info.table_offset as usize) as *mut MsixTableEntry; let mut info = MappedMsixRegs { virt_table_base: NonNull::new(virt_table_base).unwrap(), @@ -114,7 +131,9 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> File { interrupt_handle }; - pcid_handle.enable_feature(PciFeature::MsiX).expect("rtl8168d: failed to enable MSI-X"); + pcid_handle + .enable_feature(PciFeature::MsiX) + .expect("rtl8168d: failed to enable MSI-X"); log::info!("Enabled MSI-X"); method @@ -143,14 +162,12 @@ fn find_bar(pci_config: &SubdriverArguments) -> Option<(usize, usize)> { // RTL8168 uses BAR2, RTL8169 uses BAR1, search in that order for &barnum in &[2, 1] { match pci_config.func.bars[barnum] { - pcid_interface::PciBar::Memory32 { addr, size } => return Some(( - addr.try_into().unwrap(), - size.try_into().unwrap() - )), - pcid_interface::PciBar::Memory64 { addr, size } => return Some(( - addr.try_into().unwrap(), - size.try_into().unwrap() - )), + pcid_interface::PciBar::Memory32 { addr, size } => { + return Some((addr.try_into().unwrap(), size.try_into().unwrap())) + } + pcid_interface::PciBar::Memory64 { addr, size } => { + return Some((addr.try_into().unwrap(), size.try_into().unwrap())) + } other => log::warn!("BAR {} is {:?} instead of memory BAR", barnum, other), } } @@ -166,7 +183,8 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { log::LevelFilter::Info, ); - let mut pcid_handle = PciFunctionHandle::connect_default().expect("rtl8168d: failed to setup channel to pcid"); + let mut pcid_handle = + PciFunctionHandle::connect_default().expect("rtl8168d: failed to setup channel to pcid"); let pci_config = pcid_handle.config(); @@ -177,8 +195,13 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { log::info!(" + RTL8168 {}", pci_config.func.display()); let address = unsafe { - common::physmap(bar_ptr, bar_size, common::Prot::RW, common::MemoryType::Uncacheable) - .expect("rtl8168d: failed to map address") as usize + common::physmap( + bar_ptr, + bar_size, + common::Prot::RW, + common::MemoryType::Uncacheable, + ) + .expect("rtl8168d: failed to map address") as usize }; //TODO: MSI-X @@ -196,9 +219,22 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { } } - let mut event_queue = EventQueue::::new().expect("rtl8168d: Could not create event queue."); - event_queue.subscribe(irq_file.as_raw_fd() as usize, Source::Irq, event::EventFlags::READ).unwrap(); - event_queue.subscribe(scheme.event_handle() as usize, Source::Scheme, event::EventFlags::READ).unwrap(); + let mut event_queue = + EventQueue::::new().expect("rtl8168d: Could not create event queue."); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); + event_queue + .subscribe( + scheme.event_handle() as usize, + Source::Scheme, + event::EventFlags::READ, + ) + .unwrap(); libredox::call::setrens(0, 0).expect("rtl8168d: failed to enter null namespace"); diff --git a/ps2d/src/controller.rs b/ps2d/src/controller.rs index 24968b84a5..9172fa5ee3 100644 --- a/ps2d/src/controller.rs +++ b/ps2d/src/controller.rs @@ -1,19 +1,25 @@ -use log::{debug, error, info, trace}; use common::io::{Io, Pio, ReadOnly, WriteOnly}; +use log::{debug, error, info, trace}; use std::fmt; #[cfg(target_arch = "aarch64")] #[inline(always)] -pub(crate) unsafe fn pause() { std::arch::aarch64::__yield(); } +pub(crate) unsafe fn pause() { + std::arch::aarch64::__yield(); +} #[cfg(target_arch = "x86")] #[inline(always)] -pub(crate) unsafe fn pause() { std::arch::x86::_mm_pause(); } +pub(crate) unsafe fn pause() { + std::arch::x86::_mm_pause(); +} #[cfg(target_arch = "x86_64")] #[inline(always)] -pub(crate) unsafe fn pause() { std::arch::x86_64::_mm_pause(); } +pub(crate) unsafe fn pause() { + std::arch::x86_64::_mm_pause(); +} #[derive(Debug)] pub enum Error { @@ -67,7 +73,7 @@ enum Command { Diagnostic = 0xAC, DisableFirst = 0xAD, EnableFirst = 0xAE, - WriteSecond = 0xD4 + WriteSecond = 0xD4, } #[derive(Clone, Copy, Debug)] @@ -77,13 +83,13 @@ enum KeyboardCommand { EnableReporting = 0xF4, SetDefaultsDisable = 0xF5, SetDefaults = 0xF6, - Reset = 0xFF + Reset = 0xFF, } #[derive(Clone, Copy, Debug)] #[repr(u8)] enum KeyboardCommandData { - ScancodeSet = 0xF0 + ScancodeSet = 0xF0, } #[derive(Clone, Copy, Debug)] @@ -97,7 +103,7 @@ enum MouseCommand { EnableReporting = 0xF4, SetDefaultsDisable = 0xF5, SetDefaults = 0xF6, - Reset = 0xFF + Reset = 0xFF, } #[derive(Clone, Copy, Debug)] @@ -132,7 +138,9 @@ impl Ps2 { if self.status().contains(StatusFlags::OUTPUT_FULL) { return Ok(()); } - unsafe { pause(); } + unsafe { + pause(); + } timeout -= 1; } Err(Error::ReadTimeout) @@ -141,10 +149,12 @@ impl Ps2 { fn wait_write(&mut self) -> Result<(), Error> { let mut timeout = 100_000; while timeout > 0 { - if ! self.status().contains(StatusFlags::INPUT_FULL) { + if !self.status().contains(StatusFlags::INPUT_FULL) { return Ok(()); } - unsafe { pause(); } + unsafe { + pause(); + } timeout -= 1; } Err(Error::WriteTimeout) @@ -157,7 +167,9 @@ impl Ps2 { let val = self.data.read(); trace!("ps2d: flush {}: {:X}", message, val); } - unsafe { pause(); } + unsafe { + pause(); + } timeout -= 1; } } @@ -179,7 +191,12 @@ impl Ps2 { Ok(()) } - fn retry Result>(&mut self, name: fmt::Arguments, retries: usize, f: F) -> Result { + fn retry Result>( + &mut self, + name: fmt::Arguments, + retries: usize, + f: F, + ) -> Result { trace!("ps2d: {}", name); let mut res = Err(Error::NoMoreTries); for retry in 0..retries { @@ -187,7 +204,7 @@ impl Ps2 { match res { Ok(ok) => { return Ok(ok); - }, + } Err(ref err) => { info!("ps2d: {}: retry {}/{}: {:?}", name, retry + 1, retries, err); } @@ -197,26 +214,19 @@ impl Ps2 { } fn config(&mut self) -> Result { - self.retry( - format_args!("read config"), - 4, - |x| { - x.command(Command::ReadConfig)?; - x.read() - } - ).map(ConfigFlags::from_bits_truncate) + self.retry(format_args!("read config"), 4, |x| { + x.command(Command::ReadConfig)?; + x.read() + }) + .map(ConfigFlags::from_bits_truncate) } fn set_config(&mut self, config: ConfigFlags) -> Result<(), Error> { - self.retry( - format_args!("write config"), - 4, - |x| { - x.command(Command::WriteConfig)?; - x.write(config.bits())?; - Ok(0) - } - )?; + self.retry(format_args!("write config"), 4, |x| { + x.command(Command::WriteConfig)?; + x.write(config.bits())?; + Ok(0) + })?; Ok(()) } @@ -229,14 +239,16 @@ impl Ps2 { } fn keyboard_command(&mut self, command: KeyboardCommand) -> Result { - self.retry( - format_args!("keyboard command {:?}", command), - 4, - |x| x.keyboard_command_inner(command as u8) - ) + self.retry(format_args!("keyboard command {:?}", command), 4, |x| { + x.keyboard_command_inner(command as u8) + }) } - fn keyboard_command_data(&mut self, command: KeyboardCommandData, data: u8) -> Result { + fn keyboard_command_data( + &mut self, + command: KeyboardCommandData, + data: u8, + ) -> Result { self.retry( format_args!("keyboard command {:?} {:#x}", command, data), 4, @@ -248,7 +260,7 @@ impl Ps2 { } x.write(data); x.read() - } + }, ) } @@ -262,11 +274,9 @@ impl Ps2 { } fn mouse_command(&mut self, command: MouseCommand) -> Result { - self.retry( - format_args!("mouse command {:?}", command), - 4, - |x| x.mouse_command_inner(command as u8) - ) + self.retry(format_args!("mouse command {:?}", command), 4, |x| { + x.mouse_command_inner(command as u8) + }) } fn mouse_command_data(&mut self, command: MouseCommandData, data: u8) -> Result { @@ -282,7 +292,7 @@ impl Ps2 { x.command(Command::WriteSecond)?; x.write(data as u8)?; x.read() - } + }, ) } @@ -290,7 +300,7 @@ impl Ps2 { let status = self.status(); if status.contains(StatusFlags::OUTPUT_FULL) { let data = self.data.read(); - Some((! status.contains(StatusFlags::SECOND_OUTPUT_FULL), data)) + Some((!status.contains(StatusFlags::SECOND_OUTPUT_FULL), data)) } else { None } @@ -323,32 +333,31 @@ impl Ps2 { self.flush_read("keyboard reset"); } - self.retry( - format_args!("keyboard defaults"), - 4, - |x| { - x.flush_read("keyboard before defaults"); + self.retry(format_args!("keyboard defaults"), 4, |x| { + x.flush_read("keyboard before defaults"); - // Set defaults and disable scanning - let b = x.keyboard_command(KeyboardCommand::SetDefaultsDisable)?; - if b != 0xFA { - error!("ps2d: keyboard failed to set defaults: {:02X}", b); - return Err(Error::CommandRetry); - } - - // Clear remaining data - x.flush_read("keyboard after defaults"); - - Ok(b) + // Set defaults and disable scanning + let b = x.keyboard_command(KeyboardCommand::SetDefaultsDisable)?; + if b != 0xFA { + error!("ps2d: keyboard failed to set defaults: {:02X}", b); + return Err(Error::CommandRetry); } - )?; + + // Clear remaining data + x.flush_read("keyboard after defaults"); + + Ok(b) + })?; { // Set scancode set to 2 let scancode_set = 2; b = self.keyboard_command_data(KeyboardCommandData::ScancodeSet, scancode_set)?; if b != 0xFA { - error!("ps2d: keyboard failed to set scancode set {}: {:02X}", scancode_set, b); + error!( + "ps2d: keyboard failed to set scancode set {}: {:02X}", + scancode_set, b + ); } // Clear remaining data @@ -369,38 +378,34 @@ impl Ps2 { self.flush_read("enable second"); } - self.retry( - format_args!("mouse reset"), - 4, - |x| { - // Clear remaining data - x.flush_read("mouse before reset"); + self.retry(format_args!("mouse reset"), 4, |x| { + // Clear remaining data + x.flush_read("mouse before reset"); - // Reset mouse - let mut b = x.mouse_command(MouseCommand::Reset)?; - if b == 0xFA { - b = x.read()?; - if b != 0xAA { - error!("ps2d: mouse failed self test 1: {:02X}", b); - return Err(Error::CommandRetry); - } - - b = x.read()?; - if b != 0x00 { - error!("ps2d: mouse failed self test 2: {:02X}", b); - return Err(Error::CommandRetry); - } - } else { - error!("ps2d: mouse failed to reset: {:02X}", b); + // Reset mouse + let mut b = x.mouse_command(MouseCommand::Reset)?; + if b == 0xFA { + b = x.read()?; + if b != 0xAA { + error!("ps2d: mouse failed self test 1: {:02X}", b); return Err(Error::CommandRetry); } - // Clear remaining data - x.flush_read("mouse after reset"); - - Ok(b) + b = x.read()?; + if b != 0x00 { + error!("ps2d: mouse failed self test 2: {:02X}", b); + return Err(Error::CommandRetry); + } + } else { + error!("ps2d: mouse failed to reset: {:02X}", b); + return Err(Error::CommandRetry); } - )?; + + // Clear remaining data + x.flush_read("mouse after reset"); + + Ok(b) + })?; { // Set defaults @@ -417,8 +422,9 @@ impl Ps2 { // Enable extra packet on mouse //TODO: show error return values if self.mouse_command_data(MouseCommandData::SetSampleRate, 200)? != 0xFA - || self.mouse_command_data(MouseCommandData::SetSampleRate, 100)? != 0xFA - || self.mouse_command_data(MouseCommandData::SetSampleRate, 80)? != 0xFA { + || self.mouse_command_data(MouseCommandData::SetSampleRate, 100)? != 0xFA + || self.mouse_command_data(MouseCommandData::SetSampleRate, 80)? != 0xFA + { error!("ps2d: mouse failed to enable extra packet"); } @@ -442,7 +448,10 @@ impl Ps2 { let resolution = 3; b = self.mouse_command_data(MouseCommandData::SetResolution, resolution)?; if b != 0xFA { - error!("ps2d: mouse failed to set resolution to {}: {:02X}", resolution, b); + error!( + "ps2d: mouse failed to set resolution to {}: {:02X}", + resolution, b + ); } // Clear remaining data @@ -453,7 +462,7 @@ impl Ps2 { // Set scaling to 1:1 b = self.mouse_command(MouseCommand::SetScaling1To1)?; if b != 0xFA { - error!("ps2d: mouse failed to set scaling: {:02X}", b); + error!("ps2d: mouse failed to set scaling: {:02X}", b); } // Clear remaining data @@ -465,7 +474,10 @@ impl Ps2 { let sample_rate = 200; b = self.mouse_command_data(MouseCommandData::SetSampleRate, sample_rate)?; if b != 0xFA { - error!("ps2d: mouse failed to set sample rate to {}: {:02X}", sample_rate, b); + error!( + "ps2d: mouse failed to set sample rate to {}: {:02X}", + sample_rate, b + ); } // Clear remaining data @@ -475,13 +487,16 @@ impl Ps2 { { b = self.mouse_command(MouseCommand::StatusRequest)?; if b != 0xFA { - error!("ps2d: mouse failed to request status: {:02X}", b); + error!("ps2d: mouse failed to request status: {:02X}", b); } else { let a = self.read()?; let b = self.read()?; let c = self.read()?; - debug!("ps2d: mouse status {:#x} resolution {:#x} sample rate {:#x}", a, b, c); + debug!( + "ps2d: mouse status {:#x} resolution {:#x} sample rate {:#x}", + a, b, c + ); } } @@ -506,9 +521,9 @@ impl Ps2 { { // Since the default config may have interrupts enabled, and the kernel may eat up // our data in that case, we will write a config without reading the current one - config = ConfigFlags::POST_PASSED | - ConfigFlags::FIRST_DISABLED | - ConfigFlags::SECOND_DISABLED; + config = ConfigFlags::POST_PASSED + | ConfigFlags::FIRST_DISABLED + | ConfigFlags::SECOND_DISABLED; trace!("ps2d: config set {:?}", config); self.set_config(config)?; diff --git a/ps2d/src/keymap.rs b/ps2d/src/keymap.rs index 236e7caa07..46264606a7 100644 --- a/ps2d/src/keymap.rs +++ b/ps2d/src/keymap.rs @@ -57,7 +57,7 @@ pub mod us { ['\0', '\0'], ['\0', '\0'], ['\0', '\0'], - [' ', ' '] + [' ', ' '], ]; pub fn get_char(scancode: u8, shift: bool) -> char { @@ -236,7 +236,7 @@ pub mod dvorak { ['\0', '\0'], ['\0', '\0'], ['\0', '\0'], - [' ', ' '] + [' ', ' '], ]; pub fn get_char(scancode: u8, shift: bool) -> char { @@ -311,7 +311,7 @@ pub mod azerty { ['\0', '\0'], ['\0', '\0'], ['\0', '\0'], - [' ', ' '] + [' ', ' '], ]; pub fn get_char(scancode: u8, shift: bool) -> char { @@ -386,7 +386,7 @@ pub mod bepo { ['\0', '\0'], ['\0', '\0'], ['\0', '\0'], - [' ', ' '] + [' ', ' '], ]; pub fn get_char(scancode: u8, shift: bool) -> char { @@ -461,7 +461,7 @@ pub mod it { ['\0', '\0'], ['\0', '\0'], ['\0', '\0'], - [' ', ' '] + [' ', ' '], ]; pub fn get_char(scancode: u8, shift: bool) -> char { diff --git a/ps2d/src/main.rs b/ps2d/src/main.rs index 2b08b8fb97..5455aaa161 100644 --- a/ps2d/src/main.rs +++ b/ps2d/src/main.rs @@ -5,11 +5,11 @@ extern crate bitflags; extern crate orbclient; extern crate syscall; -use std::{env, process}; use std::fs::OpenOptions; use std::io::{Read, Write}; use std::os::unix::fs::OpenOptionsExt; use std::os::unix::io::AsRawFd; +use std::{env, process}; use log::info; use syscall::call::iopl; @@ -21,7 +21,6 @@ mod keymap; mod state; mod vm; - fn daemon(daemon: redox_daemon::Daemon) -> ! { common::setup_logging( "misc", @@ -35,10 +34,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { iopl(3).expect("ps2d: failed to get I/O permission"); } - let (keymap, keymap_name): ( - fn(u8, bool) -> char, - &str - ) = match env::args().skip(1).next() { + let (keymap, keymap_name): (fn(u8, bool) -> char, &str) = match env::args().skip(1).next() { Some(k) => match k.to_lowercase().as_ref() { "dvorak" => (keymap::dvorak::get_char, "dvorak"), "us" => (keymap::us::get_char, "us"), @@ -71,11 +67,13 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { .open("/scheme/serio/0") .expect("ps2d: failed to open /scheme/serio/0"); - event_file.write(&syscall::Event { - id: key_file.as_raw_fd() as usize, - flags: syscall::EVENT_READ, - data: 0 - }).expect("ps2d: failed to event /scheme/serio/0"); + event_file + .write(&syscall::Event { + id: key_file.as_raw_fd() as usize, + flags: syscall::EVENT_READ, + data: 0, + }) + .expect("ps2d: failed to event /scheme/serio/0"); let mut mouse_file = OpenOptions::new() .read(true) @@ -84,15 +82,19 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { .open("/scheme/serio/1") .expect("ps2d: failed to open /scheme/serio/1"); - event_file.write(&syscall::Event { - id: mouse_file.as_raw_fd() as usize, - flags: syscall::EVENT_READ, - data: 1 - }).expect("ps2d: failed to event /scheme/serio/1"); + event_file + .write(&syscall::Event { + id: mouse_file.as_raw_fd() as usize, + flags: syscall::EVENT_READ, + data: 1, + }) + .expect("ps2d: failed to event /scheme/serio/1"); libredox::call::setrens(0, 0).expect("ps2d: failed to enter null namespace"); - daemon.ready().expect("ps2d: failed to mark daemon as ready"); + daemon + .ready() + .expect("ps2d: failed to mark daemon as ready"); let mut ps2d = Ps2d::new(input, keymap); @@ -108,7 +110,11 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { // to grab bytes and sort them based on the source let mut event = syscall::Event::default(); - if event_file.read(&mut event).expect("ps2d: failed to read event file") == 0 { + if event_file + .read(&mut event) + .expect("ps2d: failed to read event file") + == 0 + { break; } diff --git a/ps2d/src/state.rs b/ps2d/src/state.rs index 22db4e26e0..b25cec9455 100644 --- a/ps2d/src/state.rs +++ b/ps2d/src/state.rs @@ -4,7 +4,7 @@ use std::os::unix::io::AsRawFd; use std::str; use log::{error, warn}; -use orbclient::{KeyEvent, MouseEvent, MouseRelativeEvent, ButtonEvent, ScrollEvent}; +use orbclient::{ButtonEvent, KeyEvent, MouseEvent, MouseRelativeEvent, ScrollEvent}; use crate::controller::Ps2; use crate::vm; @@ -22,7 +22,7 @@ bitflags! { } } -pub struct Ps2d char> { +pub struct Ps2d char> { ps2: Ps2, vmmouse: bool, vmmouse_relative: bool, @@ -39,10 +39,10 @@ pub struct Ps2d char> { packet_i: usize, extra_packet: bool, //Keymap function - get_char: F + get_char: F, } -impl char> Ps2d { +impl char> Ps2d { pub fn new(input: File, keymap: F) -> Self { let mut ps2 = Ps2::new(); let extra_packet = ps2.init().expect("ps2d: failed to initialize"); @@ -67,7 +67,7 @@ impl char> Ps2d { packets: [0; 4], packet_i: 0, extra_packet, - get_char: keymap + get_char: keymap, } } @@ -228,11 +228,19 @@ impl char> Ps2d { } if scancode != 0 { - self.input.write(&KeyEvent { - character: (self.get_char)(ps2_scancode, self.lshift || self.rshift), - scancode, - pressed - }.to_event()).expect("ps2d: failed to write key event"); + self.input + .write( + &KeyEvent { + character: (self.get_char)( + ps2_scancode, + self.lshift || self.rshift, + ), + scancode, + pressed, + } + .to_event(), + ) + .expect("ps2d: failed to write key event"); } } } else if self.vmmouse { @@ -254,10 +262,15 @@ impl char> Ps2d { if self.vmmouse_relative { if dx != 0 || dy != 0 { - self.input.write(&MouseRelativeEvent { - dx: dx as i32, - dy: dy as i32, - }.to_event()).expect("ps2d: failed to write mouse event"); + self.input + .write( + &MouseRelativeEvent { + dx: dx as i32, + dy: dy as i32, + } + .to_event(), + ) + .expect("ps2d: failed to write mouse event"); } } else { let x = dx as i32; @@ -272,24 +285,37 @@ impl char> Ps2d { }; if dz != 0 { - self.input.write(&ScrollEvent { - x: 0, - y: -(dz as i32), - }.to_event()).expect("ps2d: failed to write scroll event"); + self.input + .write( + &ScrollEvent { + x: 0, + y: -(dz as i32), + } + .to_event(), + ) + .expect("ps2d: failed to write scroll event"); } let left = status & vm::LEFT_BUTTON == vm::LEFT_BUTTON; let middle = status & vm::MIDDLE_BUTTON == vm::MIDDLE_BUTTON; let right = status & vm::RIGHT_BUTTON == vm::RIGHT_BUTTON; - if left != self.mouse_left || middle != self.mouse_middle || right != self.mouse_right { + if left != self.mouse_left + || middle != self.mouse_middle + || right != self.mouse_right + { self.mouse_left = left; self.mouse_middle = middle; self.mouse_right = right; - self.input.write(&ButtonEvent { - left: left, - middle: middle, - right: right, - }.to_event()).expect("ps2d: failed to write button event"); + self.input + .write( + &ButtonEvent { + left: left, + middle: middle, + right: right, + } + .to_event(), + ) + .expect("ps2d: failed to write button event"); } } } else { @@ -297,13 +323,17 @@ impl char> Ps2d { self.packet_i += 1; let flags = MousePacketFlags::from_bits_truncate(self.packets[0]); - if ! flags.contains(MousePacketFlags::ALWAYS_ON) { + if !flags.contains(MousePacketFlags::ALWAYS_ON) { error!("ps2d: mouse misalign {:X}", self.packets[0]); self.packets = [0; 4]; self.packet_i = 0; - } else if self.packet_i >= self.packets.len() || (!self.extra_packet && self.packet_i >= 3) { - if ! flags.contains(MousePacketFlags::X_OVERFLOW) && ! flags.contains(MousePacketFlags::Y_OVERFLOW) { + } else if self.packet_i >= self.packets.len() + || (!self.extra_packet && self.packet_i >= 3) + { + if !flags.contains(MousePacketFlags::X_OVERFLOW) + && !flags.contains(MousePacketFlags::Y_OVERFLOW) + { let mut dx = self.packets[1] as i32; if flags.contains(MousePacketFlags::X_SIGN) { dx -= 0x100; @@ -324,34 +354,43 @@ impl char> Ps2d { } if dx != 0 || dy != 0 { - self.input.write(&MouseRelativeEvent { - dx: dx, - dy: dy, - }.to_event()).expect("ps2d: failed to write mouse event"); + self.input + .write(&MouseRelativeEvent { dx: dx, dy: dy }.to_event()) + .expect("ps2d: failed to write mouse event"); } if dz != 0 { - self.input.write(&ScrollEvent { - x: 0, - y: dz, - }.to_event()).expect("ps2d: failed to write scroll event"); + self.input + .write(&ScrollEvent { x: 0, y: dz }.to_event()) + .expect("ps2d: failed to write scroll event"); } let left = flags.contains(MousePacketFlags::LEFT_BUTTON); let middle = flags.contains(MousePacketFlags::MIDDLE_BUTTON); let right = flags.contains(MousePacketFlags::RIGHT_BUTTON); - if left != self.mouse_left || middle != self.mouse_middle || right != self.mouse_right { + if left != self.mouse_left + || middle != self.mouse_middle + || right != self.mouse_right + { self.mouse_left = left; self.mouse_middle = middle; self.mouse_right = right; - self.input.write(&ButtonEvent { - left: left, - middle: middle, - right: right, - }.to_event()).expect("ps2d: failed to write button event"); + self.input + .write( + &ButtonEvent { + left: left, + middle: middle, + right: right, + } + .to_event(), + ) + .expect("ps2d: failed to write button event"); } } else { - warn!("ps2d: overflow {:X} {:X} {:X} {:X}", self.packets[0], self.packets[1], self.packets[2], self.packets[3]); + warn!( + "ps2d: overflow {:X} {:X} {:X} {:X}", + self.packets[0], self.packets[1], self.packets[2], self.packets[3] + ); } self.packets = [0; 4]; diff --git a/storage/ahcid/src/ahci/disk_ata.rs b/storage/ahcid/src/ahci/disk_ata.rs index 394b61dd35..2dc2a1f190 100644 --- a/storage/ahcid/src/ahci/disk_ata.rs +++ b/storage/ahcid/src/ahci/disk_ata.rs @@ -5,7 +5,7 @@ use syscall::error::Result; use common::dma::Dma; -use super::hba::{HbaPort, HbaCmdTable, HbaCmdHeader}; +use super::hba::{HbaCmdHeader, HbaCmdTable, HbaPort}; use super::Disk; enum BufferKind<'a> { @@ -28,7 +28,7 @@ pub struct DiskATA { clb: Dma<[HbaCmdHeader; 32]>, ctbas: [Dma; 32], _fb: Dma<[u8; 256]>, - buf: Dma<[u8; 256 * 512]> + buf: Dma<[u8; 256 * 512]>, } impl DiskATA { @@ -56,26 +56,28 @@ impl DiskATA { clb: clb, ctbas, _fb: fb, - buf: buf + buf: buf, }) } fn request(&mut self, block: u64, mut buffer_kind: BufferKind) -> Result> { let (write, address, total_sectors) = match buffer_kind { - BufferKind::Read(ref buffer) => (false, buffer.as_ptr() as usize, buffer.len()/512), - BufferKind::Write(ref buffer) => (true, buffer.as_ptr() as usize, buffer.len()/512), + BufferKind::Read(ref buffer) => (false, buffer.as_ptr() as usize, buffer.len() / 512), + BufferKind::Write(ref buffer) => (true, buffer.as_ptr() as usize, buffer.len() / 512), }; loop { let mut request = match self.request_opt.take() { - Some(request) => if address == request.address && total_sectors == request.total_sectors { - // Keep servicing current request - request - } else { - // Have to wait for another request to finish - self.request_opt = Some(request); - return Ok(None); - }, + Some(request) => { + if address == request.address && total_sectors == request.total_sectors { + // Keep servicing current request + request + } else { + // Have to wait for another request to finish + self.request_opt = Some(request); + return Ok(None); + } + } None => { // Create new request Request { @@ -99,7 +101,13 @@ impl DiskATA { self.port.ata_stop(running.0)?; if let BufferKind::Read(ref mut buffer) = buffer_kind { - unsafe { ptr::copy(self.buf.as_ptr(), buffer.as_mut_ptr().add(request.sector * 512), running.1 * 512); } + unsafe { + ptr::copy( + self.buf.as_ptr(), + buffer.as_mut_ptr().add(request.sector * 512), + running.1 * 512, + ); + } } request.sector += running.1; @@ -114,10 +122,23 @@ impl DiskATA { }; if let BufferKind::Write(ref buffer) = buffer_kind { - unsafe { ptr::copy(buffer.as_ptr().add(request.sector * 512), self.buf.as_mut_ptr(), sectors * 512); } + unsafe { + ptr::copy( + buffer.as_ptr().add(request.sector * 512), + self.buf.as_mut_ptr(), + sectors * 512, + ); + } } - if let Some(slot) = self.port.ata_dma(block + request.sector as u64, sectors, write, &mut self.clb, &mut self.ctbas, &mut self.buf) { + if let Some(slot) = self.port.ata_dma( + block + request.sector as u64, + sectors, + write, + &mut self.clb, + &mut self.ctbas, + &mut self.buf, + ) { request.running_opt = Some((slot, sectors)); } @@ -146,7 +167,7 @@ impl Disk for DiskATA { loop { match self.request(block, BufferKind::Read(buffer))? { Some(count) => return Ok(Some(count)), - None => std::thread::yield_now() + None => std::thread::yield_now(), } } } @@ -156,7 +177,7 @@ impl Disk for DiskATA { loop { match self.request(block, BufferKind::Write(buffer))? { Some(count) => return Ok(Some(count)), - None => std::thread::yield_now() + None => std::thread::yield_now(), } } } diff --git a/storage/ahcid/src/ahci/disk_atapi.rs b/storage/ahcid/src/ahci/disk_atapi.rs index a3c63f7abb..29ae47996c 100644 --- a/storage/ahcid/src/ahci/disk_atapi.rs +++ b/storage/ahcid/src/ahci/disk_atapi.rs @@ -3,13 +3,13 @@ use std::convert::TryInto; use std::ptr; -use byteorder::{ByteOrder, BigEndian}; +use byteorder::{BigEndian, ByteOrder}; -use syscall::error::{Result, EBADF, Error}; +use syscall::error::{Error, Result, EBADF}; use common::dma::Dma; -use super::hba::{HbaPort, HbaCmdTable, HbaCmdHeader}; +use super::hba::{HbaCmdHeader, HbaCmdTable, HbaPort}; use super::Disk; const SCSI_READ_CAPACITY: u8 = 0x25; @@ -24,7 +24,7 @@ pub struct DiskATAPI { _fb: Dma<[u8; 256]>, // Just using the same buffer size as DiskATA // Although the sector size is different (and varies) - buf: Dma<[u8; 256 * 512]> + buf: Dma<[u8; 256 * 512]>, } impl DiskATAPI { @@ -60,7 +60,8 @@ impl DiskATAPI { let mut cmd = [0; 16]; cmd[0] = SCSI_READ_CAPACITY; - self.port.atapi_dma(&cmd, 8, &mut self.clb, &mut self.ctbas, &mut self.buf)?; + self.port + .atapi_dma(&cmd, 8, &mut self.clb, &mut self.ctbas, &mut self.buf)?; // Instead of a count, contains number of last LBA, so add 1 let blk_count = BigEndian::read_u32(&self.buf[0..4]) + 1; @@ -78,7 +79,7 @@ impl Disk for DiskATAPI { fn size(&mut self) -> u64 { match self.read_capacity() { Ok((blk_count, blk_size)) => (blk_count as u64) * (blk_size as u64), - Err(_) => 0 // XXX + Err(_) => 0, // XXX } } @@ -101,17 +102,45 @@ impl Disk for DiskATAPI { let buf_size = buf_len * blk_len; while sectors - sector >= buf_len { let cmd = read10_cmd(block as u32 + sector, buf_len as u16); - self.port.atapi_dma(&cmd, buf_size, &mut self.clb, &mut self.ctbas, &mut self.buf)?; + self.port.atapi_dma( + &cmd, + buf_size, + &mut self.clb, + &mut self.ctbas, + &mut self.buf, + )?; - unsafe { ptr::copy(self.buf.as_ptr(), buffer.as_mut_ptr().offset(sector as isize * blk_len as isize), buf_size as usize); } + unsafe { + ptr::copy( + self.buf.as_ptr(), + buffer + .as_mut_ptr() + .offset(sector as isize * blk_len as isize), + buf_size as usize, + ); + } sector += blk_len; } if sector < sectors { let cmd = read10_cmd(block as u32 + sector, (sectors - sector) as u16); - self.port.atapi_dma(&cmd, buf_size, &mut self.clb, &mut self.ctbas, &mut self.buf)?; + self.port.atapi_dma( + &cmd, + buf_size, + &mut self.clb, + &mut self.ctbas, + &mut self.buf, + )?; - unsafe { ptr::copy(self.buf.as_ptr(), buffer.as_mut_ptr().offset(sector as isize * blk_len as isize), ((sectors - sector) * blk_len) as usize); } + unsafe { + ptr::copy( + self.buf.as_ptr(), + buffer + .as_mut_ptr() + .offset(sector as isize * blk_len as isize), + ((sectors - sector) * blk_len) as usize, + ); + } sector += sectors - sector; } diff --git a/storage/ahcid/src/ahci/fis.rs b/storage/ahcid/src/ahci/fis.rs index 0e4b380271..5c1f69b78d 100644 --- a/storage/ahcid/src/ahci/fis.rs +++ b/storage/ahcid/src/ahci/fis.rs @@ -17,7 +17,7 @@ pub enum FisType { /// PIO setup FIS - device to host PioSetup = 0x5F, /// Set device bits FIS - device to host - DevBits = 0xA1 + DevBits = 0xA1, } #[repr(packed)] @@ -27,25 +27,25 @@ pub struct FisRegH2D { pub pm: Mmio, // Port multiplier, 1: Command, 0: Control - pub command: Mmio, // Command register + pub command: Mmio, // Command register pub featurel: Mmio, // Feature register, 7:0 // DWORD 1 - pub lba0: Mmio, // LBA low register, 7:0 - pub lba1: Mmio, // LBA mid register, 15:8 - pub lba2: Mmio, // LBA high register, 23:16 + pub lba0: Mmio, // LBA low register, 7:0 + pub lba1: Mmio, // LBA mid register, 15:8 + pub lba2: Mmio, // LBA high register, 23:16 pub device: Mmio, // Device register // DWORD 2 - pub lba3: Mmio, // LBA register, 31:24 - pub lba4: Mmio, // LBA register, 39:32 - pub lba5: Mmio, // LBA register, 47:40 + pub lba3: Mmio, // LBA register, 31:24 + pub lba4: Mmio, // LBA register, 39:32 + pub lba5: Mmio, // LBA register, 47:40 pub featureh: Mmio, // Feature register, 15:8 // DWORD 3 - pub countl: Mmio, // Count register, 7:0 - pub counth: Mmio, // Count register, 15:8 - pub icc: Mmio, // Isochronous command completion + pub countl: Mmio, // Count register, 7:0 + pub counth: Mmio, // Count register, 15:8 + pub icc: Mmio, // Isochronous command completion pub control: Mmio, // Control register // DWORD 4 @@ -60,12 +60,12 @@ pub struct FisRegD2H { pub pm: Mmio, // Port multiplier, Interrupt bit: 2 pub status: Mmio, // Status register - pub error: Mmio, // Error register + pub error: Mmio, // Error register // DWORD 1 - pub lba0: Mmio, // LBA low register, 7:0 - pub lba1: Mmio, // LBA mid register, 15:8 - pub lba2: Mmio, // LBA high register, 23:16 + pub lba0: Mmio, // LBA low register, 7:0 + pub lba1: Mmio, // LBA mid register, 15:8 + pub lba2: Mmio, // LBA high register, 23:16 pub device: Mmio, // Device register // DWORD 2 @@ -75,8 +75,8 @@ pub struct FisRegD2H { pub rsv2: Mmio, // Reserved // DWORD 3 - pub countl: Mmio, // Count register, 7:0 - pub counth: Mmio, // Count register, 15:8 + pub countl: Mmio, // Count register, 7:0 + pub counth: Mmio, // Count register, 15:8 pub rsv3: [Mmio; 2], // Reserved // DWORD 4 @@ -104,12 +104,12 @@ pub struct FisPioSetup { pub pm: Mmio, // Port multiplier, direction: 4 - device to host, interrupt: 2 pub status: Mmio, // Status register - pub error: Mmio, // Error register + pub error: Mmio, // Error register // DWORD 1 - pub lba0: Mmio, // LBA low register, 7:0 - pub lba1: Mmio, // LBA mid register, 15:8 - pub lba2: Mmio, // LBA high register, 23:16 + pub lba0: Mmio, // LBA low register, 7:0 + pub lba1: Mmio, // LBA mid register, 15:8 + pub lba2: Mmio, // LBA high register, 23:16 pub device: Mmio, // Device register // DWORD 2 @@ -119,13 +119,13 @@ pub struct FisPioSetup { pub rsv2: Mmio, // Reserved // DWORD 3 - pub countl: Mmio, // Count register, 7:0 - pub counth: Mmio, // Count register, 15:8 - pub rsv3: Mmio, // Reserved + pub countl: Mmio, // Count register, 7:0 + pub counth: Mmio, // Count register, 15:8 + pub rsv3: Mmio, // Reserved pub e_status: Mmio, // New value of status register // DWORD 4 - pub tc: Mmio, // Transfer count + pub tc: Mmio, // Transfer count pub rsv4: [Mmio; 2], // Reserved } diff --git a/storage/ahcid/src/ahci/hba.rs b/storage/ahcid/src/ahci/hba.rs index b893fddc81..00e80f37e4 100644 --- a/storage/ahcid/src/ahci/hba.rs +++ b/storage/ahcid/src/ahci/hba.rs @@ -6,7 +6,7 @@ use std::{ptr, u32}; use common::io::{Io, Mmio}; use syscall::error::{Error, Result, EIO}; -use super::fis::{FisType, FisRegH2D}; +use super::fis::{FisRegH2D, FisType}; use common::dma::Dma; @@ -42,20 +42,20 @@ pub enum HbaPortType { #[repr(packed)] pub struct HbaPort { pub clb: [Mmio; 2], // 0x00, command list base address, 1K-byte aligned - pub fb: [Mmio; 2], // 0x08, FIS base address, 256-byte aligned - pub is: Mmio, // 0x10, interrupt status - pub ie: Mmio, // 0x14, interrupt enable - pub cmd: Mmio, // 0x18, command and status - pub _rsv0: Mmio, // 0x1C, Reserved - pub tfd: Mmio, // 0x20, task file data - pub sig: Mmio, // 0x24, signature - pub ssts: Mmio, // 0x28, SATA status (SCR0:SStatus) - pub sctl: Mmio, // 0x2C, SATA control (SCR2:SControl) - pub serr: Mmio, // 0x30, SATA error (SCR1:SError) - pub sact: Mmio, // 0x34, SATA active (SCR3:SActive) - pub ci: Mmio, // 0x38, command issue - pub sntf: Mmio, // 0x3C, SATA notification (SCR4:SNotification) - pub fbs: Mmio, // 0x40, FIS-based switch control + pub fb: [Mmio; 2], // 0x08, FIS base address, 256-byte aligned + pub is: Mmio, // 0x10, interrupt status + pub ie: Mmio, // 0x14, interrupt enable + pub cmd: Mmio, // 0x18, command and status + pub _rsv0: Mmio, // 0x1C, Reserved + pub tfd: Mmio, // 0x20, task file data + pub sig: Mmio, // 0x24, signature + pub ssts: Mmio, // 0x28, SATA status (SCR0:SStatus) + pub sctl: Mmio, // 0x2C, SATA control (SCR2:SControl) + pub serr: Mmio, // 0x30, SATA error (SCR1:SError) + pub sact: Mmio, // 0x34, SATA active (SCR3:SActive) + pub ci: Mmio, // 0x38, command issue + pub sntf: Mmio, // 0x3C, SATA notification (SCR4:SNotification) + pub fbs: Mmio, // 0x40, FIS-based switch control pub _rsv1: [Mmio; 11], // 0x44 ~ 0x6F, Reserved pub vendor: [Mmio; 4], // 0x70 ~ 0x7F, vendor specific } @@ -104,13 +104,20 @@ impl HbaPort { None } - pub fn init(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32], fb: &mut Dma<[u8; 256]>) { + pub fn init( + &mut self, + clb: &mut Dma<[HbaCmdHeader; 32]>, + ctbas: &mut [Dma; 32], + fb: &mut Dma<[u8; 256]>, + ) { self.stop(); for i in 0..32 { let cmdheader = &mut clb[i]; cmdheader.ctba_low.write(ctbas[i].physical() as u32); - cmdheader.ctba_high.write((ctbas[i].physical() as u64 >> 32) as u32); + cmdheader + .ctba_high + .write((ctbas[i].physical() as u64 >> 32) as u32); cmdheader.prdtl.write(0); } @@ -125,7 +132,7 @@ impl HbaPort { self.serr.write(serr); // Disable power management - let sctl = self.sctl.read() ; + let sctl = self.sctl.read(); self.sctl.write(sctl | 7 << 8); // Power on and spin up device @@ -134,16 +141,29 @@ impl HbaPort { debug!(" - AHCI init {:X}", self.cmd.read()); } - pub unsafe fn identify(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32]) -> Option { + pub unsafe fn identify( + &mut self, + clb: &mut Dma<[HbaCmdHeader; 32]>, + ctbas: &mut [Dma; 32], + ) -> Option { self.identify_inner(ATA_CMD_IDENTIFY, clb, ctbas) } - pub unsafe fn identify_packet(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32]) -> Option { + pub unsafe fn identify_packet( + &mut self, + clb: &mut Dma<[HbaCmdHeader; 32]>, + ctbas: &mut [Dma; 32], + ) -> Option { self.identify_inner(ATA_CMD_IDENTIFY_PACKET, clb, ctbas) } // Shared between identify() and identify_packet() - unsafe fn identify_inner(&mut self, cmd: u8, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32]) -> Option { + unsafe fn identify_inner( + &mut self, + cmd: u8, + clb: &mut Dma<[HbaCmdHeader; 32]>, + ctbas: &mut [Dma; 32], + ) -> Option { let dest: Dma<[u16; 256]> = Dma::new([0; 256]).unwrap(); let slot = self.ata_start(clb, ctbas, |cmdheader, cmdfis, prdt_entries, _acmd| { @@ -151,7 +171,9 @@ impl HbaPort { let prdt_entry = &mut prdt_entries[0]; prdt_entry.dba_low.write(dest.physical() as u32); - prdt_entry.dba_high.write((dest.physical() as u64 >> 32) as u32); + prdt_entry + .dba_high + .write((dest.physical() as u64 >> 32) as u32); prdt_entry.dbc.write(512 | 1); cmdfis.pm.write(1 << 7); @@ -201,10 +223,10 @@ impl HbaPort { } } - let mut sectors = (dest[100] as u64) | - ((dest[101] as u64) << 16) | - ((dest[102] as u64) << 32) | - ((dest[103] as u64) << 48); + let mut sectors = (dest[100] as u64) + | ((dest[101] as u64) << 16) + | ((dest[102] as u64) << 32) + | ((dest[103] as u64) << 48); let lba_bits = if sectors == 0 { sectors = (dest[60] as u64) | ((dest[61] as u64) << 16); @@ -213,8 +235,14 @@ impl HbaPort { 48 }; - info!(" + Serial: {} Firmware: {} Model: {} {}-bit LBA Size: {} MB", - 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 { @@ -222,8 +250,22 @@ impl HbaPort { } } - pub fn ata_dma(&mut self, block: u64, sectors: usize, write: bool, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32], buf: &mut Dma<[u8; 256 * 512]>) -> Option { - trace!("AHCI {:X} DMA BLOCK: {:X} SECTORS: {} WRITE: {}", (self as *mut HbaPort) as usize, block, sectors, write); + pub fn ata_dma( + &mut self, + block: u64, + sectors: usize, + write: bool, + clb: &mut Dma<[HbaCmdHeader; 32]>, + ctbas: &mut [Dma; 32], + buf: &mut Dma<[u8; 256 * 512]>, + ) -> Option { + trace!( + "AHCI {:X} DMA BLOCK: {:X} SECTORS: {} WRITE: {}", + (self as *mut HbaPort) as usize, + block, + sectors, + write + ); assert!(sectors > 0 && sectors < 256); @@ -237,7 +279,9 @@ impl HbaPort { let prdt_entry = &mut prdt_entries[0]; prdt_entry.dba_low.write(buf.physical() as u32); - prdt_entry.dba_high.write((buf.physical() as u64 >> 32) as u32); + prdt_entry + .dba_high + .write((buf.physical() as u64 >> 32) as u32); prdt_entry.dbc.write(((sectors * 512) as u32) | 1); cmdfis.pm.write(1 << 7); @@ -263,44 +307,74 @@ impl HbaPort { } /// Send ATAPI packet - pub fn atapi_dma(&mut self, cmd: &[u8; 16], size: u32, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32], buf: &mut Dma<[u8; 256 * 512]>) -> Result<()> { - let slot = self.ata_start(clb, ctbas, |cmdheader, cmdfis, prdt_entries, acmd| { - let cfl = cmdheader.cfl.read(); - cmdheader.cfl.write(cfl | 1 << 5); + pub fn atapi_dma( + &mut self, + cmd: &[u8; 16], + size: u32, + clb: &mut Dma<[HbaCmdHeader; 32]>, + ctbas: &mut [Dma; 32], + buf: &mut Dma<[u8; 256 * 512]>, + ) -> Result<()> { + let slot = self + .ata_start(clb, ctbas, |cmdheader, cmdfis, prdt_entries, acmd| { + let cfl = cmdheader.cfl.read(); + cmdheader.cfl.write(cfl | 1 << 5); - cmdheader.prdtl.write(1); + cmdheader.prdtl.write(1); - let prdt_entry = &mut prdt_entries[0]; - prdt_entry.dba_low.write(buf.physical() as u32); - prdt_entry.dba_high.write((buf.physical() as u64 >> 32) as u32); - prdt_entry.dbc.write(size - 1); + let prdt_entry = &mut prdt_entries[0]; + prdt_entry.dba_low.write(buf.physical() as u32); + prdt_entry + .dba_high + .write((buf.physical() as u64 >> 32) as u32); + prdt_entry.dbc.write(size - 1); - cmdfis.pm.write(1 << 7); - cmdfis.command.write(ATA_CMD_PACKET); - cmdfis.device.write(0); - cmdfis.lba1.write(0); - cmdfis.lba2.write(0); - cmdfis.featurel.write(1); - cmdfis.featureh.write(0); + cmdfis.pm.write(1 << 7); + cmdfis.command.write(ATA_CMD_PACKET); + cmdfis.device.write(0); + cmdfis.lba1.write(0); + cmdfis.lba2.write(0); + cmdfis.featurel.write(1); + cmdfis.featureh.write(0); - unsafe { ptr::write_volatile(acmd.as_mut_ptr() as *mut [u8; 16], *cmd) }; - }).ok_or(Error::new(EIO))?; + unsafe { ptr::write_volatile(acmd.as_mut_ptr() as *mut [u8; 16], *cmd) }; + }) + .ok_or(Error::new(EIO))?; self.ata_stop(slot) } - pub fn ata_start(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma; 32], callback: F) -> Option - where F: FnOnce(&mut HbaCmdHeader, &mut FisRegH2D, &mut [HbaPrdtEntry; PRDT_ENTRIES], &mut [Mmio; 16]) { - + pub fn ata_start( + &mut self, + clb: &mut Dma<[HbaCmdHeader; 32]>, + ctbas: &mut [Dma; 32], + callback: F, + ) -> Option + where + F: FnOnce( + &mut HbaCmdHeader, + &mut FisRegH2D, + &mut [HbaPrdtEntry; PRDT_ENTRIES], + &mut [Mmio; 16], + ), + { //TODO: Should probably remove self.is.write(u32::MAX); if let Some(slot) = self.slot() { { let cmdheader = &mut clb[slot as usize]; - cmdheader.cfl.write((size_of::() / size_of::()) as u8); + cmdheader + .cfl + .write((size_of::() / size_of::()) as u8); let cmdtbl = &mut ctbas[slot as usize]; - unsafe { ptr::write_bytes(cmdtbl.deref_mut() as *mut HbaCmdTable as *mut u8, 0, size_of::()); } + unsafe { + ptr::write_bytes( + cmdtbl.deref_mut() as *mut HbaCmdTable as *mut u8, + 0, + size_of::(), + ); + } let cmdfis = unsafe { &mut *(cmdtbl.cfis.as_mut_ptr() as *mut FisRegH2D) }; cmdfis.fis_type.write(FisType::RegH2D as u8); @@ -338,18 +412,25 @@ impl HbaPort { self.stop(); if self.is.read() & HBA_PORT_IS_ERR != 0 { - let ( - is, ie, cmd, tfd, - ssts, sctl, serr, sact, - ci, sntf, fbs - ) = ( - 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() + let (is, ie, cmd, tfd, ssts, sctl, serr, sact, ci, sntf, fbs) = ( + 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(), ); error!("IS {:X} IE {:X} CMD {:X} TFD {:X}", is, ie, cmd, tfd); - error!("SSTS {:X} SCTL {:X} SERR {:X} SACT {:X}", ssts, sctl, serr, sact); + error!( + "SSTS {:X} SCTL {:X} SERR {:X} SACT {:X}", + ssts, sctl, serr, sact + ); error!("CI {:X} SNTF {:X} FBS {:X}", ci, sntf, fbs); self.is.write(u32::MAX); @@ -362,20 +443,20 @@ impl HbaPort { #[repr(packed)] pub struct HbaMem { - pub cap: Mmio, // 0x00, Host capability - pub ghc: Mmio, // 0x04, Global host control - pub is: Mmio, // 0x08, Interrupt status - pub pi: Mmio, // 0x0C, Port implemented - pub vs: Mmio, // 0x10, Version - pub ccc_ctl: Mmio, // 0x14, Command completion coalescing control - pub ccc_pts: Mmio, // 0x18, Command completion coalescing ports - pub em_loc: Mmio, // 0x1C, Enclosure management location - pub em_ctl: Mmio, // 0x20, Enclosure management control - pub cap2: Mmio, // 0x24, Host capabilities extended - pub bohc: Mmio, // 0x28, BIOS/OS handoff control and status - pub _rsv: [Mmio; 116], // 0x2C - 0x9F, Reserved + pub cap: Mmio, // 0x00, Host capability + pub ghc: Mmio, // 0x04, Global host control + pub is: Mmio, // 0x08, Interrupt status + pub pi: Mmio, // 0x0C, Port implemented + pub vs: Mmio, // 0x10, Version + pub ccc_ctl: Mmio, // 0x14, Command completion coalescing control + pub ccc_pts: Mmio, // 0x18, Command completion coalescing ports + pub em_loc: Mmio, // 0x1C, Enclosure management location + pub em_ctl: Mmio, // 0x20, Enclosure management control + pub cap2: Mmio, // 0x24, Host capabilities extended + pub bohc: Mmio, // 0x28, BIOS/OS handoff control and status + pub _rsv: [Mmio; 116], // 0x2C - 0x9F, Reserved pub vendor: [Mmio; 96], // 0xA0 - 0xFF, Vendor specific registers - pub ports: [HbaPort; 32], // 0x100 - 0x10FF, Port control registers + pub ports: [HbaPort; 32], // 0x100 - 0x10FF, Port control registers } impl HbaMem { @@ -388,18 +469,25 @@ impl HbaMem { */ self.ghc.write(1 << 31 | 1 << 1); - debug!(" - 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()); + debug!( + " - 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() + ); } } #[repr(packed)] pub struct HbaPrdtEntry { - dba_low: Mmio, // Data base address (low + dba_low: Mmio, // Data base address (low dba_high: Mmio, // Data base address (high) - _rsv0: Mmio, // Reserved - dbc: Mmio, // Byte count, 4M max, interrupt = 1 + _rsv0: Mmio, // Reserved + dbc: Mmio, // Byte count, 4M max, interrupt = 1 } #[repr(packed)] @@ -431,7 +519,7 @@ pub struct HbaCmdHeader { _prdbc: Mmio, // Physical region descriptor byte count transferred // DW2, 3 - ctba_low: Mmio, // Command table descriptor base address (low) + ctba_low: Mmio, // Command table descriptor base address (low) ctba_high: Mmio, // Command table descriptor base address (high) // DW4 - 7 diff --git a/storage/ahcid/src/ahci/mod.rs b/storage/ahcid/src/ahci/mod.rs index aaf3b78523..73e66c5ec5 100644 --- a/storage/ahcid/src/ahci/mod.rs +++ b/storage/ahcid/src/ahci/mod.rs @@ -1,6 +1,6 @@ +use common::io::Io; use driver_block::Disk; use log::{error, info}; -use common::io::Io; use self::disk_ata::DiskATA; use self::disk_atapi::DiskATAPI; @@ -16,37 +16,33 @@ pub fn disks(base: usize, name: &str) -> (&'static mut HbaMem, Vec hba_mem.init(); let pi = hba_mem.pi.read(); let disks: Vec> = (0..hba_mem.ports.len()) - .filter(|&i| pi & 1 << i as i32 == 1 << i as i32) - .filter_map(|i| { - let port = unsafe { &mut *hba_mem.ports.as_mut_ptr().add(i) }; - let port_type = port.probe(); - info!("{}-{}: {:?}", name, i, port_type); + .filter(|&i| pi & 1 << i as i32 == 1 << i as i32) + .filter_map(|i| { + let port = unsafe { &mut *hba_mem.ports.as_mut_ptr().add(i) }; + let port_type = port.probe(); + info!("{}-{}: {:?}", name, i, port_type); - let disk: Option> = match port_type { - HbaPortType::SATA => { - match DiskATA::new(i, port) { - Ok(disk) => Some(Box::new(disk)), - Err(err) => { - error!("{}: {}", i, err); - None - } - } - } - HbaPortType::SATAPI => { - match DiskATAPI::new(i, port) { - Ok(disk) => Some(Box::new(disk)), - Err(err) => { - error!("{}: {}", i, err); - None - } - } - } - _ => None, - }; + let disk: Option> = match port_type { + HbaPortType::SATA => match DiskATA::new(i, port) { + Ok(disk) => Some(Box::new(disk)), + Err(err) => { + error!("{}: {}", i, err); + None + } + }, + HbaPortType::SATAPI => match DiskATAPI::new(i, port) { + Ok(disk) => Some(Box::new(disk)), + Err(err) => { + error!("{}: {}", i, err); + None + } + }, + _ => None, + }; - disk - }) - .collect(); + disk + }) + .collect(); (hba_mem, disks) } diff --git a/storage/ahcid/src/main.rs b/storage/ahcid/src/main.rs index e380d997c2..3cfb63a435 100644 --- a/storage/ahcid/src/main.rs +++ b/storage/ahcid/src/main.rs @@ -1,8 +1,8 @@ #![cfg_attr(target_arch = "aarch64", feature(stdsimd))] // Required for yield instruction #![feature(int_roundings)] -extern crate syscall; extern crate byteorder; +extern crate syscall; use std::io::{Read, Write}; use std::os::fd::AsRawFd; @@ -33,7 +33,10 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let mut name = pci_config.func.name(); name.push_str("_ahci"); - let irq = pci_config.func.legacy_interrupt_line.expect("ahcid: no legacy interrupts supported"); + let irq = pci_config + .func + .legacy_interrupt_line + .expect("ahcid: no legacy interrupts supported"); common::setup_logging( "disk", @@ -45,10 +48,13 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { info!(" + AHCI {}", pci_config.func.display()); - let address = unsafe { pcid_handle.map_bar(5).expect("ahcid") }.ptr.as_ptr() as usize; + let address = unsafe { pcid_handle.map_bar(5).expect("ahcid") } + .ptr + .as_ptr() as usize; { let scheme_name = format!("disk.{}", name); - let socket = Socket::::nonblock(&scheme_name).expect("ahcid: failed to create disk scheme"); + let socket = + Socket::::nonblock(&scheme_name).expect("ahcid: failed to create disk scheme"); let mut irq_file = irq.irq_handle("ahcid"); let irq_fd = irq_file.as_raw_fd() as usize; @@ -57,8 +63,12 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { libredox::call::setrens(0, 0).expect("ahcid: failed to enter null namespace"); - event_queue.subscribe(socket.inner().raw(), 1, EventFlags::READ).expect("ahcid: failed to event scheme socket"); - event_queue.subscribe(irq_fd, 1, EventFlags::READ).expect("ahcid: failed to event irq scheme"); + event_queue + .subscribe(socket.inner().raw(), 1, EventFlags::READ) + .expect("ahcid: failed to event scheme socket"); + event_queue + .subscribe(irq_fd, 1, EventFlags::READ) + .expect("ahcid: failed to event irq scheme"); daemon.ready().expect("ahcid: failed to notify parent"); @@ -68,7 +78,11 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let mut mounted = true; let mut todo = Vec::new(); while mounted { - let Some(event) = event_queue.next().transpose().expect("ahcid: failed to read event file") else { + let Some(event) = event_queue + .next() + .transpose() + .expect("ahcid: failed to read event file") + else { break; }; if event.fd == socket.inner().raw() { @@ -77,39 +91,53 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { Ok(None) => { mounted = false; break; - }, - Ok(Some(s)) => if let RequestKind::Call(call) = s.kind() { - call - } else { - // TODO: Support e.g. cancellation - continue; - }, - Err(err) => if err.errno == EWOULDBLOCK || err.errno == EAGAIN { - break; - } else { - panic!("ahcid: failed to read disk scheme: {}", err); + } + Ok(Some(s)) => { + if let RequestKind::Call(call) = s.kind() { + call + } else { + // TODO: Support e.g. cancellation + continue; + } + } + Err(err) => { + if err.errno == EWOULDBLOCK || err.errno == EAGAIN { + break; + } else { + panic!("ahcid: failed to read disk scheme: {}", err); + } } }; if let Some(response) = sqe.handle_scheme_block_mut(&mut scheme) { // TODO: handle full CQE? - socket.write_response(response, SignalBehavior::Restart).expect("ahcid: failed to write disk scheme"); + socket + .write_response(response, SignalBehavior::Restart) + .expect("ahcid: failed to write disk scheme"); } else { todo.push(sqe); } } } else if event.fd == irq_fd { let mut irq = [0; 8]; - if irq_file.read(&mut irq).expect("ahcid: failed to read irq file") >= irq.len() { + 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"); + 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(resp) = todo[i].handle_scheme_block_mut(&mut scheme) { let _sqe = todo.remove(i); - socket.write_response(resp, SignalBehavior::Restart).expect("ahcid: failed to write disk scheme"); + socket + .write_response(resp, SignalBehavior::Restart) + .expect("ahcid: failed to write disk scheme"); } else { i += 1; } @@ -125,15 +153,22 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { while i < todo.len() { if let Some(response) = todo[i].handle_scheme_block_mut(&mut scheme) { let _sqe = todo.remove(i); - socket.write_response(response, SignalBehavior::Restart).expect("ahcid: failed to write disk scheme"); + socket + .write_response(response, SignalBehavior::Restart) + .expect("ahcid: failed to write disk scheme"); } else { i += 1; } } - if ! mounted { + if !mounted { for sqe in todo.drain(..) { - socket.write_response(Response::new(&sqe, Err(Error::new(ENODEV))), SignalBehavior::Restart).expect("ahcid: failed to write disk scheme"); + socket + .write_response( + Response::new(&sqe, Err(Error::new(ENODEV))), + SignalBehavior::Restart, + ) + .expect("ahcid: failed to write disk scheme"); } } } diff --git a/storage/ahcid/src/scheme.rs b/storage/ahcid/src/scheme.rs index c5f03d97b6..67ea31262e 100644 --- a/storage/ahcid/src/scheme.rs +++ b/storage/ahcid/src/scheme.rs @@ -1,22 +1,22 @@ use std::collections::BTreeMap; -use std::str; use std::fmt::Write; +use std::str; +use common::io::Io as _; use driver_block::{Disk, DiskWrapper}; +use redox_scheme::{CallerCtx, OpenResult, SchemeBlockMut}; use syscall::schemev2::NewFdFlags; use syscall::{ - Error, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, Result, Stat, MODE_DIR, + Error, Result, Stat, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, MODE_DIR, MODE_FILE, O_DIRECTORY, O_STAT, }; -use common::io::Io as _; -use redox_scheme::{CallerCtx, OpenResult, SchemeBlockMut}; use crate::ahci::hba::HbaMem; #[derive(Clone)] enum Handle { - List(Vec), // Dir contents buffer - Disk(usize), // Disk index + List(Vec), // Dir contents buffer + Disk(usize), // Disk index Partition(usize, u32), // Disk index, partition index } @@ -25,17 +25,25 @@ pub struct DiskScheme { hba_mem: &'static mut HbaMem, disks: Box<[DiskWrapper]>, handles: BTreeMap, - next_id: usize + next_id: usize, } impl DiskScheme { - pub fn new(scheme_name: String, hba_mem: &'static mut HbaMem, disks: Vec>) -> DiskScheme { + pub fn new( + scheme_name: String, + hba_mem: &'static mut HbaMem, + disks: Vec>, + ) -> DiskScheme { DiskScheme { scheme_name, hba_mem, - disks: disks.into_iter().map(DiskWrapper::new).collect::>().into_boxed_slice(), + disks: disks + .into_iter() + .map(DiskWrapper::new) + .collect::>() + .into_boxed_slice(), handles: BTreeMap::new(), - next_id: 0 + next_id: 0, } } @@ -62,19 +70,25 @@ impl DiskScheme { fn check_locks(&self, disk_i: usize, part_i_opt: Option) -> Result<()> { for (_, handle) in self.handles.iter() { match handle { - Handle::Disk(i) => if disk_i == *i { - return Err(Error::new(ENOLCK)); - }, - Handle::Partition(i, p) => if disk_i == *i { - match part_i_opt { - Some(part_i) => if part_i == *p { - return Err(Error::new(ENOLCK)); - }, - None => { - return Err(Error::new(ENOLCK)); + Handle::Disk(i) => { + if disk_i == *i { + return Err(Error::new(ENOLCK)); + } + } + Handle::Partition(i, p) => { + if disk_i == *i { + match part_i_opt { + Some(part_i) => { + if part_i == *p { + return Err(Error::new(ENOLCK)); + } + } + None => { + return Err(Error::new(ENOLCK)); + } } } - }, + } _ => (), } } @@ -99,7 +113,7 @@ impl SchemeBlockMut for DiskScheme { write!(list, "{}\n", disk_index).unwrap(); if disk.pt.is_none() { - continue + continue; } for part_index in 0..disk.pt.as_ref().unwrap().partitions.len() { write!(list, "{}p{}\n", disk_index, part_index).unwrap(); @@ -117,7 +131,15 @@ impl SchemeBlockMut for DiskScheme { let p = part_id_str.parse::().or(Err(Error::new(ENOENT)))?; let disk = self.disks.get(i).ok_or(Error::new(ENOENT))?; - if disk.pt.is_none() || disk.pt.as_ref().unwrap().partitions.get(p as usize).is_none() { + if disk.pt.is_none() + || disk + .pt + .as_ref() + .unwrap() + .partitions + .get(p as usize) + .is_none() + { return Err(Error::new(ENOENT)); } @@ -137,11 +159,14 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; self.handles.insert(id, handle); - Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) + Ok(Some(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::POSITIONED, + })) } fn xdup(&mut self, id: usize, buf: &[u8], _: &CallerCtx) -> Result> { - if ! buf.is_empty() { + if !buf.is_empty() { return Err(Error::new(EINVAL)); } @@ -153,7 +178,10 @@ impl SchemeBlockMut for DiskScheme { let new_id = self.next_id; self.next_id += 1; self.handles.insert(new_id, new_handle); - Ok(Some(OpenResult::ThisScheme { number: new_id, flags: NewFdFlags::POSITIONED })) + Ok(Some(OpenResult::ThisScheme { + number: new_id, + flags: NewFdFlags::POSITIONED, + })) } fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result> { @@ -162,7 +190,7 @@ impl SchemeBlockMut for DiskScheme { stat.st_mode = MODE_DIR; stat.st_size = data.len() as u64; Ok(Some(0)) - }, + } Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; stat.st_mode = MODE_FILE; @@ -174,7 +202,10 @@ impl SchemeBlockMut for DiskScheme { let disk = self.disks.get_mut(disk_id).ok_or(Error::new(EBADF))?; let size = { let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?; - let partition = pt.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?; + let partition = pt + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))?; partition.size }; @@ -232,15 +263,24 @@ impl SchemeBlockMut for DiskScheme { Ok(Some(i)) } - fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result> { + fn read( + &mut self, + id: usize, + buf: &mut [u8], + offset: u64, + _fcntl_flags: u32, + ) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { Handle::List(ref handle) => { - let src = usize::try_from(offset).ok().and_then(|o| handle.get(o..)).unwrap_or(&[]); + let src = usize::try_from(offset) + .ok() + .and_then(|o| handle.get(o..)) + .unwrap_or(&[]); let byte_count = core::cmp::min(src.len(), buf.len()); buf[..byte_count].copy_from_slice(&src[..byte_count]); Ok(Some(byte_count)) - }, + } Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; let blk_len = disk.block_length()?; @@ -255,7 +295,10 @@ impl SchemeBlockMut for DiskScheme { let abs_block = { let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?; - let partition = pt.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?; + let partition = pt + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))?; let abs_block = partition.start_lba + rel_block; // TODO: This shouldn't return EOVERFLOW? @@ -270,11 +313,15 @@ impl SchemeBlockMut for DiskScheme { } } - fn write(&mut self, id: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> Result> { + fn write( + &mut self, + id: usize, + buf: &[u8], + offset: u64, + _fcntl_flags: u32, + ) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(_) => { - Err(Error::new(EBADF)) - }, + Handle::List(_) => Err(Error::new(EBADF)), Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; let blk_len = disk.block_length()?; @@ -289,7 +336,10 @@ impl SchemeBlockMut for DiskScheme { let abs_block = { let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?; - let partition = pt.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?; + let partition = pt + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))?; let abs_block = partition.start_lba + rel_block; if rel_block >= partition.size { @@ -304,21 +354,33 @@ impl SchemeBlockMut for DiskScheme { } fn fsize(&mut self, id: usize) -> Result> { - Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref mut handle) => handle.len() as u64, - Handle::Disk(number) => { - let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; - disk.size() - } - Handle::Partition(disk_num, part_num) => { - let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?; - let block_count = disk.pt.as_ref().ok_or(Error::new(EBADF))?.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?.size; - u64::from(disk.block_length()?) * block_count - } - })) + Ok(Some( + match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { + Handle::List(ref mut handle) => handle.len() as u64, + Handle::Disk(number) => { + let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; + disk.size() + } + Handle::Partition(disk_num, part_num) => { + let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?; + let block_count = disk + .pt + .as_ref() + .ok_or(Error::new(EBADF))? + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))? + .size; + u64::from(disk.block_length()?) * block_count + } + }, + )) } fn close(&mut self, id: usize) -> Result> { - self.handles.remove(&id).ok_or(Error::new(EBADF)).and(Ok(Some(0))) + self.handles + .remove(&id) + .ok_or(Error::new(EBADF)) + .and(Ok(Some(0))) } } diff --git a/storage/bcm2835-sdhcid/src/main.rs b/storage/bcm2835-sdhcid/src/main.rs index 60a151052c..878604a0a4 100644 --- a/storage/bcm2835-sdhcid/src/main.rs +++ b/storage/bcm2835-sdhcid/src/main.rs @@ -1,17 +1,26 @@ -use std::{fs::File, io::{Read, Write}, process}; +use std::{ + fs::File, + io::{Read, Write}, + process, +}; use driver_block::Disk; use event::{EventFlags, RawEventQueue}; -use fdt::{Fdt, node::FdtNode}; +use fdt::{node::FdtNode, Fdt}; use redox_scheme::{RequestKind, Response, SignalBehavior, Socket, V2}; use syscall::{ - data::{Event, Packet}, error::{Error, ENODEV}, flag::EVENT_READ, io::Io, scheme::SchemeBlockMut, EAGAIN, EINTR, EWOULDBLOCK + data::{Event, Packet}, + error::{Error, ENODEV}, + flag::EVENT_READ, + io::Io, + scheme::SchemeBlockMut, + EAGAIN, EINTR, EWOULDBLOCK, }; use crate::scheme::DiskScheme; -mod sd; mod scheme; +mod sd; #[cfg(target_os = "redox")] fn get_dtb() -> Vec { @@ -45,12 +54,23 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let compat_node = fdt.find_compatible(&with).unwrap(); let reg = compat_node.reg().unwrap().next().unwrap(); let reg_size = reg.size.unwrap(); - println!("DeviceMemory start = 0x{:08x}, size = 0x{:08x}", reg.starting_address as usize, reg_size); + println!( + "DeviceMemory start = 0x{:08x}, size = 0x{:08x}", + reg.starting_address as usize, reg_size + ); let addr = unsafe { - common::physmap(reg.starting_address as usize, reg_size, common::Prot::RW, common::MemoryType::DeviceMemory) - .expect("bcm2835-sdhcid: failed to map address") as usize + common::physmap( + reg.starting_address as usize, + reg_size, + common::Prot::RW, + common::MemoryType::DeviceMemory, + ) + .expect("bcm2835-sdhcid: failed to map address") as usize }; - println!("ioremap 0x{:08x} to 0x{:08x} 2222", reg.starting_address as usize, addr); + println!( + "ioremap 0x{:08x} to 0x{:08x} 2222", + reg.starting_address as usize, addr + ); let mut sdhci = sd::SdHostCtrl::new(addr); unsafe { sdhci.init(); @@ -80,12 +100,13 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { */ } - let scheme_name = "disk.mmc"; let socket_fd = Socket::::create(&scheme_name).expect("mmcd: failed to create disk scheme"); let mut event_queue = RawEventQueue::new().expect("mmcd: failed to open event file"); - event_queue.subscribe(socket_fd.inner().raw(), 0, EventFlags::READ).expect("mmcd: failed to event disk scheme"); + event_queue + .subscribe(socket_fd.inner().raw(), 0, EventFlags::READ) + .expect("mmcd: failed to event disk scheme"); libredox::call::setrens(0, 0).expect("mmcd: failed to enter null namespace"); daemon.ready().expect("mmcd: failed to notify parent"); @@ -97,26 +118,36 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let mut scheme = DiskScheme::new(scheme_name.to_string(), disks); 'outer: loop { - let Some(event) = event_queue.next().transpose().expect("mmcd: failed to read event file") else { + let Some(event) = event_queue + .next() + .transpose() + .expect("mmcd: failed to read event file") + else { break; }; if event.fd == socket_fd.inner().raw() { loop { let req = match socket_fd.next_request(SignalBehavior::Interrupt) { Ok(None) => break 'outer, - Ok(Some(r)) => if let RequestKind::Call(c) = r.kind() { - c - } else { - continue; - }, - Err(err) => if matches!(err.errno, EAGAIN | EWOULDBLOCK | EINTR) { - break; - } else { - panic!("mmcd: failed to read disk scheme: {}", err); + Ok(Some(r)) => { + if let RequestKind::Call(c) = r.kind() { + c + } else { + continue; + } + } + Err(err) => { + if matches!(err.errno, EAGAIN | EWOULDBLOCK | EINTR) { + break; + } else { + panic!("mmcd: failed to read disk scheme: {}", err); + } } }; if let Some(resp) = req.handle_scheme_block_mut(&mut scheme) { - socket_fd.write_response(resp, SignalBehavior::Restart).expect("mmcd: failed to write disk scheme"); + socket_fd + .write_response(resp, SignalBehavior::Restart) + .expect("mmcd: failed to write disk scheme"); } else { todo.push(req); } @@ -129,14 +160,20 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let mut i = 0; while i < todo.len() { if let Some(resp) = todo[i].handle_scheme_block_mut(&mut scheme) { - socket_fd.write_response(resp, SignalBehavior::Restart).expect("mmcd: failed to write disk scheme"); + socket_fd + .write_response(resp, SignalBehavior::Restart) + .expect("mmcd: failed to write disk scheme"); } else { i += 1; } } for req in todo.drain(..) { - socket_fd.write_response(Response::new(&req, Err(Error::new(ENODEV))), SignalBehavior::Restart) + socket_fd + .write_response( + Response::new(&req, Err(Error::new(ENODEV))), + SignalBehavior::Restart, + ) .expect("mmcd: failed to write disk scheme"); } } diff --git a/storage/bcm2835-sdhcid/src/scheme.rs b/storage/bcm2835-sdhcid/src/scheme.rs index 203c72ff40..18e8d28a3f 100644 --- a/storage/bcm2835-sdhcid/src/scheme.rs +++ b/storage/bcm2835-sdhcid/src/scheme.rs @@ -1,12 +1,12 @@ use std::collections::BTreeMap; -use std::str; use std::fmt::Write; +use std::str; use std::sync::{Arc, Mutex}; use driver_block::{Disk, DiskWrapper}; use syscall::schemev2::NewFdFlags; use syscall::{ - Error, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, Result, Stat, MODE_DIR, + Error, Result, Stat, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, MODE_DIR, MODE_FILE, O_DIRECTORY, O_STAT, }; @@ -14,8 +14,8 @@ use redox_scheme::{CallerCtx, OpenResult, SchemeBlockMut}; #[derive(Clone)] enum Handle { - List(Vec), // Dir contents buffer - Disk(usize), // Disk index + List(Vec), // Dir contents buffer + Disk(usize), // Disk index Partition(usize, u32), // Disk index, partition index } @@ -23,16 +23,20 @@ pub struct DiskScheme { scheme_name: String, disks: Box<[DiskWrapper]>, handles: BTreeMap, - next_id: usize + next_id: usize, } impl DiskScheme { pub fn new(scheme_name: String, disks: Vec>) -> DiskScheme { DiskScheme { scheme_name, - disks: disks.into_iter().map(DiskWrapper::new).collect::>().into_boxed_slice(), + disks: disks + .into_iter() + .map(DiskWrapper::new) + .collect::>() + .into_boxed_slice(), handles: BTreeMap::new(), - next_id: 0 + next_id: 0, } } @@ -40,19 +44,25 @@ impl DiskScheme { fn check_locks(&self, disk_i: usize, part_i_opt: Option) -> Result<()> { for (_, handle) in self.handles.iter() { match handle { - Handle::Disk(i) => if disk_i == *i { - return Err(Error::new(ENOLCK)); - }, - Handle::Partition(i, p) => if disk_i == *i { - match part_i_opt { - Some(part_i) => if part_i == *p { - return Err(Error::new(ENOLCK)); - }, - None => { - return Err(Error::new(ENOLCK)); + Handle::Disk(i) => { + if disk_i == *i { + return Err(Error::new(ENOLCK)); + } + } + Handle::Partition(i, p) => { + if disk_i == *i { + match part_i_opt { + Some(part_i) => { + if part_i == *p { + return Err(Error::new(ENOLCK)); + } + } + None => { + return Err(Error::new(ENOLCK)); + } } } - }, + } _ => (), } } @@ -72,7 +82,7 @@ impl SchemeBlockMut for DiskScheme { write!(list, "{}\n", disk_index).unwrap(); if disk.pt.is_none() { - continue + continue; } for part_index in 0..disk.pt.as_ref().unwrap().partitions.len() { write!(list, "{}p{}\n", disk_index, part_index).unwrap(); @@ -82,7 +92,10 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; self.handles.insert(id, Handle::List(list.into_bytes())); - Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) + Ok(Some(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::POSITIONED, + })) } else { Err(Error::new(EISDIR)) } @@ -96,7 +109,15 @@ impl SchemeBlockMut for DiskScheme { let p = part_id_str.parse::().or(Err(Error::new(ENOENT)))?; if let Some(disk) = self.disks.get(i) { - if disk.pt.is_none() || disk.pt.as_ref().unwrap().partitions.get(p as usize).is_none() { + if disk.pt.is_none() + || disk + .pt + .as_ref() + .unwrap() + .partitions + .get(p as usize) + .is_none() + { return Err(Error::new(ENOENT)); } @@ -105,7 +126,10 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; self.handles.insert(id, Handle::Partition(i, p)); - Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) + Ok(Some(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::POSITIONED, + })) } else { Err(Error::new(ENOENT)) } @@ -118,7 +142,10 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; self.handles.insert(id, Handle::Disk(i)); - Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) + Ok(Some(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::POSITIONED, + })) } else { Err(Error::new(ENOENT)) } @@ -129,7 +156,7 @@ impl SchemeBlockMut for DiskScheme { } fn dup(&mut self, id: usize, buf: &[u8]) -> Result> { - if ! buf.is_empty() { + if !buf.is_empty() { return Err(Error::new(EINVAL)); } @@ -150,7 +177,7 @@ impl SchemeBlockMut for DiskScheme { stat.st_mode = MODE_DIR; stat.st_size = data.len() as u64; Ok(Some(0)) - }, + } Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; stat.st_mode = MODE_FILE; @@ -162,7 +189,10 @@ impl SchemeBlockMut for DiskScheme { let disk = self.disks.get_mut(disk_id).ok_or(Error::new(EBADF))?; let size = { let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?; - let partition = pt.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?; + let partition = pt + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))?; partition.size }; @@ -220,14 +250,23 @@ impl SchemeBlockMut for DiskScheme { Ok(Some(i)) } - fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _flags: u32) -> Result> { + fn read( + &mut self, + id: usize, + buf: &mut [u8], + offset: u64, + _flags: u32, + ) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { Handle::List(ref handle) => { - let src = usize::try_from(offset).ok().and_then(|o| handle.get(o..)).unwrap_or(&[]); + let src = usize::try_from(offset) + .ok() + .and_then(|o| handle.get(o..)) + .unwrap_or(&[]); let bytes = src.len().min(buf.len()); buf[..bytes].copy_from_slice(&src[..bytes]); Ok(Some(bytes)) - }, + } Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; let blk_len = disk.block_length()?; @@ -242,7 +281,10 @@ impl SchemeBlockMut for DiskScheme { let abs_block = { let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?; - let partition = pt.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?; + let partition = pt + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))?; let abs_block = partition.start_lba + rel_block; if rel_block >= partition.size { @@ -258,9 +300,7 @@ impl SchemeBlockMut for DiskScheme { fn write(&mut self, id: usize, buf: &[u8], offset: u64, _flags: u32) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(_) => { - Err(Error::new(EBADF)) - }, + Handle::List(_) => Err(Error::new(EBADF)), Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; let blk_len = disk.block_length()?; @@ -275,7 +315,10 @@ impl SchemeBlockMut for DiskScheme { let abs_block = { let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?; - let partition = pt.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?; + let partition = pt + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))?; let abs_block = partition.start_lba + rel_block; if rel_block >= partition.size { @@ -291,22 +334,30 @@ impl SchemeBlockMut for DiskScheme { fn fsize(&mut self, id: usize) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref mut handle) => { - Ok(Some(handle.len() as u64)) - }, + Handle::List(ref mut handle) => Ok(Some(handle.len() as u64)), Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; Ok(Some(disk.size())) } Handle::Partition(disk_num, part_num) => { let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?; - let block_count = disk.pt.as_ref().ok_or(Error::new(EBADF))?.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?.size; + let block_count = disk + .pt + .as_ref() + .ok_or(Error::new(EBADF))? + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))? + .size; Ok(Some(u64::from(disk.block_length()?) * block_count)) } } } fn close(&mut self, id: usize) -> Result> { - self.handles.remove(&id).ok_or(Error::new(EBADF)).and(Ok(Some(0))) + self.handles + .remove(&id) + .ok_or(Error::new(EBADF)) + .and(Ok(Some(0))) } } diff --git a/storage/bcm2835-sdhcid/src/sd/mod.rs b/storage/bcm2835-sdhcid/src/sd/mod.rs index 2e31b3ae19..00d967725c 100644 --- a/storage/bcm2835-sdhcid/src/sd/mod.rs +++ b/storage/bcm2835-sdhcid/src/sd/mod.rs @@ -26,7 +26,6 @@ pub(crate) unsafe fn wait_msec(mut n: usize) { asm!("mrs {0}, cntfrq_el0", out(reg) f); asm!("mrs {0}, cntpct_el0", out(reg) t); - t += ((f / 1000) * n) / 1000; loop { @@ -34,7 +33,7 @@ pub(crate) unsafe fn wait_msec(mut n: usize) { if r >= t { break; } - }; + } } #[cfg(target_arch = "x86_64")] @@ -60,15 +59,13 @@ const CMD_STOP_TRANS: u32 = 0x0c03_0000; const CMD_READ_SINGLE: u32 = 0x1122_0010; const CMD_READ_MULTI: u32 = 0x1222_0032; const CMD_SET_BLOCKCNT: u32 = 0x1702_0000; -const CMD_WRITE_SINGLE:u32 = 0x1822_0000; -const CMD_WRITE_MULTI:u32 = 0x1922_0022; +const CMD_WRITE_SINGLE: u32 = 0x1822_0000; +const CMD_WRITE_MULTI: u32 = 0x1922_0022; const CMD_APP_CMD: u32 = 0x3700_0000; -const CMD_SET_BUS_WIDTH: u32 = 0x0602_0000|CMD_NEED_APP; -const CMD_SEND_OP_COND: u32 = 0x2902_0000|CMD_NEED_APP; -const CMD_SEND_SCR: u32 = 0x3322_0010|CMD_NEED_APP; - - +const CMD_SET_BUS_WIDTH: u32 = 0x0602_0000 | CMD_NEED_APP; +const CMD_SEND_OP_COND: u32 = 0x2902_0000 | CMD_NEED_APP; +const CMD_SEND_SCR: u32 = 0x3322_0010 | CMD_NEED_APP; //STATUS register settings const SR_READ_AVAILABLE: u32 = 0x0000_0800; @@ -93,7 +90,6 @@ const C1_CLK_EN: u32 = 0x0000_0004; const C1_CLK_STABLE: u32 = 0x0000_0002; const C1_CLK_INTLEN: u32 = 0x0000_0001; - //INTERRUPT register settings const INT_DATA_TIMEOUT: u32 = 0x0010_0000; const INT_CMD_TIMEOUT: u32 = 0x0001_0000; @@ -168,7 +164,7 @@ pub struct SdHostCtrlRegs { _rsvd: [Mmio; 47], //Slot Interrupt Status and Version - slotisr_ver: Mmio + slotisr_ver: Mmio, } //TODO: refactor, sd/sdhci/bcmh2835-sdhci three different modules. @@ -180,13 +176,13 @@ pub struct SdHostCtrl { rca: u32, //relative card address scr: [u32; 2], ocr: u32, - size: u64 + size: u64, } impl SdHostCtrl { pub fn new(address: usize) -> Self { SdHostCtrl { - regs: RwLock::new(unsafe { &mut *(address as *mut SdHostCtrlRegs)}), + regs: RwLock::new(unsafe { &mut *(address as *mut SdHostCtrlRegs) }), host_spec_ver: 0, cid: [0; 4], csd: [0; 4], @@ -207,15 +203,14 @@ impl SdHostCtrl { reg_val = regs.control1.read(); regs.control1.write(reg_val | C1_SRST_HC); let mut cnt = 1000; - while (cnt >= 0) && - ((regs.control1.read() & C1_SRST_HC) == C1_SRST_HC) { + while (cnt >= 0) && ((regs.control1.read() & C1_SRST_HC) == C1_SRST_HC) { cnt -= 1; wait_msec(10); } if cnt < 0 { println!("ERROR: failed to reset EMMC"); - return ; + return; } println!("EMMC: reset OK"); reg_val = regs.control1.read(); @@ -226,7 +221,7 @@ impl SdHostCtrl { { if let Err(_) = self.set_clock(40_0000) { println!("ERROR: failed to set clock {}", 40_0000); - return ; + return; } } @@ -236,12 +231,12 @@ impl SdHostCtrl { if let Err(_) = self.sd_cmd(CMD_GO_IDLE, 0) { println!("failed to go idle"); - return ; + return; } if let Err(_) = self.sd_cmd(CMD_SEND_IF_COND, 0x0000_01aa) { println!("failed to send if cond"); - return ; + return; } cnt = 6; @@ -268,21 +263,25 @@ impl SdHostCtrl { print!("\n"); } else { println!("ERROR: EMMC ACMD41 returned error"); - return ; + return; } } if (reg_val & ACMD41_CMD_COMPLETE) == 0 || cnt <= 0 { println!("ACMD41 TIMEOUT"); - return ; + return; } if (reg_val & ACMD41_VOLTAGE) == 0 { println!("ACMD41 VOLTAGE NOT FOUND!"); - return ; + return; } - let ccs = if (reg_val & ACMD41_CMD_CCS) != 0 { SCR_SUPP_CCS } else { 0 }; + let ccs = if (reg_val & ACMD41_CMD_CCS) != 0 { + SCR_SUPP_CCS + } else { + 0 + }; if let Err(_) = self.sd_cmd(CMD_ALL_SEND_CID, 0) { println!("CMD_ALL_SEND_CID ERROR, IGNORE!"); @@ -294,7 +293,7 @@ impl SdHostCtrl { if let Err(_) = self.sd_cmd(CMD_SEND_CSD, sd_rca) { println!("failed to get csd"); - return ; + return; } let (csize, cmult) = if (self.ocr & ACMD41_CMD_CCS) != 0 { @@ -309,20 +308,19 @@ impl SdHostCtrl { self.size = ((csize + 1) << (cmult + 2)) * 512; println!("mmc size = 0x{:08x}", self.size); - if let Err(_) = self.set_clock(2500_0000) { println!("failed to set clock 2500_0000 Hz"); - return ; + return; } if let Err(_) = self.sd_cmd(CMD_CARD_SELECT, sd_rca) { println!("failed to CMD_CARD_SELECT 0x{:08x}", sd_rca); - return ; + return; } if let Err(_) = self.sd_status(SR_DAT_INHIBIT) { println!("SR_DAT_INHIBIT return"); - return ; + return; } let regs = self.regs.get_mut().unwrap(); @@ -330,12 +328,12 @@ impl SdHostCtrl { if let Err(_) = self.sd_cmd(CMD_SEND_SCR, 0) { println!("failed to CMD_SEND_SCR"); - return ; + return; } if let Err(_) = self.sd_int(INT_READ_RDY) { println!("failed to INT_READ_RDY"); - return ; + return; } cnt = 10000; @@ -354,13 +352,13 @@ impl SdHostCtrl { } if i != 2 { println!("SD TIMEOUT FOR SCR[; 2]"); - return ; + return; } if (self.scr[0] & SCR_SD_BUS_WIDTH_4) != 0 { if let Err(_) = self.sd_cmd(CMD_SET_BUS_WIDTH, sd_rca | 2) { println!("failed to set bus width, {}", sd_rca | 2); - return ; + return; } let regs = self.regs.get_mut().unwrap(); regs.control0.write(C0_HCTL_DWITDH); @@ -411,13 +409,32 @@ impl SdHostCtrl { if x == 0 { s = 0; } else { - if (x & 0xffff_0000) == 0 { x <<= 16; s -= 16; } - if (x & 0xff00_0000) == 0 { x <<= 8; s -= 8; } - if (x & 0xf000_0000) == 0 { x <<= 4; s -= 4; } - if (x & 0xc000_0000) == 0 { x <<= 2; s -= 2; } - if (x & 0x8000_0000) == 0 { x <<= 1; s -= 1; } - if s > 0 { s -= 1; } - if s > 7 { s = 7; } + if (x & 0xffff_0000) == 0 { + x <<= 16; + s -= 16; + } + if (x & 0xff00_0000) == 0 { + x <<= 8; + s -= 8; + } + if (x & 0xf000_0000) == 0 { + x <<= 4; + s -= 4; + } + if (x & 0xc000_0000) == 0 { + x <<= 2; + s -= 2; + } + if (x & 0x8000_0000) == 0 { + x <<= 1; + s -= 1; + } + if s > 0 { + s -= 1; + } + if s > 7 { + s = 7; + } } let mut d = 0; if self.host_spec_ver > HOST_SPEC_V2 { @@ -437,7 +454,7 @@ impl SdHostCtrl { h = (d & 0x300) >> 2; } - d = ( ((d & 0xff) << 8)| h); + d = (((d & 0xff) << 8) | h); reg_val = regs.control1.read() & 0xffff_003f; regs.control1.write(reg_val | d); wait_msec(10); @@ -550,7 +567,6 @@ impl SdHostCtrl { } else { return Ok(reg_val & CMD_ERRORS_MASK); } - } pub unsafe fn sd_status(&mut self, mask: u32) -> Result<()> { @@ -647,7 +663,8 @@ impl SdHostCtrl { cnt += 1; } - if num > 1 && (self.scr[0] & SCR_SUPP_SET_BLKCNT) == 0 && (self.scr[0] & SCR_SUPP_CCS) != 0 { + if num > 1 && (self.scr[0] & SCR_SUPP_SET_BLKCNT) == 0 && (self.scr[0] & SCR_SUPP_CCS) != 0 + { self.sd_cmd(CMD_STOP_TRANS, 0).unwrap(); } Ok((num * 512) as usize) @@ -707,7 +724,8 @@ impl SdHostCtrl { return Err(Error::new(EINVAL)); } - if num > 1 && (self.scr[0] & SCR_SUPP_SET_BLKCNT) == 0 && (self.scr[0] & SCR_SUPP_CCS) != 0 { + if num > 1 && (self.scr[0] & SCR_SUPP_SET_BLKCNT) == 0 && (self.scr[0] & SCR_SUPP_CCS) != 0 + { self.sd_cmd(CMD_STOP_TRANS, 0).unwrap(); } Ok((num * 512) as usize) @@ -724,10 +742,9 @@ impl Disk for SdHostCtrl { self.size } - fn read(&mut self, block:u64, buffer: &mut [u8]) -> Result> { + fn read(&mut self, block: u64, buffer: &mut [u8]) -> Result> { if (buffer.len() % 512) != 0 { - println!("buffer.len {} should be aligned to {}", - buffer.len(), 512); + println!("buffer.len {} should be aligned to {}", buffer.len(), 512); return Err(Error::new(EINVAL)); } let u32_len = buffer.len() / core::mem::size_of::(); @@ -739,14 +756,13 @@ impl Disk for SdHostCtrl { }; match ret { Ok(cnt) => Ok(Some(cnt)), - Err(err) => Err(err) + Err(err) => Err(err), } } - fn write(&mut self, block:u64, buffer: &[u8]) -> Result> { + fn write(&mut self, block: u64, buffer: &[u8]) -> Result> { if (buffer.len() % 512) != 0 { - println!("buffer.len {} should be aligned to {}", - buffer.len(), 512); + println!("buffer.len {} should be aligned to {}", buffer.len(), 512); return Err(Error::new(EINVAL)); } let u32_len = buffer.len() / core::mem::size_of::(); @@ -758,12 +774,11 @@ impl Disk for SdHostCtrl { }; match ret { Ok(cnt) => Ok(Some(cnt)), - Err(err) => Err(err) + Err(err) => Err(err), } } fn block_length(&mut self) -> Result { Ok(512) } - } diff --git a/storage/ided/src/ide.rs b/storage/ided/src/ide.rs index f61003c1a2..c63cedfc38 100644 --- a/storage/ided/src/ide.rs +++ b/storage/ided/src/ide.rs @@ -80,12 +80,14 @@ impl Channel { prdt: unsafe { Dma::zeroed( //TODO: PhysBox::new_in_32bit_space(4096)? - )?.assume_init() + )? + .assume_init() }, buf: unsafe { Dma::zeroed( //TODO: PhysBox::new_in_32bit_space(16 * 4096)? - )?.assume_init() + )? + .assume_init() }, }) } @@ -142,7 +144,12 @@ impl Channel { break; } if start.elapsed() >= TIMEOUT { - log::error!("line {} polling {} timeout with status 0x{:02X}", line, if read { "read" } else { "write" }, status); + log::error!( + "line {} polling {} timeout with status 0x{:02X}", + line, + if read { "read" } else { "write" }, + status + ); return Err(Error::new(EIO)); } thread::yield_now(); @@ -181,7 +188,13 @@ impl Disk for AtaDisk { let sectors = (chunk.len() + 511) / 512; assert!(sectors <= 128); - log::trace!("IDE read chan {} dev {} block {:#x} count {:#x}", self.chan_i, self.dev, block, sectors); + log::trace!( + "IDE read chan {} dev {} block {:#x} count {:#x}", + self.chan_i, + self.dev, + block, + sectors + ); let mut chan = self.chan.lock().unwrap(); @@ -315,7 +328,13 @@ impl Disk for AtaDisk { let sectors = (chunk.len() + 511) / 512; assert!(sectors <= 128); - log::trace!("IDE write chan {} dev {} block {:#x} count {:#x}", self.chan_i, self.dev, block, sectors); + log::trace!( + "IDE write chan {} dev {} block {:#x} count {:#x}", + self.chan_i, + self.dev, + block, + sectors + ); let mut chan = self.chan.lock().unwrap(); @@ -424,10 +443,10 @@ impl Disk for AtaDisk { for i in 0..128 { chan.data32.write( - ((chunk[sector * 512 + i * 4 + 0] as u32) << 0) | - ((chunk[sector * 512 + i * 4 + 1] as u32) << 8) | - ((chunk[sector * 512 + i * 4 + 2] as u32) << 16) | - ((chunk[sector * 512 + i * 4 + 3] as u32) << 24) + ((chunk[sector * 512 + i * 4 + 0] as u32) << 0) + | ((chunk[sector * 512 + i * 4 + 1] as u32) << 8) + | ((chunk[sector * 512 + i * 4 + 2] as u32) << 16) + | ((chunk[sector * 512 + i * 4 + 3] as u32) << 24), ); } } diff --git a/storage/ided/src/main.rs b/storage/ided/src/main.rs index 73db90c14f..cc8abb79f2 100644 --- a/storage/ided/src/main.rs +++ b/storage/ided/src/main.rs @@ -1,3 +1,4 @@ +use common::io::Io as _; use driver_block::Disk; use event::{EventFlags, RawEventQueue}; use libredox::flag; @@ -12,9 +13,12 @@ use std::{ thread::{self, sleep}, time::Duration, }; -use common::io::Io as _; use syscall::{ - data::{Event, Packet}, error::{Error, ENODEV}, flag::EVENT_READ, scheme::SchemeBlockMut, EAGAIN, EINTR, EWOULDBLOCK + data::{Event, Packet}, + error::{Error, ENODEV}, + flag::EVENT_READ, + scheme::SchemeBlockMut, + EAGAIN, EINTR, EWOULDBLOCK, }; use crate::{ @@ -164,10 +168,10 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { } } - let mut sectors = (dest[100] as u64) | - ((dest[101] as u64) << 16) | - ((dest[102] as u64) << 32) | - ((dest[103] as u64) << 48); + let mut sectors = (dest[100] as u64) + | ((dest[101] as u64) << 16) + | ((dest[102] as u64) << 32) + | ((dest[103] as u64) << 48); let lba_bits = if sectors == 0 { sectors = (dest[60] as u64) | ((dest[61] as u64) << 16); @@ -196,21 +200,23 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { } let scheme_name = format!("disk.{}", name); - let socket_fd = Socket::::nonblock(&scheme_name) - .expect("ided: failed to create disk scheme"); + let socket_fd = + Socket::::nonblock(&scheme_name).expect("ided: failed to create disk scheme"); let primary_irq_fd = libredox::call::open( &format!("/scheme/irq/{}", primary_irq), flag::O_RDWR | flag::O_NONBLOCK, 0, - ).expect("ided: failed to open irq file"); + ) + .expect("ided: failed to open irq file"); let mut primary_irq_file = unsafe { File::from_raw_fd(primary_irq_fd as RawFd) }; let secondary_irq_fd = libredox::call::open( &format!("/scheme/irq/{}", secondary_irq), flag::O_RDWR | flag::O_NONBLOCK, 0, - ).expect("ided: failed to open irq file"); + ) + .expect("ided: failed to open irq file"); let mut secondary_irq_file = unsafe { File::from_raw_fd(secondary_irq_fd as RawFd) }; let mut event_queue = RawEventQueue::new().expect("ided: failed to open event file"); @@ -219,63 +225,75 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { daemon.ready().expect("ided: failed to notify parent"); - event_queue.subscribe( - socket_fd.inner().raw(), - 0, - EventFlags::READ, - ).expect("ided: failed to event disk scheme"); + event_queue + .subscribe(socket_fd.inner().raw(), 0, EventFlags::READ) + .expect("ided: failed to event disk scheme"); - event_queue.subscribe( - primary_irq_fd, - 0, - EventFlags::READ, - ).expect("ided: failed to event irq scheme"); + event_queue + .subscribe(primary_irq_fd, 0, EventFlags::READ) + .expect("ided: failed to event irq scheme"); - event_queue.subscribe( - secondary_irq_fd, - 0, - EventFlags::READ, - ).expect("ided: failed to event irq scheme"); + event_queue + .subscribe(secondary_irq_fd, 0, EventFlags::READ) + .expect("ided: failed to event irq scheme"); let mut scheme = DiskScheme::new(scheme_name, chans, disks); let mut todo = Vec::new(); 'outer: loop { - let Some(event) = event_queue.next().transpose().expect("ided: failed to read event file") else { + let Some(event) = event_queue + .next() + .transpose() + .expect("ided: failed to read event file") + else { break; }; if event.fd == socket_fd.inner().raw() { loop { let req = match socket_fd.next_request(SignalBehavior::Interrupt) { Ok(None) => break 'outer, - Ok(Some(r)) => if let RequestKind::Call(c) = r.kind() { - c - } else { - continue; - }, - Err(err) => if matches!(err.errno, EAGAIN | EWOULDBLOCK | EINTR) { - break; - } else { - panic!("ided: failed to read disk scheme: {}", err); + Ok(Some(r)) => { + if let RequestKind::Call(c) = r.kind() { + c + } else { + continue; + } + } + Err(err) => { + if matches!(err.errno, EAGAIN | EWOULDBLOCK | EINTR) { + break; + } else { + panic!("ided: failed to read disk scheme: {}", err); + } } }; if let Some(resp) = req.handle_scheme_block_mut(&mut scheme) { - socket_fd.write_response(resp, SignalBehavior::Restart).expect("ided: failed to write disk scheme"); + socket_fd + .write_response(resp, SignalBehavior::Restart) + .expect("ided: failed to write disk scheme"); } else { todo.push(req); } } } else if event.fd == primary_irq_fd { let mut irq = [0; 8]; - if primary_irq_file.read(&mut irq).expect("ided: failed to read irq file") >= irq.len() { + if primary_irq_file + .read(&mut irq) + .expect("ided: failed to read irq file") + >= irq.len() + { if scheme.irq(0) { - primary_irq_file.write(&irq).expect("ided: failed to write irq file"); + primary_irq_file + .write(&irq) + .expect("ided: 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(resp) = todo[i].handle_scheme_block_mut(&mut scheme) { - socket_fd.write_response(resp, SignalBehavior::Restart).expect("ided: failed to write disk scheme"); + socket_fd + .write_response(resp, SignalBehavior::Restart) + .expect("ided: failed to write disk scheme"); } else { i += 1; } @@ -284,15 +302,23 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { } } else if event.fd == secondary_irq_fd { let mut irq = [0; 8]; - if secondary_irq_file.read(&mut irq).expect("ided: failed to read irq file") >= irq.len() { + if secondary_irq_file + .read(&mut irq) + .expect("ided: failed to read irq file") + >= irq.len() + { if scheme.irq(1) { - secondary_irq_file.write(&irq).expect("ided: failed to write irq file"); + secondary_irq_file + .write(&irq) + .expect("ided: 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(resp) = todo[i].handle_scheme_block_mut(&mut scheme) { - socket_fd.write_response(resp, SignalBehavior::Restart).expect("ided: failed to write disk scheme"); + socket_fd + .write_response(resp, SignalBehavior::Restart) + .expect("ided: failed to write disk scheme"); } else { i += 1; } @@ -307,14 +333,20 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let mut i = 0; while i < todo.len() { if let Some(resp) = todo[i].handle_scheme_block_mut(&mut scheme) { - socket_fd.write_response(resp, SignalBehavior::Restart).expect("ided: failed to write disk scheme"); + socket_fd + .write_response(resp, SignalBehavior::Restart) + .expect("ided: failed to write disk scheme"); } else { i += 1; } } for req in todo.drain(..) { - socket_fd.write_response(Response::new(&req, Err(Error::new(ENODEV))), SignalBehavior::Restart) + socket_fd + .write_response( + Response::new(&req, Err(Error::new(ENODEV))), + SignalBehavior::Restart, + ) .expect("ided: failed to write disk scheme"); } } diff --git a/storage/ided/src/scheme.rs b/storage/ided/src/scheme.rs index bb46d11082..0248cae6c5 100644 --- a/storage/ided/src/scheme.rs +++ b/storage/ided/src/scheme.rs @@ -1,22 +1,22 @@ use std::collections::BTreeMap; -use std::str; use std::fmt::Write; +use std::str; use std::sync::{Arc, Mutex}; use driver_block::{Disk, DiskWrapper}; use syscall::schemev2::NewFdFlags; use syscall::{ - Error, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, Result, Stat, MODE_DIR, + Error, Result, Stat, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, MODE_DIR, MODE_FILE, O_DIRECTORY, O_STAT, }; -use redox_scheme::{CallerCtx, OpenResult, SchemeBlockMut}; use crate::ide::Channel; +use redox_scheme::{CallerCtx, OpenResult, SchemeBlockMut}; #[derive(Clone)] enum Handle { - List(Vec), // Dir contents buffer - Disk(usize), // Disk index + List(Vec), // Dir contents buffer + Disk(usize), // Disk index Partition(usize, u32), // Disk index, partition index } @@ -25,17 +25,25 @@ pub struct DiskScheme { chans: Box<[Arc>]>, disks: Box<[DiskWrapper]>, handles: BTreeMap, - next_id: usize + next_id: usize, } impl DiskScheme { - pub fn new(scheme_name: String, chans: Vec>>, disks: Vec>) -> DiskScheme { + pub fn new( + scheme_name: String, + chans: Vec>>, + disks: Vec>, + ) -> DiskScheme { DiskScheme { scheme_name, chans: chans.into_boxed_slice(), - disks: disks.into_iter().map(DiskWrapper::new).collect::>().into_boxed_slice(), + disks: disks + .into_iter() + .map(DiskWrapper::new) + .collect::>() + .into_boxed_slice(), handles: BTreeMap::new(), - next_id: 0 + next_id: 0, } } @@ -49,19 +57,25 @@ impl DiskScheme { fn check_locks(&self, disk_i: usize, part_i_opt: Option) -> Result<()> { for (_, handle) in self.handles.iter() { match handle { - Handle::Disk(i) => if disk_i == *i { - return Err(Error::new(ENOLCK)); - }, - Handle::Partition(i, p) => if disk_i == *i { - match part_i_opt { - Some(part_i) => if part_i == *p { - return Err(Error::new(ENOLCK)); - }, - None => { - return Err(Error::new(ENOLCK)); + Handle::Disk(i) => { + if disk_i == *i { + return Err(Error::new(ENOLCK)); + } + } + Handle::Partition(i, p) => { + if disk_i == *i { + match part_i_opt { + Some(part_i) => { + if part_i == *p { + return Err(Error::new(ENOLCK)); + } + } + None => { + return Err(Error::new(ENOLCK)); + } } } - }, + } _ => (), } } @@ -81,7 +95,7 @@ impl SchemeBlockMut for DiskScheme { write!(list, "{}\n", disk_index).unwrap(); if disk.pt.is_none() { - continue + continue; } for part_index in 0..disk.pt.as_ref().unwrap().partitions.len() { write!(list, "{}p{}\n", disk_index, part_index).unwrap(); @@ -91,7 +105,10 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; self.handles.insert(id, Handle::List(list.into_bytes())); - Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) + Ok(Some(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::POSITIONED, + })) } else { Err(Error::new(EISDIR)) } @@ -105,7 +122,15 @@ impl SchemeBlockMut for DiskScheme { let p = part_id_str.parse::().or(Err(Error::new(ENOENT)))?; if let Some(disk) = self.disks.get(i) { - if disk.pt.is_none() || disk.pt.as_ref().unwrap().partitions.get(p as usize).is_none() { + if disk.pt.is_none() + || disk + .pt + .as_ref() + .unwrap() + .partitions + .get(p as usize) + .is_none() + { return Err(Error::new(ENOENT)); } @@ -114,7 +139,10 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; self.handles.insert(id, Handle::Partition(i, p)); - Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) + Ok(Some(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::POSITIONED, + })) } else { Err(Error::new(ENOENT)) } @@ -127,7 +155,10 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; self.handles.insert(id, Handle::Disk(i)); - Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) + Ok(Some(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::POSITIONED, + })) } else { Err(Error::new(ENOENT)) } @@ -138,7 +169,7 @@ impl SchemeBlockMut for DiskScheme { } fn dup(&mut self, id: usize, buf: &[u8]) -> Result> { - if ! buf.is_empty() { + if !buf.is_empty() { return Err(Error::new(EINVAL)); } @@ -159,7 +190,7 @@ impl SchemeBlockMut for DiskScheme { stat.st_mode = MODE_DIR; stat.st_size = data.len() as u64; Ok(Some(0)) - }, + } Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; stat.st_mode = MODE_FILE; @@ -171,7 +202,10 @@ impl SchemeBlockMut for DiskScheme { let disk = self.disks.get_mut(disk_id).ok_or(Error::new(EBADF))?; let size = { let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?; - let partition = pt.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?; + let partition = pt + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))?; partition.size }; @@ -229,14 +263,23 @@ impl SchemeBlockMut for DiskScheme { Ok(Some(i)) } - fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _flags: u32) -> Result> { + fn read( + &mut self, + id: usize, + buf: &mut [u8], + offset: u64, + _flags: u32, + ) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { Handle::List(ref handle) => { - let src = usize::try_from(offset).ok().and_then(|o| handle.get(o..)).unwrap_or(&[]); + let src = usize::try_from(offset) + .ok() + .and_then(|o| handle.get(o..)) + .unwrap_or(&[]); let bytes = src.len().min(buf.len()); buf[..bytes].copy_from_slice(&src[..bytes]); Ok(Some(bytes)) - }, + } Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; let blk_len = disk.block_length()?; @@ -251,7 +294,10 @@ impl SchemeBlockMut for DiskScheme { let abs_block = { let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?; - let partition = pt.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?; + let partition = pt + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))?; let abs_block = partition.start_lba + rel_block; if rel_block >= partition.size { @@ -267,9 +313,7 @@ impl SchemeBlockMut for DiskScheme { fn write(&mut self, id: usize, buf: &[u8], offset: u64, _flags: u32) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(_) => { - Err(Error::new(EBADF)) - }, + Handle::List(_) => Err(Error::new(EBADF)), Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; let blk_len = disk.block_length()?; @@ -284,7 +328,10 @@ impl SchemeBlockMut for DiskScheme { let abs_block = { let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?; - let partition = pt.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?; + let partition = pt + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))?; let abs_block = partition.start_lba + rel_block; if rel_block >= partition.size { @@ -300,22 +347,30 @@ impl SchemeBlockMut for DiskScheme { fn fsize(&mut self, id: usize) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref mut handle) => { - Ok(Some(handle.len() as u64)) - }, + Handle::List(ref mut handle) => Ok(Some(handle.len() as u64)), Handle::Disk(number) => { let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?; Ok(Some(disk.size())) } Handle::Partition(disk_num, part_num) => { let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?; - let block_count = disk.pt.as_ref().ok_or(Error::new(EBADF))?.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?.size; + let block_count = disk + .pt + .as_ref() + .ok_or(Error::new(EBADF))? + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))? + .size; Ok(Some(u64::from(disk.block_length()?) * block_count)) } } } fn close(&mut self, id: usize) -> Result> { - self.handles.remove(&id).ok_or(Error::new(EBADF)).and(Ok(Some(0))) + self.handles + .remove(&id) + .ok_or(Error::new(EBADF)) + .and(Ok(Some(0))) } } diff --git a/storage/lived/src/main.rs b/storage/lived/src/main.rs index 038b53388d..2a611690f6 100644 --- a/storage/lived/src/main.rs +++ b/storage/lived/src/main.rs @@ -12,12 +12,12 @@ use libredox::flag; use redox_scheme::{CallerCtx, OpenResult, RequestKind, SchemeMut, SignalBehavior, Socket, V2}; use syscall::data::Stat; -use syscall::schemev2::NewFdFlags; use syscall::error::*; use syscall::flag::{MODE_DIR, MODE_FILE}; +use syscall::schemev2::NewFdFlags; use syscall::PAGE_SIZE; -use anyhow::{anyhow, Context, bail}; +use anyhow::{anyhow, bail, Context}; const LIST: [u8; 2] = *b"0\n"; @@ -46,7 +46,10 @@ impl DiskScheme { let mut size = 0; // TODO: handle error - for line in std::fs::read_to_string("/scheme/sys/env").context("failed to read env")?.lines() { + for line in std::fs::read_to_string("/scheme/sys/env") + .context("failed to read env")? + .lines() + { let mut parts = line.splitn(2, '='); let name = parts.next().unwrap_or(""); let value = parts.next().unwrap_or(""); @@ -61,11 +64,18 @@ impl DiskScheme { } if phys == 0 || size == 0 { - bail!("either livedisk phys ({}) or size ({}) was zero", phys, size); + bail!( + "either livedisk phys ({}) or size ({}) was zero", + phys, + size + ); } let start = phys.div_floor(PAGE_SIZE) * PAGE_SIZE; - let end = phys.checked_add(size).context("phys + size overflow")?.next_multiple_of(PAGE_SIZE); + let end = phys + .checked_add(size) + .context("phys + size overflow")? + .next_multiple_of(PAGE_SIZE); let size = end - start; let the_data = unsafe { @@ -77,23 +87,24 @@ impl DiskScheme { length: size, prot: flag::PROT_READ | flag::PROT_WRITE, flags: flag::MAP_SHARED, - }).map_err(|err| anyhow!("failed to mmap livedisk: {}", err))?; + }) + .map_err(|err| anyhow!("failed to mmap livedisk: {}", err))?; std::slice::from_raw_parts_mut(base as *mut u8, size) }; - Ok(DiskScheme { - the_data, - }) + Ok(DiskScheme { the_data }) } } impl SchemeMut for DiskScheme { fn fsize(&mut self, id: usize) -> Result { - Ok(match HandleType::try_from_raw(id).ok_or(Error::new(EBADF))? { - HandleType::TopLevel => LIST.len() as u64, - HandleType::TheData => self.the_data.len() as u64, - }) + Ok( + match HandleType::try_from_raw(id).ok_or(Error::new(EBADF))? { + HandleType::TopLevel => LIST.len() as u64, + HandleType::TheData => self.the_data.len() as u64, + }, + ) } fn fcntl(&mut self, _id: usize, _cmd: usize, _arg: usize) -> Result { @@ -116,12 +127,8 @@ impl SchemeMut for DiskScheme { Ok(OpenResult::ThisScheme { number: match path_trimmed { - "" => { - HandleType::TopLevel as usize - }, - "0" => { - HandleType::TheData as usize - } + "" => HandleType::TopLevel as usize, + "0" => HandleType::TheData as usize, _ => return Err(Error::new(ENOENT)), }, flags: NewFdFlags::POSITIONED, @@ -133,7 +140,10 @@ impl SchemeMut for DiskScheme { HandleType::TopLevel => &LIST, }; - let src = usize::try_from(offset).ok().and_then(|o| data.get(o..)).unwrap_or(&[]); + let src = usize::try_from(offset) + .ok() + .and_then(|o| data.get(o..)) + .unwrap_or(&[]); let byte_count = std::cmp::min(src.len(), buf.len()); buf[..byte_count].copy_from_slice(&src[..byte_count]); Ok(byte_count) @@ -144,7 +154,10 @@ impl SchemeMut for DiskScheme { HandleType::TopLevel => return Err(Error::new(EBADF)), }; - let dst = usize::try_from(offset).ok().and_then(|o| data.get_mut(o..)).unwrap_or(&mut []); + let dst = usize::try_from(offset) + .ok() + .and_then(|o| data.get_mut(o..)) + .unwrap_or(&mut []); let byte_count = std::cmp::min(dst.len(), buf.len()); dst[..byte_count].copy_from_slice(&buf[..byte_count]); Ok(byte_count) @@ -190,18 +203,26 @@ fn main() -> anyhow::Result<()> { daemon.ready().expect("failed to signal readiness"); loop { - let req = match socket_fd.next_request(SignalBehavior::Restart).expect("failed to get next request") { - Some(r) => if let RequestKind::Call(c) = r.kind() { - c - } else { - continue; - }, + let req = match socket_fd + .next_request(SignalBehavior::Restart) + .expect("failed to get next request") + { + Some(r) => { + if let RequestKind::Call(c) = r.kind() { + c + } else { + continue; + } + } None => break, }; let resp = req.handle_scheme_mut(&mut scheme); - socket_fd.write_response(resp, SignalBehavior::Restart).expect("failed to write packet"); + socket_fd + .write_response(resp, SignalBehavior::Restart) + .expect("failed to write packet"); } std::process::exit(0); - }).map_err(|err| anyhow!("failed to start daemon: {}", err))?; + }) + .map_err(|err| anyhow!("failed to start daemon: {}", err))?; } diff --git a/storage/nvmed/src/main.rs b/storage/nvmed/src/main.rs index 0676d6a3be..d969a51af3 100644 --- a/storage/nvmed/src/main.rs +++ b/storage/nvmed/src/main.rs @@ -12,10 +12,7 @@ use std::{slice, usize}; use libredox::flag; use pcid_interface::{PciFeature, PciFeatureInfo, PciFunction, PciFunctionHandle}; use redox_scheme::{CallRequest, RequestKind, SignalBehavior, Socket, V2}; -use syscall::{ - Event, Packet, Result, SchemeBlockMut, - PAGE_SIZE, -}; +use syscall::{Event, Packet, Result, SchemeBlockMut, PAGE_SIZE}; use self::nvme::{InterruptMethod, InterruptSources, Nvme}; use self::scheme::DiskScheme; @@ -53,10 +50,8 @@ fn get_int_method( fn bar_base(pcid_handle: &mut PciFunctionHandle, bir: u8) -> Result> { Ok(unsafe { pcid_handle.map_bar(bir) }.expect("nvmed").ptr) } - let table_bar_base: *mut u8 = - bar_base(pcid_handle, msix_info.table_bar)?.as_ptr(); - let table_base = - unsafe { table_bar_base.offset(msix_info.table_offset as isize) }; + let table_bar_base: *mut u8 = bar_base(pcid_handle, msix_info.table_bar)?.as_ptr(); + let table_base = unsafe { table_bar_base.offset(msix_info.table_offset as isize) }; let vector_count = msix_info.table_size; let table_entries: &'static mut [MsixTableEntry] = unsafe { @@ -107,11 +102,13 @@ fn get_int_method( let (msg_addr_and_data, irq_handle) = irq_helpers::allocate_single_interrupt_vector_for_msi(bsp_cpu_id); - pcid_handle.set_feature_info(SetFeatureInfo::Msi(MsiSetFeatureInfo { - message_address_and_data: Some(msg_addr_and_data), - multi_message_enable: Some(0), // enable 2^0=1 vectors - mask_bits: None, - })).unwrap(); + pcid_handle + .set_feature_info(SetFeatureInfo::Msi(MsiSetFeatureInfo { + message_address_and_data: Some(msg_addr_and_data), + multi_message_enable: Some(0), // enable 2^0=1 vectors + mask_bits: None, + })) + .unwrap(); (0, irq_handle) }; @@ -177,9 +174,8 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { daemon.ready().expect("nvmed: failed to signal readiness"); let (reactor_sender, reactor_receiver) = crossbeam_channel::unbounded(); - let (interrupt_method, interrupt_sources) = - get_int_method(&mut pcid_handle, &pci_config.func) - .expect("nvmed: failed to find a suitable interrupt method"); + let (interrupt_method, interrupt_sources) = get_int_method(&mut pcid_handle, &pci_config.func) + .expect("nvmed: failed to find a suitable interrupt method"); let mut nvme = Nvme::new( address.as_ptr() as usize, interrupt_method, @@ -191,7 +187,11 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { log::debug!("Finished base initialization"); let nvme = Arc::new(nvme); #[cfg(feature = "async")] - let reactor_thread = nvme::cq_reactor::start_cq_reactor_thread(Arc::clone(&nvme), interrupt_sources, reactor_receiver); + let reactor_thread = nvme::cq_reactor::start_cq_reactor_thread( + Arc::clone(&nvme), + interrupt_sources, + reactor_receiver, + ); let namespaces = nvme.init_with_queues(); libredox::call::setrens(0, 0).expect("nvmed: failed to enter null namespace"); @@ -200,15 +200,20 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let mut todo = Vec::new(); loop { // TODO: Use a proper event queue once interrupt support is back. - match socket.next_request(SignalBehavior::Restart).expect("nvmed: failed to read disk scheme") { + match socket + .next_request(SignalBehavior::Restart) + .expect("nvmed: failed to read disk scheme") + { None => { break; - }, - Some(req) => if let RequestKind::Call(c) = req.kind() { - todo.push(c); - } else { - // TODO: cancellation - continue; + } + Some(req) => { + if let RequestKind::Call(c) = req.kind() { + todo.push(c); + } else { + // TODO: cancellation + continue; + } } } @@ -216,7 +221,8 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { while i < todo.len() { if let Some(resp) = todo[i].handle_scheme_block_mut(&mut scheme) { let _req = todo.remove(i); - socket.write_response(resp, SignalBehavior::Restart) + socket + .write_response(resp, SignalBehavior::Restart) .expect("nvmed: failed to write disk scheme"); } else { i += 1; @@ -226,7 +232,9 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { //TODO: destroy NVMe stuff #[cfg(feature = "async")] - reactor_thread.join().expect("nvmed: failed to join reactor thread"); + reactor_thread + .join() + .expect("nvmed: failed to join reactor thread"); std::process::exit(0); } diff --git a/storage/nvmed/src/nvme/cq_reactor.rs b/storage/nvmed/src/nvme/cq_reactor.rs index cf65635de7..3a10c136ef 100644 --- a/storage/nvmed/src/nvme/cq_reactor.rs +++ b/storage/nvmed/src/nvme/cq_reactor.rs @@ -19,7 +19,7 @@ use syscall::Result; use crossbeam_channel::Receiver; -use super::{CmdId, CqId, InterruptSources, Nvme, NvmeComp, NvmeCmd, SqId}; +use super::{CmdId, CqId, InterruptSources, Nvme, NvmeCmd, NvmeComp, SqId}; /// A notification request, sent by the future in order to tell the completion thread that the /// current task wants a notification when a matching completion queue entry has been seen. @@ -39,7 +39,7 @@ pub enum NotifReq { RequestAvailSubmission { sq_id: SqId, waker: task::Waker, - } + }, } enum PendingReq { @@ -97,7 +97,11 @@ impl CqReactor { receiver, }) } - fn handle_notif_reqs_raw(pending_reqs: &mut Vec, receiver: &Receiver, block_until_first: bool) { + fn handle_notif_reqs_raw( + pending_reqs: &mut Vec, + receiver: &Receiver, + block_until_first: bool, + ) { let mut blocking_iter; let mut nonblocking_iter; @@ -125,7 +129,9 @@ impl CqReactor { message, waker, }), - NotifReq::RequestAvailSubmission { sq_id, waker } => pending_reqs.push(PendingReq::PendingAvailSubmission { sq_id, waker, }), + NotifReq::RequestAvailSubmission { sq_id, waker } => { + pending_reqs.push(PendingReq::PendingAvailSubmission { sq_id, waker }) + } } } } @@ -144,14 +150,22 @@ impl CqReactor { while let Some((head, entry)) = completion_queue.complete(None) { unsafe { self.nvme.completion_queue_head(cq_id, head) }; - log::trace!("Got completion queue entry (CQID {}): {:?} at {}", cq_id, entry, head); + log::trace!( + "Got completion queue entry (CQID {}): {:?} at {}", + cq_id, + entry, + head + ); { let submission_queues_read_lock = self.nvme.submission_queues.read().unwrap(); // this lock is actually important, since it will block during submission from other // threads. the lock won't be held for long by the submitters, but it still prevents // the entry being lost before this reactor is actually able to respond: - let &(ref sq_lock, corresponding_cq_id) = submission_queues_read_lock.get(&{entry.sq_id}).expect("nvmed: internal error: queue returned from controller doesn't exist"); + let &(ref sq_lock, corresponding_cq_id) = + submission_queues_read_lock.get(&{ entry.sq_id }).expect( + "nvmed: internal error: queue returned from controller doesn't exist", + ); assert_eq!(cq_id, corresponding_cq_id); let mut sq_guard = sq_lock.lock().unwrap(); sq_guard.head = entry.sq_head; @@ -159,7 +173,6 @@ impl CqReactor { Self::handle_notif_reqs_raw(&mut self.pending_reqs, &self.receiver, false); } - Self::try_notify_futures(&mut self.pending_reqs, cq_id, &entry); entry_count += 1; @@ -169,11 +182,16 @@ impl CqReactor { Some(()) } - fn finish_pending_completion(pending_reqs: &mut Vec, req_cq_id: CqId, cq_id: CqId, sq_id: SqId, cmd_id: CmdId, entry: &NvmeComp, i: usize) -> bool { - if req_cq_id == cq_id - && sq_id == entry.sq_id - && cmd_id == entry.cid - { + fn finish_pending_completion( + pending_reqs: &mut Vec, + req_cq_id: CqId, + cq_id: CqId, + sq_id: SqId, + cmd_id: CmdId, + entry: &NvmeComp, + i: usize, + ) -> bool { + if req_cq_id == cq_id && sq_id == entry.sq_id && cmd_id == entry.cid { let (waker, message) = match pending_reqs.remove(i) { PendingReq::PendingCompletion { waker, message, .. } => (waker, message), _ => unreachable!(), @@ -187,7 +205,12 @@ impl CqReactor { false } } - fn finish_pending_avail_submission(pending_reqs: &mut Vec, sq_id: SqId, entry: &NvmeComp, i: usize) -> bool { + fn finish_pending_avail_submission( + pending_reqs: &mut Vec, + sq_id: SqId, + entry: &NvmeComp, + i: usize, + ) -> bool { if sq_id == entry.sq_id { let waker = match pending_reqs.remove(i) { PendingReq::PendingAvailSubmission { waker, .. } => waker, @@ -200,22 +223,43 @@ impl CqReactor { false } } - fn try_notify_futures(pending_reqs: &mut Vec, cq_id: CqId, entry: &NvmeComp) -> Option<()> { + fn try_notify_futures( + pending_reqs: &mut Vec, + cq_id: CqId, + entry: &NvmeComp, + ) -> Option<()> { let mut i = 0usize; let mut futures_notified = 0; while i < pending_reqs.len() { match &pending_reqs[i] { - &PendingReq::PendingCompletion { cq_id: req_cq_id, sq_id, cmd_id, .. } => if Self::finish_pending_completion(pending_reqs, req_cq_id, cq_id, sq_id, cmd_id, entry, i) { - futures_notified += 1; - } else { - i += 1; + &PendingReq::PendingCompletion { + cq_id: req_cq_id, + sq_id, + cmd_id, + .. + } => { + if Self::finish_pending_completion( + pending_reqs, + req_cq_id, + cq_id, + sq_id, + cmd_id, + entry, + i, + ) { + futures_notified += 1; + } else { + i += 1; + } } - &PendingReq::PendingAvailSubmission { sq_id, .. } => if Self::finish_pending_avail_submission(pending_reqs, sq_id, entry, i) { - futures_notified += 1; - } else { - i += 1; + &PendingReq::PendingAvailSubmission { sq_id, .. } => { + if Self::finish_pending_avail_submission(pending_reqs, sq_id, entry, i) { + futures_notified += 1; + } else { + i += 1; + } } } } @@ -272,7 +316,7 @@ pub fn start_cq_reactor_thread( // multiple vectors to point to different CPUs, so that the load can be balanced across the // logical processors. let reactor = CqReactor::new(nvme, interrupt_sources, receiver) - .expect("nvmed: failed to setup CQ reactor"); + .expect("nvmed: failed to setup CQ reactor"); thread::spawn(move || reactor.run()) } @@ -317,7 +361,11 @@ where let this = &mut self.get_mut().state; match mem::replace(this, CompletionFutureState::Placeholder) { - CompletionFutureState::PendingSubmission { cmd_init, nvme, sq_id } => { + CompletionFutureState::PendingSubmission { + cmd_init, + nvme, + sq_id, + } => { let sqs_read_guard = nvme.submission_queues.read().unwrap(); let &(ref sq_lock, cq_id) = sqs_read_guard .get(&sq_id) @@ -329,20 +377,43 @@ where // when the CQ reactor gets a new completion queue entry, it'll lock the // submisson queue it came from. since we're holding the same lock, this // message will always be sent before the reactor is done with the entry. - nvme.reactor_sender.send(NotifReq::RequestAvailSubmission { sq_id, waker: context.waker().clone() }).unwrap(); - *this = CompletionFutureState::PendingSubmission { cmd_init, nvme, sq_id }; + nvme.reactor_sender + .send(NotifReq::RequestAvailSubmission { + sq_id, + waker: context.waker().clone(), + }) + .unwrap(); + *this = CompletionFutureState::PendingSubmission { + cmd_init, + nvme, + sq_id, + }; return task::Poll::Pending; } - let cmd_id = - u16::try_from(sq.tail).expect("nvmed: internal error: CQ has more than 2^16 entries"); + let cmd_id = u16::try_from(sq.tail) + .expect("nvmed: internal error: CQ has more than 2^16 entries"); let tail = sq.submit_unchecked(cmd_init(cmd_id)); let tail = u16::try_from(tail).unwrap(); // make sure that we register interest before the reactor can get notified let message = Arc::new(Mutex::new(None)); - *this = CompletionFutureState::PendingCompletion { nvme, cq_id, cmd_id, sq_id, message: Arc::clone(&message), }; - nvme.reactor_sender.send(NotifReq::RequestCompletion { cq_id, sq_id, cmd_id, message, waker: context.waker().clone() }).expect("reactor dead"); + *this = CompletionFutureState::PendingCompletion { + nvme, + cq_id, + cmd_id, + sq_id, + message: Arc::clone(&message), + }; + nvme.reactor_sender + .send(NotifReq::RequestCompletion { + cq_id, + sq_id, + cmd_id, + message, + waker: context.waker().clone(), + }) + .expect("reactor dead"); unsafe { nvme.submission_queue_tail(sq_id, tail) }; task::Poll::Pending } @@ -357,14 +428,22 @@ where *this = CompletionFutureState::Finished; return task::Poll::Ready(value.cq_entry); } - nvme.reactor_sender.send(NotifReq::RequestCompletion { + nvme.reactor_sender + .send(NotifReq::RequestCompletion { + cq_id, + sq_id, + cmd_id, + waker: context.waker().clone(), + message: Arc::clone(&message), + }) + .expect("reactor dead"); + *this = CompletionFutureState::PendingCompletion { + message, cq_id, - sq_id, cmd_id, - waker: context.waker().clone(), - message: Arc::clone(&message), - }).expect("reactor dead"); - *this = CompletionFutureState::PendingCompletion { message, cq_id, cmd_id, sq_id, nvme }; + sq_id, + nvme, + }; task::Poll::Pending } CompletionFutureState::Finished => { diff --git a/storage/nvmed/src/nvme/identify.rs b/storage/nvmed/src/nvme/identify.rs index 6f22a1fe40..af82008f17 100644 --- a/storage/nvmed/src/nvme/identify.rs +++ b/storage/nvmed/src/nvme/identify.rs @@ -61,7 +61,6 @@ pub struct IdentifyNamespaceData { pub nows: u16, pub _rsvd1: [u8; 18], // 92 - pub anagrpid: u32, pub _rsvd2: [u8; 3], pub nsattr: u8, @@ -137,8 +136,12 @@ impl LbaFormat { ((self.0 >> 16) & 0xFF) as u8 } pub fn lba_data_size(&self) -> Option { - if self.log_lba_data_size() < 9 { return None } - if self.log_lba_data_size() >= 32 { return None } + if self.log_lba_data_size() < 9 { + return None; + } + if self.log_lba_data_size() >= 32 { + return None; + } Some(1u64 << self.log_lba_data_size()) } pub fn metadata_size(&self) -> u16 { @@ -153,8 +156,9 @@ impl Nvme { let data: Dma = unsafe { Dma::zeroed().unwrap().assume_init() }; // println!(" - Attempting to identify controller"); - let comp = self - .submit_and_complete_admin_command(|cid| NvmeCmd::identify_controller(cid, data.physical())); + let comp = self.submit_and_complete_admin_command(|cid| { + NvmeCmd::identify_controller(cid, data.physical()) + }); log::trace!("Completion: {:?}", comp); // println!(" - Dumping identify controller"); @@ -169,7 +173,9 @@ impl Nvme { log::info!( " - Model: {} Serial: {} Firmware: {}", - model, serial, firmware, + model, + serial, + firmware, ); } pub fn identify_namespace_list(&self, base: u32) -> Vec { @@ -177,10 +183,9 @@ impl Nvme { let data: Dma<[u32; 1024]> = unsafe { Dma::zeroed().unwrap().assume_init() }; // println!(" - Attempting to retrieve namespace ID list"); - let comp = self - .submit_and_complete_admin_command(|cid| { - NvmeCmd::identify_namespace_list(cid, data.physical(), base) - }); + let comp = self.submit_and_complete_admin_command(|cid| { + NvmeCmd::identify_namespace_list(cid, data.physical(), base) + }); log::trace!("Completion2: {:?}", comp); @@ -192,8 +197,9 @@ impl Nvme { let data: Dma = unsafe { Dma::zeroed().unwrap().assume_init() }; // println!(" - Attempting to identify namespace {}", nsid); - let comp = self - .submit_and_complete_admin_command(|cid| NvmeCmd::identify_namespace(cid, data.physical(), nsid)); + let comp = self.submit_and_complete_admin_command(|cid| { + NvmeCmd::identify_namespace(cid, data.physical(), nsid) + }); // println!(" - Dumping identify namespace"); @@ -201,7 +207,10 @@ impl Nvme { let capacity = data.capacity_in_blocks(); log::info!("NSID: {} Size: {} Capacity: {}", nsid, size, capacity); - let block_size = data.formatted_lba_size().lba_data_size().expect("nvmed: error: size outside 512-2^64 range"); + let block_size = data + .formatted_lba_size() + .lba_data_size() + .expect("nvmed: error: size outside 512-2^64 range"); log::debug!("NVME block size: {}", block_size); NvmeNamespace { diff --git a/storage/nvmed/src/nvme/mod.rs b/storage/nvmed/src/nvme/mod.rs index a4127a3b51..4ef6c13b77 100644 --- a/storage/nvmed/src/nvme/mod.rs +++ b/storage/nvmed/src/nvme/mod.rs @@ -9,8 +9,8 @@ use std::thread; use crossbeam_channel::Sender; use smallvec::{smallvec, SmallVec}; -use syscall::error::{Error, Result, EINVAL, EIO}; use common::io::{Io, Mmio}; +use syscall::error::{Error, Result, EINVAL, EIO}; use common::dma::Dma; @@ -27,15 +27,21 @@ use pcid_interface::PciFunctionHandle; #[cfg(target_arch = "aarch64")] #[inline(always)] -pub(crate) unsafe fn pause() { std::arch::aarch64::__yield(); } +pub(crate) unsafe fn pause() { + std::arch::aarch64::__yield(); +} #[cfg(target_arch = "x86")] #[inline(always)] -pub(crate) unsafe fn pause() { std::arch::x86::_mm_pause(); } +pub(crate) unsafe fn pause() { + std::arch::x86::_mm_pause(); +} #[cfg(target_arch = "x86_64")] #[inline(always)] -pub(crate) unsafe fn pause() { std::arch::x86_64::_mm_pause(); } +pub(crate) unsafe fn pause() { + std::arch::x86_64::_mm_pause(); +} /// Used in conjunction with `InterruptMethod`, primarily by the CQ reactor. #[derive(Debug)] @@ -91,7 +97,10 @@ pub enum InterruptMethod { /// Traditional level-triggered, INTx# interrupt pins. Intx, /// Message signaled interrupts - Msi { msi_info: MsiInfo, log2_multiple_message_enabled: u8 }, + Msi { + msi_info: MsiInfo, + log2_multiple_message_enabled: u8, + }, /// Extended message signaled interrupts MsiX(MappedMsixRegs), } @@ -218,7 +227,8 @@ impl Nvme { std::iter::once((0u16, (Mutex::new(NvmeCmdQueue::new()?), 0u16))).collect(), ), completion_queues: RwLock::new( - std::iter::once((0u16, Mutex::new((NvmeCompQueue::new()?, smallvec!(0))))).collect(), + std::iter::once((0u16, Mutex::new((NvmeCompQueue::new()?, smallvec!(0))))) + .collect(), ), // map the zero interrupt vector (which according to the spec shall always point to the // admin completion queue) to CQID 0 (admin completion queue) @@ -301,12 +311,24 @@ impl Nvme { for (qid, queue) in self.completion_queues.get_mut().unwrap().iter_mut() { let &(ref cq, ref sq_ids) = &*queue.get_mut().unwrap(); let data = &cq.data; - log::debug!("completion queue {}: {:X}, {}, (submission queue ids: {:?}", qid, data.physical(), data.len(), sq_ids); + log::debug!( + "completion queue {}: {:X}, {}, (submission queue ids: {:?}", + qid, + data.physical(), + data.len(), + sq_ids + ); } for (qid, (queue, cq_id)) in self.submission_queues.get_mut().unwrap().iter_mut() { let data = &queue.get_mut().unwrap().data; - log::debug!("submission queue {}: {:X}, {}, attached to CQID: {}", qid, data.physical(), data.len(), cq_id); + log::debug!( + "submission queue {}: {:X}, {}, attached to CQID: {}", + qid, + data.physical(), + data.len(), + cq_id + ); } { @@ -319,9 +341,11 @@ impl Nvme { regs.aqa .write(((acq.data.len() as u32 - 1) << 16) | (asq.data.len() as u32 - 1)); regs.asq_low.write(asq.data.physical() as u32); - regs.asq_high.write((asq.data.physical() as u64 >> 32) as u32); + regs.asq_high + .write((asq.data.physical() as u64 >> 32) as u32); regs.acq_low.write(acq.data.physical() as u32); - regs.acq_high.write((acq.data.physical() as u64 >> 32) as u32); + regs.acq_high + .write((acq.data.physical() as u64 >> 32) as u32); // Set IOCQES, IOSQES, AMS, MPS, and CSS let mut cc = regs.cc.read(); @@ -371,7 +395,10 @@ impl Nvme { self.regs.write().unwrap().intmc.write(0x0000_0001); } } - &mut InterruptMethod::Msi { msi_info: _, log2_multiple_message_enabled: log2_enabled_messages } => { + &mut InterruptMethod::Msi { + msi_info: _, + log2_multiple_message_enabled: log2_enabled_messages, + } => { let mut to_mask = 0x0000_0000; let mut to_clear = 0x0000_0000; @@ -421,7 +448,11 @@ impl Nvme { } #[cfg(not(feature = "async"))] - pub fn submit_and_complete_command NvmeCmd>(&self, sq_id: SqId, cmd_init: F) -> NvmeComp { + pub fn submit_and_complete_command NvmeCmd>( + &self, + sq_id: SqId, + cmd_init: F, + ) -> NvmeComp { // Submit command let cmd = { let sqs_read_guard = self.submission_queues.read().unwrap(); @@ -433,10 +464,15 @@ impl Nvme { assert!(!sq.is_full()); - let cmd_id = - u16::try_from(sq.tail).expect("nvmed: internal error: CQ has more than 2^16 entries"); + let cmd_id = u16::try_from(sq.tail) + .expect("nvmed: internal error: CQ has more than 2^16 entries"); let cmd = cmd_init(cmd_id); - log::trace!("Sent submission queue entry (SQID {}): {:?} at {}", sq_id, cmd, cmd_id); + log::trace!( + "Sent submission queue entry (SQID {}): {:?} at {}", + sq_id, + cmd, + cmd_id + ); let tail = sq.submit_unchecked(cmd); let tail = u16::try_from(tail).unwrap(); @@ -460,7 +496,12 @@ impl Nvme { while let Some((head, entry)) = completion_queue.complete(Some((sq_id, cmd))) { unsafe { self.completion_queue_head(*cq_id, head) }; - log::trace!("Got completion queue entry (CQID {}): {:?} at {}", cq_id, entry, head); + log::trace!( + "Got completion queue entry (CQID {}): {:?} at {}", + cq_id, + entry, + head + ); assert_eq!(sq_id, { entry.sq_id }); assert_eq!({ cmd.cid }, { entry.cid }); @@ -484,16 +525,25 @@ impl Nvme { } #[cfg(feature = "async")] - pub fn submit_and_complete_command NvmeCmd>(&self, sq_id: SqId, cmd_init: F) -> NvmeComp { + pub fn submit_and_complete_command NvmeCmd>( + &self, + sq_id: SqId, + cmd_init: F, + ) -> NvmeComp { use crate::nvme::cq_reactor::{CompletionFuture, CompletionFutureState}; - futures::executor::block_on( - CompletionFuture { - state: CompletionFutureState::PendingSubmission { cmd_init, nvme: &self, sq_id }, - } - ) + futures::executor::block_on(CompletionFuture { + state: CompletionFutureState::PendingSubmission { + cmd_init, + nvme: &self, + sq_id, + }, + }) } - pub fn submit_and_complete_admin_command NvmeCmd>(&self, cmd_init: F) -> NvmeComp { + pub fn submit_and_complete_admin_command NvmeCmd>( + &self, + cmd_init: F, + ) -> NvmeComp { self.submit_and_complete_command(0, cmd_init) } @@ -522,10 +572,9 @@ impl Nvme { .checked_sub(1) .expect("nvmed: internal error: CQID 0 for I/O CQ"); - let comp = self - .submit_and_complete_admin_command(|cid| { - NvmeCmd::create_io_completion_queue(cid, io_cq_id, ptr, raw_len, vector) - }); + let comp = self.submit_and_complete_admin_command(|cid| { + NvmeCmd::create_io_completion_queue(cid, io_cq_id, ptr, raw_len, vector) + }); if let Some(vector) = vector { self.cqs_for_ivs @@ -540,14 +589,15 @@ impl Nvme { let (ptr, len) = { let mut submission_queues_guard = self.submission_queues.write().unwrap(); - let (queue_lock, _) = submission_queues_guard - .entry(io_sq_id) - .or_insert_with(|| { - (Mutex::new( + let (queue_lock, _) = submission_queues_guard.entry(io_sq_id).or_insert_with(|| { + ( + Mutex::new( NvmeCmdQueue::new() .expect("nvmed: failed to allocate I/O completion queue"), - ), io_cq_id) - }); + ), + io_cq_id, + ) + }); let queue = queue_lock.get_mut().unwrap(); (queue.data.physical(), queue.data.len()) @@ -559,10 +609,9 @@ impl Nvme { .checked_sub(1) .expect("nvmed: internal error: SQID 0 for I/O SQ"); - let comp = self - .submit_and_complete_admin_command(|cid| { - NvmeCmd::create_io_submission_queue(cid, io_sq_id, ptr, raw_len, io_cq_id) - }); + let comp = self.submit_and_complete_admin_command(|cid| { + NvmeCmd::create_io_submission_queue(cid, io_sq_id, ptr, raw_len, io_cq_id) + }); } pub fn init_with_queues(&self) -> BTreeMap { @@ -604,7 +653,10 @@ impl Nvme { } else if bytes <= 8192 { (buffer_prp_guard[0], buffer_prp_guard[1]) } else { - (buffer_prp_guard[0], (buffer_prp_guard.physical() + 8) as u64) + ( + buffer_prp_guard[0], + (buffer_prp_guard.physical() + 8) as u64, + ) }; let mut cmd = NvmeCmd::default(); diff --git a/storage/nvmed/src/nvme/queues.rs b/storage/nvmed/src/nvme/queues.rs index 3fd1b23adf..836ec89a6a 100644 --- a/storage/nvmed/src/nvme/queues.rs +++ b/storage/nvmed/src/nvme/queues.rs @@ -69,9 +69,7 @@ impl NvmeCompQueue { //HACK FOR SOMETIMES RETURNING INVALID DATA ON QEMU! if let Some((sq_id, cmd)) = cmd_opt { - if entry.sq_id != sq_id - || entry.cid != cmd.cid - { + if entry.sq_id != sq_id || entry.cid != cmd.cid { return None; } } @@ -94,7 +92,9 @@ impl NvmeCompQueue { if let Some(some) = self.complete(cmd_opt) { return some; } else { - unsafe { super::pause(); } + unsafe { + super::pause(); + } } } } diff --git a/storage/nvmed/src/scheme.rs b/storage/nvmed/src/scheme.rs index a38fb1cada..4c63169ce0 100644 --- a/storage/nvmed/src/scheme.rs +++ b/storage/nvmed/src/scheme.rs @@ -6,12 +6,12 @@ use std::io::prelude::*; use std::sync::Arc; use std::{cmp, str}; +use redox_scheme::{CallerCtx, OpenResult, SchemeBlockMut}; use syscall::schemev2::NewFdFlags; use syscall::{ Error, Result, Stat, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, MODE_DIR, MODE_FILE, O_DIRECTORY, O_STAT, SEEK_CUR, SEEK_END, SEEK_SET, }; -use redox_scheme::{CallerCtx, OpenResult, SchemeBlockMut}; use crate::nvme::{Nvme, NvmeNamespace}; @@ -84,8 +84,10 @@ impl DiskWrapper { return Err(io::Error::from_raw_os_error(syscall::EOVERFLOW)); } loop { - match nvme.namespace_read(disk, disk.id, block, block_bytes) - .map_err(|err| io::Error::from_raw_os_error(err.errno))? { + match nvme + .namespace_read(disk, disk.id, block, block_bytes) + .map_err(|err| io::Error::from_raw_os_error(err.errno))? + { Some(bytes) => { assert_eq!(bytes, block_bytes.len()); assert_eq!(bytes, blksize as usize); @@ -164,19 +166,25 @@ impl DiskScheme { fn check_locks(&self, disk_i: u32, part_i_opt: Option) -> Result<()> { for (_, handle) in self.handles.iter() { match handle { - Handle::Disk(i) => if disk_i == *i { - return Err(Error::new(ENOLCK)); - }, - Handle::Partition(i, p) => if disk_i == *i { - match part_i_opt { - Some(part_i) => if part_i == *p { - return Err(Error::new(ENOLCK)); - }, - None => { - return Err(Error::new(ENOLCK)); + Handle::Disk(i) => { + if disk_i == *i { + return Err(Error::new(ENOLCK)); + } + } + Handle::Partition(i, p) => { + if disk_i == *i { + match part_i_opt { + Some(part_i) => { + if part_i == *p { + return Err(Error::new(ENOLCK)); + } + } + None => { + return Err(Error::new(ENOLCK)); + } } } - }, + } _ => (), } } @@ -185,12 +193,16 @@ impl DiskScheme { } impl SchemeBlockMut for DiskScheme { - fn xopen(&mut self, path_str: &str, flags: usize, ctx: &CallerCtx) -> Result> { + fn xopen( + &mut self, + path_str: &str, + flags: usize, + ctx: &CallerCtx, + ) -> Result> { if ctx.uid != 0 { return Err(Error::new(EACCES)); } - let path_str = path_str - .trim_matches('/'); + let path_str = path_str.trim_matches('/'); let handle = if path_str.is_empty() { if flags & O_DIRECTORY == O_DIRECTORY || flags & O_STAT == O_STAT { @@ -253,7 +265,10 @@ impl SchemeBlockMut for DiskScheme { let id = self.next_id; self.next_id += 1; self.handles.insert(id, handle); - Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) + Ok(Some(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::POSITIONED, + })) } fn dup(&mut self, id: usize, buf: &[u8]) -> Result> { @@ -358,10 +373,19 @@ impl SchemeBlockMut for DiskScheme { Ok(Some(i)) } - fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result> { + fn read( + &mut self, + id: usize, + buf: &mut [u8], + offset: u64, + _fcntl_flags: u32, + ) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { Handle::List(ref handle) => { - let src = usize::try_from(offset).ok().and_then(|o| handle.get(o..)).unwrap_or(&[]); + let src = usize::try_from(offset) + .ok() + .and_then(|o| handle.get(o..)) + .unwrap_or(&[]); let count = core::cmp::min(src.len(), buf.len()); buf[..count].copy_from_slice(&src[..count]); Ok(Some(count)) @@ -369,7 +393,8 @@ impl SchemeBlockMut for DiskScheme { Handle::Disk(number) => { let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?; let block_size = disk.as_ref().block_size; - self.nvme.namespace_read(disk.as_ref(), disk.as_ref().id, offset / block_size, buf) + self.nvme + .namespace_read(disk.as_ref(), disk.as_ref().id, offset / block_size, buf) } Handle::Partition(disk_num, part_num) => { let disk = self.disks.get_mut(&disk_num).ok_or(Error::new(EBADF))?; @@ -389,18 +414,26 @@ impl SchemeBlockMut for DiskScheme { let abs_block = part.start_lba + rel_block; - self.nvme.namespace_read(disk.as_ref(), disk.as_ref().id, abs_block, buf) + self.nvme + .namespace_read(disk.as_ref(), disk.as_ref().id, abs_block, buf) } } } - fn write(&mut self, id: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> Result> { + fn write( + &mut self, + id: usize, + buf: &[u8], + offset: u64, + _fcntl_flags: u32, + ) -> Result> { match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { Handle::List(_) => Err(Error::new(EBADF)), Handle::Disk(number) => { let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?; let block_size = disk.as_ref().block_size; - self.nvme.namespace_write(disk.as_ref(), disk.as_ref().id, offset / block_size, buf) + self.nvme + .namespace_write(disk.as_ref(), disk.as_ref().id, offset / block_size, buf) } Handle::Partition(disk_num, part_num) => { let disk = self.disks.get_mut(&disk_num).ok_or(Error::new(EBADF))?; @@ -420,31 +453,34 @@ impl SchemeBlockMut for DiskScheme { let abs_block = part.start_lba + rel_block; - self.nvme.namespace_write(disk.as_ref(), disk.as_ref().id, abs_block, buf) + self.nvme + .namespace_write(disk.as_ref(), disk.as_ref().id, abs_block, buf) } } } fn fsize(&mut self, id: usize) -> Result> { - Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List(ref handle) => handle.len() as u64, - Handle::Disk(number) => { - let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?; - disk.as_ref().blocks * disk.as_ref().block_size - } - Handle::Partition(disk_num, part_num) => { - let disk = self.disks.get_mut(&disk_num).ok_or(Error::new(EBADF))?; - let part = disk - .pt - .as_ref() - .ok_or(Error::new(EBADF))? - .partitions - .get(part_num as usize) - .ok_or(Error::new(EBADF))?; + Ok(Some( + match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { + Handle::List(ref handle) => handle.len() as u64, + Handle::Disk(number) => { + let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?; + disk.as_ref().blocks * disk.as_ref().block_size + } + Handle::Partition(disk_num, part_num) => { + let disk = self.disks.get_mut(&disk_num).ok_or(Error::new(EBADF))?; + let part = disk + .pt + .as_ref() + .ok_or(Error::new(EBADF))? + .partitions + .get(part_num as usize) + .ok_or(Error::new(EBADF))?; - part.size * disk.as_ref().block_size - } - })) + part.size * disk.as_ref().block_size + } + }, + )) } fn close(&mut self, id: usize) -> Result> { diff --git a/storage/usbscsid/src/main.rs b/storage/usbscsid/src/main.rs index 39cc0e9771..4f15115c55 100644 --- a/storage/usbscsid/src/main.rs +++ b/storage/usbscsid/src/main.rs @@ -33,7 +33,8 @@ fn main() { scheme, port, protocol ); - redox_daemon::Daemon::new(move |d| daemon(d, scheme, port, protocol)).expect("usbscsid: failed to daemonize"); + redox_daemon::Daemon::new(move |d| daemon(d, scheme, port, protocol)) + .expect("usbscsid: failed to daemonize"); } fn daemon(daemon: redox_daemon::Daemon, scheme: String, port: usize, protocol: u8) -> ! { let disk_scheme_name = format!(":disk.usb-{scheme}+{port}-scsi"); @@ -81,8 +82,8 @@ fn daemon(daemon: redox_daemon::Daemon, scheme: String, port: usize, protocol: u // TODO: Let all of the USB drivers fork or be managed externally, and xhcid won't have to keep // track of all the drivers. - let socket_fd = Socket::::create(&disk_scheme_name) - .expect("usbscsid: failed to create disk scheme"); + let socket_fd = + Socket::::create(&disk_scheme_name).expect("usbscsid: failed to create disk scheme"); //libredox::call::setrens(0, 0).expect("scsid: failed to enter null namespace"); let mut scsi = Scsi::new(&mut *protocol).expect("usbscsid: failed to setup SCSI"); @@ -95,11 +96,16 @@ fn daemon(daemon: redox_daemon::Daemon, scheme: String, port: usize, protocol: u // TODO: Use nonblocking and put all pending calls in a todo VecDeque. Use an eventfd as well. loop { - let req = match socket_fd.next_request(SignalBehavior::Restart).expect("scsid: failed to read disk scheme") { - Some(r) => if let RequestKind::Call(c) = r.kind() { - c - } else { - continue; + let req = match socket_fd + .next_request(SignalBehavior::Restart) + .expect("scsid: failed to read disk scheme") + { + Some(r) => { + if let RequestKind::Call(c) = r.kind() { + c + } else { + continue; + } } None => break, }; diff --git a/storage/usbscsid/src/protocol/bot.rs b/storage/usbscsid/src/protocol/bot.rs index 17e2432b9f..6f1f847db2 100644 --- a/storage/usbscsid/src/protocol/bot.rs +++ b/storage/usbscsid/src/protocol/bot.rs @@ -3,8 +3,8 @@ use std::slice; use xhcid_interface::{ ConfDesc, DeviceReqData, EndpBinaryDirection, EndpDirection, EndpointStatus, IfDesc, Invalid, - PortReqRecipient, PortReqTy, PortTransferStatus, PortTransferStatusKind, XhciClientHandle, XhciClientHandleError, - XhciEndpHandle, + PortReqRecipient, PortReqTy, PortTransferStatus, PortTransferStatusKind, XhciClientHandle, + XhciClientHandleError, XhciEndpHandle, }; use super::{Protocol, ProtocolError, SendCommandStatus, SendCommandStatusKind}; @@ -162,9 +162,16 @@ impl<'a> BulkOnlyTransport<'a> { } Ok(()) } - fn read_csw_raw(&mut self, csw_buffer: &mut [u8; 13], already: bool) -> Result<(), ProtocolError> { + fn read_csw_raw( + &mut self, + csw_buffer: &mut [u8; 13], + already: bool, + ) -> Result<(), ProtocolError> { match self.bulk_in.transfer_read(&mut csw_buffer[..])? { - PortTransferStatus { kind: PortTransferStatusKind::Stalled, .. } => { + PortTransferStatus { + kind: PortTransferStatusKind::Stalled, + .. + } => { if already { self.reset_recovery()?; } @@ -172,8 +179,14 @@ impl<'a> BulkOnlyTransport<'a> { self.clear_stall_in()?; self.read_csw_raw(csw_buffer, true)?; } - PortTransferStatus { kind: PortTransferStatusKind::ShortPacket, bytes_transferred } if bytes_transferred != 13 => { - panic!("received a short packet when reading CSW ({} != 13)", bytes_transferred) + PortTransferStatus { + kind: PortTransferStatusKind::ShortPacket, + bytes_transferred, + } if bytes_transferred != 13 => { + panic!( + "received a short packet when reading CSW ({} != 13)", + bytes_transferred + ) } _ => (), } @@ -199,24 +212,38 @@ impl<'a> Protocol for BulkOnlyTransport<'a> { let cbw = *cbw; match self.bulk_out.transfer_write(&cbw_bytes)? { - PortTransferStatus { kind: PortTransferStatusKind::Stalled, .. } => { + PortTransferStatus { + kind: PortTransferStatusKind::Stalled, + .. + } => { // TODO: Error handling panic!("bulk out endpoint stalled when sending CBW {:?}", cbw); //self.clear_stall_out()?; //dbg!(self.bulk_in.status()?, self.bulk_out.status()?); } - PortTransferStatus { bytes_transferred, .. } if bytes_transferred != 31 => { - panic!("received short packet when sending CBW ({} != 31)", bytes_transferred); + PortTransferStatus { + bytes_transferred, .. + } if bytes_transferred != 31 => { + panic!( + "received short packet when sending CBW ({} != 31)", + bytes_transferred + ); } _ => (), } let early_residue: Option = match data { DeviceReqData::In(buffer) => match self.bulk_in.transfer_read(buffer)? { - PortTransferStatus { kind, bytes_transferred } => match kind { + PortTransferStatus { + kind, + bytes_transferred, + } => match kind { PortTransferStatusKind::Success => None, PortTransferStatusKind::ShortPacket => { - println!("received short packet (len {}) when transferring data", bytes_transferred); + println!( + "received short packet (len {}) when transferring data", + bytes_transferred + ); NonZeroU32::new(bytes_transferred) } PortTransferStatusKind::Stalled => { @@ -230,13 +257,19 @@ impl<'a> Protocol for BulkOnlyTransport<'a> { )), )); } - } - } + }, + }, DeviceReqData::Out(buffer) => match self.bulk_out.transfer_write(buffer)? { - PortTransferStatus { kind, bytes_transferred } => match kind { + PortTransferStatus { + kind, + bytes_transferred, + } => match kind { PortTransferStatusKind::Success => None, PortTransferStatusKind::ShortPacket => { - println!("received short packet (len {}) when transferring data", bytes_transferred); + println!( + "received short packet (len {}) when transferring data", + bytes_transferred + ); NonZeroU32::new(bytes_transferred) } PortTransferStatusKind::Stalled => { @@ -245,10 +278,12 @@ impl<'a> Protocol for BulkOnlyTransport<'a> { } PortTransferStatusKind::Unknown => { return Err(ProtocolError::XhciError( - XhciClientHandleError::InvalidResponse(Invalid("unknown transfer status")), + XhciClientHandleError::InvalidResponse(Invalid( + "unknown transfer status", + )), )); } - } + }, }, DeviceReqData::NoData => None, }; @@ -266,10 +301,16 @@ impl<'a> Protocol for BulkOnlyTransport<'a> { if !csw.is_valid() || csw.tag != cbw.tag { println!("Invald CSW {:?} (for CBW {:?})", csw, cbw); self.reset_recovery()?; - if self.bulk_in.status()? == EndpointStatus::Halted || self.bulk_out.status()? == EndpointStatus::Halted { - return Err(ProtocolError::ProtocolError("Reset Recovery didn't reset endpoints")); + if self.bulk_in.status()? == EndpointStatus::Halted + || self.bulk_out.status()? == EndpointStatus::Halted + { + return Err(ProtocolError::ProtocolError( + "Reset Recovery didn't reset endpoints", + )); } - return Err(ProtocolError::ProtocolError("CSW invalid, but a recover was successful")); + return Err(ProtocolError::ProtocolError( + "CSW invalid, but a recover was successful", + )); } /*if self.bulk_in.status()? == EndpointStatus::Halted diff --git a/storage/usbscsid/src/scheme.rs b/storage/usbscsid/src/scheme.rs index a175780958..ed89dd2254 100644 --- a/storage/usbscsid/src/scheme.rs +++ b/storage/usbscsid/src/scheme.rs @@ -47,8 +47,7 @@ impl SchemeMut for ScsiScheme<'_> { if flags & O_DIRECTORY != 0 && flags & O_STAT == 0 { return Err(Error::new(EACCES)); } - let path_str = path_str - .trim_start_matches('/'); + let path_str = path_str.trim_start_matches('/'); let handle = if path_str.is_empty() { // List Handle::List @@ -60,7 +59,10 @@ impl SchemeMut for ScsiScheme<'_> { }; self.next_fd += 1; self.handles.insert(self.next_fd, handle); - Ok(OpenResult::ThisScheme { number: self.next_fd, flags: NewFdFlags::POSITIONED }) + Ok(OpenResult::ThisScheme { + number: self.next_fd, + flags: NewFdFlags::POSITIONED, + }) } fn fstat(&mut self, fd: usize, stat: &mut syscall::Stat) -> Result { match self.handles.get(&fd).ok_or(Error::new(EBADF))? { @@ -111,7 +113,10 @@ impl SchemeMut for ScsiScheme<'_> { } } Handle::List => { - let src = usize::try_from(offset).ok().and_then(|o| LIST_CONTENTS.get(o..)).unwrap_or(&[]); + let src = usize::try_from(offset) + .ok() + .and_then(|o| LIST_CONTENTS.get(o..)) + .unwrap_or(&[]); let min = core::cmp::min(src.len(), buf.len()); buf[..min].copy_from_slice(&src[..min]); diff --git a/storage/usbscsid/src/scsi/cmds.rs b/storage/usbscsid/src/scsi/cmds.rs index 8eb58a0cb6..3868f57eae 100644 --- a/storage/usbscsid/src/scsi/cmds.rs +++ b/storage/usbscsid/src/scsi/cmds.rs @@ -1,6 +1,6 @@ use super::opcodes::Opcode; -use std::{fmt, mem, slice}; use std::convert::TryInto; +use std::{fmt, mem, slice}; #[repr(packed)] pub struct Inquiry { @@ -517,7 +517,7 @@ impl<'a> Iterator for ModePageIterRaw<'a> { #[derive(Clone, Copy, Debug)] pub enum AnyModePage<'a> { RwErrorRecovery(&'a RwErrorRecoveryPage), - Caching(&'a CachingModePage) + Caching(&'a CachingModePage), } struct ModePageIter<'a> { @@ -540,9 +540,7 @@ impl<'a> Iterator for ModePageIter<'a> { plain::from_bytes(next_buf).ok()?, )) } else if page_code == 0x08 { - Some(AnyModePage::Caching( - plain::from_bytes(next_buf).ok()?, - )) + Some(AnyModePage::Caching(plain::from_bytes(next_buf).ok()?)) } else { println!("Unimplemented sub_page {}", base64::encode(next_buf)); None diff --git a/storage/usbscsid/src/scsi/mod.rs b/storage/usbscsid/src/scsi/mod.rs index ad818421a9..b5741fbd81 100644 --- a/storage/usbscsid/src/scsi/mod.rs +++ b/storage/usbscsid/src/scsi/mod.rs @@ -56,7 +56,7 @@ impl Scsi { let max_inquiry_len = this.get_inquiry_alloc_len(protocol)?; // Get the Standard Inquiry Data. this.get_standard_inquiry_data(protocol, max_inquiry_len)?; - + let version = this.res_standard_inquiry_data().version(); println!("Inquiry version: {}", version); @@ -89,50 +89,52 @@ impl Scsi { let standard_inquiry_data = self.res_standard_inquiry_data(); Ok(4 + u16::from(standard_inquiry_data.additional_len)) } - pub fn get_standard_inquiry_data(&mut self, protocol: &mut dyn Protocol, max_inquiry_len: u16) -> Result<()> { + pub fn get_standard_inquiry_data( + &mut self, + protocol: &mut dyn Protocol, + max_inquiry_len: u16, + ) -> Result<()> { let inquiry = self.cmd_inquiry(); *inquiry = cmds::Inquiry::new(false, 0, max_inquiry_len, 0); - protocol - .send_command( - &self.command_buffer[..INQUIRY_CMD_LEN as usize], - DeviceReqData::In(&mut self.inquiry_buffer[..max_inquiry_len as usize]), - )?; + protocol.send_command( + &self.command_buffer[..INQUIRY_CMD_LEN as usize], + DeviceReqData::In(&mut self.inquiry_buffer[..max_inquiry_len as usize]), + )?; Ok(()) } pub fn get_ff_sense(&mut self, protocol: &mut dyn Protocol, alloc_len: u8) -> Result<()> { let request_sense = self.cmd_request_sense(); *request_sense = cmds::RequestSense::new(false, alloc_len, 0); self.data_buffer.resize(alloc_len.into(), 0); - protocol - .send_command( - &self.command_buffer[..REQUEST_SENSE_CMD_LEN as usize], - DeviceReqData::In(&mut self.data_buffer[..alloc_len as usize]), - )?; + protocol.send_command( + &self.command_buffer[..REQUEST_SENSE_CMD_LEN as usize], + DeviceReqData::In(&mut self.data_buffer[..alloc_len as usize]), + )?; Ok(()) } - pub fn read_capacity(&mut self, protocol: &mut dyn Protocol) -> Result<&cmds::ReadCapacity10ParamData> { + pub fn read_capacity( + &mut self, + protocol: &mut dyn Protocol, + ) -> Result<&cmds::ReadCapacity10ParamData> { // The spec explicitly states that the allocation length is 8 bytes. let read_capacity10 = self.cmd_read_capacity10(); *read_capacity10 = cmds::ReadCapacity10::new(0); self.data_buffer.resize(10usize, 0u8); - protocol - .send_command( - &self.command_buffer[..10], - DeviceReqData::In(&mut self.data_buffer[..8]), - )?; + protocol.send_command( + &self.command_buffer[..10], + DeviceReqData::In(&mut self.data_buffer[..8]), + )?; Ok(self.res_read_capacity10()) } pub fn get_mode_sense10( &mut self, protocol: &mut dyn Protocol, - ) -> Result< - ( - &cmds::ModeParamHeader10, - BlkDescSlice, - impl Iterator, - ) - > { + ) -> Result<( + &cmds::ModeParamHeader10, + BlkDescSlice, + impl Iterator, + )> { let initial_alloc_len = mem::size_of::() as u16; // covers both mode_data_len and blk_desc_len. let mode_sense10 = self.cmd_mode_sense10(); *mode_sense10 = cmds::ModeSense10::get_block_desc(initial_alloc_len, 0); @@ -149,9 +151,7 @@ impl Scsi { panic!("{:?}", self.res_ff_sense_data()); } - let optimal_alloc_len = - self.res_mode_param_header10().mode_data_len() - + 2; // the length of the mode data field itself + let optimal_alloc_len = self.res_mode_param_header10().mode_data_len() + 2; // the length of the mode data field itself let mode_sense10 = self.cmd_mode_sense10(); *mode_sense10 = cmds::ModeSense10::get_block_desc(optimal_alloc_len, 0); @@ -278,12 +278,7 @@ impl Scsi { buffer[..bytes_to_read].copy_from_slice(&self.data_buffer[..bytes_to_read]); Ok(status.bytes_transferred(bytes_to_read as u32)) } - pub fn write( - &mut self, - protocol: &mut dyn Protocol, - lba: u64, - buffer: &[u8], - ) -> Result { + pub fn write(&mut self, protocol: &mut dyn Protocol, lba: u64, buffer: &[u8]) -> Result { let blocks_to_write = buffer.len() as u64 / u64::from(self.block_size); let bytes_to_write = blocks_to_write as usize * self.block_size as usize; let transfer_len = u32::try_from(blocks_to_write).or(Err(ScsiError::Overflow( diff --git a/storage/virtio-blkd/src/main.rs b/storage/virtio-blkd/src/main.rs index 7fa906f017..df5cda91a5 100644 --- a/storage/virtio-blkd/src/main.rs +++ b/storage/virtio-blkd/src/main.rs @@ -154,12 +154,22 @@ fn deamon(deamon: redox_daemon::Daemon) -> anyhow::Result<()> { deamon.ready().expect("virtio-blkd: failed to deamonize"); loop { - let req = match socket_fd.next_request(SignalBehavior::Restart) - .expect("virtio-blkd: failed to read disk scheme") { - Some(r) => if let RequestKind::Call(c) = r.kind() { c } else { continue }, - None => break, + let req = match socket_fd + .next_request(SignalBehavior::Restart) + .expect("virtio-blkd: failed to read disk scheme") + { + Some(r) => { + if let RequestKind::Call(c) = r.kind() { + c + } else { + continue; + } + } + None => break, }; - let resp = req.handle_scheme_block_mut(&mut scheme).expect("TODO: block?"); + let resp = req + .handle_scheme_block_mut(&mut scheme) + .expect("TODO: block?"); socket_fd .write_response(resp, SignalBehavior::Restart) .expect("virtio-blkd: failed to write to disk scheme"); diff --git a/storage/virtio-blkd/src/scheme.rs b/storage/virtio-blkd/src/scheme.rs index fe24c5b813..79d116db03 100644 --- a/storage/virtio-blkd/src/scheme.rs +++ b/storage/virtio-blkd/src/scheme.rs @@ -14,8 +14,8 @@ use partitionlib::PartitionTable; use redox_scheme::CallerCtx; use redox_scheme::OpenResult; use redox_scheme::SchemeBlockMut; -use syscall::flag::*; use syscall::error::*; +use syscall::flag::*; use syscall::schemev2::NewFdFlags; use virtio_core::spec::{Buffer, ChainBuilder, DescriptorFlags}; use virtio_core::transport::Queue; @@ -40,7 +40,11 @@ impl BlkExtension for Queue<'_> { }) .unwrap(); - let result = unsafe { Dma::<[u8]>::zeroed_slice(target.len()).unwrap().assume_init() }; + let result = unsafe { + Dma::<[u8]>::zeroed_slice(target.len()) + .unwrap() + .assume_init() + }; let status = Dma::new(u8::MAX).unwrap(); let chain = ChainBuilder::new() @@ -65,7 +69,11 @@ impl BlkExtension for Queue<'_> { }) .unwrap(); - let mut result = unsafe { Dma::<[u8]>::zeroed_slice(target.len()).unwrap().assume_init() }; + let mut result = unsafe { + Dma::<[u8]>::zeroed_slice(target.len()) + .unwrap() + .assume_init() + }; result.copy_from_slice(target.as_ref()); let status = Dma::new(u8::MAX).unwrap(); @@ -122,30 +130,31 @@ impl<'a> DiskScheme<'a> { impl<'a, 'b> Read for VirtioShim<'a, 'b> { fn read(&mut self, buf: &mut [u8]) -> IoResult { - let read_block = |block: u64, block_bytes: &mut [u8]| -> Result<(), std::io::Error> { - let req = Dma::new(BlockVirtRequest { - ty: BlockRequestTy::In, - reserved: 0, - sector: block, - }) - .unwrap(); + let read_block = + |block: u64, block_bytes: &mut [u8]| -> Result<(), std::io::Error> { + let req = Dma::new(BlockVirtRequest { + ty: BlockRequestTy::In, + reserved: 0, + sector: block, + }) + .unwrap(); - let result = Dma::new([0u8; 512]).unwrap(); - let status = Dma::new(u8::MAX).unwrap(); + let result = Dma::new([0u8; 512]).unwrap(); + let status = Dma::new(u8::MAX).unwrap(); - let chain = ChainBuilder::new() - .chain(Buffer::new(&req)) - .chain(Buffer::new(&result).flags(DescriptorFlags::WRITE_ONLY)) - .chain(Buffer::new(&status).flags(DescriptorFlags::WRITE_ONLY)) - .build(); + let chain = ChainBuilder::new() + .chain(Buffer::new(&req)) + .chain(Buffer::new(&result).flags(DescriptorFlags::WRITE_ONLY)) + .chain(Buffer::new(&status).flags(DescriptorFlags::WRITE_ONLY)) + .build(); - futures::executor::block_on(self.scheme.queue.send(chain)); - assert_eq!(*status, 0); + futures::executor::block_on(self.scheme.queue.send(chain)); + assert_eq!(*status, 0); - let size = core::cmp::min(block_bytes.len(), result.len()); - block_bytes[..size].copy_from_slice(&result.as_slice()[..size]); - Ok(()) - }; + let size = core::cmp::min(block_bytes.len(), result.len()); + block_bytes[..size].copy_from_slice(&result.as_slice()[..size]); + Ok(()) + }; let bytes_read = driver_block::block_read(self.offset, 512, buf, self.block_bytes, read_block) @@ -224,7 +233,10 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> { }, ); - Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) + Ok(Some(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::POSITIONED, + })) } else { return Err(syscall::Error::new(EISDIR)); } @@ -242,14 +254,13 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> { let id = self.next_id; self.next_id += 1; - self.handles.insert( - id, - Handle::Partition { - number: part_num, - }, - ); + self.handles + .insert(id, Handle::Partition { number: part_num }); - Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) + Ok(Some(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::POSITIONED, + })) } else { let nsid = path_str.parse::().unwrap(); assert_eq!(nsid, 0); @@ -257,94 +268,110 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> { let id = self.next_id; self.next_id += 1; self.handles.insert(id, Handle::Disk); - Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED })) + Ok(Some(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::POSITIONED, + })) } } - fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> syscall::Result> { - Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List { - ref mut entries, - } => { - let src = usize::try_from(offset).ok().and_then(|o| entries.get(o..)).unwrap_or(&[]); - let count = core::cmp::min(src.len(), buf.len()); - buf[..count].copy_from_slice(&src[..count]); - count - } + fn read( + &mut self, + id: usize, + buf: &mut [u8], + offset: u64, + _fcntl_flags: u32, + ) -> syscall::Result> { + Ok(Some( + match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { + Handle::List { ref mut entries } => { + let src = usize::try_from(offset) + .ok() + .and_then(|o| entries.get(o..)) + .unwrap_or(&[]); + let count = core::cmp::min(src.len(), buf.len()); + buf[..count].copy_from_slice(&src[..count]); + count + } - Handle::Partition { - number, - } => { - let part_table = self.part_table.as_ref().unwrap(); - let part = part_table - .partitions - .get(number as usize) - .ok_or(Error::new(EBADF))?; + Handle::Partition { number } => { + let part_table = self.part_table.as_ref().unwrap(); + let part = part_table + .partitions + .get(number as usize) + .ok_or(Error::new(EBADF))?; - // Get the offset in sectors. - let rel_block = offset / BLK_SIZE; - // if rel_block >= part.size { - // return Err(Error::new(EOVERFLOW)); - // } + // Get the offset in sectors. + let rel_block = offset / BLK_SIZE; + // if rel_block >= part.size { + // return Err(Error::new(EOVERFLOW)); + // } - let abs_block = part.start_lba + rel_block; + let abs_block = part.start_lba + rel_block; - futures::executor::block_on(self.queue.read(abs_block, buf)) - } + futures::executor::block_on(self.queue.read(abs_block, buf)) + } - Handle::Disk => { - let block_size = self.cfg.block_size(); + Handle::Disk => { + let block_size = self.cfg.block_size(); - futures::executor::block_on( - self.queue.read(offset / u64::from(block_size), buf), - ) - } - })) + futures::executor::block_on( + self.queue.read(offset / u64::from(block_size), buf), + ) + } + }, + )) } - fn write(&mut self, id: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> syscall::Result> { - Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::Disk => { - let block_size = self.cfg.block_size(); - futures::executor::block_on( - self.queue.write(offset / u64::from(block_size), buf), - ) - } + fn write( + &mut self, + id: usize, + buf: &[u8], + offset: u64, + _fcntl_flags: u32, + ) -> syscall::Result> { + Ok(Some( + match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { + Handle::Disk => { + let block_size = self.cfg.block_size(); + futures::executor::block_on( + self.queue.write(offset / u64::from(block_size), buf), + ) + } - _ => todo!(), - })) + _ => todo!(), + }, + )) } fn fsize(&mut self, id: usize) -> syscall::Result> { - Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::List { - ref entries, - } => { - let len = entries.len() as u64; - log::debug!("list: part_len={len:?}"); + Ok(Some( + match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? { + Handle::List { ref entries } => { + let len = entries.len() as u64; + log::debug!("list: part_len={len:?}"); - len - } + len + } - Handle::Partition { - number, - } => { - let part_table = self.part_table.as_ref().unwrap(); - let part = part_table - .partitions - .get(number as usize) - .ok_or(Error::new(EBADF))?; + Handle::Partition { number } => { + let part_table = self.part_table.as_ref().unwrap(); + let part = part_table + .partitions + .get(number as usize) + .ok_or(Error::new(EBADF))?; - // Partition size in bytes. - let len = part.size * BLK_SIZE; + // Partition size in bytes. + let len = part.size * BLK_SIZE; - log::debug!("part: part_len={len:?}"); + log::debug!("part: part_len={len:?}"); - len - } + len + } - Handle::Disk => self.cfg.capacity() * u64::from(self.cfg.block_size()), - })) + Handle::Disk => self.cfg.capacity() * u64::from(self.cfg.block_size()), + }, + )) } fn fpath(&mut self, _id: usize, _buf: &mut [u8]) -> syscall::Result> { diff --git a/usbhidd/src/main.rs b/usbhidd/src/main.rs index d63840715f..f34b0f692d 100644 --- a/usbhidd/src/main.rs +++ b/usbhidd/src/main.rs @@ -9,7 +9,9 @@ use rehid::{ report_handler::ReportHandler, usage_tables::{GenericDesktopUsage, UsagePage}, }; -use xhcid_interface::{ConfigureEndpointsReq, DevDesc, EndpDirection, EndpointTy, PortReqRecipient, XhciClientHandle}; +use xhcid_interface::{ + ConfigureEndpointsReq, DevDesc, EndpDirection, EndpointTy, PortReqRecipient, XhciClientHandle, +}; mod keymap; mod reqs; @@ -203,36 +205,36 @@ fn main() { .expect("Failed to get standard descriptors"); log::info!("{:X?}", desc); - let (conf_desc, conf_num, (if_desc, endpoint_num_opt, hid_desc)) = desc - .config_descs - .iter() - .enumerate() - .find_map(|(conf_num, conf_desc)| { - let if_desc = conf_desc.interface_descs.iter().find_map(|if_desc| { - if if_desc.number == interface_num { - let endpoint_num_opt = if_desc.endpoints.iter().enumerate().find_map(|(endpoint_i, endpoint)| { - if endpoint.ty() == EndpointTy::Interrupt && endpoint.direction() == EndpDirection::In { - Some(endpoint_i + 1) - } else { - None - } - }); - let hid_desc = if_desc.hid_descs.iter().find_map(|hid_desc| { - //TODO: should we do any filtering? - Some(hid_desc) - })?; - Some((if_desc.clone(), endpoint_num_opt, hid_desc)) - } else { - None - } - })?; - Some(( - conf_desc.clone(), - conf_num, - if_desc, - )) - }) - .expect("Failed to find suitable configuration"); + let (conf_desc, conf_num, (if_desc, endpoint_num_opt, hid_desc)) = + desc.config_descs + .iter() + .enumerate() + .find_map(|(conf_num, conf_desc)| { + let if_desc = conf_desc.interface_descs.iter().find_map(|if_desc| { + if if_desc.number == interface_num { + let endpoint_num_opt = if_desc.endpoints.iter().enumerate().find_map( + |(endpoint_i, endpoint)| { + if endpoint.ty() == EndpointTy::Interrupt + && endpoint.direction() == EndpDirection::In + { + Some(endpoint_i + 1) + } else { + None + } + }, + ); + let hid_desc = if_desc.hid_descs.iter().find_map(|hid_desc| { + //TODO: should we do any filtering? + Some(hid_desc) + })?; + Some((if_desc.clone(), endpoint_num_opt, hid_desc)) + } else { + None + } + })?; + Some((conf_desc.clone(), conf_num, if_desc)) + }) + .expect("Failed to find suitable configuration"); handle .configure_endpoints(&ConfigureEndpointsReq { @@ -292,7 +294,9 @@ fn main() { if let Some(endpoint) = &mut endpoint_opt { // interrupt transfer - endpoint.transfer_read(&mut report_buffer).expect("failed to get report"); + endpoint + .transfer_read(&mut report_buffer) + .expect("failed to get report"); } else { // control transfer reqs::get_report( @@ -419,10 +423,7 @@ fn main() { } if scroll_y != 0 { - let scroll_event = orbclient::event::ScrollEvent { - x: 0, - y: scroll_y, - }; + let scroll_event = orbclient::event::ScrollEvent { x: 0, y: scroll_y }; match display.write(&scroll_event.to_event()) { Ok(_) => (), diff --git a/usbhubd/src/main.rs b/usbhubd/src/main.rs index a3f5521310..2f32ba8c70 100644 --- a/usbhubd/src/main.rs +++ b/usbhubd/src/main.rs @@ -3,7 +3,10 @@ use std::env; use std::fs::File; use std::io::{Read, Write}; -use xhcid_interface::{plain, usb, ConfigureEndpointsReq, DevDesc, DeviceReqData, EndpDirection, EndpointTy, PortReqRecipient, PortReqTy, XhciClientHandle}; +use xhcid_interface::{ + plain, usb, ConfigureEndpointsReq, DevDesc, DeviceReqData, EndpDirection, EndpointTy, + PortReqRecipient, PortReqTy, XhciClientHandle, +}; fn main() { common::setup_logging( @@ -55,11 +58,7 @@ fn main() { None } })?; - Some(( - conf_desc.clone(), - conf_num, - if_desc, - )) + Some((conf_desc.clone(), conf_num, if_desc)) }) .expect("Failed to find suitable configuration"); diff --git a/vboxd/src/bga.rs b/vboxd/src/bga.rs index d9fe280100..264c9c568c 100644 --- a/vboxd/src/bga.rs +++ b/vboxd/src/bga.rs @@ -43,4 +43,4 @@ impl Bga { self.write(BGA_INDEX_BPP, 32); self.write(BGA_INDEX_ENABLE, 0x41); } -} \ No newline at end of file +} diff --git a/vboxd/src/main.rs b/vboxd/src/main.rs index 8a50ccce82..4c29c5260a 100644 --- a/vboxd/src/main.rs +++ b/vboxd/src/main.rs @@ -1,14 +1,14 @@ //#![deny(warnings)] use event::{user_data, EventQueue}; -use std::{iter, mem}; -use std::os::unix::io::AsRawFd; use std::fs::File; -use std::io::{Result, Read, Write}; +use std::io::{Read, Result, Write}; +use std::os::unix::io::AsRawFd; +use std::{iter, mem}; +use common::io::{Io, Mmio, Pio}; use pcid_interface::{PciBar, PciFunctionHandle}; use syscall::flag::EventFlags; -use common::io::{Io, Mmio, Pio}; use common::dma::Dma; @@ -56,7 +56,9 @@ struct VboxGetMouse { } impl VboxGetMouse { - fn request() -> u32 { 1 } + fn request() -> u32 { + 1 + } fn new() -> syscall::Result> { let mut packet = unsafe { Dma::::zeroed()?.assume_init() }; @@ -79,7 +81,9 @@ struct VboxSetMouse { } impl VboxSetMouse { - fn request() -> u32 { 2 } + fn request() -> u32 { + 2 + } fn new() -> syscall::Result> { let mut packet = unsafe { Dma::::zeroed()?.assume_init() }; @@ -100,7 +104,9 @@ struct VboxAckEvents { } impl VboxAckEvents { - fn request() -> u32 { 41 } + fn request() -> u32 { + 41 + } fn new() -> syscall::Result> { let mut packet = unsafe { Dma::::zeroed()?.assume_init() }; @@ -121,7 +127,9 @@ struct VboxGuestCaps { } impl VboxGuestCaps { - fn request() -> u32 { 55 } + fn request() -> u32 { + 55 + } fn new() -> syscall::Result> { let mut packet = unsafe { Dma::::zeroed()?.assume_init() }; @@ -144,7 +152,9 @@ struct VboxDisplayChange { } impl VboxDisplayChange { - fn request() -> u32 { 51 } + fn request() -> u32 { + 51 + } fn new() -> syscall::Result> { let mut packet = unsafe { Dma::::zeroed()?.assume_init() }; @@ -166,7 +176,9 @@ struct VboxGuestInfo { } impl VboxGuestInfo { - fn request() -> u32 { 50 } + fn request() -> u32 { + 50 + } fn new() -> syscall::Result> { let mut packet = unsafe { Dma::::zeroed()?.assume_init() }; @@ -189,7 +201,10 @@ fn main() { let bar0 = pci_config.func.bars[0].expect_port(); - let irq = pci_config.func.legacy_interrupt_line.expect("vboxd: no legacy interrupts supported"); + let irq = pci_config + .func + .legacy_interrupt_line + .expect("vboxd: no legacy interrupts supported"); println!(" + VirtualBox {}", pci_config.func.display()); @@ -205,15 +220,28 @@ fn main() { if let Ok(count) = libredox::call::fpath(display.as_raw_fd() as usize, &mut buf) { let path = unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) }; let res = path.split(":").nth(1).unwrap_or(""); - width = res.split("/").nth(1).unwrap_or("").parse::().unwrap_or(0); - height = res.split("/").nth(2).unwrap_or("").parse::().unwrap_or(0); + width = res + .split("/") + .nth(1) + .unwrap_or("") + .parse::() + .unwrap_or(0); + height = res + .split("/") + .nth(2) + .unwrap_or("") + .parse::() + .unwrap_or(0); } } let mut irq_file = irq.irq_handle("vboxd"); let mut port = Pio::::new(bar0 as u16); - let address = unsafe { pcid_handle.map_bar(1) }.expect("vboxd").ptr.as_ptr(); + let address = unsafe { pcid_handle.map_bar(1) } + .expect("vboxd") + .ptr + .as_ptr(); { let vmmdev = unsafe { &mut *(address as *mut VboxVmmDev) }; @@ -230,7 +258,9 @@ fn main() { set_mouse.features.write(1 << 4 | 1); port.write(set_mouse.physical() as u32); - vmmdev.guest_events.write(VBOX_EVENT_DISPLAY | VBOX_EVENT_MOUSE); + vmmdev + .guest_events + .write(VBOX_EVENT_DISPLAY | VBOX_EVENT_MOUSE); user_data! { enum Source { @@ -238,8 +268,15 @@ fn main() { } } - let event_queue = EventQueue::::new().expect("vboxd: Could not create event queue."); - event_queue.subscribe(irq_file.as_raw_fd() as usize, Source::Irq, event::EventFlags::READ).unwrap(); + let event_queue = + EventQueue::::new().expect("vboxd: Could not create event queue."); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); daemon.ready().expect("failed to signal readiness"); @@ -247,10 +284,13 @@ fn main() { let mut bga = Bga::new(); let get_mouse = VboxGetMouse::new().expect("vboxd: failed to map GetMouse"); - let display_change = VboxDisplayChange::new().expect("vboxd: failed to map DisplayChange"); + let display_change = + VboxDisplayChange::new().expect("vboxd: failed to map DisplayChange"); let ack_events = VboxAckEvents::new().expect("vboxd: failed to map AckEvents"); - for Source::Irq in iter::once(Source::Irq).chain(event_queue.map(|e| e.expect("vboxd: failed to get next event").user_data)) { + for Source::Irq in iter::once(Source::Irq) + .chain(event_queue.map(|e| e.expect("vboxd: failed to get next event").user_data)) + { let mut irq = [0; 8]; if irq_file.read(&mut irq).unwrap() >= irq.len() { let host_events = vmmdev.host_events.read(); @@ -268,10 +308,9 @@ fn main() { height = new_height; println!("Display {}, {}", width, height); bga.set_size(width as u16, height as u16); - let _ = display.write(&orbclient::ResizeEvent { - width, - height, - }.to_event()); + let _ = display.write( + &orbclient::ResizeEvent { width, height }.to_event(), + ); } } } @@ -281,10 +320,13 @@ fn main() { if let Some(ref mut display) = display_opt { let x = get_mouse.x.read() * width / 0x10000; let y = get_mouse.y.read() * height / 0x10000; - let _ = display.write(&orbclient::MouseEvent { - x: x as i32, - y: y as i32, - }.to_event()); + let _ = display.write( + &orbclient::MouseEvent { + x: x as i32, + y: y as i32, + } + .to_event(), + ); } } } @@ -293,5 +335,6 @@ fn main() { } std::process::exit(0); - }).expect("vboxd: failed to daemonize"); + }) + .expect("vboxd: failed to daemonize"); } diff --git a/xhcid/src/main.rs b/xhcid/src/main.rs index e117f2a867..dc280e6636 100644 --- a/xhcid/src/main.rs +++ b/xhcid/src/main.rs @@ -45,11 +45,11 @@ use pcid_interface::{ MsiSetFeatureInfo, PciFeature, PciFeatureInfo, PciFunctionHandle, SetFeatureInfo, }; +use common::io::Io; use event::{Event, RawEventQueue}; use syscall::data::Packet; use syscall::error::EWOULDBLOCK; use syscall::flag::EventFlags; -use common::io::Io; use syscall::scheme::Scheme; use crate::xhci::{InterruptMethod, Xhci}; diff --git a/xhcid/src/xhci/context.rs b/xhcid/src/xhci/context.rs index 932fe6f202..a866886800 100644 --- a/xhcid/src/xhci/context.rs +++ b/xhcid/src/xhci/context.rs @@ -1,8 +1,8 @@ use std::collections::BTreeMap; +use common::io::{Io, Mmio}; use log::debug; use syscall::error::Result; -use common::io::{Io, Mmio}; use syscall::PAGE_SIZE; use common::dma::Dma; diff --git a/xhcid/src/xhci/event.rs b/xhcid/src/xhci/event.rs index f2da331a95..13bdeff7d1 100644 --- a/xhcid/src/xhci/event.rs +++ b/xhcid/src/xhci/event.rs @@ -1,5 +1,5 @@ -use syscall::error::Result; use common::io::{Io, Mmio}; +use syscall::error::Result; use common::dma::Dma; diff --git a/xhcid/src/xhci/extended.rs b/xhcid/src/xhci/extended.rs index 1f8115b7e5..2ef900cf41 100644 --- a/xhcid/src/xhci/extended.rs +++ b/xhcid/src/xhci/extended.rs @@ -1,7 +1,7 @@ +use common::io::{Io, Mmio}; use std::ops::Range; use std::ptr::NonNull; use std::{fmt, mem, ptr, slice}; -use common::io::{Io, Mmio}; pub struct ExtendedCapabilitiesIter { base: *const u8, diff --git a/xhcid/src/xhci/mod.rs b/xhcid/src/xhci/mod.rs index a0a72f296a..5a2d17f2be 100644 --- a/xhcid/src/xhci/mod.rs +++ b/xhcid/src/xhci/mod.rs @@ -20,8 +20,8 @@ use std::sync::{Arc, Mutex, MutexGuard, Weak}; use std::{mem, process, slice, sync::atomic, task, thread}; -use syscall::error::{Error, Result, EBADF, EBADMSG, EIO, ENOENT}; use common::io::Io; +use syscall::error::{Error, Result, EBADF, EBADMSG, EIO, ENOENT}; use syscall::PAGE_SIZE; use chashmap::CHashMap; diff --git a/xhcid/src/xhci/operational.rs b/xhcid/src/xhci/operational.rs index 42918c922c..cfe1dc5878 100644 --- a/xhcid/src/xhci/operational.rs +++ b/xhcid/src/xhci/operational.rs @@ -1,6 +1,6 @@ +use common::io::{Io, Mmio}; use std::num::NonZeroU8; use std::slice; -use common::io::{Io, Mmio}; use super::CapabilityRegs; diff --git a/xhcid/src/xhci/scheme.rs b/xhcid/src/xhci/scheme.rs index 47914b8769..dd011c9736 100644 --- a/xhcid/src/xhci/scheme.rs +++ b/xhcid/src/xhci/scheme.rs @@ -67,8 +67,9 @@ lazy_static! { .expect("Failed to create the regex for the port/request scheme"); static ref REGEX_PORT_ENDPOINTS: Regex = Regex::new(r"^port(\d{1,3})/endpoints$") .expect("Failed to create the regex for the port/endpoints scheme"); - static ref REGEX_PORT_SPECIFIC_ENDPOINT: Regex = Regex::new(r"^port(\d{1,3})/endpoints/(\d{1,3})$") - .expect("Failed to create the regex for the port/endpoints/ scheme"); + static ref REGEX_PORT_SPECIFIC_ENDPOINT: Regex = + Regex::new(r"^port(\d{1,3})/endpoints/(\d{1,3})$") + .expect("Failed to create the regex for the port/endpoints/ scheme"); static ref REGEX_PORT_SUB_ENDPOINT: Regex = Regex::new( r"port(\d{1,3})/endpoints/(\d{1,3})/(ctl|data)$" ) @@ -352,33 +353,27 @@ impl SchemeParameters { Ok(Self::ConfigureEndpoints(port_num)) } else if REGEX_PORT_DESCRIPTORS.is_match(scheme) { - let port_num = get_usize_from_regex(®EX_PORT_DESCRIPTORS, scheme, 0)?; Ok(Self::PortDesc(port_num)) } else if REGEX_PORT_STATE.is_match(scheme) { - let port_num = get_usize_from_regex(®EX_PORT_STATE, scheme, 0)?; Ok(Self::PortState(port_num)) } else if REGEX_PORT_REQUEST.is_match(scheme) { - let port_num = get_usize_from_regex(®EX_PORT_REQUEST, scheme, 0)?; Ok(Self::PortReq(port_num)) } else if REGEX_PORT_ENDPOINTS.is_match(scheme) { - let port_num = get_usize_from_regex(®EX_PORT_ENDPOINTS, scheme, 0)?; Ok(Self::Endpoints(port_num)) } else if REGEX_PORT_SPECIFIC_ENDPOINT.is_match(scheme) { - let port_num = get_usize_from_regex(®EX_PORT_SPECIFIC_ENDPOINT, scheme, 0)?; let endpoint_num = get_u8_from_regex(®EX_PORT_SPECIFIC_ENDPOINT, scheme, 1)?; Ok(Self::Endpoint(port_num, endpoint_num, String::from("root"))) } else if REGEX_PORT_SUB_ENDPOINT.is_match(scheme) { - let port_num = get_usize_from_regex(®EX_PORT_SUB_ENDPOINT, scheme, 0)?; let endpoint_num = get_u8_from_regex(®EX_PORT_SUB_ENDPOINT, scheme, 1)?; let handle_type = get_string_from_regex(®EX_PORT_SUB_ENDPOINT, scheme, 2)?; diff --git a/xhcid/src/xhci/trb.rs b/xhcid/src/xhci/trb.rs index f30443a5f4..0705468d14 100644 --- a/xhcid/src/xhci/trb.rs +++ b/xhcid/src/xhci/trb.rs @@ -1,6 +1,6 @@ use crate::usb; -use std::{fmt, mem}; use common::io::{Io, Mmio}; +use std::{fmt, mem}; use super::context::StreamContextType;