You need to sign in or sign up before continuing.
Newer
Older
#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(!acquired_sleeplock(&b->sleeplock))
if((b->flags & (B_VALID|B_DIRTY)) == B_VALID)
acquire(&idelock); // DOC:acquire-lock
for(pp=&idequeue; *pp; pp=&(*pp)->qnext) // DOC:insert-queue
while((b->flags & (B_VALID|B_DIRTY)) != B_VALID){