Retire the synchronous character driver protocol

- change all sync char drivers into async drivers;
- retire support for the sync protocol in libchardev;
- remove async dev style, as this is now the default;
- remove dev_status from VFS;
- clean up now-unused protocol messages.

Change-Id: I6aacff712292f6b29f2ccd51bc1e7d7003723e87
This commit is contained in:
David van Moolenbroek 2013-08-30 11:14:03 +02:00 committed by Lionel Sambuc
parent 97172a1db0
commit 6331e8f845
48 changed files with 475 additions and 1105 deletions

View file

@ -334,10 +334,10 @@ static int parse_arguments(int argc, char **argv, u32_t *rss_flags)
}
}
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;

View file

@ -624,7 +624,7 @@ main(int argc, char *argv[])
sef_local_startup();
chardriver_task(&bmp085_tab, CHARDRIVER_SYNC);
chardriver_task(&bmp085_tab);
return 0;
}

View file

@ -382,7 +382,7 @@ main(int argc, char *argv[])
fb_edid_args_parse();
sef_local_startup();
chardriver_task(&fb_tab, CHARDRIVER_SYNC);
chardriver_task(&fb_tab);
return OK;
}

View file

@ -181,7 +181,7 @@ int main(void)
/*
* Run the main loop.
*/
chardriver_task(&hello_tab, CHARDRIVER_SYNC);
chardriver_task(&hello_tab);
return OK;
}

View file

@ -553,7 +553,7 @@ main(int argc, char *argv[])
memset(i2cdev, '\0', sizeof(i2cdev));
sef_local_startup();
chardriver_task(&i2c_tab, CHARDRIVER_SYNC);
chardriver_task(&i2c_tab);
return OK;
}

View file

@ -29,7 +29,6 @@ static int log_transfer(endpoint_t endpt, int opcode, u64_t position,
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);
@ -44,7 +43,7 @@ static struct chardriver log_dtab = {
nop_alarm, /* no alarm */
log_cancel, /* CANCEL request */
log_select, /* DEV_SELECT request */
log_other /* Unrecognized messages */
NULL /* Unrecognized messages */
};
/* SEF functions and variables. */
@ -64,7 +63,7 @@ int main(void)
sef_local_startup();
/* Call the generic receive loop. */
chardriver_task(&log_dtab, CHARDRIVER_ASYNC);
chardriver_task(&log_dtab);
return(OK);
}
@ -370,48 +369,25 @@ static int log_do_open(message *m_ptr)
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);
@ -419,10 +395,10 @@ static int log_select(message *m_ptr)
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
@ -430,13 +406,13 @@ static int log_select(message *m_ptr)
}
/* 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

View file

@ -117,8 +117,7 @@ int main(void)
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);

View file

@ -2,7 +2,6 @@
/* 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)
@ -24,7 +23,7 @@ int sef_cb_lu_prepare(int state)
break;
case SEF_LU_STATE_PROTOCOL_FREE:
is_ready = (!writing && !is_status_msg_expected);
is_ready = (!writing);
break;
/* Custom states. */
@ -52,15 +51,13 @@ void sef_cb_lu_state_dump(int state)
{
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));
}

View file

@ -14,15 +14,13 @@
* 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 |
* |-------------+---------+---------+---------+---------|
@ -87,8 +85,6 @@
*/
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 */
@ -105,11 +101,11 @@ static int irq_hook_id; /* id of irq hook at kernel */
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. */
@ -118,7 +114,6 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info);
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 *
@ -142,26 +137,25 @@ int main(void)
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);
}
}
}
@ -213,7 +207,7 @@ register message *m_ptr; /* pointer to the newly arrived message */
{
/* 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;
@ -224,13 +218,10 @@ register message *m_ptr; /* pointer to the newly arrived message */
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;
@ -255,6 +246,9 @@ register message *m_ptr; /* pointer to the newly arrived message */
/* 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);
}
}
@ -267,6 +261,7 @@ static void output_done()
* Otherwise, reply to caller (FS).
*/
register int status;
message m;
if (!writing) return; /* probably leftover interrupt */
if (done_status != OK) { /* printer error occurred */
@ -292,32 +287,15 @@ static void output_done()
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;
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 */
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 */
writing = FALSE; /* unmark event */
}
/*===========================================================================*
@ -332,30 +310,32 @@ register message *m_ptr; /* pointer to the newly arrived message */
* 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 */
}

