extern CODE1 void tty_erase(uint8_t minor);
extern CODE1 void tty_putc_wait(uint8_t minor, unsigned char c);
+typedef enum {
+ TTY_READY_NOW=1, /* port is ready immediately */
+ TTY_READY_SOON=0, /* we'll be ready shortly, kernel should spin, polling the port repeatedly */
+ TTY_READY_LATER=-1 /* we'll be a long time, put this process to sleep and schedule another */
+} ttyready_t;
+
/* provided by platform */
extern struct s_queue ttyinq[NUM_DEV_TTY + 1];
-extern CODE2 bool tty_writeready(uint8_t minor);
+extern CODE2 ttyready_t tty_writeready(uint8_t minor);
extern CODE2 void tty_putc(uint8_t minor, unsigned char c);
extern CODE2 void tty_setup(uint8_t minor);
extern CODE2 int tty_carrier(uint8_t minor);
tty_putc(1, c);
}
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
uint8_t c;
if (minor == 1)
- return 1;
+ return TTY_READY_NOW;
c = *uartb;
- return c & 1;
+ return (c & 1) ? TTY_READY_NOW : TTY_READY_SOON;
}
void tty_putc(uint8_t minor, unsigned char c)
tty_putc(1, c);
}
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
uint8_t c;
if (minor == 1)
- return 1;
+ return TTY_READY_NOW;
c = *uartb;
- return c & 1;
+ return (c & 1) ? TTY_READY_NOW : TTY_READY_SOON;
}
void tty_putc(uint8_t minor, unsigned char c)
tty_putc(1, c);
}
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
uint8_t c;
if (minor == 1)
- return 1;
+ return TTY_READY_NOW;
c = *uartb;
- return c & 1;
+ return (c & 1) ? TTY_READY_NOW : TTY_READY_SOON;
}
void tty_putc(uint8_t minor, unsigned char c)
tty_putc(1, c);
}
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
uint8_t c;
if (minor == 1)
- return 1;
+ return TTY_READY_NOW;
c = *uart_status;
- return c & 16; /* TX DATA empty */
+ return (c & 16) ? TTY_READY_NOW : TTY_READY_SOON; /* TX DATA empty */
}
/* For DragonPlus we should perhaps support both monitors 8) */
tty_putc(1, c);
}
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
uint8_t c;
if (minor == 1)
- return 1;
+ return TTY_READY_NOW;
c = *uart_status;
- return c & 16; /* TX DATA empty */
+ return (c & 16) ? TTY_READY_NOW : TTY_READY_SOON; /* TX DATA empty */
}
/* For DragonPlus we should perhaps support both monitors 8) */
}
/* Both console and debug port are always ready */
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
minor;
- return 1;
+ return TTY_READY_NOW;
}
void tty_putc(uint8_t minor, unsigned char c)
}
/* Both console and debug port are always ready */
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
minor;
- return 1;
+ return TTY_READY_NOW;
}
void tty_putc(uint8_t minor, unsigned char c)
tty_putc(1, c);
}
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
uint8_t reg = 0xFF;
if (minor == 3)
reg = serialAc;
if (minor == 4)
reg = serialBc;
- return reg & 4;
+ return (reg & 4) ? TTY_READY_NOW : TTY_READY_SOON;
}
void tty_putc(uint8_t minor, unsigned char c)
}
}
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
minor;
- return 1;
+ return TTY_READY_NOW;
}
/* kernel writes to system console -- never sleep! */
#ifndef __DEVTTY_DOT_H__
#define __DEVTTY_DOT_H__
void tty_putc(uint8_t minor, unsigned char c);
-bool tty_writeready(uint8_t minor);
void tty_pollirq_asci0(void);
void tty_pollirq_asci1(void);
tty_putc(1, c);
}
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
uint8_t c;
if (minor == 1)
- return 1;
+ return TTY_READY_NOW;
c = uartb;
- return c & 1;
+ return (c & 1) ? TTY_READY_NOW : TTY_READY_SOON;
}
void tty_putc(uint8_t minor, unsigned char c)
}
}
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
minor;
- return 1;
+ return TTY_READY_NOW;
}
/* kernel writes to system console -- never sleep! */
#ifndef __DEVTTY_DOT_H__
#define __DEVTTY_DOT_H__
void tty_putc(uint8_t minor, unsigned char c);
-bool tty_writeready(uint8_t minor);
void tty_pollirq_escc(void);
void tty_pollirq_asci0(void);
void tty_pollirq_asci1(void);
irqrestore(irq);
}
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
if (minor == 1)
- return 1; /* VT */
+ return TTY_READY_NOW;
else
- return dartrr(minor, 0) & 4;
+ return (dartrr(minor, 0) & 4) ? TTY_READY_NOW : TTY_READY_SOON;
}
extern void bugout(uint16_t c);
#define __DEVTTY_DOT_H__
void tty_putc(uint8_t minor, char c);
-bool tty_writeready(uint8_t minor);
void tty_init_port(void);
void tty_irq(void);
}
/* It's the console display, always ready */
-static bool tty_writeready(uint8_t minor)
+static ttyready_t tty_writeready(uint8_t minor)
{
minor;
- return 1;
+ return TTY_READY_NOW;
}
void tty_putc(uint8_t minor, unsigned char c)
#ifndef __DEVTTY_DOT_H__
#define __DEVTTY_DOT_H__
void tty_putc(uint8_t minor, unsigned char c);
-bool tty_writeready(uint8_t minor);
void tty_pollirq(void);
void tty_setup(uint8_t minor);
#endif
tty_putc(1, c);
}
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
- return 1;
+ return TTY_READY_NOW;
}
void tty_putc(uint8_t minor, unsigned char c)
tty_putc(1, c);
}
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
uint8_t reg;
if (minor == 1)
- return 1;
+ return TTY_READY_NOW;
reg = tr1865_status;
- if (reg & 0x40)
- return 1;
- return 0;
+ return (reg & 0x40) ? TTY_READY_NOW : TTY_READY_SOON;
}
void tty_putc(uint8_t minor, unsigned char c)
tty_putc(1, c);
}
-static bool tty_writeready(uint8_t minor)
+static ttyready_t tty_writeready(uint8_t minor)
{
minor;
- return 1;
+ return TTY_READY_NOW;
}
void tty_putc(uint8_t minor, unsigned char c)
}
/* Both console and debug port are always ready */
-bool tty_writeready(uint8_t minor)
+ttyready_t tty_writeready(uint8_t minor)
{
minor;
- return 1;
+ return TTY_READY_NOW;
}
void tty_putc(uint8_t minor, unsigned char c)
costs versus waiting a bit. A box with tx interrupts and sufficient
performance can buffer or sleep in tty_putc instead.
- The driver should return 1 - send bytes, 0 - spinning may be useful,
- -1 - blocked, don't spin (eg flow controlled) */
+ The driver should return a value from the ttyready_t enum:
+ 1 (TTY_READY_NOW) -- send bytes now
+ 0 (TTY_READY_SOON) -- spinning may be useful
+ -1 (TTY_READY_LATER) -- blocked, don't spin (eg flow controlled) */
if (!udata.u_ininterrupt) {
- while ((t = tty_writeready(minor)) != 1)
- if (t || need_resched())
+ while ((t = tty_writeready(minor)) != TTY_READY_NOW)
+ if (t != TTY_READY_SOON || need_resched())
psleep(&ttydata[minor]);
}
tty_putc(minor, c);