libdriver changes:

- remove obsolete non-safecopy support
- merge libdriver and libdriver_asyn
- change standard reply model from sendnb to senda
This commit is contained in:
David van Moolenbroek 2009-12-02 09:57:48 +00:00
parent 4924d1a9b5
commit 30a7fe5fa9
19 changed files with 285 additions and 1373 deletions

View File

@ -16,7 +16,6 @@ usage:
build: all build: all
all install depend clean: all install depend clean:
cd ./libdriver && $(MAKE) $@ cd ./libdriver && $(MAKE) $@
cd ./libdriver_asyn && $(MAKE) $@
cd ./tty && $(MAKE) $@ cd ./tty && $(MAKE) $@
cd ./amddev && $(MAKE) $@ cd ./amddev && $(MAKE) $@
cd ./at_wini && $(MAKE) $@ cd ./at_wini && $(MAKE) $@
@ -40,7 +39,6 @@ all install depend clean:
image: image:
cd ./libdriver && $(MAKE) build cd ./libdriver && $(MAKE) build
cd ./libdriver_asyn && $(MAKE) build
cd ./tty && $(MAKE) build cd ./tty && $(MAKE) build
cd ./at_wini && $(MAKE) build cd ./at_wini && $(MAKE) build
cd ./floppy && $(MAKE) build cd ./floppy && $(MAKE) build

View File