View file

@ -59,7 +59,7 @@ int main(void)
sef_local_startup();
/* Call the generic receive loop. */
chardriver_task(&r_dtab, CHARDRIVER_ASYNC);
chardriver_task(&r_dtab);
return(OK);
}

View file

@ -527,7 +527,7 @@ main(int argc, char *argv[])
sef_local_startup();
chardriver_task(&sht21_tab, CHARDRIVER_SYNC);
chardriver_task(&sht21_tab);
return 0;
}

View file

@ -356,7 +356,6 @@ int
main(int argc, char *argv[])
{
int r;
endpoint_t user, caller;
message m;
int ipc_status;
@ -407,26 +406,8 @@ main(int argc, char *argv[])
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;

View file

@ -476,7 +476,7 @@ main(int argc, char *argv[])
sef_local_startup();
chardriver_task(&tsl2550_tab, CHARDRIVER_SYNC);
chardriver_task(&tsl2550_tab);
return 0;
}

View file

@ -33,12 +33,6 @@ kb_init_once(void)
{
}
int
kbd_status(message *m)
{
return 0;
}
int
kbd_loadmap(message *m)
{

View file

@ -266,27 +266,20 @@ rs_write(register tty_t *tp, int try)
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;

View file

@ -215,14 +215,10 @@ int try;
/* 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;
@ -825,14 +821,16 @@ void do_video(message *m)
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;
@ -847,9 +845,7 @@ void do_video(message *m)
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
@ -870,11 +866,12 @@ void do_video(message *m)
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:
@ -883,7 +880,8 @@ void do_video(message *m)
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);
}

View file

@ -19,6 +19,7 @@
#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"
@ -134,6 +135,7 @@ static struct kbd
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
@ -154,7 +156,6 @@ static long debug_fkeys = 1;
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);
@ -186,20 +187,6 @@ void do_kbd(message *m)
}
/*===========================================================================*
* 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 *
*===========================================================================*/
@ -224,8 +211,9 @@ message *m;
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)
@ -235,8 +223,9 @@ message *m;
}
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)
{
@ -256,8 +245,7 @@ message *m;
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 */
@ -306,11 +294,11 @@ message *m;
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))
@ -323,10 +311,13 @@ message *m;
{
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;
@ -362,7 +353,7 @@ message *m;
r= OK;
break;
}
if (kbdp == &kbd && m->TTY_REQUEST == KIOCBELL)
if (kbdp == &kbd && m->REQUEST == KIOCBELL)
{
kio_bell_t bell;
clock_t ticks;
@ -390,59 +381,8 @@ message *m;
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);
}
@ -490,7 +430,7 @@ int scode;
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;
@ -516,15 +456,40 @@ void kbd_interrupt(message *UNUSED(m_ptr))
#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. */

View file

@ -269,26 +269,18 @@ static int rs_write(register tty_t *tp, int try)
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;

View file

