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>
This commit is contained in:
parent
94b849aaf6
commit
4e639fdf0d
3 changed files with 50 additions and 27 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2007 Red Hat, Inc.
|
* Copyright 2007-2010 Red Hat, Inc.
|
||||||
* by Peter Jones <pjones@redhat.com>
|
* by Peter Jones <pjones@redhat.com>
|
||||||
* Copyright 2008 IBM, Inc.
|
* Copyright 2008 IBM, Inc.
|
||||||
* by Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
|
* by Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
|
||||||
|
@ -19,6 +19,9 @@
|
||||||
*
|
*
|
||||||
* Changelog:
|
* Changelog:
|
||||||
*
|
*
|
||||||
|
* 06 Jan 2010 - Peter Jones <pjones@redhat.com>
|
||||||
|
* New changelog entries are in the git log from now on. Not here.
|
||||||
|
*
|
||||||
* 14 Mar 2008 - Konrad Rzeszutek <ketuzsezr@darnok.org>
|
* 14 Mar 2008 - Konrad Rzeszutek <ketuzsezr@darnok.org>
|
||||||
* Updated comments and copyrights. (v0.4.9)
|
* Updated comments and copyrights. (v0.4.9)
|
||||||
*
|
*
|
||||||
|
@ -78,9 +81,10 @@
|
||||||
#include <linux/stat.h>
|
#include <linux/stat.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/acpi.h>
|
||||||
|
|
||||||
#define IBFT_ISCSI_VERSION "0.4.9"
|
#define IBFT_ISCSI_VERSION "0.5.0"
|
||||||
#define IBFT_ISCSI_DATE "2008-Mar-14"
|
#define IBFT_ISCSI_DATE "2010-Feb-25"
|
||||||
|
|
||||||
MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and \
|
MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and \
|
||||||
Konrad Rzeszutek <ketuzsezr@darnok.org>");
|
Konrad Rzeszutek <ketuzsezr@darnok.org>");
|
||||||
|
@ -238,7 +242,7 @@ static const char *ibft_initiator_properties[] =
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct ibft_kobject {
|
struct ibft_kobject {
|
||||||
struct ibft_table_header *header;
|
struct acpi_table_ibft *header;
|
||||||
union {
|
union {
|
||||||
struct ibft_initiator *initiator;
|
struct ibft_initiator *initiator;
|
||||||
struct ibft_nic *nic;
|
struct ibft_nic *nic;
|
||||||
|
@ -536,12 +540,13 @@ static int __init ibft_check_device(void)
|
||||||
u8 *pos;
|
u8 *pos;
|
||||||
u8 csum = 0;
|
u8 csum = 0;
|
||||||
|
|
||||||
len = ibft_addr->length;
|
len = ibft_addr->header.length;
|
||||||
|
|
||||||
/* Sanity checking of iBFT. */
|
/* Sanity checking of iBFT. */
|
||||||
if (ibft_addr->revision != 1) {
|
if (ibft_addr->header.revision != 1) {
|
||||||
printk(KERN_ERR "iBFT module supports only revision 1, " \
|
printk(KERN_ERR "iBFT module supports only revision 1, " \
|
||||||
"while this is %d.\n", ibft_addr->revision);
|
"while this is %d.\n",
|
||||||
|
ibft_addr->header.revision);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
for (pos = (u8 *)ibft_addr; pos < (u8 *)ibft_addr + len; pos++)
|
for (pos = (u8 *)ibft_addr; pos < (u8 *)ibft_addr + len; pos++)
|
||||||
|
@ -558,7 +563,7 @@ static int __init ibft_check_device(void)
|
||||||
/*
|
/*
|
||||||
* Helper function for ibft_register_kobjects.
|
* Helper function for ibft_register_kobjects.
|
||||||
*/
|
*/
|
||||||
static int __init ibft_create_kobject(struct ibft_table_header *header,
|
static int __init ibft_create_kobject(struct acpi_table_ibft *header,
|
||||||
struct ibft_hdr *hdr,
|
struct ibft_hdr *hdr,
|
||||||
struct list_head *list)
|
struct list_head *list)
|
||||||
{
|
{
|
||||||
|
@ -596,7 +601,7 @@ static int __init ibft_create_kobject(struct ibft_table_header *header,
|
||||||
default:
|
default:
|
||||||
printk(KERN_ERR "iBFT has unknown structure type (%d). " \
|
printk(KERN_ERR "iBFT has unknown structure type (%d). " \
|
||||||
"Report this bug to %.6s!\n", hdr->id,
|
"Report this bug to %.6s!\n", hdr->id,
|
||||||
header->oem_id);
|
header->header.oem_id);
|
||||||
rc = 1;
|
rc = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -649,7 +654,7 @@ out_invalid_struct:
|
||||||
* found add them on the passed-in list. We do not support the other
|
* found add them on the passed-in list. We do not support the other
|
||||||
* fields at this point, so they are skipped.
|
* fields at this point, so they are skipped.
|
||||||
*/
|
*/
|
||||||
static int __init ibft_register_kobjects(struct ibft_table_header *header,
|
static int __init ibft_register_kobjects(struct acpi_table_ibft *header,
|
||||||
struct list_head *list)
|
struct list_head *list)
|
||||||
{
|
{
|
||||||
struct ibft_control *control = NULL;
|
struct ibft_control *control = NULL;
|
||||||
|
@ -660,7 +665,7 @@ static int __init ibft_register_kobjects(struct ibft_table_header *header,
|
||||||
|
|
||||||
control = (void *)header + sizeof(*header);
|
control = (void *)header + sizeof(*header);
|
||||||
end = (void *)control + control->hdr.length;
|
end = (void *)control + control->hdr.length;
|
||||||
eot_offset = (void *)header + header->length - (void *)control;
|
eot_offset = (void *)header + header->header.length - (void *)control;
|
||||||
rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control,
|
rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control,
|
||||||
sizeof(*control));
|
sizeof(*control));
|
||||||
|
|
||||||
|
@ -672,7 +677,8 @@ static int __init ibft_register_kobjects(struct ibft_table_header *header,
|
||||||
}
|
}
|
||||||
for (ptr = &control->initiator_off; ptr < end; ptr += sizeof(u16)) {
|
for (ptr = &control->initiator_off; ptr < end; ptr += sizeof(u16)) {
|
||||||
offset = *(u16 *)ptr;
|
offset = *(u16 *)ptr;
|
||||||
if (offset && offset < header->length && offset < eot_offset) {
|
if (offset && offset < header->header.length &&
|
||||||
|
offset < eot_offset) {
|
||||||
rc = ibft_create_kobject(header,
|
rc = ibft_create_kobject(header,
|
||||||
(void *)header + offset,
|
(void *)header + offset,
|
||||||
list);
|
list);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2007 Red Hat, Inc.
|
* Copyright 2007-2010 Red Hat, Inc.
|
||||||
* by Peter Jones <pjones@redhat.com>
|
* by Peter Jones <pjones@redhat.com>
|
||||||
* Copyright 2007 IBM, Inc.
|
* Copyright 2007 IBM, Inc.
|
||||||
* by Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
|
* by Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/efi.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
|
@ -30,13 +31,15 @@
|
||||||
#include <linux/stat.h>
|
#include <linux/stat.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/acpi.h>
|
||||||
|
#include <linux/iscsi_ibft.h>
|
||||||
|
|
||||||
#include <asm/mmzone.h>
|
#include <asm/mmzone.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Physical location of iSCSI Boot Format Table.
|
* Physical location of iSCSI Boot Format Table.
|
||||||
*/
|
*/
|
||||||
struct ibft_table_header *ibft_addr;
|
struct acpi_table_ibft *ibft_addr;
|
||||||
EXPORT_SYMBOL_GPL(ibft_addr);
|
EXPORT_SYMBOL_GPL(ibft_addr);
|
||||||
|
|
||||||
#define IBFT_SIGN "iBFT"
|
#define IBFT_SIGN "iBFT"
|
||||||
|
@ -46,6 +49,13 @@ EXPORT_SYMBOL_GPL(ibft_addr);
|
||||||
#define VGA_MEM 0xA0000 /* VGA buffer */
|
#define VGA_MEM 0xA0000 /* VGA buffer */
|
||||||
#define VGA_SIZE 0x20000 /* 128kB */
|
#define VGA_SIZE 0x20000 /* 128kB */
|
||||||
|
|
||||||
|
#ifdef CONFIG_ACPI
|
||||||
|
static int __init acpi_find_ibft(struct acpi_table_header *header)
|
||||||
|
{
|
||||||
|
ibft_addr = (struct acpi_table_ibft *)header;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_ACPI */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routine used to find the iSCSI Boot Format Table. The logical
|
* Routine used to find the iSCSI Boot Format Table. The logical
|
||||||
|
@ -59,6 +69,11 @@ unsigned long __init find_ibft_region(unsigned long *sizep)
|
||||||
|
|
||||||
ibft_addr = NULL;
|
ibft_addr = NULL;
|
||||||
|
|
||||||
|
/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
|
||||||
|
* only use ACPI for this */
|
||||||
|
if (efi_enabled)
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
|
for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
|
||||||
/* The table can't be inside the VGA BIOS reserved space,
|
/* The table can't be inside the VGA BIOS reserved space,
|
||||||
* so skip that area */
|
* so skip that area */
|
||||||
|
@ -72,14 +87,24 @@ unsigned long __init find_ibft_region(unsigned long *sizep)
|
||||||
/* if the length of the table extends past 1M,
|
/* if the length of the table extends past 1M,
|
||||||
* the table cannot be valid. */
|
* the table cannot be valid. */
|
||||||
if (pos + len <= (IBFT_END-1)) {
|
if (pos + len <= (IBFT_END-1)) {
|
||||||
ibft_addr = (struct ibft_table_header *)virt;
|
ibft_addr = (struct acpi_table_ibft *)virt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_ACPI
|
||||||
|
/*
|
||||||
|
* One spec says "IBFT", the other says "iBFT". We have to check
|
||||||
|
* for both.
|
||||||
|
*/
|
||||||
|
if (!ibft_addr)
|
||||||
|
acpi_table_parse(ACPI_SIG_IBFT, acpi_find_ibft);
|
||||||
|
if (!ibft_addr)
|
||||||
|
acpi_table_parse("iBFT", acpi_find_ibft);
|
||||||
|
#endif /* CONFIG_ACPI */
|
||||||
if (ibft_addr) {
|
if (ibft_addr) {
|
||||||
*sizep = PAGE_ALIGN(len);
|
*sizep = PAGE_ALIGN(ibft_addr->header.length);
|
||||||
return pos;
|
return (u64)isa_virt_to_bus(ibft_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
*sizep = 0;
|
*sizep = 0;
|
||||||
|
|
|
@ -21,21 +21,13 @@
|
||||||
#ifndef ISCSI_IBFT_H
|
#ifndef ISCSI_IBFT_H
|
||||||
#define ISCSI_IBFT_H
|
#define ISCSI_IBFT_H
|
||||||
|
|
||||||
struct ibft_table_header {
|
#include <acpi/acpi.h>
|
||||||
char signature[4];
|
|
||||||
u32 length;
|
|
||||||
u8 revision;
|
|
||||||
u8 checksum;
|
|
||||||
char oem_id[6];
|
|
||||||
char oem_table_id[8];
|
|
||||||
char reserved[24];
|
|
||||||
} __attribute__((__packed__));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Logical location of iSCSI Boot Format Table.
|
* Logical location of iSCSI Boot Format Table.
|
||||||
* If the value is NULL there is no iBFT on the machine.
|
* If the value is NULL there is no iBFT on the machine.
|
||||||
*/
|
*/
|
||||||
extern struct ibft_table_header *ibft_addr;
|
extern struct acpi_table_ibft *ibft_addr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routine used to find and reserve the iSCSI Boot Format Table. The
|
* Routine used to find and reserve the iSCSI Boot Format Table. The
|
||||||
|
|
Loading…
Reference in a new issue