summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2011-04-01 16:53:22 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2011-04-01 16:53:22 -0700
commit7c5ce55464bb182b79cfa772dc840e0dc2c9bd0a (patch)
tree8b79f0064a7c6c9e0d3d47e5bb01b05c539511cf
parent2ce2f3b9d05a30fe11b9e69562b73b0f068c6bc6 (diff)
parent823141cd241c419fc7e88e2b10bf0fe800de4bad (diff)
downloadsyslinux-4.04-pre17.tar.gz
Merge remote-tracking branch 'genec/memdiskdbg-for-sha0'syslinux-4.04-pre17
-rw-r--r--memdisk/dskprobe.c61
1 files changed, 54 insertions, 7 deletions
diff --git a/memdisk/dskprobe.c b/memdisk/dskprobe.c
index 84400a83..460bf647 100644
--- a/memdisk/dskprobe.c
+++ b/memdisk/dskprobe.c
@@ -49,17 +49,54 @@ static void probe_any(uint8_t func, uint8_t drive, com32sys_t * regs)
}
/**
+ * Determine if the return from probe_int13h_01h indicates a failure; a
+ * return of zero indicates no known failure.
+ */
+static int probe_int13h_01h_fail(int istatus)
+{
+ int status = 0;
+
+ if (istatus >= 256)
+ status = istatus;
+ else
+ switch (istatus) {
+ case 1: status = istatus;
+ }
+ return status;
+}
+
+/**
+ * INT 0x13, AH == 0x01: Get status of last command.
+ */
+static int probe_int13h_01h(uint8_t drive)
+{
+ int status;
+ com32sys_t regs;
+
+ memset(&regs, 0, sizeof regs);
+ probe_any(0x01, drive, &regs);
+ status = (regs.eflags.l & 1) * 256 + regs.eax.b[1];
+ dskprobe_printf(" AH01: CF%d AH%02x", regs.eflags.l & 1, regs.eax.b[1]);
+ return status;
+}
+
+/**
* INT 0x13, AH == 0x08: Get drive parameters.
*/
static int probe_int13h_08h(uint8_t drive, com32sys_t * regs)
{
int present;
+ int status;
memset(regs, 0, sizeof *regs);
probe_any(0x08, drive, regs);
- present = !(regs->eflags.l & 1);
- dskprobe_printf(" AH08: CF%d BL%02x DL%02x\n", regs->eflags.l & 1,
+ dskprobe_printf(" AH08: CF%d AH%02x AL%02x BL%02x DL%02x ",
+ regs->eflags.l & 1, regs->eax.b[1], regs->eax.b[0],
regs->ebx.b[0], regs->edx.b[0]);
+ present = !(regs->eflags.l & 1) && !regs->eax.b[1];
+ status = probe_int13h_01h(drive);
+ present = present && !(probe_int13h_01h_fail(status));
+ dskprobe_printf(" P%d\n", present);
return present;
}
@@ -69,12 +106,17 @@ static int probe_int13h_08h(uint8_t drive, com32sys_t * regs)
static int probe_int13h_15h(uint8_t drive, com32sys_t * regs)
{
int present;
+ int status;
memset(regs, 0, sizeof *regs);
probe_any(0x15, drive, regs);
+ dskprobe_printf(" AH15: CF%d AH%02x AL%02x CX%04x DX%04x",
+ regs->eflags.l & 1, regs->eax.b[1], regs->eax.b[0],
+ regs->ecx.w[0], regs->edx.w[0]);
present = !(regs->eflags.l & 1) && regs->eax.b[1];
- dskprobe_printf(" AH15: CF%d AH%02x\n", regs->eflags.l & 1,
- regs->eax.b[1]);
+ status = probe_int13h_01h(drive);
+ present = present && !(probe_int13h_01h_fail(status));
+ dskprobe_printf(" P%d\n", present);
return present;
}
@@ -84,13 +126,18 @@ static int probe_int13h_15h(uint8_t drive, com32sys_t * regs)
static int probe_int13h_41h(uint8_t drive, com32sys_t * regs)
{
int present;
+ int status;
memset(regs, 0, sizeof *regs);
regs->ebx.w[0] = 0x55AA; /* BX == 0x55AA */
probe_any(0x41, drive, regs);
- present = !(regs->eflags.l & 1);
- dskprobe_printf(" AH41: CF%d BX%04x AH%02x DH%02x\n", regs->eflags.l & 1,
- regs->ebx.w[0], regs->eax.b[1], regs->edx.b[1]);
+ dskprobe_printf(" AH41: CF%d AH%02x BX%04x CX%04x DH%02x",
+ regs->eflags.l & 1, regs->eax.b[1], regs->ebx.w[0],
+ regs->ecx.w[0], regs->edx.b[1]);
+ present = !(regs->eflags.l & 1) && (regs->ebx.w[0] == 0xAA55);
+ status = probe_int13h_01h(drive);
+ present = present && !(probe_int13h_01h_fail(status));
+ dskprobe_printf(" P%d\n", present);
return present;
}