@ -33,7 +33,6 @@ typedef struct pty {
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 */
@ -42,7 +41,6 @@ typedef struct pty {
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 */
@ -56,9 +54,9 @@ typedef struct pty {
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 */
@ -75,7 +73,7 @@ static int pty_read(tty_t *tp, int try);
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 *
@ -105,7 +103,6 @@ void do_pty(tty_t *tp, message *m_ptr)
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;
@ -123,8 +120,7 @@ void do_pty(tty_t *tp, message *m_ptr)
pp->rdleft = pp->rdcum = 0;
pp->rdgrant = GRANT_INVALID;
} else {
r = SUSPEND; /* do suspend */
pp->rdsendreply = FALSE;
return; /* do suspend */
}
break;
@ -146,7 +142,6 @@ void do_pty(tty_t *tp, message *m_ptr)
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;
@ -164,8 +159,7 @@ void do_pty(tty_t *tp, message *m_ptr)
pp->wrgrant = GRANT_INVALID;
r = EAGAIN;
} else {
pp->wrsendreply = FALSE; /* do suspend */
r = SUSPEND;
return; /* do suspend */
}
break;
@ -174,21 +168,24 @@ void do_pty(tty_t *tp, message *m_ptr)
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;
@ -209,7 +206,8 @@ void do_pty(tty_t *tp, message *m_ptr)
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);
}
/*===========================================================================*
@ -228,14 +226,10 @@ static int pty_write(tty_t *tp, int try)
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;
}
@ -281,14 +275,10 @@ static int pty_write(tty_t *tp, int try)
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);
@ -358,12 +348,10 @@ static void pty_finish(pty_t *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;
}
}
@ -382,14 +370,10 @@ static int pty_read(tty_t *tp, int try)
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;
}
@ -417,13 +401,10 @@ static int pty_read(tty_t *tp, int try)
/* 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;
}
}
@ -441,13 +422,17 @@ static int pty_close(tty_t *tp, int UNUSED(try))
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;
@ -464,9 +449,10 @@ static int pty_icancel(tty_t *tp, int UNUSED(try))
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;
@ -515,60 +501,6 @@ void pty_init(tty_t *tp)
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 *
*===========================================================================*/
@ -600,35 +532,38 @@ static int select_try_pty(tty_t *tp, int ops)
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 */

View file

@ -27,28 +27,25 @@
* 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:
@ -111,7 +108,6 @@ static void do_close(tty_t *tp, message *m_ptr);
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);
@ -164,7 +160,7 @@ int main(void)
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. */
@ -231,21 +227,16 @@ int main(void)
; /* 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) {
@ -274,10 +265,20 @@ int main(void)
/* 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;
}
@ -293,8 +294,8 @@ int main(void)
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);
}
}
@ -537,97 +538,6 @@ static void sef_cb_signal_handler(int signo)
}
}
/*===========================================================================*
* 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 *
*===========================================================================*/
@ -654,7 +564,6 @@ register message *m_ptr; /* pointer to message sent to the task */
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;
@ -692,14 +601,14 @@ register message *m_ptr; /* pointer to message sent to the task */
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);
}
@ -724,7 +633,6 @@ register message *m_ptr; /* pointer to message sent to the task */
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;
@ -739,14 +647,14 @@ register message *m_ptr; /* pointer to message sent to the task */
/* 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);
}
/*===========================================================================*
@ -767,7 +675,7 @@ message *m_ptr; /* pointer to message sent to task */
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 */
@ -801,7 +709,7 @@ message *m_ptr; /* pointer to message sent to task */
}
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,
@ -820,12 +728,12 @@ message *m_ptr; /* pointer to message sent to task */
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. */
@ -906,7 +814,8 @@ message *m_ptr; /* pointer to message sent to task */
}
/* 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);
}
/*===========================================================================*
@ -922,7 +831,7 @@ message *m_ptr; /* pointer to message sent to task */
*/
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 {
@ -936,7 +845,8 @@ message *m_ptr; /* pointer to message sent to task */
(*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);
}
/*===========================================================================*
@ -948,7 +858,7 @@ message *m_ptr; /* pointer to message sent to task */
{
/* 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);
@ -957,7 +867,8 @@ message *m_ptr; /* pointer to message sent to task */
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);
}
/*===========================================================================*
@ -970,35 +881,39 @@ message *m_ptr; /* pointer to message sent to task */
/* 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)
@ -1037,8 +952,14 @@ 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;
}
@ -1080,16 +1001,10 @@ tty_t *tp; /* TTY to check for events. */
/* 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)
{
@ -1162,16 +1077,10 @@ register tty_t *tp; /* pointer to terminal to read from */
/* 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;
}
}
@ -1601,9 +1510,9 @@ tty_t *tp;
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;
}
/*===========================================================================*
@ -1667,25 +1576,52 @@ tty_t *tp;
*===========================================================================*/
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 *
*===========================================================================*/
@ -1824,18 +1760,17 @@ register message *m_ptr; /* pointer to message sent to the task */
{
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);
}

View file

@ -5,8 +5,6 @@
#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
@ -63,16 +61,12 @@ typedef struct tty {
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 */
@ -80,15 +74,14 @@ typedef struct tty {
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 */
@ -146,9 +139,10 @@ int in_process(struct tty *tp, char *buf, int count, int scode);
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);
@ -175,11 +169,8 @@ void kbd_interrupt(message *m);
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);

