home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.unix.bsd
- Path: sparky!uunet!destroyer!sol.ctr.columbia.edu!ucselx!crash!fpm
- From: fpm@crash.cts.com (Frank Maclachlan)
- Subject: wd.c problem (w/ Patch)
- Organization: CTS Network Services (crash, ctsnet), El Cajon, CA
- Date: 19 Aug 92 16:32:35 PDT
- Message-ID: <1992Aug19.163236.16943@crash>
- Summary: bad144 bug fixed
- Keywords: bad144, ESDI
- Lines: 73
-
- Greetings:
-
- I think there is a problem in 'usr/src/sys.386bsd/i386/isa/wd.c'
- when the first sector in a multi-sector read or write request is
- present in the bad144 table. The bad144 table search code at
- line 382 finds the sector in the bad144 table and replaces the
- block number, cylinder, head, and sector addresses with values
- corresponding to the replacement sector. At line 434, the sector
- count register is loaded with the number of sectors in the entire
- transfer. This is wrong; it *MUST* be set to *one* sector. A
- read would return the wrong data in sectors after the first; a
- write would *overwrite* other replacement sectors or even the
- bad144 table on the last track.
-
- You could fix this by changing lines 382 and 383 from
-
- if ((du->dk_flags & (/*DKFL_SINGLE|*/DKFL_BADSECT))
- == (/*DKFL_SINGLE|*/DKFL_BADSECT))
-
- to
- if ((du->dk_flags & (DKFL_SINGLE|DKFL_BADSECT))
- == (DKFL_SINGLE|DKFL_BADSECT))
-
- This prevents the defective sector from being replaced the first
- time through (DKFL_SINGLE is not set). Assuming the sector is
- marked bad, the read or write of the defective sector will fail,
- and the interrupt routine (wdintr) will retry the operation with
- the DKFL_SINGLE bit set. This causes the sector to be replaced
- and the transfer count is properly set to 1.
-
- Another solution is to leave the above two lines unchanged and
- apply the following patch. This has the advantage of immediately
- replacing a defective sector at the start of a transfer without
- requiring that the operation first fail.
-
- ---- snip snip ----
- *** wd.c.ORIG Wed Aug 19 15:43:21 1992
- --- wd.c Wed Aug 19 16:16:18 1992
- ***************
- *** 402,407 ****
- --- 402,408 ----
- cylin = blknum / secpercyl;
- head = (blknum % secpercyl) / secpertrk;
- sector = blknum % secpertrk;
- + du->dk_flags |= DKFL_SINGLE;
- #ifdef WDDEBUG
- printf("new = %d\n", blknum);
- #endif
- ---- snip snip ----
-
- Note that the bad144 code *doesn't* work unless *all* sectors
- present in the bad144 table are marked bad (any attempt to read
- or write any of them will return an immediate error - usually a
- BAD BLOCK error code).
-
- On a different note, when setting up your hard disk, be aware that
- many diagnostic packages assume that the last cylinder on a hard
- disk is a test cylinder and will cheerfully scribble on it when
- performing hard disk diagnostics. Also, if the hard disk has more
- than 1024 cylinders and the BIOS parameter table entry for the
- drive shows less than the number of cylinders on the drive (a
- Western Digital WD1007v-se2 controller attached to a drive having
- 1222 cylinders sets up a BIOS parameter table indicating 1023
- cylinders), disk diagnostics assume that the last cylinder as
- specified by the BIOS parameter table is a test cylinder. I once
- trashed an SCO Xenix filesystem by running a diagnostic which
- wrote test patterns on cylinder 1023 on a 1222 cylinder hard disk.
- You have been warned!
- --
- UUCP: {hplabs!hp-sdd ucsd nosc}!crash!fpm
- ARPA: crash!fpm@nosc.mil
- INET: fpm@crash.cts.com
-
-