From owner-freebsd-bugs Tue Jan 19 19:22:37 1999 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id TAA19851 for freebsd-bugs-outgoing; Tue, 19 Jan 1999 19:22:37 -0800 (PST) (envelope-from owner-freebsd-bugs@FreeBSD.ORG) Received: from geocities.com (mail10.geocities.com [209.1.224.138]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id TAA19846 for ; Tue, 19 Jan 1999 19:22:35 -0800 (PST) (envelope-from yaldabaoth@geocities.com) Received: from geocities.com (207-172-144-131.s4.as2.fdk.erols.com [207.172.144.131]) by geocities.com (8.9.1/8.9.1) with ESMTP id TAA23125; Tue, 19 Jan 1999 19:21:35 -0800 (PST) Message-ID: <36A54AEA.81B56C88@geocities.com> Date: Tue, 19 Jan 1999 22:18:03 -0500 From: Andrew Sherrod X-Mailer: Mozilla 4.06 [en] (Win98; U) MIME-Version: 1.0 To: Bruce Evans CC: freebsd-bugs@FreeBSD.ORG, ixkatl@yahoo.com Subject: Re: [Modified Patch] Re: i386/9431: wd.c Does nto recognize certain LBA disks [patch attached] References: <199901121651.DAA10604@godzilla.zeta.org.au> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org I am afraid my initial posting to GNATS / bugs@FreeBSD.org was unclear. Judging from your response I assume you thought I was reporting a problem with LBA support. However, what I am reporting is not an LBA issue but an issue with disk geometry. However, as several postings to -bugs and -current have passed without comment, I will assume that others have also decided that this patch is not worth considering. I can see only three reasons for this: 1. They consider the problem unimportant. 2. They do not think the patch works. 3. They worry the patch will break existing code. Thus, I have decided to address these three points and, hopefully, in the process, show that the two attached changes to existing code are worth making. 1. Background For those unfamiliar with the wd.c code, I will present a short description of how FreeBSD handles disk geometry. If a disk partition table (either DOS or FreeBSD) exists, the kernel will accept the reported number of cylinders heads and sectors ("CHS geometry"). Otherwise, the drive will be polled and return a lengthy structure as specified in "Information Technology - AT Attachment Interface with Extensions (ATA-2) Working Draft" (ASC X3T10 Revision 4c Mar. 18 1996) ("ATA-2"). This structure, among other things, defines the CHS geometry of the disk (words 1,3,and 6) , returning the number of cylinders, heads, and sectors. This structure also contains a set of flags (word 49) showing disk capabilities (wdp_capability in wd.c's wdparam structure), including whether DMA and LBA are supported. In both 2.2.8 and 3.0 these flags are ignored. A third part of the structure returns the "LBA size" (words 60-61) which is used by LBA to determine disk size. This value is used by FreeBSD under a few specific circumstances: 1. In 3.0 ONLY, if the user specifies LBA mode, and the product obtained by multiplying C*H*S is less than lba_size, then lba_size is used. 2. In both 2.2.8 and 3.0, if the number of cylinders is 16383 and lba_size is greater than the CHS product, then lba_size is used. If user LBA is not defined, and number of reported cylinders is not 16383, a disk without a partition table will be seen by FreeBSD to have a size defined by: Sectors(total) = ( (Cylinders * Heads/Cylinder) * Sectors/ Head) There is one problem with this model, however. (And I know this is a point which some will debate). Certain BIOSes (in my case Award Modular BIOS v 4.51PG ), do not return a Cylinder count of 16383 for disks smaller than 8 GB, nor do they return a cylinder value which makes the CHS size match the LBA size. Instead, these BIOSes return a fictitious Cylinder count (in my case, and at least one other in the mailing list archives, 4092). It is this problem I hope to correct with the attached patches.. 2. Why This Problem Should Be Corrected Even a cursory examination of GNATS and the mailing list archives will show that incorrect disk geometry is one of the most prevalent complaints during a FreeBSD installation. Complaints about drives reporting 4092 cylinders, not recognizing disks over 8GB, producing false CHS geometries when using "dangerously dedicated" disks, and others are numerous. The problem is so common, that the "solution" of creating a temporary DOS partition has made its way into the handbook, FAQs, and Mr. Lehey's manual. And it IS a problem. How popular would Microsoft products be, if every new user was told, "Oh, we can recognize several drives, and if we can't, just put a Linux file system on the disk"? I speak from experience. I almost gave up on my first FreeBSD installation because it had lopped almost 2 GB of space off each of two disk drives. If it is our hope to attract new (read "novice") users, we cannot afford such user unfriendliness during their first encounter with the system. Installation is intimidating enough without the added headache of sifting through the FAQs only to discover they must stop and add a superfluous DOS partition just to get the use of all their disk space. I know at this point many readers are thinking, "But how often do you install the system?" And that is true. In fact, I think it may explain why I received so little response. My readers are already proficient. They already have a system up and running. They have disks which are configured correctly. They haven't seen an fresh install in quite some time. And even if they have, they know exactly how to fix the problem. Even the DOS work-around is an old familiar practice. They don't think of it as a problem. But to the new user, this is not the case. Most people come to UN*X systems because they have complaints against Microsoft, and to be told that we rely upon Microsoft for our disk partitioning reduces our credibility quite a bit. (To be fair at this point, we are not alone in this problem. Three different Linux systems gave the same incorrect geometries. But that does not excuse us from trying to fix the problem.) We often talk about publicity, and expanding the user base. Yet we do not take simple steps to make the new user's first encounter less intimidating. Too often we take a reasonable question and brush it off with "RTFM". And all too often it is a problem which could be easily fixed, but which is not interesting enough to attract a developer, or else it is a problem only encountered by newbies who don't have enough experience to fix it, and is thus unknown to, because it does not effect, those with more experience. This is such a problem. Fortunately, it annoyed me enough that I spent some time (and made quite a few false starts, as my GNATS PR will show) and found a relatively simple solution. 3. Do the Patches Work Well, the simplest answer is to show my dmesg output before and after the fix. My system has 3 drives. Wd0 is an 8 GB Quantum Fireball. Wd1 is a 3 GB Western Digital. Wd2 is a 4.1 GB Maxtor. The dmesg before the patch (same output for both 2.2.8 and 3.0) edited to show only the relevant portions: fdc0 at 0x3f0-0x3f7 irq 6 drq 2 on isa fdc0: FIFO enabled, 8 bytes threshold fd0: 1.44MB 3.5in wdc0 at 0x1f0-0x1f7 irq 14 on isa wdc0: unit 0 (wd0): wd0: 8063MB (16514064 sectors), 16383 cyls, 16 heads, 63 S/T, 512 B/S wdc0: unit 1 (wd1): wd1: 2014MB (4124736 sectors), 4092 cyls, 16 heads, 63 S/T, 512 B/S wdc1 at 0x170-0x177 irq 15 on isa wdc1: unit 0 (wd2): wd2: 1888MB (3866940 sectors), 4092 cyls, 15 heads, 63 S/T, 512 B/S wdc1: unit 1 (atapi): , removable, intr, dma, iordis wcd0: 5512KB/sec, 256KB cache, audio play, 255 volume levels, ejectable tray wcd0: no disc inside, unlocked As you can see, wd1 and wd2 are both reported to be much smaller than they really are. And both are also reporting 4092 cylinders. Here is dmesg after the patch.(Once again 2.2.8 and 3.0 showed the same results). fdc0 at 0x3f0-0x3f7 irq 6 drq 2 on isa fdc0: FIFO enabled, 8 bytes threshold fd0: 1.44MB 3.5in wdc0 at 0x1f0-0x1f7 irq 14 on isa wdc0: unit 0 (wd0): wd0: 8063MB (16514064 sectors), 16383 cyls, 16 heads, 63 S/T, 512 B/S wdc0: unit 1 (wd1): wd1: 3020MB (6185088 sectors), 6136 cyls, 16 heads, 63 S/T, 512 B/S wdc1 at 0x170-0x177 irq 15 on isa wdc1: unit 0 (wd2): wd2: 4120MB (8439184 sectors), 8930 cyls, 15 heads, 63 S/T, 512 B/S wdc1: unit 1 (atapi): , removable, intr, dma, iordis wcd0: 5512KB/sec, 256KB cache, audio play, 255 volume levels, ejectable tray wcd0: no disc inside, unlocked Once the patch is applied, wd1 and wd2 both show the correct size. In addition, to prove that the pacth works for system installtion, I ran /stand./sysinstall for 3.0 (Release) from both the CD and from the hard-drive (using the patched kernel). After removing the partition table from the two smaller disks, I tried the CD install. The kernel reported the incorrect size for both wd1 and wd2. I tried to enter the correct geometry on the "slice" page, but when I selected "A" to use the whole disk, it returned to the incorrect geometry. I then completed installation. After installation df and fdisk both showed the same incorrect geometry. I then cleared the disk partitions again from wd1 and wd2 (both '/usr' and '/' are on wd0), installed my 3.0 patch, and ran /stand/sysinstall from the hard drive. This time the installation "slice" screen showed the correct geometry for all 3 disks. After a minimal install (just to commit the changes), df, fdisk and dmesg all reported the correct geometries. For anyone who has followed my lengthy trail of patches, I admit my first few attempts had some unwanted side effects, but I shall defer those to the next section. Why does this patch work? Basically, the patch checks word 49 (the LBA/DMA/etc. flags) returned by the BIOS and, if the LBA bit is set and lba_size is greater than the CHS product, uses the lba_size. This is supported by the ATA-2 standard. Page 40 states (regarding the LBA bit) "If this bit is set, words 60-61 [lba_size] shall be valid." Thus, if the LBA bit is active, then the LBA size gives an accurate measurement of the disk size. if this size is larger than the CHS geometry indicates, the CHS geometry must be in error. (To forestall any objections that pre-ATA-2 drives may give incorrect values for both capabilities and lba_size, I shall address that objection in the following section as well.) 4. Does the Patch break Existing Code I will be the first to admit that my first few attempts resulted in unwanted side effects. My initial attempts actually forced DMA and LBA on if they were supported, whether the user activated them or not. However, I think the current patch avoids any such problems. I have run it on both a 2.2.8 and a 3.0 (Release) system, with no consequences. The only valid objection I have heard raised to my patches is that certain older disks and BIOSes may incorrectly return an LBA flag and garbage data in the lba_size. However, as I have said before, this raises the question whether we want to support the bugs of older disks or the bugs of newer BIOSes. Those using the older hardware are usually more experienced and sometimes are contributors themselves, thus, we have a tendency to support old bugs rather than new. However, in this case, I think supporting new bugs is preferable. Disks wear out faster than motherboards, and Award isn't likely to fix this bug any time soon. And, since ATA-2 came into effect in the mid 1990's, noncompliant disks are likely to vanish as time goes on, while Award is not violating any standards in their somewhat buggy BIOS, so they have little reason to change. (And, since it doesn't cause any problems for Microsoft products, which are by far their largest market, they have no financial incentive to change.) Those using old non-ATA-2 compliant disks are likely to be a small minority growing ever smaller as those disks wear out or are replaced, while those using newer Award BIOSes is a group likely to grow. Thus, it seems that this patch likely fixes more problems than it creates, and this is even more true in the future than it is now. Well, having addressed all your concerns (I hope) I ask that anyone who has an objection or finds a problem with this code to please send it to me at ixkatl@yahoo.com . I do not believe this patch causes any major problems, but I welcome any comment or criticism. Thanks. Andrew Sherrod -------------------------------------------------------------------------------------------------------- DIFFS: -------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------- 3.0 Release -------------------------------------------------------------------------------------------------------- *** wd.c Mon Jan 18 19:39:22 1999 --- wd.c.original Mon Jan 18 18:24:14 1999 *************** *** 120,131 **** #define WDOPT_MULTIMASK 0x00ff /* - * This define is used to determine if the drive is LBA capable - */ - - #define WDCAP_LBA 0x02 - - /* * This biotab field doubles as a field for the physical unit number on * the controller. */ --- 120,125 ---- *************** *** 1940,1960 **** du->dk_dd.d_ntracks * du->dk_dd.d_nsectors; du->dk_dd.d_secperunit = du->dk_dd.d_secpercyl * du->dk_dd.d_ncylinders; ! ! /* ! * tThe following change determines if the disk ! * is LBA capable. If it is, and the lba size is ! * larger than the CHS size, use the LBA size. ! * This should allow certain difficult BIOSES ! * (eg. Award) which do not report the correct ! * CHS size to still give an accurate measure ! * of disk size,w ithout forcing the user to ! * enable LBA mode. ! * A. Sherrod (01/18/1999) ! */ ! ! if ( ( (wp->wdp_capability & WDCAP_LBA) || ! (wp->wdp_cylinders == 16383) ) && du->dk_dd.d_secperunit < wp->wdp_lbasize) { du->dk_dd.d_secperunit = wp->wdp_lbasize; du->dk_dd.d_ncylinders = --- 1932,1938 ---- du->dk_dd.d_ntracks * du->dk_dd.d_nsectors; du->dk_dd.d_secperunit = du->dk_dd.d_secpercyl * du->dk_dd.d_ncylinders; ! if (wp->wdp_cylinders == 16383 && du->dk_dd.d_secperunit < wp->wdp_lbasize) { du->dk_dd.d_secperunit = wp->wdp_lbasize; du->dk_dd.d_ncylinders = -------------------------------------------------------------------------------------------------------- 2.2.8 -------------------------------------------------------------------------------------------------------- *** wd.c.2_2_8 Wed Jan 13 21:07:30 1999 --- wd.c.original.2_2_8 Wed Jan 13 21:08:24 1999 *************** *** 113,122 **** #define WDOPT_FORCEHD(x) (((x)&0x0f00)>>8) #define WDOPT_MULTIMASK 0x00ff - /* This bit mask is used to determine if the drive supports LBA addressing. */ - - #define WDCAP_LBA 0x02 - /* * This biotab field doubles as a field for the physical unit number on * the controller. --- 113,118 ---- *************** *** 1731,1745 **** du->dk_dd.d_nsectors = wp->wdp_sectors; du->dk_dd.d_secpercyl = du->dk_dd.d_ntracks * du->dk_dd.d_nsectors; du->dk_dd.d_secperunit = du->dk_dd.d_secpercyl * du->dk_dd.d_ncylinders; ! ! /* Check for BIOS LBA flag. This should allow kernel to determine ! actual disk geometry for diffiuclt BIOSes. ! This will likely only be of use during initial installation, or ! perhaps when configuring a new drive. Otherwise, the disk geometry ! should already be known. -A. Sherrod 01/13/1999*/ ! ! if ( ( (wp->wdp_capability & WDCAP_LBA) || ! (wp->wdp_cylinders == 16383 ) ) && du->dk_dd.d_secperunit < wp->wdp_lbasize) { du->dk_dd.d_secperunit = wp->wdp_lbasize; du->dk_dd.d_ncylinders = --- 1727,1733 ---- du->dk_dd.d_nsectors = wp->wdp_sectors; du->dk_dd.d_secpercyl = du->dk_dd.d_ntracks * du->dk_dd.d_nsectors; du->dk_dd.d_secperunit = du->dk_dd.d_secpercyl * du->dk_dd.d_ncylinders; ! if (wp->wdp_cylinders == 16383 && du->dk_dd.d_secperunit < wp->wdp_lbasize) { du->dk_dd.d_secperunit = wp->wdp_lbasize; du->dk_dd.d_ncylinders = -------------------------------------------------------------------------------------------------------- > (I could really use the input of some disk gurus here. Any idea why the > Award BIOS would NOT return > any flags? The driver ignores the BIOS. The flags are whatever you set them to be in the FreeBSD configuration of the driver. > And, more important, if LBA is not enabled, will any lba_size > value be returned?Or if LBA is off > is a null or 0 returned?) Support for LBA mode is nonexistent in 2.2.8 and dangerously incomplete in 3.0 (if it is used, then kernel dumps may trash filesystems). There is no reason to use it because all known disks (except possibly yours :-) support CHS mode. > *** wd.c.3_0 Mon Jan 11 21:01:30 1999 > --- wd.c.original.3_0 Sun Jan 10 21:27:22 1999 > *************** > *** 1949,1964 **** > du->dk_dd.d_ntracks * du->dk_dd.d_nsectors; > du->dk_dd.d_secperunit = > du->dk_dd.d_secpercyl * du->dk_dd.d_ncylinders; > ! > ! /* It appears that certain Award BIOSes (newer versions > ! apparently) do not return LBA flags when LBA is > ! active. Hwoever, as LBA size should not be returned > ! when LBA is off, this hack should be safe. > ! > ! A. Sherrod 01/11/1998 */ > ! > ! > ! if(du->dk_dd.d_secperunit < wp->wdp_lbasize) { > du->dk_dd.d_secperunit = wp->wdp_lbasize; > du->dk_dd.d_ncylinders = > du->dk_dd.d_secperunit / du->dk_dd.d_secpercyl; > --- 1949,1956 ---- > du->dk_dd.d_ntracks * du->dk_dd.d_nsectors; > du->dk_dd.d_secperunit = > du->dk_dd.d_secpercyl * du->dk_dd.d_ncylinders; > ! if (wp->wdp_cylinders == 16383 && > ! du->dk_dd.d_secperunit < wp->wdp_lbasize) { > du->dk_dd.d_secperunit = wp->wdp_lbasize; > du->dk_dd.d_ncylinders = > du->dk_dd.d_secperunit / du->dk_dd.d_secpercyl; > The magic number 16383 is tested because the current ATA (draft?) standard specifies that CHS mode is specially broken for drives with more than 1024*255*63 sectors. Such drives are supposed to have a C/H/S geometry of 16383/16/63 (or something like that) for their default translation mode so that they work as least unwell as possible with old, broken BIOSes. Previous versions of the standard permitted the default geometry to have up to 65535 cylinders, and we know that drives with more than 32767 cylinders used to be made because the driver used to have sign extension bugs for them. The driver multiplies out the CHS values to get the number of sectors unless the drive appears to have specially broken CHS. It doesn't trust the wdp_lbasize value otherwise because wdp_lbasize may be garbage for old drives. Drives with 16383 cylinders are presumably new enough to have a valid wdp_lbasize. Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message