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>
