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);
|
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
73
ide.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
param.h
1
param.h
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue