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