View file

@ -65,7 +65,7 @@ kill_by_name syslogd
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

View file

@ -167,7 +167,7 @@ start)
# 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 ]
@ -188,9 +188,9 @@ start)
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

View file

@ -108,8 +108,5 @@
#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 */

View file

@ -19,17 +19,12 @@ struct chardriver {
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);

View file

@ -196,7 +196,6 @@
#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 */
@ -208,8 +207,6 @@
#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 */
@ -241,12 +238,6 @@
#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 *
*===========================================================================*/
@ -937,6 +928,11 @@
#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 *
*===========================================================================*/

View file

@ -4,12 +4,8 @@
#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 *

View file

@ -159,8 +159,6 @@ int sys_umap_data_fb(endpoint_t proc_ep, vir_bytes vir_addr, vir_bytes
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)

View file

@ -20,11 +20,7 @@
* |-------------+---------+---------+---------+---------+---------|
* | DEV_IOCTL_S | device | proc nr |func code| | buf ptr |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_STATUS | | | | | |
* |-------------+---------+---------+---------+---------+---------|
* | HARD_INT | | | | | |
* |-------------+---------+---------+---------+---------+---------|
* | SIG_STOP | | | | | |
* -----------------------------------------------------------------
*
* The file contains one entry point:
@ -81,7 +77,6 @@ static void sef_cb_signal_handler(int signo);
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)
{
@ -121,8 +116,10 @@ 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);
@ -133,6 +130,8 @@ int main(void)
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);
@ -146,7 +145,7 @@ int main(void)
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);
}
@ -156,13 +155,13 @@ int main(void)
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;
@ -626,35 +625,6 @@ static void msg_hardware(void) {
}
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)
{
@ -712,6 +682,7 @@ 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];
@ -730,8 +701,13 @@ static void handle_int_read(int sub_dev_nr)
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 */
* 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;
@ -790,9 +766,6 @@ static void data_from_user(sub_dev_t *subdev)
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,
@ -835,7 +808,6 @@ static void data_from_user(sub_dev_t *subdev)
}
subdev->ReviveStatus = subdev->FragSize;
subdev->ReadyToRevive = TRUE;
m.m_type = DEV_REVIVE; /* build message */
m.REP_ENDPT = subdev->ReviveProcNr;
@ -849,7 +821,6 @@ static void data_from_user(sub_dev_t *subdev)
}
/* reset variables */
subdev->ReadyToRevive = FALSE;
subdev->RevivePending = 0;
}
@ -860,7 +831,6 @@ static void data_to_user(sub_dev_t *sub_dev_ptr)
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 */
@ -896,7 +866,6 @@ static void data_to_user(sub_dev_t *sub_dev_ptr)
}
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 */
@ -911,7 +880,6 @@ static void data_to_user(sub_dev_t *sub_dev_ptr)
}
/* reset variables */
sub_dev_ptr->ReadyToRevive = FALSE;
sub_dev_ptr->RevivePending = 0;
}

View file

@ -1,7 +1,5 @@
#include <minix/audio_fw.h>
/* State management variables. */
EXTERN int is_status_msg_expected;
/*
* - From audio_fw.h:
* EXTERN drv_t drv;
@ -60,8 +58,7 @@ int sef_cb_lu_prepare(int state)
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. */
@ -95,8 +92,6 @@ void sef_cb_lu_state_dump(int state)
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);
@ -105,8 +100,7 @@ void sef_cb_lu_state_dump(int state)
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",

View file

@ -73,9 +73,9 @@ void *data;
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);

View file

