Improve ahcid interrupt handling
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use std::mem::size_of;
|
||||
use std::ops::DerefMut;
|
||||
use std::{ptr, u32, thread};
|
||||
use std::{ptr, u32};
|
||||
|
||||
use syscall::io::{Dma, Io, Mmio};
|
||||
use syscall::error::{Error, Result, EIO};
|
||||
@@ -75,7 +75,7 @@ impl HbaPort {
|
||||
|
||||
pub fn start(&mut self) {
|
||||
while self.cmd.readf(HBA_PORT_CMD_CR) {
|
||||
thread::yield_now();
|
||||
unsafe { asm!("pause"); }
|
||||
}
|
||||
|
||||
self.cmd.writef(HBA_PORT_CMD_FRE | HBA_PORT_CMD_ST, true);
|
||||
@@ -85,7 +85,7 @@ impl HbaPort {
|
||||
self.cmd.writef(HBA_PORT_CMD_ST, false);
|
||||
|
||||
while self.cmd.readf(HBA_PORT_CMD_FR | HBA_PORT_CMD_CR) {
|
||||
thread::yield_now();
|
||||
unsafe { asm!("pause"); }
|
||||
}
|
||||
|
||||
self.cmd.writef(HBA_PORT_CMD_FRE, false);
|
||||
@@ -305,7 +305,7 @@ impl HbaPort {
|
||||
}
|
||||
|
||||
while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) {
|
||||
thread::yield_now();
|
||||
unsafe { asm!("pause"); }
|
||||
}
|
||||
|
||||
self.ci.writef(1 << slot, true);
|
||||
@@ -325,7 +325,7 @@ impl HbaPort {
|
||||
|
||||
pub fn ata_stop(&mut self, slot: u32) -> Result<()> {
|
||||
while self.ata_running(slot) {
|
||||
thread::yield_now();
|
||||
unsafe { asm!("pause"); }
|
||||
}
|
||||
|
||||
self.stop();
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
//#![deny(warnings)]
|
||||
#![feature(asm)]
|
||||
|
||||
extern crate syscall;
|
||||
extern crate byteorder;
|
||||
|
||||
+14
-14
@@ -95,7 +95,7 @@ impl DiskWrapper {
|
||||
|
||||
impl std::ops::Deref for DiskWrapper {
|
||||
type Target = dyn Disk;
|
||||
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&*self.disk
|
||||
}
|
||||
@@ -128,22 +128,22 @@ impl DiskScheme {
|
||||
|
||||
impl DiskScheme {
|
||||
pub fn irq(&mut self) -> bool {
|
||||
let pi = self.hba_mem.pi.read();
|
||||
let is = self.hba_mem.is.read();
|
||||
let pi_is = pi & is;
|
||||
|
||||
for i in 0..self.hba_mem.ports.len() {
|
||||
if pi_is & 1 << i > 0 {
|
||||
let port = &mut self.hba_mem.ports[i];
|
||||
let is = port.is.read();
|
||||
//println!("IRQ Port {}: {:#>08x}", i, is);
|
||||
//TODO: Handle requests for only this port here
|
||||
port.is.write(is);
|
||||
if is > 0 {
|
||||
let pi = self.hba_mem.pi.read();
|
||||
let pi_is = pi & is;
|
||||
for i in 0..self.hba_mem.ports.len() {
|
||||
if pi_is & 1 << i > 0 {
|
||||
let port = &mut self.hba_mem.ports[i];
|
||||
let is = port.is.read();
|
||||
port.is.write(is);
|
||||
}
|
||||
}
|
||||
self.hba_mem.is.write(is);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
self.hba_mem.is.write(is);
|
||||
is != 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -764,18 +764,16 @@ impl IntelHDA {
|
||||
|
||||
pub fn handle_interrupts(&mut self) -> bool {
|
||||
let intsts = self.regs.intsts.read();
|
||||
let sis = intsts & 0x3FFFFFFF;
|
||||
//print!("IHDA INTSTS: {:08X}\n", intsts);
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user