@ -264,6 +264,8 @@ int w_testing = 0, w_silent = 0;
int w_next_drive = 0; int w_next_drive = 0;
u32_t system_hz;
/* Variables. */ /* Variables. */
/* The struct wini is indexed by controller first, then drive (0-3). /* The struct wini is indexed by controller first, then drive (0-3).
@ -356,16 +358,16 @@ FORWARD _PROTOTYPE( char *w_name, (void) );
FORWARD _PROTOTYPE( int w_specify, (void) ); FORWARD _PROTOTYPE( int w_specify, (void) );
FORWARD _PROTOTYPE( int w_io_test, (void) ); FORWARD _PROTOTYPE( int w_io_test, (void) );
FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, u64_t position, FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, u64_t position,
iovec_t *iov, unsigned nr_req, int safe)); iovec_t *iov, unsigned nr_req));
FORWARD _PROTOTYPE( int com_out, (struct command *cmd) ); FORWARD _PROTOTYPE( int com_out, (struct command *cmd) );
FORWARD _PROTOTYPE( int com_out_ext, (struct command *cmd) ); FORWARD _PROTOTYPE( int com_out_ext, (struct command *cmd) );
FORWARD _PROTOTYPE( void setup_dma, (unsigned *sizep, int proc_nr, FORWARD _PROTOTYPE( void setup_dma, (unsigned *sizep, int proc_nr,
iovec_t *iov, size_t addr_offset, int do_write, iovec_t *iov, size_t addr_offset, int do_write,
int *do_copyoutp, int safe) ); int *do_copyoutp) );
FORWARD _PROTOTYPE( void w_need_reset, (void) ); FORWARD _PROTOTYPE( void w_need_reset, (void) );
FORWARD _PROTOTYPE( void ack_irqs, (unsigned int) ); FORWARD _PROTOTYPE( void ack_irqs, (unsigned int) );
FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int w_other, (struct driver *dp, message *m_ptr, int)); FORWARD _PROTOTYPE( int w_other, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int w_hw_int, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int w_hw_int, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int com_simple, (struct command *cmd) ); FORWARD _PROTOTYPE( int com_simple, (struct command *cmd) );
FORWARD _PROTOTYPE( void w_timeout, (void) ); FORWARD _PROTOTYPE( void w_timeout, (void) );
@ -381,7 +383,7 @@ FORWARD _PROTOTYPE( int atapi_intr_wait, (int dma, size_t max) );
FORWARD _PROTOTYPE( int atapi_open, (void) ); FORWARD _PROTOTYPE( int atapi_open, (void) );
FORWARD _PROTOTYPE( void atapi_close, (void) ); FORWARD _PROTOTYPE( void atapi_close, (void) );
FORWARD _PROTOTYPE( int atapi_transfer, (int proc_nr, int opcode, FORWARD _PROTOTYPE( int atapi_transfer, (int proc_nr, int opcode,
u64_t position, iovec_t *iov, unsigned nr_req, int safe)); u64_t position, iovec_t *iov, unsigned nr_req) );
#endif #endif
#define sys_voutb(out, n) at_voutb(__LINE__, (out), (n)) #define sys_voutb(out, n) at_voutb(__LINE__, (out), (n))
@ -450,7 +452,7 @@ PUBLIC int main(int argc, char *argv[])
env_setargs(argc, argv); env_setargs(argc, argv);
init_params(); init_params();
signal(SIGTERM, SIG_IGN); signal(SIGTERM, SIG_IGN);
driver_task(&w_dtab); driver_task(&w_dtab, DRIVER_STD);
return(OK); return(OK);
} }
@ -1159,7 +1161,7 @@ PRIVATE int w_io_test(void)
if (w_prepare(w_drive * DEV_PER_DRIVE) == NIL_DEV) if (w_prepare(w_drive * DEV_PER_DRIVE) == NIL_DEV)
panic(w_name(), "Couldn't switch devices", NO_NUM); panic(w_name(), "Couldn't switch devices", NO_NUM);
r = w_transfer(SELF, DEV_GATHER_S, cvu64(0), &iov, 1, 0); r = w_transfer(SELF, DEV_GATHER_S, cvu64(0), &iov, 1);
/* Switch back. */ /* Switch back. */
if (w_prepare(save_dev) == NIL_DEV) if (w_prepare(save_dev) == NIL_DEV)
@ -1356,13 +1358,12 @@ int error_dma(struct wini *wn)
/*===========================================================================* /*===========================================================================*
* w_transfer * * w_transfer *
*===========================================================================*/ *===========================================================================*/
PRIVATE int w_transfer(proc_nr, opcode, position, iov, nr_req, safe) PRIVATE int w_transfer(proc_nr, opcode, position, iov, nr_req)
int proc_nr; /* process doing the request */ int proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER_S or DEV_SCATTER_S */ int opcode; /* DEV_GATHER_S or DEV_SCATTER_S */
u64_t position; /* offset on device to read or write */ u64_t position; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe; /* iov contains addresses (0) or grants? */
{ {
struct wini *wn = w_wn; struct wini *wn = w_wn;
iovec_t *iop, *iov_end = iov + nr_req; iovec_t *iop, *iov_end = iov + nr_req;
@ -1375,7 +1376,7 @@ int safe; /* iov contains addresses (0) or grants? */
#if ENABLE_ATAPI #if ENABLE_ATAPI
if (w_wn->state & ATAPI) { if (w_wn->state & ATAPI) {
return atapi_transfer(proc_nr, opcode, position, iov, nr_req, safe); return atapi_transfer(proc_nr, opcode, position, iov, nr_req);
} }
#endif #endif
@ -1410,7 +1411,7 @@ int safe; /* iov contains addresses (0) or grants? */
if (do_dma) { if (do_dma) {
stop_dma(wn); stop_dma(wn);
setup_dma(&nbytes, proc_nr, iov, addr_offset, do_write, setup_dma(&nbytes, proc_nr, iov, addr_offset, do_write,
&do_copyout, safe); &do_copyout);
#if 0 #if 0
printf("nbytes = %d\n", nbytes); printf("nbytes = %d\n", nbytes);
#endif #endif
@ -1472,21 +1473,19 @@ int safe; /* iov contains addresses (0) or grants? */
if (do_copyout) if (do_copyout)
{ {
if(safe) { if(proc_nr != SELF) {
s= sys_safecopyto(proc_nr, iov->iov_addr, s= sys_safecopyto(proc_nr, iov->iov_addr,
addr_offset, addr_offset,
(vir_bytes)dma_buf+dma_buf_offset, n, D); (vir_bytes)dma_buf+dma_buf_offset, n, D);
} else { if (s != OK)
s= sys_vircopy(SELF, D, {
(vir_bytes)dma_buf+dma_buf_offset,
proc_nr, D,
iov->iov_addr + addr_offset, n);
}
if (s != OK)
{
panic(w_name(), panic(w_name(),
"w_transfer: sys_vircopy failed", "w_transfer: sys_vircopy failed",
s); s);
}
} else {
memcpy((char *) iov->iov_addr + addr_offset,
dma_buf + dma_buf_offset, n);
} }
} }
@ -1533,23 +1532,20 @@ int safe; /* iov contains addresses (0) or grants? */
/* Copy bytes to or from the device's buffer. */ /* Copy bytes to or from the device's buffer. */
if (opcode == DEV_GATHER_S) { if (opcode == DEV_GATHER_S) {
if(safe) { if(proc_nr != SELF) {
s=sys_safe_insw(wn->base_cmd + REG_DATA, proc_nr, s=sys_safe_insw(wn->base_cmd + REG_DATA, proc_nr,
(void *) (iov->iov_addr), addr_offset, (void *) (iov->iov_addr), addr_offset,
SECTOR_SIZE); SECTOR_SIZE);
if(s != OK) {
panic(w_name(),"Call to sys_safe_insw() failed", s);
}
} else { } else {
s=sys_insw(wn->base_cmd + REG_DATA, proc_nr, s=sys_insw(wn->base_cmd + REG_DATA, proc_nr,
(void *) (iov->iov_addr + addr_offset), (void *) (iov->iov_addr + addr_offset),
SECTOR_SIZE); SECTOR_SIZE);
}
if(s != OK) { if(s != OK) {
panic(w_name(),"Call to sys_insw() failed", s); panic(w_name(),"Call to sys_insw() failed", s);
} }
}
} else { } else {
if(safe) { if(proc_nr != SELF) {
s=sys_safe_outsw(wn->base_cmd + REG_DATA, proc_nr, s=sys_safe_outsw(wn->base_cmd + REG_DATA, proc_nr,
(void *) (iov->iov_addr), addr_offset, (void *) (iov->iov_addr), addr_offset,
SECTOR_SIZE); SECTOR_SIZE);
@ -1560,12 +1556,11 @@ int safe; /* iov contains addresses (0) or grants? */
} }
if(s != OK) { if(s != OK) {
panic(w_name(),"Call to sys_outsw() failed", panic(w_name(),"Call to sys_outsw() failed", s);
s);
} }
/* Data sent, wait for an interrupt. */ /* Data sent, wait for an interrupt. */
if ((r = at_intr_wait()) != OK) break; if ((r = at_intr_wait()) != OK) break;
} }
/* Book the bytes successfully transferred. */ /* Book the bytes successfully transferred. */
@ -1703,14 +1698,13 @@ struct command *cmd; /* Command block */
* setup_dma * * setup_dma *
*===========================================================================*/ *===========================================================================*/
PRIVATE void setup_dma(sizep, proc_nr, iov, addr_offset, do_write, PRIVATE void setup_dma(sizep, proc_nr, iov, addr_offset, do_write,
do_copyoutp, safe) do_copyoutp)
unsigned *sizep; unsigned *sizep;
int proc_nr; int proc_nr;
iovec_t *iov; iovec_t *iov;
size_t addr_offset; size_t addr_offset;
int do_write; int do_write;
int *do_copyoutp; int *do_copyoutp;
int safe;
{ {
phys_bytes phys, user_phys; phys_bytes phys, user_phys;
unsigned n, offset, size; unsigned n, offset, size;
@ -1742,16 +1736,20 @@ int safe;
n= size; n= size;
if (n == 0 || (n & 1)) if (n == 0 || (n & 1))
panic("at_wini", "bad size in iov", iov[i].iov_size); panic("at_wini", "bad size in iov", iov[i].iov_size);
if(safe) { if(proc_nr != SELF) {
r= sys_umap(proc_nr, VM_GRANT, iov[i].iov_addr, n,&user_phys); r= sys_umap(proc_nr, VM_GRANT, iov[i].iov_addr, n,
if (r != 0) &user_phys);
panic("at_wini", "can't map user buffer (VM_GRANT)", r); if (r != 0)
user_phys += offset + addr_offset; panic("at_wini",
"can't map user buffer (VM_GRANT)", r);
user_phys += offset + addr_offset;
} else { } else {
r= sys_umap(proc_nr, VM_D, iov[i].iov_addr+offset+addr_offset, r= sys_umap(proc_nr, VM_D,
n, &user_phys); iov[i].iov_addr+offset+addr_offset, n,
if (r != 0) &user_phys);
panic("at_wini", "can't map user buffer (VM_D)", r); if (r != 0)
panic("at_wini",
"can't map user buffer (VM_D)", r);
} }
if (user_phys & 1) if (user_phys & 1)
{ {
@ -1834,20 +1832,19 @@ int safe;
if (n > iov->iov_size) if (n > iov->iov_size)
n= iov->iov_size; n= iov->iov_size;
if(safe) { if(proc_nr != SELF) {
r= sys_safecopyfrom(proc_nr, iov->iov_addr, r= sys_safecopyfrom(proc_nr, iov->iov_addr,
addr_offset, (vir_bytes)dma_buf+offset, addr_offset, (vir_bytes)dma_buf+offset,
n, D); n, D);
} else { if (r != OK)
r= sys_vircopy(proc_nr, D, {
iov->iov_addr+addr_offset, SELF, D,
(vir_bytes)dma_buf+offset, n);
}
if (r != OK)
{
panic(w_name(), panic(w_name(),
"setup_dma: sys_vircopy failed", "setup_dma: sys_vircopy failed", r);
r); }
} else {
memcpy(dma_buf + offset,
(char *) iov->iov_addr + addr_offset,
n);
} }
iov++; iov++;
addr_offset= 0; addr_offset= 0;
@ -2276,13 +2273,12 @@ void sense_request(void)
/*===========================================================================* /*===========================================================================*
* atapi_transfer * * atapi_transfer *
*===========================================================================*/ *===========================================================================*/
PRIVATE int atapi_transfer(proc_nr, opcode, position, iov, nr_req, safe) PRIVATE int atapi_transfer(proc_nr, opcode, position, iov, nr_req)
int proc_nr; /* process doing the request */ int proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER_S or DEV_SCATTER_S */ int opcode; /* DEV_GATHER_S or DEV_SCATTER_S */
u64_t position; /* offset on device to read or write */ u64_t position; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe; /* use safecopies? */
{ {
struct wini *wn = w_wn; struct wini *wn = w_wn;
iovec_t *iop, *iov_end = iov + nr_req; iovec_t *iop, *iov_end = iov + nr_req;
@ -2348,7 +2344,7 @@ int safe; /* use safecopies? */
int do_copyout = 0; int do_copyout = 0;
stop_dma(wn); stop_dma(wn);
setup_dma(&nbytes, proc_nr, iov, addr_offset, 0, setup_dma(&nbytes, proc_nr, iov, addr_offset, 0,
&do_copyout, safe); &do_copyout);
if(do_copyout || (nbytes != nblocks * CD_SECTOR_SIZE)) { if(do_copyout || (nbytes != nblocks * CD_SECTOR_SIZE)) {
stop_dma(wn); stop_dma(wn);
do_dma = 0; do_dma = 0;
@ -2409,12 +2405,14 @@ int safe; /* use safecopies? */
chunk = nbytes; chunk = nbytes;
if (chunk > count) chunk = count; if (chunk > count) chunk = count;
if (chunk > iov->iov_size) chunk = iov->iov_size; if (chunk > iov->iov_size) chunk = iov->iov_size;
if(safe) { if(proc_nr != SELF) {
s=sys_safe_insw(wn->base_cmd + REG_DATA, proc_nr, s=sys_safe_insw(wn->base_cmd + REG_DATA,
(void *) iov->iov_addr, addr_offset, chunk); proc_nr, (void *) iov->iov_addr,
addr_offset, chunk);
} else { } else {
s=sys_insw(wn->base_cmd + REG_DATA, proc_nr, s=sys_insw(wn->base_cmd + REG_DATA, proc_nr,
(void *) (iov->iov_addr + addr_offset), chunk); (void *) (iov->iov_addr + addr_offset),
chunk);
} }
if (s != OK) if (s != OK)
panic(w_name(),"Call to sys_insw() failed", s); panic(w_name(),"Call to sys_insw() failed", s);
@ -2531,10 +2529,9 @@ int do_dma;
/*===========================================================================* /*===========================================================================*
* w_other * * w_other *
*===========================================================================*/ *===========================================================================*/
PRIVATE int w_other(dr, m, safe) PRIVATE int w_other(dr, m)
struct driver *dr; struct driver *dr;
message *m; message *m;
int safe;
{ {
int r, timeout, prev; int r, timeout, prev;
@ -2542,13 +2539,8 @@ int safe;
return EINVAL; return EINVAL;
if (m->REQUEST == DIOCTIMEOUT) { if (m->REQUEST == DIOCTIMEOUT) {
if(safe) { r= sys_safecopyfrom(m->IO_ENDPT, (vir_bytes) m->IO_GRANT,
r= sys_safecopyfrom(m->IO_ENDPT, (vir_bytes) m->IO_GRANT,
0, (vir_bytes)&timeout, sizeof(timeout), D); 0, (vir_bytes)&timeout, sizeof(timeout), D);
} else {
r= sys_datacopy(m->IO_ENDPT, (vir_bytes)m->ADDRESS,
SELF, (vir_bytes)&timeout, sizeof(timeout));
}
if(r != OK) if(r != OK)
return r; return r;
@ -2576,15 +2568,8 @@ int safe;
timeout_ticks = timeout; timeout_ticks = timeout;
} }
if(safe) { r= sys_safecopyto(m->IO_ENDPT, (vir_bytes) m->IO_GRANT,
r= sys_safecopyto(m->IO_ENDPT,
(vir_bytes) m->IO_GRANT,
0, (vir_bytes)&prev, sizeof(prev), D); 0, (vir_bytes)&prev, sizeof(prev), D);
} else {
r=sys_datacopy(SELF, (vir_bytes)&prev,
m->IO_ENDPT, (vir_bytes)m->ADDRESS,
sizeof(prev));
}
if(r != OK) if(r != OK)
return r; return r;
@ -2595,13 +2580,8 @@ int safe;
int count; int count;
if (w_prepare(m->DEVICE) == NIL_DEV) return ENXIO; if (w_prepare(m->DEVICE) == NIL_DEV) return ENXIO;
count = w_wn->open_ct; count = w_wn->open_ct;
if(safe) { r= sys_safecopyto(m->IO_ENDPT, (vir_bytes) m->IO_GRANT,
r= sys_safecopyto(m->IO_ENDPT, (vir_bytes) m->IO_GRANT,
0, (vir_bytes)&count, sizeof(count), D); 0, (vir_bytes)&count, sizeof(count), D);
} else {
r=sys_datacopy(SELF, (vir_bytes)&count,
m->IO_ENDPT, (vir_bytes)m->ADDRESS, sizeof(count));
}
if(r != OK) if(r != OK)
return r; return r;

View File

@ -69,12 +69,12 @@ _PROTOTYPE(int main, (void) );
FORWARD _PROTOTYPE( struct device *w_prepare, (int device) ); FORWARD _PROTOTYPE( struct device *w_prepare, (int device) );
FORWARD _PROTOTYPE( char *w_name, (void) ); FORWARD _PROTOTYPE( char *w_name, (void) );
FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, u64_t position, FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, u64_t position,
iovec_t *iov, unsigned nr_req, int safe) ); iovec_t *iov, unsigned nr_req) );
FORWARD _PROTOTYPE( int w_do_open, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int w_do_open, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void w_init, (void) ); FORWARD _PROTOTYPE( void w_init, (void) );
FORWARD _PROTOTYPE( void w_geometry, (struct partition *entry)); FORWARD _PROTOTYPE( void w_geometry, (struct partition *entry));
FORWARD _PROTOTYPE( int w_other, (struct driver *dp, message *m_ptr, int) ); FORWARD _PROTOTYPE( int w_other, (struct driver *dp, message *m_ptr) );
/* Entry points to this driver. */ /* Entry points to this driver. */
PRIVATE struct driver w_dtab = { PRIVATE struct driver w_dtab = {
@ -106,7 +106,7 @@ PUBLIC int main()
remap_first= v; remap_first= v;
/* Set special disk parameters then call the generic main loop. */ /* Set special disk parameters then call the generic main loop. */
driver_task(&w_dtab); driver_task(&w_dtab, DRIVER_STD);
return(OK); return(OK);
} }
@ -150,13 +150,12 @@ PRIVATE char *w_name()
/*===========================================================================* /*===========================================================================*
* w_transfer * * w_transfer *
*===========================================================================*/ *===========================================================================*/
PRIVATE int w_transfer(proc_nr, opcode, pos64, iov, nr_req, safe) PRIVATE int w_transfer(proc_nr, opcode, pos64, iov, nr_req)
int proc_nr; /* process doing the request */ int proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER or DEV_SCATTER */ int opcode; /* DEV_GATHER or DEV_SCATTER */
u64_t pos64; /* offset on device to read or write */ u64_t pos64; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe; /* use safecopies? */
{ {
struct wini *wn = w_wn; struct wini *wn = w_wn;
iovec_t *iop, *iov_end = iov + nr_req; iovec_t *iop, *iov_end = iov + nr_req;
@ -222,7 +221,7 @@ int safe; /* use safecopies? */
if (count + chunk > nbytes) chunk = nbytes - count; if (count + chunk > nbytes) chunk = nbytes - count;
assert(chunk <= rem_buf_size); assert(chunk <= rem_buf_size);
if(safe) { if(proc_nr != SELF) {
r=sys_safecopyfrom(proc_nr, r=sys_safecopyfrom(proc_nr,
(cp_grant_id_t) iop->iov_addr, (cp_grant_id_t) iop->iov_addr,
0, (vir_bytes) (bios_buf_v+count), 0, (vir_bytes) (bios_buf_v+count),
@ -230,9 +229,6 @@ int safe; /* use safecopies? */
if (r != OK) if (r != OK)
panic(ME, "copy failed", r); panic(ME, "copy failed", r);
} else { } else {
if(proc_nr != SELF) {
panic(ME, "unsafe outside self", r);
}
memcpy(bios_buf_v+count, memcpy(bios_buf_v+count,
(char *) iop->iov_addr, chunk); (char *) iop->iov_addr, chunk);
} }
@ -291,15 +287,14 @@ int safe; /* use safecopies? */
if (count + chunk > nbytes) chunk = nbytes - count; if (count + chunk > nbytes) chunk = nbytes - count;
assert(chunk <= rem_buf_size); assert(chunk <= rem_buf_size);
if(safe) { if(proc_nr != SELF) {
r=sys_safecopyto(proc_nr, iop->iov_addr, r=sys_safecopyto(proc_nr, iop->iov_addr,
0, (vir_bytes) (bios_buf_v+count), chunk, D); 0, (vir_bytes) (bios_buf_v+count),
chunk, D);
if (r != OK) if (r != OK)
panic(ME, "sys_vircopy failed", r); panic(ME, "sys_vircopy failed", r);
} else { } else {
if (proc_nr != SELF)
panic(ME, "unsafe without self", NO_NUM);
memcpy((char *) iop->iov_addr, memcpy((char *) iop->iov_addr,
bios_buf_v+count, chunk); bios_buf_v+count, chunk);
} }
@ -493,10 +488,9 @@ struct partition *entry;
/*============================================================================* /*============================================================================*
* w_other * * w_other *
*============================================================================*/ *============================================================================*/
PRIVATE int w_other(dr, m, safe) PRIVATE int w_other(dr, m)
struct driver *dr; struct driver *dr;
message *m; message *m;
int safe;
{ {
int r, timeout, prev; int r, timeout, prev;
@ -507,13 +501,8 @@ int safe;
int count; int count;
if (w_prepare(m->DEVICE) == NIL_DEV) return ENXIO; if (w_prepare(m->DEVICE) == NIL_DEV) return ENXIO;
count = w_wn->open_ct; count = w_wn->open_ct;
if(safe) { r=sys_safecopyto(m->IO_ENDPT, (vir_bytes)m->IO_GRANT,
r=sys_safecopyto(m->IO_ENDPT, (vir_bytes)m->ADDRESS,
0, (vir_bytes)&count, sizeof(count), D); 0, (vir_bytes)&count, sizeof(count), D);
} else {
r=sys_datacopy(SELF, (vir_bytes)&count,
m->IO_ENDPT, (vir_bytes)m->ADDRESS, sizeof(count));
}
if(r != OK) if(r != OK)
return r; return r;

View File

@ -240,6 +240,7 @@ PRIVATE u8_t f_results[MAX_RESULTS];/* the controller can give lots of output */
PRIVATE timer_t f_tmr_timeout; /* timer for various timeouts */ PRIVATE timer_t f_tmr_timeout; /* timer for various timeouts */
PRIVATE timer_t *f_timers; /* queue of floppy timers */ PRIVATE timer_t *f_timers; /* queue of floppy timers */
PRIVATE clock_t f_next_timeout; /* the next timeout time */ PRIVATE clock_t f_next_timeout; /* the next timeout time */
PRIVATE u32_t system_hz; /* system clock frequency */
FORWARD _PROTOTYPE( void f_expire_tmrs, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( void f_expire_tmrs, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void f_set_timer, (timer_t *tp, clock_t delta, FORWARD _PROTOTYPE( void f_set_timer, (timer_t *tp, clock_t delta,
tmr_func_t watchdog) ); tmr_func_t watchdog) );
@ -250,7 +251,7 @@ FORWARD _PROTOTYPE( struct device *f_prepare, (int device) );
FORWARD _PROTOTYPE( char *f_name, (void) ); FORWARD _PROTOTYPE( char *f_name, (void) );
FORWARD _PROTOTYPE( void f_cleanup, (void) ); FORWARD _PROTOTYPE( void f_cleanup, (void) );
FORWARD _PROTOTYPE( int f_transfer, (int proc_nr, int opcode, u64_t position, FORWARD _PROTOTYPE( int f_transfer, (int proc_nr, int opcode, u64_t position,
iovec_t *iov, unsigned nr_req, int) ); iovec_t *iov, unsigned nr_req) );
FORWARD _PROTOTYPE( int dma_setup, (int opcode) ); FORWARD _PROTOTYPE( int dma_setup, (int opcode) );
FORWARD _PROTOTYPE( void start_motor, (void) ); FORWARD _PROTOTYPE( void start_motor, (void) );
FORWARD _PROTOTYPE( int seek, (void) ); FORWARD _PROTOTYPE( int seek, (void) );
@ -298,6 +299,8 @@ PUBLIC void main()
struct floppy *fp; struct floppy *fp;
int s; int s;
system_hz = sys_hz();
if(!(floppy_buf = alloc_contig(2*DMA_BUF_SIZE, if(!(floppy_buf = alloc_contig(2*DMA_BUF_SIZE,
AC_LOWER16M | AC_ALIGN4K, &floppy_buf_phys))) AC_LOWER16M | AC_ALIGN4K, &floppy_buf_phys)))
panic("FLOPPY", "couldn't allocate dma buffer", NO_NUM); panic("FLOPPY", "couldn't allocate dma buffer", NO_NUM);
@ -324,7 +327,7 @@ PUBLIC void main()
/* Ignore signals */ /* Ignore signals */
signal(SIGHUP, SIG_IGN); signal(SIGHUP, SIG_IGN);
driver_task(&f_dtab); driver_task(&f_dtab, DRIVER_STD);
} }
/*===========================================================================* /*===========================================================================*
@ -442,13 +445,12 @@ PRIVATE void f_cleanup()
/*===========================================================================* /*===========================================================================*
* f_transfer * * f_transfer *
*===========================================================================*/ *===========================================================================*/
PRIVATE int f_transfer(proc_nr, opcode, pos64, iov, nr_req, safe) PRIVATE int f_transfer(proc_nr, opcode, pos64, iov, nr_req)
int proc_nr; /* process doing the request */ int proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER_S or DEV_SCATTER_S */ int opcode; /* DEV_GATHER_S or DEV_SCATTER_S */
u64_t pos64; /* offset on device to read or write */ u64_t pos64; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe;
{ {
#define NO_OFFSET -1 #define NO_OFFSET -1
struct floppy *fp = f_fp; struct floppy *fp = f_fp;
@ -467,12 +469,6 @@ int safe;
return OK; /* Way beyond EOF */ return OK; /* Way beyond EOF */
position= cv64ul(pos64); position= cv64ul(pos64);
/* internally, floppy uses f_transfer without grant id, with safe set to
* 0. This is OK, as long as proc_nr is SELF.
*/
if(!safe && proc_nr != SELF)
panic("FLOPPY", "f_transfer: not safe and proc_nr not SELF", proc_nr);
/* Check disk address. */ /* Check disk address. */
if ((position & SECTOR_MASK) != 0) return(EINVAL); if ((position & SECTOR_MASK) != 0) return(EINVAL);
@ -501,14 +497,13 @@ int safe;
if (iov->iov_size < SECTOR_SIZE + sizeof(fmt_param)) if (iov->iov_size < SECTOR_SIZE + sizeof(fmt_param))
return(EINVAL); return(EINVAL);
if(safe) { if(proc_nr != SELF) {
s=sys_safecopyfrom(proc_nr, iov->iov_addr, s=sys_safecopyfrom(proc_nr, iov->iov_addr,
SECTOR_SIZE + iov_offset, (vir_bytes) &fmt_param, SECTOR_SIZE + iov_offset, (vir_bytes) &fmt_param,
(phys_bytes) sizeof(fmt_param), D); (phys_bytes) sizeof(fmt_param), D);
if(s != OK) if(s != OK)
panic("FLOPPY", "sys_safecopyfrom failed", s); panic("FLOPPY", "sys_safecopyfrom failed", s);
} else { } else {
assert(proc_nr == SELF);
memcpy(&fmt_param, (void *) (iov->iov_addr + memcpy(&fmt_param, (void *) (iov->iov_addr +
SECTOR_SIZE + iov_offset), SECTOR_SIZE + iov_offset),
(phys_bytes) sizeof(fmt_param)); (phys_bytes) sizeof(fmt_param));
@ -608,14 +603,13 @@ int safe;
if (r == OK && opcode == DEV_SCATTER_S) { if (r == OK && opcode == DEV_SCATTER_S) {
/* Copy the user bytes to the DMA buffer. */ /* Copy the user bytes to the DMA buffer. */
if(safe) { if(proc_nr != SELF) {
s=sys_safecopyfrom(proc_nr, *ug, *up, s=sys_safecopyfrom(proc_nr, *ug, *up,
(vir_bytes) floppy_buf, (vir_bytes) floppy_buf,
(phys_bytes) SECTOR_SIZE, D); (phys_bytes) SECTOR_SIZE, D);
if(s != OK) if(s != OK)
panic("FLOPPY", "sys_safecopyfrom failed", s); panic("FLOPPY", "sys_safecopyfrom failed", s);
} else { } else {
assert(proc_nr == SELF);
memcpy(floppy_buf, (void *) (*ug + *up), SECTOR_SIZE); memcpy(floppy_buf, (void *) (*ug + *up), SECTOR_SIZE);
} }
} }
@ -634,14 +628,13 @@ int safe;
if (r == OK && opcode == DEV_GATHER_S) { if (r == OK && opcode == DEV_GATHER_S) {
/* Copy the DMA buffer to user space. */ /* Copy the DMA buffer to user space. */
if(safe) { if(proc_nr != SELF) {
s=sys_safecopyto(proc_nr, *ug, *up, s=sys_safecopyto(proc_nr, *ug, *up,
(vir_bytes) floppy_buf, (vir_bytes) floppy_buf,
(phys_bytes) SECTOR_SIZE, D); (phys_bytes) SECTOR_SIZE, D);
if(s != OK) if(s != OK)
panic("FLOPPY", "sys_safecopyto failed", s); panic("FLOPPY", "sys_safecopyto failed", s);
} else { } else {
assert(proc_nr == SELF);
memcpy((void *) (*ug + *up), floppy_buf, SECTOR_SIZE); memcpy((void *) (*ug + *up), floppy_buf, SECTOR_SIZE);
} }
} }
@ -1353,7 +1346,7 @@ int density;
position = (off_t) f_dp->test << SECTOR_SHIFT; position = (off_t) f_dp->test << SECTOR_SHIFT;
iovec1.iov_addr = (vir_bytes) floppy_buf; iovec1.iov_addr = (vir_bytes) floppy_buf;
iovec1.iov_size = SECTOR_SIZE; iovec1.iov_size = SECTOR_SIZE;
result = f_transfer(SELF, DEV_GATHER_S, cvul64(position), &iovec1, 1, 0); result = f_transfer(SELF, DEV_GATHER_S, cvul64(position), &iovec1, 1);
if (iovec1.iov_size != 0) return(EIO); if (iovec1.iov_size != 0) return(EIO);

View File

@ -9,32 +9,30 @@
* *
* The drivers support the following operations (using message format m2): * The drivers support the following operations (using message format m2):
* *
* m_type DEVICE IO_ENDPT COUNT POSITION ADRRESS * m_type DEVICE IO_ENDPT COUNT POSITION HIGHPOS IO_GRANT
* ---------------------------------------------------------------- * ----------------------------------------------------------------------------
* | DEV_OPEN | device | proc nr | | | | * | DEV_OPEN | device | proc nr | | | | |
* |------------+---------+---------+---------+---------+---------| * |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_CLOSE | device | proc nr | | | | * | DEV_CLOSE | device | proc nr | | | | |
* |------------+---------+---------+---------+---------+---------| * |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_READ | device | proc nr | bytes | offset | buf ptr | * | DEV_READ_S | device | proc nr | bytes | off lo | off hi i buf grant |
* |------------+---------+---------+---------+---------+---------| * |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_WRITE | device | proc nr | bytes | offset | buf ptr | * | DEV_WRITE_S | device | proc nr | bytes | off lo | off hi | buf grant |
* |------------+---------+---------+---------+---------+---------| * |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_GATHER | device | proc nr | iov len | offset | iov ptr | * | DEV_GATHER_S | device | proc nr | iov len | off lo | off hi | iov grant |
* |------------+---------+---------+---------+---------+---------| * |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_SCATTER| device | proc nr | iov len | offset | iov ptr | * | DEV_SCATTER_S | device | proc nr | iov len | off lo | off hi | iov grant |
* |------------+---------+---------+---------+---------+---------| * |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_IOCTL | device | proc nr |func code| | buf ptr | * | DEV_IOCTL_S | device | proc nr | request | | | buf grant |
* |------------+---------+---------+---------+---------+---------| * |---------------+--------+---------+---------+--------+--------+-----------|
* | CANCEL | device | proc nr | r/w | | | * | CANCEL | device | proc nr | r/w | | | |
* |------------+---------+---------+---------+---------+---------| * ----------------------------------------------------------------------------
* | HARD_STOP | | | | | |
* |------------+---------+---------+---------+---------+---------|
* | DEV_*_S | variants using safecopies of above |
* ----------------------------------------------------------------
* *
* The file contains one entry point: * The file contains the following entry points:
* *
* driver_task: called by the device dependent task entry * driver_task: called by the device dependent task entry
* init_buffer: initialize a DMA buffer
* mq_queue: queue an incoming message for later processing
*/ */
@ -45,23 +43,84 @@
#include "driver.h" #include "driver.h"
/* Claim space for variables. */ /* Claim space for variables. */
#if 0 u8_t *tmp_buf = NULL; /* the DMA buffer eventually */
PRIVATE u8_t buffer[(unsigned) 2 * DMA_BUF_SIZE];
#endif
u8_t *tmp_buf; /* the DMA buffer eventually */
phys_bytes tmp_phys; /* phys address of DMA buffer */ phys_bytes tmp_phys; /* phys address of DMA buffer */
FORWARD _PROTOTYPE( int do_rdwt, (struct driver *dr, message *mp, int safe) ); FORWARD _PROTOTYPE( void asyn_reply, (message *mess, int proc_nr, int r) );
FORWARD _PROTOTYPE( int do_vrdwt, (struct driver *dr, message *mp, int safe) ); FORWARD _PROTOTYPE( int do_rdwt, (struct driver *dr, message *mp) );
FORWARD _PROTOTYPE( int do_vrdwt, (struct driver *dr, message *mp) );
int device_caller; int device_caller;
PRIVATE mq_t *queue_head = NULL; PRIVATE mq_t *queue_head = NULL;
/*===========================================================================*
* asyn_reply *
*===========================================================================*/
PRIVATE void asyn_reply(mess, proc_nr, r)
message *mess;
int proc_nr;
int r;
{
/* Send a reply using the new asynchronous character device protocol.
*/
message reply_mess;
switch (mess->m_type) {
case DEV_OPEN:
reply_mess.m_type = DEV_REVIVE;
reply_mess.REP_ENDPT = proc_nr;
reply_mess.REP_STATUS = r;
break;
case DEV_CLOSE:
reply_mess.m_type = DEV_CLOSE_REPL;
reply_mess.REP_ENDPT = proc_nr;
reply_mess.REP_STATUS = r;
break;
case DEV_READ_S:
case DEV_WRITE_S:
if (r == SUSPEND)
printf("driver_task: reviving %d with SUSPEND\n", proc_nr);
reply_mess.m_type = DEV_REVIVE;
reply_mess.REP_ENDPT = proc_nr;
reply_mess.REP_IO_GRANT = (cp_grant_id_t) mess->IO_GRANT;
reply_mess.REP_STATUS = r;
break;
case CANCEL:
/* The original request should send a reply. */
return;
case DEV_SELECT:
reply_mess.m_type = DEV_SEL_REPL1;
reply_mess.DEV_MINOR = mess->DEVICE;
reply_mess.DEV_SEL_OPS = r;
break;
default:
reply_mess.m_type = TASK_REPLY;
reply_mess.REP_ENDPT = proc_nr;
/* Status is # of bytes transferred or error code. */
reply_mess.REP_STATUS = r;
break;
}
r= asynsend(device_caller, &reply_mess);
if (r != OK)
{
printf("driver_task: unable to asynsend to %d: %d\n",
device_caller, r);
}
}
/*===========================================================================* /*===========================================================================*
* driver_task * * driver_task *
*===========================================================================*/ *===========================================================================*/
PUBLIC void driver_task(dp) PUBLIC void driver_task(dp, type)
struct driver *dp; /* Device dependent entry points. */ struct driver *dp; /* Device dependent entry points. */
int type; /* Driver type (DRIVER_STD or DRIVER_ASYN) */
{ {
/* Main program of any device driver task. */ /* Main program of any device driver task. */
@ -69,8 +128,6 @@ struct driver *dp; /* Device dependent entry points. */
message mess; message mess;
sigset_t set; sigset_t set;
system_hz = sys_hz();
/* Init MQ library. */ /* Init MQ library. */
mq_init(); mq_init();
@ -120,7 +177,7 @@ struct driver *dp; /* Device dependent entry points. */
break; break;
default: default:
if(dp->dr_other) if(dp->dr_other)
r = (*dp->dr_other)(dp, &mess, 0); r = (*dp->dr_other)(dp, &mess);
else else
r = EINVAL; r = EINVAL;
goto send_reply; goto send_reply;
@ -132,28 +189,17 @@ struct driver *dp; /* Device dependent entry points. */
switch(mess.m_type) { switch(mess.m_type) {
case DEV_OPEN: r = (*dp->dr_open)(dp, &mess); break; case DEV_OPEN: r = (*dp->dr_open)(dp, &mess); break;
case DEV_CLOSE: r = (*dp->dr_close)(dp, &mess); break; case DEV_CLOSE: r = (*dp->dr_close)(dp, &mess); break;
#ifdef DEV_IOCTL case DEV_IOCTL_S: r = (*dp->dr_ioctl)(dp, &mess); break;
case DEV_IOCTL: r = (*dp->dr_ioctl)(dp, &mess, 0); break;
#endif
case DEV_IOCTL_S: r = (*dp->dr_ioctl)(dp, &mess, 1); break;
case CANCEL: r = (*dp->dr_cancel)(dp, &mess);break; case CANCEL: r = (*dp->dr_cancel)(dp, &mess);break;
case DEV_SELECT: r = (*dp->dr_select)(dp, &mess);break; case DEV_SELECT: r = (*dp->dr_select)(dp, &mess);break;
#ifdef DEV_READ
case DEV_READ:
case DEV_WRITE: r = do_rdwt(dp, &mess, 0); break;
#endif
case DEV_READ_S: case DEV_READ_S:
case DEV_WRITE_S: r = do_rdwt(dp, &mess, 1); break; case DEV_WRITE_S: r = do_rdwt(dp, &mess); break;
#ifdef DEV_GATHER
case DEV_GATHER:
case DEV_SCATTER: r = do_vrdwt(dp, &mess, 0); break;
#endif
case DEV_GATHER_S: case DEV_GATHER_S:
case DEV_SCATTER_S: r = do_vrdwt(dp, &mess, 1); break; case DEV_SCATTER_S: r = do_vrdwt(dp, &mess); break;
default: default:
if(dp->dr_other) if(dp->dr_other)
r = (*dp->dr_other)(dp, &mess, 0); r = (*dp->dr_other)(dp, &mess);
else else
r = EINVAL; r = EINVAL;
break; break;
@ -164,17 +210,39 @@ send_reply:
(*dp->dr_cleanup)(); (*dp->dr_cleanup)();
/* Finally, prepare and send the reply message. */ /* Finally, prepare and send the reply message. */
if (r != EDONTREPLY) { if (r == EDONTREPLY)
continue;
switch (type) {
case DRIVER_STD:
mess.m_type = TASK_REPLY; mess.m_type = TASK_REPLY;
mess.REP_ENDPT = proc_nr; mess.REP_ENDPT = proc_nr;
/* Status is # of bytes transferred or error code. */ /* Status is # of bytes transferred or error code. */
mess.REP_STATUS = r; mess.REP_STATUS = r;
r= sendnb(device_caller, &mess);
/* Changed from sendnb() to asynsend() by dcvmoole on 20091129.
* This introduces a potential overflow if a single process is
* flooding us with requests, but we need reliable delivery of
* reply messages for the 'filter' driver. A possible solution
* would be to allow only one pending asynchronous reply to a
* single process at any time. FIXME.
*/
r= asynsend(device_caller, &mess);
if (r != OK) if (r != OK)
{ {
printf("driver_task: unable to sendnb to %d: %d\n", printf("driver_task: unable to send reply to %d: %d\n",
device_caller, r); device_caller, r);
} }
break;
case DRIVER_ASYN:
asyn_reply(&mess, proc_nr, r);
break;
default:
panic(__FILE__, "unknown driver type", type);
} }
} }
} }
@ -199,10 +267,9 @@ PUBLIC void init_buffer(void)
/*===========================================================================* /*===========================================================================*
* do_rdwt * * do_rdwt *
*===========================================================================*/ *===========================================================================*/
PRIVATE int do_rdwt(dp, mp, safe) PRIVATE int do_rdwt(dp, mp)
struct driver *dp; /* device dependent entry points */ struct driver *dp; /* device dependent entry points */
message *mp; /* pointer to read or write message */ message *mp; /* pointer to read or write message */
int safe; /* use safecopies? */
{ {
/* Carry out a single read or write request. */ /* Carry out a single read or write request. */
iovec_t iovec1; iovec_t iovec1;
@ -213,29 +280,19 @@ int safe; /* use safecopies? */
/* Disk address? Address and length of the user buffer? */ /* Disk address? Address and length of the user buffer? */
if (mp->COUNT < 0) return(EINVAL); if (mp->COUNT < 0) return(EINVAL);
/* Check the user buffer (not relevant for safe copies). */
if(!safe) {
printf("libdriver_asyn: do_rdwt: no support for non-safe command.\n");
return EINVAL;
}
/* Prepare for I/O. */ /* Prepare for I/O. */
if ((*dp->dr_prepare)(mp->DEVICE) == NIL_DEV) return(ENXIO); if ((*dp->dr_prepare)(mp->DEVICE) == NIL_DEV) return(ENXIO);
/* Create a one element scatter/gather vector for the buffer. */ /* Create a one element scatter/gather vector for the buffer. */
if( if(mp->m_type == DEV_READ_S) opcode = DEV_GATHER_S;
#ifdef DEV_READ
mp->m_type == DEV_READ ||
#endif
mp->m_type == DEV_READ_S) opcode = DEV_GATHER_S;
else opcode = DEV_SCATTER_S; else opcode = DEV_SCATTER_S;
iovec1.iov_addr = (vir_bytes) mp->ADDRESS; iovec1.iov_addr = (vir_bytes) mp->IO_GRANT;
iovec1.iov_size = mp->COUNT; iovec1.iov_size = mp->COUNT;
/* Transfer bytes from/to the device. */ /* Transfer bytes from/to the device. */
position= make64(mp->POSITION, mp->HIGHPOS); position= make64(mp->POSITION, mp->HIGHPOS);
r = (*dp->dr_transfer)(mp->IO_ENDPT, opcode, position, &iovec1, 1, safe); r = (*dp->dr_transfer)(mp->IO_ENDPT, opcode, position, &iovec1, 1);
/* Return the number of bytes transferred or an error code. */ /* Return the number of bytes transferred or an error code. */
return(r == OK ? (mp->COUNT - iovec1.iov_size) : r); return(r == OK ? (mp->COUNT - iovec1.iov_size) : r);
@ -244,17 +301,15 @@ int safe; /* use safecopies? */
/*==========================================================================* /*==========================================================================*
* do_vrdwt * * do_vrdwt *
*==========================================================================*/ *==========================================================================*/
PRIVATE int do_vrdwt(dp, mp, safe) PRIVATE int do_vrdwt(dp, mp)
struct driver *dp; /* device dependent entry points */ struct driver *dp; /* device dependent entry points */
message *mp; /* pointer to read or write message */ message *mp; /* pointer to read or write message */
int safe; /* use safecopies? */
{ {
/* Carry out an device read or write to/from a vector of user addresses. /* Carry out an device read or write to/from a vector of user addresses.
* The "user addresses" are assumed to be safe, i.e. FS transferring to/from * The "user addresses" are assumed to be safe, i.e. FS transferring to/from
* its own buffers, so they are not checked. * its own buffers, so they are not checked.
*/ */
static iovec_t iovec[NR_IOREQS]; static iovec_t iovec[NR_IOREQS];
iovec_t *iov;
phys_bytes iovec_size; phys_bytes iovec_size;
unsigned nr_req; unsigned nr_req;
int r, j, opcode; int r, j, opcode;
@ -262,24 +317,13 @@ int safe; /* use safecopies? */
nr_req = mp->COUNT; /* Length of I/O vector */ nr_req = mp->COUNT; /* Length of I/O vector */
{ /* Copy the vector from the caller to kernel space. */
/* Copy the vector from the caller to kernel space. */ if (nr_req > NR_IOREQS) nr_req = NR_IOREQS;
if (nr_req > NR_IOREQS) nr_req = NR_IOREQS; iovec_size = (phys_bytes) (nr_req * sizeof(iovec[0]));
iovec_size = (phys_bytes) (nr_req * sizeof(iovec[0]));
if(safe) { if (OK != sys_safecopyfrom(mp->m_source, (vir_bytes) mp->IO_GRANT,
if (OK != sys_safecopyfrom(mp->m_source, (vir_bytes) mp->IO_GRANT, 0, (vir_bytes) iovec, iovec_size, D)) {
0, (vir_bytes) iovec, iovec_size, D)) { panic((*dp->dr_name)(),"bad I/O vector by", mp->m_source);
panic((*dp->dr_name)(),"bad (safe) I/O vector by", mp->m_source);
}
} else {
if (OK != sys_datacopy(mp->m_source, (vir_bytes) mp->ADDRESS,
SELF, (vir_bytes) iovec, iovec_size)) {
panic((*dp->dr_name)(),"bad I/O vector by", mp->m_source);
}
}
iov = iovec;
} }
/* Prepare for I/O. */ /* Prepare for I/O. */
@ -288,18 +332,12 @@ int safe; /* use safecopies? */
/* Transfer bytes from/to the device. */ /* Transfer bytes from/to the device. */
opcode = mp->m_type; opcode = mp->m_type;
position= make64(mp->POSITION, mp->HIGHPOS); position= make64(mp->POSITION, mp->HIGHPOS);
r = (*dp->dr_transfer)(mp->IO_ENDPT, opcode, position, iov, r = (*dp->dr_transfer)(mp->IO_ENDPT, opcode, position, iovec, nr_req);
nr_req, safe);
/* Copy the I/O vector back to the caller. */ /* Copy the I/O vector back to the caller. */
if(safe) { if (OK != sys_safecopyto(mp->m_source, (vir_bytes) mp->IO_GRANT,
if (OK != sys_safecopyto(mp->m_source, (vir_bytes) mp->IO_GRANT, 0, (vir_bytes) iovec, iovec_size, D)) {
0, (vir_bytes) iovec, iovec_size, D)) { panic((*dp->dr_name)(),"couldn't return I/O vector", mp->m_source);
panic((*dp->dr_name)(),"couldn't return I/O vector", mp->m_source);
}
} else {
sys_datacopy(SELF, (vir_bytes) iovec,
mp->m_source, (vir_bytes) mp->ADDRESS, iovec_size);
} }
return(r); return(r);
@ -333,20 +371,17 @@ message *mp;
case DEV_OPEN: return(ENODEV); case DEV_OPEN: return(ENODEV);
case DEV_CLOSE: return(OK); case DEV_CLOSE: return(OK);
case DEV_IOCTL_S: case DEV_IOCTL_S:
#ifdef DEV_IOCTL default: printf("nop: ignoring code %d\n", mp->m_type);
case DEV_IOCTL: return(ENOTTY); return(EIO);
#endif
default: printf("nop: ignoring code %d\n", mp->m_type); return(EIO);
} }
} }
/*============================================================================* /*============================================================================*
* nop_ioctl * * nop_ioctl *
*============================================================================*/ *============================================================================*/
PUBLIC int nop_ioctl(dp, mp, safe) PUBLIC int nop_ioctl(dp, mp)
struct driver *dp; struct driver *dp;
message *mp; message *mp;
int safe;
{ {
return(ENOTTY); return(ENOTTY);
} }
@ -409,10 +444,9 @@ PUBLIC int nop_select(struct driver *dr, message *m)
/*============================================================================* /*============================================================================*
* do_diocntl * * do_diocntl *
*============================================================================*/ *============================================================================*/
PUBLIC int do_diocntl(dp, mp, safe) PUBLIC int do_diocntl(dp, mp)
struct driver *dp; struct driver *dp;
message *mp; /* pointer to ioctl request */ message *mp; /* pointer to ioctl request */
int safe; /* addresses or grants? */
{ {
/* Carry out a partition setting/getting request. */ /* Carry out a partition setting/getting request. */
struct device *dv; struct device *dv;
@ -421,7 +455,7 @@ int safe; /* addresses or grants? */
if (mp->REQUEST != DIOCSETP && mp->REQUEST != DIOCGETP) { if (mp->REQUEST != DIOCSETP && mp->REQUEST != DIOCGETP) {
if(dp->dr_other) { if(dp->dr_other) {
return dp->dr_other(dp, mp, safe); return dp->dr_other(dp, mp);
} else return(ENOTTY); } else return(ENOTTY);
} }
@ -430,13 +464,8 @@ int safe; /* addresses or grants? */
if (mp->REQUEST == DIOCSETP) { if (mp->REQUEST == DIOCSETP) {
/* Copy just this one partition table entry. */ /* Copy just this one partition table entry. */
if(safe) { s=sys_safecopyfrom(mp->IO_ENDPT, (vir_bytes) mp->IO_GRANT,
s=sys_safecopyfrom(mp->IO_ENDPT, (vir_bytes) mp->IO_GRANT, 0, (vir_bytes) &entry, sizeof(entry), D);
0, (vir_bytes) &entry, sizeof(entry), D);
} else{
s=sys_datacopy(mp->IO_ENDPT, (vir_bytes) mp->ADDRESS,
SELF, (vir_bytes) &entry, sizeof(entry));
}
if(s != OK) if(s != OK)
return s; return s;
dv->dv_base = entry.base; dv->dv_base = entry.base;
@ -446,13 +475,8 @@ int safe; /* addresses or grants? */
entry.base = dv->dv_base; entry.base = dv->dv_base;
entry.size = dv->dv_size; entry.size = dv->dv_size;
(*dp->dr_geometry)(&entry); (*dp->dr_geometry)(&entry);
if(safe) { s=sys_safecopyto(mp->IO_ENDPT, (vir_bytes) mp->IO_GRANT,
s=sys_safecopyto(mp->IO_ENDPT, (vir_bytes) mp->IO_GRANT, 0, (vir_bytes) &entry, sizeof(entry), D);
0, (vir_bytes) &entry, sizeof(entry), D);
} else {
s=sys_datacopy(SELF, (vir_bytes) &entry,
mp->IO_ENDPT, (vir_bytes) mp->ADDRESS, sizeof(entry));
}
if (OK != s) if (OK != s)
return s; return s;
} }

View File

@ -31,17 +31,17 @@ struct driver {
_PROTOTYPE( char *(*dr_name), (void) ); _PROTOTYPE( char *(*dr_name), (void) );
_PROTOTYPE( int (*dr_open), (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int (*dr_open), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_close), (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int (*dr_close), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_ioctl), (struct driver *dp, message *m_ptr, int safe) ); _PROTOTYPE( int (*dr_ioctl), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( struct device *(*dr_prepare), (int device) ); _PROTOTYPE( struct device *(*dr_prepare), (int device) );
_PROTOTYPE( int (*dr_transfer), (int proc_nr, int opcode, u64_t position, _PROTOTYPE( int (*dr_transfer), (int proc_nr, int opcode, u64_t position,
iovec_t *iov, unsigned nr_req, int safe) ); iovec_t *iov, unsigned nr_req) );
_PROTOTYPE( void (*dr_cleanup), (void) ); _PROTOTYPE( void (*dr_cleanup), (void) );
_PROTOTYPE( void (*dr_geometry), (struct partition *entry) ); _PROTOTYPE( void (*dr_geometry), (struct partition *entry) );
_PROTOTYPE( void (*dr_signal), (struct driver *dp, sigset_t *set) ); _PROTOTYPE( void (*dr_signal), (struct driver *dp, sigset_t *set) );
_PROTOTYPE( void (*dr_alarm), (struct driver *dp, message *m_ptr) ); _PROTOTYPE( void (*dr_alarm), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_cancel), (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int (*dr_cancel), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_select), (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int (*dr_select), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_other), (struct driver *dp, message *m_ptr, int safe) ); _PROTOTYPE( int (*dr_other), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_hw_int), (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int (*dr_hw_int), (struct driver *dp, message *m_ptr) );
}; };
@ -53,8 +53,11 @@ struct device {
#define NIL_DEV ((struct device *) 0) #define NIL_DEV ((struct device *) 0)
#define DRIVER_STD 0 /* Use the standard reply protocol */
#define DRIVER_ASYN 1 /* Use the new asynchronous protocol */
/* Functions defined by driver.c: */ /* Functions defined by driver.c: */
_PROTOTYPE( void driver_task, (struct driver *dr) ); _PROTOTYPE( void driver_task, (struct driver *dr, int type) );
_PROTOTYPE( char *no_name, (void) ); _PROTOTYPE( char *no_name, (void) );
_PROTOTYPE( int do_nop, (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int do_nop, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( struct device *nop_prepare, (int device) ); _PROTOTYPE( struct device *nop_prepare, (int device) );
@ -64,8 +67,8 @@ _PROTOTYPE( void nop_signal, (struct driver *dp, sigset_t *set) );
_PROTOTYPE( void nop_alarm, (struct driver *dp, message *m_ptr) ); _PROTOTYPE( void nop_alarm, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int nop_cancel, (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int nop_cancel, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int nop_select, (struct driver *dp, message *m_ptr) ); _PROTOTYPE( int nop_select, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int do_diocntl, (struct driver *dp, message *m_ptr, int safe) ); _PROTOTYPE( int do_diocntl, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int nop_ioctl, (struct driver *dp, message *m_ptr, int safe) ); _PROTOTYPE( int nop_ioctl, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int mq_queue, (message *m_ptr) ); _PROTOTYPE( int mq_queue, (message *m_ptr) );
_PROTOTYPE( void init_buffer, (void) ); _PROTOTYPE( void init_buffer, (void) );
@ -84,5 +87,3 @@ extern u8_t *tmp_buf; /* the DMA buffer */
extern u8_t tmp_buf[]; /* the DMA buffer */ extern u8_t tmp_buf[]; /* the DMA buffer */
#endif #endif
extern phys_bytes tmp_phys; /* phys address of DMA buffer */ extern phys_bytes tmp_phys; /* phys address of DMA buffer */
u32_t system_hz;

View File

@ -164,7 +164,7 @@ struct part_entry *table; /* four entries */
iovec1.iov_addr = (vir_bytes) partbuf; iovec1.iov_addr = (vir_bytes) partbuf;
iovec1.iov_size = CD_SECTOR_SIZE; iovec1.iov_size = CD_SECTOR_SIZE;
if ((*dp->dr_prepare)(device) != NIL_DEV) { if ((*dp->dr_prepare)(device) != NIL_DEV) {
(void) (*dp->dr_transfer)(SELF, DEV_GATHER_S, position, &iovec1, 1, 0); (void) (*dp->dr_transfer)(SELF, DEV_GATHER_S, position, &iovec1, 1);
} }
if (iovec1.iov_size != 0) { if (iovec1.iov_size != 0) {
return 0; return 0;

View File

@ -1,34 +0,0 @@
# Makefile for driver library
# Directories
u = /usr
i = $u/include
s = $i/sys
b = $i/ibm
m = $i/minix
# Programs, flags, etc.
CC = exec cc
CFLAGS = -I$i $(CPROFILE)
LDFLAGS = -i
LIBS = -lsys
LIB = libdriver.a
OBJECTS = driver.o drvlib.o mq.o
all build install: $(LIB)
$(LIB): $(OBJECTS)
ar rc $(LIB) $(OBJECTS)
# $(CC) -c $@ $(LDFLAGS) $(OBJ) $(LIBS)
clean:
rm -f *.o *.bak *.a
depend:
mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
# Include generated dependencies.
include .depend

View File

@ -1,631 +0,0 @@
/* This file contains device independent device driver interface.
*
* Changes:
* Sep 25, 2009 removed all macros depending on NOTIFY_FROM() (T. Hruby)
* Jul 25, 2005 added SYS_SIG type for signals (Jorrit N. Herder)
* Sep 15, 2004 added SYN_ALARM type for timeouts (Jorrit N. Herder)
* Jul 23, 2004 removed kernel dependencies (Jorrit N. Herder)
* Apr 02, 1992 constructed from AT wini and floppy driver (Kees J. Bot)
*
*
* The drivers support the following operations (using message format m2):
*
* m_type DEVICE IO_ENDPT COUNT POSITION ADRRESS
* ----------------------------------------------------------------
* | DEV_OPEN | device | proc nr | | | |
* |------------+---------+---------+---------+---------+---------|
* | DEV_CLOSE | device | proc nr | | | |
* |------------+---------+---------+---------+---------+---------|
* | DEV_READ | device | proc nr | bytes | offset | buf ptr |
* |------------+---------+---------+---------+---------+---------|
* | DEV_WRITE | device | proc nr | bytes | offset | buf ptr |
* |------------+---------+---------+---------+---------+---------|
* | DEV_GATHER | device | proc nr | iov len | offset | iov ptr |
* |------------+---------+---------+---------+---------+---------|
* | DEV_SCATTER| device | proc nr | iov len | offset | iov ptr |
* |------------+---------+---------+---------+---------+---------|
* | DEV_IOCTL | device | proc nr |func code| | buf ptr |
* |------------+---------+---------+---------+---------+---------|
* | CANCEL | device | proc nr | r/w | | |
* |------------+---------+---------+---------+---------+---------|
* | HARD_STOP | | | | | |
* |------------+---------+---------+---------+---------+---------|
* | DEV_*_S | variants using safecopies of above |
* ----------------------------------------------------------------
*
* The file contains one entry point:
*
* driver_task: called by the device dependent task entry
*/
#include "../drivers.h"
#include <sys/ioc_disk.h>
#include <minix/mq.h>
#include <minix/endpoint.h>
#include "driver.h"
/* Claim space for variables. */
u8_t *tmp_buf = NULL; /* the DMA buffer eventually */
phys_bytes tmp_phys; /* phys address of DMA buffer */
FORWARD _PROTOTYPE( void init_buffer, (void) );
FORWARD _PROTOTYPE( int do_rdwt, (struct driver *dr, message *mp, int safe) );
FORWARD _PROTOTYPE( int do_vrdwt, (struct driver *dr, message *mp, int safe) );
int device_caller;
PRIVATE mq_t *queue_head = NULL;
/*===========================================================================*
* driver_task *
*===========================================================================*/
PUBLIC void driver_task(dp)
struct driver *dp; /* Device dependent entry points. */
{
/* Main program of any device driver task. */
int r, proc_nr;
message mess, reply_mess;
sigset_t set;
/* Init MQ library. */
mq_init();
/* Here is the main loop of the disk task. It waits for a message, carries
* it out, and sends a reply.
*/
while (TRUE) {
/* Any queued messages? Oldest are at the head. */
if(queue_head) {
mq_t *mq;
mq = queue_head;
memcpy(&mess, &mq->mq_mess, sizeof(mess));
queue_head = queue_head->mq_next;
mq_free(mq);
} else {
int s;
/* Wait for a request to read or write a disk block. */
if ((s=receive(ANY, &mess)) != OK)
panic((*dp->dr_name)(),"receive() failed", s);
}
device_caller = mess.m_source;
proc_nr = mess.IO_ENDPT;
if (mess.m_type == DEV_SELECT)
{
static int first= 1;
if (first)
{
first= 0;
#if 0
printf(
"libdriver_asyn`driver_task: first DEV_SELECT: minor 0x%x, ops 0x%x\n",
mess.DEVICE, mess.IO_ENDPT);
#endif
}
}
/* Now carry out the work. */
if (is_notify(mess.m_type)) {
switch (_ENDPOINT_P(mess.m_source)) {
case HARDWARE:
/* leftover interrupt or expired timer. */
if(dp->dr_hw_int) {
(*dp->dr_hw_int)(dp, &mess);
}
break;
case PM_PROC_NR:
if (getsigset(&set) != 0) break;
(*dp->dr_signal)(dp, &set);
break;
case SYSTEM:
set = mess.NOTIFY_ARG;
(*dp->dr_signal)(dp, &set);
break;
case CLOCK:
(*dp->dr_alarm)(dp, &mess);
break;
case RS_PROC_NR:
notify(mess.m_source);
break;
default:
if(dp->dr_other)
r = (*dp->dr_other)(dp, &mess, 0);
else
r = EINVAL;
goto send_reply;
}
/* done, get a new message */
continue;
}
switch(mess.m_type) {
case DEV_OPEN: r = (*dp->dr_open)(dp, &mess); break;
case DEV_CLOSE: r = (*dp->dr_close)(dp, &mess); break;
#ifdef DEV_IOCTL
case DEV_IOCTL: r = (*dp->dr_ioctl)(dp, &mess, 0); break;
#endif
case DEV_IOCTL_S: r = (*dp->dr_ioctl)(dp, &mess, 1); break;
case CANCEL: r = (*dp->dr_cancel)(dp, &mess);break;
case DEV_SELECT: r = (*dp->dr_select)(dp, &mess);break;
#ifdef DEV_READ
case DEV_READ:
case DEV_WRITE: r = do_rdwt(dp, &mess, 0); break;
#endif
case DEV_READ_S:
case DEV_WRITE_S: r = do_rdwt(dp, &mess, 1); break;
#ifdef DEV_GATHER
case DEV_GATHER:
case DEV_SCATTER: r = do_vrdwt(dp, &mess, 0); break;
#endif
case DEV_GATHER_S:
case DEV_SCATTER_S: r = do_vrdwt(dp, &mess, 1); break;
default:
if(dp->dr_other)
r = (*dp->dr_other)(dp, &mess, 0);
else
r = EINVAL;
break;
}
send_reply:
/* Clean up leftover state. */
(*dp->dr_cleanup)();
/* Finally, prepare and send the reply message. */
if (r != EDONTREPLY) {
if (mess.m_type == DEV_OPEN)
{
reply_mess.m_type = DEV_REVIVE;
reply_mess.REP_ENDPT = proc_nr;
reply_mess.REP_STATUS = r;
}
else if (mess.m_type == DEV_CLOSE)
{
reply_mess.m_type = DEV_CLOSE_REPL;
reply_mess.REP_ENDPT = proc_nr;
reply_mess.REP_STATUS = r;
}
else if (mess.m_type == DEV_READ_S ||
mess.m_type == DEV_WRITE_S)
{
if (r == SUSPEND)
{
printf(
"driver_task: reviving %d with SUSPEND\n",
proc_nr);
}
reply_mess.m_type = DEV_REVIVE;
reply_mess.REP_ENDPT = proc_nr;
reply_mess.REP_IO_GRANT = (cp_grant_id_t)mess.ADDRESS;
reply_mess.REP_STATUS = r;
}
else if (mess.m_type == CANCEL)
{
continue; /* The original request should send a
* reply.
*/
}
else if (mess.m_type == DEV_SELECT)
{
reply_mess.m_type = DEV_SEL_REPL1;
reply_mess.DEV_MINOR = mess.DEVICE;
reply_mess.DEV_SEL_OPS = r;
}
else
{
#if 0
printf("driver_task: TASK_REPLY to req %d\n",
mess.m_type);
#endif
reply_mess.m_type = TASK_REPLY;
reply_mess.REP_ENDPT = proc_nr;
/* Status is # of bytes transferred or error code. */
reply_mess.REP_STATUS = r;
}
r= asynsend(device_caller, &reply_mess);
if (r != OK)
{
printf("driver_task: unable to asynsend to %d: %d\n",
device_caller, r);
}
}
}
}
/*===========================================================================*
* init_buffer *
*===========================================================================*/
PRIVATE void init_buffer()
{
/* Select a buffer that can safely be used for DMA transfers. It may also
* be used to read partition tables and such. Its absolute address is
* 'tmp_phys', the normal address is 'tmp_buf'.
*/
unsigned left;
if(!(tmp_buf = alloc_contig(2*DMA_BUF_SIZE, 0, &tmp_phys))) {
panic(__FILE__, "can't allocate tmp_buf", NO_NUM);
}
}
/*===========================================================================*
* do_rdwt *
*===========================================================================*/
PRIVATE int do_rdwt(dp, mp, safe)
struct driver *dp; /* device dependent entry points */
message *mp; /* pointer to read or write message */
int safe; /* use safecopies? */
{
/* Carry out a single read or write request. */
iovec_t iovec1;
int r, opcode;
phys_bytes phys_addr;
u64_t position;
/* Disk address? Address and length of the user buffer? */
if (mp->COUNT < 0) return(EINVAL);
/* Check the user buffer (not relevant for safe copies). */
if(!safe) {
sys_umap(mp->IO_ENDPT, D, (vir_bytes) mp->ADDRESS, mp->COUNT, &phys_addr);
if (phys_addr == 0) return(EFAULT);
}
/* Prepare for I/O. */
if ((*dp->dr_prepare)(mp->DEVICE) == NIL_DEV) return(ENXIO);
/* Create a one element scatter/gather vector for the buffer. */
if(
#ifdef DEV_READ
mp->m_type == DEV_READ ||
#endif
mp->m_type == DEV_READ_S) opcode = DEV_GATHER_S;
else opcode = DEV_SCATTER_S;
iovec1.iov_addr = (vir_bytes) mp->ADDRESS;
iovec1.iov_size = mp->COUNT;
/* Transfer bytes from/to the device. */
position= make64(mp->POSITION, mp->HIGHPOS);
r = (*dp->dr_transfer)(mp->IO_ENDPT, opcode, position, &iovec1, 1, safe);
/* Return the number of bytes transferred or an error code. */
return(r == OK ? (mp->COUNT - iovec1.iov_size) : r);
}
/*==========================================================================*
* do_vrdwt *
*==========================================================================*/
PRIVATE int do_vrdwt(dp, mp, safe)
struct driver *dp; /* device dependent entry points */
message *mp; /* pointer to read or write message */
int safe; /* use safecopies? */
{
/* Carry out an device read or write to/from a vector of user addresses.
* The "user addresses" are assumed to be safe, i.e. FS transferring to/from
* its own buffers, so they are not checked.
*/
static iovec_t iovec[NR_IOREQS];
iovec_t *iov;
phys_bytes iovec_size;
unsigned nr_req;
int r, j, opcode;
u64_t position;
nr_req = mp->COUNT; /* Length of I/O vector */
{
/* Copy the vector from the caller to kernel space. */
if (nr_req > NR_IOREQS) nr_req = NR_IOREQS;
iovec_size = (phys_bytes) (nr_req * sizeof(iovec[0]));
if(safe) {
if (OK != sys_safecopyfrom(mp->m_source, (vir_bytes) mp->IO_GRANT,
0, (vir_bytes) iovec, iovec_size, D)) {
panic((*dp->dr_name)(),"bad (safe) I/O vector by", mp->m_source);
}
} else {
if (OK != sys_datacopy(mp->m_source, (vir_bytes) mp->ADDRESS,
SELF, (vir_bytes) iovec, iovec_size)) {
panic((*dp->dr_name)(),"bad I/O vector by", mp->m_source);
}
}
iov = iovec;
}
/* Prepare for I/O. */
if ((*dp->dr_prepare)(mp->DEVICE) == NIL_DEV) return(ENXIO);
/* Transfer bytes from/to the device. */
opcode = mp->m_type;
position= make64(mp->POSITION, mp->HIGHPOS);
r = (*dp->dr_transfer)(mp->IO_ENDPT, opcode, position, iov,
nr_req, safe);
/* Copy the I/O vector back to the caller. */
if(safe) {
if (OK != sys_safecopyto(mp->m_source, (vir_bytes) mp->IO_GRANT,
0, (vir_bytes) iovec, iovec_size, D)) {
panic((*dp->dr_name)(),"couldn't return I/O vector", mp->m_source);
}
} else {
sys_datacopy(SELF, (vir_bytes) iovec,
mp->m_source, (vir_bytes) mp->ADDRESS, iovec_size);
}
return(r);
}
/*===========================================================================*
* no_name *
*===========================================================================*/
PUBLIC char *no_name()
{
/* Use this default name if there is no specific name for the device. This was
* originally done by fetching the name from the task table for this process:
* "return(tasktab[proc_number(proc_ptr) + NR_TASKS].name);", but currently a
* real "noname" is returned. Perhaps, some system information service can be
* queried for a name at a later time.
*/
static char name[] = "noname";
return name;
}
/*============================================================================*
* do_nop *
*============================================================================*/
PUBLIC int do_nop(dp, mp)
struct driver *dp;
message *mp;
{
/* Nothing there, or nothing to do. */
switch (mp->m_type) {
case DEV_OPEN: return(ENODEV);
case DEV_CLOSE: return(OK);
case DEV_IOCTL_S:
#ifdef DEV_IOCTL
case DEV_IOCTL: return(ENOTTY);
#endif
default: printf("nop: ignoring code %d\n", mp->m_type); return(EIO);
}
}
/*============================================================================*
* nop_ioctl *
*============================================================================*/
PUBLIC int nop_ioctl(dp, mp, safe)
struct driver *dp;
message *mp;
int safe;
{
return(ENOTTY);
}
/*============================================================================*
* nop_signal *
*============================================================================*/
PUBLIC void nop_signal(dp, set)
struct driver *dp;
sigset_t *set;
{
/* Default action for signal is to ignore. */
}
/*============================================================================*
* nop_alarm *
*============================================================================*/
PUBLIC void nop_alarm(dp, mp)
struct driver *dp;
message *mp;
{
/* Ignore the leftover alarm. */
}
/*===========================================================================*
* nop_prepare *
*===========================================================================*/
PUBLIC struct device *nop_prepare(device)
{
/* Nothing to prepare for. */
return(NIL_DEV);
}
/*===========================================================================*
* nop_cleanup *
*===========================================================================*/
PUBLIC void nop_cleanup()
{
/* Nothing to clean up. */
}
/*===========================================================================*
* nop_cancel *
*===========================================================================*/
PUBLIC int nop_cancel(struct driver *dr, message *m)
{
/* Nothing to do for cancel. */
return(OK);
}
/*===========================================================================*
* nop_select *
*===========================================================================*/
PUBLIC int nop_select(struct driver *dr, message *m)
{
/* Nothing to do for select. */
return(OK);
}
/*============================================================================*
* do_diocntl *
*============================================================================*/
PUBLIC int do_diocntl(dp, mp, safe)
struct driver *dp;
message *mp; /* pointer to ioctl request */
int safe; /* addresses or grants? */
{
/* Carry out a partition setting/getting request. */
struct device *dv;
struct partition entry;
int s;
if (mp->REQUEST != DIOCSETP && mp->REQUEST != DIOCGETP) {
if(dp->dr_other) {
return dp->dr_other(dp, mp, safe);
} else return(ENOTTY);
}
/* Decode the message parameters. */
if ((dv = (*dp->dr_prepare)(mp->DEVICE)) == NIL_DEV) return(ENXIO);
if (mp->REQUEST == DIOCSETP) {
/* Copy just this one partition table entry. */
if(safe) {
s=sys_safecopyfrom(mp->IO_ENDPT, (vir_bytes) mp->IO_GRANT,
0, (vir_bytes) &entry, sizeof(entry), D);
} else{
s=sys_datacopy(mp->IO_ENDPT, (vir_bytes) mp->ADDRESS,
SELF, (vir_bytes) &entry, sizeof(entry));
}
if(s != OK)
return s;
dv->dv_base = entry.base;
dv->dv_size = entry.size;
} else {
/* Return a partition table entry and the geometry of the drive. */
entry.base = dv->dv_base;
entry.size = dv->dv_size;
(*dp->dr_geometry)(&entry);
if(safe) {
s=sys_safecopyto(mp->IO_ENDPT, (vir_bytes) mp->IO_GRANT,
0, (vir_bytes) &entry, sizeof(entry), D);
} else {
s=sys_datacopy(SELF, (vir_bytes) &entry,
mp->IO_ENDPT, (vir_bytes) mp->ADDRESS, sizeof(entry));
}
if (OK != s)
return s;
}
return(OK);
}
/*===========================================================================*
* mq_queue *
*===========================================================================*/
PUBLIC int mq_queue(message *m)
{
mq_t *mq, *mi;
if(!(mq = mq_get()))
panic("libdriver","mq_queue: mq_get failed", NO_NUM);
memcpy(&mq->mq_mess, m, sizeof(mq->mq_mess));
mq->mq_next = NULL;
if(!queue_head) {
queue_head = mq;
} else {
for(mi = queue_head; mi->mq_next; mi = mi->mq_next)
;
mi->mq_next = mq;
}
return OK;
}
#if 0
#define ASYN_NR 100
PRIVATE asynmsg_t msgtable[ASYN_NR];
PRIVATE int first_slot= 0, next_slot= 0;
PUBLIC int asynsend(dst, mp)
endpoint_t dst;
message *mp;
{
int r, src_ind, dst_ind;
unsigned flags;
/* Update first_slot */
for (; first_slot < next_slot; first_slot++)
{
flags= msgtable[first_slot].flags;
if ((flags & (AMF_VALID|AMF_DONE)) == (AMF_VALID|AMF_DONE))
{
if (msgtable[first_slot].result != OK)
{
printf(
"asynsend: found completed entry %d with error %d\n",
first_slot,
msgtable[first_slot].result);
}
continue;
}
if (flags != AMF_EMPTY)
break;
}
if (first_slot >= next_slot)
{
/* Reset first_slot and next_slot */
next_slot= first_slot= 0;
}
if (next_slot >= ASYN_NR)
{
/* Tell the kernel to stop processing */
r= senda(NULL, 0);
if (r != OK)
panic(__FILE__, "asynsend: senda failed", r);
dst_ind= 0;
for (src_ind= first_slot; src_ind<next_slot; src_ind++)
{
flags= msgtable[src_ind].flags;
if ((flags & (AMF_VALID|AMF_DONE)) ==
(AMF_VALID|AMF_DONE))
{
if (msgtable[src_ind].result != OK)
{
printf(
"asynsend: found completed entry %d with error %d\n",
src_ind,
msgtable[src_ind].result);
}
continue;
}
if (flags == AMF_EMPTY)
continue;
#if 0
printf("asynsend: copying entry %d to %d\n",
src_ind, dst_ind);
#endif
if (src_ind != dst_ind)
msgtable[dst_ind]= msgtable[src_ind];
dst_ind++;
}
first_slot= 0;
next_slot= dst_ind;
if (next_slot >= ASYN_NR)
panic(__FILE__, "asynsend: msgtable full", NO_NUM);
}
msgtable[next_slot].dst= dst;
msgtable[next_slot].msg= *mp;
msgtable[next_slot].flags= AMF_VALID; /* Has to be last. The kernel
* scans this table while we
* are sleeping.
*/
next_slot++;
/* Tell the kernel to rescan the table */
return senda(msgtable+first_slot, next_slot-first_slot);
}
#endif

View File

@ -1,85 +0,0 @@
/* Types and constants shared between the generic and device dependent
* device driver code.
*/
#define _POSIX_SOURCE 1 /* tell headers to include POSIX stuff */
#define _MINIX 1 /* tell headers to include MINIX stuff */
#define _SYSTEM 1 /* get negative error number in <errno.h> */
/* The following are so basic, all the *.c files get them automatically. */
#include <minix/config.h> /* MUST be first */
#include <ansi.h> /* MUST be second */
#include <minix/type.h>
#include <minix/ipc.h>
#include <minix/com.h>
#include <minix/callnr.h>
#include <sys/types.h>
#include <minix/const.h>
#include <minix/syslib.h>
#include <minix/sysutil.h>
#include <string.h>
#include <limits.h>
#include <stddef.h>
#include <errno.h>
#include <minix/partition.h>
#include <minix/u64.h>
/* Info about and entry points into the device dependent code. */
struct driver {
_PROTOTYPE( char *(*dr_name), (void) );
_PROTOTYPE( int (*dr_open), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_close), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_ioctl), (struct driver *dp, message *m_ptr, int safe) );
_PROTOTYPE( struct device *(*dr_prepare), (int device) );
_PROTOTYPE( int (*dr_transfer), (int proc_nr, int opcode, u64_t position,
iovec_t *iov, unsigned nr_req, int safe) );
_PROTOTYPE( void (*dr_cleanup), (void) );
_PROTOTYPE( void (*dr_geometry), (struct partition *entry) );
_PROTOTYPE( void (*dr_signal), (struct driver *dp, sigset_t *set) );
_PROTOTYPE( void (*dr_alarm), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_cancel), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_select), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_other), (struct driver *dp, message *m_ptr, int safe) );
_PROTOTYPE( int (*dr_hw_int), (struct driver *dp, message *m_ptr) );
};
/* Base and size of a partition in bytes. */
struct device {
u64_t dv_base;
u64_t dv_size;
};
#define NIL_DEV ((struct device *) 0)
/* Functions defined by driver.c: */
_PROTOTYPE( void driver_task, (struct driver *dr) );
_PROTOTYPE( char *no_name, (void) );
_PROTOTYPE( int do_nop, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( struct device *nop_prepare, (int device) );
_PROTOTYPE( void nop_cleanup, (void) );
_PROTOTYPE( void nop_task, (void) );
_PROTOTYPE( void nop_signal, (struct driver *dp, sigset_t *set) );
_PROTOTYPE( void nop_alarm, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int nop_cancel, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int nop_select, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int do_diocntl, (struct driver *dp, message *m_ptr, int safe) );
_PROTOTYPE( int nop_ioctl, (struct driver *dp, message *m_ptr, int safe) );
_PROTOTYPE( int mq_queue, (message *m_ptr) );
/* Parameters for the disk drive. */
#define SECTOR_SIZE 512 /* physical sector size in bytes */
#define SECTOR_SHIFT 9 /* for division */
#define SECTOR_MASK 511 /* and remainder */
/* Size of the DMA buffer buffer in bytes. */
#define USE_EXTRA_DMA_BUF 0 /* usually not needed */
#define DMA_BUF_SIZE (DMA_SECTORS * SECTOR_SIZE)
#if (CHIP == INTEL)
extern u8_t *tmp_buf; /* the DMA buffer */
#else
extern u8_t tmp_buf[]; /* the DMA buffer */
#endif
extern phys_bytes tmp_phys; /* phys address of DMA buffer */

View File

@ -1,199 +0,0 @@
/* IBM device driver utility functions. Author: Kees J. Bot
* 7 Dec 1995
* Entry point:
* partition: partition a disk to the partition table(s) on it.
*/
#include "driver.h"
#include "drvlib.h"
#include <unistd.h>
/* Extended partition? */
#define ext_part(s) ((s) == 0x05 || (s) == 0x0F)
FORWARD _PROTOTYPE( void extpartition, (struct driver *dp, int extdev,
unsigned long extbase) );
FORWARD _PROTOTYPE( int get_part_table, (struct driver *dp, int device,
unsigned long offset, struct part_entry *table));
FORWARD _PROTOTYPE( void sort, (struct part_entry *table) );
#ifndef CD_SECTOR_SIZE
#define CD_SECTOR_SIZE 2048
#endif
/*============================================================================*
* partition *
*============================================================================*/
PUBLIC void partition(dp, device, style, atapi)
struct driver *dp; /* device dependent entry points */
int device; /* device to partition */
int style; /* partitioning style: floppy, primary, sub. */
int atapi; /* atapi device */
{
/* This routine is called on first open to initialize the partition tables
* of a device. It makes sure that each partition falls safely within the
* device's limits. Depending on the partition style we are either making
* floppy partitions, primary partitions or subpartitions. Only primary
* partitions are sorted, because they are shared with other operating
* systems that expect this.
*/
struct part_entry table[NR_PARTITIONS], *pe;
int disk, par;
struct device *dv;
unsigned long base, limit, part_limit;
/* Get the geometry of the device to partition */
if ((dv = (*dp->dr_prepare)(device)) == NIL_DEV
|| cmp64u(dv->dv_size, 0) == 0) return;
base = div64u(dv->dv_base, SECTOR_SIZE);
limit = base + div64u(dv->dv_size, SECTOR_SIZE);
/* Read the partition table for the device. */
if(!get_part_table(dp, device, 0L, table)) {
return;
}
/* Compute the device number of the first partition. */
switch (style) {
case P_FLOPPY:
device += MINOR_fd0p0;
break;
case P_PRIMARY:
sort(table); /* sort a primary partition table */
device += 1;
break;
case P_SUB:
disk = device / DEV_PER_DRIVE;
par = device % DEV_PER_DRIVE - 1;
device = MINOR_d0p0s0 + (disk * NR_PARTITIONS + par) * NR_PARTITIONS;
}
/* Find an array of devices. */
if ((dv = (*dp->dr_prepare)(device)) == NIL_DEV) return;
/* Set the geometry of the partitions from the partition table. */
for (par = 0; par < NR_PARTITIONS; par++, dv++) {
/* Shrink the partition to fit within the device. */
pe = &table[par];
part_limit = pe->lowsec + pe->size;
if (part_limit < pe->lowsec) part_limit = limit;
if (part_limit > limit) part_limit = limit;
if (pe->lowsec < base) pe->lowsec = base;
if (part_limit < pe->lowsec) part_limit = pe->lowsec;
dv->dv_base = mul64u(pe->lowsec, SECTOR_SIZE);
dv->dv_size = mul64u(part_limit - pe->lowsec, SECTOR_SIZE);
if (style == P_PRIMARY) {
/* Each Minix primary partition can be subpartitioned. */
if (pe->sysind == MINIX_PART)
partition(dp, device + par, P_SUB, atapi);
/* An extended partition has logical partitions. */
if (ext_part(pe->sysind))
extpartition(dp, device + par, pe->lowsec);
}
}
}
/*============================================================================*
* extpartition *
*============================================================================*/
PRIVATE void extpartition(dp, extdev, extbase)
struct driver *dp; /* device dependent entry points */
int extdev; /* extended partition to scan */
unsigned long extbase; /* sector offset of the base extended partition */
{
/* Extended partitions cannot be ignored alas, because people like to move
* files to and from DOS partitions. Avoid reading this code, it's no fun.
*/
struct part_entry table[NR_PARTITIONS], *pe;
int subdev, disk, par;
struct device *dv;
unsigned long offset, nextoffset;
disk = extdev / DEV_PER_DRIVE;
par = extdev % DEV_PER_DRIVE - 1;
subdev = MINOR_d0p0s0 + (disk * NR_PARTITIONS + par) * NR_PARTITIONS;
offset = 0;
do {
if (!get_part_table(dp, extdev, offset, table)) return;
sort(table);
/* The table should contain one logical partition and optionally
* another extended partition. (It's a linked list.)
*/
nextoffset = 0;
for (par = 0; par < NR_PARTITIONS; par++) {
pe = &table[par];
if (ext_part(pe->sysind)) {
nextoffset = pe->lowsec;
} else
if (pe->sysind != NO_PART) {
if ((dv = (*dp->dr_prepare)(subdev)) == NIL_DEV) return;
dv->dv_base = mul64u(extbase + offset + pe->lowsec,
SECTOR_SIZE);
dv->dv_size = mul64u(pe->size, SECTOR_SIZE);
/* Out of devices? */
if (++subdev % NR_PARTITIONS == 0) return;
}
}
} while ((offset = nextoffset) != 0);
}
/*============================================================================*
* get_part_table *
*============================================================================*/
PRIVATE int get_part_table(dp, device, offset, table)
struct driver *dp;
int device;
unsigned long offset; /* sector offset to the table */
struct part_entry *table; /* four entries */
{
/* Read the partition table for the device, return true iff there were no
* errors.
*/
iovec_t iovec1;
u64_t position;
static unsigned char partbuf[CD_SECTOR_SIZE];
position = mul64u(offset, SECTOR_SIZE);
iovec1.iov_addr = (vir_bytes) partbuf;
iovec1.iov_size = CD_SECTOR_SIZE;
if ((*dp->dr_prepare)(device) != NIL_DEV) {
(void) (*dp->dr_transfer)(SELF, DEV_GATHER_S, position, &iovec1, 1, 0);
}
if (iovec1.iov_size != 0) {
return 0;
}
if (partbuf[510] != 0x55 || partbuf[511] != 0xAA) {
/* Invalid partition table. */
return 0;
}
memcpy(table, (partbuf + PART_TABLE_OFF), NR_PARTITIONS * sizeof(table[0]));
return 1;
}
/*===========================================================================*
* sort *
*===========================================================================*/
PRIVATE void sort(table)
struct part_entry *table;
{
/* Sort a partition table. */
struct part_entry *pe, tmp;
int n = NR_PARTITIONS;
do {
for (pe = table; pe < table + NR_PARTITIONS-1; pe++) {
if (pe[0].sysind == NO_PART
|| (pe[0].lowsec > pe[1].lowsec
&& pe[1].sysind != NO_PART)) {
tmp = pe[0]; pe[0] = pe[1]; pe[1] = tmp;
}
}
} while (--n > 0);
}

View File

@ -1,27 +0,0 @@
/* IBM device driver definitions Author: Kees J. Bot
* 7 Dec 1995
*/
#include <ibm/partition.h>
_PROTOTYPE( void partition, (struct driver *dr, int device, int style, int atapi) );
/* BIOS parameter table layout. */
#define bp_cylinders(t) (* (u16_t *) (&(t)[0]))
#define bp_heads(t) (* (u8_t *) (&(t)[2]))
#define bp_reduced_wr(t) (* (u16_t *) (&(t)[3]))
#define bp_precomp(t) (* (u16_t *) (&(t)[5]))
#define bp_max_ecc(t) (* (u8_t *) (&(t)[7]))
#define bp_ctlbyte(t) (* (u8_t *) (&(t)[8]))
#define bp_landingzone(t) (* (u16_t *) (&(t)[12]))
#define bp_sectors(t) (* (u8_t *) (&(t)[14]))
/* Miscellaneous. */
#define DEV_PER_DRIVE (1 + NR_PARTITIONS)
#define MINOR_t0 64
#define MINOR_r0 120
#define MINOR_d0p0s0 128
#define MINOR_fd0p0 (28<<2)
#define P_FLOPPY 0
#define P_PRIMARY 1
#define P_SUB 2

View File

@ -1,61 +0,0 @@
/*
inet/mq.c
Created: Jan 3, 1992 by Philip Homburg
Copyright 1995 Philip Homburg
*/
#include <ansi.h>
#include <assert.h>
#include <minix/config.h>
#include <minix/const.h>
#include <minix/type.h>
#include <minix/ipc.h>
#include <minix/mq.h>
#define MQ_SIZE 128
PRIVATE mq_t mq_list[MQ_SIZE];
PRIVATE mq_t *mq_freelist;
void mq_init()
{
int i;
mq_freelist= NULL;
for (i= 0; i<MQ_SIZE; i++)
{
mq_list[i].mq_next= mq_freelist;
mq_freelist= &mq_list[i];
mq_list[i].mq_allocated= 0;
}
}
mq_t *mq_get()
{
mq_t *mq;
mq= mq_freelist;
assert(mq != NULL);
mq_freelist= mq->mq_next;
mq->mq_next= NULL;
assert(mq->mq_allocated == 0);
mq->mq_allocated= 1;
return mq;
}
void mq_free(mq)
mq_t *mq;
{
mq->mq_next= mq_freelist;
mq_freelist= mq;
assert(mq->mq_allocated == 1);
mq->mq_allocated= 0;
}
/*
* $PchId: mq.c,v 1.7 1998/10/23 20:10:47 philip Exp $
*/

View File

@ -12,9 +12,9 @@ d = ..
MAKE = exec make MAKE = exec make
CC = exec cc CC = exec cc
CFLAGS = -I$i $(CPROFILE) CFLAGS = -I$i $(CPROFILE)
LDFLAGS = -i -L../libdriver_asyn LDFLAGS = -i -L../libdriver
LIBS = -ldriver -lsys LIBS = -ldriver -lsys
LIB_DEP = ../libdriver_asyn/libdriver.a LIB_DEP = ../libdriver/libdriver.a
OBJ = log.o diag.o OBJ = log.o diag.o

View File

@ -25,14 +25,14 @@ PRIVATE int log_device = -1; /* current device */
FORWARD _PROTOTYPE( char *log_name, (void) ); FORWARD _PROTOTYPE( char *log_name, (void) );
FORWARD _PROTOTYPE( struct device *log_prepare, (int device) ); FORWARD _PROTOTYPE( struct device *log_prepare, (int device) );
FORWARD _PROTOTYPE( int log_transfer, (int proc_nr, int opcode, u64_t position, FORWARD _PROTOTYPE( int log_transfer, (int proc_nr, int opcode, u64_t position,
iovec_t *iov, unsigned nr_req, int safe) ); iovec_t *iov, unsigned nr_req) );
FORWARD _PROTOTYPE( int log_do_open, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int log_do_open, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int log_cancel, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int log_cancel, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int log_select, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int log_select, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void log_signal, (struct driver *dp, sigset_t *set) ); FORWARD _PROTOTYPE( void log_signal, (struct driver *dp, sigset_t *set) );
FORWARD _PROTOTYPE( int log_other, (struct driver *dp, message *m_ptr, int) ); FORWARD _PROTOTYPE( int log_other, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void log_geometry, (struct partition *entry) ); FORWARD _PROTOTYPE( void log_geometry, (struct partition *entry) );
FORWARD _PROTOTYPE( int subread, (struct logdevice *log, int count, int proc_nr, vir_bytes user_vir, size_t, int safe) ); FORWARD _PROTOTYPE( int subread, (struct logdevice *log, int count, int proc_nr, vir_bytes user_vir, size_t) );
/* Entry points to this driver. */ /* Entry points to this driver. */
PRIVATE struct driver log_dtab = { PRIVATE struct driver log_dtab = {
@ -71,7 +71,7 @@ PUBLIC int main(void)
logdevices[i].log_proc_nr = 0; logdevices[i].log_proc_nr = 0;
logdevices[i].log_revive_alerted = 0; logdevices[i].log_revive_alerted = 0;
} }
driver_task(&log_dtab); driver_task(&log_dtab, DRIVER_ASYN);
return(OK); return(OK);
} }
@ -100,11 +100,11 @@ int device;
} }
/*===========================================================================* /*===========================================================================*
* subwrite * * subwrite *
*===========================================================================*/ *===========================================================================*/
PRIVATE int PRIVATE int
subwrite(struct logdevice *log, int count, int proc_nr, subwrite(struct logdevice *log, int count, int proc_nr,
vir_bytes user_vir, size_t offset, int safe) vir_bytes user_vir, size_t offset)
{ {
int d, r; int d, r;
char *buf; char *buf;
@ -118,15 +118,9 @@ subwrite(struct logdevice *log, int count, int proc_nr,
memcpy(buf, (char *) user_vir, count); memcpy(buf, (char *) user_vir, count);
} }
else { else {
if(safe) { if((r=sys_safecopyfrom(proc_nr, user_vir, offset,
if((r=sys_safecopyfrom(proc_nr, user_vir, offset,
(vir_bytes)buf, count, D)) != OK) (vir_bytes)buf, count, D)) != OK)
return r; return r;
} else {
if((r=sys_vircopy(proc_nr, D,
user_vir + offset, SELF,D,(int)buf, count)) != OK)
return r;
}
} }
LOGINC(log->log_write, count); LOGINC(log->log_write, count);
@ -145,7 +139,7 @@ subwrite(struct logdevice *log, int count, int proc_nr,
*/ */
log->log_status = subread(log, log->log_iosize, log->log_status = subread(log, log->log_iosize,
log->log_proc_nr, log->log_user_vir_g, log->log_proc_nr, log->log_user_vir_g,
log->log_user_vir_offset, log->log_safe); log->log_user_vir_offset);
m.m_type = DEV_REVIVE; m.m_type = DEV_REVIVE;
m.REP_ENDPT = log->log_proc_nr; m.REP_ENDPT = log->log_proc_nr;
@ -204,10 +198,10 @@ log_append(char *buf, int count)
if(count > LOG_SIZE) skip = count - LOG_SIZE; if(count > LOG_SIZE) skip = count - LOG_SIZE;
count -= skip; count -= skip;
buf += skip; buf += skip;
w = subwrite(&logdevices[0], count, SELF, (vir_bytes) buf,0,0); w = subwrite(&logdevices[0], count, SELF, (vir_bytes) buf,0);
if(w > 0 && w < count) if(w > 0 && w < count)
subwrite(&logdevices[0], count-w, SELF, (vir_bytes) buf+w,0,0); subwrite(&logdevices[0], count-w, SELF, (vir_bytes) buf+w,0);
return; return;
} }
@ -216,7 +210,7 @@ log_append(char *buf, int count)
*===========================================================================*/ *===========================================================================*/
PRIVATE int PRIVATE int
subread(struct logdevice *log, int count, int proc_nr, subread(struct logdevice *log, int count, int proc_nr,
vir_bytes user_vir, size_t offset, int safe) vir_bytes user_vir, size_t offset)
{ {
char *buf; char *buf;
int r; int r;
@ -226,11 +220,9 @@ subread(struct logdevice *log, int count, int proc_nr,
count = LOG_SIZE - log->log_read; count = LOG_SIZE - log->log_read;
buf = log->log_buffer + log->log_read; buf = log->log_buffer + log->log_read;
if(safe) { if((r=sys_safecopyto(proc_nr, user_vir, offset,
if((r=sys_safecopyto(proc_nr, user_vir, offset,
(vir_bytes)buf, count, D)) != OK) (vir_bytes)buf, count, D)) != OK)
return r; return r;
}
LOGINC(log->log_read, count); LOGINC(log->log_read, count);
log->log_size -= count; log->log_size -= count;
@ -241,13 +233,12 @@ subread(struct logdevice *log, int count, int proc_nr,
/*===========================================================================* /*===========================================================================*
* log_transfer * * log_transfer *
*===========================================================================*/ *===========================================================================*/
PRIVATE int log_transfer(proc_nr, opcode, position, iov, nr_req, safe) PRIVATE int log_transfer(proc_nr, opcode, position, iov, nr_req)
int proc_nr; /* process doing the request */ int proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER_S or DEV_SCATTER_S */ int opcode; /* DEV_GATHER_S or DEV_SCATTER_S */
u64_t position; /* offset on device to read or write */ u64_t position; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe; /* safe copies? */
{ {
/* Read or write one the driver's minor devices. */ /* Read or write one the driver's minor devices. */
unsigned count; unsigned count;
@ -292,7 +283,6 @@ int safe; /* safe copies? */
log->log_user_vir_g = user_vir; log->log_user_vir_g = user_vir;
log->log_user_vir_offset = 0; log->log_user_vir_offset = 0;
log->log_revive_alerted = 0; log->log_revive_alerted = 0;
log->log_safe = safe;
/* Device_caller is a global in drivers library. */ /* Device_caller is a global in drivers library. */
log->log_source = device_caller; log->log_source = device_caller;
@ -302,13 +292,13 @@ int safe; /* safe copies? */
#endif #endif
return(EDONTREPLY); return(EDONTREPLY);
} }
count = subread(log, count, proc_nr, user_vir, vir_offset, safe); count = subread(log, count, proc_nr, user_vir, vir_offset);
if(count < 0) { if(count < 0) {
return count; return count;
} }
accumulated_read += count; accumulated_read += count;
} else { } else {
count = subwrite(log, count, proc_nr, user_vir, vir_offset, safe); count = subwrite(log, count, proc_nr, user_vir, vir_offset);
if(count < 0) if(count < 0)
return count; return count;
} }
@ -382,10 +372,9 @@ sigset_t *set;
/*============================================================================* /*============================================================================*
* log_other * * log_other *
*============================================================================*/ *============================================================================*/
PRIVATE int log_other(dp, m_ptr, safe) PRIVATE int log_other(dp, m_ptr)
struct driver *dp; struct driver *dp;
message *m_ptr; message *m_ptr;
int safe;
{ {
int r; int r;

View File

@ -24,7 +24,6 @@ struct logdevice {
log_revive_alerted, log_revive_alerted,
log_status; /* proc that is blocking on read */ log_status; /* proc that is blocking on read */
vir_bytes log_user_vir_g, log_user_vir_offset; vir_bytes log_user_vir_g, log_user_vir_offset;
int log_safe;
#endif #endif
int log_selected, log_select_proc, int log_selected, log_select_proc,
log_select_alerted, log_select_ready_ops; log_select_alerted, log_select_ready_ops;

View File

@ -50,12 +50,12 @@ PRIVATE int openct[NR_DEVS];
FORWARD _PROTOTYPE( char *m_name, (void) ); FORWARD _PROTOTYPE( char *m_name, (void) );
FORWARD _PROTOTYPE( struct device *m_prepare, (int device) ); FORWARD _PROTOTYPE( struct device *m_prepare, (int device) );
FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode, u64_t position, FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode,
iovec_t *iov, unsigned nr_req, int safe)); u64_t position, iovec_t *iov, unsigned nr_req) );
FORWARD _PROTOTYPE( int m_do_open, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int m_do_open, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int m_do_close, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int m_do_close, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void m_init, (void) ); FORWARD _PROTOTYPE( void m_init, (void) );
FORWARD _PROTOTYPE( int m_ioctl, (struct driver *dp, message *m_ptr, int safe)); FORWARD _PROTOTYPE( int m_ioctl, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void m_geometry, (struct partition *entry) ); FORWARD _PROTOTYPE( void m_geometry, (struct partition *entry) );
/* Entry points to this driver. */ /* Entry points to this driver. */
@ -96,9 +96,9 @@ PUBLIC int main(void)
sa.sa_flags = 0; sa.sa_flags = 0;
if (sigaction(SIGTERM,&sa,NULL)<0) panic("MEM","sigaction failed", errno); if (sigaction(SIGTERM,&sa,NULL)<0) panic("MEM","sigaction failed", errno);
m_init(); m_init();
driver_task(&m_dtab); driver_task(&m_dtab, DRIVER_STD);
return(OK); return(OK);
} }
/*===========================================================================* /*===========================================================================*
@ -127,13 +127,12 @@ int device;
/*===========================================================================* /*===========================================================================*
* m_transfer * * m_transfer *
*===========================================================================*/ *===========================================================================*/
PRIVATE int m_transfer(proc_nr, opcode, pos64, iov, nr_req, safe) PRIVATE int m_transfer(proc_nr, opcode, pos64, iov, nr_req)
int proc_nr; /* process doing the request */ int proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER_S or DEV_SCATTER_S */ int opcode; /* DEV_GATHER_S or DEV_SCATTER_S */
u64_t pos64; /* offset on device to read or write */ u64_t pos64; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe; /* safe copies */
{ {
/* Read or write one the driver's minor devices. */ /* Read or write one the driver's minor devices. */
unsigned count, left, chunk; unsigned count, left, chunk;
@ -144,11 +143,6 @@ int safe; /* safe copies */
off_t position; off_t position;
vir_bytes dev_vaddr; vir_bytes dev_vaddr;
if(!safe) {
printf("m_transfer: unsafe?\n");
return EPERM;
}
/* ZERO_DEV and NULL_DEV are infinite in size. */ /* ZERO_DEV and NULL_DEV are infinite in size. */
if (m_device != ZERO_DEV && m_device != NULL_DEV && ex64hi(pos64) != 0) if (m_device != ZERO_DEV && m_device != NULL_DEV && ex64hi(pos64) != 0)
return OK; /* Beyond EOF */ return OK; /* Beyond EOF */
@ -390,21 +384,15 @@ PRIVATE void m_init()
/*===========================================================================* /*===========================================================================*
* m_ioctl * * m_ioctl *
*===========================================================================*/ *===========================================================================*/
PRIVATE int m_ioctl(dp, m_ptr, safe) PRIVATE int m_ioctl(dp, m_ptr)
struct driver *dp; /* pointer to driver structure */ struct driver *dp; /* pointer to driver structure */
message *m_ptr; /* pointer to control message */ message *m_ptr; /* pointer to control message */
int safe;
{ {
/* I/O controls for the memory driver. Currently there is one I/O control: /* I/O controls for the memory driver. Currently there is one I/O control:
* - MIOCRAMSIZE: to set the size of the RAM disk. * - MIOCRAMSIZE: to set the size of the RAM disk.
*/ */
struct device *dv; struct device *dv;
if(!safe) {
printf("m_transfer: unsafe?\n");
return EPERM;
}
switch (m_ptr->REQUEST) { switch (m_ptr->REQUEST) {
case MIOCRAMSIZE: { case MIOCRAMSIZE: {
/* Someone wants to create a new RAM disk with the given size. */ /* Someone wants to create a new RAM disk with the given size. */
@ -465,7 +453,7 @@ int safe;
} }
default: default:
return(do_diocntl(&m_dtab, m_ptr, safe)); return(do_diocntl(&m_dtab, m_ptr));
} }
return(OK); return(OK);
} }

View File

@ -13,9 +13,9 @@ d = ..
MAKE = exec make MAKE = exec make
CC = exec cc CC = exec cc
CFLAGS = -I$i $(CPROFILE) CFLAGS = -I$i $(CPROFILE)
LDFLAGS = -i -L../libdriver_asyn LDFLAGS = -i -L../libdriver
LIBS = -ldriver -lsys LIBS = -ldriver -lsys
LIB_DEPS=../libdriver_asyn/libdriver.a LIB_DEPS=../libdriver/libdriver.a
OBJ = main.o random.o sha2.o aes/rijndael_api.o aes/rijndael_alg.o OBJ = main.o random.o sha2.o aes/rijndael_api.o aes/rijndael_alg.o

View File

@ -24,10 +24,10 @@ extern int errno; /* error number for PM calls */
FORWARD _PROTOTYPE( char *r_name, (void) ); FORWARD _PROTOTYPE( char *r_name, (void) );
FORWARD _PROTOTYPE( struct device *r_prepare, (int device) ); FORWARD _PROTOTYPE( struct device *r_prepare, (int device) );
FORWARD _PROTOTYPE( int r_transfer, (int proc_nr, int opcode, u64_t position, FORWARD _PROTOTYPE( int r_transfer, (int proc_nr, int opcode, u64_t position,
iovec_t *iov, unsigned nr_req, int safe) ); iovec_t *iov, unsigned nr_req) );
FORWARD _PROTOTYPE( int r_do_open, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( int r_do_open, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void r_init, (void) ); FORWARD _PROTOTYPE( void r_init, (void) );
FORWARD _PROTOTYPE( int r_ioctl, (struct driver *dp, message *m_ptr, int safe) ); FORWARD _PROTOTYPE( int r_ioctl, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void r_geometry, (struct partition *entry) ); FORWARD _PROTOTYPE( void r_geometry, (struct partition *entry) );
FORWARD _PROTOTYPE( void r_random, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( void r_random, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void r_updatebin, (int source, struct k_randomness_bin *rb)); FORWARD _PROTOTYPE( void r_updatebin, (int source, struct k_randomness_bin *rb));
@ -59,8 +59,8 @@ PRIVATE char random_buf[RANDOM_BUF_SIZE];
*===========================================================================*/ *===========================================================================*/
PUBLIC int main(void) PUBLIC int main(void)
{ {
r_init(); /* initialize the memory driver */ r_init(); /* initialize the memory driver */
driver_task(&r_dtab); /* start driver's main loop */ driver_task(&r_dtab, DRIVER_ASYN); /* start driver's main loop */
return(OK); return(OK);
} }
@ -91,13 +91,12 @@ int device;
/*===========================================================================* /*===========================================================================*
* r_transfer * * r_transfer *
*===========================================================================*/ *===========================================================================*/
PRIVATE int r_transfer(proc_nr, opcode, position, iov, nr_req, safe) PRIVATE int r_transfer(proc_nr, opcode, position, iov, nr_req)
int proc_nr; /* process doing the request */ int proc_nr; /* process doing the request */
int opcode; /* DEV_GATHER or DEV_SCATTER */ int opcode; /* DEV_GATHER or DEV_SCATTER */
u64_t position; /* offset on device to read or write */ u64_t position; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */ iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */ unsigned nr_req; /* length of request vector */
int safe; /* safe copies? */
{ {
/* Read or write one the driver's minor devices. */ /* Read or write one the driver's minor devices. */
unsigned count, left, chunk; unsigned count, left, chunk;
@ -128,34 +127,24 @@ int safe; /* safe copies? */
chunk = (left > RANDOM_BUF_SIZE) ? RANDOM_BUF_SIZE : left; chunk = (left > RANDOM_BUF_SIZE) ? RANDOM_BUF_SIZE : left;
if (opcode == DEV_GATHER_S) { if (opcode == DEV_GATHER_S) {
random_getbytes(random_buf, chunk); random_getbytes(random_buf, chunk);
if(safe) { r= sys_safecopyto(proc_nr, user_vir, vir_offset,
r= sys_safecopyto(proc_nr, user_vir, vir_offset, (vir_bytes) random_buf, chunk, D);
(vir_bytes) random_buf, chunk, D); if (r != OK)
if (r != OK) {
{ printf(
printf( "random: sys_safecopyto failed for proc %d, grant %d\n",
"random: sys_safecopyto failed for proc %d, grant %d\n", proc_nr, user_vir);
proc_nr, user_vir); return r;
return r;
}
} else {
sys_vircopy(SELF, D, (vir_bytes) random_buf,
proc_nr, D, user_vir + vir_offset, chunk);
} }
} else if (opcode == DEV_SCATTER_S) { } else if (opcode == DEV_SCATTER_S) {
if(safe) { r= sys_safecopyfrom(proc_nr, user_vir, vir_offset,
r= sys_safecopyfrom(proc_nr, user_vir, vir_offset, (vir_bytes) random_buf, chunk, D);
(vir_bytes) random_buf, chunk, D); if (r != OK)
if (r != OK) {
{ printf(
printf(
"random: sys_safecopyfrom failed for proc %d, grant %d\n", "random: sys_safecopyfrom failed for proc %d, grant %d\n",
proc_nr, user_vir); proc_nr, user_vir);
return r; return r;
}
} else {
sys_vircopy(proc_nr, D, user_vir + vir_offset,
SELF, D, (vir_bytes) random_buf, chunk);
} }
random_putbytes(random_buf, chunk); random_putbytes(random_buf, chunk);
} }
@ -225,10 +214,9 @@ PRIVATE void r_init()
/*===========================================================================* /*===========================================================================*
* r_ioctl * * r_ioctl *
*===========================================================================*/ *===========================================================================*/
PRIVATE int r_ioctl(dp, m_ptr, safe) PRIVATE int r_ioctl(dp, m_ptr)
struct driver *dp; /* pointer to driver structure */ struct driver *dp; /* pointer to driver structure */
message *m_ptr; /* pointer to control message */ message *m_ptr; /* pointer to control message */
int safe; /* safe i/o? */
{ {
struct device *dv; struct device *dv;
if ((dv = r_prepare(m_ptr->DEVICE)) == NIL_DEV) return(ENXIO); if ((dv = r_prepare(m_ptr->DEVICE)) == NIL_DEV) return(ENXIO);
@ -236,7 +224,7 @@ int safe; /* safe i/o? */
switch (m_ptr->REQUEST) { switch (m_ptr->REQUEST) {
default: default:
return(do_diocntl(&r_dtab, m_ptr, safe)); return(do_diocntl(&r_dtab, m_ptr));
} }
return(OK); return(OK);
} }