Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 01 Apr 96 02:14:11 PST
From:      "Brett Glass" <Brett_Glass@ccgate.infoworld.com>
To:        freebsd-hardware@freebsd.org, freebsd-hackers@freebsd.org
Subject:   Hacked kernel with option to disable "green" mode
Message-ID:  <9603018283.AA828371297@ccgate.infoworld.com>

next in thread | raw e-mail | index | archive | help
Tonight, I bit the bullet and hacked the FreeBSD kernel (specifically, the
wdc driver) to disable "green" mode on LARIAT.ORG's ST5660A IDE hard drive.
As reported in earlier messages, the drive was retracting its heads and
spinning down during periods of inactivity, which caused FreeBSD's disk
routines to time out and complain. The system would splatter the screen
with kernel error messages and freeze for seconds at a time. (I haven't
tried FreeBSD on a laptop, but this must occur frequently in that
environment if the same kind of drive is used.)

In any event, after an extensive search of the Web, I dredged up the key
piece of information needed to solve the problem from the archive

ftp://ftp.seagate.com/techsuppt/misc/no_idle.zip

on Seagate's Web site.  Essentially, to turn off the "green mode"
inactivity timer, one issues controller command 0xFB for the relevant
drive, with a 0 in the controller's sector count register, during
initialization. (A number larger than zero sets the timer to that number of
milliseconds.)

I'm not a UNIX kernel hacker (or I wasn't, anyway), and was utterly
unfamiliar with all the conventions used in FreeBSD, so the source in
wd.c took quite a while to analyze. (It's much more complex than it needs
to be, and uses -- Aargh! -- uninterruptible busy-waits at the kernel
level.  THIS is why the entire OS freezes for seconds at a time.) After
much staring at the code, I figured out how to get an existing
function to do most of the work. The increase in kernel size was therefore
negligible.

Turning "green mode" off should be optional, so I grabbed two apparently
unused configuration flag bits -- 0x0100 and 0x0200 -- for wdc. (The
configuration utility doesn't expose flag words for the individual drives;
if it did, the flags would really belong THERE.) These bits disable
inactivity timeouts on the master and slave drives, respectively.

The new kernel seemed to work without breaking anything, but since I
haven't played with this code before, and am not ENTIRELY sure that I
didn't step on something, I'd like a second or third opinion.

[Aside: Maybe, at the same time, someone could tell me what the SLEEPHACK
configuration bit does. It looks as if it's supposed to make the driver
more tolerant of drive spindowns on laptops, but I'm not sure that it will
work as advertised. On this machine, the unwedge() function, which it
calls, also complains when the disk spins down.]

I don't know how integration of kernel modifications into FreeBSD works,
but I'd be glad to send the diffs for the two files I changed (wd.c and
wdreg.h) to anyone who wants them. (I started with 2.1.0-RELEASE.)
Feel free to integrate them into -current, and add information about the
flags to the FAQ.  Maybe this will save the next person the week of agony I
endured before I figured out how to get this system running.

--Brett




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9603018283.AA828371297>