fix ide, pit interfaces
This commit is contained in:
parent
6c8acf9e04
commit
19297caf0d
|
@ -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
19
bio.c
|
@ -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.
|
||||
|
|
|
@ -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
6
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);
|
||||
|
|
64
ide.c
64
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));
|
||||
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)
|
||||
{
|
||||
|
|
10
picirq.c
10
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<<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)
|
||||
|
|
Loading…
Reference in a new issue