aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorPeter Jones <pjones@redhat.com>2010-02-25 15:37:17 -0500
committerKonrad Rzeszutek Wilk <konrad@kernel.org>2010-05-11 13:02:23 -0400
commit4e639fdf0d0d745648aa62228ab8a0d9c03a563f (patch)
treec6cb611ffc6f3e17e10ca3f39ac00f0e39b1ee4b /drivers/firmware
parent94b849aaf6e22ab7bf54b0d0377a882d4892396d (diff)
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>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/iscsi_ibft.c30
-rw-r--r--drivers/firmware/iscsi_ibft_find.c35
2 files changed, 48 insertions, 17 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
85MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and \ 89MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and \
86Konrad Rzeszutek <ketuzsezr@darnok.org>"); 90Konrad Rzeszutek <ketuzsezr@darnok.org>");
@@ -238,7 +242,7 @@ static const char *ibft_initiator_properties[] =
238 */ 242 */
239 243
240struct ibft_kobject { 244struct 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 */
561static int __init ibft_create_kobject(struct ibft_table_header *header, 566static 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 */
652static int __init ibft_register_kobjects(struct ibft_table_header *header, 657static 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 */
39struct ibft_table_header *ibft_addr; 42struct acpi_table_ibft *ibft_addr;
40EXPORT_SYMBOL_GPL(ibft_addr); 43EXPORT_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
53static 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;