Date: Wed, 15 Jan 2003 22:36:38 +0500
From: Stanislav Safronov <Stanislav_Safronov@f630.n5020.z2.fidonet.org>
Newsgroups: ftn.ru.linux
Subject: Патчи для корректной работы c COM портами в dosemu
Кидаю патчи для корректной работы c COM портами и fossil dosemu-1.1.4 и предидущих
версий!!!
Удивительно, что народ как минимум с 1998 не исправил ошибки... А
жалобные стоны раздаются и по сей день в инете на работу dosemu с портами,
ошибками в zmodem и пр.
Теперь BBS/BW должна нормально работать на трансфер файлов пользователям (проверены
временем на RA/ELE/BlueWave).
Изменения коснулись и *fossil* драйвера. Судя по архиву эхи уверен, что кому-то эти
патчи пригодятся, поэтому кидаю в эху. Они маленькие:
Исправлены ошибки(эта ошибка во многих версиях dosemu):
=== Cut ===
-+- ser_irq.c.old Wed Dec 18 04:36:38 2002
+++ ser_irq.c Tue Jan 7 00:22:02 2003
@@ -160,13 +160,20 @@ void transmit_engine(int num) /* Interna
if (!(control & TIOCM_CTS)) return; /* Return if CTS is low */
}
- if (com[num].tx_overflow) { /* Is it in overflow state? */
- rtrn = RPT_SYSCALL(write(com[num].fd, &com[num].TX, 1)); /* Write port */
- if (rtrn == 1) /* Did it succeed? */
- com[num].tx_overflow = 0; /* Exit overflow state */
- }
- else if (com[num].fifo_enable) { /* Is FIFO enabled? */
+ if (com[num].fifo_enable) { /* Is FIFO enabled? */
+ if (com[num].tx_overflow){
+ if(RPT_SYSCALL(write(com[num].fd, &com[num].tx_buf[com[num].tx_buf_start],
1))!=1){
+ return; /* write error */
+ }else{
+ /* Squeeze char into FIFO */
+ com[num].tx_buf[com[num].tx_buf_end] = com[num].TX ;
+ /* Update FIFO queue pointers */
+ com[num].tx_buf_end = (com[num].tx_buf_end + 1) % TX_BUFFER_SIZE;
+ com[num].tx_buf_start = (com[num].tx_buf_start + 1) % TX_BUFFER_SIZE;
+ com[num].tx_overflow = 0; /* Exit overflow state */
+ }
+ }
/* Clear as much of the transmit FIFO as possible! */
while (com[num].tx_buf_bytes > 0) { /* Any data in fifo? */
rtrn = RPT_SYSCALL(write(com[num].fd, &com[num].tx_buf[com[num].tx_buf_start], 1));
@@ -184,6 +191,11 @@ void transmit_engine(int num) /* Interna
}
}
else { /* Not in FIFO mode */
+ if (com[num].tx_overflow) { /* Is it in overflow state? */
+ rtrn = RPT_SYSCALL(write(com[num].fd, &com[num].TX, 1)); /* Write port */
+ if (rtrn == 1) /* Did it succeed? */
+ com[num].tx_overflow = 0; /* Exit overflow state */
+ }
if (com[num].tx_trigger) { /* Is it time to trigger int */
com[num].tx_trigger = 0;
com[num].LSRqueued |= UART_LSR_TEMT | UART_LSR_THRE;
=== Cut ===
В фосиле была ошибка все это время патчите!!:
=== Cut ===
-+- fossil.c.old Wed Dec 18 04:36:38 2002
+++ fossil.c Sat Jan 18 01:12:56 2003
@@ -93,7 +93,7 @@ void fossil_int14(int num)
case 0x00:
{
int lcr;
- int divisors[] = { DIV_19200, DIV_38400, DIV_300, DIV_600, DIV_1200,
+ int divisors[] = { DIV_19200, DIV_115200, DIV_300, DIV_600, DIV_1200,
DIV_2400, DIV_4800, DIV_9600 }; /* hack for 3840 -- 115200 */
Здесь пример хаков если у ВАС модем на COM3, если быть внимаетельным, то в последней
версии многие программы могли не работать!!! Правте этот патч под ваши значения (это
патч-хак):
=== Cut ===
-+- ser_init.c.old Wed Dec 18 04:36:44 2002
+++ ser_init.c Tue Jan 7 12:14:19 2003
@@ -246,6 +246,10 @@ static int ser_open(int num)
}
}
else
+ if (com[num].real_comport==3) {
+ com[num].dev_locked = TRUE; /* hack for COM3 */
+ }
+ else
if ( tty_lock(com[num].dev, 1) >= 0) { /* Lock port */
/* We know that we have access to the serial port */
com[num].dev_locked = TRUE;
@@ -347,8 +351,10 @@ static void ser_set_params(int num)
/* Pull down DTR and RTS. This is the most natural for most comm */
/* devices including mice so that DTR rises during mouse init. */
if (!com[num].virtual) {
- data = TIOCM_DTR | TIOCM_RTS;
- ioctl(com[num].fd, TIOCMBIC, &data);
+ if (!com[num].virtual && com[num].real_comport!=3) { /* hack for COM3 */
+ data = TIOCM_DTR | TIOCM_RTS;
+ ioctl(com[num].fd, TIOCMBIC, &data);
+ }
}
}
@@ -372,7 +378,7 @@ static int ser_close(int num)
/* Clear the lockfile from DOSEMU */
if (com[num].dev_locked) {
- if (tty_lock(com[num].dev, 0) >= 0)
+ if (com[num].real_comport==3 || tty_lock(com[num].dev, 0) >= 0) /* HACK COM3 */
com[num].dev_locked = FALSE;
}
return (i);
@@ -474,8 +480,11 @@ static void do_ser_init(int num)
* If this is nonzero, Linux will handle RTS/CTS flow control directly.
* DANG_FIXTHIS This needs more work before it is implemented into /etc/dosemu.conf as an 'rtscts' option.
*/
- com[num].system_rtscts = 0;
-
+ if (com[num].real_comport==3) { /* HACK COM3 */
+ com[num].system_rtscts = 1;
+ }else{
+ com[num].system_rtscts = 0;
+ }
/* convert irq number to pic_ilevel number and set up interrupt
* if irq is invalid, no interrupt will be assigned
*/
@@ -548,7 +557,11 @@ static void do_ser_init(int num)
serial_timer_update();
/* Set file descriptor as unused, then attempt to open serial port */
- com[num].fd = -1;
+ com[num].fd = -1;
+ if (com[num].real_comport==3) { /* hack COM3 */
+ ser_open(num);
+ ser_set_params(num);
+ }
}
=== Cut ===
Этот патч улучшает прием при RTSCTS:
=== Cut ===
-+- ser_ports.c.old Wed Dec 18 04:36:38 2002
+++ ser_ports.c Sat Jan 18 01:22:59 2003
@@ -73,18 +73,15 @@ static inline void tx_buffer_dump(int nu
/* This function updates the flow control status depending on buffer condition */
-static inline void flow_control_update(int num)
+static inline void flow_control_update(int num, u_char rts)
{
static int control;
- if (com[num].rx_buf_bytes == 0) { /* buffer empty? */
- control = TIOCM_RTS;
+ control = TIOCM_RTS;
+ if (rts)
ioctl(com[num].fd, TIOCMBIS, &control); /* Raise RTS */
- }
- else { /* Buffer has chars */
- control = TIOCM_RTS;
+ else
ioctl(com[num].fd, TIOCMBIC, &control); /* Lower RTS */
- com[num].rx_timer = RX_READ_FREQ; /* Reset rcv read() timer */
- }
+ s_printf("SER%d: RTS --> %dn",num,rts);
}
@@ -118,13 +115,23 @@ static inline void rx_buffer_slide(int n
void uart_fill(int num)
{
static int size;
+ static int control;
/* Return if in loopback mode */
if (com[num].MCR & UART_MCR_LOOP) return;
/* If DOSEMU is given direct rts/cts control then update rts/cts status. */
- if (com[num].system_rtscts) flow_control_update(num);
-
+ if (com[num].system_rtscts){
+ ioctl(com[num].fd, TIOCMGET, &control);
+ if (com[num].rx_buf_bytes<RX_BUFFER_SIZE/2) { /* buffer empty? */
+ if(!(control & TIOCM_RTS))
+ flow_control_update(num,1);
+ }else{
+ com[num].rx_timer = RX_READ_FREQ; /* Reset rcv read() timer */
+ if(control & TIOCM_RTS)
+ flow_control_update(num,0);
+ }
+ }
/* Is it time to do another read() of the serial device yet?
* The rx_timer is used to prevent system load caused by empty read()'s
* It also skip the following code block if the receive buffer
@@ -148,8 +155,10 @@ void uart_fill(int num)
com[num].rx_timer = RX_READ_FREQ; /* Reset rcv read() timer */
}
else if (size > 0) { /* Note that size is -1 if error */
- com[num].rx_timeout = TIMEOUT_RX; /* Reset timeout counter */
com[num].rx_buf_bytes += size; /* No. of chars in buffer */
+ if (com[num].system_rtscts && com[num].rx_buf_bytes>(RX_BUFFER_SIZE/2))
+ flow_control_update(num,0);
+ com[num].rx_timeout = TIMEOUT_RX; /* Reset timeout counter */
}
}
}
=== Cut ===
По желанию, у меня на P-166 без включения отладки замечательно работает:
=== Cut ===
-+- serial.h.old Wed Dec 18 04:36:38 2002
+++ serial.h Sat Jan 18 01:42:14 2003
@@ -42,8 +42,8 @@
*
* DANG_FIXTHIS Why does a RX_BUFFER_SIZE of 256 cause slower performance than a
size of 128?
*/
-#define RX_BUFFER_SIZE 128
-#define TX_BUFFER_SIZE 64
+#define RX_BUFFER_SIZE 2048
+#define TX_BUFFER_SIZE 2048
EXTERN u_char irq_source_num[255]; /* Index to map from IRQ no. to serial port */
EXTERN u_char com_port_used[17]; /* Used for auto-assign comport config */
@@ -106,13 +106,13 @@ typedef struct serial_struct {
* is still emulated using a counter, to improve compatibility.
*/
u_char rx_buf[RX_BUFFER_SIZE]; /* Receive Buffer */
- u_char rx_buf_start; /* Receive Buffer queue start */
- u_char rx_buf_end; /* Receive Buffer queue end */
- u_char rx_buf_bytes; /* # of bytes in Receive Buffer */
+ int rx_buf_start; /* Receive Buffer queue start */
+ int rx_buf_end; /* Receive Buffer queue end */
+ int rx_buf_bytes; /* # of bytes in Receive Buffer */
u_char tx_buf[TX_BUFFER_SIZE]; /* Transmit Buffer */
- u_char tx_buf_start; /* Transmit Buffer queue start */
- u_char tx_buf_end; /* Transmit Buffer queue end */
- u_char tx_buf_bytes; /* # of bytes in Transmit Buffer */
+ int tx_buf_start; /* Transmit Buffer queue start */
+ int tx_buf_end; /* Transmit Buffer queue end */
+ int tx_buf_bytes; /* # of bytes in Transmit Buffer */
struct termios oldset; /* Original termios settings */
struct termios newset; /* Current termios settings */
=== Cut ===