queue with disk requests

This commit is contained in:
kaashoek 2006-07-10 19:06:48 +00:00
parent 084f21430c
commit 7ea6c9d197
4 changed files with 62 additions and 24 deletions

5
defs.h
View file

@ -70,8 +70,7 @@ int fd_read(struct fd *fd, char *addr, int n);
int fd_write(struct fd *fd, char *addr, int n); int fd_write(struct fd *fd, char *addr, int n);
// ide.c // ide.c
extern int disk_channel;
void ide_init(void); void ide_init(void);
void ide_intr(void); void ide_intr(void);
int ide_start_read(uint32_t secno, void *dst, unsigned nsecs); void* ide_start_read(uint32_t secno, void *dst, unsigned nsecs);
int ide_read(uint32_t secno, void *dst, unsigned nsecs); int ide_finish_read(void *);

73
ide.c
View file

@ -16,6 +16,14 @@
#define IDE_DF 0x20 #define IDE_DF 0x20
#define IDE_ERR 0x01 #define IDE_ERR 0x01
struct ide_request {
uint32_t secno;
void *dst;
unsigned nsecs;
};
struct ide_request request[NREQUEST];
int head, tail;
static int diskno = 0; static int diskno = 0;
int disk_channel; int disk_channel;
@ -44,11 +52,9 @@ void
ide_intr(void) ide_intr(void)
{ {
cprintf("ide_intr\n"); cprintf("ide_intr\n");
wakeup(&disk_channel); wakeup(&request[tail]);
} }
int int
ide_probe_disk1(void) ide_probe_disk1(void)
{ {
@ -79,35 +85,66 @@ ide_set_disk(int d)
diskno = d; diskno = d;
} }
int void
ide_start_request (void)
{
struct ide_request *r;
if (head == tail) {
r = &request[tail];
ide_wait_ready(0);
outb(0x3f6, 0);
outb(0x1F2, r->nsecs);
outb(0x1F3, r->secno & 0xFF);
outb(0x1F4, (r->secno >> 8) & 0xFF);
outb(0x1F5, (r->secno >> 16) & 0xFF);
outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((r->secno>>24)&0x0F));
outb(0x1F7, 0x20); // CMD 0x20 means read sector
}
}
void *
ide_start_read(uint32_t secno, void *dst, unsigned nsecs) ide_start_read(uint32_t secno, void *dst, unsigned nsecs)
{ {
struct ide_request *r;
if(nsecs > 256) if(nsecs > 256)
panic("ide_start_read: nsecs too large"); panic("ide_start_read: nsecs too large");
ide_wait_ready(0); while ((head + 1) % NREQUEST == tail)
sleep (&disk_channel);
outb(0x3f6, 0); r = &request[head];
outb(0x1F2, nsecs); r->secno = secno;
outb(0x1F3, secno & 0xFF); r->dst = dst;
outb(0x1F4, (secno >> 8) & 0xFF); r->nsecs = nsecs;
outb(0x1F5, (secno >> 16) & 0xFF);
outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
outb(0x1F7, 0x20); // CMD 0x20 means read sector
return 0; ide_start_request();
head = (head + 1) % NREQUEST;
return r;
} }
int int
ide_read(uint32_t secno, void *dst, unsigned nsecs) ide_finish_read(void *c)
{ {
int r; int r = 0;
struct ide_request *req = (struct ide_request *) c;
for (; nsecs > 0; nsecs--, dst += 512) { for (; req->nsecs > 0; req->nsecs--, req->dst += 512) {
if ((r = ide_wait_ready(1)) < 0) if ((r = ide_wait_ready(1)) < 0)
return r; break;
insl(0x1F0, dst, 512/4); insl(0x1F0, req->dst, 512/4);
} }
if ((head + 1) % NREQUEST == tail) {
wakeup(&disk_channel);
}
tail = (tail + 1) % NREQUEST;
ide_start_request();
return 0; return 0;
} }

View file

@ -4,3 +4,4 @@
#define NCPU 8 #define NCPU 8
#define NOFILE 16 // file descriptors per process #define NOFILE 16 // file descriptors per process
#define NFD 100 // file descriptors per system #define NFD 100 // file descriptors per system
#define NREQUEST 100 // outstanding disk requests

View file

@ -229,15 +229,16 @@ sys_block(void)
{ {
char buf[512]; char buf[512];
int i, j; int i, j;
void *c;
cprintf("%d: call sys_block\n", cpu()); cprintf("%d: call sys_block\n", cpu());
for (i = 0; i < 100; i++) { for (i = 0; i < 100; i++) {
if (ide_start_read(i, buf, 1)) { if ((c = ide_start_read(i, buf, 1)) == 0) {
panic("couldn't start read\n"); panic("couldn't start read\n");
} }
cprintf("call sleep\n"); cprintf("call sleep\n");
sleep (&disk_channel); sleep (c);
if (ide_read(i, buf, 1)) { if (ide_finish_read(c)) {
panic("couldn't do read\n"); panic("couldn't do read\n");
} }
cprintf("sector %d: ", i); cprintf("sector %d: ", i);