diff --git a/src/WIN/plat_serial.h b/src/WIN/plat_serial.h index cf87192c0..56cf08126 100644 --- a/src/WIN/plat_serial.h +++ b/src/WIN/plat_serial.h @@ -8,7 +8,7 @@ * * Definitions for the Bottom Half of the SERIAL card. * - * Version: @(#)plat_serial.h 1.0.3 2017/05/17 + * Version: @(#)plat_serial.h 1.0.5 2017/06/04 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -18,7 +18,7 @@ typedef struct { - char name[79]; /* name of open port */ + char name[80]; /* name of open port */ void (*rd_done)(void *, int); void *rd_arg; #ifdef BHTTY_C @@ -28,6 +28,9 @@ typedef struct { int tmo; /* current timeout value */ DCB dcb, /* terminal settings */ odcb; + thread_t *tid; /* pointer to receiver thread */ + char buff[1024]; + int icnt, ihead, itail; #endif } BHTTY; @@ -41,7 +44,7 @@ extern int bhtty_params(BHTTY *, char __dbit, char __par, char __sbit); extern int bhtty_sstate(BHTTY *, void *__arg); extern int bhtty_gstate(BHTTY *, void *__arg); extern int bhtty_crtscts(BHTTY *, char __yesno); - +extern int bhtty_active(BHTTY *, int); extern int bhtty_write(BHTTY *, unsigned char); extern int bhtty_read(BHTTY *, unsigned char *, int); diff --git a/src/WIN/win_serial.c b/src/WIN/win_serial.c index cfe8f0b43..1db962177 100644 --- a/src/WIN/win_serial.c +++ b/src/WIN/win_serial.c @@ -12,7 +12,7 @@ * Windows and UNIX systems, with support for FTDI and Prolific * USB ports. Support for these has been removed. * - * Version: @(#)win_serial.c 1.0.2 2017/05/17 + * Version: @(#)win_serial.c 1.0.3 2017/06/04 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -21,6 +21,7 @@ #include #include #include +#include "plat_thread.h" #define BHTTY_C #include "plat_serial.h" @@ -28,6 +29,60 @@ extern void pclog(char *__fmt, ...); +/* Handle the receiving of data from the host port. */ +static void +bhtty_reader(void *arg) +{ + BHTTY *pp = (BHTTY *)arg; + unsigned char b; + DWORD n; + + pclog("%s: thread started\n", pp->name); + + /* As long as the channel is open.. */ + while (pp->tid != NULL) { + /* Post a READ on the device. */ + n = 0; + if (ReadFile(pp->handle, &b, (DWORD)1, &n, &pp->rov) == FALSE) { + n = GetLastError(); + if (n != ERROR_IO_PENDING) { + /* Not good, we got an error. */ + pclog("%s: I/O error %d in read!\n", pp->name, n); + break; + } + + /* The read is pending, wait for it.. */ + if (GetOverlappedResult(pp->handle, &pp->rov, &n, TRUE) == FALSE) { + n = GetLastError(); + pclog("%s: I/O error %d in read!\n", pp->name, n); + break; + } + } + +pclog("%s: got %d bytes of data\n", pp->name, n); + if (n == 1) { + /* We got data, update stuff. */ + if (pp->icnt < sizeof(pp->buff)) { +pclog("%s: queued byte %02x (%d)\n", pp->name, b, pp->icnt+1); + pp->buff[pp->ihead++] = b; + pp->ihead &= (sizeof(pp->buff)-1); + pp->icnt++; + + /* Do a callback to let them know. */ + if (pp->rd_done != NULL) + pp->rd_done(pp->rd_arg, n); + } else { + pclog("%s: RX buffer overrun!\n", pp->name); + } + } + } + + /* Error or done, clean up. */ + pp->tid = NULL; + pclog("%s: thread stopped.\n", pp->name); +} + + /* Set the state of a port. */ int bhtty_sstate(BHTTY *pp, void *arg) @@ -35,8 +90,8 @@ bhtty_sstate(BHTTY *pp, void *arg) int i = 0; /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("invalid argument\n"); + if (arg == NULL) { + pclog("%s: invalid argument\n", pp->name); return(-1); } @@ -57,8 +112,8 @@ bhtty_gstate(BHTTY *pp, void *arg) int i = 0; /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("BHTTY: invalid argument\n"); + if (arg == NULL) { + pclog("%s: invalid argument\n", pp->name); return(-1); } @@ -76,12 +131,6 @@ bhtty_gstate(BHTTY *pp, void *arg) int bhtty_crtscts(BHTTY *pp, char yesno) { - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - /* Get the current mode. */ if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); @@ -124,12 +173,6 @@ bhtty_crtscts(BHTTY *pp, char yesno) int bhtty_params(BHTTY *pp, char dbit, char par, char sbit) { - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - /* Get the current mode. */ if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); @@ -220,8 +263,8 @@ bhtty_raw(BHTTY *pp, void *arg) DCB *dcb = (DCB *)arg; /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("invalid parameter\n"); + if (arg == NULL) { + pclog("%s: invalid parameter\n", pp->name); return; } @@ -263,12 +306,6 @@ bhtty_speed(BHTTY *pp, long speed) { int i; - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - /* Get the current mode and speed. */ if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); @@ -296,12 +333,6 @@ bhtty_flush(BHTTY *pp) COMSTAT cs; int i = 0; - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - /* First, clear any errors. */ (void)ClearCommError(pp->handle, &dwErrs, &cs); @@ -327,13 +358,18 @@ bhtty_flush(BHTTY *pp) void bhtty_close(BHTTY *pp) { - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("BHTTY: invalid handle\n"); - return; - } + /* If the polling thread is running, stop it. */ + (void)bhtty_active(pp, 0); + + /* Close the event handles. */ + if (pp->rov.hEvent != INVALID_HANDLE_VALUE) + CloseHandle(pp->rov.hEvent); + if (pp->wov.hEvent != INVALID_HANDLE_VALUE) + CloseHandle(pp->wov.hEvent); if (pp->handle != INVALID_HANDLE_VALUE) { + pclog("%s: closing host port\n", pp->name); + /* Restore the previous port state, if any. */ (void)bhtty_sstate(pp, &pp->odcb); @@ -351,20 +387,11 @@ bhtty_close(BHTTY *pp) BHTTY * bhtty_open(char *port, int tmo) { - char buff[64]; + char temp[64]; COMMTIMEOUTS to; -#if 0 COMMCONFIG conf; - DWORD d; -#endif BHTTY *pp; - int i = 0; - - /* Make sure we can do this. */ - if (port == NULL) { - pclog("invalid argument!\n"); - return(NULL); - } + DWORD d; /* First things first... create a control block. */ if ((pp = (BHTTY *)malloc(sizeof(BHTTY))) == NULL) { @@ -375,45 +402,53 @@ bhtty_open(char *port, int tmo) strncpy(pp->name, port, sizeof(pp->name)-1); /* Try a regular Win32 serial port. */ - sprintf(buff, "\\\\.\\%s", pp->name); - pp->handle = CreateFile(buff, - (GENERIC_READ|GENERIC_WRITE), - 0, NULL, OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - 0); - if (pp->handle == INVALID_HANDLE_VALUE) { + sprintf(temp, "\\\\.\\%s", pp->name); + if ((pp->handle = CreateFile(temp, + (GENERIC_READ|GENERIC_WRITE), + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + 0)) == INVALID_HANDLE_VALUE) { pclog("%s: open port: %d\n", pp->name, GetLastError()); free(pp); return(NULL); } -#if 0 + /* Create event handles. */ + pp->rov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + pp->wov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + /* Set up buffer size of the port. */ if (SetupComm(pp->handle, 32768L, 32768L) == FALSE) { /* This fails on FTDI-based devices. */ pclog("%s: set buffers: %d\n", pp->name, GetLastError()); -// CloseHandle(pp->handle); -// free(pp); -// return(NULL); +#if 0 + CloseHandle(pp->handle); + free(pp); + return(NULL); +#endif } /* Grab default config for the driver and set it. */ d = sizeof(COMMCONFIG); memset(&conf, 0x00, d); conf.dwSize = d; - if (GetDefaultCommConfig(pp->name, &conf, &d) == TRUE) { + if (GetDefaultCommConfig(temp, &conf, &d) == TRUE) { /* Change config here... */ /* Set new configuration. */ if (SetCommConfig(pp->handle, &conf, d) == FALSE) { /* This fails on FTDI-based devices. */ pclog("%s: set configuration: %d\n", pp->name, GetLastError()); -// CloseHandle(pp->handle); -// free(pp); -// return(NULL); +#if 0 + CloseHandle(pp->handle); + free(pp); + return(NULL); +#endif } } -#endif + pclog("%s: host port '%s' open\n", pp->name, temp); /* * We now have an open port. To allow for clean exit @@ -460,8 +495,7 @@ bhtty_open(char *port, int tmo) to.ReadTotalTimeoutConstant = tmo; } if (SetCommTimeouts(pp->handle, &to) == FALSE) { - pclog("%s: error %d while setting TO\n", - pp->name, GetLastError()); + pclog("%s: error %d while setting TO\n", pp->name, GetLastError()); (void)bhtty_close(pp); return(NULL); } @@ -476,25 +510,22 @@ bhtty_open(char *port, int tmo) } -/* A pending WRITE has finished, handle it. */ -static VOID CALLBACK -bhtty_write_comp(DWORD err, DWORD num, OVERLAPPED *priv) +/* Activate the I/O for this port. */ +int +bhtty_active(BHTTY *pp, int flg) { - BHTTY *pp = (BHTTY *)priv->hEvent; + if (flg) { + pclog("%s: starting thread..\n", pp->name); + pp->tid = thread_create(bhtty_reader, pp); + } else { + if (pp->tid != NULL) { + pclog("%s: stopping thread..\n", pp->name); + thread_kill(pp->tid); + pp->tid = NULL; + } + } -//pclog("%s: write complete, status %d, num %d\n", pp->name, err, num); -#if 0 - if ( - if (GetOverlappedResult(p->handle, - &p->rov, &mst, TRUE) == FALSE) { - r = GetLastError(); - if (r != ERROR_OPERATION_ABORTED) - /* OK, we're being shut down. */ - sprintf(serial_errmsg, - "%s: I/O read error!", p->name); - return(-1); - } -#endif + return(0); } @@ -502,56 +533,26 @@ bhtty_write_comp(DWORD err, DWORD num, OVERLAPPED *priv) int bhtty_write(BHTTY *pp, unsigned char val) { - DWORD n; + DWORD n = 0; - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid parameter\n"); - return(-1); - } -//pclog("BHwrite(%08lx, %02x, '%c')\n", pp->handle, val, val); - - /* Save the control pointer for later use. */ - pp->wov.hEvent = (HANDLE)pp; - - if (WriteFileEx(pp->handle, - &val, 1, - &pp->wov, - bhtty_write_comp) == FALSE) { +pclog("%s: writing byte %02x\n", pp->name, val); + if (WriteFile(pp->handle, &val, 1, &n, &pp->wov) == FALSE) { n = GetLastError(); - pclog("%s: I/O error %d in write!\n", pp->name, n); - return(-1); + if (n != ERROR_IO_PENDING) { + /* Not good, we got an error. */ + pclog("%s: I/O error %d in write!\n", pp->name, n); + return(-1); + } + + /* The write is pending, wait for it.. */ + if (GetOverlappedResult(pp->handle, &pp->wov, &n, TRUE) == FALSE) { + n = GetLastError(); + pclog("%s: I/O error %d in write!\n", pp->name, n); + return(-1); + } } - /* Its pending, so handled in the completion routine. */ - SleepEx(1, TRUE); - - return(0); -} - - -/* - * A pending READ has finished, handle it. - */ -static VOID CALLBACK -bhtty_read_comp(DWORD err, DWORD num, OVERLAPPED *priv) -{ - BHTTY *pp = (BHTTY *)priv->hEvent; - DWORD r; -//pclog("%s: read complete, status %d, num %d\n", pp->name, err, num); - - if (GetOverlappedResult(pp->handle, &pp->rov, &r, TRUE) == FALSE) { - r = GetLastError(); - if (r != ERROR_OPERATION_ABORTED) - /* OK, we're being shut down. */ - pclog("%s: I/O read error!", pp->name); - return; - } -//pclog("%s: read done, num=%d (%d)\n", pp->name, num, r); - - /* Do a callback to let them know. */ - if (pp->rd_done != NULL) - pp->rd_done(pp->rd_arg, num); + return((int)n); } @@ -561,46 +562,18 @@ bhtty_read_comp(DWORD err, DWORD num, OVERLAPPED *priv) * For now, we will use one byte per call. Eventually, * we should go back to loading a buffer full of data, * just to speed things up a bit. --FvK - * - * Also, not that we do not wait here. We just POST a - * read operation, and the completion routine will do - * the clean-up and notify the caller. */ int bhtty_read(BHTTY *pp, unsigned char *bufp, int max) { - DWORD r; + if (pp->icnt == 0) return(0); - /* Just one byte. */ - max = 1; - - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid parameter\n"); - return(-1); + while (max-- > 0) { + *bufp++ = pp->buff[pp->itail++]; +pclog("%s: dequeued byte %02x (%d)\n", pp->name, *(bufp-1), pp->icnt); + pp->itail &= (sizeof(pp->buff)-1); + if (--pp->icnt == 0) break; } - /* Save the control pointer for later use. */ - pp->rov.hEvent = (HANDLE)pp; -//pclog("%s: read(%08lx, %d)\n", pp->name, pp->handle, max); - - /* Post a READ on the device. */ - if (ReadFileEx(pp->handle, - bufp, (DWORD)max, - &pp->rov, - bhtty_read_comp) == FALSE) { - r = GetLastError(); - if (r != ERROR_IO_PENDING) { - /* OK, we're being shut down. */ - if (r != ERROR_INVALID_HANDLE) - pclog("%s: I/O read error!\n", pp->name); - return(-1); - } - } - - /* Make ourself alertable. */ - SleepEx(1, TRUE); - - /* OK, it's pending, so we are good for now. */ - return(0); + return(max); } diff --git a/src/serial.c b/src/serial.c index bf6e6a45c..c89b9be1b 100644 --- a/src/serial.c +++ b/src/serial.c @@ -33,7 +33,7 @@ * * Based on the 86Box serial port driver as a framework. * - * Version: @(#)serial.c 1.0.6 2017/06/02 + * Version: @(#)serial.c 1.0.7 2017/06/04 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -47,6 +47,9 @@ #include "plat_serial.h" +#define NUM_SERIAL 2 /* we support 2 ports */ + + enum { SERINT_LSR = 1, SERINT_RECEIVE = 2, @@ -137,8 +140,7 @@ enum { #define MSR_MASK (0x0f) -static SERIAL serial1, /* serial port 1 data */ - serial2; /* serial port 2 data */ +static SERIAL ports[NUM_SERIAL]; /* serial port data */ int serial_do_log; @@ -222,16 +224,6 @@ serial_write_fifo(SERIAL *sp, uint8_t dat) } -#ifdef WALTJE -static void -serial_write_str(SERIAL *sp, const char *str) -{ - while (*str) - serial_write_fifo(sp, (uint8_t)*str++); -} -#endif - - static uint8_t read_fifo(SERIAL *sp) { @@ -244,19 +236,6 @@ read_fifo(SERIAL *sp) } -/* BHTTY WRITE COMPLETE handler. */ -static void -serial_wr_done(void *arg) -{ - SERIAL *sp = (SERIAL *)arg; - - /* The WRITE completed, we are ready for more. */ - sp->lsr |= LSR_THRE; - sp->int_status |= SERINT_TRANSMIT; - update_ints(sp); -} - - /* Handle a WRITE operation to one of our registers. */ static void serial_write(uint16_t addr, uint8_t val, void *priv) @@ -278,13 +257,12 @@ serial_write(uint16_t addr, uint8_t val, void *priv) sp->thr = val; if (sp->bh != NULL) { /* We are linked, so send to BH layer. */ -#if 0 - bhtty_write((BHTTY *)sp->bh, - sp->thr, serial_wr_done, sp); -#else bhtty_write((BHTTY *)sp->bh, sp->thr); - serial_wr_done(sp); -#endif + + /* The WRITE completed, we are ready for more. */ + sp->lsr |= LSR_THRE; + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); } else { /* Not linked. Just fake LOOPBACK mode. */ if (! (sp->mctrl & MCR_LMS)) @@ -316,19 +294,25 @@ serial_write(uint16_t addr, uint8_t val, void *priv) baud = ((sp->dlab2<<8) | sp->dlab1); if (baud > 0) { speed = 115200UL/baud; +#ifdef ENABLE_SERIAL_LOG serial_log(2, "Serial%d: divisor %u, baudrate %ld\n", +#endif sp->port, baud, speed); if ((sp->bh != NULL) && (speed > 0)) bhtty_speed((BHTTY *)sp->bh, speed); } else { +#ifdef ENABLE_SERIAL_LOG serial_log(1, "Serial%d: divisor %u invalid!\n", sp->port, baud); +#endif } } wl = (val & LCR_WLS) + 5; /* databits */ sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; +#ifdef ENABLE_SERIAL_LOG serial_log(2, "Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); +#endif if (sp->bh != NULL) bhtty_params((BHTTY *)sp->bh, wl, pa, sb); sp->lcr = val; @@ -344,12 +328,17 @@ serial_write(uint16_t addr, uint8_t val, void *priv) */ if (sp->rts_callback) { sp->rts_callback(sp->rts_callback_p); +#ifdef ENABLE_SERIAL_LOG serial_log(1, "RTS raised; sending ID\n"); +#endif } } if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) { - if (sp->bh == NULL) { + if (sp->bh != NULL) { + /* Linked, start host port. */ + (void)bhtty_active(sp->bh, 1); + } else { /* Not linked, start RX timer. */ timer_add(serial_timer, &sp->receive_delay, @@ -361,11 +350,6 @@ serial_write(uint16_t addr, uint8_t val, void *priv) MSR_DCD | MSR_DDCD); sp->int_status |= SERINT_MSR; update_ints(sp); - -#ifdef WALTJE - /* For testing. */ - serial_write_str(sp, "Welcome!\r\n"); -#endif } } sp->mctrl = val; @@ -420,12 +404,15 @@ static void serial_rd_done(void *arg, int num) { SERIAL *sp = (SERIAL *)arg; -#ifdef WALTJE -serial_log(0, "%04x: %d bytes available: %02x (%c)\n",sp->addr,num,sp->hold,sp->hold); -#endif - /* Stuff the byte in the FIFO and set intr. */ - serial_write_fifo(sp, sp->hold); + /* We can do at least 'num' bytes.. */ + while (num-- > 0) { + /* Get a byte from them. */ + if (bhtty_read(sp->bh, &sp->hold, 1) < 0) break; + + /* Stuff it into the FIFO and set intr. */ + serial_write_fifo(sp, sp->hold); + } } @@ -440,21 +427,19 @@ serial_read(uint16_t addr, void *priv) case 0: /* DATA / DLAB1 */ if (sp->lcr & LCR_DLAB) { ret = sp->dlab1; - break; + } else { + sp->lsr &= ~LSR_DR; + sp->int_status &= ~SERINT_RECEIVE; + update_ints(sp); + ret = read_fifo(sp); + if ((sp->bh == NULL) && + (sp->fifo_read != sp->fifo_write)) + sp->receive_delay = 1000 * TIMER_USEC; } - sp->lsr &= ~LSR_DR; - sp->int_status &= ~SERINT_RECEIVE; - update_ints(sp); - ret = read_fifo(sp); - if ((sp->bh == NULL) && (sp->fifo_read != sp->fifo_write)) - sp->receive_delay = 1000 * TIMER_USEC; break; case 1: /* LCR / DLAB2 */ - if (sp->lcr & LCR_DLAB) - ret = sp->dlab2; - else - ret = sp->ier; + ret = (sp->lcr & LCR_DLAB) ? sp->dlab2 : sp->ier; break; case 2: /* IIR */ @@ -463,9 +448,8 @@ serial_read(uint16_t addr, void *priv) sp->int_status &= ~SERINT_TRANSMIT; update_ints(sp); } - if (sp->fcr & 0x01) { + if (sp->fcr & 0x01) ret |= 0xc0; - } break; case 3: /* LCR */ @@ -512,32 +496,25 @@ serial_setup(int port, uint16_t addr, int irq) { SERIAL *sp; +#ifdef ENABLE_SERIAL_LOG serial_log(0, "Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); +#endif /* Grab the desired port block. */ - sp = (port == 2) ? &serial2 : &serial1; + sp = &ports[port-1]; /* Set up the basic info. */ if (sp->addr != 0x0000) { /* Unlink the previous handler. Just in case. */ io_removehandler(sp->addr, 8, - serial_read, NULL, NULL, - serial_write, NULL, NULL, sp); + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); } sp->addr = addr; sp->irq = irq; /* Request an I/O range. */ io_sethandler(sp->addr, 8, - serial_read, NULL, NULL, - serial_write, NULL, NULL, sp); - -#if 1 - /* Do not disable here, it breaks the SIO chips. */ -#else - /* No DTR/RTS callback for now. */ - sp->rts_callback = NULL; -#endif + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); } @@ -548,17 +525,10 @@ serial_remove(int port) SERIAL *sp; /* Grab the desired port block. */ - sp = (port == 2) ? &serial2 : &serial1; + sp = &ports[port-1]; // FIXME: stop timer, if enabled! -#if 1 - /* Do not disable here, it breaks the SIO chips. */ -#else - /* Remove any callbacks. */ - sp->rts_callback = NULL; -#endif - /* Close the host device. */ if (sp->bh != NULL) (void)serial_link(port, NULL); @@ -566,8 +536,7 @@ serial_remove(int port) /* Release our I/O range. */ if (sp->addr != 0x0000) { io_removehandler(sp->addr, 8, - serial_read, NULL, NULL, - serial_write, NULL, NULL, sp); + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); } sp->addr = 0x0000; sp->irq = 0; @@ -578,21 +547,31 @@ serial_remove(int port) void serial_init(void) { + SERIAL *sp; + int i; + #if ENABLE_SERIAL_LOG serial_do_log = ENABLE_SERIAL_LOG; #endif - memset(&serial1, 0x00, sizeof(SERIAL)); - serial1.port = 1; - serial_setup(serial1.port, SERIAL1_ADDR, SERIAL1_IRQ); -#ifdef xWALTJE - serial_link(serial1.port, "COM1"); -#endif - memset(&serial2, 0x00, sizeof(SERIAL)); - serial2.port = 2; - serial_setup(serial2.port, SERIAL2_ADDR, SERIAL2_IRQ); -#ifdef xWALTJE - serial_link(serial2.port, "COM2"); + /* FIXME: we should probably initialize the platform module here. */ + + /* Initialize each port. */ + for (i=0; iport = (i+1); + + if (i == 0) + serial_setup(sp->port, SERIAL1_ADDR, SERIAL1_IRQ); + else + serial_setup(sp->port, SERIAL2_ADDR, SERIAL2_IRQ); + } + +#ifdef WALTJE + /* Link to host port. */ + serial_link(1, "COM1"); + serial_link(2, "COM2"); #endif } @@ -605,11 +584,15 @@ serial_init(void) void serial_reset(void) { - serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; - serial1.fifo_read = serial1.fifo_write = 0; + SERIAL *sp; + int i; - serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; - serial2.fifo_read = serial2.fifo_write = 0; + for (i=0; iiir = sp->ier = sp->lcr = sp->mctrl = 0x00; + sp->fifo_read = sp->fifo_write = 0x00; + } } @@ -621,19 +604,23 @@ serial_link(int port, char *arg) BHTTY *bh; /* Grab the desired port block. */ - sp = (port == 2) ? &serial2 : &serial1; + sp = &ports[port-1]; if (arg != NULL) { /* Make sure we're not already linked. */ if (sp->bh != NULL) { +#if ENABLE_SERIAL_LOG serial_log(0, "Serial%d already linked!\n", port); +#endif return(-1); } /* Request a port from the host system. */ bh = bhtty_open(arg, 0); if (bh == NULL) { +#if ENABLE_SERIAL_LOG serial_log(0, "Serial%d unable to link to '%s' !\n", port, arg); +#endif return(-1); } sp->bh = bh; @@ -661,7 +648,7 @@ serial_attach(int port, void *func, void *arg) SERIAL *sp; /* Grab the desired port block. */ - sp = (port == 2) ? &serial2 : &serial1; + sp = &ports[port-1]; /* Set up callback info. */ sp->rts_callback = func;