Rewrite character driver protocol

As a side effect, remove the clone style, as the normal device style
supports device cloning now.

Change-Id: Ie82d1ef0385514a04a8faa139129a617895780b5
This commit is contained in:
David van Moolenbroek 2013-09-10 20:25:01 +02:00 committed by Lionel Sambuc
parent 87337273e4
commit 665198b4c2
38 changed files with 515 additions and 661 deletions

View file

@ -335,9 +335,9 @@ 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_TTY",
"STYLE_CTTY", "STYLE_CLONE", NULL };
"STYLE_CTTY", NULL };
int dev_style_values[] = { STYLE_DEV, STYLE_TTY,
STYLE_CTTY, STYLE_CLONE };
STYLE_CTTY };
for(j=0;dev_style_keys[j]!=NULL;j++) {
if(!strcmp(dev_style_keys[j], argv[i+1])) {
break;

View file

@ -167,17 +167,17 @@ subwrite(struct logdevice *log, size_t size, endpoint_t endpt,
log->log_source = NONE;
}
if (log->log_size > 0 && (log->log_selected & SEL_RD)) {
if (log->log_size > 0 && (log->log_selected & CDEV_OP_RD)) {
/* Someone(s) who was/were select()ing can now be awoken. If there was
* a blocking read (above), this can only happen if the blocking read
* didn't swallow all the data (log_size > 0).
*/
minor = log-logdevices;
#if LOG_DEBUG
printf("select sending DEV_SEL_REPL2\n");
printf("select sending CDEV_SEL2_REPLY\n");
#endif
chardriver_reply_select(log->log_select_proc, minor, SEL_RD);
log->log_selected &= ~SEL_RD;
chardriver_reply_select(log->log_select_proc, minor, CDEV_OP_RD);
log->log_selected &= ~CDEV_OP_RD;
}
return r;
@ -248,7 +248,7 @@ static ssize_t log_read(devminor_t minor, u64_t UNUSED(position),
if (log->log_source != NONE) return OK;
if (!log->log_size && size > 0) {
if (flags & FLG_OP_NONBLOCK) return EAGAIN;
if (flags & CDEV_NONBLOCK) return EAGAIN;
/* No data available; let caller block. */
log->log_source = endpt;
@ -319,24 +319,24 @@ static int log_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
if (minor < 0 || minor >= NR_DEVS)
return ENXIO;
want_ops = ops & (SEL_RD|SEL_WR|SEL_ERR);
want_ops = ops & (CDEV_OP_RD | CDEV_OP_WR | CDEV_OP_ERR);
/* Read blocks when there is no log. */
if ((want_ops & SEL_RD) && logdevices[minor].log_size > 0) {
if ((want_ops & CDEV_OP_RD) && logdevices[minor].log_size > 0) {
#if LOG_DEBUG
printf("log can read; size %d\n", logdevices[minor].log_size);
#endif
ready_ops |= SEL_RD;
ready_ops |= CDEV_OP_RD;
}
/* Write never blocks. */
if (want_ops & SEL_WR) ready_ops |= SEL_WR;
if (want_ops & CDEV_OP_WR) ready_ops |= CDEV_OP_WR;
/* Enable select calback if not all requested operations were ready to go,
* and notify was enabled.
*/
want_ops &= ~ready_ops;
if ((ops & SEL_NOTIFY) && want_ops) {
if ((ops & CDEV_NOTIFY) && want_ops) {
logdevices[minor].log_selected |= want_ops;
logdevices[minor].log_select_proc = endpt;
#if LOG_DEBUG

View file

@ -5,27 +5,6 @@
* Changes:
* May 07, 2004 fix: wait until printer is ready (Jorrit N. Herder)
* May 06, 2004 printer driver moved to user-space (Jorrit N. Herder)
*
* The valid messages and their parameters are:
*
* DEV_OPEN: initializes the printer
* DEV_CLOSE: does nothing
* HARD_INT: interrupt handler has finished current chunk of output
* DEV_WRITE: a process wants to write on a terminal
* CANCEL: terminate a previous incomplete system call immediately
*
* m_type DEVICE USER_ENDPT COUNT ADDRESS
* |-------------+---------+---------+---------+---------|
* | DEV_OPEN | | | | |
* |-------------+---------+---------+---------+---------|
* | DEV_CLOSE | | proc nr | | |
* |-------------+---------+---------+---------+---------|
* | HARD_INT | | | | |
* |-------------+---------+---------+---------+---------|
* | DEV_WRITE |minor dev| proc nr | count | buf ptr |
* |-------------+---------+---------+---------+---------|
* | CANCEL |minor dev| proc nr | | |
* -------------------------------------------------------
*
* Note: since only 1 printer is supported, minor dev is not used at present.
*/
@ -192,7 +171,7 @@ static ssize_t printer_write(devminor_t UNUSED(minor), u64_t UNUSED(position),
*/
if (writing) return EIO;
if (size <= 0) return EINVAL;
if (flags & FLG_OP_NONBLOCK) return EAGAIN; /* not supported */
if (flags & CDEV_NONBLOCK) return EAGAIN; /* not supported */
/* If no errors occurred, continue printing with the caller.
* First wait until the printer is online to prevent stupid errors.

View file

@ -261,7 +261,7 @@ kbd_read(devminor_t minor, u64_t UNUSED(position), endpoint_t endpt,
/* If no data is available, suspend the caller. */
if (kbdp->avail == 0) {
if (flags & FLG_OP_NONBLOCK)
if (flags & CDEV_NONBLOCK)
return EAGAIN;
kbdp->req_size = size;
kbdp->req_id = id;
@ -420,14 +420,14 @@ kbd_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
if ((kbdp = line2kbd(minor)) == NULL)
return ENXIO;
watch = (ops & SEL_NOTIFY);
ops &= (SEL_RD | SEL_WR | SEL_ERR);
watch = (ops & CDEV_NOTIFY);
ops &= (CDEV_OP_RD | CDEV_OP_WR | CDEV_OP_ERR);
ready_ops = 0;
if (kbdp->avail && (ops & SEL_RD))
ready_ops |= SEL_RD;
if (ops & SEL_WR)
ready_ops |= SEL_WR; /* writes never block */
if (kbdp->avail && (ops & CDEV_OP_RD))
ready_ops |= CDEV_OP_RD;
if (ops & CDEV_OP_WR)
ready_ops |= CDEV_OP_WR; /* writes never block */
ops &= ~ready_ops;
if (ops && watch) {
@ -543,10 +543,10 @@ void kbd_interrupt(message *UNUSED(m_ptr))
kbdp->req_caller = NONE;
}
/* Only satisfy pending select if characters weren't just read. */
if (kbdp->avail && (kbdp->select_ops & SEL_RD)) {
if (kbdp->avail && (kbdp->select_ops & CDEV_OP_RD)) {
chardriver_reply_select(kbdp->select_proc, kbdp->minor,
SEL_RD);
kbdp->select_ops &= ~SEL_RD;
CDEV_OP_RD);
kbdp->select_ops &= ~CDEV_OP_RD;
}
return;
}
@ -557,7 +557,7 @@ void kbd_interrupt(message *UNUSED(m_ptr))
if (ihead == ibuf + KB_IN_BYTES) ihead = ibuf;
icount++;
tty_table[ccurrent].tty_events = 1;
if (tty_table[ccurrent].tty_select_ops & SEL_RD) {
if (tty_table[ccurrent].tty_select_ops & CDEV_OP_RD) {
select_retry(&tty_table[ccurrent]);
}
}
@ -581,7 +581,7 @@ void do_kb_inject(message *msg)
if (injhead == injbuf + KB_IN_BYTES) injhead = injbuf;
injcount++;
tty_table[ccurrent].tty_events = 1;
if (tty_table[ccurrent].tty_select_ops & SEL_RD) {
if (tty_table[ccurrent].tty_select_ops & CDEV_OP_RD) {
select_retry(&tty_table[ccurrent]);
}
}

View file

@ -167,7 +167,7 @@ static ssize_t pty_master_read(devminor_t minor, u64_t UNUSED(position),
return EDONTREPLY; /* already done */
}
if (flags & FLG_OP_NONBLOCK) {
if (flags & CDEV_NONBLOCK) {
r = pp->rdcum > 0 ? pp->rdcum : EAGAIN;
pp->rdleft = pp->rdcum = 0;
pp->rdcaller = NONE;
@ -214,7 +214,7 @@ static ssize_t pty_master_write(devminor_t minor, u64_t UNUSED(position),
return EDONTREPLY; /* already done */
}
if (flags & FLG_OP_NONBLOCK) {
if (flags & CDEV_NONBLOCK) {
r = pp->wrcum > 0 ? pp->wrcum : EAGAIN;
pp->wrleft = pp->wrcum = 0;
pp->wrcaller = NONE;
@ -265,18 +265,18 @@ static int select_try_pty(tty_t *tp, int ops)
pty_t *pp = tp->tty_priv;
int r = 0;
if (ops & SEL_WR) {
if (ops & CDEV_OP_WR) {
/* Write won't block on error. */
if (pp->state & TTY_CLOSED) r |= SEL_WR;
else if (pp->wrleft != 0 || pp->wrcum != 0) r |= SEL_WR;
else if (tp->tty_inleft > 0) r |= SEL_WR; /* There's a reader. */
if (pp->state & TTY_CLOSED) r |= CDEV_OP_WR;
else if (pp->wrleft != 0 || pp->wrcum != 0) r |= CDEV_OP_WR;
else if (tp->tty_inleft > 0) r |= CDEV_OP_WR; /* There's a reader. */
}
if (ops & SEL_RD) {
if (ops & CDEV_OP_RD) {
/* Read won't block on error. */
if (pp->state & TTY_CLOSED) r |= SEL_RD;
else if (pp->rdleft != 0 || pp->rdcum != 0) r |= SEL_RD;
else if (pp->ocount > 0) r |= SEL_RD; /* Actual data. */
if (pp->state & TTY_CLOSED) r |= CDEV_OP_RD;
else if (pp->rdleft != 0 || pp->rdcum != 0) r |= CDEV_OP_RD;
else if (pp->ocount > 0) r |= CDEV_OP_RD; /* Actual data. */
}
return r;
@ -313,8 +313,8 @@ static int pty_master_select(devminor_t minor, unsigned int ops,
return ENXIO;
pp = tp->tty_priv;
watch = (ops & SEL_NOTIFY);
ops &= (SEL_RD | SEL_WR | SEL_ERR);
watch = (ops & CDEV_NOTIFY);
ops &= (CDEV_OP_RD | CDEV_OP_WR | CDEV_OP_ERR);
ready_ops = select_try_pty(tp, ops);

View file

@ -16,38 +16,6 @@
* to, you guessed it, wake up the TTY to check if input or output can
* continue.
*
* The valid messages and their parameters are:
*
* notify from HARDWARE: output has been completed or input has arrived
* notify from SYSTEM : e.g., MINIX wants to shutdown; run code to
* cleanly stop
* DEV_READ: a process wants to read from a terminal
* DEV_WRITE: a process wants to write on a terminal
* DEV_IOCTL: a process wants to change a terminal's parameters
* DEV_OPEN: a tty line has been opened
* DEV_CLOSE: a tty line has been closed
* DEV_SELECT: start select notification request
* CANCEL: terminate a previous incomplete system call immediately
*
* m_type DEVICE USER_ENDPT COUNT POSITION IO_GRANT
* -----------------------------------------------------------------
* | HARD_INT | | | | | |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_READ |minor dev| proc nr | count | | grant |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_WRITE |minor dev| proc nr | count | | grant |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_IOCTL |minor dev| proc nr |func code|user proc| |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_OPEN |minor dev| proc nr | O_NOCTTY| | |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_CLOSE |minor dev| proc nr | | | |
* |-------------+---------+---------+---------+---------+---------|
* | CANCEL |minor dev| proc nr | | | |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_SELECT |minor dev| sel ops | | | |
* -----------------------------------------------------------------
*
* Changes:
* Jan 20, 2004 moved TTY driver to user-space (Jorrit N. Herder)
* Sep 20, 2004 local timer management/ sync alarms (Jorrit N. Herder)
@ -235,7 +203,7 @@ int main(void)
; /* do nothing; end switch */
}
if (!IS_DEV_RQ(tty_mess.m_type)) {
if (!IS_CDEV_RQ(tty_mess.m_type)) {
chardriver_process(&tty_tab, &tty_mess, ipc_status);
continue;
}
@ -243,7 +211,7 @@ int main(void)
/* Only device requests should get to this point.
* All requests have a minor device number.
*/
line = tty_mess.DEVICE;
line = tty_mess.CDEV_MINOR;
if (line == KBD_MINOR || line == KBDAUX_MINOR) {
do_kbd(&tty_mess, ipc_status);
continue;
@ -251,7 +219,7 @@ int main(void)
do_video(&tty_mess, ipc_status);
continue;
} else if (line - PTYPX_MINOR < NR_PTYS &&
tty_mess.m_type != DEV_IOCTL_S) {
tty_mess.m_type != CDEV_IOCTL) {
/* Terminals and pseudo terminals belong together. We can only
* make a distinction between the two based on position in the
* tty_table and not on minor number (i.e., use ispty macro).
@ -276,7 +244,7 @@ set_color(tty_t *tp, int color)
buf[0] = '\033';
snprintf(&buf[1], sizeof(buf) - 1, "[1;%dm", color);
do_write(tp->tty_minor, 0, KERNEL, (cp_grant_id_t) buf, sizeof(buf),
FLG_OP_NONBLOCK, 0);
CDEV_NONBLOCK, 0);
}
static void
@ -288,7 +256,7 @@ reset_color(tty_t *tp)
buf[0] = '\033';
snprintf(&buf[1], sizeof(buf) - 1, "[0;%dm", SGR_COLOR_RESET);
do_write(tp->tty_minor, 0, KERNEL, (cp_grant_id_t) buf, sizeof(buf),
FLG_OP_NONBLOCK, 0);
CDEV_NONBLOCK, 0);
}
tty_t *
@ -466,7 +434,7 @@ do_new_kmess(void)
set_color(tp, kernel_msg_color);
do_write(tp->tty_minor, 0, KERNEL,
(cp_grant_id_t) kernel_buf_copy, bytes,
FLG_OP_NONBLOCK, 0);
CDEV_NONBLOCK, 0);
if (kernel_msg_color != 0)
reset_color(tp);
if (restore) {
@ -553,7 +521,7 @@ static ssize_t do_read(devminor_t minor, u64_t UNUSED(position),
return EDONTREPLY; /* already done */
/* There were no bytes in the input queue available. */
if (flags & FLG_OP_NONBLOCK) {
if (flags & CDEV_NONBLOCK) {
tty_icancel(tp);
r = tp->tty_incum > 0 ? tp->tty_incum : EAGAIN;
tp->tty_inleft = tp->tty_incum = 0;
@ -602,7 +570,7 @@ static ssize_t do_write(devminor_t minor, u64_t UNUSED(position),
return EDONTREPLY; /* already done */
/* None or not all the bytes could be written. */
if (flags & FLG_OP_NONBLOCK) {
if (flags & CDEV_NONBLOCK) {
r = tp->tty_outcum > 0 ? tp->tty_outcum : EAGAIN;
tp->tty_outleft = tp->tty_outcum = 0;
tp->tty_outcaller = NONE;
@ -677,7 +645,7 @@ static int do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
case TCSETSF:
case TCDRAIN:
if (tp->tty_outleft > 0) {
if (flags & FLG_OP_NONBLOCK)
if (flags & CDEV_NONBLOCK)
return EAGAIN;
/* Wait for all ongoing output processing to finish. */
tp->tty_iocaller = endpt;
@ -771,8 +739,8 @@ static int do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
static int do_open(devminor_t minor, int access, endpoint_t user_endpt)
{
/* A tty line has been opened. Make it the callers controlling tty if
* O_NOCTTY is *not* set and it is not the log device. 1 is returned if
* the tty is made the controlling tty, otherwise OK or an error code.
* CDEV_NOCTTY is *not* set and it is not the log device. CDEV_CTTY is returned
* if the tty is made the controlling tty, otherwise OK or an error code.
*/
tty_t *tp;
int r = OK;
@ -782,11 +750,11 @@ static int do_open(devminor_t minor, int access, endpoint_t user_endpt)
if (minor == LOG_MINOR && isconsole(tp)) {
/* The log device is a write-only diagnostics device. */
if (access & R_BIT) return EACCES;
if (access & CDEV_R_BIT) return EACCES;
} else {
if (!(access & O_NOCTTY)) {
if (!(access & CDEV_NOCTTY)) {
tp->tty_pgrp = user_endpt;
r = 1;
r = CDEV_CTTY;
}
tp->tty_openct++;
if (tp->tty_openct == 1) {
@ -874,10 +842,10 @@ int select_try(struct tty *tp, int ops)
ready_ops |= ops;
}
if (ops & SEL_RD) {
if (ops & CDEV_OP_RD) {
/* will i/o not block on read? */
if (tp->tty_inleft > 0) {
ready_ops |= SEL_RD; /* EIO - no blocking */
ready_ops |= CDEV_OP_RD; /* EIO - no blocking */
} else if (tp->tty_incount > 0) {
/* Is a regular read possible? tty_incount
* says there is data. But a read will only succeed
@ -885,14 +853,14 @@ int select_try(struct tty *tp, int ops)
*/
if (!(tp->tty_termios.c_lflag & ICANON) ||
tp->tty_eotct > 0) {
ready_ops |= SEL_RD;
ready_ops |= CDEV_OP_RD;
}
}
}
if (ops & SEL_WR) {
if (tp->tty_outleft > 0) ready_ops |= SEL_WR;
else if ((*tp->tty_devwrite)(tp, 1)) ready_ops |= SEL_WR;
if (ops & CDEV_OP_WR) {
if (tp->tty_outleft > 0) ready_ops |= CDEV_OP_WR;
else if ((*tp->tty_devwrite)(tp, 1)) ready_ops |= CDEV_OP_WR;
}
return ready_ops;
}
@ -924,8 +892,8 @@ static int do_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
if (tp->tty_minor != minor)
return EBADF;
watch = (ops & SEL_NOTIFY);
ops &= (SEL_RD | SEL_WR | SEL_ERR);
watch = (ops & CDEV_NOTIFY);
ops &= (CDEV_OP_RD | CDEV_OP_WR | CDEV_OP_ERR);
ready_ops = select_try(tp, ops);

View file

@ -25,9 +25,6 @@
#define ESC '\33' /* escape */
#define O_NOCTTY 00400 /* from <fcntl.h>, or cc will choke */
#define O_NONBLOCK 04000
struct tty;
typedef int(*devfun_t) (struct tty *tp, int try_only);
typedef void(*devfunarg_t) (struct tty *tp, int c);

View file

@ -65,10 +65,10 @@ 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
service up /usr/sbin/lwip -script /etc/rs.inet -dev /dev/ip
dhcpd --lwip &
else
service up /usr/sbin/inet -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE
service up /usr/sbin/inet -script /etc/rs.inet -dev /dev/ip
daemonize dhcpd
fi
daemonize nonamed -L

View 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
up lwip -script /etc/rs.inet -dev /dev/ip
else
up inet -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE
up inet -script /etc/rs.inet -dev /dev/ip
fi
up -n ipc

View file

@ -8,8 +8,8 @@
* 1 - 0xFF POSIX requests (see callnr.h)
* 0x200 - 0x2FF Data link layer requests and responses
* 0x300 - 0x3FF Bus controller requests and responses
* 0x400 - 0x4FF Character device requests
* 0x500 - 0x5FF Character device responses
* 0x400 - 0x4FF Character device requests and responses
* 0x500 - 0x5FF Block device requests and responses
* 0x600 - 0x6FF Kernel calls to SYSTEM task
* 0x700 - 0x7FF Reincarnation Server (RS) requests
* 0x800 - 0x8FF Data Store (DS) requests
@ -25,7 +25,7 @@
* 0x1200 - 0x12FF Devman
* 0x1300 - 0x13FF TTY Requests
* 0x1400 - 0x14FF VFS-FS transaction IDs
* 0x1500 - 0x15FF Block device requests and responses
* 0x1500 - 0x15FF (unused)
* 0x1600 - 0x16FF VirtualBox (VBOX) requests (see vboxif.h)
* 0x1700 - 0x17FF Real Time Clock requests and responses
*
@ -186,58 +186,6 @@
#define BUSC_I2C_EXEC (BUSC_RQ_BASE + 65) /* perform i2c action */
#define BUSC_I2C_GRANT m2_i1 /* grant for request */
/*===========================================================================*
* Messages for CHARACTER device drivers *
*===========================================================================*/
/* Message types for character device drivers. */
#define DEV_RQ_BASE 0x400 /* base for character device request types */
#define DEV_RS_BASE 0x500 /* base for character device response types */
#define CANCEL (DEV_RQ_BASE + 0) /* force a task to cancel */
#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_READ_S (DEV_RQ_BASE + 20) /* (safecopy) read from minor */
#define DEV_WRITE_S (DEV_RQ_BASE + 21) /* (safecopy) write to minor */
#define DEV_SCATTER_S (DEV_RQ_BASE + 22) /* (safecopy) write from a vector */
#define DEV_GATHER_S (DEV_RQ_BASE + 23) /* (safecopy) read into a vector */
#define DEV_IOCTL_S (DEV_RQ_BASE + 24) /* (safecopy) I/O control code */
#define IS_DEV_RQ(type) (((type) & ~0xff) == DEV_RQ_BASE)
#define DEV_REVIVE (DEV_RS_BASE + 2) /* driver revives process */
#define DEV_CLOSE_REPL (DEV_RS_BASE + 6) /* reply to DEV_CLOSE */
#define DEV_SEL_REPL1 (DEV_RS_BASE + 7) /* first reply to DEV_SELECT */
#define DEV_SEL_REPL2 (DEV_RS_BASE + 8) /* (opt) second reply to DEV_SELECT */
#define DEV_OPEN_REPL (DEV_RS_BASE + 9) /* reply to DEV_OPEN */
#define IS_DEV_RS(type) (((type) & ~0xff) == DEV_RS_BASE)
/* Field names for messages to character device drivers. */
#define DEVICE m2_i1 /* major-minor device */
#define USER_ENDPT m2_i2 /* which endpoint initiated this call? */
#define COUNT m2_i3 /* how many bytes to transfer */
#define REQUEST m2_i3 /* ioctl request code */
#define POSITION m2_l1 /* file offset (low 4 bytes) */
#define HIGHPOS m2_l2 /* file offset (high 4 bytes) */
#define ADDRESS m2_p1 /* core buffer address */
#define IO_GRANT m2_p1 /* grant id (for DEV_*_S variants) */
#define FLAGS m2_s1 /* operation flags */
#define FLG_OP_NONBLOCK 0x1 /* operation is non blocking */
/* Field names for DEV_SELECT messages to character device drivers. */
#define DEV_MINOR m2_i1 /* minor device */
#define DEV_SEL_OPS m2_i2 /* which select operations are requested */
/* Field names used in reply messages from tasks. */
#define REP_ENDPT m2_i1 /* # of proc on whose behalf I/O was done */
#define REP_STATUS m2_i2 /* bytes transferred or error number */
#define REP_IO_GRANT m2_i3 /* DEV_REVIVE: grant by which I/O was done */
# define SUSPEND -998 /* status to suspend caller, reply later */
/*===========================================================================*
* Messages for networking layer *
*===========================================================================*/
@ -939,6 +887,11 @@
#define VFS_PFS_FD m2_i3
#define VFS_PFS_FILP m2_p1
/* Field names for GETRUSAGE related calls */
#define RU_ENDPT m1_i1 /* indicates a process for sys_getrusage */
#define RU_WHO m1_i1 /* who argument in getrusage call */
#define RU_RUSAGE_ADDR m1_p1 /* pointer to struct rusage */
/*===========================================================================*
* Messages for VM server *
*===========================================================================*/
@ -1298,13 +1251,71 @@
#define VFS_TRANSID (VFS_TRANSACTION_BASE + 1)
#define IS_VFS_FS_TRANSID(type) (((type) & ~0xff) == VFS_TRANSACTION_BASE)
/*===========================================================================*
* Messages for character devices *
*===========================================================================*/
/* Base type for character device requests and responses. */
#define CDEV_RQ_BASE 0x400
#define CDEV_RS_BASE 0x480
#define IS_CDEV_RQ(type) (((type) & ~0x7f) == CDEV_RQ_BASE)
#define IS_CDEV_RS(type) (((type) & ~0x7f) == CDEV_RS_BASE)
/* Message types for character device requests. */
#define CDEV_OPEN (CDEV_RQ_BASE + 0) /* open a minor device */
#define CDEV_CLOSE (CDEV_RQ_BASE + 1) /* close a minor device */
#define CDEV_READ (CDEV_RQ_BASE + 2) /* read into a buffer */
#define CDEV_WRITE (CDEV_RQ_BASE + 3) /* write from a buffer */
#define CDEV_IOCTL (CDEV_RQ_BASE + 4) /* I/O control operation */
#define CDEV_CANCEL (CDEV_RQ_BASE + 5) /* cancel suspended request */
#define CDEV_SELECT (CDEV_RQ_BASE + 6) /* test for ready operations */
/* Message types for character device responses. */
#define CDEV_REPLY (CDEV_RS_BASE + 0) /* general reply code */
#define CDEV_SEL1_REPLY (CDEV_RS_BASE + 1) /* immediate select reply */
#define CDEV_SEL2_REPLY (CDEV_RS_BASE + 2) /* select notification reply */
/* Field names for block device messages. */
#define CDEV_MINOR m10_i1 /* minor device number */
#define CDEV_STATUS m10_i2 /* OK, error code, minor device, operations */
#define CDEV_ACCESS m10_i2 /* access bits for open requests */
#define CDEV_GRANT m10_i2 /* grant ID of buffer */
#define CDEV_OPS m10_i2 /* requested select operations */
#define CDEV_COUNT m10_i3 /* number of bytes to transfer */
#define CDEV_USER m10_i3 /* endpoint of user process */
#define CDEV_FLAGS m10_i4 /* transfer flags */
#define CDEV_ID m10_l1 /* opaque request ID */
#define CDEV_REQUEST m10_l2 /* I/O control request */
#define CDEV_POS_LO m10_l2 /* transfer position (low bits) */
#define CDEV_POS_HI m10_l3 /* transfer position (high bits) */
/* Bits in 'CDEV_ACCESS' field of block device open requests. */
# define CDEV_R_BIT 0x01 /* open with read access */
# define CDEV_W_BIT 0x02 /* open with write access */
# define CDEV_NOCTTY 0x04 /* not to become the controlling TTY */
/* Bits in 'CDEV_FLAGS' field of block device transfer requests. */
# define CDEV_NOFLAGS 0x00 /* no flags are set */
# define CDEV_NONBLOCK 0x01 /* do not suspend I/O request */
/* Bits in 'CDEV_OPS', 'CDEV_STATUS' fields of block device select messages. */
# define CDEV_OP_RD 0x01 /* selected for read operation */
# define CDEV_OP_WR 0x02 /* selected for write operation */
# define CDEV_OP_ERR 0x04 /* selected for error operation */
# define CDEV_NOTIFY 0x08 /* notification requested */
/* Bits in 'CDEV_STATUS' field of block device open responses. */
# define CDEV_CLONED 0x20000000 /* device is cloned */
# define CDEV_CTTY 0x40000000 /* device is controlling TTY */
/*===========================================================================*
* Messages for block devices *
*===========================================================================*/
/* Base type for block device requests and responses. */
#define BDEV_RQ_BASE 0x1500
#define BDEV_RS_BASE 0x1580
#define BDEV_RQ_BASE 0x500
#define BDEV_RS_BASE 0x580
#define IS_BDEV_RQ(type) (((type) & ~0x7f) == BDEV_RQ_BASE)
#define IS_BDEV_RS(type) (((type) & ~0x7f) == BDEV_RS_BASE)
@ -1343,11 +1354,6 @@
# define BDEV_FORCEWRITE 0x01 /* force write to disk immediately */
# define BDEV_NOPAGE 0x02 /* eeprom: don't send page address */
/* Field names for GETRUSAGE related calls */
#define RU_ENDPT m1_i1 /* indicates a process for sys_getrusage */
#define RU_WHO m1_i1 /* who argument in getrusage call */
#define RU_RUSAGE_ADDR m1_p1 /* pointer to struct rusage */
/*===========================================================================*
* Messages for Real Time Clocks *
*===========================================================================*/
@ -1382,4 +1388,10 @@
#define RTCDEV_Y2KBUG 0x01 /* Interpret 1980 as 2000 for RTC w/Y2K bug */
#define RTCDEV_CMOSREG 0x02 /* Also set the CMOS clock register bits. */
/*===========================================================================*
* Internal codes used by several services *
*===========================================================================*/
#define SUSPEND -998 /* status to suspend caller, reply later */
/* _MINIX_COM_H */

View file

@ -4,8 +4,8 @@
#include <minix/sys_config.h>
#include <minix/ipc.h>
enum dev_style { STYLE_NDEV, STYLE_DEV, STYLE_TTY, STYLE_CTTY, STYLE_CLONE };
#define IS_DEV_STYLE(s) (s>=STYLE_NDEV && s<=STYLE_CLONE)
enum dev_style { STYLE_NDEV, STYLE_DEV, STYLE_TTY, STYLE_CTTY };
#define IS_DEV_STYLE(s) (s>=STYLE_NDEV && s<=STYLE_CTTY)
/*===========================================================================*
* Major and minor device numbers *

View file

@ -5,23 +5,6 @@
* extra buffer space beside the dma buffer.
* This driver also support sub devices, which can be independently
* opened and closed.
*
* The driver supports the following operations:
*
* m_type DEVICE USER_ENDPT COUNT POSITION ADRRESS
* -----------------------------------------------------------------
* | DEV_OPEN | device | proc nr | | | |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_CLOSE | device | proc nr | | | |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_READ_S | device | proc nr | bytes | | buf ptr |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_WRITE_S | device | proc nr | bytes | | buf ptr |
* |-------------+---------+---------+---------+---------+---------|
* | DEV_IOCTL_S | device | proc nr |func code| | buf ptr |
* |-------------+---------+---------+---------+---------+---------|
* | HARD_INT | | | | | |
* -----------------------------------------------------------------
*
* The file contains one entry point:
*

View file

@ -369,9 +369,9 @@ static void do_char_open(message *m_ptr, int ipc_status)
memset(&m_reply, 0, sizeof(m_reply));
m_reply.m_type = DEV_OPEN_REPL;
m_reply.REP_ENDPT = m_ptr->USER_ENDPT;
m_reply.REP_STATUS = ENXIO;
m_reply.m_type = CDEV_REPLY;
m_reply.CDEV_STATUS = ENXIO;
m_reply.CDEV_ID = m_ptr->CDEV_ID;
send_reply(m_ptr->m_source, &m_reply, ipc_status);
}
@ -413,7 +413,7 @@ void blockdriver_process_on_thread(struct blockdriver *bdp, message *m_ptr,
* someone creates a character device node for a block driver, opening that
* device node will cause the corresponding VFS thread to block forever.
*/
if (m_ptr->m_type == DEV_OPEN) {
if (m_ptr->m_type == CDEV_OPEN) {
do_char_open(m_ptr, ipc_status);
return;

View file

@ -1,27 +1,36 @@
/* This file contains the device independent character driver interface.
*
* The drivers support the following operations (using message format m2):
* Charaxter drivers support the following requests. Message format m10 is
* used. Field names are prefixed with CDEV_. Separate field names are used for
* the "access", "ops", "user", and "request" fields.
*
* m_type DEVICE USER_ENDPT COUNT POSITION HIGHPOS IO_GRANT
* ----------------------------------------------------------------------------
* | DEV_OPEN | device | proc nr | mode | | | |
* |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_CLOSE | device | proc nr | | | | |
* |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_READ_S | device | proc nr | bytes | off lo | off hi i buf grant |
* |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_WRITE_S | device | proc nr | bytes | off lo | off hi | buf grant |
* |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_GATHER_S | device | proc nr | iov len | off lo | off hi | iov grant |
* |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_SCATTER_S | device | proc nr | iov len | off lo | off hi | iov grant |
* |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_IOCTL_S | device | proc nr | request | | | buf grant |
* |---------------+--------+---------+---------+--------+--------+-----------|
* | CANCEL | device | proc nr | r/w | | | grant |
* |---------------+--------+---------+---------+--------+--------+-----------|
* | DEV_SELECT | device | ops | | | | |
* ----------------------------------------------------------------------------
* m_type MINOR GRANT COUNT FLAGS ID POS_LO POS_HI
* +-------------+-------+--------+-------+-------+------+---------+--------+
* | CDEV_OPEN | minor | access | user | | id | | |
* |-------------+-------+--------+-------+-------+------+---------+--------|
* | CDEV_CLOSE | minor | | | | id | | |
* |-------------+-------+--------+-------+-------+------+---------+--------|
* | CDEV_READ | minor | grant | bytes | flags | id | position |
* |-------------+-------+--------+-------+-------+------+---------+--------|
* | CDEV_WRITE | minor | grant | bytes | flags | id | position |
* |-------------+-------+--------+-------+-------+------+---------+--------|
* | CDEV_IOCTL | minor | grant | user | flags | id | request | |
* |-------------+-------+--------+-------+-------+------+---------+--------|
* | CDEV_CANCEL | minor | | | | id | | |
* |-------------+-------+--------+-------+-------+------+---------+--------|
* | CDEV_SELECT | minor | ops | | | | | |
* --------------------------------------------------------------------------
*
* The following reply messages are used.
*
* m_type MINOR STATUS ID
* +-----------------+-------+--------+-----+-----+------+---------+--------+
* | CDEV_REPLY | | status | | | id | | |
* |-----------------+-------+--------+-----+-----+------+---------+--------|
* | CDEV_SEL1_REPLY | minor | status | | | | | |
* |-----------------+-------+--------+-----+-----+------+---------+--------|
* | CDEV_SEL2_REPLY | minor | status | | | | | |
* --------------------------------------------------------------------------
*
* Changes:
* Sep 01, 2013 complete rewrite of the API (D.C. van Moolenboek)
@ -110,7 +119,7 @@ void chardriver_announce(void)
if ((r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE)) != OK)
panic("chardriver_init: unable to publish driver up event: %d", r);
/* Expect a DEV_OPEN for any device before serving regular driver requests. */
/* Expect an open for any device before serving regular driver requests. */
clear_open_devs();
}
@ -130,10 +139,9 @@ void chardriver_reply_task(endpoint_t endpt, cdev_id_t id, int r)
memset(&m_reply, 0, sizeof(m_reply));
m_reply.m_type = DEV_REVIVE;
m_reply.REP_STATUS = r;
m_reply.REP_ENDPT = endpt; /* XXX FIXME: hack */
m_reply.REP_IO_GRANT = (cp_grant_id_t) id;
m_reply.m_type = CDEV_REPLY;
m_reply.CDEV_STATUS = r;
m_reply.CDEV_ID = id;
if ((r = asynsend3(endpt, &m_reply, AMF_NOREPLY)) != OK)
printf("chardriver_reply_task: send to %d failed: %d\n", endpt, r);
@ -155,9 +163,9 @@ void chardriver_reply_select(endpoint_t endpt, devminor_t minor, int r)
memset(&m_reply, 0, sizeof(m_reply));
m_reply.m_type = DEV_SEL_REPL2;
m_reply.DEV_MINOR = minor;
m_reply.DEV_SEL_OPS = r;
m_reply.m_type = CDEV_SEL2_REPLY;
m_reply.CDEV_MINOR = minor;
m_reply.CDEV_STATUS = r;
if ((r = asynsend3(endpt, &m_reply, AMF_NOREPLY)) != OK)
printf("chardriver_reply_select: send to %d failed: %d\n", endpt, r);
@ -194,15 +202,20 @@ static void chardriver_reply(message *mess, int ipc_status, int r)
*/
if (r == EDONTREPLY) {
switch (mess->m_type) {
case DEV_READ_S:
case DEV_WRITE_S:
case DEV_IOCTL_S:
#if 0 /* XXX doesn't match lwip's model, disabled for now */
if (mess->FLAGS & FLG_OP_NONBLOCK)
case CDEV_READ:
case CDEV_WRITE:
case CDEV_IOCTL:
/* FIXME: we should be able to check CDEV_FLAGS against
* CDEV_NONBLOCK here, but in practice, several drivers do not
* send a reply through this path (eg TTY) or simply do not
* implement nonblocking calls properly (eg audio, LWIP).
*/
#if 0
if (mess->CDEV_FLAGS & CDEV_NONBLOCK)
panic("chardriver: cannot suspend nonblocking I/O");
#endif
/*fall-through*/
case CANCEL:
case CDEV_CANCEL:
return; /* alright */
default:
panic("chardriver: cannot suspend request %d", mess->m_type);
@ -222,32 +235,21 @@ static void chardriver_reply(message *mess, int ipc_status, int r)
memset(&reply_mess, 0, sizeof(reply_mess));
switch (mess->m_type) {
case DEV_OPEN:
reply_mess.m_type = DEV_OPEN_REPL;
reply_mess.REP_ENDPT = mess->USER_ENDPT;
reply_mess.REP_STATUS = r;
case CDEV_OPEN:
case CDEV_CLOSE:
case CDEV_READ:
case CDEV_WRITE:
case CDEV_IOCTL:
case CDEV_CANCEL: /* For cancel, this is a reply to the original request! */
reply_mess.m_type = CDEV_REPLY;
reply_mess.CDEV_STATUS = r;
reply_mess.CDEV_ID = mess->CDEV_ID;
break;
case DEV_CLOSE:
reply_mess.m_type = DEV_CLOSE_REPL;
reply_mess.REP_ENDPT = mess->USER_ENDPT;
reply_mess.REP_STATUS = r;
break;
case DEV_READ_S:
case DEV_WRITE_S:
case DEV_IOCTL_S:
case CANCEL: /* For CANCEL, this is a reply to the original request! */
reply_mess.m_type = DEV_REVIVE;
reply_mess.REP_ENDPT = mess->USER_ENDPT;
reply_mess.REP_IO_GRANT = (cp_grant_id_t) mess->IO_GRANT;
reply_mess.REP_STATUS = r;
break;
case DEV_SELECT:
reply_mess.m_type = DEV_SEL_REPL1;
reply_mess.DEV_MINOR = mess->DEVICE;
reply_mess.DEV_SEL_OPS = r;
case CDEV_SELECT:
reply_mess.m_type = CDEV_SEL1_REPLY;
reply_mess.CDEV_MINOR = mess->CDEV_MINOR;
reply_mess.CDEV_STATUS = r;
break;
default:
@ -272,15 +274,18 @@ static int do_open(struct chardriver *cdp, message *m_ptr)
return OK;
/* Call the open hook. */
minor = m_ptr->DEVICE;
access = m_ptr->COUNT;
user_endpt = m_ptr->USER_ENDPT;
minor = m_ptr->CDEV_MINOR;
access = m_ptr->CDEV_ACCESS;
user_endpt = m_ptr->CDEV_USER;
r = cdp->cdr_open(minor, access, user_endpt);
/* If the device has been cloned, mark the new minor as open too. */
if (r >= 0 && !is_open_dev(r)) /* XXX FIXME */
set_open_dev(r);
if (r >= 0 && (r & CDEV_CLONED)) {
minor = r & ~(CDEV_CLONED | CDEV_CTTY);
if (!is_open_dev(minor))
set_open_dev(minor);
}
return r;
}
@ -298,7 +303,7 @@ static int do_close(struct chardriver *cdp, message *m_ptr)
return OK;
/* Call the close hook. */
minor = m_ptr->DEVICE;
minor = m_ptr->CDEV_MINOR;
return cdp->cdr_close(minor);
}
@ -318,13 +323,13 @@ static int do_transfer(struct chardriver *cdp, message *m_ptr, int do_write)
cdev_id_t id;
ssize_t r;
minor = m_ptr->DEVICE;
position = make64(m_ptr->POSITION, m_ptr->HIGHPOS);
minor = m_ptr->CDEV_MINOR;
position = make64(m_ptr->CDEV_POS_LO, m_ptr->CDEV_POS_HI);
endpt = m_ptr->m_source;
grant = (cp_grant_id_t) m_ptr->IO_GRANT;
size = m_ptr->COUNT;
flags = m_ptr->FLAGS;
id = (cdev_id_t) m_ptr->IO_GRANT;
grant = (cp_grant_id_t) m_ptr->CDEV_GRANT;
size = m_ptr->CDEV_COUNT;
flags = m_ptr->CDEV_FLAGS;
id = m_ptr->CDEV_ID;
/* Call the read/write hook, if the appropriate one is in place. */
if (!do_write && cdp->cdr_read != NULL)
@ -355,13 +360,13 @@ static int do_ioctl(struct chardriver *cdp, message *m_ptr)
return ENOTTY;
/* Call the ioctl hook. */
minor = m_ptr->DEVICE;
request = m_ptr->REQUEST;
minor = m_ptr->CDEV_MINOR;
request = m_ptr->CDEV_REQUEST;
endpt = m_ptr->m_source;
grant = (cp_grant_id_t) m_ptr->IO_GRANT;
flags = m_ptr->FLAGS;
user_endpt = (endpoint_t) m_ptr->POSITION;
id = (cdev_id_t) m_ptr->IO_GRANT;
grant = m_ptr->CDEV_GRANT;
flags = m_ptr->CDEV_FLAGS;
user_endpt = m_ptr->CDEV_USER;
id = m_ptr->CDEV_ID;
return cdp->cdr_ioctl(minor, request, endpt, grant, flags, user_endpt, id);
}
@ -383,9 +388,9 @@ static int do_cancel(struct chardriver *cdp, message *m_ptr)
return EDONTREPLY;
/* Call the cancel hook. */
minor = m_ptr->DEVICE;
minor = m_ptr->CDEV_MINOR;
endpt = m_ptr->m_source;
id = (cdev_id_t) m_ptr->IO_GRANT;
id = m_ptr->CDEV_ID;
return cdp->cdr_cancel(minor, endpt, id);
}
@ -405,8 +410,8 @@ static int do_select(struct chardriver *cdp, message *m_ptr)
return EBADF;
/* Call the select hook. */
minor = m_ptr->DEV_MINOR;
ops = m_ptr->DEV_SEL_OPS;
minor = m_ptr->CDEV_MINOR;
ops = m_ptr->CDEV_OPS;
endpt = m_ptr->m_source;
return cdp->cdr_select(minor, ops, endpt);
@ -473,24 +478,24 @@ void chardriver_process(struct chardriver *cdp, message *m_ptr, int ipc_status)
/* We might get spurious requests if the driver has been restarted. Deny any
* requests on devices that have not previously been opened.
*/
if (IS_DEV_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->DEVICE)) {
if (IS_CDEV_RQ(m_ptr->m_type) && !is_open_dev(m_ptr->CDEV_MINOR)) {
/* Ignore spurious requests for unopened devices. */
if (m_ptr->m_type != DEV_OPEN)
if (m_ptr->m_type != CDEV_OPEN)
return; /* do not send a reply */
/* Mark the device as opened otherwise. */
set_open_dev(m_ptr->DEVICE);
set_open_dev(m_ptr->CDEV_MINOR);
}
/* Call the appropriate function(s) for this request. */
switch (m_ptr->m_type) {
case DEV_OPEN: r = do_open(cdp, m_ptr); break;
case DEV_CLOSE: r = do_close(cdp, m_ptr); break;
case DEV_READ_S: r = do_transfer(cdp, m_ptr, FALSE); break;
case DEV_WRITE_S: r = do_transfer(cdp, m_ptr, TRUE); break;
case DEV_IOCTL_S: r = do_ioctl(cdp, m_ptr); break;
case CANCEL: r = do_cancel(cdp, m_ptr); break;
case DEV_SELECT: r = do_select(cdp, m_ptr); break;
case CDEV_OPEN: r = do_open(cdp, m_ptr); break;
case CDEV_CLOSE: r = do_close(cdp, m_ptr); break;
case CDEV_READ: r = do_transfer(cdp, m_ptr, FALSE); break;
case CDEV_WRITE: r = do_transfer(cdp, m_ptr, TRUE); break;
case CDEV_IOCTL: r = do_ioctl(cdp, m_ptr); break;
case CDEV_CANCEL: r = do_cancel(cdp, m_ptr); break;
case CDEV_SELECT: r = do_select(cdp, m_ptr); break;
default:
if (cdp->cdr_other)
cdp->cdr_other(m_ptr, ipc_status);

View file

@ -261,7 +261,7 @@ struct socket * get_unused_sock(void)
static int socket_request_socket(struct socket * sock, struct sock_req * req)
{
int r, blocking = req->flags & FLG_OP_NONBLOCK ? 0 : 1;
int r, blocking = (req->flags & CDEV_NONBLOCK) ? 0 : 1;
switch (req->type) {
case SOCK_REQ_READ:
@ -292,7 +292,12 @@ static int socket_request_socket(struct socket * sock, struct sock_req * req)
static int netsock_open(devminor_t minor, int UNUSED(access),
endpoint_t UNUSED(user_endpt))
{
return socket_open(minor);
int r;
if ((r = socket_open(minor)) < 0)
return r;
return CDEV_CLONED | r;
}
static int netsock_close(devminor_t minor)
@ -505,26 +510,26 @@ int generic_op_select(struct socket * sock, unsigned int sel)
/* in this case any operation would block, no error */
if (sock->flags & SOCK_FLG_OP_PENDING) {
if (sel & SEL_NOTIFY) {
if (sel & SEL_RD)
if (sel & CDEV_NOTIFY) {
if (sel & CDEV_OP_RD)
sock->flags |= SOCK_FLG_SEL_READ;
if (sel & SEL_WR)
if (sel & CDEV_OP_WR)
sock->flags |= SOCK_FLG_SEL_WRITE;
/* FIXME we do not monitor error */
}
return 0;
}
if (sel & SEL_RD) {
if (sel & CDEV_OP_RD) {
if (sock->recv_head)
retsel |= SEL_RD;
else if (sel & SEL_NOTIFY)
retsel |= CDEV_OP_RD;
else if (sel & CDEV_NOTIFY)
sock->flags |= SOCK_FLG_SEL_READ;
}
/* FIXME generic packet socket never blocks on write */
if (sel & SEL_WR)
retsel |= SEL_WR;
/* FIXME SEL_ERR is ignored, we do not generate exceptions */
if (sel & CDEV_OP_WR)
retsel |= CDEV_OP_WR;
/* FIXME CDEV_OP_ERR is ignored, we do not generate exceptions */
return retsel;
}
@ -545,7 +550,7 @@ int generic_op_select_reply(struct socket * sock)
}
if (sock->flags & SOCK_FLG_SEL_READ && sock->recv_head)
sel |= SEL_RD;
sel |= CDEV_OP_RD;
if (sel)
sock->flags &= ~(SOCK_FLG_SEL_WRITE | SOCK_FLG_SEL_READ |

View file

@ -146,7 +146,7 @@ static int sr_open(devminor_t minor, int UNUSED(access),
return fd;
}
sr_fd->srf_fd= fd;
return i; /* cloned! */
return CDEV_CLONED | i;
}
static int sr_close(devminor_t minor)
@ -214,7 +214,7 @@ static int sr_rwio(sr_req_t *req)
assert(sr_fd->srf_flags & susp_flag);
assert(*q_head_ptr);
if (m->mq_req.srr_flags & FLG_OP_NONBLOCK) {
if (m->mq_req.srr_flags & CDEV_NONBLOCK) {
mq_free(m);
return EAGAIN;
}
@ -264,7 +264,7 @@ static int sr_rwio(sr_req_t *req)
(printf("r= %d\n", r), 0));
if (r == SUSPEND) {
sr_fd->srf_flags |= susp_flag;
if (m->mq_req.srr_flags & FLG_OP_NONBLOCK) {
if (m->mq_req.srr_flags & CDEV_NONBLOCK) {
r= sr_cancel(m->mq_req.srr_minor, m->mq_req.srr_endpt,
m->mq_req.srr_id);
assert(r == EDONTREPLY); /* head of the queue */
@ -442,19 +442,19 @@ static int sr_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
sr_fd->srf_select_proc= endpt;
i_ops= 0;
if (ops & SEL_RD) i_ops |= SR_SELECT_READ;
if (ops & SEL_WR) i_ops |= SR_SELECT_WRITE;
if (ops & SEL_ERR) i_ops |= SR_SELECT_EXCEPTION;
if (!(ops & SEL_NOTIFY)) i_ops |= SR_SELECT_POLL;
if (ops & CDEV_OP_RD) i_ops |= SR_SELECT_READ;
if (ops & CDEV_OP_WR) i_ops |= SR_SELECT_WRITE;
if (ops & CDEV_OP_ERR) i_ops |= SR_SELECT_EXCEPTION;
if (!(ops & CDEV_NOTIFY)) i_ops |= SR_SELECT_POLL;
r= (*sr_fd->srf_select)(sr_fd->srf_fd, i_ops);
if (r < 0) {
m_ops= r;
} else {
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;
if (r & SR_SELECT_READ) m_ops |= CDEV_OP_RD;
if (r & SR_SELECT_WRITE) m_ops |= CDEV_OP_WR;
if (r & SR_SELECT_EXCEPTION) m_ops |= CDEV_OP_ERR;
}
return m_ops;
@ -657,9 +657,9 @@ static void sr_select_res(int fd, unsigned ops)
sr_fd= &sr_fd_table[fd];
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;
if (ops & SR_SELECT_READ) m_ops |= CDEV_OP_RD;
if (ops & SR_SELECT_WRITE) m_ops |= CDEV_OP_WR;
if (ops & SR_SELECT_EXCEPTION) m_ops |= CDEV_OP_ERR;
chardriver_reply_select(sr_fd->srf_select_proc, fd, m_ops);
}

View file

@ -76,7 +76,6 @@ static char * dmap_style(int dev_style)
case STYLE_DEV: return "STYLE_DEV";
case STYLE_TTY: return "STYLE_TTY";
case STYLE_CTTY: return "STYLE_CTTY";
case STYLE_CLONE: return "STYLE_CLONE";
default: return "UNKNOWN";
}
}

View file

@ -1082,22 +1082,22 @@ static int tcp_op_select(struct socket * sock, unsigned int sel)
/* in this case any operation would block, no error */
if (sock->flags & SOCK_FLG_OP_PENDING) {
debug_tcp_print("SOCK_FLG_OP_PENDING");
if (sel & SEL_NOTIFY) {
if (sel & SEL_RD) {
if (sel & CDEV_NOTIFY) {
if (sel & CDEV_OP_RD) {
sock->flags |= SOCK_FLG_SEL_READ;
debug_tcp_print("monitor read");
}
if (sel & SEL_WR) {
if (sel & CDEV_OP_WR) {
sock->flags |= SOCK_FLG_SEL_WRITE;
debug_tcp_print("monitor write");
}
if (sel & SEL_ERR)
if (sel & CDEV_OP_ERR)
sock->flags |= SOCK_FLG_SEL_ERROR;
}
return 0;
}
if (sel & SEL_RD) {
if (sel & CDEV_OP_RD) {
/*
* If recv_head is not NULL we can either read or accept a
* connection which is the same for select()
@ -1105,38 +1105,38 @@ static int tcp_op_select(struct socket * sock, unsigned int sel)
if (sock->pcb) {
if (sock->recv_head &&
!(sock->flags & SOCK_FLG_OP_WRITING))
retsel |= SEL_RD;
retsel |= CDEV_OP_RD;
else if (!(sock->flags & SOCK_FLG_OP_LISTENING) &&
((struct tcp_pcb *) sock->pcb)->state != ESTABLISHED)
retsel |= SEL_RD;
else if (sel & SEL_NOTIFY) {
retsel |= CDEV_OP_RD;
else if (sel & CDEV_NOTIFY) {
sock->flags |= SOCK_FLG_SEL_READ;
debug_tcp_print("monitor read");
}
} else
retsel |= SEL_RD; /* not connected read does not block */
} else /* not connected read does not block */
retsel |= CDEV_OP_RD;
}
if (sel & SEL_WR) {
if (sel & CDEV_OP_WR) {
if (sock->pcb) {
if (((struct tcp_pcb *) sock->pcb)->state == ESTABLISHED)
retsel |= SEL_WR;
else if (sel & SEL_NOTIFY) {
retsel |= CDEV_OP_WR;
else if (sel & CDEV_NOTIFY) {
sock->flags |= SOCK_FLG_SEL_WRITE;
debug_tcp_print("monitor write");
}
} else
retsel |= SEL_WR; /* not connected write does not block */
} else /* not connected write does not block */
retsel |= CDEV_OP_WR;
}
if (retsel & SEL_RD) {
if (retsel & CDEV_OP_RD) {
debug_tcp_print("read won't block");
}
if (retsel & SEL_WR) {
if (retsel & CDEV_OP_WR) {
debug_tcp_print("write won't block");
}
/* we only monitor if errors will happen in the future */
if (sel & SEL_ERR && sel & SEL_NOTIFY)
if (sel & CDEV_OP_ERR && sel & CDEV_NOTIFY)
sock->flags |= SOCK_FLG_SEL_ERROR;
return retsel;
@ -1160,7 +1160,7 @@ static int tcp_op_select_reply(struct socket * sock)
(!(sock->flags & SOCK_FLG_OP_LISTENING) &&
((struct tcp_pcb *) sock->pcb)->state !=
ESTABLISHED)) {
sel |= SEL_RD;
sel |= CDEV_OP_RD;
debug_tcp_print("read won't block");
}
}
@ -1169,7 +1169,7 @@ static int tcp_op_select_reply(struct socket * sock)
(sock->pcb == NULL ||
((struct tcp_pcb *) sock->pcb)->state ==
ESTABLISHED)) {
sel |= SEL_WR;
sel |= CDEV_OP_WR;
debug_tcp_print("write won't block");
}

View file

@ -12,10 +12,9 @@
*
* Overview
*
* The interface to unix domain sockets is similar to the
* the interface to network sockets. There is a character
* device (/dev/uds) that uses STYLE_CLONE and this server
* is a 'driver' for that device.
* The interface to unix domain sockets is similar to the interface to network
* sockets. There is a character device (/dev/uds) and this server is a
* 'driver' for that device.
*/
#define DEBUG 0
@ -190,7 +189,7 @@ static int uds_open(devminor_t UNUSED(orig_minor), int access,
/* Process the response */
uds_fd_table[minor].inode_nr = fs_m_out.RES_INODE_NR;
return minor; /* cloned! */
return CDEV_CLONED | minor;
}
static int uds_close(devminor_t minor)
@ -271,40 +270,40 @@ static int uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
return EINVAL;
}
watch = (ops & SEL_NOTIFY);
ops &= (SEL_RD | SEL_WR | SEL_ERR);
watch = (ops & CDEV_NOTIFY);
ops &= (CDEV_OP_RD | CDEV_OP_WR | CDEV_OP_ERR);
ready_ops = 0;
/* check if there is data available to read */
if (ops & SEL_RD) {
if (ops & CDEV_OP_RD) {
bytes = uds_perform_read(minor, NONE, GRANT_INVALID, 1, 1);
if (bytes > 0) {
/* there is data in the pipe for us to read */
ready_ops |= SEL_RD;
ready_ops |= CDEV_OP_RD;
} else if (uds_fd_table[minor].listening == 1) {
/* check for pending connections */
for (i = 0; i < uds_fd_table[minor].backlog_size; i++)
{
if (uds_fd_table[minor].backlog[i] != -1) {
ready_ops |= SEL_RD;
ready_ops |= CDEV_OP_RD;
break;
}
}
} else if (bytes != SUSPEND) {
ready_ops |= SEL_RD;
ready_ops |= CDEV_OP_RD;
}
}
/* check if we can write without blocking */
if (ops & SEL_WR) {
if (ops & CDEV_OP_WR) {
bytes = uds_perform_write(minor, NONE, GRANT_INVALID, PIPE_BUF,
1);
if (bytes != 0 && bytes != SUSPEND) {
/* There is room to write or there is an error
* condition.
*/
ready_ops |= SEL_WR;
ready_ops |= CDEV_OP_WR;
}
}
@ -439,12 +438,12 @@ static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt,
* peer to minor); if the peer wants to know about write being possible
* and it doesn't know about it already, then let the peer know.
*/
if (peer != -1 && (uds_fd_table[peer].sel_ops & SEL_WR) &&
if (peer != -1 && (uds_fd_table[peer].sel_ops & CDEV_OP_WR) &&
(uds_fd_table[minor].size+uds_fd_table[minor].pos + 1 < PIPE_BUF)){
/* a write on peer is possible now */
chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer,
SEL_WR);
uds_fd_table[peer].sel_ops &= ~SEL_WR;
CDEV_OP_WR);
uds_fd_table[peer].sel_ops &= ~CDEV_OP_WR;
}
return fs_m_out.RES_NBYTES; /* return number of bytes read */
@ -604,11 +603,12 @@ static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
* data ready to read and it doesn't know about it already, then let
* the peer know we have data for it.
*/
if ((uds_fd_table[peer].sel_ops & SEL_RD) && fs_m_out.RES_NBYTES > 0) {
if ((uds_fd_table[peer].sel_ops & CDEV_OP_RD) &&
fs_m_out.RES_NBYTES > 0) {
/* a read on peer is possible now */
chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer,
SEL_RD);
uds_fd_table[peer].sel_ops &= ~SEL_RD;
CDEV_OP_RD);
uds_fd_table[peer].sel_ops &= ~CDEV_OP_RD;
}
return fs_m_out.RES_NBYTES; /* return number of bytes written */
@ -644,7 +644,7 @@ static ssize_t uds_read(devminor_t minor, u64_t position, endpoint_t endpt,
uds_fd_table[minor].susp_id = id;
/* If the call wasn't supposed to block, cancel immediately. */
if (flags & FLG_OP_NONBLOCK) {
if (flags & CDEV_NONBLOCK) {
uds_cancel(minor, endpt, id);
rc = EAGAIN;
@ -684,7 +684,7 @@ static ssize_t uds_write(devminor_t minor, u64_t position, endpoint_t endpt,
uds_fd_table[minor].susp_id = id;
/* If the call wasn't supposed to block, cancel immediately. */
if (flags & FLG_OP_NONBLOCK) {
if (flags & CDEV_NONBLOCK) {
uds_cancel(minor, endpt, id);
rc = EAGAIN;
@ -730,7 +730,7 @@ static int uds_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
uds_fd_table[minor].susp_id = id;
/* If the call wasn't supposed to block, cancel immediately. */
if (flags & FLG_OP_NONBLOCK) {
if (flags & CDEV_NONBLOCK) {
uds_cancel(minor, endpt, id);
rc = EAGAIN;

View file

@ -42,7 +42,7 @@ int main(int argc, char *argv[])
get_work(&pfs_m_in, &ipc_status);
/* If this is a UDS device request, process it and continue. */
if (IS_DEV_RQ(pfs_m_in.m_type)) {
if (IS_CDEV_RQ(pfs_m_in.m_type)) {
uds_request(&pfs_m_in, ipc_status);
continue;

View file

@ -464,7 +464,7 @@ static int do_connect(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
}
/* see if the server is blocked on select() */
if (uds_fd_table[i].sel_ops & SEL_RD) {
if (uds_fd_table[i].sel_ops & CDEV_OP_RD) {
/* if the server wants to know about
* data ready to read and it doesn't
* doesn't know about it already, then
@ -473,9 +473,9 @@ static int do_connect(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
*/
chardriver_reply_select(
uds_fd_table[i].sel_endpt, i,
SEL_RD);
CDEV_OP_RD);
uds_fd_table[i].sel_ops &= ~SEL_RD;
uds_fd_table[i].sel_ops &= ~CDEV_OP_RD;
}
/* we found our server */

View file

@ -179,7 +179,7 @@ struct uds_fd {
*/
endpoint_t sel_endpt;
/* Options (SEL_RD, SEL_WR, SEL_ERR) that are requested. */
/* Options (CDEV_OP_RD,WR,ERR) that are requested. */
unsigned int sel_ops;
};

View file

@ -48,7 +48,7 @@ struct boot_image_dev boot_image_dev_table[] = {
{ 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_DEV, STYLE_NDEV },
{ PFS_PROC_NR, SRV_DF, UDS_MAJOR, STYLE_CLONE,STYLE_NDEV },
{ PFS_PROC_NR, SRV_DF, UDS_MAJOR, STYLE_DEV, STYLE_NDEV },
{ DEFAULT_BOOT_NR, SRV_DF, 0, STYLE_NDEV, STYLE_NDEV } /* default
* entry
*/

View file

@ -93,7 +93,7 @@ int drv_sendrec(endpoint_t drv_e, message *reqmp)
panic("driver endpoint %d invalid", drv_e);
lock_dmap(dp);
if (dp->dmap_servicing != NONE)
if (dp->dmap_servicing != INVALID_THREAD)
panic("driver locking inconsistency");
dp->dmap_servicing = self->w_tid;
self->w_task = drv_e;
@ -108,7 +108,7 @@ int drv_sendrec(endpoint_t drv_e, message *reqmp)
util_stacktrace();
}
dp->dmap_servicing = NONE;
dp->dmap_servicing = INVALID_THREAD;
self->w_task = NONE;
self->w_drv_sendrec = NULL;
unlock_dmap(dp);

View file

@ -26,14 +26,7 @@
/* test if the process is blocked on something */
#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))
#define DUP_MASK 0100 /* mask to distinguish dup2 from dup */
#define LOOK_UP 0 /* tells search_dir to lookup string */
#define ENTER 1 /* tells search_dir to make dir entry */
#define DELETE 2 /* tells search_dir to delete entry */
#define IS_EMPTY 3 /* tells search_dir to ret. OK or ENOTEMPTY */
#define INVALID_THREAD ((thread_t) -1) /* known-invalid thread ID */
#define SYMLOOP 16
@ -43,4 +36,10 @@
*/
#define FSTYPE_MAX VFS_NAMELEN /* maximum file system type size */
/* possible select() operation types; read, write, errors */
#define SEL_RD CDEV_OP_RD
#define SEL_WR CDEV_OP_WR
#define SEL_ERR CDEV_OP_ERR
#define SEL_NOTIFY CDEV_NOTIFY /* not a real select operation */
#endif

View file

@ -2,24 +2,25 @@
* Special character files also require I/O. The routines for these are here.
*
* The entry points in this file are:
* dev_open: open a character device
* dev_close: close a character device
* cdev_reply: process the result of a character driver request
* bdev_open: open a block device
* bdev_close: close a block device
* bdev_reply: process the result of a block driver request
* dev_io: FS does a read or write on a device
* gen_opcl: generic call to a character driver to perform an open/close
* gen_io: generic call to a character driver to initiate I/O
* no_dev: open/close processing for devices that don't exist
* no_dev_io: i/o processing for devices that don't exist
* tty_opcl: perform tty-specific processing for open/close
* ctty_opcl: perform controlling-tty-specific processing for open/close
* ctty_io: perform controlling-tty-specific processing for I/O
* pm_setsid: perform VFS's side of setsid system call
* do_ioctl: perform the IOCTL system call
* dev_select: initiate a select call on a device
* dev_cancel: cancel an I/O request, blocking until it has been cancelled
* cdev_open: open a character device
* cdev_close: close a character device
* cdev_io: initiate a read, write, or ioctl to a character device
* cdev_select: initiate a select call on a device
* cdev_cancel: cancel an I/O request, blocking until it has been cancelled
* cdev_reply: process the result of a character driver request
* bdev_open: open a block device
* bdev_close: close a block device
* bdev_reply: process the result of a block driver request
* bdev_up: a block driver has been mapped in
* gen_opcl: generic call to a character driver to perform an open/close
* gen_io: generic call to a character driver to initiate I/O
* no_dev: open/close processing for devices that don't exist
* no_dev_io: i/o processing for devices that don't exist
* tty_opcl: perform tty-specific processing for open/close
* ctty_opcl: perform controlling-tty-specific processing for open/close
* ctty_io: perform controlling-tty-specific processing for I/O
* pm_setsid: perform VFS's side of setsid system call
* do_ioctl: perform the IOCTL system call
*/
#include "fs.h"
@ -44,15 +45,10 @@ static int block_io(endpoint_t driver_e, message *mess_ptr);
static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op,
void *buf, unsigned long size);
static int dummyproc;
/*===========================================================================*
* dev_open *
* cdev_open *
*===========================================================================*/
int dev_open(
dev_t dev, /* device to open */
int flags /* mode bits and flags */
)
int cdev_open(dev_t dev, int flags)
{
/* Open a character device. */
devmajor_t major_dev;
@ -65,17 +61,15 @@ int dev_open(
major_dev = major(dev);
if (major_dev < 0 || major_dev >= NR_DEVICES) return(ENXIO);
if (dmap[major_dev].dmap_driver == NONE) return(ENXIO);
r = (*dmap[major_dev].dmap_opcl)(DEV_OPEN, dev, fp->fp_endpoint, flags);
r = (*dmap[major_dev].dmap_opcl)(CDEV_OPEN, dev, fp->fp_endpoint, flags);
return(r);
}
/*===========================================================================*
* dev_close *
* cdev_close *
*===========================================================================*/
int dev_close(
dev_t dev /* device to close */
)
int cdev_close(dev_t dev)
{
/* Close a character device. */
devmajor_t major_dev;
@ -85,7 +79,7 @@ int dev_close(
major_dev = major(dev);
if (major_dev < 0 || major_dev >= NR_DEVICES) return(ENXIO);
if (dmap[major_dev].dmap_driver == NONE) return(ENXIO);
r = (*dmap[major_dev].dmap_opcl)(DEV_CLOSE, dev, fp->fp_endpoint, 0);
r = (*dmap[major_dev].dmap_opcl)(CDEV_CLOSE, dev, fp->fp_endpoint, 0);
return(r);
}
@ -204,30 +198,6 @@ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, unsigned long req,
}
/*===========================================================================*
* find_suspended_ep *
*===========================================================================*/
static endpoint_t find_suspended_ep(endpoint_t driver, cp_grant_id_t g)
{
/* A process is suspended on a driver for which VFS issued a grant. Find out
* which process it was.
*/
struct fproc *rfp;
for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
if(rfp->fp_pid == PID_FREE)
continue;
if (rfp->fp_task == driver && rfp->fp_grant == g) {
assert(!fp_is_blocked(rfp) ||
rfp->fp_blocked_on == FP_BLOCKED_ON_OTHER);
return(rfp->fp_endpoint);
}
}
return(NONE);
}
/*===========================================================================*
* make_grant *
*===========================================================================*/
@ -240,13 +210,13 @@ static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op,
size_t size;
switch (op) {
case DEV_READ_S:
case DEV_WRITE_S:
case CDEV_READ:
case CDEV_WRITE:
gid = cpf_grant_magic(driver_e, user_e, (vir_bytes) buf,
(size_t) bytes, op == DEV_READ_S ? CPF_WRITE : CPF_READ);
(size_t) bytes, op == CDEV_READ ? CPF_WRITE : CPF_READ);
break;
case DEV_IOCTL_S:
case CDEV_IOCTL:
case BDEV_IOCTL:
/* For IOCTLs, the bytes parameter contains the IOCTL request.
* This request encodes the requested access method and buffer size.
@ -259,8 +229,9 @@ static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op,
else
size = _MINIX_IOCTL_SIZE(bytes);
/* Grant access to the buffer even if no I/O happens with the ioctl, in
* order to disambiguate requests with DEV_IOCTL_S.
/* Grant access to the buffer even if no I/O happens with the ioctl,
* although now that we no longer identify responses based on grants,
* this is not strictly necessary.
*/
gid = cpf_grant_magic(driver_e, user_e, (vir_bytes) buf, size, access);
break;
@ -277,27 +248,27 @@ static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op,
/*===========================================================================*
* dev_io *
* cdev_io *
*===========================================================================*/
int dev_io(
int op, /* DEV_READ_S, DEV_WRITE_S, or DEV_IOCTL_S */
int cdev_io(
int op, /* CDEV_READ, CDEV_WRITE, or CDEV_IOCTL */
dev_t dev, /* major-minor device number */
endpoint_t proc_e, /* in whose address space is buf? */
void *buf, /* virtual address of the buffer */
off_t pos, /* byte position */
size_t bytes, /* how many bytes to transfer */
unsigned long bytes, /* how many bytes to transfer, or request */
int flags /* special flags, like O_NONBLOCK */
)
{
/* Initiate a read, write, or ioctl to a device. */
/* Initiate a read, write, or ioctl to a character device. */
struct dmap *dp;
message dev_mess;
cp_grant_id_t gid;
devmajor_t major_dev;
devminor_t minor_dev;
int r;
int r, slot;
assert(op == DEV_READ_S || op == DEV_WRITE_S || op == DEV_IOCTL_S);
assert(op == CDEV_READ || op == CDEV_WRITE || op == CDEV_IOCTL);
/* Determine task dmap. */
major_dev = major(dev);
@ -307,7 +278,7 @@ int dev_io(
/* See if driver is roughly valid. */
if (dp->dmap_driver == NONE) return(ENXIO);
if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
if(isokendpt(dp->dmap_driver, &slot) != OK) {
printf("VFS: dev_io: old driver for major %x (%d)\n", major_dev,
dp->dmap_driver);
return(ENXIO);
@ -318,21 +289,21 @@ int dev_io(
/* Set up the rest of the message that will be sent to the driver. */
memset(&dev_mess, 0, sizeof(dev_mess));
dev_mess.m_type = op;
dev_mess.DEVICE = minor_dev;
if (op == DEV_IOCTL_S) {
dev_mess.REQUEST = bytes;
dev_mess.POSITION = proc_e;
dev_mess.m_type = op;
dev_mess.CDEV_MINOR = minor_dev;
if (op == CDEV_IOCTL) {
dev_mess.CDEV_REQUEST = bytes;
dev_mess.CDEV_USER = proc_e;
} else {
dev_mess.POSITION = ex64lo(pos);
dev_mess.COUNT = bytes;
dev_mess.CDEV_POS_LO = ex64lo(pos);
dev_mess.CDEV_POS_HI = ex64hi(pos);
dev_mess.CDEV_COUNT = (size_t) bytes;
}
dev_mess.HIGHPOS = ex64hi(pos);
dev_mess.USER_ENDPT = VFS_PROC_NR;
dev_mess.IO_GRANT = (void *) gid;
dev_mess.FLAGS = 0;
dev_mess.CDEV_ID = proc_e;
dev_mess.CDEV_GRANT = gid;
dev_mess.CDEV_FLAGS = 0;
if (flags & O_NONBLOCK)
dev_mess.FLAGS |= FLG_OP_NONBLOCK;
dev_mess.CDEV_FLAGS |= CDEV_NONBLOCK;
/* Send the request to the driver. */
r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
@ -347,7 +318,6 @@ int dev_io(
wait_for(dp->dmap_driver);
assert(!GRANT_VALID(fp->fp_grant));
fp->fp_grant = gid; /* revoke this when unsuspended. */
fp->fp_ioproc = VFS_PROC_NR;
return SUSPEND;
}
@ -374,14 +344,14 @@ static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor)
r = req_newnode(PFS_PROC_NR, fp->fp_effuid, fp->fp_effgid,
ALL_MODES | I_CHAR_SPECIAL, dev, &res);
if (r != OK) {
(void) gen_opcl(DEV_CLOSE, dev, proc_e, 0);
(void) gen_opcl(CDEV_CLOSE, dev, proc_e, 0);
return r;
}
/* Drop old node and use the new values */
if ((vp = get_free_vnode()) == NULL) {
req_putnode(PFS_PROC_NR, res.inode_nr, 1); /* is this right? */
(void) gen_opcl(DEV_CLOSE, dev, proc_e, 0);
(void) gen_opcl(CDEV_CLOSE, dev, proc_e, 0);
return(err_code);
}
lock_vnode(vp, VNODE_OPCL);
@ -409,7 +379,7 @@ static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor)
* gen_opcl *
*===========================================================================*/
int gen_opcl(
int op, /* operation, DEV_OPEN or DEV_CLOSE */
int op, /* operation, CDEV_OPEN or CDEV_CLOSE */
dev_t dev, /* device to open or close */
endpoint_t proc_e, /* process to open/close for */
int flags /* mode bits and flags */
@ -417,10 +387,10 @@ int gen_opcl(
{
/* Called from the dmap struct on opens & closes of special files.*/
devmajor_t major_dev;
devminor_t minor_dev;
devminor_t minor_dev, new_minor;
struct dmap *dp;
message dev_mess;
int r;
int r, r2;
/* Determine task dmap. */
major_dev = major(dev);
@ -435,9 +405,15 @@ int gen_opcl(
memset(&dev_mess, 0, sizeof(dev_mess));
dev_mess.m_type = op;
dev_mess.DEVICE = minor_dev;
dev_mess.USER_ENDPT = proc_e;
dev_mess.COUNT = flags;
dev_mess.CDEV_MINOR = minor_dev;
dev_mess.CDEV_ID = proc_e;
if (op == CDEV_OPEN) {
dev_mess.CDEV_USER = proc_e;
dev_mess.CDEV_ACCESS = 0;
if (flags & R_BIT) dev_mess.CDEV_ACCESS |= CDEV_R_BIT;
if (flags & W_BIT) dev_mess.CDEV_ACCESS |= CDEV_W_BIT;
if (flags & O_NOCTTY) dev_mess.CDEV_ACCESS |= CDEV_NOCTTY;
}
/* Call the task. */
r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
@ -454,15 +430,33 @@ int gen_opcl(
self->w_task = NONE;
self->w_drv_sendrec = NULL;
r = dev_mess.CDEV_STATUS;
/* Some devices need special processing upon open. Such a device is "cloned",
* i.e. on a succesful open it is replaced by a new device with a new unique
* minor device number. This new device number identifies a new object (such
* as a new network connection) that has been allocated within a task.
*/
if (op == CDEV_OPEN && r >= 0) {
if (r & CDEV_CLONED) {
new_minor = r & ~(CDEV_CLONED | CDEV_CTTY);
r &= CDEV_CTTY;
if ((r2 = cdev_clone(dev, proc_e, new_minor)) < 0)
r = r2;
} else
r &= CDEV_CTTY;
/* Upon success, we now return either OK or CDEV_CTTY. */
}
/* Return the result from the driver. */
return(dev_mess.REP_STATUS);
return(r);
}
/*===========================================================================*
* tty_opcl *
*===========================================================================*/
int tty_opcl(
int op, /* operation, DEV_OPEN or DEV_CLOSE */
int op, /* operation, CDEV_OPEN or CDEV_CLOSE */
dev_t dev, /* device to open or close */
endpoint_t proc_e, /* process to open/close for */
int flags /* mode bits and flags */
@ -490,7 +484,7 @@ int tty_opcl(
r = gen_opcl(op, dev, proc_e, flags);
/* Did this call make the tty the controlling tty? */
if (r == 1) {
if (r >= 0 && (r & CDEV_CTTY)) {
fp->fp_tty = dev;
r = OK;
}
@ -503,7 +497,7 @@ int tty_opcl(
* ctty_opcl *
*===========================================================================*/
int ctty_opcl(
int op, /* operation, DEV_OPEN or DEV_CLOSE */
int op, /* operation, CDEV_OPEN or CDEV_CLOSE */
dev_t UNUSED(dev), /* device to open or close */
endpoint_t UNUSED(proc_e), /* process to open/close for */
int UNUSED(flags) /* mode bits and flags */
@ -569,8 +563,8 @@ int do_ioctl(message *UNUSED(m_out))
if (S_ISBLK(vp->v_mode))
r = bdev_ioctl(dev, who_e, ioctlrequest, argx);
else
r = dev_io(DEV_IOCTL_S, dev, who_e, argx, 0,
ioctlrequest, f->filp_flags);
r = cdev_io(CDEV_IOCTL, dev, who_e, argx, 0, ioctlrequest,
f->filp_flags);
}
unlock_filp(f);
@ -580,9 +574,9 @@ int do_ioctl(message *UNUSED(m_out))
/*===========================================================================*
* dev_select *
* cdev_select *
*===========================================================================*/
int dev_select(dev_t dev, int ops)
int cdev_select(dev_t dev, int ops)
{
/* Initiate a select call on a device. Return OK iff the request was sent. */
devmajor_t major_dev;
@ -598,9 +592,9 @@ int dev_select(dev_t dev, int ops)
memset(&dev_mess, 0, sizeof(dev_mess));
dev_mess.m_type = DEV_SELECT;
dev_mess.DEV_MINOR = minor_dev;
dev_mess.DEV_SEL_OPS = ops;
dev_mess.m_type = CDEV_SELECT;
dev_mess.CDEV_MINOR = minor_dev;
dev_mess.CDEV_OPS = ops;
/* Call the task. */
return (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
@ -608,9 +602,9 @@ int dev_select(dev_t dev, int ops)
/*===========================================================================*
* dev_cancel *
* cdev_cancel *
*===========================================================================*/
int dev_cancel(dev_t dev)
int cdev_cancel(dev_t dev)
{
/* Cancel an I/O request, blocking until it has been cancelled. */
devmajor_t major_dev;
@ -625,14 +619,9 @@ int dev_cancel(dev_t dev)
memset(&dev_mess, 0, sizeof(dev_mess));
dev_mess.m_type = CANCEL;
dev_mess.DEVICE = minor_dev;
dev_mess.USER_ENDPT = fp->fp_ioproc;
dev_mess.IO_GRANT = (char *) fp->fp_grant;
/* Tell driver R or W. Mode is from current call, not open. */
/* FIXME: ioctls also pass through here! */
dev_mess.COUNT = fp->fp_block_callnr == READ ? R_BIT : W_BIT;
dev_mess.m_type = CDEV_CANCEL;
dev_mess.CDEV_MINOR = minor_dev;
dev_mess.CDEV_ID = fp->fp_endpoint;
r = (*dp->dmap_io)(fp->fp_task, &dev_mess);
if (r != OK) return r; /* ctty_io returned an error? should be impossible */
@ -653,7 +642,7 @@ int dev_cancel(dev_t dev)
fp->fp_grant = GRANT_INVALID;
}
r = dev_mess.REP_STATUS;
r = dev_mess.CDEV_STATUS;
return (r == EAGAIN) ? EINTR : r;
}
@ -721,8 +710,6 @@ int gen_io(endpoint_t drv_e, message *mess_ptr)
if (r != OK) panic("VFS: asynsend in gen_io failed: %d", r);
/* Fake a SUSPEND */
mess_ptr->REP_STATUS = SUSPEND;
return(OK);
}
@ -740,6 +727,7 @@ int ctty_io(
* major/minor pair for /dev/tty itself.
*/
struct dmap *dp;
int slot;
if (fp->fp_tty == 0) {
/* No controlling tty present anymore, return an I/O error. */
@ -747,14 +735,14 @@ int ctty_io(
} else {
/* Substitute the controlling terminal device. */
dp = &dmap[major(fp->fp_tty)];
mess_ptr->DEVICE = minor(fp->fp_tty);
mess_ptr->CDEV_MINOR = minor(fp->fp_tty);
if (dp->dmap_driver == NONE) {
printf("FS: ctty_io: no driver for dev\n");
return(EIO);
}
if (isokendpt(dp->dmap_driver, &dummyproc) != OK) {
if (isokendpt(dp->dmap_driver, &slot) != OK) {
printf("VFS: ctty_io: old driver %d\n", dp->dmap_driver);
return(EIO);
}
@ -768,7 +756,7 @@ int ctty_io(
* no_dev *
*===========================================================================*/
int no_dev(
int UNUSED(op), /* operation, DEV_OPEN or DEV_CLOSE */
int UNUSED(op), /* operation, CDEV_OPEN or CDEV_CLOSE */
dev_t UNUSED(dev), /* device to open or close */
endpoint_t UNUSED(proc), /* process to open/close for */
int UNUSED(flags) /* mode bits and flags */
@ -788,35 +776,6 @@ int no_dev_io(endpoint_t UNUSED(proc), message *UNUSED(m))
return(EIO);
}
/*===========================================================================*
* clone_opcl *
*===========================================================================*/
int clone_opcl(
int op, /* operation, DEV_OPEN or DEV_CLOSE */
dev_t dev, /* device to open or close */
endpoint_t proc_e, /* process to open/close for */
int flags /* mode bits and flags */
)
{
/* Some devices need special processing upon open. Such a device is "cloned",
* i.e. on a succesful open it is replaced by a new device with a new unique
* minor device number. This new device number identifies a new object (such
* as a new network connection) that has been allocated within a task.
*/
int r;
r = gen_opcl(op, dev, proc_e, flags);
if (op == DEV_OPEN && r >= 0) {
if (r != minor(dev))
r = cdev_clone(dev, proc_e, r);
else
r = OK;
}
return r;
}
/*===========================================================================*
* bdev_up *
@ -881,74 +840,46 @@ void bdev_up(devmajor_t maj)
/*===========================================================================*
* opcl_reply *
* cdev_generic_reply *
*===========================================================================*/
static void opcl_reply(message *m_ptr)
static void cdev_generic_reply(message *m_ptr)
{
/* A character driver has replied to an open or close request. This function
* MUST NOT block its calling thread.
/* A character driver has results for an open, close, read, write, or ioctl
* call (i.e., everything except select). There may be a thread waiting for
* these results as part of an ongoing open, close, or (for read/write/ioctl)
* cancel call. If so, wake up that thread; if not, send a reply to the
* requesting process. This function MUST NOT block its calling thread.
*/
struct fproc *rfp;
struct worker_thread *wp;
endpoint_t proc_e;
int slot;
proc_e = m_ptr->REP_ENDPT;
if (isokendpt(proc_e, &slot) != OK) return;
rfp = &fproc[slot];
wp = rfp->fp_worker;
if (wp == NULL || wp->w_task != who_e) {
printf("VFS: no worker thread waiting for a reply from %d\n", who_e);
proc_e = m_ptr->CDEV_ID;
if (m_ptr->CDEV_STATUS == SUSPEND) {
printf("VFS: got SUSPEND from %d, not reviving\n", m_ptr->m_source);
return;
}
*wp->w_drv_sendrec = *m_ptr;
worker_signal(wp); /* Continue open/close */
}
/*===========================================================================*
* task_reply *
*===========================================================================*/
static void task_reply(message *m_ptr)
{
/* A character driver has results for a read, write, or ioctl call. There may
* be a thread waiting for these results as part of an ongoing dev_cancel call.
* If so, wake up that thread; if not, send a reply to the requesting process.
* This function MUST NOT block its calling thread.
*/
struct fproc *rfp;
struct worker_thread *wp;
endpoint_t proc_e;
int slot;
proc_e = m_ptr->REP_ENDPT;
if (proc_e == VFS_PROC_NR)
proc_e = find_suspended_ep(m_ptr->m_source, m_ptr->REP_IO_GRANT);
else
printf("VFS: endpoint %u from %u is not VFS\n",
proc_e, m_ptr->m_source);
if (proc_e == NONE) {
printf("VFS: proc with grant %d from %d not found\n",
m_ptr->REP_IO_GRANT, m_ptr->m_source);
} else if (m_ptr->REP_STATUS == SUSPEND) {
printf("VFS: got SUSPEND on DEV_REVIVE: not reviving proc\n");
} else {
/* If there is a thread active for this process, we assume that this
* thread aims to cancel the ongoing operation. In that case, wake up
* the thread to let it finish unpausing the process. Otherwise, revive
* the process as usual.
if (isokendpt(proc_e, &slot) != OK) {
printf("VFS: proc %d from %d not found\n", proc_e, m_ptr->m_source);
return;
}
rfp = &fproc[slot];
wp = rfp->fp_worker;
if (wp != NULL && wp->w_task == who_e) {
assert(!fp_is_blocked(rfp));
*wp->w_drv_sendrec = *m_ptr;
worker_signal(wp); /* Continue open/close/cancel */
} else if (rfp->fp_blocked_on != FP_BLOCKED_ON_OTHER ||
rfp->fp_task != m_ptr->m_source) {
/* This would typically be caused by a protocol error, i.e. a driver
* not properly following the character driver protocol rules.
*/
if (isokendpt(proc_e, &slot) != OK) return;
rfp = &fproc[slot];
wp = rfp->fp_worker;
if (wp != NULL && wp->w_task == who_e) {
assert(!fp_is_blocked(rfp));
*wp->w_drv_sendrec = *m_ptr;
worker_signal(wp); /* Continue cancel */
} else {
revive(proc_e, m_ptr->REP_STATUS);
}
printf("VFS: proc %d not blocked on %d\n", proc_e, m_ptr->m_source);
} else {
revive(proc_e, m_ptr->CDEV_STATUS);
}
}
@ -960,15 +891,20 @@ void cdev_reply(void)
{
/* A character driver has results for us. */
if (get_dmap(who_e) == NULL) {
printf("VFS: ignoring char dev reply from unknown driver %d\n", who_e);
return;
}
switch (call_nr) {
case DEV_OPEN_REPL:
case DEV_CLOSE_REPL: opcl_reply(&m_in); break;
case DEV_REVIVE: task_reply(&m_in); break;
case DEV_SEL_REPL1:
select_reply1(m_in.m_source, m_in.DEV_MINOR, m_in.DEV_SEL_OPS);
case CDEV_REPLY:
cdev_generic_reply(&m_in);
break;
case DEV_SEL_REPL2:
select_reply2(m_in.m_source, m_in.DEV_MINOR, m_in.DEV_SEL_OPS);
case CDEV_SEL1_REPLY:
select_reply1(m_in.m_source, m_in.CDEV_MINOR, m_in.CDEV_STATUS);
break;
case CDEV_SEL2_REPLY:
select_reply2(m_in.m_source, m_in.CDEV_MINOR, m_in.CDEV_STATUS);
break;
default:
printf("VFS: char driver %u sent unknown reply %x\n", who_e, call_nr);
@ -979,15 +915,24 @@ void cdev_reply(void)
/*===========================================================================*
* bdev_reply *
*===========================================================================*/
void bdev_reply(struct dmap *dp)
void bdev_reply(void)
{
/* A block driver has results for a call. There must be a thread waiting for
* these results - wake it up. This function MUST NOT block its calling thread.
*/
struct worker_thread *wp;
struct dmap *dp;
assert(dp != NULL);
assert(dp->dmap_servicing != NONE);
if ((dp = get_dmap(who_e)) == NULL) {
printf("VFS: ignoring block dev reply from unknown driver %d\n",
who_e);
return;
}
if (dp->dmap_servicing == INVALID_THREAD) {
printf("VFS: ignoring spurious block dev reply from %d\n", who_e);
return;
}
wp = worker_get(dp->dmap_servicing);
if (wp == NULL || wp->w_task != who_e) {

View file

@ -182,9 +182,6 @@ int flags; /* device flags */
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;
default:
return(EINVAL);
@ -281,7 +278,7 @@ void init_dmap()
dmap[i].dmap_io = no_dev_io;
dmap[i].dmap_driver = NONE;
dmap[i].dmap_style = STYLE_NDEV;
dmap[i].dmap_servicing = NONE;
dmap[i].dmap_servicing = INVALID_THREAD;
}
}
@ -344,7 +341,7 @@ void dmap_endpt_up(endpoint_t proc_e, int is_blk)
if (dp->dmap_recovering) {
printf("VFS: driver recovery failure for"
" major %d\n", major);
if (dp->dmap_servicing != NONE) {
if (dp->dmap_servicing != INVALID_THREAD) {
worker = worker_get(dp->dmap_servicing);
worker_stop(worker);
}
@ -355,7 +352,7 @@ void dmap_endpt_up(endpoint_t proc_e, int is_blk)
bdev_up(major);
dp->dmap_recovering = 0;
} else {
if (dp->dmap_servicing != NONE) {
if (dp->dmap_servicing != INVALID_THREAD) {
worker = worker_get(dp->dmap_servicing);
worker_stop(worker);
}

View file

@ -22,7 +22,7 @@ extern struct dmap {
int dmap_style;
int dmap_sel_busy;
struct filp *dmap_sel_filp;
endpoint_t dmap_servicing;
thread_t dmap_servicing;
mutex_t dmap_lock;
mutex_t *dmap_lock_ref;
int dmap_recovering;

View file

@ -579,7 +579,7 @@ struct filp *f;
(void) bdev_close(dev); /* Ignore errors */
} else {
(void) dev_close(dev); /* Ignore errors */
(void) cdev_close(dev); /* Ignore errors */
}
f->filp_mode = FILP_CLOSED;

View file

@ -29,8 +29,6 @@ EXTERN struct fproc {
int fp_block_callnr; /* blocked call if rd/wr can't finish */
int fp_cum_io_partial; /* partial byte count if rd/wr can't finish */
endpoint_t fp_task; /* which task is proc suspended on */
endpoint_t fp_ioproc; /* proc no. in suspended-on i/o message */
cp_grant_id_t fp_grant; /* revoke this grant on unsuspend if > -1 */
uid_t fp_realuid; /* real user id */

View file

@ -124,36 +124,14 @@ int main(void)
continue;
}
/* At this point we either have results from an asynchronous device
* or a new system call. In both cases a new worker thread has to be
* started and there might not be one available from the pool. This is
* not a problem (requests/replies are simply queued), except when
* they're from an FS endpoint, because these can cause a deadlock.
* handle_work() takes care of the details. */
if (IS_DRV_REPLY(call_nr)) {
/* We've got results for a device request */
struct dmap *dp;
dp = get_dmap(who_e);
if (dp != NULL) {
if (!IS_BDEV_RS(call_nr)) {
cdev_reply();
} else {
if (dp->dmap_servicing == NONE) {
printf("Got spurious dev reply from %d",
who_e);
} else {
bdev_reply(dp);
}
}
continue;
}
printf("VFS: ignoring dev reply from unknown driver %d\n",
who_e);
if (IS_BDEV_RS(call_nr)) {
/* We've got results for a block device request. */
bdev_reply();
} else if (IS_CDEV_RS(call_nr)) {
/* We've got results for a character device request. */
cdev_reply();
} else {
/* Normal syscall. */
/* Normal syscall. This spawns a new thread. */
handle_work(do_work);
}
}

View file

@ -659,7 +659,7 @@ static void free_proc(int flags)
if (!S_ISCHR(vp->v_mode)) continue;
if ((dev_t) vp->v_sdev != dev) continue;
lock_filp(rfilp, VNODE_READ);
(void) dev_close(dev); /* Ignore any errors. */
(void) cdev_close(dev); /* Ignore any errors. */
rfilp->filp_mode = FILP_CLOSED;
unlock_filp(rfilp);

View file

@ -156,9 +156,9 @@ int common_open(char path[PATH_MAX], int oflags, mode_t omode)
/* Invoke the driver for special processing. */
dev = (dev_t) vp->v_sdev;
/* TTY needs to know about the O_NOCTTY flag. */
r = dev_open(dev, bits | (oflags & O_NOCTTY));
r = cdev_open(dev, bits | (oflags & O_NOCTTY));
vp = filp->filp_vno; /* Might be updated by
* dev_open/clone_opcl */
* cdev_open after cloning */
break;
case S_IFBLK:

View file

@ -527,7 +527,7 @@ void unpause(void)
blocked_on = fp->fp_blocked_on;
/* Clear the block status now. The procedure below might make blocking calls
* and it is imperative that while at least dev_cancel() is executing, other
* and it is imperative that while at least cdev_cancel() is executing, other
* parts of VFS do not perceive this process as blocked on something.
*/
fp->fp_blocked_on = FP_BLOCKED_ON_NONE;
@ -573,7 +573,7 @@ void unpause(void)
}
dev = (dev_t) f->filp_vno->v_sdev; /* device hung on */
status = dev_cancel(dev);
status = cdev_cancel(dev);
break;
default :

View file

@ -29,14 +29,17 @@ void fs_sendmore(struct vmnt *vmp);
void send_work(void);
/* device.c */
int dev_open(dev_t dev, int flags);
int dev_close(dev_t dev);
int cdev_open(dev_t dev, int flags);
int cdev_close(dev_t dev);
int cdev_io(int op, dev_t dev, endpoint_t proc_e, void *buf, off_t pos,
unsigned long bytes, int flags);
int cdev_select(dev_t dev, int ops);
int cdev_cancel(dev_t dev);
void cdev_reply(void);
int bdev_open(dev_t dev, int access);
int bdev_close(dev_t dev);
void bdev_reply(struct dmap *dp);
int dev_io(int op, dev_t dev, endpoint_t proc_e, void *buf, off_t pos,
size_t bytes, int flags);
void bdev_reply(void);
void bdev_up(int major);
int gen_opcl(int op, dev_t dev, endpoint_t task_nr, int flags);
int gen_io(endpoint_t drv_e, message *mess_ptr);
int no_dev(int op, dev_t dev, endpoint_t proc, int flags);
@ -46,10 +49,7 @@ int ctty_opcl(int op, dev_t dev, endpoint_t proc, int flags);
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);
int dev_select(dev_t dev, int ops);
int dev_cancel(dev_t dev);
void pm_setsid(endpoint_t proc_e);
void bdev_up(int major);
/* dmap.c */
void lock_dmap(struct dmap *dp);

View file

@ -137,6 +137,7 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
off_t position, res_pos;
unsigned int cum_io, cum_io_incr, res_cum_io;
int op, r;
dev_t dev;
position = f->filp_pos;
vp = f->filp_vno;
@ -147,7 +148,7 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
if (size > SSIZE_MAX) return(EINVAL);
op = (rw_flag == READING ? DEV_READ_S : DEV_WRITE_S);
op = (rw_flag == READING ? CDEV_READ : CDEV_WRITE);
if (S_ISFIFO(vp->v_mode)) { /* Pipes */
if (rfp->fp_cum_io_partial != 0) {
@ -159,9 +160,6 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
}
r = rw_pipe(rw_flag, for_e, f, buf, size);
} else if (S_ISCHR(vp->v_mode)) { /* Character special files. */
dev_t dev;
int op = (rw_flag == READING ? DEV_READ_S : DEV_WRITE_S);
if(rw_flag == PEEKING) {
printf("read_write: peek on char device makes no sense\n");
return EINVAL;
@ -172,7 +170,7 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
dev = (dev_t) vp->v_sdev;
r = dev_io(op, dev, for_e, buf, position, size, f->filp_flags);
r = cdev_io(op, dev, for_e, buf, position, size, f->filp_flags);
if (r >= 0) {
/* This should no longer happen: all calls are asynchronous. */
printf("VFS: I/O to device %x succeeded immediately!?\n", dev);

View file

@ -406,7 +406,7 @@ static int select_request_char(struct filp *f, int *ops, int block)
return(SUSPEND);
f->filp_select_flags &= ~FSF_UPDATE;
r = dev_select(f->filp_vno->v_sdev, rops);
r = cdev_select(f->filp_vno->v_sdev, rops);
if (r != OK)
return(r);
@ -719,7 +719,7 @@ void select_timeout_check(timer_t *timer)
if (se->requestor == NULL) return;
if (se->expiry <= 0) return; /* Strange, did we even ask for a timeout? */
se->expiry = 0;
if (is_deferred(se)) return; /* Wait for initial replies to DEV_SELECT */
if (is_deferred(se)) return; /* Wait for initial replies to CDEV_SELECT */
select_return(se);
}
@ -771,7 +771,7 @@ endpoint_t driver_e;
int minor;
int status;
{
/* Handle the initial reply to DEV_SELECT request. This function MUST NOT
/* Handle the initial reply to CDEV_SELECT request. This function MUST NOT
* block its calling thread.
*/
int major;
@ -788,7 +788,7 @@ int status;
/* Get filp belonging to character special file */
if (!dp->dmap_sel_busy) {
printf("VFS (%s:%d): major %d was not expecting a DEV_SELECT reply\n",
printf("VFS (%s:%d): major %d was not expecting a CDEV_SELECT reply\n",
__FILE__, __LINE__, major);
return;
}

View file

@ -75,13 +75,4 @@ int select(int, fd_set * __restrict, fd_set * __restrict,
__END_DECLS
#endif /* _KERNEL */
#if defined(__minix) && defined(_NETBSD_SOURCE)
/* possible select() operation types; read, write, errors */
/* (FS/driver internal use only) */
#define SEL_RD (1 << 0)
#define SEL_WR (1 << 1)
#define SEL_ERR (1 << 2)
#define SEL_NOTIFY (1 << 3) /* not a real select operation */
#endif /* defined(__minix) && defined(_NETBSD_SOURCE) */
#endif /* !_SYS_SELECT_H_ */