Subject: hp300 DCA lockups (with a fix)
To: None <port-hp300@NetBSD.ORG, bfox@ai.mit.edu>
From: David Carrel <carrel@cisco.com>
List: port-hp300
Date: 02/25/1995 13:23:18
------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <6497.793746808.1@cisco.com>

All,

I have been having troubles for a while with my hp locking up when I
accessed the serial port.  It would just hang solid and nothing but a power
cycle would help.  Several others claim to see this same problem.  I
narrowed down the conditions that cause it to this:  It hangs on the
open(2) of the device, and only when there is input waiting in the buffer.
This happens consistently on my hp380(375) but never on my hp340.

Kudos go to Brian Fox (bfox@ai.mit.edu) for coming up with a fix.  There is
a modem control register for enabling interrupts (MCR_IEN).  The dca driver
only uses this for hp700s but it seems to be needed on my hp380.  In the
following patch (Brian's patch with a tad of cleaning) the MCR_IEN bit is
enabled for all machines.  I have tested this on my hp380 and it seems to
solve the problem completely.  I also tested this on my 340.  The 340 has
the unbuffered dca which does not seem to need (or maybe doesn't even have)
the MCR_IEN bit.  My kernel that uses MCR_IEN doesn't seem to have any
negative side effects on the 340.

Both the 380 and the 340 claim to have the hp98644 serial port, though the
two are very different.  The dca code claims to work on the 98644 and the
98626.  I have no way of testing this fix on the 98626.  Anyone out there
have one of these?  Anyone know what it is?

Enjoy, and thanks Brian.

Dave


------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <6497.793746808.2@cisco.com>
Content-Description: patch to sys/arch/hp300/dev/dca.c

*** /home/carrel/NetBSD/dca.c	Sat Feb 25 12:33:32 1995
--- dca.c	Sat Feb 25 12:55:06 1995
***************
*** 43,51 ****
   *	98626/98644/internal serial interface on hp300/hp400
   *	internal serial ports on hp700
   *
!  *  N.B. On the hp700, there is a "secret bit" with undocumented behavior.
!  *  The third bit of the Modem Control Register (MCR_IEN == 0x08) must be
!  *  set to enable interrupts.
   */
  #include <sys/param.h>
  #include <sys/systm.h>
--- 43,52 ----
   *	98626/98644/internal serial interface on hp300/hp400
   *	internal serial ports on hp700
   *
!  *  On the hp700 and some hp300s, there is a "secret bit" with undocumented
!  *  behavior.  The third bit of the Modem Control Register (MCR_IEN == 0x08)
!  *  must be set to enable interrupts.  On hp300s without this bit, there
!  *  seems to be no side effects to setting it anyway.
   */
  #include <sys/param.h>
  #include <sys/systm.h>
***************
*** 568,576 ****
  
  	dca = dca_addr[unit];
  	dca->dca_ier = IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC;
- #ifdef hp700
  	dca->dca_mcr |= MCR_IEN;
- #endif
  	if (ospeed == 0) {
  		(void) dcamctl(unit, 0, DMSET);	/* hang up line */
  		return (0);
--- 569,575 ----
***************
*** 669,675 ****
  
  	unit = UNIT(dev);
  	dca = dca_addr[unit];
- #ifdef hp700
  	/*
  	 * Always make sure MCR_IEN is set (unless setting to 0)
  	 */
--- 668,673 ----
***************
*** 682,688 ****
  		bits |= MCR_IEN;
  	else if (how == DMBIC)
  		bits &= ~MCR_IEN;
- #endif
  	s = spltty();
  	switch (how) {
  
--- 680,685 ----
***************
*** 800,808 ****
  	dca->dca_ier = rate >> 8;
  	dca->dca_cfcr = CFCR_8BITS;
  	dca->dca_ier = IER_ERXRDY | IER_ETXRDY;
- #ifdef hp700
  	dca->dca_mcr |= MCR_IEN;
- #endif
  	dca->dca_fifo = FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_14;
  	DELAY(100);
  	stat = dca->dca_iir;
--- 797,803 ----

------- =_aaaaaaaaaa0--