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(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*
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.

View file

@ -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;

6
defs.h
View file

@ -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);

68
ide.c
View file

@ -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)
{

View file

@ -11,9 +11,9 @@
// Current IRQ mask.
// 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_mask_8259A = mask;
@ -22,6 +22,12 @@ irq_setmask_8259A(ushort mask)
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.
void
pic_init(void)

View file

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