fix ide, pit interfaces

This commit is contained in:
rsc 2006-09-07 15:29:54 +00:00
parent 6c8acf9e04
commit 19297caf0d
7 changed files with 53 additions and 56 deletions

View file

@ -42,5 +42,5 @@ pit8253_timerinit(void)
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(IO_TIMER1, TIMER_DIV(100) % 256); outb(IO_TIMER1, TIMER_DIV(100) % 256);
outb(IO_TIMER1, TIMER_DIV(100) / 256); outb(IO_TIMER1, TIMER_DIV(100) / 256);
irq_setmask_8259A(irq_mask_8259A & ~(1<<IRQ_TIMER)); irq_enable(IRQ_TIMER);
} }

19
bio.c
View file

@ -102,37 +102,28 @@ bget(uint dev, uint sector)
struct buf* struct buf*
bread(uint dev, uint sector) bread(uint dev, uint sector)
{ {
void *c;
struct buf *b; struct buf *b;
extern struct spinlock ide_lock;
b = bget(dev, sector); b = bget(dev, sector);
if(b->flags & B_VALID) if(b->flags & B_VALID)
return b; return b;
acquire(&ide_lock); ide_rw(dev & 0xff, sector, b->data, 1, 1);
c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1);
sleep(c, &ide_lock);
ide_finish(c);
b->flags |= B_VALID; b->flags |= B_VALID;
release(&ide_lock);
return b; return b;
} }
// Write buf's contents to disk. // Write buf's contents to disk.
// Must be locked.
void void
bwrite(struct buf *b, uint sector) bwrite(struct buf *b, uint sector)
{ {
void *c; if((b->flags & B_BUSY) == 0)
extern struct spinlock ide_lock; panic("bwrite");
acquire(&ide_lock); ide_rw(b->dev & 0xff, sector, b->data, 1, 0);
c = ide_start_rw(b->dev & 0xff, sector, b->data, 1, 0);
sleep(c, &ide_lock);
ide_finish(c);
b->flags |= B_VALID; b->flags |= B_VALID;
release(&ide_lock);
} }
// Release the buffer buf. // Release the buffer buf.

View file

@ -409,7 +409,7 @@ console_init()
devsw[CONSOLE].write = console_write; devsw[CONSOLE].write = console_write;
devsw[CONSOLE].read = console_read; devsw[CONSOLE].read = console_read;
irq_setmask_8259A(irq_mask_8259A & ~(1 << IRQ_KBD)); irq_enable(IRQ_KBD);
ioapic_enable(IRQ_KBD, 0); ioapic_enable(IRQ_KBD, 0);
use_console_lock = 1; use_console_lock = 1;

6
defs.h
View file

@ -49,9 +49,8 @@ int argptr(int, char**, int);
int argstr(int, char**); int argstr(int, char**);
// picirq.c // picirq.c
extern ushort irq_mask_8259A;
void pic_init(void); void pic_init(void);
void irq_setmask_8259A(ushort); void irq_enable(int);
// 8253pit.c // 8253pit.c
void pit8253_timerinit(void); void pit8253_timerinit(void);
@ -109,8 +108,7 @@ void fileincref(struct file*);
// ide.c // ide.c
void ide_init(void); void ide_init(void);
void ide_intr(void); void ide_intr(void);
void* ide_start_rw(int, uint, void*, uint, int); void ide_rw(int, uint, void*, uint, int);
int ide_finish(void*);
// bio.c // bio.c
void binit(void); void binit(void);

64
ide.c
View file

