From 19297caf0d141e23fa2f5da6e2fb0ffa181d7a82 Mon Sep 17 00:00:00 2001 From: rsc Date: Thu, 7 Sep 2006 15:29:54 +0000 Subject: [PATCH] fix ide, pit interfaces --- 8253pit.c | 2 +- bio.c | 19 ++++------------ console.c | 2 +- defs.h | 6 ++--- ide.c | 68 ++++++++++++++++++++++++++++--------------------------- picirq.c | 10 ++++++-- sysfile.c | 2 +- 7 files changed, 53 insertions(+), 56 deletions(-) diff --git a/8253pit.c b/8253pit.c index 0b82e29..d94d59c 100644 --- a/8253pit.c +++ b/8253pit.c @@ -42,5 +42,5 @@ pit8253_timerinit(void) outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(IO_TIMER1, TIMER_DIV(100) % 256); outb(IO_TIMER1, TIMER_DIV(100) / 256); - irq_setmask_8259A(irq_mask_8259A & ~(1<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. diff --git a/console.c b/console.c index b2c363e..218a627 100644 --- a/console.c +++ b/console.c @@ -409,7 +409,7 @@ console_init() devsw[CONSOLE].write = console_write; devsw[CONSOLE].read = console_read; - irq_setmask_8259A(irq_mask_8259A & ~(1 << IRQ_KBD)); + irq_enable(IRQ_KBD); ioapic_enable(IRQ_KBD, 0); use_console_lock = 1; diff --git a/defs.h b/defs.h index 9babf92..0225e5d 100644 --- a/defs.h +++ b/defs.h @@ -49,9 +49,8 @@ int argptr(int, char**, int); 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); @@ -109,8 +108,7 @@ void fileincref(struct file*); // 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); diff --git a/ide.c b/ide.c index 3afd19b..ffe1b08 100644 --- a/ide.c +++ b/ide.c @@ -31,15 +31,16 @@ struct ide_request { 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) { @@ -57,12 +58,13 @@ void 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) { @@ -71,7 +73,8 @@ 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; @@ -92,7 +95,8 @@ ide_probe_disk1(void) return x < 1000; } -void +// Start the next request in the queue. +static void ide_start_request (void) { struct ide_request *r; @@ -115,16 +119,20 @@ ide_start_request (void) } } -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; @@ -132,35 +140,29 @@ ide_start_rw(int diskno, uint secno, void *addr, uint nsecs, int read) 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) { diff --git a/picirq.c b/picirq.c index eaac053..b7d0116 100644 --- a/picirq.c +++ b/picirq.c @@ -11,9 +11,9 @@ // Current IRQ mask. // Initial IRQ mask has interrupt 2 enabled (for slave 8259A). -ushort irq_mask_8259A = 0xFFFF & ~(1<> 8)); } +void +irq_enable(int irq) +{ + irq_setmask_8259A(irq_mask_8259A & ~(1<nlink += 1; + dp->nlink++; iupdate(dp); memset(de.name, '\0', DIRSIZ);