From owner-freebsd-hackers Mon Apr 1 07:09:47 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id HAA29051 for hackers-outgoing; Mon, 1 Apr 1996 07:09:47 -0800 (PST) Received: from lserver.infoworld.com (lserver.infoworld.com [192.216.48.4]) by freefall.freebsd.org (8.7.3/8.7.3) with SMTP id HAA29044 Mon, 1 Apr 1996 07:09:44 -0800 (PST) Received: from ccgate.infoworld.com by lserver.infoworld.com with smtp (Smail3.1.29.1 #12) id m0u3laX-000x1UC; Mon, 1 Apr 96 07:32 PST Received: from cc:Mail by ccgate.infoworld.com id AA828371297; Mon, 01 Apr 96 02:14:11 PST Date: Mon, 01 Apr 96 02:14:11 PST From: "Brett Glass" Message-Id: <9603018283.AA828371297@ccgate.infoworld.com> To: freebsd-hardware@freebsd.org, freebsd-hackers@freebsd.org Subject: Hacked kernel with option to disable "green" mode Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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