struct buf*
bread(uint dev, uint sector)
{
- void *c;
struct buf *b;
- extern struct spinlock ide_lock;
b = bget(dev, sector);
if(b->flags & B_VALID)
return b;
- acquire(&ide_lock);
- c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1);
- sleep(c, &ide_lock);
- ide_finish(c);
+ ide_rw(dev & 0xff, sector, b->data, 1, 1);
b->flags |= B_VALID;
- release(&ide_lock);
return b;
}
// Write buf's contents to disk.
+// Must be locked.
void
bwrite(struct buf *b, uint sector)
{
- void *c;
- extern struct spinlock ide_lock;
+ if((b->flags & B_BUSY) == 0)
+ panic("bwrite");
- acquire(&ide_lock);
- c = ide_start_rw(b->dev & 0xff, sector, b->data, 1, 0);
- sleep(c, &ide_lock);
- ide_finish(c);
+ ide_rw(b->dev & 0xff, sector, b->data, 1, 0);
b->flags |= B_VALID;
- release(&ide_lock);
}
// Release the buffer buf.
int argstr(int, char**);
// picirq.c
-extern ushort irq_mask_8259A;
void pic_init(void);
-void irq_setmask_8259A(ushort);
+void irq_enable(int);
// 8253pit.c
void pit8253_timerinit(void);
// ide.c
void ide_init(void);
void ide_intr(void);
-void* ide_start_rw(int, uint, void*, uint, int);
-int ide_finish(void*);
+void ide_rw(int, uint, void*, uint, int);
// bio.c
void binit(void);
uint read;
};
-struct ide_request request[NREQUEST];
-int head, tail;
-struct spinlock ide_lock;
+static struct ide_request request[NREQUEST];
+static int head, tail;
+static struct spinlock ide_lock;
-int disk_1_present;
-int disk_channel;
+static int disk_1_present;
+static int disk_queue;
-int ide_probe_disk1(void);
+static int ide_probe_disk1(void);
+// Wait for IDE disk to become ready.
static int
ide_wait_ready(int check_error)
{
ide_init(void)
{
initlock(&ide_lock, "ide");
- irq_setmask_8259A(irq_mask_8259A & ~(1 << IRQ_IDE));
- ioapic_enable (IRQ_IDE, ncpu - 1);
+ irq_enable(IRQ_IDE);
+ ioapic_enable(IRQ_IDE, ncpu - 1);
ide_wait_ready(0);
disk_1_present = ide_probe_disk1();
}
+// Interrupt handler - wake up the request that just finished.
void
ide_intr(void)
{
release(&ide_lock);
}
-int
+// Probe to see if disk 1 exists (we assume disk 0 exists).
+static int
ide_probe_disk1(void)
{
int r, x;
return x < 1000;
}
-void
+// Start the next request in the queue.
+static void
ide_start_request (void)
{
struct ide_request *r;
}
}
-void*
-ide_start_rw(int diskno, uint secno, void *addr, uint nsecs, int read)
+// Run an entire disk operation.
+void
+ide_rw(int diskno, uint secno, void *addr, uint nsecs, int read)
{
struct ide_request *r;
if(diskno && !disk_1_present)
panic("ide disk 1 not present");
+ acquire(&ide_lock);
+
+ // Add request to queue.
while((head + 1) % NREQUEST == tail)
- sleep(&disk_channel, &ide_lock);
+ sleep(&disk_queue, &ide_lock);
r = &request[head];
r->secno = secno;
r->nsecs = nsecs;
r->diskno = diskno;
r->read = read;
-
head = (head + 1) % NREQUEST;
+ // Start request if necessary.
ide_start_request();
-
- return r;
-}
-
-int
-ide_finish(void *c)
-{
- int r;
- struct ide_request *req = (struct ide_request*) c;
-
- if(req->read) {
- if((r = ide_wait_ready(1)) >= 0)
- insl(0x1F0, req->addr, 512/4);
- }
-
- if((head + 1) % NREQUEST == tail) {
- wakeup(&disk_channel);
+
+ // Wait for request to finish.
+ sleep(r, &ide_lock);
+
+ // Finish request.
+ if(read){
+ if(ide_wait_ready(1) >= 0)
+ insl(0x1F0, addr, 512/4);
}
+ // Remove request from queue.
+ if((head + 1) % NREQUEST == tail)
+ wakeup(&disk_queue);
tail = (tail + 1) % NREQUEST;
- ide_start_request();
- return 0;
+ release(&ide_lock);
}
+// Synchronous disk write.
int
ide_write(int diskno, uint secno, const void *src, uint nsecs)
{