Newer
Older
#include "param.h"
#include "mmu.h"
#include "proc.h"
#include "x86.h"
#define IDE_BSY 0x80
#define IDE_DRDY 0x40
#define IDE_DF 0x20
#define IDE_ERR 0x01
#define IDE_CMD_READ 0x20
#define IDE_CMD_WRITE 0x30
// idequeue points to the buf now being read/written to the disk.
// idequeue->qnext points to the next buf to be processed.
// You must hold idelock while manipulating queue.
static struct spinlock idelock;
static struct buf *idequeue;
while(((r = inb(0x1f7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
picenable(IRQ_IDE);
ioapicenable(IRQ_IDE, ncpu - 1);
idewait(0);
// Start the request for b. Caller must hold idelock.
outb(0x3f6, 0); // generate interrupt
outb(0x1f2, 1); // number of sectors
outb(0x1f3, b->sector & 0xff);
outb(0x1f4, (b->sector >> 8) & 0xff);
outb(0x1f5, (b->sector >> 16) & 0xff);
// Take first buffer off queue.
acquire(&idelock);
if((b = idequeue) == 0){
release(&idelock);
cprintf("Spurious IDE interrupt.\n");
if(!(b->flags & B_DIRTY) && idewait(1) >= 0)
insl(0x1f0, b->data, 512/4);
// Wake process waiting for this buf.
b->flags |= B_VALID;
b->flags &= ~B_DIRTY;
// Sync buf with disk.
// If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID.
// Else if B_VALID is not set, read buf from disk, set B_VALID.
if((b->flags & (B_VALID|B_DIRTY)) == B_VALID)
while((b->flags & (B_VALID|B_DIRTY)) != B_VALID){