*/
arg_t net_read(struct socket *s, uint8_t flag)
{
- usize_t n = 0;
struct sockdata *sd = s->s_priv;
irqflags_t irq;
uint8_t st;
break;
}
uputc(data, udata.u_base++);
- n++;
- if (n < udata.u_count)
+ udata.u_done++;
+ if (udata.u_done < udata.u_count)
continue;
}
- if (n)
+ if (udata.u_done)
break;
s->s_iflag &= ~SI_DATA;
- if (psleep_flags_io(&s->s_iflag, flag, &n)) {
+ if (psleep_flags_io(&s->s_iflag, flag)) {
irqrestore(irq);
return -1;
}
}
- if (n)
- return n;
+ if (udata.u_done)
+ return udata.u_done;
if (st & 0x80) {
err_xlate(s);
return -1;
*/
arg_t net_write(struct socket * s, uint8_t flag)
{
- usize_t n = 0;
uint8_t p = 0;
struct sockdata *sd = s->s_priv;
irqflags_t irq;
break;
/* Good status after a write means byte ok */
- n += p;
- if (n == udata.u_count) {
+ udata.u_done += p;
+ if (udata.u_done == udata.u_count) {
irqrestore(irq);
- return n;
+ return udata.u_done;
}
/* Can we send more bytes ? */
p = 0;
continue;
}
s->s_iflag |= SI_THROTTLE;
- if (psleep_flags_io(&s->s_iflag, flag, &n)) {
+ if (psleep_flags_io(&s->s_iflag, flag)) {
irqrestore(irq);
return n;
}
}
/* It broke mummy ! */
irqrestore(irq);
- if (n) {
+ if (udata.u_done) {
s->s_error = udata.u_error;
udata.u_error = 0;
- return n;
+ return udata.u_done;
}
err_xlate(s);
if (udata.u_error == EPIPE)
return 0;
}
-static int iopoll(int sofar)
+static uint8_t iopoll(void)
{
/* Ought to be a core helper for this lot ? */
if (need_reschedule())
_sched_yield();
if (chksigs()) {
- if (sofar)
- return sofar;
- udata.u_error = EINTR;
- return -1;
+ if (!udata.u_done) {
+ udata.u_error = EINTR;
+ udata.u_done = (usize_t)-1;
+ }
+ return 1;
}
return 0;
}
int lpr_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
{
- int c = udata.u_count;
char *p = udata.u_base;
minor; rawflag; flag; // shut up compiler
- while(c) {
+ while(udata.u_done < udata.u_count) {
/* Note; on real hardware it might well be necessary to
busy wait a bit just to get acceptable performance */
while (lpstat != 0xFF) {
- int n;
- if (n = iopoll(p - udata.u_base))
- return n;
+ if (iopoll())
+ return udata.u_done;
}
/* FIXME: tidy up ugetc and sysio checks globally */
lpdata = ugetc(p++);
+ udata.u_done++;
}
- return (-1);
+ return udata.u_done;
}
Miscellaneous helpers
**********************************************************************/
-int psleep_flags_io(void *p, unsigned char flags, usize_t *n)
+int psleep_flags_io(void *p, unsigned char flags)
{
if (flags & O_NDELAY) {
- if (!*n) {
- *n = (usize_t)-1;
+ if (!udata.u_done) {
+ udata.u_done = (usize_t)-1;
udata.u_error = EAGAIN;
}
return -1;
}
psleep(p);
if (chksigs()) {
- if (!*n) {
- *n = (usize_t)-1;
+ if (!udata.u_done) {
+ udata.u_done = (usize_t)-1;
udata.u_error = EINTR;
}
return -1;
int psleep_flags(void *p, unsigned char flags)
{
- usize_t dummy = 0;
- return psleep_flags_io(p, flags, &dummy);
+ if (flags & O_NDELAY) {
+ udata.u_error = EAGAIN;
+ return -1;
+ }
+ psleep(p);
+ if (chksigs()) {
+ udata.u_error = EINTR;
+ return -1;
+ }
+ return 0;
}
void kputs(const char *p)
#define NULL (void *)0
#endif
+#ifndef regptr
+#define regptr
+#endif
+
#define min(a,b) ( (a) < (b) ? (a) : (b) )
#define max(a,b) ( (a) > (b) ? (a) : (b) )
#define aligndown(v,a) (uint8_t*)((intptr_t)(v) & ~((a)-1))
#include "level2.h"
#else
-#define jobcontrol_in(x,y,z) 0
-#define jobcontrol_out(x,y,z) 0
+#define jobcontrol_in(x,y) 0
+#define jobcontrol_out(x,y) 0
#define jobcontrol_ioctl(x,y,z) 0
#define limit_exceeded(x,y) (0)
uint16_t u_blkoff; /* Offset in block */
usize_t u_nblock; /* Number of blocks */
uint8_t *u_dptr; /* Address for I/O */
+ usize_t u_done; /* Counter for driver methods */
#ifdef CONFIG_LEVEL_2
uint16_t u_groups[NGROUP]; /* Group list */
extern bool remq(struct s_queue *q, unsigned char *cp);
extern void clrq(struct s_queue *q);
extern bool uninsq(struct s_queue *q, unsigned char *cp);
-extern int psleep_flags_io(void *event, unsigned char flags, usize_t *n);
+extern int psleep_flags_io(void *event, unsigned char flags);
extern int psleep_flags(void *event, unsigned char flags);
extern int nxio_open(uint8_t minor, uint16_t flag);
extern int no_open(uint8_t minor, uint16_t flag);
udata.u_sysio = false; /* I/O to user data space */
udata.u_base = (unsigned char *) udata.u_argn1; /* buf */
udata.u_count = (susize_t) udata.u_argn2; /* nbytes */
+ udata.u_done = 0; /* bytes done so far */
if ((ino = getinode(udata.u_argn)) == NULLINODE) {
/* kprintf("[WRS: rwsetup(): getinode(%x) fails]", udata.u_argn); */
}
/* For input readign with SIGTTIN blocked gets you an EIO */
-uint8_t jobcontrol_in(uint8_t minor, struct tty *t, usize_t *nread)
+uint8_t jobcontrol_in(uint8_t minor, struct tty *t)
{
if (!jobop(minor, SIGTTIN, t, 0))
return 0;
- if (*nread == 0) {
+ if (udata.u_done == 0) {
udata.u_error = EINTR;
- *nread = (usize_t)-1;
+ udata.u_done = (usize_t)-1;
}
return 1;
}
/* For output ignored stop is taken to mean as write anyway */
-uint8_t jobcontrol_out(uint8_t minor, struct tty *t, usize_t *written)
+uint8_t jobcontrol_out(uint8_t minor, struct tty *t)
{
if (!(t->termios.c_lflag & TOSTOP))
return 0;
if (!jobop(minor, SIGTTOU, t, 1))
return 0;
- if (*written == 0) {
+ if (udata.u_done == 0) {
udata.u_error = EINTR;
- *written = (usize_t)-1;
+ udata.u_done = (usize_t)-1;
}
return 1;
}
int tty_read(uint8_t minor, uint8_t rawflag, uint8_t flag)
{
- usize_t nread;
unsigned char c;
struct s_queue *q;
struct tty *t;
q = &ttyinq[minor];
t = &ttydata[minor];
- nread = 0;
- while (nread < udata.u_count) {
+
+ while (udata.u_done < udata.u_count) {
for (;;) {
#ifdef CONFIG_LEVEL_2
- if (jobcontrol_in(minor, t, &nread))
- return nread;
+ if (jobcontrol_in(minor, t))
+ return udata.u_done;
#endif
if ((t->flag & TTYF_DEAD) && (!q->q_count))
goto dead;
if (!(t->termios.c_lflag & ICANON)) {
uint8_t n = t->termios.c_cc[VTIME];
- if ((nread || !n) && nread >= t->termios.c_cc[VMIN])
+ if ((udata.u_done || !n) && udata.u_done >= t->termios.c_cc[VMIN])
goto out;
if (n)
udata.u_ptab->p_timeout = n + 1;
}
- if (psleep_flags_io(q, flag, &nread))
+ if (psleep_flags_io(q, flag))
goto out;
/* timer expired */
if (udata.u_ptab->p_timeout == 1)
goto out;
}
- ++nread;
+ ++udata.u_done;
/* return according to mode */
if (t->termios.c_lflag & ICANON) {
- if (nread == 1 && (c == t->termios.c_cc[VEOF])) {
+ if (udata.u_done == 1 && (c == t->termios.c_cc[VEOF])) {
/* ^D */
- nread = 0;
+ udata.u_done = 0;
break;
}
if (c == '\n' || c == t->termios.c_cc[VEOL])
}
out:
wakeup(&q->q_count);
- return nread;
+ return udata.u_done;
dead:
udata.u_error = ENXIO;
int tty_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
{
struct tty *t;
- usize_t written = 0;
uint8_t c;
used(rawflag);
t = &ttydata[minor];
- while (udata.u_count-- != 0) {
+ while (udata.u_done != udata.u_count) {
for (;;) { /* Wait on the ^S/^Q flag */
#ifdef CONFIG_LEVEL_2
- if (jobcontrol_out(minor, t, &written))
- return written;
+ if (jobcontrol_out(minor, t))
+ return udata.u_done;
#endif
if (t->flag & TTYF_DEAD) {
udata.u_error = ENXIO;
}
if (!(t->flag & TTYF_STOP))
break;
- if (psleep_flags_io(&t->flag, flag, &written))
- return written;
+ if (psleep_flags_io(&t->flag, flag))
+ return udata.u_done;
}
if (!(t->flag & TTYF_DISCARD)) {
if (udata.u_sysio)
break;
}
++udata.u_base;
- ++written;
+ ++udata.u_done;
}
- return written;
+ return udata.u_done;
}