@ -28,6 +28,7 @@
* 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)
@ -117,16 +118,19 @@ void chardriver_announce(void)
}
/*===========================================================================*
* 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;
@ -150,7 +154,7 @@ static void async_reply(message *mess, int r)
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;
@ -170,60 +174,22 @@ static void async_reply(message *mess, int r)
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);
}
/*===========================================================================*
@ -343,7 +309,7 @@ static int handle_request(struct chardriver *cdp, message *m_ptr)
* 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;
@ -380,8 +346,7 @@ static int handle_request(struct chardriver *cdp, message *m_ptr)
/*===========================================================================*
* 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;
@ -394,14 +359,14 @@ void chardriver_process(struct chardriver *cdp, int driver_type,
} 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;
@ -416,7 +381,7 @@ void chardriver_task(struct chardriver *cdp, int driver_type)
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);
}
}

View file

@ -93,19 +93,14 @@ _ddekit_minix_queue_msg (
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));

View file

@ -76,7 +76,6 @@ SRCS+= \
sys_vsafecopy.c \
sys_vtimer.c \
sys_vumap.c \
send_taskreply.c \
taskcall.c \
tickdelay.c \
timers.c \

View file

@ -1,20 +0,0 @@
#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);
}

View file

@ -25,31 +25,10 @@
* | 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"
@ -72,7 +51,6 @@ THIS_FILE
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);
@ -82,16 +60,14 @@ static int sr_restart_read(sr_fd_t *fdp);
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);
@ -111,44 +87,26 @@ void sr_init()
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;
@ -158,24 +116,17 @@ mq_t *m;
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;
@ -185,7 +136,7 @@ mq_t *m;
}
if (send_reply)
{
sr_reply_(m, result, FALSE /* !is_revive */);
sr_reply_(m, code, result, FALSE /* !is_revive */);
}
if (free_mess)
mq_free(m);
@ -469,7 +420,6 @@ message *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);
@ -493,27 +443,24 @@ message *m;
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;
@ -521,72 +468,22 @@ message *m;
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"));
}
@ -651,8 +548,9 @@ int minor;
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;
{
@ -667,30 +565,12 @@ 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)
@ -739,7 +619,7 @@ int for_ioctl;
*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)
@ -800,7 +680,7 @@ int for_ioctl;
*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)
@ -820,15 +700,26 @@ int for_ioctl;
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;
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;
notify(sr_fd->srf_select_proc);
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)
@ -998,45 +889,6 @@ vir_bytes offset;
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 $
*/

View file

@ -43,9 +43,6 @@ typedef struct sr_fd
#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];

View file

@ -74,11 +74,9 @@ static char * dmap_style(int dev_style)
{
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";
}
}

View file

@ -1074,14 +1074,8 @@ int uds_cancel(message *dev_m_in, message *dev_m_out)
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. */
@ -1184,8 +1178,7 @@ int uds_cancel(message *dev_m_in, message *dev_m_out)
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;

View file

@ -61,10 +61,10 @@ int (*dev_call_vec[])(message *dev_m_in, message *dev_m_out) = {
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 */

View file

@ -47,8 +47,8 @@ struct boot_image_dev boot_image_dev_table[] = {
/*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
*/

View file

@ -28,7 +28,7 @@
#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 */
@ -50,4 +50,6 @@
#define VFS_DEV_IOCTL 2005
#define VFS_DEV_SELECT 2006
#define dev_style_asyn(n) (TRUE)
#endif

View file

@ -8,7 +8,6 @@
* 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
@ -169,7 +168,7 @@ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, int req, void *buf)
/* 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);
}
@ -188,7 +187,7 @@ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, int req, void *buf)
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);
@ -225,71 +224,6 @@ endpoint_t find_suspended_ep(endpoint_t driver, cp_grant_id_t g)
}
/*===========================================================================*
* 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 *
*===========================================================================*/
@ -514,18 +448,22 @@ int gen_opcl(
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;
@ -637,9 +575,9 @@ int do_ioctl(message *UNUSED(m_out))
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);

View file

@ -179,26 +179,18 @@ int flags; /* device flags */
/* 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;

View file

@ -42,7 +42,6 @@ EXTERN unsigned long calls_stats[NCALLS];
/* 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);
@ -114,8 +113,6 @@ int main(void)
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;
@ -140,7 +137,8 @@ int main(void)
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 {
@ -272,23 +270,6 @@ static void *do_control_msgs(void *arg)
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 *
*===========================================================================*/

View file

@ -612,7 +612,7 @@ void unpause(endpoint_t proc_e)
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;

View file

@ -48,7 +48,6 @@ int clone_opcl(int op, dev_t dev, endpoint_t proc, int flags);
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);

View file

@ -415,8 +415,7 @@ static int select_request_major(struct filp *f, int *ops, int block)
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);