aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2011-02-23 00:02:24 -0800
committerDan Williams <dan.j.williams@intel.com>2011-07-03 03:55:30 -0700
commit8db37aabaceb3dcd18754c1e782d4474e4052c81 (patch)
treedb23bf522bd632dd5017adf2c4dbe4b38864d823
parentd044af17aacd03a1f4fced1af4b7570d205c8fd9 (diff)
isci: Adding EFI variable skeletal support
Adding EFI variable retrieving for OEM parameters. Still need GUID and variable name. Also updated the data struct for oem parameters and hex file for firmware Signed-off-by: Dave Jiang <dave.jiang@intel.com> [fix CONFIG_EFI=n compile error] Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/scsi/isci/init.c7
-rw-r--r--drivers/scsi/isci/probe_roms.c64
-rw-r--r--drivers/scsi/isci/probe_roms.h2
3 files changed, 68 insertions, 5 deletions
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index 65519321e1c..13105294fbe 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -474,10 +474,9 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic
return -ENOMEM;
pci_set_drvdata(pdev, pci_info);
- if (efi_enabled) {
- /* do EFI parsing here */
- orom = NULL;
- } else
+ if (efi_enabled)
+ orom = isci_get_efi_var(pdev);
+ else
orom = isci_request_oprom(pdev);
if (!orom) {
diff --git a/drivers/scsi/isci/probe_roms.c b/drivers/scsi/isci/probe_roms.c
index 0b90e7c546c..927feaddc04 100644
--- a/drivers/scsi/isci/probe_roms.c
+++ b/drivers/scsi/isci/probe_roms.c
@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/firmware.h>
#include <linux/uaccess.h>
+#include <linux/efi.h>
#include <asm/probe_roms.h>
#include "isci.h"
@@ -36,6 +37,15 @@
#include "sci_environment.h"
#include "probe_roms.h"
+struct efi_variable {
+ efi_char16_t VariableName[1024/sizeof(efi_char16_t)];
+ efi_guid_t VendorGuid;
+ unsigned long DataSize;
+ __u8 Data[1024];
+ efi_status_t Status;
+ __u32 Attributes;
+} __attribute__((packed));
+
struct isci_orom *isci_request_oprom(struct pci_dev *pdev)
{
void __iomem *oprom = pci_map_biosrom(pdev);
@@ -131,3 +141,57 @@ struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmw
return orom;
}
+
+static struct efi *get_efi(void)
+{
+ #ifdef CONFIG_EFI
+ return &efi;
+ #else
+ return NULL;
+ #endif
+}
+
+struct isci_orom *isci_get_efi_var(struct pci_dev *pdev)
+{
+ struct efi_variable *evar;
+ efi_status_t status;
+ struct isci_orom *orom = NULL;
+
+ evar = devm_kzalloc(&pdev->dev,
+ sizeof(struct efi_variable),
+ GFP_KERNEL);
+ if (!evar) {
+ dev_warn(&pdev->dev,
+ "Unable to allocate memory for EFI var\n");
+ return NULL;
+ }
+
+ evar->DataSize = 1024;
+ evar->VendorGuid = ISCI_EFI_VENDOR_GUID;
+ evar->Attributes = ISCI_EFI_ATTRIBUTES;
+
+ if (get_efi())
+ status = get_efi()->get_variable(evar->VariableName,
+ &evar->VendorGuid,
+ &evar->Attributes,
+ &evar->DataSize,
+ evar->Data);
+ else
+ status = EFI_NOT_FOUND;
+
+ if (status == EFI_SUCCESS)
+ orom = (struct isci_orom *)evar->Data;
+ else
+ dev_warn(&pdev->dev,
+ "Unable to obtain EFI variable for OEM parms\n");
+
+ if (orom && memcmp(orom->hdr.signature, ISCI_ROM_SIG,
+ strlen(ISCI_ROM_SIG)) != 0)
+ dev_warn(&pdev->dev,
+ "Verifying OROM signature failed\n");
+
+ if (!orom)
+ devm_kfree(&pdev->dev, evar);
+
+ return orom;
+}
diff --git a/drivers/scsi/isci/probe_roms.h b/drivers/scsi/isci/probe_roms.h
index 76651c01895..96d8b921245 100644
--- a/drivers/scsi/isci/probe_roms.h
+++ b/drivers/scsi/isci/probe_roms.h
@@ -69,7 +69,7 @@ enum sci_status isci_parse_oem_parameters(
struct isci_orom *orom,
int scu_index);
struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw);
-int isci_get_efi_var(struct pci_dev *pdev);
+struct isci_orom *isci_get_efi_var(struct pci_dev *pdev);
#else
#define SCI_MAX_PORTS 4
#define SCI_MAX_PHYS 4