@ -31,15 +31,16 @@ struct ide_request {
uint read; uint read;
}; };
struct ide_request request[NREQUEST]; static struct ide_request request[NREQUEST];
int head, tail; static int head, tail;
struct spinlock ide_lock; static struct spinlock ide_lock;
int disk_1_present; static int disk_1_present;
int disk_channel; static int disk_queue;
int ide_probe_disk1(void); static int ide_probe_disk1(void);
// Wait for IDE disk to become ready.
static int static int
ide_wait_ready(int check_error) ide_wait_ready(int check_error)
{ {
@ -57,12 +58,13 @@ void
ide_init(void) ide_init(void)
{ {
initlock(&ide_lock, "ide"); initlock(&ide_lock, "ide");
irq_setmask_8259A(irq_mask_8259A & ~(1 << IRQ_IDE)); irq_enable(IRQ_IDE);
ioapic_enable (IRQ_IDE, ncpu - 1); ioapic_enable(IRQ_IDE, ncpu - 1);
ide_wait_ready(0); ide_wait_ready(0);
disk_1_present = ide_probe_disk1(); disk_1_present = ide_probe_disk1();
} }
// Interrupt handler - wake up the request that just finished.
void void
ide_intr(void) ide_intr(void)
{ {
@ -71,7 +73,8 @@ ide_intr(void)
release(&ide_lock); release(&ide_lock);
} }
int // Probe to see if disk 1 exists (we assume disk 0 exists).
static int
ide_probe_disk1(void) ide_probe_disk1(void)
{ {
int r, x; int r, x;
@ -92,7 +95,8 @@ ide_probe_disk1(void)
return x < 1000; return x < 1000;
} }
void // Start the next request in the queue.
static void
ide_start_request (void) ide_start_request (void)
{ {
struct ide_request *r; struct ide_request *r;
@ -115,16 +119,20 @@ ide_start_request (void)
} }
} }
void* // Run an entire disk operation.
ide_start_rw(int diskno, uint secno, void *addr, uint nsecs, int read) void
ide_rw(int diskno, uint secno, void *addr, uint nsecs, int read)
{ {
struct ide_request *r; struct ide_request *r;
if(diskno && !disk_1_present) if(diskno && !disk_1_present)
panic("ide disk 1 not present"); panic("ide disk 1 not present");
acquire(&ide_lock);
// Add request to queue.
while((head + 1) % NREQUEST == tail) while((head + 1) % NREQUEST == tail)
sleep(&disk_channel, &ide_lock); sleep(&disk_queue, &ide_lock);
r = &request[head]; r = &request[head];
r->secno = secno; r->secno = secno;
@ -132,35 +140,29 @@ ide_start_rw(int diskno, uint secno, void *addr, uint nsecs, int read)
r->nsecs = nsecs; r->nsecs = nsecs;
r->diskno = diskno; r->diskno = diskno;
r->read = read; r->read = read;
head = (head + 1) % NREQUEST; head = (head + 1) % NREQUEST;
// Start request if necessary.
ide_start_request(); ide_start_request();
return r; // Wait for request to finish.
} sleep(r, &ide_lock);
int // Finish request.
ide_finish(void *c) if(read){
{ if(ide_wait_ready(1) >= 0)
int r; insl(0x1F0, addr, 512/4);
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);
} }
// Remove request from queue.
if((head + 1) % NREQUEST == tail)
wakeup(&disk_queue);
tail = (tail + 1) % NREQUEST; tail = (tail + 1) % NREQUEST;
ide_start_request();
return 0; release(&ide_lock);
} }
// Synchronous disk write.
int int
ide_write(int diskno, uint secno, const void *src, uint nsecs) ide_write(int diskno, uint secno, const void *src, uint nsecs)
{ {

View file

@ -11,9 +11,9 @@
// Current IRQ mask. // Current IRQ mask.
// Initial IRQ mask has interrupt 2 enabled (for slave 8259A). // Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
ushort irq_mask_8259A = 0xFFFF & ~(1<<IRQ_SLAVE); static ushort irq_mask_8259A = 0xFFFF & ~(1<<IRQ_SLAVE);
void static void
irq_setmask_8259A(ushort mask) irq_setmask_8259A(ushort mask)
{ {
irq_mask_8259A = mask; irq_mask_8259A = mask;
@ -22,6 +22,12 @@ irq_setmask_8259A(ushort mask)
outb(IO_PIC2+1, (char)(mask >> 8)); outb(IO_PIC2+1, (char)(mask >> 8));
} }
void
irq_enable(int irq)
{
irq_setmask_8259A(irq_mask_8259A & ~(1<<irq));
}
// Initialize the 8259A interrupt controllers. // Initialize the 8259A interrupt controllers.
void void
pic_init(void) pic_init(void)

View file

@ -220,7 +220,7 @@ sys_mkdir(void)
return -1; return -1;
} }
dp->nlink += 1; dp->nlink++;
iupdate(dp); iupdate(dp);
memset(de.name, '\0', DIRSIZ); memset(de.name, '\0', DIRSIZ);