Главная страница


ru.linux

 
 - RU.LINUX ---------------------------------------------------------------------
 From : Stanislav Safronov                   2:5020/630     04 Feb 2003  00:20:18
 To : All
 Subject : dosemu serial patch
 -------------------------------------------------------------------------------- 
 
 * Originally in ru.linux
 * Crossposted in su.ra
 
 Кидаю патчи для корректной работы 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 */
 
      s_printf("SER%d: FOSSIL 0x00: Initialize port %d, AL=0x%02x\n",
 @@ -225,11 +225,18 @@ void fossil_int14(int num)
 
    /* Write character (without wait) */
    case 0x0b:
 -    write_char(num, LO(ax));
 +    if (!com[num].tx_overflow){
 +      write_char(num, LO(ax));
 +      LWORD(eax)= 1;
 +    #if SER_DEBUG_FOSSIL_RW
 +      s_printf("SER%d: FOSSIL 0x0b: Write char 0x%02x, return AX=%d\n", num,
 LO(ax), 1);
 +    #endif
 +    }else{
      #if SER_DEBUG_FOSSIL_RW
        s_printf("SER%d: FOSSIL 0x0b: Write char 0x%02x, return AX=%d\n", num,
 LO(ax), !com[num].tx_overflow);
      #endif
      LWORD(eax) = !com[num].tx_overflow;
 +    }
      break;
 
    /* Block read */
 === Cut ===
 
 Здесь пример хаков если у ВАС модем на 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 --> %d\n",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 ===
 
 Этот патчик для mgetty для запуска BBS по ESC-ESC!
 === Cut ===
 -+- logname.c   Tue Sep  1 14:56:20 1998
 +++ logname.c   Mon Dec  2 23:40:30 2002
 @@ -473,6 +473,18 @@
  #endif
         }
     }
 +   else{
 +       if ( i >= maxsize )         /* buffer full, */
 +       fputs( "\b \b", stdout );       /* -> ignore */
 +       else
 +         if(i==0||buf[i-1]!=27)
 +       buf[i++] = ch;
 +         else{
 +       strcpy(buf,"bbs\n");i=4;
 +       lprintf( L_MESG, "BBS call!" );
 +       break;
 +         }
 +   }
      }
      while ( ch != '\n' && ch != '\r' );
 
 === Cut ===
 
 Stanislav
 
 --- GoldED+/LNX 1.1.4.7
  * Origin: -= Crazy Students BBS 423-3328 Time 00:00-05:30 =- (2:5020/630)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 dosemu serial patch   Stanislav Safronov   04 Feb 2003 00:20:18 
Архивное /ru.linux/207423e3ed4ba.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional