queue with disk requests
This commit is contained in:
parent
084f21430c
commit
7ea6c9d197
5
defs.h
5
defs.h
|
@ -70,8 +70,7 @@ int fd_read(struct fd *fd, char *addr, int n);
|
|||
int fd_write(struct fd *fd, char *addr, int n);
|
||||
|
||||
// ide.c
|
||||
extern int disk_channel;
|
||||
void ide_init(void);
|
||||
void ide_intr(void);
|
||||
int ide_start_read(uint32_t secno, void *dst, unsigned nsecs);
|
||||
int ide_read(uint32_t secno, void *dst, unsigned nsecs);
|
||||
void* ide_start_read(uint32_t secno, void *dst, unsigned nsecs);
|
||||
int ide_finish_read(void *);
|
||||
|
|
73
ide.c
73
ide.c
|
@ -16,6 +16,14 @@
|
|||
#define IDE_DF 0x20
|
||||
#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;
|
||||
int disk_channel;
|
||||
|
||||
|
@ -44,11 +52,9 @@ void
|
|||
ide_intr(void)
|
||||
{
|
||||
cprintf("ide_intr\n");
|
||||
wakeup(&disk_channel);
|
||||
wakeup(&request[tail]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
ide_probe_disk1(void)
|
||||
{
|
||||
|
@ -79,35 +85,66 @@ ide_set_disk(int 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)
|
||||
{
|
||||
struct ide_request *r;
|
||||
|
||||
if(nsecs > 256)
|
||||
panic("ide_start_read: nsecs too large");
|
||||
|
||||
ide_wait_ready(0);
|
||||
while ((head + 1) % NREQUEST == tail)
|
||||
sleep (&disk_channel);
|
||||
|
||||
outb(0x3f6, 0);
|
||||
outb(0x1F2, nsecs);
|
||||
outb(0x1F3, secno & 0xFF);
|
||||
outb(0x1F4, (secno >> 8) & 0xFF);
|
||||
outb(0x1F5, (secno >> 16) & 0xFF);
|
||||
outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
|
||||
outb(0x1F7, 0x20); // CMD 0x20 means read sector
|
||||
r = &request[head];
|
||||
r->secno = secno;
|
||||
r->dst = dst;
|
||||
r->nsecs = nsecs;
|
||||
|
||||
return 0;
|
||||
ide_start_request();
|
||||
|
||||
head = (head + 1) % NREQUEST;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
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)
|
||||
return r;
|
||||
insl(0x1F0, dst, 512/4);
|
||||
break;
|
||||
insl(0x1F0, req->dst, 512/4);
|
||||
}
|
||||
|
||||
if ((head + 1) % NREQUEST == tail) {
|
||||
wakeup(&disk_channel);
|
||||
}
|
||||
|
||||
tail = (tail + 1) % NREQUEST;
|
||||
ide_start_request();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
1
param.h
1
param.h
|
@ -4,3 +4,4 @@
|
|||
#define NCPU 8
|
||||
#define NOFILE 16 // file descriptors per process
|
||||
#define NFD 100 // file descriptors per system
|
||||
#define NREQUEST 100 // outstanding disk requests
|
||||
|
|
|
@ -229,15 +229,16 @@ sys_block(void)
|
|||
{
|
||||
char buf[512];
|
||||
int i, j;
|
||||
void *c;
|
||||
|
||||
cprintf("%d: call sys_block\n", cpu());
|
||||
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");
|
||||
}
|
||||
cprintf("call sleep\n");
|
||||
sleep (&disk_channel);
|
||||
if (ide_read(i, buf, 1)) {
|
||||
sleep (c);
|
||||
if (ide_finish_read(c)) {
|
||||
panic("couldn't do read\n");
|
||||
}
|
||||
cprintf("sector %d: ", i);
|
||||
|
|
Loading…
Reference in a new issue