You can import this changeset into BK by piping this whole message to '| bk receive [path to repository]' or apply the patch as usual. =================================================================== ChangeSet@1.582, 2002-09-03 15:05:38-05:00, Matt_Domsch@dell.com Initial release of x86 BIOS Enhanced Disk Device (EDD) polling Documentation/i386/zero-page.txt | 2 arch/i386/Config.help | 10 arch/i386/boot/setup.S | 46 +++ arch/i386/config.in | 4 arch/i386/defconfig | 1 arch/i386/kernel/Makefile | 1 arch/i386/kernel/edd.c | 455 +++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/i386_ksyms.c | 6 arch/i386/kernel/setup.c | 23 + include/asm-i386/edd.h | 162 +++++++++++++ 10 files changed, 710 insertions diff -Nru a/Documentation/i386/zero-page.txt b/Documentation/i386/zero-page.txt --- a/Documentation/i386/zero-page.txt Tue Sep 3 15:06:13 2002 +++ b/Documentation/i386/zero-page.txt Tue Sep 3 15:06:13 2002 @@ -31,6 +31,7 @@ 0x1e0 unsigned long ALT_MEM_K, alternative mem check, in Kb 0x1e8 char number of entries in E820MAP (below) +0x1e9 unsigned char number of entries in EDDBUF (below) 0x1f1 char size of setup.S, number of sectors 0x1f2 unsigned short MOUNT_ROOT_RDONLY (if !=0) 0x1f4 unsigned short size of compressed kernel-part in the @@ -66,6 +67,7 @@ 0x220 4 bytes (setup.S) 0x224 unsigned short setup.S heap end pointer 0x2d0 - 0x600 E820MAP +0x600 - 0x7D4 EDDBUF (setup.S) 0x800 string, 2K max COMMAND_LINE, the kernel commandline as copied using CL_OFFSET. diff -Nru a/arch/i386/Config.help b/arch/i386/Config.help --- a/arch/i386/Config.help Tue Sep 3 15:06:13 2002 +++ b/arch/i386/Config.help Tue Sep 3 15:06:13 2002 @@ -967,3 +967,13 @@ absence of features. For more information take a look at Documentation/swsusp.txt. + +CONFIG_EDD + Say Y or M here if you want to enable BIOS Enhanced Disk Device + Services real mode BIOS calls to determine which disk + BIOS tries boot from. This feature creates a /proc/edd directory + and files for each BIOS device detected. + + This option is experimental, and most disk controller BIOS + vendors do not yet implement this feature. + diff -Nru a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S --- a/arch/i386/boot/setup.S Tue Sep 3 15:06:13 2002 +++ b/arch/i386/boot/setup.S Tue Sep 3 15:06:13 2002 @@ -44,6 +44,8 @@ * * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes * by Robert Schwebel, December 2001 + * + * BIOS EDD support September 2002 by Matt Domsch * */ @@ -53,6 +55,7 @@ #include #include #include +#include #include /* Signature words to ensure LILO loaded us right */ @@ -541,6 +544,49 @@ no_32_apm_bios: andw $0xfffd, (76) # remove 32 bit support bit done_apm_bios: +#endif + +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) +# Do the BIOS EDD calls +# This code is sensitive to the size of the structs in edd.h +edd_start: + # %ds points to the bootsector + # result buffer for fn48 + movw $EDDBUF+EDDEXTSIZE, %si # in ds:si, fn41 results + # kept just before that + movb $0, (EDDNR) # zero value at EDDNR + movb $0x80, %dl # BIOS device 0x80 + +edd_check_ext: + movb $0x41, %ah # Function 41 + movw $0x55aa, %bx # magic + int $0x13 # make the call + jc edd_done # no more BIOS devices + + cmpw $0xAA55, %bx # is magic right? + jne edd_next # nope, next... + + movb %dl, %ds:-4(%si) # store device number + movb %ah, %ds:-3(%si) # store version + movw %cx, %ds:-2(%si) # store extensions + incb (EDDNR) # note that we stored something + +edd_get_device_params: + movw $EDDPARMSIZE, %ds:(%si) # put size + movb $0x48, %ah # Function 48 + int $0x13 # make the call + # Don't check for fail return + # it doesn't matter. + movw %si, %ax # increment si + addw $EDDPARMSIZE+EDDEXTSIZE, %ax + movw %ax, %si + +edd_next: + incb %dl # increment to next device + cmpb $EDDMAXNR, (EDDNR) # Out of space? + jb edd_check_ext # keep looping + +edd_done: #endif # Now we want to move to protected mode ... diff -Nru a/arch/i386/config.in b/arch/i386/config.in --- a/arch/i386/config.in Tue Sep 3 15:06:13 2002 +++ b/arch/i386/config.in Tue Sep 3 15:06:13 2002 @@ -181,6 +181,10 @@ tristate '/dev/cpu/*/msr - Model-specific register support' CONFIG_X86_MSR tristate '/dev/cpu/*/cpuid - CPU information support' CONFIG_X86_CPUID +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate 'BIOS Enhanced Disk Device calls determine boot disk (EXPERIMENTAL)' CONFIG_EDD +fi + choice 'High Memory Support' \ "off CONFIG_NOHIGHMEM \ 4GB CONFIG_HIGHMEM4G \ diff -Nru a/arch/i386/defconfig b/arch/i386/defconfig --- a/arch/i386/defconfig Tue Sep 3 15:06:13 2002 +++ b/arch/i386/defconfig Tue Sep 3 15:06:13 2002 @@ -69,6 +69,7 @@ # CONFIG_MICROCODE is not set # CONFIG_X86_MSR is not set # CONFIG_X86_CPUID is not set +# CONFIG_EDD is not set CONFIG_NOHIGHMEM=y # CONFIG_HIGHMEM4G is not set # CONFIG_HIGHMEM64G is not set diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile --- a/arch/i386/kernel/Makefile Tue Sep 3 15:06:13 2002 +++ b/arch/i386/kernel/Makefile Tue Sep 3 15:06:13 2002 @@ -25,6 +25,7 @@ obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o +obj-$(CONFIG_EDD) += edd.o ifdef CONFIG_VISWS obj-y += setup-visws.o obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o diff -Nru a/arch/i386/kernel/edd.c b/arch/i386/kernel/edd.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/edd.c Tue Sep 3 15:06:13 2002 @@ -0,0 +1,455 @@ +/* + * BIOS Enhanced Disk Device Services + * + * Copyright (C) 2002 Dell Computer Corporation + * + * This code takes information provided by BIOS EDD calls + * made in setup.S, copied to safe structures in setup.c, + * and presents it in /proc/edd/{bios_device_number}. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License v2.0 as published by + * the Free Software Foundation + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Matt Domsch "); +MODULE_DESCRIPTION("/proc interface to BIOS EDD information"); +MODULE_LICENSE("GPL"); + +static int debug; +MODULE_PARM(debug, "i"); +MODULE_PARM_DESC(debug, "Enable additional verbose debug output."); + +#define EDD_VERSION "0.01 2002-Sep-03" + +/* Don't need to keep a pointer to edd_info here because + it will get passed in to edd_read for us. +*/ +struct edd_proc_info { + struct proc_dir_entry *entry; + struct list_head list; +}; + +static LIST_HEAD(edd_list); +static spinlock_t edd_lock = SPIN_LOCK_UNLOCKED; /* protects edd_list */ +static struct proc_dir_entry *edd_dir; + +#define edd_entry(n) list_entry(n, struct edd_proc_info, list) + + + +static int +proc_calc_metrics(char *page, char **start, off_t off, + int count, int *eof, int len) +{ + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +static int +edd_dump_raw_data(char *b, void *data, int length) +{ + char *orig_b = b; + char buffer1[80], buffer2[80], *b1, *b2, c; + unsigned char *p = data; + unsigned long column=0; + int length_printed = 0; + const char maxcolumn = 16; + while (length_printed < length) { + b1 = buffer1; + b2 = buffer2; + for (column = 0; + column < maxcolumn && length_printed < length; + column ++) { + b1 += sprintf(b1, "%02x ",(unsigned char) *p); + if (*p < 32 || *p > 126) c = '.'; + else c = *p; + b2 += sprintf(b2, "%c", c); + p++; + length_printed++; + } + /* pad out the line */ + for (; column < maxcolumn; column++) + { + b1 += sprintf(b1, " "); + b2 += sprintf(b2, " "); + } + + b += sprintf(b, "%s\t%s\n", buffer1, buffer2); + } + return (b - orig_b); +} + + +/*** + * edd_read() - exports EDD information to /proc/edd/{device_number} + * + * Returns: number of bytes written, or -EINVAL on failure + */ +static int +edd_read(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = 0; + struct edd_info *edd=(struct edd_info *)data; + int i, warn_padding=0, nonzero_path=0, warn_key=0, warn_checksum=0; + uint8_t checksum=0, c=0; + char *p = page; + enum _bus_type {bus_type_unknown, + isa, pci, pcix, + ibnd, xprs, htpt} bus_type = bus_type_unknown; + enum _interface_type {interface_type_unknown, + ata, atapi, scsi, usb, + i1394, fibre, i2o, raid, sata} + interface_type = interface_type_unknown; + + if (!data) { + *eof=1; + return 0; + } + + MOD_INC_USE_COUNT; + + if (debug) { + p += edd_dump_raw_data(p, edd, sizeof(*edd)); + + p += sprintf(p, "version: "); + switch (edd->version) { + case 0x0: + p += sprintf(p, "unsupported\n"); + case 0x21: + p += sprintf(p, "1.1\n"); + break; + case 0x30: + p += sprintf(p, "3.0\n"); + break; + default: + p += sprintf(p, "(unknown version %xh)\n", + edd->version); + break; + } + + p += sprintf(p, "Extensions:\n"); + if (edd->interface_support & EDD_EXT_FIXED_DISK_ACCESS) { + p += sprintf(p, "\tFixed disk access\n"); + } + if (edd->interface_support & EDD_EXT_DEVICE_LOCKING_AND_EJECTING) { + p += sprintf(p, "\tDevice locking and ejecting\n"); + } + if (edd->interface_support & EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT) { + p += sprintf(p, "\tEnhanced Disk Drive support\n"); + } + if (edd->interface_support & EDD_EXT_64BIT_EXTENSIONS) { + p += sprintf(p, "\t64-bit extensions\n"); + } + + p += sprintf(p, "Info Flags:\n"); + if (edd->params.info_flags & EDD_INFO_DMA_BOUNDRY_ERROR_TRANSPARENT) + p += sprintf(p, "\tdma_boundry_error_transparent\n"); + if (edd->params.info_flags & EDD_INFO_GEOMETRY_VALID) + p += sprintf(p, "\tgeometry_valid\n"); + if (edd->params.info_flags & EDD_INFO_REMOVABLE) + p += sprintf(p, "\tremovable\n"); + if (edd->params.info_flags & EDD_INFO_WRITE_VERIFY) + p += sprintf(p, "\twrite_verify\n"); + if (edd->params.info_flags & EDD_INFO_MEDIA_CHANGE_NOTIFICATION) + p += sprintf(p, "\tmedia_change_notification\n"); + if (edd->params.info_flags & EDD_INFO_LOCKABLE) + p += sprintf(p, "\tlockable\n"); + if (edd->params.info_flags & EDD_INFO_NO_MEDIA_PRESENT) + p += sprintf(p, "\tno_media_present\n"); + if (edd->params.info_flags & EDD_INFO_USE_INT13_FN50) + p += sprintf(p, "\tuse_int13_fn50\n"); + + p += sprintf(p, "num_default_cylinders: %x\n", + edd->params.num_default_cylinders); + p += sprintf(p, "num_default_heads: %x\n", edd->params.num_default_heads); + p += sprintf(p, "sectors_per_track: %x\n", edd->params.sectors_per_track); + p += sprintf(p, "number_of_sectors: %llx\n", + edd->params.number_of_sectors); + } /* if (debug) */ + + /* Spec violation here. Adaptec AIC7899 returns 0xDDBE + here, when it should be (per spec) 0xBEDD. + */ + if (edd->params.key == 0xDDBE) { + warn_key=1; + } + + if (! (edd->params.key == 0xBEDD || edd->params.key == 0xDDBE)) { + len = (p + 1 - page); + MOD_DEC_USE_COUNT; + return proc_calc_metrics(page, start, off, count, eof, len); + } + + for (i=30; i<=73; i++) { + c = *(((uint8_t *)edd)+i+4); + if (c) nonzero_path++; + checksum += c; + } + if (checksum) { + warn_checksum=1; + if (!nonzero_path) { + p += sprintf(p, "Warning: Spec violation. Device Path checksum invalid (0x%02x should be 0x00).\n", checksum); + len = (p + 1 - page); + MOD_DEC_USE_COUNT; + return proc_calc_metrics(page, start, off, count, eof, len); + } + } + + + /* Spec violation here. Adaptec AIC7899 has 0x00 (NULL) bytes for + padding instead of 0x20 (space) bytes. */ + + p += sprintf(p, "host_bus: "); + for (i=0; i<4; i++) { + if (isprint(edd->params.host_bus_type[i])) { + p += sprintf(p, "%c", edd->params.host_bus_type[i]); + } else { + p += sprintf(p, " "); + warn_padding++; + } + + + } + + /* Print interface path information */ + if (!strncmp(edd->params.host_bus_type, "ISA", 3)) { + bus_type = isa; + } else if (!strncmp(edd->params.host_bus_type, "PCIX", 4)) { + bus_type = pcix; + } else if (!strncmp(edd->params.host_bus_type, "PCI", 3)) { + bus_type = pci; + } else if (!strncmp(edd->params.host_bus_type, "IBND", 4)) { + bus_type = ibnd; + } else if (!strncmp(edd->params.host_bus_type, "XPRS", 4)) { + bus_type = xprs; + } else if (!strncmp(edd->params.host_bus_type, "HTPT", 4)) { + bus_type = htpt; + } + switch (bus_type) { + case isa: + p += sprintf(p, "\tbase_address: %x\n", + edd->params.interface_path.isa.base_address); + break; + case pci: + case pcix: + p += sprintf(p, + "\t%02x:%02x.%01x channel: %x\n", + edd->params.interface_path.pci.bus, + edd->params.interface_path.pci.slot, + edd->params.interface_path.pci.function, + edd->params.interface_path.pci.channel); + break; + case ibnd: + case xprs: + case htpt: + p += sprintf(p, + "\tTBD: %llx\n", + edd->params.interface_path.ibnd.reserved); + break; + default: + p += sprintf(p, "\tunknown: %llx\n", + edd->params.interface_path.unknown.reserved); + break; + } + + /* Spec violation here. Adaptec AIC7899 has 0x00 (NULL) bytes for + padding instead of 0x20 (space) bytes. */ + /* Print device path information */ + p += sprintf(p, "interface: "); + for (i=0; i<8; i++) { + if (isprint(edd->params.interface_type[i])) { + p += sprintf(p, "%c", edd->params.interface_type[i]); + } else { + p += sprintf(p, " "); + warn_padding++; + } + } + if (!strncmp(edd->params.interface_type, "ATAPI", 5)) { + interface_type = atapi; + } else if (!strncmp(edd->params.interface_type, "ATA", 3)) { + interface_type = ata; + } else if (!strncmp(edd->params.interface_type, "SCSI", 4)) { + interface_type = scsi; + } else if (!strncmp(edd->params.interface_type, "USB", 3)) { + interface_type = usb; + } else if (!strncmp(edd->params.interface_type, "1394", 4)) { + interface_type = i1394; + } else if (!strncmp(edd->params.interface_type, "FIBRE", 5)) { + interface_type = fibre; + } else if (!strncmp(edd->params.interface_type, "I2O", 3)) { + interface_type = i2o; + } else if (!strncmp(edd->params.interface_type, "RAID", 4)) { + interface_type = raid; + } else if (!strncmp(edd->params.interface_type, "SATA", 4)) { + interface_type = sata; + } + + + switch (interface_type) { + case ata: + p += sprintf(p, "\tdevice: %x\n", + edd->params.device_path.ata.device); + break; + case atapi: + p += sprintf(p, "\tdevice: %x lun: %x\n", + edd->params.device_path.atapi.device, + edd->params.device_path.atapi.lun); + break; + case scsi: + p += sprintf(p, "\tid: %x lun: %llx\n", + edd->params.device_path.scsi.id, + edd->params.device_path.scsi.lun); + break; + case usb: + p += sprintf(p, "\tserial_number: %llx\n", + edd->params.device_path.usb.serial_number); + break; + case i1394: + p += sprintf(p, "\teui: %llx\n", + edd->params.device_path.i1394.eui); + break; + case fibre: + p += sprintf(p, "\twwid: %llx lun: %llx\n", + edd->params.device_path.fibre.wwid, + edd->params.device_path.fibre.lun); + break; + case i2o: + p += sprintf(p, "\tidentity_tag: %llx\n", + edd->params.device_path.i2o.identity_tag); + break; + case raid: + p += sprintf(p, "\tidentity_tag: %x\n", + edd->params.device_path.raid.array_number); + break; + case sata: + p += sprintf(p, "\tdevice: %x\n", + edd->params.device_path.sata.device); + break; + default: + p += sprintf(p, "\tunknown: %llx %llx\n", + edd->params.device_path.unknown.reserved1, + edd->params.device_path.unknown.reserved2); + + } + + p += sprintf(p, "\n"); + if (warn_key) { + p += sprintf(p, "Warning: Spec violation. Key should be 0xBEDD, is 0xDDBE\n"); + } + if (warn_padding) { + p += sprintf(p, "Warning: Spec violation. Padding should be 0x20, is 0x00\n"); + } + if (warn_checksum) { + p += sprintf(p, "Warning: Spec violation. Device Path checksum invalid (0x%02x should be 0x00).\n", checksum); + } + + len = (p + 1 - page); + + MOD_DEC_USE_COUNT; + + return proc_calc_metrics(page, start, off, count, eof, len); +} + +/** + * edd_create_proc_entry() + * + * Returns 1 on failure, 0 on success + */ +static int +edd_create_proc_entry(struct edd_info *info) +{ + + char name[4]; + struct edd_proc_info *new_proc_info; + + if (!info || !info->device) return 1; + new_proc_info = kmalloc(sizeof(*new_proc_info), + GFP_KERNEL); + + if (!new_proc_info) return 1; + memset(new_proc_info, 0, sizeof(*new_proc_info)); + + snprintf(name, 4, "%02x", info->device); + + /* Create the entry in proc */ + new_proc_info->entry = create_proc_read_entry(name, 0444, edd_dir, edd_read, info); + if (!new_proc_info->entry) { + kfree(new_proc_info); + return 1; + } + spin_lock(&edd_lock); + list_add(&new_proc_info->list, &edd_list); + spin_unlock(&edd_lock); + + return 0; +} + + + +/** + * edd_init() - creates /proc/edd/{device} tree. + * + * This assumes that eddnr and edd were + * assigned in setup.c already. + */ +static int __init +edd_init(void) +{ + + unsigned int i; + + printk(KERN_INFO "BIOS EDD facility v%s, %d devices found\n", EDD_VERSION, eddnr); + + if (!eddnr) { + printk(KERN_INFO "EDD information not available.\n"); + return 1; + } + + edd_dir = proc_mkdir("edd", edd_dir); + if (!edd_dir) return 1; + + for (i=0; ientry->name, edd_dir); + list_del(&proc_info->list); + kfree(proc_info); + } + spin_unlock(&edd_lock); + remove_proc_entry(edd_dir->name, NULL); +} + +late_initcall(edd_init); +module_exit(edd_exit); diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c --- a/arch/i386/kernel/i386_ksyms.c Tue Sep 3 15:06:13 2002 +++ b/arch/i386/kernel/i386_ksyms.c Tue Sep 3 15:06:13 2002 @@ -29,6 +29,7 @@ #include #include #include +#include extern void dump_thread(struct pt_regs *, struct user *); extern spinlock_t rtc_lock; @@ -172,3 +173,8 @@ EXPORT_SYMBOL(is_sony_vaio_laptop); EXPORT_SYMBOL(__PAGE_KERNEL); + +#ifdef CONFIG_EDD_MODULE +EXPORT_SYMBOL(edd); +EXPORT_SYMBOL(eddnr); +#endif diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c --- a/arch/i386/kernel/setup.c Tue Sep 3 15:06:13 2002 +++ b/arch/i386/kernel/setup.c Tue Sep 3 15:06:13 2002 @@ -36,6 +36,7 @@ #include #include #include +#include /* * Machine setup.. @@ -106,6 +107,8 @@ #define KERNEL_START (*(unsigned long *) (PARAM+0x214)) #define INITRD_START (*(unsigned long *) (PARAM+0x218)) #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) +#define EDD_NR (*(unsigned char *) (PARAM+EDDNR)) +#define EDD_BUF ((struct edd_info *) (PARAM+EDDBUF)) #define COMMAND_LINE ((char *) (PARAM+2048)) #define COMMAND_LINE_SIZE 256 @@ -486,6 +489,25 @@ return 0; } +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) +unsigned char eddnr; +struct edd_info edd[EDDNR]; +/** + * copy_edd() - Copy the BIOS EDD information into a safe place. + * + */ +static inline void copy_edd(void) +{ + eddnr = EDD_NR; + memcpy(edd, EDD_BUF, sizeof(edd)); +} +#else +static inline void copy_edd(void) +{ +} +#endif + + /* * Do NOT EVER look at the BIOS memory size location. * It does not work on many machines. @@ -631,6 +653,7 @@ rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); #endif setup_memory_region(); + copy_edd(); if (!MOUNT_ROOT_RDONLY) root_mountflags &= ~MS_RDONLY; diff -Nru a/include/asm-i386/edd.h b/include/asm-i386/edd.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-i386/edd.h Tue Sep 3 15:06:13 2002 @@ -0,0 +1,162 @@ +/* + * linux/include/asm-i386/edd.h + * by Matt Domsch + * Copyright 2002 Dell Computer Corporation + * + * structures and definitions for the int 13, ax={41,48}h + * BIOS Enhanced Disk Device Services + * This is based on the T13 group document D1572 Revision 0 (August 14 2002) + * available at http://www.t13.org/docs2002/d1572r0.pdf. It is + * very similar to D1484 Revision 3 http://www.t13.org/docs2002/d1484r3.pdf + * + * In a nutshell, arch/i386/boot/setup.S populates a scratch table + * in the empty_zero_block that contains a list of BIOS-enumerated + * boot devices. + * In arch/i386/kernel/setup.c, this information is + * transferred into the edd structure, and in arch/i386/kernel/edd.c, that + * information is used to identify BIOS boot disk. The code in setup.S + * is very sensitive to the size of these structures. + * + */ +#ifndef _ASM_I386_EDD_H +#define _ASM_I386_EDD_H + +#define EDDNR 0x1e9 /* addr of number of edd_info structs at EDDBUF + in empty_zero_block - treat this as 1 byte */ +#define EDDBUF 0x600 /* addr of edd_info structs in empty_zero_block */ +#define EDDMAXNR 6 /* number of edd_info structs starting at EDDBUF */ +#define EDDEXTSIZE 4 /* change these if you muck with the structures */ +#define EDDPARMSIZE 74 + +#define EDD_EXT_FIXED_DISK_ACCESS (1 << 0) +#define EDD_EXT_DEVICE_LOCKING_AND_EJECTING (1 << 1) +#define EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT (1 << 2) +#define EDD_EXT_64BIT_EXTENSIONS (1 << 3) + +#define EDD_INFO_DMA_BOUNDRY_ERROR_TRANSPARENT (1 << 0) +#define EDD_INFO_GEOMETRY_VALID (1 << 1) +#define EDD_INFO_REMOVABLE (1 << 2) +#define EDD_INFO_WRITE_VERIFY (1 << 3) +#define EDD_INFO_MEDIA_CHANGE_NOTIFICATION (1 << 4) +#define EDD_INFO_LOCKABLE (1 << 5) +#define EDD_INFO_NO_MEDIA_PRESENT (1 << 6) +#define EDD_INFO_USE_INT13_FN50 (1 << 7) + + + +#ifndef __ASSEMBLY__ + +struct edd_device_params { + u16 length; + u16 info_flags; + u32 num_default_cylinders; + u32 num_default_heads; + u32 sectors_per_track; + u64 number_of_sectors; + u16 bytes_per_sector; + u32 dpte_ptr; /* 0xFFFFFFFF for our purposes */ + u16 key; /* = 0xBEDD */ + u8 device_path_info_length; /* = 44 */ + u8 reserved2; + u16 reserved3; + u8 host_bus_type[4]; + u8 interface_type[8]; + union { + struct { + u16 base_address; + u16 reserved1; + u32 reserved2; + } __attribute__((packed)) isa; + struct { + u8 bus; + u8 slot; + u8 function; + u8 channel; + u32 reserved; + } __attribute__((packed)) pci; + /* pcix is same as pci */ + struct { + u64 reserved; + } __attribute__((packed)) ibnd; + struct { + u64 reserved; + } __attribute__((packed)) xprs; + struct { + u64 reserved; + } __attribute__((packed)) htpt; + struct { + u64 reserved; + } __attribute__((packed)) unknown; + } interface_path; + union { + struct { + u8 device; + u8 reserved1; + u16 reserved2; + u32 reserved3; + u64 reserved4; + } __attribute__((packed)) ata; + struct { + u8 device; + u8 lun; + u8 reserved1; + u8 reserved2; + u32 reserved3; + u64 reserved4; + } __attribute__((packed)) atapi; + struct { + u16 id; + u64 lun; + u16 reserved1; + u32 reserved2; + } __attribute__((packed)) scsi; + struct { + u64 serial_number; + u64 reserved; + } __attribute__((packed)) usb; + struct { + u64 eui; + u64 reserved; + } __attribute__((packed)) i1394; + struct { + u64 wwid; + u64 lun; + } __attribute__((packed)) fibre; + struct { + u64 identity_tag; + u64 reserved; + } __attribute__((packed)) i2o; + struct { + u32 array_number; + u32 reserved1; + u64 reserved2; + } __attribute((packed)) raid; + struct { + u8 device; + u8 reserved1; + u16 reserved2; + u32 reserved3; + u64 reserved4; + } __attribute__((packed)) sata; + struct { + u64 reserved1; + u64 reserved2; + } __attribute__((packed)) unknown; + } device_path; + u8 reserved4; + u8 checksum; +} __attribute__((packed)); + +struct edd_info { + u8 device; + u8 version; + u16 interface_support; + struct edd_device_params params; +} __attribute__((packed)); + +extern struct edd_info edd[EDDNR]; +extern unsigned char eddnr; +#endif/*!__ASSEMBLY__*/ + +#endif /* _ASM_I386_EDD_H */ + =================================================================== This BitKeeper patch contains the following changesets: 1.582 ## Wrapped with gzip_uu ## begin 664 bkpatch29651 M'XL(`#46=3T``\P\_7/B-M,_A[]"3:=7R!'P!Y_)Y:8$R!WO)20#Y'I]>AV/ ML47P&V,SMDG"4_*_/[N2##;8"83K3&F/V+*T7]I=[&&/R0#W_Y$`NJ,N68#ZE)P>]]J?;RT8ODSD[(\VQ[MS1/@W(V5DF M<+T'W3;]W_1@;+M.(?!TQY_00$?TBV77A2))"OQ7EJNJ5*XLY(I4JBX,V91E MO2134U)*M4HIX^GS8_O^MXEN>OIP:`4%U[M;!U*79$4IUZ3Z0I6JDIII$;E0 MKBE$4HI2O2BI1"Z?2.43M78,WY)$(O+Y+90+>2]+Y%C*G),?2W\S8Y".8P66 M;A./VE3W*7%'Y*E6(>>=ZSYI.P#0H"9I6?X]:=$'RZ`DVVZU,=/YF,I$N9CZ\PUW*-V80Z@1Y8KE.TU%JE^%_JN<=3_8X6 M@JU85U53$,&IA/ENR7LNJ3*];*BU!8E6:J77Z58 M]T!Y&3##=4;67<%R8D0JT@+@E4N@&7)I1.OU^E`?*2"+9")3P:WH4JLUI;0# M728=<5AQNN2%7))JY06EY9I>ETU]5*O708"OT;4&+B*O:KE2VX&N>^HYU"Y> MZ?=T9-ETG;I22:V4%V5Y2,W12"JKAJE+AOD:=8E`5S3*LB3M(KLA>*JB3X/9 MM-#?F%:Y`M-:DHW`38@KZLJ5JES?78)XK=W[\XE?,-:E M6*[6*K5%K3H:&<.:KNKELCI4U"VEN`DXHH6UJH+VO!TD<.CK(*HX&55U43$K M-6E4HI6RKM?JPU?M(AUB;2%)Y7(J499CV#.3%G5_R(DER5587X.\4 M=:'JE;(T*M.21)6:HNJOB6L#8&0*U7)=W5W=N/)N:%JIJLK20I"3FHT!?AX)?B_AY;K:R9C6W-FDR'UG@N" M6$XM=+WS]`F!RY%'`9$["AYUCYZ2N3L#^AP(KTT+T%M#D`4B`(1%UR,3U[1& M."8(*QL`Y]28^QN)X\ZE[2SY1AWH0IM_,AK9ED$L@Q8%H_4$!1Z,# M`=CLCYE@�<=X&D]`4IY,(%\$R*::2O*#11``AB[$Z!F+$>('F/%LSGD)*9 M3TV?P^?IV0!K=/\COC5ZOT1W\<0J]@[$+3^D#Y;"LR=3&V0!J MP'*".;#'0%RU>\W/,*9QWKGL#/X@():+SJ#;[O?)Q76/-,A-HS?H-#&A(S>W MO9OK?KM`0/V0,,H@O""@$1,RL&^"H5JV+^:MF/F>^5FLT>0#G5FA/A[G3<%"KW6_V.C>#SG4W>\C(@QD&)1OI8,E@'DM;BAA; M9/AEI]GN]MO9PT\WE]C\/>-CKL2`@&2'L[ME5YBLJRQKRI-#*P(#'S`ZED_; MCCZ$-4DW30OQP>1!/C]T?1KX%&\. MP(_8Q>FR`QALH(T1J/A@PVGF.2+>RTY_H'UN-UI9Q(+/01;BF3^U'-LU[C5. M`EZ2,]*_Z72UR^OF%^VVBW_:K5,"$@%B`FJ`;POA$,8`!Y1([Q'VA-NH[+&) M/TY@,ZP%>V]!@^?0LP\\:8]TC1YAN@]-FUT?0 MWPORX"1&P"%\YS,'!X0IG`&>#)[@Y1%U1_S*IDXN`]*W1B0+U^3#&0YZS_KF M6#^0C@S2YX#A!K&1]]@+6G'(\9FX$3`^BL'X[(QC73W\((4/)&CT8"WQ'&R` M"8PSR^0XFTPU3W_4P`'K@MEAGCRXEDF.L&W)PUTP1C9"E>!=75A8M2&@&@(J MUC2 M39PS9&5%",PDFHPI>`3_"'K#`$WT)SX"95J!9X]CC"ZS:^,^A!RA61P,9>2` M$WZ*]\KR7L%[-*WL$BQB/.`RX$T?(EC?O5LG,41U2M:&O7_/L2/Z]V=@-3A@ ME$4I'?XB*4_D,)^-20F499I#Y&RF060?B*J0Q0*E]Y'(2B5'(+D@OQ9^99VH M#?X*&XZF[!ZXBJ)1$(UQ"+/!84[?OV=_X^3SQF?XA[8*'@$73EPS;30[,%4A MG=,$881MP"AT2V,5!'*82R-0/$+%A>>QQTB^_SV`?\YAJ&GR4N5PV/-26841 M9(?DF'"5S7%K0*=\Q&*.T(]F<]"'![[^1M@+_C82?,7C+A&[]!@J_X3P9HR4 MAO,`XKI'SPH""@X)Q'7<[G2_-BX)@!S!V@]Q7R;B]D+;9.1LXW^2?<_*AKG[ MX=8C%#CB%=GJ@$[U++O1FN,V&&V-JW/NS"9IQ"&L&P&H:FFWX#!B,=E@Y!N1^U4Y!LD0;SGP-PQ+R M=WBES9Q[QWUT\LN>ZQ_+!WHY.6)3",Y),(OBF[WS]^(GI"_-+J$5GS!\*\Y%B-I4Y@/!)ZW2;VFV_ MK36O;[N#TQ`*BY(XE"D:[>9*,\UC(Y!K_1?09%']1Q_%,\X,@/?$TA/T@ES:.M@P)G.IFC8U/SN<%!B@"*?D,0A MD)2'70]`TOI]9)":@D8M2.MCUFKY7 M]$1\8J+:I"?\+%E\3IF)]A.X,`3BGX0\XGPS\"O5$F(F[UA,W/XVT"XZW]HM MK=7I?]$:S28D4&+IVT#P/;BPGF"],S&?UPW(XOT0T?.VR%KMKY`5L%BST_VD M-;K0_'_MY@!NTM&*O0,,5G'#`]-N^O\0F,+-S@2TNY`U-D.&6[W.U[;6O[VY MN>X-T@E8V\KPK`?(UCGHG0FHE,X[`[R"W`C2D1>D72D=#R&WH,MYC>)*TH`. MK@L7MGZ7H`%3'?)UOX!+AS;"+H*D3O?B6FM=-;1S\!*MWA]:N]>[[FD#R,?[ MD'RUNX-<"GGF1->&N#W@S37J>:ZGL;TM0`3Q_6[X/[6OK]H#0`X+;Z>5AO". MNACYS[4'W;;,W3#TVE?77QOGE^TTX!Z=N`^86>X&]_=>9]#&U+)S\4<::(PN MJ`86;HWFNT&_:K[UH'/1:38P'4]#-:&FI<.2CKN*FN,&UL@R M6'C$\)*M$:-]OB0M-,7=A=4-.;KIM?LO:);C:IP1L;FV&Q9<\CK=@:QJ%]VR ME(8#,$:#7R"DO%X4DJX)P0A.+@F;,(;8VL7X`G#QS\0KNL3A,7D M[$R@X7YY&2[+JY7Y.<(#B\M2H"!>3`'347`Y&<+3D%7^D0^S#I9PX$9'/$0,+UB*:)VITBFQ/IQ55?@39K\L0;>U#2>XI?%V+-]N>OUML."6R=NQ?![<#+;!@ELR2>X\ MW`((NT;!L/0<=&8SNTX(T8;060,3@2!P%6^MCXM]XL%AF(.A/10`:2$*,,$V MUS8$&*V@%2>9@_#RZ56Z7Z8/F,)EY02_"K](\A/;27,<:N_-'U!7`(GO!\"W MW6`_"*.98Z#/V0^*$$KZ'/$906L*9P=U/KQ&S=Q_I@;GK4C(^U9VD,8"IC'> M`S5?5[K4W:>D%(9O._T`(@6D'>A\_C<$'1$"^!K(=_U?7``WY+@417I\4MLY M/HEOY>X?H&S"^Q=$*)M7J6M,G'Y`W1@T;G!9+B<*9F-KG&W!;[^D):%+C0&2 MD.V!JM_L=U*7SPU<^%)A#V2W_?/M^9KYPSU0X4N-[?EB[T#VP';1.>^UM]J7J.3'BINX,(71_LH(U?\;94QKOGL'6QX%T9U\4$; ML1U`V&KMXIYZ]ZA'O-=EJQ;@$O=;!G/,B^Q('B'VS-F;SJDE6O8"`91LR2FZ ME:T8M)W%7U]A7!"^L$A:\'?8'?]"Y['-;WR7 MD<=R;_[F0B",1_[1C&%/]#R;I-<'WS'ZO"9YY[5Q8.F>`20245]CRTMM,HIC0 MB4^#;*P#"&E5'Q4?RF'ZCM`SY!P"<%$W>I@G,598W^(1:3*1LN)-7DAM\;EG M59PQ^,839=V$U.?9B1=Y@P=EW:PCP09Z\BY2E_&**C2S<&YLY)O,KD1,,>4XZ2D_,([_G-7T;6-8+91TW M(/H#&#L6;K*'T'JX5*NE&H7W$:L!"-$=-"[K M=^_@$LBY:GSK]B+OF9.="FH#W^E"55M7!S$-K)!6T^B3F`>\6,[#YIF)HZD+ M`CYR4AU1W`F]I-_`GD9U8ZSA(;$L@^M$=5O,QLHUKIG7VW9EGL*3?'0N&VH] M/.2GD[CLPTF`9CQFFWRB.7[,-KG/"\=L]SEXG7S,5BW]^X_9IHB)'>^LJIDO MA#&V(VCMF^,C%R1?EGC]FB\Q2>@AUG8F?.?+YJ//%Z M9?*@>Q8[DV92P_;%A."Y9WY0?^W$;O8O M>I:61,[DOGP>5RRLD>.Q*)6HE'`%8&(H`S5)A:HX@'>C`&LZ(>:`0 M>OG6!("P,X$MN50KK9"JK\"$SIZ*,(7L.@[1B3,+_#$(.4^2?]2#3-WIS&8Q MCDY\P^._6(1,(`AQY)9.IL%<8^500W:HCX4XANL$NH7ZRM9`?)6&0C_&(Q(4 M`%$302"R,.(HA&2E_*!"'@!;\=/57#+,X$;4\WC,XW*J(+!:ZD>>Z8>5`)N= M.<\SDCE+4>!X<)B=R.0;'2-QA)L3#3I3P"/)E!_]7IWB9G!\,5]8/AU@S;8@ M"P-W<4S:CY[O7A[S_=D:.:#(1&OTK[0._F@)AE^?ET<:U]MC!TV[/?"J,JUC M7(_%!HAI=>!HF2-QM#XJ(@PZO[T0NP;`P\9D'F,HJP=<]CKF:_@2E-4R1A`# MC`/IJ2))4#WWSB5GYDJ,B;GM$H.%)8`8.7&O\8&_B(89(WI^5R8N$`@1BD;`Y:+_HG&^2IN36N7B_,3V8LH:!^?2,DD;=X MF7SB+E0B>QME\&GCU(1QJ07ND7&EA'%A?7HBF6)<.6'<>@5ZTKA*CFP.C!>5 M)R.LAH>6E^X#_$2_?75^^;_FKO6W;1N(?[;^"BT/-&X;SWK8EF,42[JU0X`F M&=)^6+$-ABPQB5)9,BP[<8;T?]\]2)F2_(C=IE@0(+%,'D^\.Y)W//[XN=\G MER7W./)@((8&T5.86FUU%C4/&>&S>8H[GKYU;'-A;OF"[RA-7#ZO9'SC\[9K M5E*V>\P(95A0:7XNR80C=-`FXU[Y]<&VF[/W\H=F_70Z-D=36"ID9,I,]HMX MJ%15]?-\:2KLF:86+J5QIZ].ZE)AU\T+YC%4R;SZ[/3H^V)J)X6@X&DIG\*C MQPE...BU24%11C'UAY8WUE,/\W`O/X'^T3FI?07IPQ*+D3'Z_8.#$?2[".MU M3IDL->)A8EU/_HM96.I_E4^E/LO,J$J;JYNDW$8^)AQ$,YP8,W#N"`(DB/BD M<($=T(VG$>9\QFUKIJQA7DJ)(O2ZOJ%7$855 M::,J'*T)3D>IZ&11)9_5*+)%5J%5?\H++1T(M$F'YPF=*1I]>7.G9RREURM. M]`K>1>\D^%\>]Y535N6X:#$\65PL\)\U'."9T7%BEAG!B"IY*##?R2)%K`^* MT_:,79&$T=7/+W_25S`,?T3?X"1<\H'X$$@164^#"L2(W_/@%0+9.Q$?3X/[ M1O#O*D)MJV7#K]L&0DW7Y7B3LR&NV_-!ZG*\Z=>+\_>GOV.7\D:0AM[&Z(I+ M\=NT]]TFF-1M=TVK"2*<,>B2]MGL_F1#`$6,Q+0WD(`49 MR@%3\F-$+I/%"7X-:80"8R,DT86PXF(FS0-BU13DR/UY7#+?>YO' M'*2MM<'6&*JY9&OK.F,;LW,3"(I(:P28#+2\=H_1O5QGW'\ZL8N<$$QOA(`YZZ&W(E^Z8I8;2&$21L;N+"A..21 M21@Q\+-K[H<9P_9EB@9V.TVQ. MK^;AS-?F?A9A7>`BS(X0$PCJ6))4EK/Q!61AWN(&Q$!<(98D1>2Q1Y'RH+;7 M?$VH^.>7=2J/0XD)BCL5,J)Z?IGS@:5G7A-3`V(JK$]C^`TN^7`3'=>G?5C9 M'>6-S%P+JODW5.V]C";`^&;(]VO.6BW?AR*#&149^M=10(A4^)WEU.33+YR= M@D(S:KDB:"ODY3A,C6V,IG[5`N&(VKFY*35FC<#HJ:63-II^@5(`BFD MF0#WDB9FL./'1J.AB-%+02=@3V1'A^X!R**.I;,)PW52C_#8J=?P;V0-IU1# M+L1E;^P',UG.+I6;@[!@WP2#VEQTQ.M$RO=><(70S!"LY`9O.U!A+A+1M9@4 M%_1'4B-8UU24F]G(F1A-)V0)18UPO46B]=9)3RHHXUV2RK#F^U$L,SCR,A&L M>%*18<$A#!YBW%`]A7J_[TMA)K`2HZ5.%ADU/PR+[U(T'G^F2/@SLB6INPFI MK>HKZF/6]D(#8-%84$HZ-V=0L@&U27L7N6&96/EB2AM?='H,%6U0*YB*-%8Q M,N,T'2EY&4J_C_!#<0K-+U+89/[<\#('8QR&TR3V1\=I%L9T1Y MLZ=X^O./=Y>G9^_./YU\V#'?F#L/.^8_/;27!%4!%E^8:R3,%\OWJ]F9F7LR M^>8D**)&O?Y"ZP?C*JHXS/E5&)MHUH;7<1A^Y-O6<0`NG#]H)"#+I:0\NVM; MC,7?ZK0]4JSNIA#UU@]3+%`I=+Y@?:5I$U\BLE2;\C?>1ILZ%BZ<=!:B.0L+ M+QE0UXAL(M^MKC4Q0O].W!YGTTPT0K&.FF>U+,]R831J>ITV(][;50_N_R+H MJSZCS%[I;2U4 M)966O+D6;733BN%?CU-8'Q_SGS1!6.$GT/60M-UU.H]MF#98@=I5!5J=V&<[ MSZ]!"':*EST\4'!1SXHAD&^Z_^%.A+K;*5]4N]N$;Y19IW2JWC;ZYBW7MZ9G MVH55#"\*Z;![`Y@M04@PUH]*`853UT/..IN M&098N-VP:IM"IORCF/KPG%+^,4.Q&$LHI(QA]IG/=W>,8ECTYVE=>>H^`613 MZGA.5^6,4T=PNOH;V:4R(V,HAL&(\J-?JU[+SX`(ALC]"G8;9^))#7V=1U3^ @-D[;%`BLS5^S-[^O,`="LX-F*QA8`^,_5\L8?Q=Q```` ` end