Fix data returned in the int13dpt structure.
Signed-off-by: Sebastian Herbszt herbszt@gmx.de
diff --git a/src/disk.c b/src/disk.c index 242c742..d7fd6b3 100644 --- a/src/disk.c +++ b/src/disk.c @@ -603,14 +603,14 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) ebda_seg, (void*)offsetof(struct extended_bios_data_area_s, dpte), 15); SET_EBDA2(ebda_seg, dpte.checksum, -sum);
- if (size < 66) { + if (size < 74) { disk_ret(regs, DISK_RET_SUCCESS); return; }
// EDD 3.x SET_INT13DPT(regs, key, 0xbedd); - SET_INT13DPT(regs, dpi_length, 36); + SET_INT13DPT(regs, dpi_length, 44); SET_INT13DPT(regs, reserved1, 0); SET_INT13DPT(regs, reserved2, 0);
@@ -619,7 +619,7 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) SET_INT13DPT(regs, host_bus[0], 'P'); SET_INT13DPT(regs, host_bus[1], 'C'); SET_INT13DPT(regs, host_bus[2], 'I'); - SET_INT13DPT(regs, host_bus[3], 0); + SET_INT13DPT(regs, host_bus[3], ' ');
u32 path = (pci_bdf_to_bus(bdf) | (pci_bdf_to_dev(bdf) << 8) | (pci_bdf_to_fn(bdf) << 16)); @@ -629,7 +629,7 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) SET_INT13DPT(regs, host_bus[0], 'I'); SET_INT13DPT(regs, host_bus[1], 'S'); SET_INT13DPT(regs, host_bus[2], 'A'); - SET_INT13DPT(regs, host_bus[3], 0); + SET_INT13DPT(regs, host_bus[3], ' ');
SET_INT13DPT(regs, iface_path, iobase1); } @@ -637,16 +637,19 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g) SET_INT13DPT(regs, iface_type[0], 'A'); SET_INT13DPT(regs, iface_type[1], 'T'); SET_INT13DPT(regs, iface_type[2], 'A'); - SET_INT13DPT(regs, iface_type[3], 0); - SET_INT13DPT(regs, iface_type[4], 0); - SET_INT13DPT(regs, iface_type[5], 0); - SET_INT13DPT(regs, iface_type[6], 0); - SET_INT13DPT(regs, iface_type[7], 0); + SET_INT13DPT(regs, iface_type[3], ' '); + SET_INT13DPT(regs, iface_type[4], ' '); + SET_INT13DPT(regs, iface_type[5], ' '); + SET_INT13DPT(regs, iface_type[6], ' '); + SET_INT13DPT(regs, iface_type[7], ' ');
- SET_INT13DPT(regs, device_path, slave); + SET_INT13DPT(regs, device_path1, slave); + SET_INT13DPT(regs, device_path2, 0); + + SET_INT13DPT(regs, reserved3, 0);
SET_INT13DPT(regs, checksum - , -checksum_far(regs->ds, (void*)(regs->si+30), 35)); + , -checksum_far(regs->ds, (void*)(regs->si+30), 43));
disk_ret(regs, DISK_RET_SUCCESS); } diff --git a/src/disk.h b/src/disk.h index 9e5b083..0ef849d 100644 --- a/src/disk.h +++ b/src/disk.h @@ -63,7 +63,8 @@ struct int13dpt_s { u8 host_bus[4]; u8 iface_type[8]; u64 iface_path; - u64 device_path; + u64 device_path1; + u64 device_path2; u8 reserved3; u8 checksum; } PACKED;
On Sat, Jul 31, 2010 at 05:26:09PM +0200, Sebastian Herbszt wrote:
Fix data returned in the int13dpt structure.
[...]
- if (size < 66) {
- if (size < 74) { disk_ret(regs, DISK_RET_SUCCESS); return; }
This is not correct - the EDD v3.0 spec has a 66 byte structure. The link in the bochs bug is for a proposed EDD v4 spec - but that hasn't been ratified - see:
http://www.t13.org/Standards/Default.aspx?DocumentType=3
Should EDD v4 be ratified and we add support for it, we'd need to support both v3 and v4 calls.
You should be able to find the current spec by googling for "specsedd30.pdf".
To be honest though, in my tests, I didn't find any OSs that use anything beyond the basic EDD v1 calls. Indeed, if you look at the Bochs code you'll see that it has an incorrect checksum calculation for EDD v2 and EDD v3. (It uses "checksum = ~checksum" where it should do "checksum = -checksum").
-Kevin
Kevin O'Connor wrote:
On Sat, Jul 31, 2010 at 05:26:09PM +0200, Sebastian Herbszt wrote:
Fix data returned in the int13dpt structure.
[...]
- if (size < 66) {
- if (size < 74) { disk_ret(regs, DISK_RET_SUCCESS); return; }
This is not correct - the EDD v3.0 spec has a 66 byte structure.
You mean the Phoenix spec (BIOS Enhanced Disk Drive Specification, Version 3.0, Rev 0.8, March 12, 1998).
What about the T13 Working Draft, D1572, Information Technology - BIOS Enhanced Disk Drive Services - 3 (EDD-3), Revision 3, November 5, 2004?
The link in the bochs bug is for a proposed EDD v4 spec - but that hasn't been ratified - see:
It is in this list as "INCITS 407-2005 (1572D): BIOS Enhanced Disk Drive Services - 3".
Should EDD v4 be ratified and we add support for it, we'd need to support both v3 and v4 calls.
You should be able to find the current spec by googling for "specsedd30.pdf".
The structure in the Phoenix spec has 66 bytes and padding is not mentioned. In the T13 documents the structure has 74 bytes and some fields are space padded.
To be honest though, in my tests, I didn't find any OSs that use anything beyond the basic EDD v1 calls.
I think Linux supplies a buffer which can hold 74 bytes [1].
Indeed, if you look at the Bochs code you'll see that it has an incorrect checksum calculation for EDD v2 and EDD v3. (It uses "checksum = ~checksum" where it should do "checksum = -checksum").
-Kevin
[1] http://lxr.linux.no/#linux+v2.6.34.1/include/linux/edd.h
Sebastian
On Sat, Jul 31, 2010 at 09:02:24PM +0200, Sebastian Herbszt wrote:
Kevin O'Connor wrote:
On Sat, Jul 31, 2010 at 05:26:09PM +0200, Sebastian Herbszt wrote:
Fix data returned in the int13dpt structure.
[...]
- if (size < 66) {
- if (size < 74) { disk_ret(regs, DISK_RET_SUCCESS); return; }
This is not correct - the EDD v3.0 spec has a 66 byte structure.
You mean the Phoenix spec (BIOS Enhanced Disk Drive Specification, Version 3.0, Rev 0.8, March 12, 1998).
What about the T13 Working Draft, D1572, Information Technology - BIOS Enhanced Disk Drive Services - 3 (EDD-3), Revision 3, November 5, 2004?
Heh. It looks like the standards are confusingly named. The T13 EDD-1 spec is actually newer than the Phoenix EDD 3 spec. At least by looking at the specs at: http://www.t10.org/t13/#Project_drafts
So, I guess you are right and the bios should support 74 byte callers. However, I also think it should still support 66 byte callers as there may be something out there coded to the Phoenix spec.
-Kevin
Kevin O'Connor wrote:
On Sat, Jul 31, 2010 at 09:02:24PM +0200, Sebastian Herbszt wrote:
Kevin O'Connor wrote:
On Sat, Jul 31, 2010 at 05:26:09PM +0200, Sebastian Herbszt wrote:
Fix data returned in the int13dpt structure.
[...]
- if (size < 66) {
- if (size < 74) { disk_ret(regs, DISK_RET_SUCCESS); return; }
This is not correct - the EDD v3.0 spec has a 66 byte structure.
You mean the Phoenix spec (BIOS Enhanced Disk Drive Specification, Version 3.0, Rev 0.8, March 12, 1998).
What about the T13 Working Draft, D1572, Information Technology - BIOS Enhanced Disk Drive Services - 3 (EDD-3), Revision 3, November 5, 2004?
Heh. It looks like the standards are confusingly named. The T13 EDD-1 spec is actually newer than the Phoenix EDD 3 spec. At least by looking at the specs at: http://www.t10.org/t13/#Project_drafts
So, I guess you are right and the bios should support 74 byte callers. However, I also think it should still support 66 byte callers as there may be something out there coded to the Phoenix spec.
-Kevin
We have the following specs:
Phoenix BIOS Enhanced Disk Drive Specification Version 1.1 May 9, 1995 (30 bytes structure)
T13 Working Draft - 1226DT Information Technology - Enhanced BIOS Services For Disk Drives Revision 7 23 Oct, 1997 (30 bytes structure)
Phoenix BIOS Enhanced Disk Drive Specification Version 3.0 Rev 0.8 March 12, 1998 (66 bytes structure, padding not mentioned)
Interrupt List, part 2 of 18 Copyright (c) 1989-1999,2000 Ralf Brown (66 bytes structure, ASCIZ strings)
T13 Working Draft - D1386 Information Technology - BIOS Enhanced Disk Drive Services (EDD) Revision 5 September 28, 2000 (74 bytes structure, space padding)
T13 Working Draft - D1484 Information Technology - BIOS Enhanced Disk Drive Services - 2 (EDD-2) Revision 3 February 21, 2002 (74 bytes structure, space padding)
T13 Working Draft - D1572 Information Technology - BIOS Enhanced Disk Drive Services - 3 (EDD-3) Revision 3 November 5, 2004 (74 bytes structure, space padding)
The device path is either Qword or double Qword (66 vs. 74 bytes). The strings are either ASCIZ or space padded. It should be possible to special case 66 bytes size buffers and then use Qword device path and ASCIZ strings.
Sebastian