generalize async read to support write too
This commit is contained in:
parent
366189214e
commit
8ec6530fee
3 changed files with 17 additions and 12 deletions
4
bio.c
4
bio.c
|
@ -42,9 +42,9 @@ bread(uint dev, uint sector)
|
||||||
b = getblk();
|
b = getblk();
|
||||||
|
|
||||||
acquire(&ide_lock);
|
acquire(&ide_lock);
|
||||||
c = ide_start_read(dev & 0xff, sector, b->data, 1);
|
c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1);
|
||||||
sleep (c, &ide_lock);
|
sleep (c, &ide_lock);
|
||||||
ide_finish_read(c);
|
ide_finish(c);
|
||||||
release(&ide_lock);
|
release(&ide_lock);
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
|
|
4
defs.h
4
defs.h
|
@ -91,8 +91,8 @@ void fd_incref(struct fd *fd);
|
||||||
// ide.c
|
// ide.c
|
||||||
void ide_init(void);
|
void ide_init(void);
|
||||||
void ide_intr(void);
|
void ide_intr(void);
|
||||||
void* ide_start_read(int diskno, uint secno, void *dst, uint nsecs);
|
void* ide_start_rw(int diskno, uint secno, void *dst, uint nsecs, int read);
|
||||||
int ide_finish_read(void *);
|
int ide_finish(void *);
|
||||||
|
|
||||||
// bio.c
|
// bio.c
|
||||||
struct buf;
|
struct buf;
|
||||||
|
|
21
ide.c
21
ide.c
|
@ -20,8 +20,9 @@
|
||||||
struct ide_request {
|
struct ide_request {
|
||||||
int diskno;
|
int diskno;
|
||||||
uint secno;
|
uint secno;
|
||||||
void *dst;
|
void *addr;
|
||||||
uint nsecs;
|
uint nsecs;
|
||||||
|
uint read;
|
||||||
};
|
};
|
||||||
struct ide_request request[NREQUEST];
|
struct ide_request request[NREQUEST];
|
||||||
int head, tail;
|
int head, tail;
|
||||||
|
@ -93,20 +94,22 @@ ide_start_request (void)
|
||||||
if (head != tail) {
|
if (head != tail) {
|
||||||
r = &request[tail];
|
r = &request[tail];
|
||||||
ide_wait_ready(0);
|
ide_wait_ready(0);
|
||||||
outb(0x3f6, 0);
|
outb(0x3f6, 0); // generate interrupt
|
||||||
outb(0x1F2, r->nsecs);
|
outb(0x1F2, r->nsecs);
|
||||||
outb(0x1F3, r->secno & 0xFF);
|
outb(0x1F3, r->secno & 0xFF);
|
||||||
outb(0x1F4, (r->secno >> 8) & 0xFF);
|
outb(0x1F4, (r->secno >> 8) & 0xFF);
|
||||||
outb(0x1F5, (r->secno >> 16) & 0xFF);
|
outb(0x1F5, (r->secno >> 16) & 0xFF);
|
||||||
outb(0x1F6, 0xE0 | ((r->diskno&1)<<4) | ((r->secno>>24)&0x0F));
|
outb(0x1F6, 0xE0 | ((r->diskno&1)<<4) | ((r->secno>>24)&0x0F));
|
||||||
outb(0x1F7, 0x20); // CMD 0x20 means read sector
|
if (r->read) outb(0x1F7, 0x20); // read
|
||||||
|
else outb(0x1F7, 0x30); // write
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ide_start_read(int diskno, uint secno, void *dst, uint nsecs)
|
ide_start_rw(int diskno, uint secno, void *addr, uint nsecs, int read)
|
||||||
{
|
{
|
||||||
struct ide_request *r;
|
struct ide_request *r;
|
||||||
|
|
||||||
if(!holding(&ide_lock))
|
if(!holding(&ide_lock))
|
||||||
panic("ide_start_read: not holding ide_lock");
|
panic("ide_start_read: not holding ide_lock");
|
||||||
|
|
||||||
|
@ -118,9 +121,10 @@ ide_start_read(int diskno, uint secno, void *dst, uint nsecs)
|
||||||
|
|
||||||
r = &request[head];
|
r = &request[head];
|
||||||
r->secno = secno;
|
r->secno = secno;
|
||||||
r->dst = dst;
|
r->addr = addr;
|
||||||
r->nsecs = nsecs;
|
r->nsecs = nsecs;
|
||||||
r->diskno = diskno;
|
r->diskno = diskno;
|
||||||
|
r->read = read;
|
||||||
|
|
||||||
head = (head + 1) % NREQUEST;
|
head = (head + 1) % NREQUEST;
|
||||||
|
|
||||||
|
@ -130,7 +134,7 @@ ide_start_read(int diskno, uint secno, void *dst, uint nsecs)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ide_finish_read(void *c)
|
ide_finish(void *c)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
struct ide_request *req = (struct ide_request *) c;
|
struct ide_request *req = (struct ide_request *) c;
|
||||||
|
@ -140,10 +144,11 @@ ide_finish_read(void *c)
|
||||||
|
|
||||||
if(!holding(&ide_lock))
|
if(!holding(&ide_lock))
|
||||||
panic("ide_start_read: not holding ide_lock");
|
panic("ide_start_read: not holding ide_lock");
|
||||||
for (; req->nsecs > 0; req->nsecs--, req->dst += 512) {
|
for (; req->nsecs > 0; req->nsecs--, req->addr += 512) {
|
||||||
if ((r = ide_wait_ready(1)) < 0)
|
if ((r = ide_wait_ready(1)) < 0)
|
||||||
break;
|
break;
|
||||||
insl(0x1F0, req->dst, 512/4);
|
if (req->read) insl(0x1F0, req->addr, 512/4);
|
||||||
|
else outsl(0x1F0, req->addr, 512/4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((head + 1) % NREQUEST == tail) {
|
if ((head + 1) % NREQUEST == tail) {
|
||||||
|
|
Loading…
Reference in a new issue