Date: Sat, 16 Feb 2002 22:25:08 -0800 (PST) From: Masahiro HARADA <mharada@iris.dti.ne.jp> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/35029: LBA48-code miscalculates size of LBA48-ready disk drive Message-ID: <200202170625.g1H6P8M29536@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 35029 >Category: kern >Synopsis: LBA48-code miscalculates size of LBA48-ready disk drive >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Feb 16 22:30:01 PST 2002 >Closed-Date: >Last-Modified: >Originator: Masahiro HARADA >Release: 4.5-STABLE >Organization: (none) >Environment: FreeBSD athlon.Free.BSD 4.5-STABLE FreeBSD 4.5-STABLE #0: Sun Feb 17 11:24:59 JST 2002 root@athlon.Free.BSD:/usr/obj/usr/src/sys/GENERIC i386 >Description: When I try to install FreeBSD to new machine, installer can not recognize a hard disk. I attached an other disk drive on ata0-slave, and boot from the disk drive. dmesg says: ad0: 0MB <ST380020ACE> [0/16/63] at ata0-master UDMA100 ad1: 38166MB <ST340824A> [77545/16/63] at ata0-slave UDMA100 acd0: CD-RW <DVD/CDRW RW9200> at ata1-master using PIO4 Mounting root from ufs:/dev/ad1s3a I add some printf to 'sys/dev/ata/ata-disk.c': --- sys/dev/ata/ata-disk.c.orig Sun Feb 17 10:48:37 2002 +++ sys/dev/ata/ata-disk.c Sun Feb 17 11:19:45 2002 @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/ata/ata-disk.c,v 1.60.2.19 2002/01/05 17:49:36 sos Exp $ + * $FreeBSD: src/sys/dev/ata/ata-disk.c,v 1.60.2.19 2002/01/05 17:49:36 sos Exp $ *** */ #include "opt_global.h" @@ -138,6 +138,9 @@ if (AD_PARAM->cylinders == 16383 && adp->total_secs < AD_PARAM->lba_size) adp->total_secs = AD_PARAM->lba_size; + printf( "* 1 * total_secs = %llu\n", adp->total_secs ); + printf( " support.address48 = %d\n", AD_PARAM->support.address48 ); + printf( " lba_size48 = %llu\n", AD_PARAM->lba_size48 ); /* use the 48bit LBA size if valid */ if (AD_PARAM->support.address48) adp->total_secs = AD_PARAM->lba_size48; Then compile it, and reboot. The patch reports: * 1 * total_secs = 156301488 support.address48 = 1 lba_size48 = 0 ad0: 0MB <ST380020ACE> [0/16/63] at ata0-master UDMA100 * 1 * total_secs = 78165360 support.address48 = 0 lba_size48 = 0 ad1: 38166MB <ST340824A> [77545/16/63] at ata0-slave UDMA100 It seems: (1) adp->total_secs keeps right value before the LBA-48 check code. (2) Seagate ST-380020A CE supports LBA-48 extension. (3) But AD_PARAM->lba_size48 has 0, so the disk size is forced to 0MB. Reading 'ATA Attachment - 6 with Packet Interface revision 3a' (download from http://www.t13.org/), on Page 52 (Acrobat 66/496) , it says: The device shall indicate support of the 48-bit Address feature set in the IDENTIFY DEVICE response. In addition, IDENTIFY DEVICE response words (103:100) contain the maximum user LBA + 1 that is accessible by 48-bit addressable commands . If the value contained in IDENTIFY DEVICE response words (103:100) is equal to or less than 268,435,455, then the content of words (61:60) shall be as described in 6.2.1. If the value in contained IDENTIFY DEVICE response words (103:100) is greater than 268,435,455, then the maximum value in words (61:60) shall be 268,435,455. That is, if the device contains greater than the capacity addressable with 28-bit commands, words (61:60) shall describe the maximum capacity that can be addressed by 28-bit commands. When the 48-bit Address feature set is implemented, the native maximum address is the highest address accepted by the device in the factory default condition using a 48-bit Address feature set command. The native maximum address is the value returned by a READ NATIVE MAX ADDRESS EXT command. If the native maximum address of a device is equal to or less than 268,435,455, a READ NATIVE MAX ADDRESS shall return the native maximum address. If the native maximum address is greater than 268,435,455, a READ NATIVE MAX ADDRESS command shall cause the device to return a value of 268,435,455. My understand is * The AD_PARAM->lba_size48 value is valid only if the value is greater then 268435455 (= 0x0FFFFFFF). * If the value is less-than or equal-to 268435455, do not use the value. (Use old method to calculate disk size.) I change the code that it checks AD_PARAM->lba_size48 (see below "Fix to the problem if known"). It looks me that the code works fine. ad0: 76319MB <ST380020ACE> [155061/16/63] at ata0-master UDMA100 ad1: 38166MB <ST340824A> [77545/16/63] at ata0-slave UDMA100 acd0: CD-RW <DVD/CDRW RW9200> at ata1-master using PIO4 Mounting root from ufs:/dev/ad1s3a >How-To-Repeat: Connecting 'Seagate ST-380020A CE' and boot. >Fix: --- sys/dev/ata/ata-disk.c.orig Sun Feb 17 10:48:37 2002 +++ sys/dev/ata/ata-disk.c Sun Feb 17 11:36:34 2002 @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/ata/ata-disk.c,v 1.60.2.19 2002/01/05 17:49:36 sos Exp $ + * $FreeBSD: src/sys/dev/ata/ata-disk.c,v 1.60.2.19 2002/01/05 17:49:36 sos Exp $ *** */ #include "opt_global.h" @@ -139,7 +139,7 @@ adp->total_secs = AD_PARAM->lba_size; /* use the 48bit LBA size if valid */ - if (AD_PARAM->support.address48) + if (AD_PARAM->support.address48 && AD_PARAM->lba_size48 > 0x0FFFFFFF) adp->total_secs = AD_PARAM->lba_size48; /* use multiple sectors/interrupt if device supports it */ >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200202170625.g1H6P8M29536>