* Check for disk extensions before using them (mostly for good practice reasons)
* A CHS read error would previously be hidden by a successful disk system reset. Not that it matters much because it'd have resulted in a non-booting system anyway. * Add some more debug output, minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30643 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2a8d619c9e
commit
03a574d8cd
@ -198,6 +198,22 @@ check_cd_boot(BIOSDrive *drive)
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
are_extensions_available(uint8 drive)
|
||||
{
|
||||
struct bios_regs regs;
|
||||
regs.eax = BIOS_IS_EXT_PRESENT;
|
||||
regs.ebx = 0x55aa;
|
||||
regs.edx = drive;
|
||||
call_bios(0x13, ®s);
|
||||
|
||||
TRACE(("checking extensions: carry: %u; ebx: 0x%08lx; ecx: 0x%08lx\n",
|
||||
regs.flags & CARRY_FLAG, regs.ebx, regs.ecx));
|
||||
return (regs.flags & CARRY_FLAG) == 0 && regs.ebx == 0xaa55
|
||||
&& (regs.ecx & 0x01 /* supports device access using packet */) != 0;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
get_ext_drive_parameters(uint8 drive, drive_parameters *targetParameters)
|
||||
{
|
||||
@ -528,7 +544,7 @@ BIOSDrive::BIOSDrive(uint8 driveID)
|
||||
{
|
||||
TRACE(("drive ID %u\n", driveID));
|
||||
|
||||
if (driveID < 0x80
|
||||
if (driveID < 0x80 || !are_extensions_available(driveID)
|
||||
|| get_ext_drive_parameters(driveID, &fParameters) != B_OK) {
|
||||
// old style CHS support
|
||||
|
||||
@ -627,12 +643,16 @@ BIOSDrive::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
||||
uint32 cylinder = head / fParameters.heads;
|
||||
head %= fParameters.heads;
|
||||
|
||||
if (cylinder >= fParameters.cylinders)
|
||||
if (cylinder >= fParameters.cylinders) {
|
||||
TRACE(("cylinder value %lu bigger than available %lu\n",
|
||||
cylinder, fParameters.cylinders));
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// try to read from the device more than once, just to make sure it'll work
|
||||
struct bios_regs regs;
|
||||
int32 tries = 3;
|
||||
bool readWorked = false;
|
||||
|
||||
while (tries-- > 0) {
|
||||
regs.eax = BIOS_READ | blocksRead;
|
||||
@ -642,21 +662,26 @@ BIOSDrive::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
||||
regs.ebx = kExtraSegmentScratch;
|
||||
call_bios(0x13, ®s);
|
||||
|
||||
if ((regs.flags & CARRY_FLAG) == 0)
|
||||
if ((regs.flags & CARRY_FLAG) == 0) {
|
||||
readWorked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE(("read failed\n"));
|
||||
|
||||
if (tries < 2) {
|
||||
// reset disk system
|
||||
TRACE(("reset disk system\n"));
|
||||
regs.eax = BIOS_RESET_DISK_SYSTEM;
|
||||
regs.edx = fDriveID;
|
||||
call_bios(0x13, ®s);
|
||||
}
|
||||
|
||||
|
||||
// wait a bit between the retries (1/20 sec)
|
||||
spin(50000);
|
||||
}
|
||||
|
||||
if (regs.flags & CARRY_FLAG) {
|
||||
if (!readWorked) {
|
||||
dprintf("reading %ld bytes from drive %u failed at %Ld\n",
|
||||
blocksRead, fDriveID, pos);
|
||||
return B_ERROR;
|
||||
|
Loading…
x
Reference in New Issue
Block a user