Subject: kern/9864: wd driver reports cylinders incorrectly on some drives
To: None <gnats-bugs@gnats.netbsd.org>
From: None <thorpej@zembu.com>
List: netbsd-bugs
Date: 04/12/2000 11:45:10
>Number: 9864
>Category: kern
>Synopsis: wd driver reports cylinders incorrectly on some drives
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Apr 12 11:46:01 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: Jason R. Thorpe
>Release: NetBSD 1.4X, March 31, 2000
>Organization:
Zembu Labs, Inc.
>Environment:
NetBSD 1.4X on Intel server hardware.
>Description:
The wd driver reports the incorrect number of cylinders on
some drives, specifically drives that report the magic number
16383, which apparently indicates that LBA is the only way the
drive can be addressed.
This causes programs like disklabel(8) do bounds-check incorrectly.
>How-To-Repeat:
This bug was found while testing a highly customized automated
installation program.
>Fix:
The following patch fixes the bug by recognizing the magic
cylinder count and then recomputing it based on the capacity
and the reported number of heads and sectors/track.
Index: wd.c
===================================================================
RCS file: /home/cvsfiles/netbsd/src/sys/dev/ata/wd.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** wd.c 2000/03/31 20:00:16 1.1
--- wd.c 2000/04/11 19:19:47 1.2
***************
*** 846,852 ****
lp->d_secsize = DEV_BSIZE;
lp->d_ntracks = wd->sc_params.atap_heads;
lp->d_nsectors = wd->sc_params.atap_sectors;
! lp->d_ncylinders = wd->sc_params.atap_cylinders;
lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
if (strcmp(wd->sc_params.atap_model, "ST506") == 0)
--- 846,862 ----
lp->d_secsize = DEV_BSIZE;
lp->d_ntracks = wd->sc_params.atap_heads;
lp->d_nsectors = wd->sc_params.atap_sectors;
! if (wd->sc_params.atap_cylinders == ATAP_CYLINDERS_LBA_ONLY) {
! /*
! * If we get the magic "LBA is the only reliably way"
! * value for ncylinders, compute the `actual' number
! * of cylinders that would correspond to our capacity
! * and reported number of heads and sectors per track.
! */
! lp->d_ncylinders = wd->sc_capacity /
! lp->d_ntracks / lp->d_nsectors;
! } else
! lp->d_ncylinders = wd->sc_params.atap_cylinders;
lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
if (strcmp(wd->sc_params.atap_model, "ST506") == 0)
Index: atareg.h
===================================================================
RCS file: /home/cvsfiles/netbsd/src/sys/dev/ata/atareg.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** atareg.h 2000/03/31 20:00:16 1.1
--- atareg.h 2000/04/11 19:19:47 1.2
***************
*** 25,30 ****
--- 25,31 ----
#define ATAPI_CFG_CMD_16 0x0001
/* words 1-9 are ATA only */
u_int16_t atap_cylinders; /* 1: # of non-removable cylinders */
+ #define ATAP_CYLINDERS_LBA_ONLY 16383 /* Stupid Evil ATA Crap */
u_int16_t __reserved1;
u_int16_t atap_heads; /* 3: # of heads */
u_int16_t __retired1[2]; /* 4-5: # of unform. bytes/track */
>Release-Note:
>Audit-Trail:
>Unformatted: