Date: Thu, 1 Sep 2016 06:35:13 +0000 (UTC) From: Toomas Soome <tsoome@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r305178 - head/sys/boot/i386/libi386 Message-ID: <201609010635.u816ZDlc025340@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tsoome Date: Thu Sep 1 06:35:13 2016 New Revision: 305178 URL: https://svnweb.freebsd.org/changeset/base/305178 Log: bd_int13probe() should check extended info if sector info is bad In some Dell systems and usb stick combinations, it is found that int13 AH=08 is reporting back bad sector information, preventing the boot. This update is allowing bd_int13probe() to use extended info call to build disk properties. It also can happen the total sectors count from extended info may be wrong, in such case, the CHS data is used to calculate total sectors. Reviewed by: allanjude Approved by: allanjude (mentor) Differential Revision: https://reviews.freebsd.org/D7718 Modified: head/sys/boot/i386/libi386/biosdisk.c Modified: head/sys/boot/i386/libi386/biosdisk.c ============================================================================== --- head/sys/boot/i386/libi386/biosdisk.c Thu Sep 1 06:32:35 2016 (r305177) +++ head/sys/boot/i386/libi386/biosdisk.c Thu Sep 1 06:35:13 2016 (r305178) @@ -244,6 +244,7 @@ static int bd_int13probe(struct bdinfo *bd) { struct edd_params params; + int ret = 1; /* assume success */ v86.ctl = V86_FLAGS; v86.addr = 0x13; @@ -251,11 +252,14 @@ bd_int13probe(struct bdinfo *bd) v86.edx = bd->bd_unit; v86int(); + /* Don't error out if we get bad sector number, try EDD as well */ if (V86_CY(v86.efl) || /* carry set */ - (v86.ecx & 0x3f) == 0 || /* absurd sector number */ (v86.edx & 0xff) <= (unsigned)(bd->bd_unit & 0x7f)) /* unit # bad */ return (0); /* skip device */ + if ((v86.ecx & 0x3f) == 0) /* absurd sector number */ + ret = 0; /* set error */ + /* Convert max cyl # -> # of cylinders */ bd->bd_cyl = ((v86.ecx & 0xc0) << 2) + ((v86.ecx & 0xff00) >> 8) + 1; /* Convert max head # -> # of heads */ @@ -280,7 +284,8 @@ bd_int13probe(struct bdinfo *bd) if (V86_CY(v86.efl) || /* carry set */ (v86.ebx & 0xffff) != 0xaa55 || /* signature */ (v86.ecx & EDD_INTERFACE_FIXED_DISK) == 0) - return (1); + return (ret); /* return code from int13 AH=08 */ + /* EDD supported */ bd->bd_flags |= BD_MODEEDD1; if ((v86.eax & 0xff00) >= 0x3000) @@ -295,12 +300,22 @@ bd_int13probe(struct bdinfo *bd) v86.esi = VTOPOFF(¶ms); v86int(); if (!V86_CY(v86.efl)) { - bd->bd_sectors = params.sectors; + uint64_t total; + + if (params.sectors != 0) + bd->bd_sectors = params.sectors; + + total = (uint64_t)params.cylinders * + params.heads * params.sectors_per_track; + if (bd->bd_sectors < total) + bd->bd_sectors = total; + bd->bd_sectorsize = params.sector_size; + ret = 1; } DEBUG("unit 0x%x flags %x, sectors %llu, sectorsize %u", bd->bd_unit, bd->bd_flags, bd->bd_sectors, bd->bd_sectorsize); - return (1); + return (ret); } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609010635.u816ZDlc025340>