Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ibft: Update iBFT handling for v1.03 of the spec.

- Use struct acpi_table_ibft instead of struct ibft_table_header
- Don't do reserve_ibft_region() on UEFI machines (section 1.4.3.1)
- If ibft_addr isn't initialized when ibft_init() is called, check for
ACPI-based tables.
- Fix compiler error when CONFIG_ACPI is not defined.

Signed-off-by: Konrad Rzeszutek Wilk <konrad@kernel.org>
Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>

authored by

Peter Jones and committed by
Konrad Rzeszutek Wilk
4e639fdf 94b849aa

+50 -27
+18 -12
drivers/firmware/iscsi_ibft.c
··· 1 1 /* 2 - * Copyright 2007 Red Hat, Inc. 2 + * Copyright 2007-2010 Red Hat, Inc. 3 3 * by Peter Jones <pjones@redhat.com> 4 4 * Copyright 2008 IBM, Inc. 5 5 * by Konrad Rzeszutek <konradr@linux.vnet.ibm.com> ··· 18 18 * GNU General Public License for more details. 19 19 * 20 20 * Changelog: 21 + * 22 + * 06 Jan 2010 - Peter Jones <pjones@redhat.com> 23 + * New changelog entries are in the git log from now on. Not here. 21 24 * 22 25 * 14 Mar 2008 - Konrad Rzeszutek <ketuzsezr@darnok.org> 23 26 * Updated comments and copyrights. (v0.4.9) ··· 81 78 #include <linux/stat.h> 82 79 #include <linux/string.h> 83 80 #include <linux/types.h> 81 + #include <linux/acpi.h> 84 82 85 - #define IBFT_ISCSI_VERSION "0.4.9" 86 - #define IBFT_ISCSI_DATE "2008-Mar-14" 83 + #define IBFT_ISCSI_VERSION "0.5.0" 84 + #define IBFT_ISCSI_DATE "2010-Feb-25" 87 85 88 86 MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and \ 89 87 Konrad Rzeszutek <ketuzsezr@darnok.org>"); ··· 242 238 */ 243 239 244 240 struct ibft_kobject { 245 - struct ibft_table_header *header; 241 + struct acpi_table_ibft *header; 246 242 union { 247 243 struct ibft_initiator *initiator; 248 244 struct ibft_nic *nic; ··· 540 536 u8 *pos; 541 537 u8 csum = 0; 542 538 543 - len = ibft_addr->length; 539 + len = ibft_addr->header.length; 544 540 545 541 /* Sanity checking of iBFT. */ 546 - if (ibft_addr->revision != 1) { 542 + if (ibft_addr->header.revision != 1) { 547 543 printk(KERN_ERR "iBFT module supports only revision 1, " \ 548 - "while this is %d.\n", ibft_addr->revision); 544 + "while this is %d.\n", 545 + ibft_addr->header.revision); 549 546 return -ENOENT; 550 547 } 551 548 for (pos = (u8 *)ibft_addr; pos < (u8 *)ibft_addr + len; pos++) ··· 563 558 /* 564 559 * Helper function for ibft_register_kobjects. 565 560 */ 566 - static int __init ibft_create_kobject(struct ibft_table_header *header, 561 + static int __init ibft_create_kobject(struct acpi_table_ibft *header, 567 562 struct ibft_hdr *hdr, 568 563 struct list_head *list) 569 564 { ··· 601 596 default: 602 597 printk(KERN_ERR "iBFT has unknown structure type (%d). " \ 603 598 "Report this bug to %.6s!\n", hdr->id, 604 - header->oem_id); 599 + header->header.oem_id); 605 600 rc = 1; 606 601 break; 607 602 } ··· 654 649 * found add them on the passed-in list. We do not support the other 655 650 * fields at this point, so they are skipped. 656 651 */ 657 - static int __init ibft_register_kobjects(struct ibft_table_header *header, 652 + static int __init ibft_register_kobjects(struct acpi_table_ibft *header, 658 653 struct list_head *list) 659 654 { 660 655 struct ibft_control *control = NULL; ··· 665 660 666 661 control = (void *)header + sizeof(*header); 667 662 end = (void *)control + control->hdr.length; 668 - eot_offset = (void *)header + header->length - (void *)control; 663 + eot_offset = (void *)header + header->header.length - (void *)control; 669 664 rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control, 670 665 sizeof(*control)); 671 666 ··· 677 672 } 678 673 for (ptr = &control->initiator_off; ptr < end; ptr += sizeof(u16)) { 679 674 offset = *(u16 *)ptr; 680 - if (offset && offset < header->length && offset < eot_offset) { 675 + if (offset && offset < header->header.length && 676 + offset < eot_offset) { 681 677 rc = ibft_create_kobject(header, 682 678 (void *)header + offset, 683 679 list);
+30 -5
drivers/firmware/iscsi_ibft_find.c
··· 1 1 /* 2 - * Copyright 2007 Red Hat, Inc. 2 + * Copyright 2007-2010 Red Hat, Inc. 3 3 * by Peter Jones <pjones@redhat.com> 4 4 * Copyright 2007 IBM, Inc. 5 5 * by Konrad Rzeszutek <konradr@linux.vnet.ibm.com> ··· 22 22 #include <linux/blkdev.h> 23 23 #include <linux/ctype.h> 24 24 #include <linux/device.h> 25 + #include <linux/efi.h> 25 26 #include <linux/err.h> 26 27 #include <linux/init.h> 27 28 #include <linux/limits.h> ··· 31 30 #include <linux/stat.h> 32 31 #include <linux/string.h> 33 32 #include <linux/types.h> 33 + #include <linux/acpi.h> 34 + #include <linux/iscsi_ibft.h> 34 35 35 36 #include <asm/mmzone.h> 36 37 37 38 /* 38 39 * Physical location of iSCSI Boot Format Table. 39 40 */ 40 - struct ibft_table_header *ibft_addr; 41 + struct acpi_table_ibft *ibft_addr; 41 42 EXPORT_SYMBOL_GPL(ibft_addr); 42 43 43 44 #define IBFT_SIGN "iBFT" ··· 49 46 #define VGA_MEM 0xA0000 /* VGA buffer */ 50 47 #define VGA_SIZE 0x20000 /* 128kB */ 51 48 49 + #ifdef CONFIG_ACPI 50 + static int __init acpi_find_ibft(struct acpi_table_header *header) 51 + { 52 + ibft_addr = (struct acpi_table_ibft *)header; 53 + return 0; 54 + } 55 + #endif /* CONFIG_ACPI */ 52 56 53 57 /* 54 58 * Routine used to find the iSCSI Boot Format Table. The logical ··· 68 58 void *virt; 69 59 70 60 ibft_addr = NULL; 61 + 62 + /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will 63 + * only use ACPI for this */ 64 + if (efi_enabled) 65 + return 0; 71 66 72 67 for (pos = IBFT_START; pos < IBFT_END; pos += 16) { 73 68 /* The table can't be inside the VGA BIOS reserved space, ··· 87 72 /* if the length of the table extends past 1M, 88 73 * the table cannot be valid. */ 89 74 if (pos + len <= (IBFT_END-1)) { 90 - ibft_addr = (struct ibft_table_header *)virt; 75 + ibft_addr = (struct acpi_table_ibft *)virt; 91 76 break; 92 77 } 93 78 } 94 79 } 80 + #ifdef CONFIG_ACPI 81 + /* 82 + * One spec says "IBFT", the other says "iBFT". We have to check 83 + * for both. 84 + */ 85 + if (!ibft_addr) 86 + acpi_table_parse(ACPI_SIG_IBFT, acpi_find_ibft); 87 + if (!ibft_addr) 88 + acpi_table_parse("iBFT", acpi_find_ibft); 89 + #endif /* CONFIG_ACPI */ 95 90 if (ibft_addr) { 96 - *sizep = PAGE_ALIGN(len); 97 - return pos; 91 + *sizep = PAGE_ALIGN(ibft_addr->header.length); 92 + return (u64)isa_virt_to_bus(ibft_addr); 98 93 } 99 94 100 95 *sizep = 0;
+2 -10
include/linux/iscsi_ibft.h
··· 21 21 #ifndef ISCSI_IBFT_H 22 22 #define ISCSI_IBFT_H 23 23 24 - struct ibft_table_header { 25 - char signature[4]; 26 - u32 length; 27 - u8 revision; 28 - u8 checksum; 29 - char oem_id[6]; 30 - char oem_table_id[8]; 31 - char reserved[24]; 32 - } __attribute__((__packed__)); 24 + #include <acpi/acpi.h> 33 25 34 26 /* 35 27 * Logical location of iSCSI Boot Format Table. 36 28 * If the value is NULL there is no iBFT on the machine. 37 29 */ 38 - extern struct ibft_table_header *ibft_addr; 30 + extern struct acpi_table_ibft *ibft_addr; 39 31 40 32 /* 41 33 * Routine used to find and reserve the iSCSI Boot Format Table. The