Subject: kern/8645: SCSI tape spacing times out immediately on 32-bit archs with clocks > 150Hz
To: None <gnats-bugs@gnats.netbsd.org>
From: None <mhitch@montana.edu>
List: netbsd-bugs
Date: 10/18/1999 11:03:47
>Number:         8645
>Category:       kern
>Synopsis:       Tape spacing times out immediately on 32 bit architectures with RTC clock > 150 Hz
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Oct 18 11:03:00 1999
>Last-Modified:
>Originator:     Michael L. Hitch
>Organization:
	
	ITC
	Montana State University
>Release:        1.4.1 <NetBSD-current source date>
>Environment:
	
System: NetBSD news.msu.montana.edu 1.4 NetBSD 1.4 (NEWS) #990517C-5: Wed Jul 7 16:11:57 MDT 1999 mhitch@news.msu.montana.edu:/d/d/sys/arch/pmax/compile/NEWS pmax


>Description:
	
	On 32 bit architectures running with an RTC clock faster than 150Hz
	(such as DECstations) a tape spacing operation with the ncr53c9x
	driver will timeout immediately.  It appears to me that this should
	also occur with several other SCSI drivers that compute the
	timeout in the same manner.

	The problem is that the timeout is computed as:
                timeout(ncr53c9x_timeout, ecb,
                    (ecb->timeout * hz) / 1000);

	The value for hz on DECstations is 256, and the ecb->timeout value
	for some tape commands is 4 * 60 * 60 * 1000.  The multiply
	overflows a 32 bit signed integer, resulting in a negative timeout.
	Values for hz between 150 and 298 result in negative overflows.
>How-To-Repeat:
	
	Build a DECstation kernel using the MI ncr53c9x and try to use a
	tape drive.  The ncr53c9x driver immediately times out.
>Fix:
	
	I was able to workaround this by making ecb->timeout an unsigned
	value.

	Another possibilty would be to do the divide by 1000 before
	multiplying by hz, but this would result in inaccuracies for
	small timeout values.  Doing the multiply first for small timeouts
	and the divide first for larger timeouts should result in more
	accurate calculations, at the expense of slightly more code.
>Audit-Trail:
>Unformatted: