build: all
all install depend clean:
cd ./libdriver && $(MAKE) $@
- cd ./libdriver_asyn && $(MAKE) $@
cd ./tty && $(MAKE) $@
cd ./amddev && $(MAKE) $@
cd ./at_wini && $(MAKE) $@
image:
cd ./libdriver && $(MAKE) build
- cd ./libdriver_asyn && $(MAKE) build
cd ./tty && $(MAKE) build
cd ./at_wini && $(MAKE) build
cd ./floppy && $(MAKE) build
int w_next_drive = 0;
+u32_t system_hz;
+
/* Variables. */
/* The struct wini is indexed by controller first, then drive (0-3).
FORWARD _PROTOTYPE( int w_specify, (void) );
FORWARD _PROTOTYPE( int w_io_test, (void) );
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_ext, (struct command *cmd) );
FORWARD _PROTOTYPE( void setup_dma, (unsigned *sizep, int proc_nr,
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 ack_irqs, (unsigned int) );
-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_do_close, (struct driver *dp, message *m_ptr) );
+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 com_simple, (struct command *cmd) );
FORWARD _PROTOTYPE( void w_timeout, (void) );
FORWARD _PROTOTYPE( int atapi_open, (void) );
FORWARD _PROTOTYPE( void atapi_close, (void) );
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
#define sys_voutb(out, n) at_voutb(__LINE__, (out), (n))
env_setargs(argc, argv);
init_params();
signal(SIGTERM, SIG_IGN);
- driver_task(&w_dtab);
+ driver_task(&w_dtab, DRIVER_STD);
return(OK);
}
if (w_prepare(w_drive * DEV_PER_DRIVE) == NIL_DEV)
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. */
if (w_prepare(save_dev) == NIL_DEV)
/*===========================================================================*
* 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 opcode; /* DEV_GATHER_S or DEV_SCATTER_S */
u64_t position; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */
-int safe; /* iov contains addresses (0) or grants? */
{
struct wini *wn = w_wn;
iovec_t *iop, *iov_end = iov + nr_req;
#if ENABLE_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
if (do_dma) {
stop_dma(wn);
setup_dma(&nbytes, proc_nr, iov, addr_offset, do_write,
- &do_copyout, safe);
+ &do_copyout);
#if 0
printf("nbytes = %d\n", nbytes);
#endif
if (do_copyout)
{
- if(safe) {
+ if(proc_nr != SELF) {
s= sys_safecopyto(proc_nr, iov->iov_addr,
addr_offset,
(vir_bytes)dma_buf+dma_buf_offset, n, D);
- } else {
- s= sys_vircopy(SELF, D,
- (vir_bytes)dma_buf+dma_buf_offset,
- proc_nr, D,
- iov->iov_addr + addr_offset, n);
- }
- if (s != OK)
- {
+ if (s != OK)
+ {
panic(w_name(),
"w_transfer: sys_vircopy failed",
s);
+ }
+ } else {
+ memcpy((char *) iov->iov_addr + addr_offset,
+ dma_buf + dma_buf_offset, n);
}
}
/* Copy bytes to or from the device's buffer. */
if (opcode == DEV_GATHER_S) {
- if(safe) {
+ if(proc_nr != SELF) {
s=sys_safe_insw(wn->base_cmd + REG_DATA, proc_nr,
(void *) (iov->iov_addr), addr_offset,
SECTOR_SIZE);
- if(s != OK) {
- panic(w_name(),"Call to sys_safe_insw() failed", s);
- }
} else {
s=sys_insw(wn->base_cmd + REG_DATA, proc_nr,
(void *) (iov->iov_addr + addr_offset),
SECTOR_SIZE);
+ }
if(s != OK) {
panic(w_name(),"Call to sys_insw() failed", s);
}
- }
} else {
- if(safe) {
+ if(proc_nr != SELF) {
s=sys_safe_outsw(wn->base_cmd + REG_DATA, proc_nr,
(void *) (iov->iov_addr), addr_offset,
SECTOR_SIZE);
}
if(s != OK) {
- panic(w_name(),"Call to sys_outsw() failed",
- s);
+ panic(w_name(),"Call to sys_outsw() failed", s);
}
- /* Data sent, wait for an interrupt. */
- if ((r = at_intr_wait()) != OK) break;
+ /* Data sent, wait for an interrupt. */
+ if ((r = at_intr_wait()) != OK) break;
}
/* Book the bytes successfully transferred. */
* setup_dma *
*===========================================================================*/
PRIVATE void setup_dma(sizep, proc_nr, iov, addr_offset, do_write,
- do_copyoutp, safe)
+ do_copyoutp)
unsigned *sizep;
int proc_nr;
iovec_t *iov;
size_t addr_offset;
int do_write;
int *do_copyoutp;
-int safe;
{
phys_bytes phys, user_phys;
unsigned n, offset, size;
n= size;
if (n == 0 || (n & 1))
panic("at_wini", "bad size in iov", iov[i].iov_size);
- if(safe) {
- r= sys_umap(proc_nr, VM_GRANT, iov[i].iov_addr, n,&user_phys);
- if (r != 0)
- panic("at_wini", "can't map user buffer (VM_GRANT)", r);
- user_phys += offset + addr_offset;
+ if(proc_nr != SELF) {
+ r= sys_umap(proc_nr, VM_GRANT, iov[i].iov_addr, n,
+ &user_phys);
+ if (r != 0)
+ panic("at_wini",
+ "can't map user buffer (VM_GRANT)", r);
+ user_phys += offset + addr_offset;
} else {
- r= sys_umap(proc_nr, VM_D, iov[i].iov_addr+offset+addr_offset,
- n, &user_phys);
- if (r != 0)
- panic("at_wini", "can't map user buffer (VM_D)", r);
+ r= sys_umap(proc_nr, VM_D,
+ iov[i].iov_addr+offset+addr_offset, n,
+ &user_phys);
+ if (r != 0)
+ panic("at_wini",
+ "can't map user buffer (VM_D)", r);
}
if (user_phys & 1)
{
if (n > iov->iov_size)
n= iov->iov_size;
- if(safe) {
+ if(proc_nr != SELF) {
r= sys_safecopyfrom(proc_nr, iov->iov_addr,
addr_offset, (vir_bytes)dma_buf+offset,
n, D);
- } else {
- r= sys_vircopy(proc_nr, D,
- iov->iov_addr+addr_offset, SELF, D,
- (vir_bytes)dma_buf+offset, n);
- }
- if (r != OK)
- {
+ if (r != OK)
+ {
panic(w_name(),
- "setup_dma: sys_vircopy failed",
- r);
+ "setup_dma: sys_vircopy failed", r);
+ }
+ } else {
+ memcpy(dma_buf + offset,
+ (char *) iov->iov_addr + addr_offset,
+ n);
}
iov++;
addr_offset= 0;
/*===========================================================================*
* 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 opcode; /* DEV_GATHER_S or DEV_SCATTER_S */
u64_t position; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */
-int safe; /* use safecopies? */
{
struct wini *wn = w_wn;
iovec_t *iop, *iov_end = iov + nr_req;
int do_copyout = 0;
stop_dma(wn);
setup_dma(&nbytes, proc_nr, iov, addr_offset, 0,
- &do_copyout, safe);
+ &do_copyout);
if(do_copyout || (nbytes != nblocks * CD_SECTOR_SIZE)) {
stop_dma(wn);
do_dma = 0;
chunk = nbytes;
if (chunk > count) chunk = count;
if (chunk > iov->iov_size) chunk = iov->iov_size;
- if(safe) {
- s=sys_safe_insw(wn->base_cmd + REG_DATA, proc_nr,
- (void *) iov->iov_addr, addr_offset, chunk);
+ if(proc_nr != SELF) {
+ s=sys_safe_insw(wn->base_cmd + REG_DATA,
+ proc_nr, (void *) iov->iov_addr,
+ addr_offset, chunk);
} else {
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)
panic(w_name(),"Call to sys_insw() failed", s);
/*===========================================================================*
* w_other *
*===========================================================================*/
-PRIVATE int w_other(dr, m, safe)
+PRIVATE int w_other(dr, m)
struct driver *dr;
message *m;
-int safe;
{
int r, timeout, prev;
return EINVAL;
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);
- } else {
- r= sys_datacopy(m->IO_ENDPT, (vir_bytes)m->ADDRESS,
- SELF, (vir_bytes)&timeout, sizeof(timeout));
- }
if(r != OK)
return r;
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);
- } else {
- r=sys_datacopy(SELF, (vir_bytes)&prev,
- m->IO_ENDPT, (vir_bytes)m->ADDRESS,
- sizeof(prev));
- }
if(r != OK)
return r;
int count;
if (w_prepare(m->DEVICE) == NIL_DEV) return ENXIO;
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);
- } else {
- r=sys_datacopy(SELF, (vir_bytes)&count,
- m->IO_ENDPT, (vir_bytes)m->ADDRESS, sizeof(count));
- }
if(r != OK)
return r;
FORWARD _PROTOTYPE( struct device *w_prepare, (int device) );
FORWARD _PROTOTYPE( char *w_name, (void) );
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_close, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void w_init, (void) );
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. */
PRIVATE struct driver w_dtab = {
remap_first= v;
/* Set special disk parameters then call the generic main loop. */
- driver_task(&w_dtab);
+ driver_task(&w_dtab, DRIVER_STD);
return(OK);
}
/*===========================================================================*
* 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 opcode; /* DEV_GATHER or DEV_SCATTER */
u64_t pos64; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */
-int safe; /* use safecopies? */
{
struct wini *wn = w_wn;
iovec_t *iop, *iov_end = iov + nr_req;
if (count + chunk > nbytes) chunk = nbytes - count;
assert(chunk <= rem_buf_size);
- if(safe) {
+ if(proc_nr != SELF) {
r=sys_safecopyfrom(proc_nr,
(cp_grant_id_t) iop->iov_addr,
0, (vir_bytes) (bios_buf_v+count),
if (r != OK)
panic(ME, "copy failed", r);
} else {
- if(proc_nr != SELF) {
- panic(ME, "unsafe outside self", r);
- }
memcpy(bios_buf_v+count,
(char *) iop->iov_addr, chunk);
}
if (count + chunk > nbytes) chunk = nbytes - count;
assert(chunk <= rem_buf_size);
- if(safe) {
+ if(proc_nr != SELF) {
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)
panic(ME, "sys_vircopy failed", r);
} else {
- if (proc_nr != SELF)
- panic(ME, "unsafe without self", NO_NUM);
memcpy((char *) iop->iov_addr,
bios_buf_v+count, chunk);
}
/*============================================================================*
* w_other *
*============================================================================*/
-PRIVATE int w_other(dr, m, safe)
+PRIVATE int w_other(dr, m)
struct driver *dr;
message *m;
-int safe;
{
int r, timeout, prev;
int count;
if (w_prepare(m->DEVICE) == NIL_DEV) return ENXIO;
count = w_wn->open_ct;
- if(safe) {
- r=sys_safecopyto(m->IO_ENDPT, (vir_bytes)m->ADDRESS,
+ r=sys_safecopyto(m->IO_ENDPT, (vir_bytes)m->IO_GRANT,
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)
return r;
PRIVATE timer_t f_tmr_timeout; /* timer for various timeouts */
PRIVATE timer_t *f_timers; /* queue of floppy timers */
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_set_timer, (timer_t *tp, clock_t delta,
tmr_func_t watchdog) );
FORWARD _PROTOTYPE( char *f_name, (void) );
FORWARD _PROTOTYPE( void f_cleanup, (void) );
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( void start_motor, (void) );
FORWARD _PROTOTYPE( int seek, (void) );
struct floppy *fp;
int s;
+ system_hz = sys_hz();
+
if(!(floppy_buf = alloc_contig(2*DMA_BUF_SIZE,
AC_LOWER16M | AC_ALIGN4K, &floppy_buf_phys)))
panic("FLOPPY", "couldn't allocate dma buffer", NO_NUM);
/* Ignore signals */
signal(SIGHUP, SIG_IGN);
- driver_task(&f_dtab);
+ driver_task(&f_dtab, DRIVER_STD);
}
/*===========================================================================*
/*===========================================================================*
* 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 opcode; /* DEV_GATHER_S or DEV_SCATTER_S */
u64_t pos64; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */
-int safe;
{
#define NO_OFFSET -1
struct floppy *fp = f_fp;
return OK; /* Way beyond EOF */
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. */
if ((position & SECTOR_MASK) != 0) return(EINVAL);
if (iov->iov_size < SECTOR_SIZE + sizeof(fmt_param))
return(EINVAL);
- if(safe) {
+ if(proc_nr != SELF) {
s=sys_safecopyfrom(proc_nr, iov->iov_addr,
SECTOR_SIZE + iov_offset, (vir_bytes) &fmt_param,
(phys_bytes) sizeof(fmt_param), D);
if(s != OK)
panic("FLOPPY", "sys_safecopyfrom failed", s);
} else {
- assert(proc_nr == SELF);
memcpy(&fmt_param, (void *) (iov->iov_addr +
SECTOR_SIZE + iov_offset),
(phys_bytes) sizeof(fmt_param));
if (r == OK && opcode == DEV_SCATTER_S) {
/* Copy the user bytes to the DMA buffer. */
- if(safe) {
+ if(proc_nr != SELF) {
s=sys_safecopyfrom(proc_nr, *ug, *up,
(vir_bytes) floppy_buf,
(phys_bytes) SECTOR_SIZE, D);
if(s != OK)
panic("FLOPPY", "sys_safecopyfrom failed", s);
} else {
- assert(proc_nr == SELF);
memcpy(floppy_buf, (void *) (*ug + *up), SECTOR_SIZE);
}
}
if (r == OK && opcode == DEV_GATHER_S) {
/* Copy the DMA buffer to user space. */
- if(safe) {
+ if(proc_nr != SELF) {
s=sys_safecopyto(proc_nr, *ug, *up,
(vir_bytes) floppy_buf,
(phys_bytes) SECTOR_SIZE, D);
if(s != OK)
panic("FLOPPY", "sys_safecopyto failed", s);
} else {
- assert(proc_nr == SELF);
memcpy((void *) (*ug + *up), floppy_buf, SECTOR_SIZE);
}
}
position = (off_t) f_dp->test << SECTOR_SHIFT;
iovec1.iov_addr = (vir_bytes) floppy_buf;
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);
*
* 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 |
- * ----------------------------------------------------------------
+ * m_type DEVICE IO_ENDPT COUNT POSITION HIGHPOS IO_GRANT
+ * ----------------------------------------------------------------------------
+ * | DEV_OPEN | device | proc nr | | | | |
+ * |---------------+--------+---------+---------+--------+--------+-----------|
+ * | DEV_CLOSE | device | proc nr | | | | |
+ * |---------------+--------+---------+---------+--------+--------+-----------|
+ * | DEV_READ_S | device | proc nr | bytes | off lo | off hi i buf grant |
+ * |---------------+--------+---------+---------+--------+--------+-----------|
+ * | DEV_WRITE_S | device | proc nr | bytes | off lo | off hi | buf grant |
+ * |---------------+--------+---------+---------+--------+--------+-----------|
+ * | DEV_GATHER_S | device | proc nr | iov len | off lo | off hi | iov grant |
+ * |---------------+--------+---------+---------+--------+--------+-----------|
+ * | DEV_SCATTER_S | device | proc nr | iov len | off lo | off hi | iov grant |
+ * |---------------+--------+---------+---------+--------+--------+-----------|
+ * | DEV_IOCTL_S | device | proc nr | request | | | buf grant |
+ * |---------------+--------+---------+---------+--------+--------+-----------|
+ * | CANCEL | device | proc nr | r/w | | | |
+ * ----------------------------------------------------------------------------
*
- * The file contains one entry point:
+ * The file contains the following entry points:
*
* driver_task: called by the device dependent task entry
+ * init_buffer: initialize a DMA buffer
+ * mq_queue: queue an incoming message for later processing
*/
#include "driver.h"
/* Claim space for variables. */
-#if 0
-PRIVATE u8_t buffer[(unsigned) 2 * DMA_BUF_SIZE];
-#endif
-u8_t *tmp_buf; /* the DMA buffer eventually */
+u8_t *tmp_buf = NULL; /* the DMA buffer eventually */
phys_bytes tmp_phys; /* phys address of DMA buffer */
-FORWARD _PROTOTYPE( int do_rdwt, (struct driver *dr, message *mp, int safe) );
-FORWARD _PROTOTYPE( int do_vrdwt, (struct driver *dr, message *mp, int safe) );
+FORWARD _PROTOTYPE( void asyn_reply, (message *mess, int proc_nr, int r) );
+FORWARD _PROTOTYPE( int do_rdwt, (struct driver *dr, message *mp) );
+FORWARD _PROTOTYPE( int do_vrdwt, (struct driver *dr, message *mp) );
int device_caller;
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 *
*===========================================================================*/
-PUBLIC void driver_task(dp)
+PUBLIC void driver_task(dp, type)
struct driver *dp; /* Device dependent entry points. */
+int type; /* Driver type (DRIVER_STD or DRIVER_ASYN) */
{
/* Main program of any device driver task. */
message mess;
sigset_t set;
- system_hz = sys_hz();
-
/* Init MQ library. */
mq_init();
break;
default:
if(dp->dr_other)
- r = (*dp->dr_other)(dp, &mess, 0);
+ r = (*dp->dr_other)(dp, &mess);
else
r = EINVAL;
goto send_reply;
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 DEV_IOCTL_S: r = (*dp->dr_ioctl)(dp, &mess); 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_WRITE_S: r = do_rdwt(dp, &mess); break;
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:
if(dp->dr_other)
- r = (*dp->dr_other)(dp, &mess, 0);
+ r = (*dp->dr_other)(dp, &mess);
else
r = EINVAL;
break;
(*dp->dr_cleanup)();
/* 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.REP_ENDPT = proc_nr;
/* Status is # of bytes transferred or error code. */
- mess.REP_STATUS = r;
- r= sendnb(device_caller, &mess);
+ mess.REP_STATUS = r;
+
+ /* 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)
{
- printf("driver_task: unable to sendnb to %d: %d\n",
+ printf("driver_task: unable to send reply to %d: %d\n",
device_caller, r);
}
+
+ break;
+
+ case DRIVER_ASYN:
+ asyn_reply(&mess, proc_nr, r);
+
+ break;
+
+ default:
+ panic(__FILE__, "unknown driver type", type);
}
}
}
/*===========================================================================*
* do_rdwt *
*===========================================================================*/
-PRIVATE int do_rdwt(dp, mp, safe)
+PRIVATE int do_rdwt(dp, mp)
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;
/* 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) {
- printf("libdriver_asyn: do_rdwt: no support for non-safe command.\n");
- return EINVAL;
- }
-
/* 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;
+ if(mp->m_type == DEV_READ_S) opcode = DEV_GATHER_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;
/* Transfer bytes from/to the device. */
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(r == OK ? (mp->COUNT - iovec1.iov_size) : r);
/*==========================================================================*
* do_vrdwt *
*==========================================================================*/
-PRIVATE int do_vrdwt(dp, mp, safe)
+PRIVATE int do_vrdwt(dp, mp)
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;
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;
+ /* 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 (OK != sys_safecopyfrom(mp->m_source, (vir_bytes) mp->IO_GRANT,
+ 0, (vir_bytes) iovec, iovec_size, D)) {
+ panic((*dp->dr_name)(),"bad I/O vector by", mp->m_source);
}
/* Prepare for I/O. */
/* 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);
+ r = (*dp->dr_transfer)(mp->IO_ENDPT, opcode, position, iovec, nr_req);
/* 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);
+ 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);
}
return(r);
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);
+ default: printf("nop: ignoring code %d\n", mp->m_type);
+ return(EIO);
}
}
/*============================================================================*
* nop_ioctl *
*============================================================================*/
-PUBLIC int nop_ioctl(dp, mp, safe)
+PUBLIC int nop_ioctl(dp, mp)
struct driver *dp;
message *mp;
-int safe;
{
return(ENOTTY);
}
/*============================================================================*
* do_diocntl *
*============================================================================*/
-PUBLIC int do_diocntl(dp, mp, safe)
+PUBLIC int do_diocntl(dp, mp)
struct driver *dp;
message *mp; /* pointer to ioctl request */
-int safe; /* addresses or grants? */
{
/* Carry out a partition setting/getting request. */
struct device *dv;
if (mp->REQUEST != DIOCSETP && mp->REQUEST != DIOCGETP) {
if(dp->dr_other) {
- return dp->dr_other(dp, mp, safe);
+ return dp->dr_other(dp, mp);
} else return(ENOTTY);
}
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));
- }
+ s=sys_safecopyfrom(mp->IO_ENDPT, (vir_bytes) mp->IO_GRANT,
+ 0, (vir_bytes) &entry, sizeof(entry), D);
if(s != OK)
return s;
dv->dv_base = entry.base;
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));
- }
+ s=sys_safecopyto(mp->IO_ENDPT, (vir_bytes) mp->IO_GRANT,
+ 0, (vir_bytes) &entry, sizeof(entry), D);
if (OK != s)
return s;
}
_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( int (*dr_ioctl), (struct driver *dp, message *m_ptr) );
_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) );
+ iovec_t *iov, unsigned nr_req) );
_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_other), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_hw_int), (struct driver *dp, message *m_ptr) );
};
#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: */
-_PROTOTYPE( void driver_task, (struct driver *dr) );
+_PROTOTYPE( void driver_task, (struct driver *dr, int type) );
_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_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 do_diocntl, (struct driver *dp, message *m_ptr) );
+_PROTOTYPE( int nop_ioctl, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int mq_queue, (message *m_ptr) );
_PROTOTYPE( void init_buffer, (void) );
extern u8_t tmp_buf[]; /* the DMA buffer */
#endif
extern phys_bytes tmp_phys; /* phys address of DMA buffer */
-
-u32_t system_hz;
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);
+ (void) (*dp->dr_transfer)(SELF, DEV_GATHER_S, position, &iovec1, 1);
}
if (iovec1.iov_size != 0) {
return 0;
+++ /dev/null
-# 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
-
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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 */
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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
+++ /dev/null
-/*
-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 $
- */
MAKE = exec make
CC = exec cc
CFLAGS = -I$i $(CPROFILE)
-LDFLAGS = -i -L../libdriver_asyn
+LDFLAGS = -i -L../libdriver
LIBS = -ldriver -lsys
-LIB_DEP = ../libdriver_asyn/libdriver.a
+LIB_DEP = ../libdriver/libdriver.a
OBJ = log.o diag.o
FORWARD _PROTOTYPE( char *log_name, (void) );
FORWARD _PROTOTYPE( struct device *log_prepare, (int device) );
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_cancel, (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( 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( 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. */
PRIVATE struct driver log_dtab = {
logdevices[i].log_proc_nr = 0;
logdevices[i].log_revive_alerted = 0;
}
- driver_task(&log_dtab);
+ driver_task(&log_dtab, DRIVER_ASYN);
return(OK);
}
}
/*===========================================================================*
- * subwrite *
+ * subwrite *
*===========================================================================*/
PRIVATE int
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;
char *buf;
memcpy(buf, (char *) user_vir, count);
}
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)
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);
*/
log->log_status = subread(log, log->log_iosize,
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.REP_ENDPT = log->log_proc_nr;
if(count > LOG_SIZE) skip = count - LOG_SIZE;
count -= 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)
- subwrite(&logdevices[0], count-w, SELF, (vir_bytes) buf+w,0,0);
+ subwrite(&logdevices[0], count-w, SELF, (vir_bytes) buf+w,0);
return;
}
*===========================================================================*/
PRIVATE int
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;
int r;
count = LOG_SIZE - 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)
return r;
- }
LOGINC(log->log_read, count);
log->log_size -= count;
/*===========================================================================*
* 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 opcode; /* DEV_GATHER_S or DEV_SCATTER_S */
u64_t position; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */
-int safe; /* safe copies? */
{
/* Read or write one the driver's minor devices. */
unsigned count;
log->log_user_vir_g = user_vir;
log->log_user_vir_offset = 0;
log->log_revive_alerted = 0;
- log->log_safe = safe;
/* Device_caller is a global in drivers library. */
log->log_source = device_caller;
#endif
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) {
return count;
}
accumulated_read += count;
} 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)
return count;
}
/*============================================================================*
* log_other *
*============================================================================*/
-PRIVATE int log_other(dp, m_ptr, safe)
+PRIVATE int log_other(dp, m_ptr)
struct driver *dp;
message *m_ptr;
-int safe;
{
int r;
log_revive_alerted,
log_status; /* proc that is blocking on read */
vir_bytes log_user_vir_g, log_user_vir_offset;
- int log_safe;
#endif
int log_selected, log_select_proc,
log_select_alerted, log_select_ready_ops;
FORWARD _PROTOTYPE( char *m_name, (void) );
FORWARD _PROTOTYPE( struct device *m_prepare, (int device) );
-FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode, u64_t position,
- iovec_t *iov, unsigned nr_req, int safe));
+FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode,
+ 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_close, (struct driver *dp, message *m_ptr) );
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) );
/* Entry points to this driver. */
sa.sa_flags = 0;
if (sigaction(SIGTERM,&sa,NULL)<0) panic("MEM","sigaction failed", errno);
- m_init();
- driver_task(&m_dtab);
- return(OK);
+ m_init();
+ driver_task(&m_dtab, DRIVER_STD);
+ return(OK);
}
/*===========================================================================*
/*===========================================================================*
* 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 opcode; /* DEV_GATHER_S or DEV_SCATTER_S */
u64_t pos64; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */
-int safe; /* safe copies */
{
/* Read or write one the driver's minor devices. */
unsigned count, left, chunk;
off_t position;
vir_bytes dev_vaddr;
- if(!safe) {
- printf("m_transfer: unsafe?\n");
- return EPERM;
- }
-
/* ZERO_DEV and NULL_DEV are infinite in size. */
if (m_device != ZERO_DEV && m_device != NULL_DEV && ex64hi(pos64) != 0)
return OK; /* Beyond EOF */
/*===========================================================================*
* m_ioctl *
*===========================================================================*/
-PRIVATE int m_ioctl(dp, m_ptr, safe)
+PRIVATE int m_ioctl(dp, m_ptr)
struct driver *dp; /* pointer to driver structure */
message *m_ptr; /* pointer to control message */
-int safe;
{
/* I/O controls for the memory driver. Currently there is one I/O control:
* - MIOCRAMSIZE: to set the size of the RAM disk.
*/
struct device *dv;
- if(!safe) {
- printf("m_transfer: unsafe?\n");
- return EPERM;
- }
-
switch (m_ptr->REQUEST) {
case MIOCRAMSIZE: {
/* Someone wants to create a new RAM disk with the given size. */
}
default:
- return(do_diocntl(&m_dtab, m_ptr, safe));
+ return(do_diocntl(&m_dtab, m_ptr));
}
return(OK);
}
MAKE = exec make
CC = exec cc
CFLAGS = -I$i $(CPROFILE)
-LDFLAGS = -i -L../libdriver_asyn
+LDFLAGS = -i -L../libdriver
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
FORWARD _PROTOTYPE( char *r_name, (void) );
FORWARD _PROTOTYPE( struct device *r_prepare, (int device) );
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( 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_random, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void r_updatebin, (int source, struct k_randomness_bin *rb));
*===========================================================================*/
PUBLIC int main(void)
{
- r_init(); /* initialize the memory driver */
- driver_task(&r_dtab); /* start driver's main loop */
+ r_init(); /* initialize the memory driver */
+ driver_task(&r_dtab, DRIVER_ASYN); /* start driver's main loop */
return(OK);
}
/*===========================================================================*
* 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 opcode; /* DEV_GATHER or DEV_SCATTER */
u64_t position; /* offset on device to read or write */
iovec_t *iov; /* pointer to read or write request vector */
unsigned nr_req; /* length of request vector */
-int safe; /* safe copies? */
{
/* Read or write one the driver's minor devices. */
unsigned count, left, chunk;
chunk = (left > RANDOM_BUF_SIZE) ? RANDOM_BUF_SIZE : left;
if (opcode == DEV_GATHER_S) {
random_getbytes(random_buf, chunk);
- if(safe) {
- r= sys_safecopyto(proc_nr, user_vir, vir_offset,
- (vir_bytes) random_buf, chunk, D);
- if (r != OK)
- {
- printf(
- "random: sys_safecopyto failed for proc %d, grant %d\n",
- proc_nr, user_vir);
- return r;
- }
- } else {
- sys_vircopy(SELF, D, (vir_bytes) random_buf,
- proc_nr, D, user_vir + vir_offset, chunk);
+ r= sys_safecopyto(proc_nr, user_vir, vir_offset,
+ (vir_bytes) random_buf, chunk, D);
+ if (r != OK)
+ {
+ printf(
+ "random: sys_safecopyto failed for proc %d, grant %d\n",
+ proc_nr, user_vir);
+ return r;
}
} else if (opcode == DEV_SCATTER_S) {
- if(safe) {
- r= sys_safecopyfrom(proc_nr, user_vir, vir_offset,
- (vir_bytes) random_buf, chunk, D);
- if (r != OK)
- {
- printf(
+ r= sys_safecopyfrom(proc_nr, user_vir, vir_offset,
+ (vir_bytes) random_buf, chunk, D);
+ if (r != OK)
+ {
+ printf(
"random: sys_safecopyfrom failed for proc %d, grant %d\n",
- proc_nr, user_vir);
- return r;
- }
- } else {
- sys_vircopy(proc_nr, D, user_vir + vir_offset,
- SELF, D, (vir_bytes) random_buf, chunk);
+ proc_nr, user_vir);
+ return r;
}
random_putbytes(random_buf, chunk);
}
/*===========================================================================*
* r_ioctl *
*===========================================================================*/
-PRIVATE int r_ioctl(dp, m_ptr, safe)
+PRIVATE int r_ioctl(dp, m_ptr)
struct driver *dp; /* pointer to driver structure */
message *m_ptr; /* pointer to control message */
-int safe; /* safe i/o? */
{
struct device *dv;
if ((dv = r_prepare(m_ptr->DEVICE)) == NIL_DEV) return(ENXIO);
switch (m_ptr->REQUEST) {
default:
- return(do_diocntl(&r_dtab, m_ptr, safe));
+ return(do_diocntl(&r_dtab, m_ptr));
}
return(OK);
}