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:
parent
4924d1a9b5
commit
30a7fe5fa9
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
|
||||||
|
|
@ -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
|
|
@ -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 */
|
|
@ -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);
|
|
||||||
}
|
|
@ -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
|
|
@ -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 $
|
|
||||||
*/
|
|
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user