diff --git a/src/arch/i386/include/int13.h b/src/arch/i386/include/int13.h index 2a0f19cf..06755724 100644 --- a/src/arch/i386/include/int13.h +++ b/src/arch/i386/include/int13.h @@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include +#include #include /** @@ -36,6 +37,10 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define INT13_EXTENDED_READ 0x42 /** Extended write */ #define INT13_EXTENDED_WRITE 0x43 +/** Verify sectors */ +#define INT13_EXTENDED_VERIFY 0x44 +/** Extended seek */ +#define INT13_EXTENDED_SEEK 0x47 /** Get extended drive parameters */ #define INT13_GET_EXTENDED_PARAMETERS 0x48 /** Get CD-ROM status / terminate emulation */ @@ -68,16 +73,22 @@ FILE_LICENCE ( GPL2_OR_LATER ); struct int13_disk_address { /** Size of the packet, in bytes */ uint8_t bufsize; - /** Reserved, must be zero */ - uint8_t reserved; + /** Reserved */ + uint8_t reserved_a; /** Block count */ - uint16_t count; + uint8_t count; + /** Reserved */ + uint8_t reserved_b; /** Data buffer */ struct segoff buffer; /** Starting block number */ uint64_t lba; - /** Data buffer (EDD-3.0 only) */ + /** Data buffer (EDD 3.0+ only) */ uint64_t buffer_phys; + /** Block count (EDD 4.0+ only) */ + uint32_t long_count; + /** Reserved */ + uint32_t reserved_c; } __attribute__ (( packed )); /** INT 13 disk parameters */ @@ -96,6 +107,10 @@ struct int13_disk_parameters { uint64_t sectors; /** Bytes per sector */ uint16_t sector_size; + /** Device parameter table extension */ + struct segoff dpte; + /** Device path information */ + struct edd_device_path_information dpi; } __attribute__ (( packed )); /** @@ -147,6 +162,8 @@ struct int13_disk_parameters { #define INT13_EXTENSION_REMOVABLE 0x02 /** EDD functions supported */ #define INT13_EXTENSION_EDD 0x04 +/** 64-bit extensions are present */ +#define INT13_EXTENSION_64BIT 0x08 /** @} */ @@ -166,6 +183,12 @@ struct int13_disk_parameters { /** @} */ +/** Maximum number of sectors for which CHS geometry is allowed to be valid + * + * This number is taken from the EDD specification. + */ +#define INT13_MAX_CHS_SECTORS 15482880 + /** Bootable CD-ROM specification packet */ struct int13_cdrom_specification { /** Size of packet in bytes */ diff --git a/src/arch/i386/interface/pcbios/int13.c b/src/arch/i386/interface/pcbios/int13.c index 97110fde..e0acc07c 100644 --- a/src/arch/i386/interface/pcbios/int13.c +++ b/src/arch/i386/interface/pcbios/int13.c @@ -35,6 +35,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include +#include #include #include #include @@ -654,8 +656,10 @@ static int int13_extension_check ( struct int13_drive *int13 __unused, if ( ix86->regs.bx == 0x55aa ) { DBGC2 ( int13, "INT13 extensions installation check\n" ); ix86->regs.bx = 0xaa55; - ix86->regs.cx = INT13_EXTENSION_LINEAR; - return INT13_EXTENSION_VER_1_X; + ix86->regs.cx = ( INT13_EXTENSION_LINEAR | + INT13_EXTENSION_EDD | + INT13_EXTENSION_64BIT ); + return INT13_EXTENSION_VER_3_0; } else { return -INT13_STATUS_INVALID; } @@ -678,25 +682,56 @@ static int int13_extended_rw ( struct int13_drive *int13, userptr_t buffer, size_t len ) ) { struct int13_disk_address addr; + uint8_t bufsize; uint64_t lba; unsigned long count; userptr_t buffer; int rc; - /* Read parameters from disk address structure */ - copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, sizeof ( addr )); - lba = addr.lba; - count = addr.count; - buffer = real_to_user ( addr.buffer.segment, addr.buffer.offset ); + /* Get buffer size */ + get_real ( bufsize, ix86->segs.ds, + ( ix86->regs.si + offsetof ( typeof ( addr ), bufsize ) ) ); + if ( bufsize < offsetof ( typeof ( addr ), buffer_phys ) ) { + DBGC2 ( int13, "\n", bufsize ); + return -INT13_STATUS_INVALID; + } + + /* Read parameters from disk address structure */ + memset ( &addr, 0, sizeof ( addr ) ); + copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, bufsize ); + lba = addr.lba; + DBGC2 ( int13, "LBA %08llx <-> ", ( ( unsigned long long ) lba ) ); + if ( ( addr.count == 0xff ) || + ( ( addr.buffer.segment == 0xffff ) && + ( addr.buffer.offset == 0xffff ) ) ) { + buffer = phys_to_user ( addr.buffer_phys ); + DBGC2 ( int13, "%08llx", + ( ( unsigned long long ) addr.buffer_phys ) ); + } else { + buffer = real_to_user ( addr.buffer.segment, + addr.buffer.offset ); + DBGC2 ( int13, "%04x:%04x", addr.buffer.segment, + addr.buffer.offset ); + } + if ( addr.count <= 0x7f ) { + count = addr.count; + } else if ( addr.count == 0xff ) { + count = addr.long_count; + } else { + DBGC2 ( int13, " \n", addr.count ); + return -INT13_STATUS_INVALID; + } + DBGC2 ( int13, " (count %ld)\n", count ); - DBGC2 ( int13, "LBA %08llx <-> %04x:%04x (count %ld)\n", - ( ( unsigned long long ) lba ), addr.buffer.segment, - addr.buffer.offset, count ); - /* Read from / write to block device */ if ( ( rc = int13_rw ( int13, lba, count, buffer, block_rw ) ) != 0 ) { DBGC ( int13, "INT13 drive %02x extended I/O failed: %s\n", int13->drive, strerror ( rc ) ); + /* Record that no blocks were transferred successfully */ + addr.count = 0; + put_real ( addr.count, ix86->segs.ds, + ( ix86->regs.si + + offsetof ( typeof ( addr ), count ) ) ); return -INT13_STATUS_READ_ERROR; } @@ -729,6 +764,117 @@ static int int13_extended_write ( struct int13_drive *int13, return int13_extended_rw ( int13, ix86, block_write ); } +/** + * INT 13, 44 - Verify sectors + * + * @v int13 Emulated drive + * @v ds:si Disk address packet + * @ret status Status code + */ +static int int13_extended_verify ( struct int13_drive *int13, + struct i386_all_regs *ix86 ) { + struct int13_disk_address addr; + uint64_t lba; + unsigned long count; + + /* Read parameters from disk address structure */ + if ( DBG_EXTRA ) { + copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, + sizeof ( addr )); + lba = addr.lba; + count = addr.count; + DBGC2 ( int13, "Verify: LBA %08llx (count %ld)\n", + ( ( unsigned long long ) lba ), count ); + } + + /* We have no mechanism for verifying sectors */ + return -INT13_STATUS_INVALID; +} + +/** + * INT 13, 44 - Extended seek + * + * @v int13 Emulated drive + * @v ds:si Disk address packet + * @ret status Status code + */ +int int13_extended_seek ( struct int13_drive *int13, + struct i386_all_regs *ix86 ) { + struct int13_disk_address addr; + uint64_t lba; + unsigned long count; + + /* Read parameters from disk address structure */ + if ( DBG_EXTRA ) { + copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, + sizeof ( addr )); + lba = addr.lba; + count = addr.count; + DBGC2 ( int13, "Seek: LBA %08llx (count %ld)\n", + ( ( unsigned long long ) lba ), count ); + } + + /* Ignore and return success */ + return 0; +} + +/** + * Build device path information + * + * @v int13 Emulated drive + * @v dpi Device path information + * @ret rc Return status code + */ +static int int13_device_path_info ( struct int13_drive *int13, + struct edd_device_path_information *dpi ) { + struct device *device; + struct device_description *desc; + unsigned int i; + uint8_t sum = 0; + int rc; + + /* Get underlying hardware device */ + device = identify_device ( &int13->block ); + if ( ! device ) { + DBGC ( int13, "INT13 drive %02x cannot identify hardware " + "device\n", int13->drive ); + return -ENODEV; + } + + /* Fill in bus type and interface path */ + desc = &device->desc; + switch ( desc->bus_type ) { + case BUS_TYPE_PCI: + dpi->host_bus_type.type = EDD_BUS_TYPE_PCI; + dpi->interface_path.pci.bus = PCI_BUS ( desc->location ); + dpi->interface_path.pci.slot = PCI_SLOT ( desc->location ); + dpi->interface_path.pci.function = PCI_FUNC ( desc->location ); + dpi->interface_path.pci.channel = 0xff; /* unused */ + break; + default: + DBGC ( int13, "INT13 drive %02x unrecognised bus type %d\n", + int13->drive, desc->bus_type ); + return -ENOTSUP; + } + + /* Get EDD block device description */ + if ( ( rc = edd_describe ( &int13->block, &dpi->interface_type, + &dpi->device_path ) ) != 0 ) { + DBGC ( int13, "INT13 drive %02x cannot identify block device: " + "%s\n", int13->drive, strerror ( rc ) ); + return rc; + } + + /* Fill in common fields and fix checksum */ + dpi->key = EDD_DEVICE_PATH_INFO_KEY; + dpi->len = sizeof ( *dpi ); + for ( i = 0 ; i < sizeof ( *dpi ) ; i++ ) + sum += *( ( ( uint8_t * ) dpi ) + i ); + dpi->checksum -= sum; + + return 0; +} + /** * INT 13, 48 - Get extended parameters * @@ -738,21 +884,62 @@ static int int13_extended_write ( struct int13_drive *int13, */ static int int13_get_extended_parameters ( struct int13_drive *int13, struct i386_all_regs *ix86 ) { - struct int13_disk_parameters params = { - .bufsize = sizeof ( params ), - .flags = INT13_FL_DMA_TRANSPARENT, - .cylinders = int13->cylinders, - .heads = int13->heads, - .sectors_per_track = int13->sectors_per_track, - .sectors = int13->capacity.blocks, - .sector_size = int13->capacity.blksize, - }; - - DBGC2 ( int13, "Get extended drive parameters to %04x:%04x\n", - ix86->segs.ds, ix86->regs.si ); + struct int13_disk_parameters params; + struct segoff address; + size_t len = sizeof ( params ); + uint16_t bufsize; + int rc; + + /* Get buffer size */ + get_real ( bufsize, ix86->segs.ds, + ( ix86->regs.si + offsetof ( typeof ( params ), bufsize ))); + + DBGC2 ( int13, "Get extended drive parameters to %04x:%04x+%02x\n", + ix86->segs.ds, ix86->regs.si, bufsize ); + + /* Build drive parameters */ + memset ( ¶ms, 0, sizeof ( params ) ); + params.flags = INT13_FL_DMA_TRANSPARENT; + if ( ( int13->cylinders < 1024 ) && + ( int13->capacity.blocks <= INT13_MAX_CHS_SECTORS ) ) { + params.flags |= INT13_FL_CHS_VALID; + } + params.cylinders = int13->cylinders; + params.heads = int13->heads; + params.sectors_per_track = int13->sectors_per_track; + params.sectors = int13->capacity.blocks; + params.sector_size = int13->capacity.blksize; + memset ( ¶ms.dpte, 0xff, sizeof ( params.dpte ) ); + if ( ( rc = int13_device_path_info ( int13, ¶ms.dpi ) ) != 0 ) { + DBGC ( int13, "INT13 drive %02x could not provide device " + "path information: %s\n", + int13->drive, strerror ( rc ) ); + len = offsetof ( typeof ( params ), dpi ); + } + + /* Calculate returned "buffer size" (which will be less than + * the length actually copied if device path information is + * present). + */ + if ( bufsize < offsetof ( typeof ( params ), dpte ) ) + return -INT13_STATUS_INVALID; + if ( bufsize < offsetof ( typeof ( params ), dpi ) ) { + params.bufsize = offsetof ( typeof ( params ), dpte ); + } else { + params.bufsize = offsetof ( typeof ( params ), dpi ); + } + + DBGC ( int13, "INT 13 drive %02x described using extended " + "parameters:\n", int13->drive ); + address.segment = ix86->segs.ds; + address.offset = ix86->regs.si; + DBGC_HDA ( int13, address, ¶ms, len ); + + /* Return drive parameters */ + if ( len > bufsize ) + len = bufsize; + copy_to_real ( ix86->segs.ds, ix86->regs.si, ¶ms, len ); - copy_to_real ( ix86->segs.ds, ix86->regs.si, ¶ms, - sizeof ( params ) ); return 0; } @@ -814,6 +1001,12 @@ static __asmcall void int13 ( struct i386_all_regs *ix86 ) { case INT13_EXTENDED_WRITE: status = int13_extended_write ( int13, ix86 ); break; + case INT13_EXTENDED_VERIFY: + status = int13_extended_verify ( int13, ix86 ); + break; + case INT13_EXTENDED_SEEK: + status = int13_extended_seek ( int13, ix86 ); + break; case INT13_GET_EXTENDED_PARAMETERS: status = int13_get_extended_parameters ( int13, ix86 ); break; diff --git a/src/core/device.c b/src/core/device.c index 1a227fd9..cb2c23b0 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -21,8 +21,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include -#include #include +#include +#include /** * @file @@ -105,3 +106,27 @@ struct startup_fn startup_devices __startup_fn ( STARTUP_NORMAL ) = { .startup = probe_devices, .shutdown = remove_devices, }; + +/** + * Identify a device behind an interface + * + * @v intf Interface + * @ret device Device, or NULL + */ +struct device * identify_device ( struct interface *intf ) { + struct interface *dest; + identify_device_TYPE ( void * ) *op = + intf_get_dest_op ( intf, identify_device, &dest ); + void *object = intf_object ( dest ); + void *device; + + if ( op ) { + device = op ( object ); + } else { + /* Default is to return NULL */ + device = NULL; + } + + intf_put ( dest ); + return device; +} diff --git a/src/core/edd.c b/src/core/edd.c new file mode 100644 index 00000000..8ba24b17 --- /dev/null +++ b/src/core/edd.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 Michael Brown . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include +#include +#include + +/** @file + * + * Enhanced Disk Drive specification + * + */ + +/** + * Describe a disk device using EDD + * + * @v intf Interface + * @v type EDD interface type + * @v path EDD device path + * @ret rc Return status code + */ +int edd_describe ( struct interface *intf, struct edd_interface_type *type, + union edd_device_path *path ) { + struct interface *dest; + edd_describe_TYPE ( void * ) *op = + intf_get_dest_op ( intf, edd_describe, &dest ); + void *object = intf_object ( dest ); + int rc; + + if ( op ) { + rc = op ( object, type, path ); + } else { + /* Default is to not support this operation */ + rc = -ENOTSUP; + } + + intf_put ( dest ); + return rc; +} diff --git a/src/include/ipxe/device.h b/src/include/ipxe/device.h index 85675300..068268ba 100644 --- a/src/include/ipxe/device.h +++ b/src/include/ipxe/device.h @@ -13,6 +13,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include +struct interface; + /** A hardware device description */ struct device_description { /** Bus type @@ -110,4 +112,8 @@ struct root_driver { /** Declare a root device */ #define __root_device __table_entry ( ROOT_DEVICES, 01 ) +extern struct device * identify_device ( struct interface *intf ); +#define identify_device_TYPE( object_type ) \ + typeof ( struct device * ( object_type ) ) + #endif /* _IPXE_DEVICE_H */ diff --git a/src/include/ipxe/edd.h b/src/include/ipxe/edd.h new file mode 100644 index 00000000..0c25593d --- /dev/null +++ b/src/include/ipxe/edd.h @@ -0,0 +1,193 @@ +#ifndef _IPXE_EDD_H +#define _IPXE_EDD_H + +/** @file + * + * Enhanced Disk Drive specification + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include +#include + +/** An EDD host bus type */ +struct edd_host_bus_type { + /** Type */ + uint32_t type; +} __attribute__ (( packed )); + +/** EDD bus type */ +#define EDD_BUS_TYPE_FIXED( a, b, c, d, ... ) \ + ( ( (a) << 0 ) | ( (b) << 8 ) | ( (c) << 16 ) | ( (d) << 24 ) ) +#define EDD_BUS_TYPE( ... ) \ + EDD_BUS_TYPE_FIXED ( __VA_ARGS__, ' ', ' ', ' ', ' ' ) +/** EDD PCI bus type */ +#define EDD_BUS_TYPE_PCI EDD_BUS_TYPE ( 'P', 'C', 'I' ) +/** EDD ISA bus type */ +#define EDD_BUS_TYPE_ISA EDD_BUS_TYPE ( 'I', 'S', 'A' ) +/** EDD PCI-X bus type */ +#define EDD_BUS_TYPE_PCIX EDD_BUS_TYPE ( 'P', 'C', 'I', 'X' ) +/** EDD Infiniband bus type */ +#define EDD_BUS_TYPE_IBND EDD_BUS_TYPE ( 'I', 'B', 'N', 'D' ) +/** EDD PCI Express bus type */ +#define EDD_BUS_TYPE_XPRS EDD_BUS_TYPE ( 'X', 'P', 'R', 'S' ) +/** EDD HyperTransport bus type */ +#define EDD_BUS_TYPE_HTPT EDD_BUS_TYPE ( 'H', 'T', 'P', 'T' ) + +/** An EDD interface type */ +struct edd_interface_type { + /** Type */ + uint64_t type; +} __attribute__ (( packed )); + +/** EDD interface type */ +#define EDD_INTF_TYPE_FIXED( a, b, c, d, e, f, g, h, ... ) \ + ( ( ( ( uint64_t ) (a) ) << 0 ) | ( ( ( uint64_t ) (b) ) << 8 ) | \ + ( ( ( uint64_t ) (c) ) << 16 ) | ( ( ( uint64_t ) (d) ) << 24 ) | \ + ( ( ( uint64_t ) (e) ) << 32 ) | ( ( ( uint64_t ) (f) ) << 40 ) | \ + ( ( ( uint64_t ) (g) ) << 48 ) | ( ( ( uint64_t ) (h) ) << 56 ) ) +#define EDD_INTF_TYPE( ... ) \ + EDD_INTF_TYPE_FIXED ( __VA_ARGS__, \ + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ) +/** EDD ATA interface type */ +#define EDD_INTF_TYPE_ATA EDD_INTF_TYPE ( 'A', 'T', 'A' ) +/** EDD ATAPI interface type */ +#define EDD_INTF_TYPE_ATAPI EDD_INTF_TYPE ( 'A', 'T', 'A', 'P', 'I' ) +/** EDD SCSI interface type */ +#define EDD_INTF_TYPE_SCSI EDD_INTF_TYPE ( 'S', 'C', 'S', 'I' ) +/** EDD USB interface type */ +#define EDD_INTF_TYPE_USB EDD_INTF_TYPE ( 'U', 'S', 'B' ) +/** EDD 1394 interface type */ +#define EDD_INTF_TYPE_1394 EDD_INTF_TYPE ( '1', '3', '9', '4' ) +/** EDD Fibre Channel interface type */ +#define EDD_INTF_TYPE_FIBRE EDD_INTF_TYPE ( 'F', 'I', 'B', 'R', 'E' ) +/** EDD I2O interface type */ +#define EDD_INTF_TYPE_I2O EDD_INTF_TYPE ( 'I', '2', 'O' ) +/** EDD RAID interface type */ +#define EDD_INTF_TYPE_RAID EDD_INTF_TYPE ( 'R', 'A', 'I', 'D' ) +/** EDD SATA interface type */ +#define EDD_INTF_TYPE_SATA EDD_INTF_TYPE ( 'S', 'A', 'T', 'A' ) +/** EDD SAS interface type */ +#define EDD_INTF_TYPE_SAS EDD_INTF_TYPE ( 'S', 'A', 'S' ) + +/** An EDD interface path */ +union edd_interface_path { + /** Legacy bus type */ + struct { + /** Base address */ + uint16_t base; + } __attribute__ (( packed )) legacy; + /** PCI, PCI-X, PCI Express, or HyperTransport bus type */ + struct { + /** Bus */ + uint8_t bus; + /** Slot */ + uint8_t slot; + /** Function */ + uint8_t function; + /** Channel number */ + uint8_t channel; + } __attribute__ (( packed )) pci; + /** Padding */ + uint8_t pad[8]; +} __attribute__ (( packed )); + +/** An EDD device path */ +union edd_device_path { + /** ATA interface type */ + struct { + /** Slave */ + uint8_t slave; + } __attribute__ (( packed )) ata; + /** ATAPI interface type */ + struct { + /** Slave */ + uint8_t slave; + /** Logical Unit Number */ + uint8_t lun; + } __attribute__ (( packed )) atapi; + /** SCSI interface type */ + struct { + /** SCSI ID */ + uint16_t id; + /** Logical Unit Number */ + uint64_t lun; + } __attribute__ (( packed )) scsi; + /** USB interface type */ + struct { + /** Serial number */ + uint64_t serial; + } __attribute__ (( packed )) usb; + /** IEEE1394 interface type */ + struct { + /** GUID */ + uint64_t guid; + } __attribute__ (( packed )) ieee1394; + /** Fibre Channel interface type */ + struct { + /** WWN */ + uint64_t wwn; + /** Logical Unit Number */ + uint64_t lun; + } __attribute__ (( packed )) fibre; + /** I2O interface type */ + struct { + /** Identity tag */ + uint64_t tag; + } __attribute__ (( packed )) i2o; + /** RAID interface type */ + struct { + /** Array number */ + uint32_t array; + } __attribute__ (( packed )) raid; + /** SATA interface type */ + struct { + /** Port number */ + uint8_t port; + /** Port multiplier number */ + uint8_t multiplier; + } __attribute__ (( packed )) sata; + /** SAS interface type */ + struct { + /** Address */ + uint64_t address; + } __attribute__ (( packed )) sas; + /** Padding */ + uint8_t pad[16]; +} __attribute__ (( packed )); + +/** EDD device path information */ +struct edd_device_path_information { + /** Key */ + uint16_t key; + /** Length of this structure */ + uint8_t len; + /** Reserved */ + uint8_t reserved_a[3]; + /** Host bus type */ + struct edd_host_bus_type host_bus_type; + /** Interface type */ + struct edd_interface_type interface_type; + /** Interface path */ + union edd_interface_path interface_path; + /** Device path */ + union edd_device_path device_path; + /** Reserved */ + uint8_t reserved_b; + /** Checksum */ + uint8_t checksum; +} __attribute__ (( packed )); + +/** EDD device path information key */ +#define EDD_DEVICE_PATH_INFO_KEY 0xbedd + +extern int edd_describe ( struct interface *intf, + struct edd_interface_type *type, + union edd_device_path *path ); +#define edd_describe_TYPE( object_type ) \ + typeof ( int ( object_type, struct edd_interface_type *type, \ + union edd_device_path *path ) ) + +#endif /* _IPXE_EDD_H */ diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h index 8101560c..10bc49d8 100644 --- a/src/include/ipxe/errfile.h +++ b/src/include/ipxe/errfile.h @@ -58,6 +58,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define ERRFILE_blockdev ( ERRFILE_CORE | 0x00120000 ) #define ERRFILE_acpi ( ERRFILE_CORE | 0x00130000 ) #define ERRFILE_null_sanboot ( ERRFILE_CORE | 0x00140000 ) +#define ERRFILE_edd ( ERRFILE_CORE | 0x00150000 ) #define ERRFILE_eisa ( ERRFILE_DRIVER | 0x00000000 ) #define ERRFILE_isa ( ERRFILE_DRIVER | 0x00010000 )