{
int base;
int irq;
+ int refcnt;
struct intrupt *intrupt;
int fifo;
int baudrate;
port->oflo++;
}
- if (dos_putc (c & 0x7f, port) < 0)
+ if (dos_putc (c, port) < 0)
{
COUNT (CNT_ORUN);
}
fd = name[3] - '1';
port = &ports[fd];
- if (port->intrupt)
+ if (port->refcnt++ > 0)
{
- /* already open (EBUSY not defined!) */
- errno = EACCES;
- return -1;
+ /* Device already opened another user. Just point at it. */
+ scb->fd = fd;
+ return 0;
}
/* force access to ID reg */
dos_close (scb)
serial_t scb;
{
- struct dos_ttystate *port = &ports[scb->fd];
+ struct dos_ttystate *port;
struct intrupt *intrupt;
+ if (!scb)
+ return;
+
+ port = &ports[scb->fd];
+
+ if (port->refcnt-- > 1)
+ return;
+
if (!(intrupt = port->intrupt))
return;
if (port->baudrate != rate)
{
int x;
+ unsigned char cfcr;
x = dos_baudconv (rate);
if (x <= 0)
}
disable ();
+ cfcr = inb (port, com_cfcr);
+
outb(port, com_cfcr, CFCR_DLAB);
outb(port, com_dlbl, x & 0xff);
outb(port, com_dlbh, x >> 8);
- outb(port, com_cfcr, CFCR_8BITS);
+ outb(port, com_cfcr, cfcr);
port->baudrate = rate;
enable ();
}
return 0;
}
+static int
+dos_setstopbits (scb, num)
+ serial_t scb;
+ int num;
+{
+ struct dos_ttystate *port = &ports[scb->fd];
+ unsigned char cfcr;
+
+ disable ();
+ cfcr = inb (port, com_cfcr);
+
+ switch (num)
+ {
+ case SERIAL_1_STOPBITS:
+ outb (port, com_cfcr, cfcr & ~CFCR_STOPB);
+ break;
+ case SERIAL_1_AND_A_HALF_STOPBITS:
+ case SERIAL_2_STOPBITS:
+ outb (port, com_cfcr, cfcr | CFCR_STOPB);
+ break;
+ default:
+ enable ();
+ return 1;
+ }
+ enable ();
+
+ return 0;
+}
static int
dos_write (scb, str, len)
return 0;
}
+
+static int
+dos_sendbreak (scb)
+ serial_t scb;
+{
+ volatile struct dos_ttystate *port = &ports[scb->fd];
+ unsigned char cfcr;
+ long then;
+
+ cfcr = inb(port, com_cfcr);
+ outb(port, com_cfcr, cfcr | CFCR_SBREAK);
+
+ /* 0.25 sec delay */
+ then = rawclock () + RAWHZ / 4;
+ while ((rawclock () - then) < 0)
+ continue;
+
+ outb(port, com_cfcr, cfcr);
+ return 0;
+}
+
+
static struct serial_ops dos_ops =
{
"hardwire",
dos_write,
dos_noop, /* flush output */
dos_flush_input,
- dos_noop, /* send break -- currently used only for nindy */
+ dos_sendbreak,
dos_raw,
dos_get_tty_state,
dos_set_tty_state,
dos_print_tty_state,
dos_noflush_set_tty_state,
dos_setbaudrate,
+ dos_setstopbits,
};
{
if (port->baudrate == 0)
continue;
- printf_filtered ("Port:\tCOM%d (%sactive)\n", port - ports,
+ printf_filtered ("Port:\tCOM%d (%sactive)\n", port - ports + 1,
port->intrupt ? "" : "not ");
printf_filtered ("Addr:\t0x%03x (irq %d)\n", port->base, port->irq);
printf_filtered ("16550:\t%s\n", port->fifo ? "yes" : "no");
printf_filtered ("Speed:\t%d baud\n", port->baudrate);
- printf_filtered ("Errs:\tframing %d parity %d overflow %d\n",
+ printf_filtered ("Errs:\tframing %d parity %d overflow %d\n\n",
port->ferr, port->perr, port->oflo);
}