}
}
else if (strcmp(argv[i], ARG_DEVSTYLE)==0) {
- char* dev_style_keys[] = { "STYLE_DEV", "STYLE_DEVA", "STYLE_TTY",
- "STYLE_CTTY", "STYLE_CLONE", "STYLE_CLONE_A", NULL };
- int dev_style_values[] = { STYLE_DEV, STYLE_DEVA, STYLE_TTY,
- STYLE_CTTY, STYLE_CLONE, STYLE_CLONE_A };
+ char* dev_style_keys[] = { "STYLE_DEV", "STYLE_TTY",
+ "STYLE_CTTY", "STYLE_CLONE", NULL };
+ int dev_style_values[] = { STYLE_DEV, STYLE_TTY,
+ STYLE_CTTY, STYLE_CLONE };
for(j=0;dev_style_keys[j]!=NULL;j++) {
if(!strcmp(dev_style_keys[j], argv[i+1])) {
break;
sef_local_startup();
- chardriver_task(&bmp085_tab, CHARDRIVER_SYNC);
+ chardriver_task(&bmp085_tab);
return 0;
}
fb_edid_args_parse();
sef_local_startup();
- chardriver_task(&fb_tab, CHARDRIVER_SYNC);
+ chardriver_task(&fb_tab);
return OK;
}
/*
* Run the main loop.
*/
- chardriver_task(&hello_tab, CHARDRIVER_SYNC);
+ chardriver_task(&hello_tab);
return OK;
}
memset(i2cdev, '\0', sizeof(i2cdev));
sef_local_startup();
- chardriver_task(&i2c_tab, CHARDRIVER_SYNC);
+ chardriver_task(&i2c_tab);
return OK;
}
static int log_do_open(message *m_ptr);
static int log_cancel(message *m_ptr);
static int log_select(message *m_ptr);
-static int log_other(message *m_ptr);
static int subread(struct logdevice *log, int count, endpoint_t endpt,
cp_grant_id_t grant, size_t);
nop_alarm, /* no alarm */
log_cancel, /* CANCEL request */
log_select, /* DEV_SELECT request */
- log_other /* Unrecognized messages */
+ NULL /* Unrecognized messages */
};
/* SEF functions and variables. */
sef_local_startup();
/* Call the generic receive loop. */
- chardriver_task(&log_dtab, CHARDRIVER_ASYNC);
+ chardriver_task(&log_dtab);
return(OK);
}
static int log_cancel(message *m_ptr)
{
int d;
- d = m_ptr->TTY_LINE;
+ d = m_ptr->DEVICE;
if(d < 0 || d >= NR_DEVS)
return EINVAL;
+ if (m_ptr->USER_ENDPT != logdevices[d].log_proc_nr)
+ return EDONTREPLY;
+ if ((cp_grant_id_t) m_ptr->IO_GRANT != logdevices[d].log_user_grant)
+ return EDONTREPLY;
logdevices[d].log_proc_nr = NONE;
logdevices[d].log_revive_alerted = 0;
return(OK);
}
-/*============================================================================*
- * log_other *
- *============================================================================*/
-static int log_other(message *m_ptr)
-{
- int r;
-
- /* This function gets messages that the generic driver doesn't
- * understand.
- */
- if (is_notify(m_ptr->m_type)) {
- return EINVAL;
- }
-
- switch(m_ptr->m_type) {
- case DEV_STATUS: {
- printf("log_other: unexpected DEV_STATUS request\n");
- r = EDONTREPLY;
- break;
- }
- default:
- r = EINVAL;
- break;
- }
- return r;
-}
-
/*============================================================================*
* log_select *
*============================================================================*/
static int log_select(message *m_ptr)
{
int d, ready_ops = 0, ops = 0;
- d = m_ptr->TTY_LINE;
+ d = m_ptr->DEV_MINOR;
if(d < 0 || d >= NR_DEVS) {
#if LOG_DEBUG
printf("line %d? EINVAL\n", d);
return EINVAL;
}
- ops = m_ptr->USER_ENDPT & (SEL_RD|SEL_WR|SEL_ERR);
+ ops = m_ptr->DEV_SEL_OPS & (SEL_RD|SEL_WR|SEL_ERR);
/* Read blocks when there is no log. */
- if((m_ptr->USER_ENDPT & SEL_RD) && logdevices[d].log_size > 0) {
+ if((m_ptr->DEV_SEL_OPS & SEL_RD) && logdevices[d].log_size > 0) {
#if LOG_DEBUG
printf("log can read; size %d\n", logdevices[d].log_size);
#endif
}
/* Write never blocks. */
- if(m_ptr->USER_ENDPT & SEL_WR) ready_ops |= SEL_WR;
+ if(m_ptr->DEV_SEL_OPS & SEL_WR) ready_ops |= SEL_WR;
/* Enable select calback if no operations were
* ready to go, but operations were requested,
* and notify was enabled.
*/
- if((m_ptr->USER_ENDPT & SEL_NOTIFY) && ops && !ready_ops) {
+ if((m_ptr->DEV_SEL_OPS & SEL_NOTIFY) && ops && !ready_ops) {
logdevices[d].log_selected |= ops;
logdevices[d].log_select_proc = m_ptr->m_source;
#if LOG_DEBUG
if (IS_BDEV_RQ(msg.m_type))
blockdriver_process(&m_bdtab, &msg, ipc_status);
else
- chardriver_process(&m_cdtab, CHARDRIVER_SYNC, &msg,
- ipc_status);
+ chardriver_process(&m_cdtab, &msg, ipc_status);
}
return(OK);
/* State management variables. */
EXTERN int writing;
-EXTERN int is_status_msg_expected;
/* Custom states definition. */
#define PR_STATE_WRITE_PROTOCOL_FREE (SEF_LU_STATE_CUSTOM_BASE + 0)
break;
case SEF_LU_STATE_PROTOCOL_FREE:
- is_ready = (!writing && !is_status_msg_expected);
+ is_ready = (!writing);
break;
/* Custom states. */
{
sef_lu_dprint("printer: live update state = %d\n", state);
sef_lu_dprint("printer: writing = %d\n", writing);
- sef_lu_dprint("printer: is_status_msg_expected = %d\n",
- is_status_msg_expected);
sef_lu_dprint("printer: SEF_LU_STATE_WORK_FREE(%d) reached = %d\n",
SEF_LU_STATE_WORK_FREE, TRUE);
sef_lu_dprint("printer: SEF_LU_STATE_REQUEST_FREE(%d) reached = %d\n",
SEF_LU_STATE_REQUEST_FREE, TRUE);
sef_lu_dprint("printer: SEF_LU_STATE_PROTOCOL_FREE(%d) reached = %d\n",
- SEF_LU_STATE_PROTOCOL_FREE, (!writing && !is_status_msg_expected));
+ SEF_LU_STATE_PROTOCOL_FREE, (!writing));
sef_lu_dprint("printer: PR_STATE_WRITE_PROTOCOL_FREE(%d) reached = %d\n",
PR_STATE_WRITE_PROTOCOL_FREE, (!writing));
}
* DEV_WRITE: a process wants to write on a terminal
* CANCEL: terminate a previous incomplete system call immediately
*
- * m_type TTY_LINE USER_ENDPT COUNT ADDRESS
+ * m_type DEVICE USER_ENDPT COUNT ADDRESS
* |-------------+---------+---------+---------+---------|
* | DEV_OPEN | | | | |
* |-------------+---------+---------+---------+---------|
* | DEV_CLOSE | | proc nr | | |
- * -------------------------------------------------------
- * | HARD_INT | | | | |
* |-------------+---------+---------+---------+---------|
- * | SYS_EVENT | | | | |
+ * | HARD_INT | | | | |
* |-------------+---------+---------+---------+---------|
* | DEV_WRITE |minor dev| proc nr | count | buf ptr |
* |-------------+---------+---------+---------+---------|
*/
static endpoint_t caller; /* process to tell when printing done (FS) */
-static int revive_pending; /* set to true if revive is pending */
-static int revive_status; /* revive status */
static int done_status; /* status of last output completion */
static int oleft; /* bytes of output left in obuf */
static unsigned char obuf[128]; /* output buffer */
static void do_cancel(message *m_ptr);
static void output_done(void);
static void do_write(message *m_ptr);
-static void do_status(message *m_ptr);
static void prepare_output(void);
static int do_probe(void);
static void do_initialize(void);
-static void reply(int code,int replyee,int proc,int status);
+static void reply(int code, endpoint_t replyee, endpoint_t proc,
+ cp_grant_id_t grant, int status);
static void do_printer_output(void);
/* SEF functions and variables. */
EXTERN int sef_cb_lu_prepare(int state);
EXTERN int sef_cb_lu_state_isvalid(int state);
EXTERN void sef_cb_lu_state_dump(int state);
-int is_status_msg_expected = FALSE;
/*===========================================================================*
* printer_task *
case HARDWARE:
do_printer_output();
break;
- default:
- reply(TASK_REPLY, pr_mess.m_source,
- pr_mess.USER_ENDPT, EINVAL);
}
continue;
}
switch(pr_mess.m_type) {
case DEV_OPEN:
- do_initialize(); /* initialize */
- /* fall through */
+ do_initialize(); /* initialize */
+ reply(DEV_OPEN_REPL, pr_mess.m_source, pr_mess.USER_ENDPT,
+ (cp_grant_id_t) pr_mess.IO_GRANT, OK);
+ break;
case DEV_CLOSE:
- reply(TASK_REPLY, pr_mess.m_source, pr_mess.USER_ENDPT, OK);
+ reply(DEV_CLOSE_REPL, pr_mess.m_source, pr_mess.USER_ENDPT,
+ (cp_grant_id_t) pr_mess.IO_GRANT, OK);
break;
case DEV_WRITE_S: do_write(&pr_mess); break;
- case DEV_STATUS: do_status(&pr_mess); break;
case CANCEL: do_cancel(&pr_mess); break;
default:
- reply(TASK_REPLY, pr_mess.m_source, pr_mess.USER_ENDPT,
- EINVAL);
+ reply(DEV_REVIVE, pr_mess.m_source, pr_mess.USER_ENDPT,
+ (cp_grant_id_t) pr_mess.IO_GRANT, EINVAL);
}
}
}
{
/* The printer is used by sending DEV_WRITE messages to it. Process one. */
- register int r = SUSPEND;
+ int r = OK;
int retries;
u32_t status;
else if (m_ptr->COUNT <= 0) r = EINVAL;
else if (m_ptr->FLAGS & FLG_OP_NONBLOCK) r = EAGAIN; /* not supported */
- /* Reply to FS, no matter what happened, possible SUSPEND caller. */
- reply(TASK_REPLY, m_ptr->m_source, m_ptr->USER_ENDPT, r);
-
- /* If no errors occurred, continue printing with SUSPENDED caller.
+ /* If no errors occurred, continue printing with the caller.
* First wait until the printer is online to prevent stupid errors.
*/
- if (SUSPEND == r) {
+ if (r == OK) {
caller = m_ptr->m_source;
proc_nr = m_ptr->USER_ENDPT;
user_left = m_ptr->COUNT;
/* If we reach this point, the printer was not online in time. */
done_status = status;
output_done();
+ } else {
+ reply(DEV_REVIVE, m_ptr->m_source, m_ptr->USER_ENDPT,
+ (cp_grant_id_t) m_ptr->IO_GRANT, r);
}
}
* Otherwise, reply to caller (FS).
*/
register int status;
+ message m;
if (!writing) return; /* probably leftover interrupt */
if (done_status != OK) { /* printer error occurred */
else { /* done! report back to FS */
status = orig_count;
}
- is_status_msg_expected = TRUE;
- revive_pending = TRUE;
- revive_status = status;
- notify(caller);
-}
-/*===========================================================================*
- * do_status *
- *===========================================================================*/
-static void do_status(m_ptr)
-register message *m_ptr; /* pointer to the newly arrived message */
-{
- if (revive_pending) {
- m_ptr->m_type = DEV_REVIVE; /* build message */
- m_ptr->REP_ENDPT = proc_nr;
- m_ptr->REP_STATUS = revive_status;
- m_ptr->REP_IO_GRANT = grant_nr;
-
- writing = FALSE; /* unmark event */
- revive_pending = FALSE; /* unmark event */
- } else {
- m_ptr->m_type = DEV_NO_STATUS;
-
- is_status_msg_expected = FALSE;
- }
- send(m_ptr->m_source, m_ptr); /* send the message */
+ memset(&m, 0, sizeof(m));
+ m.m_type = DEV_REVIVE; /* build message */
+ m.REP_ENDPT = proc_nr;
+ m.REP_STATUS = status;
+ m.REP_IO_GRANT = grant_nr;
+ send(caller, &m);
+
+ writing = FALSE; /* unmark event */
}
/*===========================================================================*
* but rely on FS to handle the EINTR reply and de-suspension properly.
*/
- if (writing && m_ptr->USER_ENDPT == proc_nr) {
+ if (writing && m_ptr->USER_ENDPT == proc_nr &&
+ (cp_grant_id_t) m_ptr->IO_GRANT == grant_nr) {
oleft = 0; /* cancel output by interrupt handler */
writing = FALSE;
- revive_pending = FALSE;
+ reply(DEV_REVIVE, m_ptr->m_source, proc_nr, grant_nr, EINTR);
}
- reply(TASK_REPLY, m_ptr->m_source, m_ptr->USER_ENDPT, EINTR);
}
/*===========================================================================*
* reply *
*===========================================================================*/
-static void reply(code, replyee, process, status)
-int code; /* TASK_REPLY or REVIVE */
-int replyee; /* destination for message (normally FS) */
-int process; /* which user requested the printing */
+static void reply(code, replyee, process, grant, status)
+int code; /* DEV_OPEN_REPL, DEV_CLOSE_REPL, DEV_REVIVE */
+endpoint_t replyee; /* destination for message (normally FS) */
+endpoint_t process; /* which user requested the printing */
+cp_grant_id_t grant; /* which grant was involved */
int status; /* number of chars printed or error code */
{
/* Send a reply telling FS that printing has started or stopped. */
message pr_mess;
- pr_mess.m_type = code; /* TASK_REPLY or REVIVE */
+ pr_mess.m_type = code; /* reply code */
pr_mess.REP_STATUS = status; /* count or EIO */
- pr_mess.REP_ENDPT = process; /* which user does this pertain to */
+ pr_mess.REP_ENDPT = process; /* which user does this pertain to */
+ pr_mess.REP_IO_GRANT = grant; /* the grant */
send(replyee, &pr_mess); /* send the message */
}
sef_local_startup();
/* Call the generic receive loop. */
- chardriver_task(&r_dtab, CHARDRIVER_ASYNC);
+ chardriver_task(&r_dtab);
return(OK);
}
sef_local_startup();
- chardriver_task(&sht21_tab, CHARDRIVER_SYNC);
+ chardriver_task(&sht21_tab);
return 0;
}
main(int argc, char *argv[])
{
int r;
- endpoint_t user, caller;
message m;
int ipc_status;
continue;
}
- caller = m.m_source;
- user = m.USER_ENDPT;
-
- /*
- * Handle Message
- *
- * So far this driver only deals with notifications
- * so it always replies to non-notifications with EINVAL.
- */
-
- /* Send Reply */
- m.m_type = TASK_REPLY;
- m.REP_ENDPT = user;
- m.REP_STATUS = EINVAL;
-
- r = sendnb(caller, &m);
- if (r != OK) {
- log_warn(&log, "sendnb() failed\n");
- continue;
- }
+ log_warn(&log, "Ignoring message 0x%x from 0x%x\n", m.m_type,
+ m.m_source);
}
return 0;
sef_local_startup();
- chardriver_task(&tsl2550_tab, CHARDRIVER_SYNC);
+ chardriver_task(&tsl2550_tab);
return 0;
}
{
}
-int
-kbd_status(message *m)
-{
- return 0;
-}
-
int
kbd_loadmap(message *m)
{
tp->tty_outcum += count;
if ((tp->tty_outleft -= count) == 0) {
/* Output is finished, reply to the writer. */
- if(tp->tty_outrepcode == TTY_REVIVE) {
- notify(tp->tty_outcaller);
- tp->tty_outrevived = 1;
- } else {
- tty_reply(tp->tty_outrepcode, tp->tty_outcaller,
- tp->tty_outproc, tp->tty_outcum);
- tp->tty_outcum = 0;
- }
+ tty_reply(DEV_REVIVE, tp->tty_outcaller,
+ tp->tty_outproc, tp->tty_outgrant,
+ tp->tty_outcum);
+ tp->tty_outcum = 0;
+ tp->tty_outgrant = GRANT_INVALID;
}
}
if (tp->tty_outleft > 0 && tp->tty_termios.c_ospeed == B0) {
/* Oops, the line has hung up. */
- if(tp->tty_outrepcode == TTY_REVIVE) {
- notify(tp->tty_outcaller);
- tp->tty_outrevived = 1;
- } else {
- tty_reply(tp->tty_outrepcode, tp->tty_outcaller,
- tp->tty_outproc, EIO);
- tp->tty_outleft = tp->tty_outcum = 0;
- }
+ tty_reply(DEV_REVIVE, tp->tty_outcaller, tp->tty_outproc,
+ tp->tty_outgrant, EIO);
+ tp->tty_outleft = tp->tty_outcum = 0;
+ tp->tty_outgrant = GRANT_INVALID;
}
return 1;
/* Reply to the writer if all output is finished or if an error occured. */
if (tp->tty_outleft == 0 || result != OK) {
- if(tp->tty_outrepcode == TTY_REVIVE) {
- notify(tp->tty_outcaller);
- tp->tty_outrevived = 1;
- } else {
- tty_reply(tp->tty_outrepcode, tp->tty_outcaller,
- tp->tty_outproc, tp->tty_outcum);
- tp->tty_outcum = 0;
- }
+ tty_reply(DEV_REVIVE, tp->tty_outcaller, tp->tty_outproc,
+ tp->tty_outgrant, result != OK ? result : tp->tty_outcum);
+ tp->tty_outcum = tp->tty_outleft = 0;
+ tp->tty_outgrant = GRANT_INVALID;
}
return 0;
case DEV_OPEN:
/* Should grant IOPL */
disable_console();
- r= OK;
- break;
+ tty_reply(DEV_OPEN_REPL, m->m_source, m->USER_ENDPT,
+ (cp_grant_id_t) m->IO_GRANT, OK);
+ return;
case DEV_CLOSE:
reenable_console();
- r= OK;
- break;
+ tty_reply(DEV_CLOSE_REPL, m->m_source, m->USER_ENDPT,
+ (cp_grant_id_t) m->IO_GRANT, OK);
+ return;
case DEV_IOCTL_S:
- switch(m->TTY_REQUEST) {
+ switch(m->REQUEST) {
case TIOCMAPMEM:
case TIOCUNMAPMEM: {
int r, do_map;
if (r != OK)
{
printf("tty: sys_safecopyfrom failed\n");
- tty_reply(TASK_REPLY, m->m_source,
- m->USER_ENDPT, r);
- return;
+ break;
}
/* In safe ioctl mode, the POSITION field contains
r = vm_unmap_phys(m->POSITION,
mapreqvm.vaddr, mapreqvm.size);
}
- tty_reply(TASK_REPLY, m->m_source, m->USER_ENDPT, r);
- return;
- }
+ break;
+ }
+ default:
+ r= ENOTTY;
+ break;
}
- r= ENOTTY;
break;
- default:
+ default:
printf(
"Warning, TTY(video) got unexpected request %d from %d\n",
m->m_type, m->m_source);
r= EINVAL;
}
- tty_reply(TASK_REPLY, m->m_source, m->USER_ENDPT, r);
+ tty_reply(DEV_REVIVE, m->m_source, m->USER_ENDPT,
+ (cp_grant_id_t) m->IO_GRANT, r);
}
#include <minix/input.h>
#include <minix/keymap.h>
#include <minix/reboot.h>
+#include <assert.h>
#include "tty.h"
#include "kernel/const.h"
#include "kernel/config.h"
int incaller;
int select_ops;
int select_proc;
+ int select_minor; /* sanity check only, can be removed */
} kbd, kbdaux;
/* Data that is to be sent to the keyboard. Each byte is ACKed by the
static timer_t tmr_kbd_wd;
static void handle_req(struct kbd *kbdp, message *m);
-static int handle_status(struct kbd *kbdp, message *m);
static void kbc_cmd0(int cmd);
static void kbc_cmd1(int cmd, int data);
static int kbc_read(void);
}
-/*===========================================================================*
- * kbd_status *
- *===========================================================================*/
-int kbd_status(message *m)
-{
- int r;
-
- r= handle_status(&kbd, m);
- if (r)
- return r;
- return handle_status(&kbdaux, m);
-}
-
-
/*===========================================================================*
* do_kbdaux *
*===========================================================================*/
switch (m->m_type) {
case DEV_OPEN:
kbdp->nr_open++;
- r= OK;
- break;
+ tty_reply(DEV_OPEN_REPL, m->m_source, m->USER_ENDPT,
+ (cp_grant_id_t) m->IO_GRANT, OK);
+ return;
case DEV_CLOSE:
kbdp->nr_open--;
if (kbdp->nr_open < 0)
}
if (kbdp->nr_open == 0)
kbdp->avail= 0;
- r= OK;
- break;
+ tty_reply(DEV_CLOSE_REPL, m->m_source, m->USER_ENDPT,
+ (cp_grant_id_t) m->IO_GRANT, OK);
+ return;
case DEV_READ_S:
if (kbdp->req_size)
{
kbdp->req_grant= (cp_grant_id_t) m->IO_GRANT;
kbdp->req_addr_offset= 0;
kbdp->incaller= m->m_source;
- r= SUSPEND;
- break;
+ return;
}
/* Handle read request */
case CANCEL:
kbdp->req_size= 0;
- r= OK;
+ r= EAGAIN;
break;
case DEV_SELECT:
- ops = m->USER_ENDPT & (SEL_RD|SEL_WR|SEL_ERR);
- watch = (m->USER_ENDPT & SEL_NOTIFY) ? 1 : 0;
+ ops = m->DEV_SEL_OPS & (SEL_RD|SEL_WR|SEL_ERR);
+ watch = (m->DEV_SEL_OPS & SEL_NOTIFY) ? 1 : 0;
r= 0;
if (kbdp->avail && (ops & SEL_RD))
{
kbdp->select_ops |= ops;
kbdp->select_proc= m->m_source;
+ kbdp->select_minor= m->DEV_MINOR;
}
- break;
+ assert(kbdp->minor == m->DEV_MINOR);
+ select_reply(DEV_SEL_REPL1, m->m_source, m->DEV_MINOR, r);
+ return;
case DEV_IOCTL_S:
- if (kbdp == &kbd && m->TTY_REQUEST == KIOCSLEDS)
+ if (kbdp == &kbd && m->REQUEST == KIOCSLEDS)
{
kio_leds_t leds;
unsigned char b;
r= OK;
break;
}
- if (kbdp == &kbd && m->TTY_REQUEST == KIOCBELL)
+ if (kbdp == &kbd && m->REQUEST == KIOCBELL)
{
kio_bell_t bell;
clock_t ticks;
m->m_type, m->m_source);
r= EINVAL;
}
- tty_reply(TASK_REPLY, m->m_source, m->USER_ENDPT, r);
-}
-
-
-/*===========================================================================*
- * handle_status *
- *===========================================================================*/
-static int handle_status(kbdp, m)
-struct kbd *kbdp;
-message *m;
-{
- int n, r;
-
- if (kbdp->avail && kbdp->req_size && m->m_source == kbdp->incaller &&
- kbdp->req_grant != GRANT_INVALID)
- {
- /* Handle read request */
- n= kbdp->avail;
- if (n > kbdp->req_size)
- n= kbdp->req_size;
- if (kbdp->offset + n > KBD_BUFSZ)
- n= KBD_BUFSZ-kbdp->offset;
- if (n <= 0)
- panic("kbd_status: bad n: %d", n);
- kbdp->req_size= 0;
- r= sys_safecopyto(kbdp->incaller, kbdp->req_grant, 0,
- (vir_bytes)&kbdp->buf[kbdp->offset], n);
- if (r == OK)
- {
- kbdp->offset= (kbdp->offset+n) % KBD_BUFSZ;
- kbdp->avail -= n;
- r= n;
- } else printf("copy in revive kbd failed: %d\n", r);
-
- m->m_type = DEV_REVIVE;
- m->REP_ENDPT= kbdp->req_proc;
- m->REP_IO_GRANT= kbdp->req_grant;
- m->REP_STATUS= r;
- kbdp->req_grant = GRANT_INVALID;
- return 1;
- }
- if (kbdp->avail && (kbdp->select_ops & SEL_RD) &&
- m->m_source == kbdp->select_proc)
- {
- m->m_type = DEV_IO_READY;
- m->DEV_MINOR = kbdp->minor;
- m->DEV_SEL_OPS = SEL_RD;
-
- kbdp->select_ops &= ~SEL_RD;
- return 1;
- }
-
- return 0;
+ tty_reply(DEV_REVIVE, m->m_source, m->USER_ENDPT,
+ (cp_grant_id_t) m->IO_GRANT, r);
}
void kbd_interrupt(message *UNUSED(m_ptr))
{
/* A keyboard interrupt has occurred. Process it. */
- int o, isaux;
+ int n, r, o, isaux;
unsigned char scode;
struct kbd *kbdp;
#endif
return; /* Buffer is full */
}
- o= (kbdp->offset + kbdp->avail) % KBD_BUFSZ;
- kbdp->buf[o]= scode;
- kbdp->avail++;
- if (kbdp->req_size) {
- notify(kbdp->incaller);
- }
- if (kbdp->select_ops & SEL_RD)
- notify(kbdp->select_proc);
- return;
+ o= (kbdp->offset + kbdp->avail) % KBD_BUFSZ;
+ kbdp->buf[o]= scode;
+ kbdp->avail++;
+ if (kbdp->req_size) {
+ /* Reply to read request */
+ n= kbdp->avail;
+ if (n > kbdp->req_size)
+ n= kbdp->req_size;
+ if (kbdp->offset + n > KBD_BUFSZ)
+ n= KBD_BUFSZ-kbdp->offset;
+ if (n <= 0)
+ panic("kbd_interrupt: bad n: %d", n);
+ kbdp->req_size= 0;
+ r= sys_safecopyto(kbdp->incaller, kbdp->req_grant, 0,
+ (vir_bytes)&kbdp->buf[kbdp->offset], n);
+ if (r == OK)
+ {
+ kbdp->offset= (kbdp->offset+n) % KBD_BUFSZ;
+ kbdp->avail -= n;
+ r= n;
+ } else printf("copy in revive kbd failed: %d\n", r);
+
+ tty_reply(DEV_REVIVE, kbdp->incaller, kbdp->req_proc,
+ kbdp->req_grant, r);
+ kbdp->req_grant = GRANT_INVALID;
+ }
+ /* Only satisfy pending select if characters weren't just read. */
+ if (kbdp->avail && (kbdp->select_ops & SEL_RD)) {
+ assert(kbdp->select_minor == kbdp->minor);
+ select_reply(DEV_SEL_REPL2, kbdp->select_proc, kbdp->minor,
+ SEL_RD);
+ kbdp->select_ops &= ~SEL_RD;
+ }
+ return;
}
/* Store the scancode in memory so the task can get at it later. */
tp->tty_outcum += count;
if ((tp->tty_outleft -= count) == 0) {
/* Output is finished, reply to the writer. */
- if(tp->tty_outrepcode == TTY_REVIVE) {
- notify(tp->tty_outcaller);
- tp->tty_outrevived = 1;
- } else {
- tty_reply(tp->tty_outrepcode, tp->tty_outcaller,
- tp->tty_outproc, tp->tty_outcum);
- tp->tty_outcum = 0;
- }
+ tty_reply(DEV_REVIVE, tp->tty_outcaller, tp->tty_outproc,
+ tp->tty_outgrant, tp->tty_outcum);
+ tp->tty_outcum = 0;
+ tp->tty_outgrant = GRANT_INVALID;
}
}
if (tp->tty_outleft > 0 && tp->tty_termios.c_ospeed == B0) {
/* Oops, the line has hung up. */
- if(tp->tty_outrepcode == TTY_REVIVE) {
- notify(tp->tty_outcaller);
- tp->tty_outrevived = 1;
- } else {
- tty_reply(tp->tty_outrepcode, tp->tty_outcaller,
- tp->tty_outproc, EIO);
- tp->tty_outleft = tp->tty_outcum = 0;
- }
+ tty_reply(DEV_REVIVE, tp->tty_outcaller, tp->tty_outproc,
+ tp->tty_outgrant, EIO);
+ tp->tty_outleft = tp->tty_outcum = 0;
+ tp->tty_outgrant = GRANT_INVALID;
}
return 1;
char state; /* flags: busy, closed, ... */
/* Read call on /dev/ptypX. */
- char rdsendreply; /* send a reply (instead of notify) */
int rdcaller; /* process making the call (usually FS) */
int rdproc; /* process that wants to read from the pty */
cp_grant_id_t rdgrant; /* grant for readers address space */
int rdcum; /* # bytes written so far */
/* Write call to /dev/ptypX. */
- char wrsendreply; /* send a reply (instead of notify) */
int wrcaller; /* process making the call (usually FS) */
int wrproc; /* process that wants to write to the pty */
cp_grant_id_t wrgrant; /* grant for writers address space */
char obuf[2048]; /* buffer for bytes going to the pty reader */
/* select() data. */
- int select_ops, /* Which operations do we want to know about? */
- select_proc, /* Who wants to know about it? */
- select_ready_ops; /* For callback. */
+ int select_ops; /* Which operations do we want to know about? */
+ int select_proc; /* Who wants to know about it? */
+ dev_t select_minor; /* sanity check only, can be removed */
} pty_t;
#define PTY_ACTIVE 0x01 /* pty is open/active */
static int pty_close(tty_t *tp, int try);
static int pty_icancel(tty_t *tp, int try);
static int pty_ocancel(tty_t *tp, int try);
-static int pty_select(tty_t *tp, message *m);
+static void pty_select(tty_t *tp, message *m);
/*===========================================================================*
* do_pty *
r = ENOBUFS;
break;
}
- pp->rdsendreply = TRUE;
pp->rdcaller = m_ptr->m_source;
pp->rdproc = m_ptr->USER_ENDPT;
pp->rdgrant = (cp_grant_id_t) m_ptr->IO_GRANT;
pp->rdleft = pp->rdcum = 0;
pp->rdgrant = GRANT_INVALID;
} else {
- r = SUSPEND; /* do suspend */
- pp->rdsendreply = FALSE;
+ return; /* do suspend */
}
break;
r = ENOBUFS;
break;
}
- pp->wrsendreply = TRUE;
pp->wrcaller = m_ptr->m_source;
pp->wrproc = m_ptr->USER_ENDPT;
pp->wrgrant = (cp_grant_id_t) m_ptr->IO_GRANT;
pp->wrgrant = GRANT_INVALID;
r = EAGAIN;
} else {
- pp->wrsendreply = FALSE; /* do suspend */
- r = SUSPEND;
+ return; /* do suspend */
}
break;
pp->state |= PTY_ACTIVE;
pp->rdcum = 0;
pp->wrcum = 0;
- break;
+ tty_reply(DEV_OPEN_REPL, m_ptr->m_source, m_ptr->USER_ENDPT,
+ (cp_grant_id_t) m_ptr->IO_GRANT, r);
+ return;
case DEV_CLOSE:
- r = OK;
if (pp->state & TTY_CLOSED) {
pp->state = 0;
} else {
pp->state |= PTY_CLOSED;
sigchar(tp, SIGHUP, 1);
}
- break;
+ tty_reply(DEV_CLOSE_REPL, m_ptr->m_source, m_ptr->USER_ENDPT,
+ (cp_grant_id_t) m_ptr->IO_GRANT, OK);
+ return;
case DEV_SELECT:
- r = pty_select(tp, m_ptr);
- break;
+ pty_select(tp, m_ptr);
+ return;
case CANCEL:
r = EINTR;
default:
r = EINVAL;
}
- tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->USER_ENDPT, r);
+ tty_reply(DEV_REVIVE, m_ptr->m_source, m_ptr->USER_ENDPT,
+ (cp_grant_id_t) m_ptr->IO_GRANT, r);
}
/*===========================================================================*
if (pp->state & PTY_CLOSED) {
if (try) return 1;
if (tp->tty_outleft > 0) {
- if(tp->tty_outrepcode == TTY_REVIVE) {
- notify(tp->tty_outcaller);
- tp->tty_outrevived = 1;
- } else {
- tty_reply(tp->tty_outrepcode, tp->tty_outcaller,
- tp->tty_outproc, EIO);
- tp->tty_outleft = tp->tty_outcum = 0;
- }
+ tty_reply(DEV_REVIVE, tp->tty_outcaller, tp->tty_outproc,
+ tp->tty_outgrant, EIO);
+ tp->tty_outleft = tp->tty_outcum = 0;
+ tp->tty_outgrant = GRANT_INVALID;
}
return 0;
}
tp->tty_outcum += count;
if ((tp->tty_outleft -= count) == 0) {
/* Output is finished, reply to the writer. */
- if(tp->tty_outrepcode == TTY_REVIVE) {
- notify(tp->tty_outcaller);
- tp->tty_outrevived = 1;
- } else {
- tty_reply(tp->tty_outrepcode, tp->tty_outcaller,
- tp->tty_outproc, tp->tty_outcum);
- tp->tty_outcum = 0;
- }
+ tty_reply(DEV_REVIVE, tp->tty_outcaller, tp->tty_outproc,
+ tp->tty_outgrant, tp->tty_outcum);
+ tp->tty_outcum = 0;
+ tp->tty_outgrant = GRANT_INVALID;
}
}
pty_finish(pp);
* transferred.
*/
if (pp->rdcum > 0) {
- if (pp->rdsendreply) {
- tty_reply(TASK_REPLY, pp->rdcaller, pp->rdproc, pp->rdcum);
- pp->rdleft = pp->rdcum = 0;
- }
- else
- notify(pp->rdcaller);
+ tty_reply(DEV_REVIVE, pp->rdcaller, pp->rdproc, pp->rdgrant,
+ pp->rdcum);
+ pp->rdleft = pp->rdcum = 0;
+ pp->rdgrant = GRANT_INVALID;
}
}
if (pp->state & PTY_CLOSED) {
if (try) return 1;
if (tp->tty_inleft > 0) {
- if(tp->tty_inrepcode == TTY_REVIVE) {
- notify(tp->tty_incaller);
- tp->tty_inrevived = 1;
- } else {
- tty_reply(tp->tty_inrepcode, tp->tty_incaller,
- tp->tty_inproc, tp->tty_incum);
- tp->tty_inleft = tp->tty_incum = 0;
- }
+ tty_reply(DEV_REVIVE, tp->tty_incaller, tp->tty_inproc,
+ tp->tty_ingrant, tp->tty_incum);
+ tp->tty_inleft = tp->tty_incum = 0;
+ tp->tty_ingrant = GRANT_INVALID;
}
return 1;
}
/* PTY writer bookkeeping. */
pp->wrcum++;
if (--pp->wrleft == 0) {
- if (pp->wrsendreply) {
- tty_reply(TASK_REPLY, pp->wrcaller, pp->wrproc,
- pp->wrcum);
- pp->wrcum = 0;
- }
- else
- notify(pp->wrcaller);
+ tty_reply(DEV_REVIVE, pp->wrcaller, pp->wrproc, pp->wrgrant,
+ pp->wrcum);
+ pp->wrcum = 0;
+ pp->wrgrant = GRANT_INVALID;
}
}
if (!(pp->state & PTY_ACTIVE)) return 0;
if (pp->rdleft > 0) {
- assert(!pp->rdsendreply);
- notify(pp->rdcaller);
+ tty_reply(DEV_REVIVE, pp->rdcaller, pp->rdproc, pp->rdgrant,
+ pp->rdcum);
+ pp->rdleft = pp->rdcum = 0;
+ pp->rdgrant = GRANT_INVALID;
}
if (pp->wrleft > 0) {
- assert(!pp->wrsendreply);
- notify(pp->wrcaller);
+ tty_reply(DEV_REVIVE, pp->wrcaller, pp->wrproc, pp->wrgrant,
+ pp->wrcum);
+ pp->wrcum = 0;
+ pp->wrgrant = GRANT_INVALID;
}
if (pp->state & PTY_CLOSED) pp->state = 0; else pp->state |= TTY_CLOSED;
pty_t *pp = tp->tty_priv;
if (pp->wrleft > 0) {
- pp->wrcum += pp->wrleft;
- pp->wrleft= 0;
- notify(pp->wrcaller);
+ tty_reply(DEV_REVIVE, pp->wrcaller, pp->wrproc, pp->wrgrant,
+ pp->wrcum + pp->wrleft);
+ pp->wrcum = pp->wrleft = 0;
+ pp->wrgrant = GRANT_INVALID;
}
return 0;
tp->tty_select_ops = 0;
}
-/*===========================================================================*
- * pty_status *
- *===========================================================================*/
-int pty_status(message *m_ptr)
-{
- int i, event_found;
- pty_t *pp;
-
- event_found = 0;
- for (i= 0, pp = pty_table; i<NR_PTYS; i++, pp++) {
- if ((((pp->state & TTY_CLOSED) && pp->rdleft > 0) ||
- pp->rdcum > 0) &&
- pp->rdcaller == m_ptr->m_source)
- {
- m_ptr->m_type = DEV_REVIVE;
- m_ptr->REP_ENDPT = pp->rdproc;
- m_ptr->REP_IO_GRANT = pp->rdgrant;
- m_ptr->REP_STATUS = pp->rdcum;
- pp->rdleft = pp->rdcum = 0;
- pp->rdgrant = GRANT_INVALID;
- event_found = 1;
- break;
- }
-
- if ((((pp->state & TTY_CLOSED) && pp->wrleft > 0) ||
- pp->wrcum > 0) &&
- pp->wrcaller == m_ptr->m_source)
- {
- m_ptr->m_type = DEV_REVIVE;
- m_ptr->REP_ENDPT = pp->wrproc;
- m_ptr->REP_IO_GRANT = pp->wrgrant;
- if (pp->wrcum == 0)
- m_ptr->REP_STATUS = EIO;
- else
- m_ptr->REP_STATUS = pp->wrcum;
-
- pp->wrleft = pp->wrcum = 0;
- pp->wrgrant = GRANT_INVALID;
- event_found = 1;
- break;
- }
-
- if (pp->select_ready_ops && pp->select_proc == m_ptr->m_source) {
- m_ptr->m_type = DEV_IO_READY;
- m_ptr->DEV_MINOR = PTYPX_MINOR + i;
- m_ptr->DEV_SEL_OPS = pp->select_ready_ops;
- pp->select_ready_ops = 0;
- event_found = 1;
- break;
- }
- }
- return event_found;
-}
-
/*===========================================================================*
* select_try_pty *
*===========================================================================*/
void select_retry_pty(tty_t *tp)
{
pty_t *pp = tp->tty_priv;
+ dev_t minor;
int r;
/* See if the pty side of a pty is ready to return a select. */
if (pp->select_ops && (r=select_try_pty(tp, pp->select_ops))) {
+ minor = PTYPX_MINOR + (int) (pp - pty_table);
+ assert(minor == pp->select_minor);
+ select_reply(DEV_SEL_REPL2, pp->select_proc, minor, r);
pp->select_ops &= ~r;
- pp->select_ready_ops |= r;
- notify(pp->select_proc);
}
}
/*===========================================================================*
* pty_select *
*===========================================================================*/
-static int pty_select(tty_t *tp, message *m)
+static void pty_select(tty_t *tp, message *m)
{
pty_t *pp = tp->tty_priv;
int ops, ready_ops = 0, watch;
- ops = m->USER_ENDPT & (SEL_RD|SEL_WR|SEL_ERR);
- watch = (m->USER_ENDPT & SEL_NOTIFY) ? 1 : 0;
+ ops = m->DEV_SEL_OPS & (SEL_RD|SEL_WR|SEL_ERR);
+ watch = (m->DEV_SEL_OPS & SEL_NOTIFY) ? 1 : 0;
ready_ops = select_try_pty(tp, ops);
if (!ready_ops && ops && watch) {
pp->select_ops |= ops;
pp->select_proc = m->m_source;
+ pp->select_minor = m->DEV_MINOR;
}
- return ready_ops;
+ select_reply(DEV_SEL_REPL1, m->m_source, m->DEV_MINOR, ready_ops);
}
#endif /* NR_PTYS > 0 */
* DEV_OPEN: a tty line has been opened
* DEV_CLOSE: a tty line has been closed
* DEV_SELECT: start select notification request
- * DEV_STATUS: FS wants to know status for SELECT or REVIVE
* CANCEL: terminate a previous incomplete system call immediately
*
- * m_type TTY_LINE USER_ENDPT COUNT TTY_SPEKS IO_GRANT
+ * m_type DEVICE USER_ENDPT COUNT POSITION IO_GRANT
* -----------------------------------------------------------------
* | HARD_INT | | | | | |
* |-------------+---------+---------+---------+---------+---------|
- * | SYS_SIG | sig set | | | | |
- * |-------------+---------+---------+---------+---------+---------|
* | DEV_READ |minor dev| proc nr | count | | grant |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_WRITE |minor dev| proc nr | count | | grant |
* |-------------+---------+---------+---------+---------+---------|
- * | DEV_IOCTL |minor dev| proc nr |func code|erase etc| |
+ * | DEV_IOCTL |minor dev| proc nr |func code|user proc| |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_OPEN |minor dev| proc nr | O_NOCTTY| | |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_CLOSE |minor dev| proc nr | | | |
* |-------------+---------+---------+---------+---------+---------|
- * | DEV_STATUS | | | | | |
- * |-------------+---------+---------+---------+---------+---------|
* | CANCEL |minor dev| proc nr | | | |
+ * |-------------+---------+---------+---------+---------+---------|
+ * | DEV_SELECT |minor dev| sel ops | | | |
* -----------------------------------------------------------------
*
* Changes:
static void do_read(tty_t *tp, message *m_ptr);
static void do_write(tty_t *tp, message *m_ptr);
static void do_select(tty_t *tp, message *m_ptr);
-static void do_status(message *m_ptr);
static void in_transfer(tty_t *tp);
static int tty_echo(tty_t *tp, int ch);
static void rawecho(tty_t *tp, int ch);
message tty_mess; /* buffer for all incoming messages */
int ipc_status;
unsigned line;
- int r;
+ int r, code;
register tty_t *tp;
/* SEF local startup. */
; /* do nothing; end switch */
}
- /* Only device requests should get to this point. All requests,
- * except DEV_STATUS, have a minor device number. Check this
- * exception and get the minor device number otherwise.
+ /* Only device requests should get to this point.
+ * All requests have a minor device number.
*/
- if (tty_mess.m_type == DEV_STATUS) {
- do_status(&tty_mess);
- continue;
- }
- line = tty_mess.TTY_LINE;
+ line = tty_mess.DEVICE;
if (line == CONS_MINOR || line == LOG_MINOR) {
/* /dev/log output goes to /dev/console */
if (consoleline != CONS_MINOR) {
/* Console output must redirected */
line = consoleline;
- tty_mess.TTY_LINE = line;
+ tty_mess.DEVICE = line;
}
}
if (line == KBD_MINOR) {
/* If the device doesn't exist or is not configured return ENXIO. */
if (tp == NULL || ! tty_active(tp)) {
- if (tty_mess.m_source != LOG_PROC_NR) {
- tty_reply(TASK_REPLY, tty_mess.m_source,
- tty_mess.USER_ENDPT, ENXIO);
+ if (tty_mess.m_source == LOG_PROC_NR)
+ continue;
+
+ /* Can all of these occur? Probably not. We're by far most
+ * likely to see DEV_OPEN, but better safe than sorry..
+ */
+ switch (tty_mess.m_type) {
+ case DEV_OPEN: code = DEV_OPEN_REPL; break;
+ case DEV_CLOSE: code = DEV_CLOSE_REPL; break;
+ default: code = DEV_REVIVE; break;
}
+
+ tty_reply(code, tty_mess.m_source, tty_mess.USER_ENDPT,
+ (cp_grant_id_t) tty_mess.IO_GRANT, ENXIO);
continue;
}
default:
printf("Warning, TTY got unexpected request %d from %d\n",
tty_mess.m_type, tty_mess.m_source);
- tty_reply(TASK_REPLY, tty_mess.m_source,
- tty_mess.USER_ENDPT, EINVAL);
+ tty_reply(DEV_REVIVE, tty_mess.m_source, tty_mess.USER_ENDPT,
+ (cp_grant_id_t) tty_mess.IO_GRANT, EINVAL);
}
}
}
}
-/*===========================================================================*
- * do_status *
- *===========================================================================*/
-static void do_status(m_ptr)
-message *m_ptr;
-{
- register struct tty *tp;
- int event_found;
- int status;
- int ops;
-
- /* Check for select or revive events on any of the ttys. If we found an,
- * event return a single status message for it. The FS will make another
- * call to see if there is more.
- */
- event_found = 0;
- for (tp = FIRST_TTY; tp < END_TTY; tp++) {
- if ((ops = select_try(tp, tp->tty_select_ops)) &&
- tp->tty_select_proc == m_ptr->m_source) {
-
- /* I/O for a selected minor device is ready. */
- m_ptr->m_type = DEV_IO_READY;
- m_ptr->DEV_MINOR = tp->tty_minor;
- m_ptr->DEV_SEL_OPS = ops;
-
- tp->tty_select_ops &= ~ops; /* unmark select event */
- event_found = 1;
- break;
- }
- else if (tp->tty_inrevived && tp->tty_incaller == m_ptr->m_source) {
-
- /* Suspended request finished. Send a REVIVE. */
- m_ptr->m_type = DEV_REVIVE;
- m_ptr->REP_ENDPT = tp->tty_inproc;
- m_ptr->REP_IO_GRANT = tp->tty_ingrant;
- m_ptr->REP_STATUS = tp->tty_incum;
-
- tp->tty_inleft = tp->tty_incum = 0;
- tp->tty_inrevived = 0; /* unmark revive event */
- tp->tty_ingrant = GRANT_INVALID;
- event_found = 1;
- break;
- }
- else if (tp->tty_outrevived && tp->tty_outcaller == m_ptr->m_source) {
-
- /* Suspended request finished. Send a REVIVE. */
- m_ptr->m_type = DEV_REVIVE;
- m_ptr->REP_ENDPT = tp->tty_outproc;
- m_ptr->REP_IO_GRANT = tp->tty_outgrant;
- m_ptr->REP_STATUS = tp->tty_outcum;
-
- tp->tty_outcum = 0;
- tp->tty_outrevived = 0; /* unmark revive event */
- tp->tty_outgrant = GRANT_INVALID;
- event_found = 1;
- break;
- }
- else if (tp->tty_iorevived && tp->tty_iocaller == m_ptr->m_source) {
-
- /* Suspended request finished. Send a REVIVE. */
- m_ptr->m_type = DEV_REVIVE;
- m_ptr->REP_ENDPT = tp->tty_ioproc;
- m_ptr->REP_IO_GRANT = tp->tty_iogrant;
- m_ptr->REP_STATUS = tp->tty_iostatus;
- tp->tty_iorevived = 0; /* unmark revive event */
- tp->tty_iogrant = GRANT_INVALID;
- event_found = 1;
- break;
- }
- }
-
-#if NR_PTYS > 0
- if (!event_found)
- event_found = pty_status(m_ptr);
-#endif
- if (!event_found)
- event_found= kbd_status(m_ptr);
-
- if (! event_found) {
- /* No events of interest were found. Return an empty message. */
- m_ptr->m_type = DEV_NO_STATUS;
- }
-
- /* Almost done. Send back the reply message to the caller. */
- status = send(m_ptr->m_source, m_ptr);
- if (status != OK) {
- printf("tty`do_status: send to %d failed: %d\n",
- m_ptr->m_source, status);
- }
-}
-
/*===========================================================================*
* do_read *
*===========================================================================*/
r = ENOBUFS;
} else {
/* Copy information from the message to the tty struct. */
- tp->tty_inrepcode = TASK_REPLY;
tp->tty_incaller = m_ptr->m_source;
tp->tty_inproc = m_ptr->USER_ENDPT;
tp->tty_ingrant = (cp_grant_id_t) m_ptr->IO_GRANT;
if (m_ptr->FLAGS & FLG_OP_NONBLOCK) {
tty_icancel(tp);
r = tp->tty_incum > 0 ? tp->tty_incum : EAGAIN;
- tp->tty_inleft = tp->tty_incum = tp->tty_inrevived = 0;
+ tp->tty_inleft = tp->tty_incum = 0;
tp->tty_ingrant = GRANT_INVALID;
} else {
- r = SUSPEND; /* suspend the caller */
- tp->tty_inrepcode = TTY_REVIVE;
+ return; /* suspend the caller */
}
}
- tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->USER_ENDPT, r);
+ tty_reply(DEV_REVIVE, m_ptr->m_source, m_ptr->USER_ENDPT,
+ (cp_grant_id_t) m_ptr->IO_GRANT, r);
if (tp->tty_select_ops)
select_retry(tp);
}
r = EINVAL;
} else {
/* Copy message parameters to the tty structure. */
- tp->tty_outrepcode = TASK_REPLY;
tp->tty_outcaller = m_ptr->m_source;
tp->tty_outproc = m_ptr->USER_ENDPT;
tp->tty_outgrant = (cp_grant_id_t) m_ptr->IO_GRANT;
/* None or not all the bytes could be written. */
if (m_ptr->FLAGS & FLG_OP_NONBLOCK) {
r = tp->tty_outcum > 0 ? tp->tty_outcum : EAGAIN;
- tp->tty_outleft = tp->tty_outcum = tp->tty_outrevived = 0;
+ tp->tty_outleft = tp->tty_outcum = 0;
tp->tty_outgrant = GRANT_INVALID;
} else {
- r = SUSPEND; /* suspend the caller */
- tp->tty_outrepcode = TTY_REVIVE;
+ return; /* suspend the caller */
}
}
- tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->USER_ENDPT, r);
+ tty_reply(DEV_REVIVE, m_ptr->m_source, m_ptr->USER_ENDPT,
+ (cp_grant_id_t) m_ptr->IO_GRANT, r);
}
/*===========================================================================*
size_t size;
/* Size of the ioctl parameter. */
- switch (m_ptr->TTY_REQUEST) {
+ switch (m_ptr->REQUEST) {
case TCGETS: /* Posix tcgetattr function */
case TCSETS: /* Posix tcsetattr function, TCSANOW option */
case TCSETSW: /* Posix tcsetattr function, TCSADRAIN option */
}
r = OK;
- switch (m_ptr->TTY_REQUEST) {
+ switch (m_ptr->REQUEST) {
case TCGETS:
/* Get the termios attributes. */
r = sys_safecopyto(m_ptr->m_source, (cp_grant_id_t) m_ptr->IO_GRANT, 0,
tp->tty_ioproc = m_ptr->USER_ENDPT;
tp->tty_ioreq = m_ptr->REQUEST;
tp->tty_iogrant = (cp_grant_id_t) m_ptr->IO_GRANT;
- r = SUSPEND;
+ return;
}
break;
}
- if (m_ptr->TTY_REQUEST == TCDRAIN) break;
- if (m_ptr->TTY_REQUEST == TCSETSF) tty_icancel(tp);
+ if (m_ptr->REQUEST == TCDRAIN) break;
+ if (m_ptr->REQUEST == TCSETSF) tty_icancel(tp);
/*FALL THROUGH*/
case TCSETS:
/* Set the termios attributes. */
}
/* Send the reply. */
- tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->USER_ENDPT, r);
+ tty_reply(DEV_REVIVE, m_ptr->m_source, m_ptr->USER_ENDPT,
+ (cp_grant_id_t) m_ptr->IO_GRANT, r);
}
/*===========================================================================*
*/
int r = OK;
- if (m_ptr->TTY_LINE == LOG_MINOR) {
+ if (m_ptr->DEVICE == LOG_MINOR) {
/* The log device is a write-only diagnostics device. */
if (m_ptr->COUNT & R_BIT) r = EACCES;
} else {
(*tp->tty_open)(tp, 0);
}
}
- tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->USER_ENDPT, r);
+ tty_reply(DEV_OPEN_REPL, m_ptr->m_source, m_ptr->USER_ENDPT,
+ (cp_grant_id_t) m_ptr->IO_GRANT, r);
}
/*===========================================================================*
{
/* A tty line has been closed. Clean up the line if it is the last close. */
- if (m_ptr->TTY_LINE != LOG_MINOR && --tp->tty_openct == 0) {
+ if (m_ptr->DEVICE != LOG_MINOR && --tp->tty_openct == 0) {
tp->tty_pgrp = 0;
tty_icancel(tp);
(*tp->tty_ocancel)(tp, 0);
tp->tty_winsize = winsize_defaults;
setattr(tp);
}
- tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->USER_ENDPT, OK);
+ tty_reply(DEV_CLOSE_REPL, m_ptr->m_source, m_ptr->USER_ENDPT,
+ (cp_grant_id_t) m_ptr->IO_GRANT, OK);
}
/*===========================================================================*
/* A signal has been sent to a process that is hanging trying to read or write.
* The pending read or write must be finished off immediately.
*/
-
- int proc_nr;
+ endpoint_t proc_nr;
+ cp_grant_id_t grant;
int mode;
- int r = EINTR;
+ int r = EDONTREPLY;
/* Check the parameters carefully, to avoid cancelling twice. */
proc_nr = m_ptr->USER_ENDPT;
+ grant = (cp_grant_id_t) m_ptr->IO_GRANT;
mode = m_ptr->COUNT;
if ((mode & R_BIT) && tp->tty_inleft != 0 && proc_nr == tp->tty_inproc &&
- tp->tty_ingrant == (cp_grant_id_t) m_ptr->IO_GRANT) {
+ tp->tty_ingrant == grant) {
/* Process was reading when killed. Clean up input. */
tty_icancel(tp);
r = tp->tty_incum > 0 ? tp->tty_incum : EAGAIN;
- tp->tty_inleft = tp->tty_incum = tp->tty_inrevived = 0;
+ tp->tty_inleft = tp->tty_incum = 0;
tp->tty_ingrant = GRANT_INVALID;
}
if ((mode & W_BIT) && tp->tty_outleft != 0 && proc_nr == tp->tty_outproc &&
- tp->tty_outgrant == (cp_grant_id_t) m_ptr->IO_GRANT) {
+ tp->tty_outgrant == grant) {
/* Process was writing when killed. Clean up output. */
r = tp->tty_outcum > 0 ? tp->tty_outcum : EAGAIN;
- tp->tty_outleft = tp->tty_outcum = tp->tty_outrevived = 0;
+ tp->tty_outleft = tp->tty_outcum = 0;
tp->tty_outgrant = GRANT_INVALID;
}
if (tp->tty_ioreq != 0 && proc_nr == tp->tty_ioproc) {
/* Process was waiting for output to drain. */
tp->tty_ioreq = 0;
+ r = EINTR;
}
tp->tty_events = 1;
- tty_reply(TASK_REPLY, m_ptr->m_source, proc_nr, r);
+ /* Only reply if we found a matching request. */
+ if (r != EDONTREPLY)
+ tty_reply(DEV_REVIVE, m_ptr->m_source, proc_nr, grant, r);
}
int select_try(struct tty *tp, int ops)
int select_retry(struct tty *tp)
{
- if (tp->tty_select_ops && select_try(tp, tp->tty_select_ops))
- notify(tp->tty_select_proc);
+ int ops;
+
+ if (tp->tty_select_ops && (ops = select_try(tp, tp->tty_select_ops))) {
+ assert(tp->tty_select_minor == tp->tty_minor);
+ select_reply(DEV_SEL_REPL2, tp->tty_select_proc, tp->tty_minor,
+ ops);
+ tp->tty_select_ops &= ~ops;
+ }
return OK;
}
/* Reply if enough bytes are available. */
if (tp->tty_incum >= tp->tty_min && tp->tty_inleft > 0) {
- if (tp->tty_inrepcode == TTY_REVIVE) {
- notify(tp->tty_incaller);
- tp->tty_inrevived = 1;
- } else {
- tty_reply(tp->tty_inrepcode, tp->tty_incaller,
- tp->tty_inproc, tp->tty_incum);
- tp->tty_inleft = tp->tty_incum = 0;
- tp->tty_inrevived = 0;
- tp->tty_ingrant = GRANT_INVALID;
- }
+ tty_reply(DEV_REVIVE, tp->tty_incaller, tp->tty_inproc,
+ tp->tty_ingrant, tp->tty_incum);
+ tp->tty_inleft = tp->tty_incum = 0;
+ tp->tty_ingrant = GRANT_INVALID;
}
if (tp->tty_select_ops)
{
/* Usually reply to the reader, possibly even if incum == 0 (EOF). */
if (tp->tty_inleft == 0) {
- if (tp->tty_inrepcode == TTY_REVIVE) {
- notify(tp->tty_incaller);
- tp->tty_inrevived = 1;
- } else {
- tty_reply(tp->tty_inrepcode, tp->tty_incaller,
- tp->tty_inproc, tp->tty_incum);
- tp->tty_inleft = tp->tty_incum = 0;
- tp->tty_inrevived = 0;
- tp->tty_ingrant = GRANT_INVALID;
- }
+ tty_reply(DEV_REVIVE, tp->tty_incaller, tp->tty_inproc,
+ tp->tty_ingrant, tp->tty_incum);
+ tp->tty_inleft = tp->tty_incum = 0;
+ tp->tty_ingrant = GRANT_INVALID;
}
}
if (result == OK) setattr(tp);
}
tp->tty_ioreq = 0;
- notify(tp->tty_iocaller);
- tp->tty_iorevived = 1;
- tp->tty_iostatus = result;
+ tty_reply(DEV_REVIVE, tp->tty_iocaller, tp->tty_ioproc, tp->tty_iogrant,
+ result);
+ tp->tty_iogrant = GRANT_INVALID;
}
/*===========================================================================*
*===========================================================================*/
void
tty_reply_f(
-file, line, code, replyee, proc_nr, status)
+file, line, code, replyee, proc_nr, grant, status)
char *file;
int line;
-int code; /* TASK_REPLY or REVIVE */
-int replyee; /* destination address for the reply */
-int proc_nr; /* to whom should the reply go? */
+int code; /* DEV_OPEN_REPL, DEV_CLOSE_REPL, DEV_REVIVE */
+endpoint_t replyee; /* destination address for the reply */
+endpoint_t proc_nr; /* to whom should the reply go? */
+cp_grant_id_t grant; /* which grant was involved? */
int status; /* reply code */
{
-/* Send a reply to a process that wanted to read or write data. */
- assert(code == TASK_REPLY);
+ message m;
+
+ assert(code == DEV_OPEN_REPL || code == DEV_CLOSE_REPL || code == DEV_REVIVE);
/* Don't reply to KERNEL (kernel messages) */
if (replyee == KERNEL) return;
- status = send_taskreply(replyee, proc_nr, status);
+ memset(&m, 0, sizeof(m));
+
+ m.REP_ENDPT = proc_nr;
+ m.REP_IO_GRANT = grant;
+ m.REP_STATUS = status;
+
+ status = _sendcall(replyee, code, &m);
if (status != OK)
printf("tty`tty_reply: send to %d failed: %d\n", replyee, status);
}
+/*===========================================================================*
+ * select_reply *
+ *===========================================================================*/
+void select_reply(int code, endpoint_t replyee, dev_t minor, int ops)
+{
+ message m;
+ int status;
+
+ memset(&m, 0, sizeof(m));
+
+ m.DEV_MINOR = minor;
+ m.DEV_SEL_OPS = ops;
+
+ status = _sendcall(replyee, code, &m);
+ if (status != OK)
+ printf("tty`select_reply: send to %d failed: %d\n", replyee, status);
+}
+
+
/*===========================================================================*
* sigchar *
*===========================================================================*/
{
int ops, ready_ops = 0, watch;
- ops = m_ptr->USER_ENDPT & (SEL_RD|SEL_WR|SEL_ERR);
- watch = (m_ptr->USER_ENDPT & SEL_NOTIFY) ? 1 : 0;
+ ops = m_ptr->DEV_SEL_OPS & (SEL_RD|SEL_WR|SEL_ERR);
+ watch = (m_ptr->DEV_SEL_OPS & SEL_NOTIFY) ? 1 : 0;
ready_ops = select_try(tp, ops);
if (!ready_ops && ops && watch) {
tp->tty_select_ops |= ops;
tp->tty_select_proc = m_ptr->m_source;
+ tp->tty_select_minor = m_ptr->DEV_MINOR;
}
- tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->USER_ENDPT, ready_ops);
-
- return;
+ assert(tp->tty_minor == m_ptr->DEV_MINOR);
+ select_reply(DEV_SEL_REPL1, m_ptr->m_source, tp->tty_minor, ready_ops);
}
-
#undef lock
#undef unlock
-#define TTY_REVIVE 6767
-
/* First minor numbers for the various classes of TTY devices. */
#define CONS_MINOR 0
#define LOG_MINOR 15
char tty_openct; /* count of number of opens of this tty */
/* Information about incomplete I/O requests is stored here. */
- int tty_inrepcode; /* reply code, TASK_REPLY or REVIVE */
- char tty_inrevived; /* set to 1 if revive callback is pending */
endpoint_t tty_incaller; /* process that made the call (usually VFS) */
endpoint_t tty_inproc; /* process that wants to read from tty */
cp_grant_id_t tty_ingrant; /* grant where data is to go */
vir_bytes tty_inoffset; /* offset into grant */
int tty_inleft; /* how many chars are still needed */
int tty_incum; /* # chars input so far */
- int tty_outrepcode; /* reply code, TASK_REPLY or REVIVE */
- int tty_outrevived; /* set to 1 if revive callback is pending */
endpoint_t tty_outcaller; /* process that made the call (usually VFS) */
endpoint_t tty_outproc; /* process that wants to write to tty */
cp_grant_id_t tty_outgrant; /* grant where data comes from */
int tty_outleft; /* # chars yet to be output */
int tty_outcum; /* # chars output so far */
endpoint_t tty_iocaller; /* process that made the call (usually VFS) */
- int tty_iorevived; /* set to 1 if revive callback is pending */
endpoint_t tty_ioproc; /* process that wants to do an ioctl */
- int tty_iostatus; /* result */
int tty_ioreq; /* ioctl request code */
cp_grant_id_t tty_iogrant; /* virtual address of ioctl buffer or grant */
/* select() data */
int tty_select_ops; /* which operations are interesting */
endpoint_t tty_select_proc; /* which process wants notification */
+ dev_t tty_select_minor; /* sanity check only, can be removed */
/* Miscellaneous. */
devfun_t tty_ioctl; /* set line speed, etc. at the device level */
void out_process(struct tty *tp, char *bstart, char *bpos, char *bend,
int *icount, int *ocount);
void tty_wakeup(clock_t now);
-#define tty_reply(c, r, p, s) tty_reply_f(__FILE__, __LINE__, (c), (r), (p), (s))
-void tty_reply_f(char *f, int l, int code, int replyee, int proc_nr, int
- status);
+#define tty_reply(c, r, p, g, s) tty_reply_f(__FILE__, __LINE__, (c), (r), (p), (g), (s))
+void tty_reply_f(char *f, int l, int code, endpoint_t replyee,
+ endpoint_t proc_nr, cp_grant_id_t grant, int status);
+void select_reply(int code, endpoint_t replyee, dev_t minor, int ops);
int select_try(struct tty *tp, int ops);
int select_retry(struct tty *tp);
void do_kbd(message *m);
void do_kb_inject(message *m);
void do_kbdaux(message *m);
-int kbd_status(message *m_ptr);
/* pty.c */
void do_pty(struct tty *tp, message *m_ptr);
void pty_init(struct tty *tp);
void select_retry_pty(struct tty *tp);
-int pty_status(message *m_ptr);
-
sleep 3
if [ X`/bin/sysenv lwip` = Xyes ]
then
- service up /usr/sbin/lwip -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE_A
+ service up /usr/sbin/lwip -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE
dhcpd --lwip &
else
service up /usr/sbin/inet -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE
# Start servers and drivers set at the boot monitor.
echo -n "Starting services:"
- up -n random -dev /dev/random -devstyle STYLE_DEVA -period 3HZ
+ up -n random -dev /dev/random -period 3HZ
# load random number generator
if [ -f $RANDOM_FILE ]
done
if [ X`/bin/sysenv lwip` = Xyes ]
then
- up lwip -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE_A
+ up lwip -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE
else
- up inet -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE
+ up inet -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE
fi
up -n ipc
#define VFS_VMCALL 117
-#define TASK_REPLY 121 /* to VFS: reply code from drivers, not
- * really a standalone call.
- */
#define MAPDRIVER 122 /* to VFS, map a device */
#define GETRUSAGE 123 /* to PM, VFS */
int(*cdr_other) (message *m_ptr);
};
-#define CHARDRIVER_SYNC 0 /* use the synchronous protocol */
-#define CHARDRIVER_ASYNC 1 /* use the asynchronous protocol */
-
-#define IS_CDEV_MINOR_RQ(type) (IS_DEV_RQ(type) && (type) != DEV_STATUS)
-
/* Functions defined by libchardriver. */
void chardriver_announce(void);
-void chardriver_process(struct chardriver *cdp, int driver_type, message
- *m_ptr, int ipc_status);
+void chardriver_process(struct chardriver *cdp, message *m_ptr,
+ int ipc_status);
void chardriver_terminate(void);
-void chardriver_task(struct chardriver *cdp, int driver_type);
+void chardriver_task(struct chardriver *cdp);
int do_nop(message *m_ptr);
void nop_cleanup(void);
#define DEV_OPEN (DEV_RQ_BASE + 6) /* open a minor device */
#define DEV_CLOSE (DEV_RQ_BASE + 7) /* close a minor device */
#define DEV_SELECT (DEV_RQ_BASE + 12) /* request select() attention */
-#define DEV_STATUS (DEV_RQ_BASE + 13) /* request driver status */
#define DEV_REOPEN (DEV_RQ_BASE + 14) /* reopen a minor device */
#define DEV_READ_S (DEV_RQ_BASE + 20) /* (safecopy) read from minor */
#define IS_DEV_RQ(type) (((type) & ~0xff) == DEV_RQ_BASE)
#define DEV_REVIVE (DEV_RS_BASE + 2) /* driver revives process */
-#define DEV_IO_READY (DEV_RS_BASE + 3) /* selected device ready */
-#define DEV_NO_STATUS (DEV_RS_BASE + 4) /* empty status reply */
#define DEV_REOPEN_REPL (DEV_RS_BASE + 5) /* reply to DEV_REOPEN */
#define DEV_CLOSE_REPL (DEV_RS_BASE + 6) /* reply to DEV_CLOSE */
#define DEV_SEL_REPL1 (DEV_RS_BASE + 7) /* first reply to DEV_SELECT */
#define REP_IO_GRANT m2_i3 /* DEV_REVIVE: grant by which I/O was done */
# define SUSPEND -998 /* status to suspend caller, reply later */
-/* Field names for messages to TTY driver. */
-#define TTY_LINE DEVICE /* message parameter: terminal line */
-#define TTY_REQUEST COUNT /* message parameter: ioctl request code */
-#define TTY_SPEK POSITION/* message parameter: ioctl speed, erasing */
-#define TTY_PGRP m2_i3 /* message parameter: process group */
-
/*===========================================================================*
* Messages for networking layer *
*===========================================================================*/
#define VFS_UMOUNT_LABEL m1_p2
#define VFS_UMOUNT_LABELLEN m1_i2
+/* Field names for the ioctl(2) call. */
+#define VFS_IOCTL_FD m2_i1
+#define VFS_IOCTL_REQ m2_i3
+#define VFS_IOCTL_ARG m2_p1
+
/*===========================================================================*
* Messages for VM server *
*===========================================================================*/
#include <minix/sys_config.h>
#include <minix/ipc.h>
-enum dev_style { STYLE_NDEV, STYLE_DEV, STYLE_DEVA, STYLE_TTY, STYLE_CTTY,
- STYLE_CLONE, STYLE_CLONE_A };
-#define IS_DEV_STYLE(s) (s>=STYLE_NDEV && s<=STYLE_CLONE_A)
-
-#define dev_style_asyn(devstyle) ((devstyle) == STYLE_DEVA || \
- (devstyle) == STYLE_CLONE_A)
+enum dev_style { STYLE_NDEV, STYLE_DEV, STYLE_TTY, STYLE_CTTY, STYLE_CLONE };
+#define IS_DEV_STYLE(s) (s>=STYLE_NDEV && s<=STYLE_CLONE)
/*===========================================================================*
* Major and minor device numbers *
int sys_umap_remote(endpoint_t proc_ep, endpoint_t grantee, int seg,
vir_bytes vir_addr, vir_bytes bytes, phys_bytes *phys_addr);
-int send_taskreply(endpoint_t who, endpoint_t endpoint, int status);
-
/* Shorthands for sys_getinfo() system call. */
#define sys_getkinfo(dst) sys_getinfo(GET_KINFO, dst, 0,0,0)
#define sys_getloadinfo(dst) sys_getinfo(GET_LOADINFO, dst, 0,0,0)
* |-------------+---------+---------+---------+---------+---------|
* | DEV_IOCTL_S | device | proc nr |func code| | buf ptr |
* |-------------+---------+---------+---------+---------+---------|
- * | DEV_STATUS | | | | | |
- * |-------------+---------+---------+---------+---------+---------|
* | HARD_INT | | | | | |
- * |-------------+---------+---------+---------+---------+---------|
- * | SIG_STOP | | | | | |
* -----------------------------------------------------------------
*
* The file contains one entry point:
EXTERN int sef_cb_lu_prepare(int state);
EXTERN int sef_cb_lu_state_isvalid(int state);
EXTERN void sef_cb_lu_state_dump(int state);
-int is_status_msg_expected = FALSE;
int main(void)
{
case DEV_OPEN:
/* open the special file ( = parameter) */
r = msg_open(mess.DEVICE);
- repl_mess.m_type = DEV_REVIVE;
+ repl_mess.m_type = DEV_OPEN_REPL;
repl_mess.REP_ENDPT = mess.USER_ENDPT;
+ repl_mess.REP_IO_GRANT =
+ (cp_grant_id_t) mess.IO_GRANT;
repl_mess.REP_STATUS = r;
send(caller, &repl_mess);
r = msg_close(mess.DEVICE);
repl_mess.m_type = DEV_CLOSE_REPL;
repl_mess.REP_ENDPT = mess.USER_ENDPT;
+ repl_mess.REP_IO_GRANT =
+ (cp_grant_id_t) mess.IO_GRANT;
repl_mess.REP_STATUS = r;
send(caller, &repl_mess);
repl_mess.m_type = DEV_REVIVE;
repl_mess.REP_ENDPT = mess.USER_ENDPT;
repl_mess.REP_IO_GRANT =
- (unsigned)mess.IO_GRANT;
+ (cp_grant_id_t) mess.IO_GRANT;
repl_mess.REP_STATUS = r;
send(caller, &repl_mess);
}
msg_read(&mess); continue; /* don't reply */
case DEV_WRITE_S:
msg_write(&mess); continue; /* don't reply */
- case DEV_STATUS:
- msg_status(&mess);continue; /* don't reply */
case DEV_REOPEN:
/* reopen the special file ( = parameter) */
r = msg_open(mess.DEVICE);
repl_mess.m_type = DEV_REOPEN_REPL;
repl_mess.REP_ENDPT = mess.USER_ENDPT;
+ repl_mess.REP_IO_GRANT =
+ (cp_grant_id_t) mess.IO_GRANT;
repl_mess.REP_STATUS = r;
send(caller, &repl_mess);
continue;
}
-static void msg_status(message *m_ptr)
-{
- int i;
-
- for (i = 0; i < drv.NrOfSubDevices; i++) {
-
- if(sub_dev[i].ReadyToRevive)
- {
- m_ptr->m_type = DEV_REVIVE; /* build message */
- m_ptr->REP_ENDPT = sub_dev[i].ReviveProcNr;
- m_ptr->REP_IO_GRANT = sub_dev[i].ReviveGrant;
- m_ptr->REP_STATUS = sub_dev[i].ReviveStatus;
- send(m_ptr->m_source, m_ptr); /* send the message */
-
- /* reset variables */
- sub_dev[i].ReadyToRevive = FALSE;
- sub_dev[i].RevivePending = 0;
-
- is_status_msg_expected = TRUE;
- return; /* stop after one mess,
- file system will get back for other processes */
- }
- }
- m_ptr->m_type = DEV_NO_STATUS;
- m_ptr->REP_STATUS = 0;
- send(m_ptr->m_source, m_ptr); /* send DEV_NO_STATUS message */
- is_status_msg_expected = FALSE;
-}
-
/* handle interrupt for specified sub device; DmaMode == DEV_WRITE_S*/
static void handle_int_write(int sub_dev_nr)
{
static void handle_int_read(int sub_dev_nr)
{
sub_dev_t *sub_dev_ptr;
+ message m;
sub_dev_ptr = &sub_dev[sub_dev_nr];
printf("All buffers full, we have a problem.\n");
drv_stop(sub_dev_nr); /* stop the sub device */
sub_dev_ptr->DmaBusy = FALSE;
- sub_dev_ptr->ReviveStatus = 0; /* no data for user,
- this is a sad story */
- sub_dev_ptr->ReadyToRevive = TRUE; /* wake user up */
+ sub_dev_ptr->ReviveStatus = 0; /* no data for user,
+ * this is a sad story
+ */
+ m.m_type = DEV_REVIVE;
+ m.REP_ENDPT = sub_dev_ptr->ReviveProcNr;
+ m.REP_IO_GRANT = sub_dev_ptr->ReviveGrant;
+ m.REP_STATUS = sub_dev_ptr->ReviveStatus;
+ send(sub_dev_ptr->SourceProcNr, &m);
return;
}
else { /* dma full, still room in extra buf;
if (!subdev->RevivePending) return; /* no new data waiting to be copied */
- if (subdev->RevivePending &&
- subdev->ReadyToRevive) return; /* we already got this data */
-
if (subdev->DmaLength < subdev->NrOfDmaFragments) { /* room in dma buf */
r = sys_safecopyfrom(subdev->SourceProcNr,
}
subdev->ReviveStatus = subdev->FragSize;
- subdev->ReadyToRevive = TRUE;
m.m_type = DEV_REVIVE; /* build message */
m.REP_ENDPT = subdev->ReviveProcNr;
}
/* reset variables */
- subdev->ReadyToRevive = FALSE;
subdev->RevivePending = 0;
}
message m;
if (!sub_dev_ptr->RevivePending) return; /* nobody is wating for data */
- if (sub_dev_ptr->ReadyToRevive) return;/* we already filled user's buffer */
if (sub_dev_ptr->BufLength == 0 && sub_dev_ptr->DmaLength == 0) return;
/* no data for user */
}
sub_dev_ptr->ReviveStatus = sub_dev_ptr->FragSize;
- sub_dev_ptr->ReadyToRevive = TRUE;
/* drv_status will send REVIVE mess to FS*/
m.m_type = DEV_REVIVE; /* build message */
}
/* reset variables */
- sub_dev_ptr->ReadyToRevive = FALSE;
sub_dev_ptr->RevivePending = 0;
}
#include <minix/audio_fw.h>
-/* State management variables. */
-EXTERN int is_status_msg_expected;
/*
* - From audio_fw.h:
* EXTERN drv_t drv;
break;
case SEF_LU_STATE_PROTOCOL_FREE:
- is_ready = (!is_read_pending && !is_write_pending
- && !is_status_msg_expected);
+ is_ready = (!is_read_pending && !is_write_pending);
break;
/* Custom states. */
load_state_info();
sef_lu_dprint("audio: live update state = %d\n", state);
- sef_lu_dprint("audio: is_status_msg_expected = %d\n",
- is_status_msg_expected);
sef_lu_dprint("audio: is_read_pending = %d\n", is_read_pending);
sef_lu_dprint("audio: is_write_pending = %d\n", is_write_pending);
sef_lu_dprint("audio: SEF_LU_STATE_REQUEST_FREE(%d) reached = %d\n",
SEF_LU_STATE_REQUEST_FREE, (!is_read_pending && !is_write_pending));
sef_lu_dprint("audio: SEF_LU_STATE_PROTOCOL_FREE(%d) reached = %d\n",
- SEF_LU_STATE_PROTOCOL_FREE, (!is_read_pending && !is_write_pending
- && !is_status_msg_expected));
+ SEF_LU_STATE_PROTOCOL_FREE, (!is_read_pending && !is_write_pending));
sef_lu_dprint("audio: AUDIO_STATE_READ_REQUEST_FREE(%d) reached = %d\n",
AUDIO_STATE_READ_REQUEST_FREE, (!is_read_pending));
sef_lu_dprint("audio: AUDIO_STATE_WRITE_REQUEST_FREE(%d) reached = %d\n",
break;
}
- m.TTY_LINE = fd;
- m.TTY_REQUEST = request;
- m.ADDRESS = (char *) addr;
+ m.VFS_IOCTL_FD = fd;
+ m.VFS_IOCTL_REQ = request;
+ m.VFS_IOCTL_ARG = (char *) addr;
r = _syscall(VFS_PROC_NR, IOCTL, &m);
* driver_receive: message receive interface for drivers
*
* Changes:
+ * Oct 20, 2013 retire synchronous protocol (D.C. van Moolenbroek)
* Oct 16, 2011 split character and block protocol (D.C. van Moolenbroek)
* Aug 27, 2011 move common functions into driver.c (A. Welzel)
* Jul 25, 2005 added SYS_SIG type for signals (Jorrit N. Herder)
}
/*===========================================================================*
- * async_reply *
+ * send_reply *
*===========================================================================*/
-static void async_reply(message *mess, int r)
+static void send_reply(message *mess, int ipc_status, int r)
{
-/* Send a reply using the asynchronous character device protocol. */
+/* Prepare and send a reply message. */
message reply_mess;
- /* Do not reply with ERESTART in this protocol. The only possible caller,
- * VFS, will find out through other means when we have restarted, and is not
- * (fully) ready to deal with ERESTART errors.
+ if (r == EDONTREPLY)
+ return;
+
+ /* Do not reply with ERESTART. The only possible caller, VFS, will find out
+ * through other means when we have restarted, and is not (fully) ready to
+ * deal with ERESTART errors.
*/
if (r == ERESTART)
return;
case DEV_WRITE_S:
case DEV_IOCTL_S:
if (r == SUSPEND)
- printf("driver_task: reviving %d (%d) with SUSPEND\n",
+ printf("chardriver_task: reviving %d (%d) with SUSPEND\n",
mess->m_source, mess->USER_ENDPT);
reply_mess.m_type = DEV_REVIVE;
break;
default:
- reply_mess.m_type = TASK_REPLY;
+ reply_mess.m_type = DEV_REVIVE;
reply_mess.REP_ENDPT = mess->USER_ENDPT;
/* Status is # of bytes transferred or error code. */
reply_mess.REP_STATUS = r;
break;
}
- r = asynsend(mess->m_source, &reply_mess);
-
- if (r != OK)
- printf("asyn_reply: unable to asynsend reply to %d: %d\n",
- mess->m_source, r);
-}
-
-/*===========================================================================*
- * sync_reply *
- *===========================================================================*/
-static void sync_reply(message *m_ptr, int ipc_status, int reply)
-{
-/* Reply to a message sent to the driver. */
- endpoint_t caller_e, user_e;
- int r;
-
- caller_e = m_ptr->m_source;
- user_e = m_ptr->USER_ENDPT;
-
- m_ptr->m_type = TASK_REPLY;
- m_ptr->REP_ENDPT = user_e;
- m_ptr->REP_STATUS = reply;
-
/* If we would block sending the message, send it asynchronously. */
if (IPC_STATUS_CALL(ipc_status) == SENDREC)
- r = sendnb(caller_e, m_ptr);
+ r = sendnb(mess->m_source, &reply_mess);
else
- r = asynsend(caller_e, m_ptr);
+ r = asynsend3(mess->m_source, &reply_mess, AMF_NOREPLY);
if (r != OK)
- printf("driver_reply: unable to send reply to %d: %d\n", caller_e, r);
-}
-
-/*===========================================================================*
- * send_reply *
- *===========================================================================*/
-static void send_reply(int type, message *m_ptr, int ipc_status, int reply)
-{
-/* Prepare and send a reply message. */
-
- if (reply == EDONTREPLY)
- return;
-
- if (type == CHARDRIVER_ASYNC)
- async_reply(m_ptr, reply);
- else
- sync_reply(m_ptr, ipc_status, reply);
+ printf("send_reply: unable to send reply to %d: %d\n",
+ mess->m_source, r);
}
/*===========================================================================*
* requests on devices that have not previously been opened, signaling the
* caller that something went wrong.
*/
- if (IS_CDEV_MINOR_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->DEVICE)) {
+ if (IS_DEV_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->DEVICE)) {
/* Reply ERESTART to spurious requests for unopened devices. */
if (m_ptr->m_type != DEV_OPEN)
return ERESTART;
/*===========================================================================*
* chardriver_process *
*===========================================================================*/
-void chardriver_process(struct chardriver *cdp, int driver_type,
- message *m_ptr, int ipc_status)
+void chardriver_process(struct chardriver *cdp, message *m_ptr, int ipc_status)
{
/* Handle the given received message. */
int r;
} else {
r = handle_request(cdp, m_ptr);
- send_reply(driver_type, m_ptr, ipc_status, r);
+ send_reply(m_ptr, ipc_status, r);
}
}
/*===========================================================================*
* chardriver_task *
*===========================================================================*/
-void chardriver_task(struct chardriver *cdp, int driver_type)
+void chardriver_task(struct chardriver *cdp)
{
/* Main program of any device driver task. */
int r, ipc_status;
if ((r = sef_receive_status(ANY, &mess, &ipc_status)) != OK)
panic("driver_receive failed: %d", r);
- chardriver_process(cdp, driver_type, &mess, ipc_status);
+ chardriver_process(cdp, &mess, ipc_status);
}
}
full = ddekit_sem_down_try(mq->msg_w_sem);
if (full) {
- /* Our message queue is full... inform the sender. */
+ /* Our message queue is full... */
int result;
- DDEBUG_MSG_WARN("Receive queue is full. Ommiting ingoing msg.\n");
-
- m->m_type = TASK_REPLY;
- m->REP_STATUS = EAGAIN;
- result = asynsend(m->m_source, m);
-
- if (result != 0) {
- ddekit_panic("unable to send reply to %d: %d\n",
- m->m_source, result);
- }
+ DDEBUG_MSG_WARN("Receive queue is full. Dropping request.\n");
+ /* XXX should reply to the sender with EIO or so, but for that
+ * we would need to look at the request and find a suitable
+ * reply code..
+ */
} else {
/* queue the message */
memcpy(&mq->messages[mq->msg_w_pos], m, sizeof(message));
sys_vsafecopy.c \
sys_vtimer.c \
sys_vumap.c \
- send_taskreply.c \
taskcall.c \
tickdelay.c \
timers.c \
+++ /dev/null
-
-#include <string.h>
-
-#include "syslib.h"
-
-/*===========================================================================*
- * sys_taskreply *
- *===========================================================================*/
-int send_taskreply(endpoint_t who, endpoint_t endpoint, int status)
-{
- message m;
-
- memset(&m, 0, sizeof(m));
-
- m.REP_ENDPT = endpoint;
- m.REP_STATUS = status;
-
- return _sendcall(who, TASK_REPLY, &m);
-}
-
* | DEV_SELECT | minor dev | ops | | |
* |-------------+-----------+-----------+-----------+-----------|
*
- * m_type
- * --------------|
- * | DEV_STATUS |
- * |-------------|
- *
* m_type DEVICE USER_ENDPT COUNT
* --------------------------------------------------|
* | CANCEL | minor dev | proc nr | mode |
* |-------------+-----------+-----------+-----------|
- *
- * Replies:
- *
- * m_type REP_ENDPT REP_STATUS REP_IO_GRANT
- * -------------------------------------------------------|
- * | TASK_REPLY | proc nr | status | grant ID |
- * |---------------+-----------+-----------+--------------|
- *
- * m_type REP_ENDPT REP_STATUS REP_IO_GRANT
- * ----------------+-----------+--------------------------|
- * | DEV_REVIVE | proc nr | | grant ID |
- * |---------------+-----------+-----------+--------------|
- * | DEV_IO_READY | minor dev | sel ops | |
- * |---------------+-----------+-----------+--------------|
- * | DEV_NO_STATUS | | | |
- * |---------------+-----------+-----------+--------------|
*/
#include "inet.h"
sr_fd_t sr_fd_table[FD_NR];
-static mq_t *repl_queue, *repl_queue_tail;
static struct vscp_vec s_cp_req[SCPVEC_NR];
static int sr_open(message *m);
static int sr_restart_write(sr_fd_t *fdp);
static int sr_restart_ioctl(sr_fd_t *fdp);
static int sr_cancel(message *m);
-static int sr_select(message *m);
-static void sr_status(message *m);
-static void sr_reply_(mq_t *m, int reply, int is_revive);
+static void sr_select(message *m);
+static void sr_reply_(mq_t *m, int code, int reply, int is_revive);
static sr_fd_t *sr_getchannel(int minor);
static acc_t *sr_get_userdata(int fd, size_t offset, size_t count, int
for_ioctl);
static int sr_put_userdata(int fd, size_t offset, acc_t *data, int
for_ioctl);
static void sr_select_res(int fd, unsigned ops);
-static int sr_repl_queue(int proc, int ref, int operation);
static int walk_queue(sr_fd_t *sr_fd, mq_t **q_head_ptr, mq_t
**q_tail_ptr, int type, int proc_nr, int ref, int first_flag);
static void sr_event(event_t *evp, ev_arg_t arg);
ev_init(&sr_fd_table[i].srf_read_ev);
ev_init(&sr_fd_table[i].srf_write_ev);
}
- repl_queue= NULL;
}
void sr_rec(m)
mq_t *m;
{
- int result;
+ int code = DEV_REVIVE, result;
int send_reply = 0, free_mess = 0;
- if (repl_queue)
- {
- if (m->mq_mess.m_type == CANCEL)
- {
- result= sr_repl_queue(m->mq_mess.USER_ENDPT,
- (int)m->mq_mess.IO_GRANT, 0);
-
- if (result)
- {
- mq_free(m);
- return; /* canceled request in queue */
- }
- }
-#if 0
- else
- sr_repl_queue(ANY, 0, 0);
-#endif
- }
-
switch (m->mq_mess.m_type)
{
case DEV_OPEN:
result= sr_open(&m->mq_mess);
+ code= DEV_OPEN_REPL;
send_reply= 1;
free_mess= 1;
break;
case DEV_CLOSE:
sr_close(&m->mq_mess);
result= OK;
+ code= DEV_CLOSE_REPL;
send_reply= 1;
free_mess= 1;
break;
result= sr_rwio(m);
assert(result == OK || result == EAGAIN || result == EINTR ||
result == SUSPEND);
- send_reply= (result == EAGAIN || result == SUSPEND);
+ send_reply= (result == EAGAIN);
free_mess= (result == EAGAIN);
break;
case CANCEL:
result= sr_cancel(&m->mq_mess);
- assert(result == OK || result == EINTR);
+ assert(result == OK || result == EINTR || result == SUSPEND);
send_reply= (result == EINTR);
free_mess= 1;
- m->mq_mess.m_type= 0;
break;
case DEV_SELECT:
- result= sr_select(&m->mq_mess);
- send_reply= 1;
- free_mess= 1;
- break;
- case DEV_STATUS:
- sr_status(&m->mq_mess);
- result= OK; /* Satisfy lint. */
+ sr_select(&m->mq_mess);
send_reply= 0;
free_mess= 1;
break;
}
if (send_reply)
{
- sr_reply_(m, result, FALSE /* !is_revive */);
+ sr_reply_(m, code, result, FALSE /* !is_revive */);
}
if (free_mess)
mq_free(m);
int result;
int proc_nr, ref;
- result=EINTR;
proc_nr= m->USER_ENDPT;
ref= (int)m->IO_GRANT;
sr_fd= sr_getchannel(m->DEVICE);
if (result != EAGAIN)
return result;
- ip_panic((
-"request not found: from %d, type %d, MINOR= %d, PROC= %d, REF= %d",
- m->m_source, m->m_type, m->DEVICE,
- m->USER_ENDPT, (int) m->IO_GRANT));
-
- return result;
+ /* We already replied to the request, so don't reply to the CANCEL. */
+ return SUSPEND;
}
-static int sr_select(m)
+static void sr_select(m)
message *m;
{
+ message m_reply;
sr_fd_t *sr_fd;
int r;
unsigned m_ops, i_ops;
- sr_fd= sr_getchannel(m->DEVICE);
+ sr_fd= sr_getchannel(m->DEV_MINOR);
assert (sr_fd);
sr_fd->srf_select_proc= m->m_source;
- m_ops= m->USER_ENDPT;
+ m_ops= m->DEV_SEL_OPS;
i_ops= 0;
if (m_ops & SEL_RD) i_ops |= SR_SELECT_READ;
if (m_ops & SEL_WR) i_ops |= SR_SELECT_WRITE;
if (!(m_ops & SEL_NOTIFY)) i_ops |= SR_SELECT_POLL;
r= (*sr_fd->srf_select)(sr_fd->srf_fd, i_ops);
- if (r < 0)
- return r;
- m_ops= 0;
- if (r & SR_SELECT_READ) m_ops |= SEL_RD;
- if (r & SR_SELECT_WRITE) m_ops |= SEL_WR;
- if (r & SR_SELECT_EXCEPTION) m_ops |= SEL_ERR;
-
- return m_ops;
-}
-
-static void sr_status(m)
-message *m;
-{
- int fd, result;
- unsigned m_ops;
- sr_fd_t *sr_fd;
- mq_t *mq;
-
- mq= repl_queue;
- if (mq != NULL)
- {
- repl_queue= mq->mq_next;
-
- mq->mq_mess.m_type= DEV_REVIVE;
- result= send(mq->mq_mess.m_source, &mq->mq_mess);
- if (result != OK)
- ip_panic(("unable to send"));
- mq_free(mq);
-
- return;
- }
-
- for (fd=0, sr_fd= sr_fd_table; fd<FD_NR; fd++, sr_fd++)
- {
- if ((sr_fd->srf_flags &
- (SFF_SELECT_R|SFF_SELECT_W|SFF_SELECT_X)) == 0)
- {
- /* Nothing to report */
- continue;
- }
- if (sr_fd->srf_select_proc != m->m_source)
- {
- /* Wrong process */
- continue;
- }
-
+ if (r < 0) {
+ m_ops= r;
+ } else {
m_ops= 0;
- if (sr_fd->srf_flags & SFF_SELECT_R) m_ops |= SEL_RD;
- if (sr_fd->srf_flags & SFF_SELECT_W) m_ops |= SEL_WR;
- if (sr_fd->srf_flags & SFF_SELECT_X) m_ops |= SEL_ERR;
-
- sr_fd->srf_flags &= ~(SFF_SELECT_R|SFF_SELECT_W|SFF_SELECT_X);
-
- m->m_type= DEV_IO_READY;
- m->DEV_MINOR= fd;
- m->DEV_SEL_OPS= m_ops;
-
- result= send(m->m_source, m);
- if (result != OK)
- ip_panic(("unable to send"));
- return;
+ if (r & SR_SELECT_READ) m_ops |= SEL_RD;
+ if (r & SR_SELECT_WRITE) m_ops |= SEL_WR;
+ if (r & SR_SELECT_EXCEPTION) m_ops |= SEL_ERR;
}
- m->m_type= DEV_NO_STATUS;
- result= send(m->m_source, m);
- if (result != OK)
+ memset(&m_reply, 0, sizeof(m_reply));
+ m_reply.m_type= DEV_SEL_REPL1;
+ m_reply.DEV_MINOR= m->DEV_MINOR;
+ m_reply.DEV_SEL_OPS= m_ops;
+
+ r= send(m->m_source, &m_reply);
+ if (r != OK)
ip_panic(("unable to send"));
}
return loc_fd;
}
-static void sr_reply_(mq, status, is_revive)
+static void sr_reply_(mq, code, status, is_revive)
mq_t *mq;
+int code;
int status;
int is_revive;
{
else
mp= &reply;
- mp->m_type= TASK_REPLY;
+ mp->m_type= code;
mp->REP_ENDPT= proc;
mp->REP_STATUS= status;
mp->REP_IO_GRANT= ref;
- if (is_revive)
- {
- notify(mq->mq_mess.m_source);
- result= ELOCKED;
- }
- else
- {
- result= send(mq->mq_mess.m_source, mp);
- }
+ result= send(mq->mq_mess.m_source, mp);
- if (result == ELOCKED && is_revive)
- {
- mq->mq_next= NULL;
- if (repl_queue)
- repl_queue_tail->mq_next= mq;
- else
- repl_queue= mq;
- repl_queue_tail= mq;
- return;
- }
if (result != OK)
ip_panic(("unable to send"));
if (is_revive)
*head_ptr= mq;
result= (int)offset;
is_revive= !(loc_fd->srf_flags & first_flag);
- sr_reply_(m, result, is_revive);
+ sr_reply_(m, DEV_REVIVE, result, is_revive);
suspended= (loc_fd->srf_flags & susp_flag);
loc_fd->srf_flags &= ~(ip_flag|susp_flag);
if (suspended)
*head_ptr= mq;
result= (int)offset;
is_revive= !(loc_fd->srf_flags & first_flag);
- sr_reply_(m, result, is_revive);
+ sr_reply_(m, DEV_REVIVE, result, is_revive);
suspended= (loc_fd->srf_flags & susp_flag);
loc_fd->srf_flags &= ~(ip_flag|susp_flag);
if (suspended)
static void sr_select_res(int fd, unsigned ops)
{
+ message m;
sr_fd_t *sr_fd;
+ unsigned int m_ops;
+ int result;
sr_fd= &sr_fd_table[fd];
-
- if (ops & SR_SELECT_READ) sr_fd->srf_flags |= SFF_SELECT_R;
- if (ops & SR_SELECT_WRITE) sr_fd->srf_flags |= SFF_SELECT_W;
- if (ops & SR_SELECT_EXCEPTION) sr_fd->srf_flags |= SFF_SELECT_X;
- notify(sr_fd->srf_select_proc);
+ m_ops= 0;
+ if (ops & SR_SELECT_READ) m_ops |= SEL_RD;
+ if (ops & SR_SELECT_WRITE) m_ops |= SEL_WR;
+ if (ops & SR_SELECT_EXCEPTION) m_ops |= SEL_ERR;
+
+ memset(&m, 0, sizeof(m));
+ m.m_type= DEV_SEL_REPL2;
+ m.DEV_MINOR= fd;
+ m.DEV_SEL_OPS= m_ops;
+
+ result= send(sr_fd->srf_select_proc, &m);
+ if (result != OK)
+ ip_panic(("unable to send"));
}
static void sr_event(evp, arg)
return OK;
}
-static int sr_repl_queue(proc, ref, operation)
-int proc;
-int ref;
-int operation;
-{
- mq_t *m, *m_cancel, *m_tmp;
- mq_t *new_queue;
- int result;
-
- m_cancel= NULL;
- new_queue= NULL;
-
- for (m= repl_queue; m;)
- {
- if (m->mq_mess.REP_ENDPT == proc &&
- m->mq_mess.REP_IO_GRANT == ref)
- {
- assert(!m_cancel);
- m_cancel= m;
- m= m->mq_next;
- continue;
- }
- m_tmp= m;
- m= m->mq_next;
- m_tmp->mq_next= new_queue;
- new_queue= m_tmp;
- }
- repl_queue= new_queue;
- if (m_cancel)
- {
- result= send(m_cancel->mq_mess.m_source, &m_cancel->mq_mess);
- if (result != OK)
- ip_panic(("unable to send: %d", result));
- mq_free(m_cancel);
- return 1;
- }
- return 0;
-}
-
/*
* $PchId: sr.c,v 1.17 2005/06/28 14:26:16 philip Exp $
*/
#define SFF_IOCTL_FIRST 0x200
#define SFF_READ_FIRST 0x400
#define SFF_WRITE_FIRST 0x800
-#define SFF_SELECT_R 0x1000
-#define SFF_SELECT_W 0x2000
-#define SFF_SELECT_X 0x4000
EXTERN sr_fd_t sr_fd_table[FD_NR];
{
switch(dev_style) {
case STYLE_DEV: return "STYLE_DEV";
- case STYLE_DEVA: return "STYLE_DEVA";
case STYLE_TTY: return "STYLE_TTY";
case STYLE_CTTY: return "STYLE_CTTY";
case STYLE_CLONE: return "STYLE_CLONE";
- case STYLE_CLONE_A: return "STYLE_CLONE_A";
default: return "UNKNOWN";
}
}
minor = uds_minor(dev_m_in);
if (uds_fd_table[minor].state != UDS_INUSE) {
-
- /* attempted to close a socket that hasn't been opened --
- * something is very wrong :(
- */
- uds_set_reply(dev_m_out, DEV_NO_STATUS, dev_m_in->USER_ENDPT,
- (cp_grant_id_t) dev_m_in->IO_GRANT, EINVAL);
-
- return EINVAL;
+ /* attempted to cancel an unknown request - this happens */
+ return SUSPEND;
}
/* Update the process endpoint. */
uds_fd_table[minor].syscall_done = 1;
}
-
- uds_set_reply(dev_m_out, DEV_NO_STATUS, dev_m_in->USER_ENDPT,
+ uds_set_reply(dev_m_out, DEV_REVIVE, dev_m_in->USER_ENDPT,
(cp_grant_id_t) dev_m_in->IO_GRANT, EINTR);
return EINTR;
uds_close, /* 7 DEV_CLOSE */
no_sys, /* 8 */
no_sys, /* 9 */
- no_sys, /* 10 TTY_SETPGRP */
- no_sys, /* 11 TTY_EXIT */
+ no_sys, /* 10 */
+ no_sys, /* 11 */
uds_select, /* 12 DEV_SELECT */
- no_sys, /* 13 DEV_STATUS */
+ no_sys, /* 13 */
uds_open, /* 14 DEV_REOPEN */
no_sys, /* 15 */
no_sys, /* 16 */
/*endpoint, flags, dev_nr, dev_style, dev_style2 */
{ TTY_PROC_NR, SRV_DF, TTY_MAJOR, STYLE_TTY, STYLE_CTTY },
{ MEM_PROC_NR, SRV_DF, MEMORY_MAJOR, STYLE_DEV, STYLE_NDEV },
- { LOG_PROC_NR, SRV_DF, LOG_MAJOR, STYLE_DEVA, STYLE_NDEV },
- { PFS_PROC_NR, SRV_DF, UDS_MAJOR, STYLE_CLONE_A,STYLE_NDEV },
+ { LOG_PROC_NR, SRV_DF, LOG_MAJOR, STYLE_DEV, STYLE_NDEV },
+ { PFS_PROC_NR, SRV_DF, UDS_MAJOR, STYLE_CLONE,STYLE_NDEV },
{ DEFAULT_BOOT_NR, SRV_DF, 0, STYLE_NDEV, STYLE_NDEV } /* default
* entry
*/
#define fp_is_blocked(fp) ((fp)->fp_blocked_on != FP_BLOCKED_ON_NONE)
/* test if reply is a driver reply */
-#define IS_DRV_REPLY(x) (IS_DEV_RS(x) || IS_BDEV_RS(x) || (x) == TASK_REPLY)
+#define IS_DRV_REPLY(x) (IS_DEV_RS(x) || IS_BDEV_RS(x))
#define DUP_MASK 0100 /* mask to distinguish dup2 from dup */
#define LOOK_UP 0 /* tells search_dir to lookup string */
#define VFS_DEV_IOCTL 2005
#define VFS_DEV_SELECT 2006
+#define dev_style_asyn(n) (TRUE)
+
#endif
* bdev_open: open a block device
* bdev_close: close a block device
* dev_io: FS does a read or write on a device
- * dev_status: FS processes callback request alert
* gen_opcl: generic call to a task to perform an open/close
* gen_io: generic call to a task to perform an I/O operation
* no_dev: open/close processing for devices that don't exist
/* Determine task dmap. */
dp = &dmap[major_dev];
if (dp->dmap_driver == NONE) {
- printf("VFS: dev_io: no driver for major %d\n", major_dev);
+ printf("VFS: bdev_ioctl: no driver for major %d\n", major_dev);
return(ENXIO);
}
dev_mess.BDEV_ID = 0;
/* Call the task. */
- (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
+ gen_io(dp->dmap_driver, &dev_mess);
/* Clean up. */
if (GRANT_VALID(gid)) cpf_revoke(gid);
}
-/*===========================================================================*
- * dev_status *
- *===========================================================================*/
-void dev_status(endpoint_t drv_e)
-{
-/* A device sent us a notification it has something for us. Retrieve it. */
-
- message st;
- int major, get_more = 1;
- endpoint_t endpt;
-
- for (major = 0; major < NR_DEVICES; major++)
- if (dmap_driver_match(drv_e, major))
- break; /* 'major' is the device that sent the message */
-
- if (major >= NR_DEVICES) /* Device endpoint not found; nothing to do */
- return;
-
- if (dev_style_asyn(dmap[major].dmap_style)) {
- printf("VFS: not doing dev_status for async driver %d\n", drv_e);
- return;
- }
-
- /* Continuously send DEV_STATUS messages until the device has nothing to
- * say to us anymore. */
- do {
- int r;
- st.m_type = DEV_STATUS;
- r = drv_sendrec(drv_e, &st);
- if (r == OK && st.REP_STATUS == ERESTART) r = EDEADEPT;
- if (r != OK) {
- printf("VFS: DEV_STATUS failed to %d: %d\n", drv_e, r);
- if (r == EDEADSRCDST || r == EDEADEPT) return;
- panic("VFS: couldn't sendrec for DEV_STATUS: %d", r);
- }
-
- switch(st.m_type) {
- case DEV_REVIVE:
- /* We've got results for a read/write/ioctl call to a
- * synchronous character driver */
- endpt = st.REP_ENDPT;
- if (endpt == VFS_PROC_NR) {
- endpt = find_suspended_ep(drv_e, st.REP_IO_GRANT);
- if (endpt == NONE) {
- printf("VFS: proc with grant %d from %d not found\n",
- st.REP_IO_GRANT, st.m_source);
- continue;
- }
- }
- revive(endpt, st.REP_STATUS);
- break;
- case DEV_IO_READY:
- /* Reply to a select request: driver is ready for I/O */
- select_reply2(st.m_source, st.DEV_MINOR, st.DEV_SEL_OPS);
- break;
- default:
- printf("VFS: unrecognized reply %d to DEV_STATUS\n",st.m_type);
- /* Fall through. */
- case DEV_NO_STATUS:
- get_more = 0;
- break;
- }
- } while(get_more);
-}
-
/*===========================================================================*
* safe_io_conversion *
*===========================================================================*/
dev_mess.BDEV_MINOR = minor_dev;
dev_mess.BDEV_ACCESS = flags;
dev_mess.BDEV_ID = 0;
+
+ /* Call the task. */
+ r = gen_io(dp->dmap_driver, &dev_mess);
} else {
dev_mess.m_type = op;
dev_mess.DEVICE = minor_dev;
dev_mess.USER_ENDPT = proc_e;
dev_mess.COUNT = flags;
+
+ /* Call the task. */
+ r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
}
- /* Call the task. */
- r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
if (r != OK) return(r);
- if (op == DEV_OPEN && dp->dmap_style == STYLE_DEVA) {
+ if (op == DEV_OPEN && dev_style_asyn(dp->dmap_style)) {
fp->fp_task = dp->dmap_driver;
self->w_task = dp->dmap_driver;
self->w_drv_sendrec = &dev_mess;
dev_t dev;
void *argx;
- scratch(fp).file.fd_nr = job_m_in.ls_fd;
- ioctlrequest = job_m_in.REQUEST;
- argx = job_m_in.ADDRESS;
+ scratch(fp).file.fd_nr = job_m_in.VFS_IOCTL_FD;
+ ioctlrequest = job_m_in.VFS_IOCTL_REQ;
+ argx = job_m_in.VFS_IOCTL_ARG;
if ((f = get_filp(scratch(fp).file.fd_nr, VNODE_READ)) == NULL)
return(err_code);
/* Store driver I/O routines based on type of device */
switch (style) {
case STYLE_DEV:
- dp->dmap_opcl = gen_opcl;
- dp->dmap_io = gen_io;
- break;
- case STYLE_DEVA:
dp->dmap_opcl = gen_opcl;
dp->dmap_io = asyn_io;
break;
case STYLE_TTY:
dp->dmap_opcl = tty_opcl;
- dp->dmap_io = gen_io;
+ dp->dmap_io = asyn_io;
break;
case STYLE_CTTY:
dp->dmap_opcl = ctty_opcl;
dp->dmap_io = ctty_io;
break;
case STYLE_CLONE:
- dp->dmap_opcl = clone_opcl;
- dp->dmap_io = gen_io;
- break;
- case STYLE_CLONE_A:
dp->dmap_opcl = clone_opcl;
dp->dmap_io = asyn_io;
break;
/* Thread related prototypes */
static void *do_async_dev_result(void *arg);
static void *do_control_msgs(void *arg);
-static void *do_dev_event(void *arg);
static void *do_fs_reply(struct job *job);
static void *do_work(void *arg);
static void *do_pm(void *arg);
handle_work(ds_event);
else if (who_e == KERNEL)
mthread_stacktraces();
- else if (fp != NULL && (fp->fp_flags & FP_SRV_PROC))
- handle_work(do_dev_event);
else
sys_worker_start(do_control_msgs);
continue;
dp = get_dmap(who_e);
if (dp != NULL) {
- if (dev_style_asyn(dp->dmap_style)) {
+ if (!IS_BDEV_RS(call_nr) &&
+ dev_style_asyn(dp->dmap_style)) {
handle_work(do_async_dev_result);
} else {
return(NULL);
}
-/*===========================================================================*
- * do_dev_event *
- *===========================================================================*/
-static void *do_dev_event(void *arg)
-{
-/* Device notifies us of an event. */
- struct job my_job;
-
- my_job = *((struct job *) arg);
- fp = my_job.j_fp;
-
- dev_status(job_m_in.m_source);
-
- thread_cleanup(fp);
- return(NULL);
-}
-
/*===========================================================================*
* do_fs_reply *
*===========================================================================*/
dev = (dev_t) f->filp_vno->v_sdev; /* device hung on */
major_dev = major(dev);
minor_dev = minor(dev);
- mess.TTY_LINE = minor_dev;
+ mess.DEVICE = minor_dev;
mess.USER_ENDPT = rfp->fp_ioproc;
mess.IO_GRANT = (char *) rfp->fp_grant;
int ctty_io(endpoint_t task_nr, message *mess_ptr);
int do_ioctl(message *m_out);
void pm_setsid(endpoint_t proc_e);
-void dev_status(endpoint_t drv_e);
void bdev_up(int major);
void cdev_up(int major);
endpoint_t find_suspended_ep(endpoint_t driver, cp_grant_id_t g);
major = major(f->filp_vno->v_sdev);
if (major < 0 || major >= NR_DEVICES) return(ENXIO);
- if (dmap[major].dmap_style == STYLE_DEVA ||
- dmap[major].dmap_style == STYLE_CLONE_A)
+ if (dev_style_asyn(dmap[major].dmap_style))
r = select_request_async(f, ops, block);
else
r = select_request_sync(f, ops, block);