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:
parent
97172a1db0
commit
6331e8f845
48 changed files with 475 additions and 1105 deletions
|
@ -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;
|
||||
|
|
|
@ -624,7 +624,7 @@ main(int argc, char *argv[])
|
|||
|
||||
sef_local_startup();
|
||||
|
||||
chardriver_task(&bmp085_tab, CHARDRIVER_SYNC);
|
||||
chardriver_task(&bmp085_tab);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ int main(void)
|
|||
/*
|
||||
* Run the main loop.
|
||||
*/
|
||||
chardriver_task(&hello_tab, CHARDRIVER_SYNC);
|
||||
chardriver_task(&hello_tab);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -527,7 +527,7 @@ main(int argc, char *argv[])
|
|||
|
||||
sef_local_startup();
|
||||
|
||||
chardriver_task(&sht21_tab, CHARDRIVER_SYNC);
|
||||
chardriver_task(&sht21_tab);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -476,7 +476,7 @@ main(int argc, char *argv[])
|
|||
|
||||
sef_local_startup();
|
||||
|
||||
chardriver_task(&tsl2550_tab, CHARDRIVER_SYNC);
|
||||
chardriver_task(&tsl2550_tab);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -33,12 +33,6 @@ kb_init_once(void)
|
|||
{
|
||||
}
|
||||
|
||||
int
|
||||
kbd_status(message *m)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
kbd_loadmap(message *m)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 *
|
||||
*===========================================================================*/
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -76,7 +76,6 @@ SRCS+= \
|
|||
sys_vsafecopy.c \
|
||||
sys_vtimer.c \
|
||||
sys_vumap.c \
|
||||
send_taskreply.c \
|
||||
taskcall.c \
|
||||
tickdelay.c \
|
||||
timers.c \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 $
|
||||
*/
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 *
|
||||
*===========================================================================*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue