aboutsummaryrefslogtreecommitdiff
path: root/drivers/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/edd.c2
-rw-r--r--drivers/firmware/efivars.c11
-rw-r--r--drivers/firmware/pcdp.c43
-rw-r--r--drivers/firmware/pcdp.h37
4 files changed, 75 insertions, 18 deletions
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index 33b669e6f97..6996476669f 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -115,7 +115,7 @@ edd_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
{
struct edd_device *dev = to_edd_device(kobj);
struct edd_attribute *edd_attr = to_edd_attr(attr);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (edd_attr->show)
ret = edd_attr->show(dev, buf);
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 0287ff65963..33b17c6a46f 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -352,7 +352,7 @@ static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr,
{
struct efivar_entry *var = to_efivar_entry(kobj);
struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -368,7 +368,7 @@ static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr,
{
struct efivar_entry *var = to_efivar_entry(kobj);
struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
- ssize_t ret = 0;
+ ssize_t ret = -EIO;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -618,8 +618,8 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
new_efivar = kmalloc(sizeof(struct efivar_entry), GFP_KERNEL);
if (!short_name || !new_efivar) {
- if (short_name) kfree(short_name);
- if (new_efivar) kfree(new_efivar);
+ kfree(short_name);
+ kfree(new_efivar);
return 1;
}
memset(short_name, 0, short_name_size+1);
@@ -644,7 +644,8 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
kobj_set_kset_s(new_efivar, vars_subsys);
kobject_register(&new_efivar->kobj);
- kfree(short_name); short_name = NULL;
+ kfree(short_name);
+ short_name = NULL;
spin_lock(&efivars_lock);
list_add(&new_efivar->list, &efivar_list);
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c
index df1b721154d..ae1fb45dbb4 100644
--- a/drivers/firmware/pcdp.c
+++ b/drivers/firmware/pcdp.c
@@ -16,6 +16,7 @@
#include <linux/console.h>
#include <linux/efi.h>
#include <linux/serial.h>
+#include <asm/vga.h>
#include "pcdp.h"
static int __init
@@ -23,12 +24,23 @@ setup_serial_console(struct pcdp_uart *uart)
{
#ifdef CONFIG_SERIAL_8250_CONSOLE
int mmio;
- static char options[64];
+ static char options[64], *p = options;
+ char parity;
mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY);
- snprintf(options, sizeof(options), "console=uart,%s,0x%lx,%lun%d",
- mmio ? "mmio" : "io", uart->addr.address, uart->baud,
- uart->bits ? uart->bits : 8);
+ p += sprintf(p, "console=uart,%s,0x%lx",
+ mmio ? "mmio" : "io", uart->addr.address);
+ if (uart->baud) {
+ p += sprintf(p, ",%lu", uart->baud);
+ if (uart->bits) {
+ switch (uart->parity) {
+ case 0x2: parity = 'e'; break;
+ case 0x3: parity = 'o'; break;
+ default: parity = 'n';
+ }
+ p += sprintf(p, "%c%d", parity, uart->bits);
+ }
+ }
return early_serial_console_init(options);
#else
@@ -37,10 +49,27 @@ setup_serial_console(struct pcdp_uart *uart)
}
static int __init
-setup_vga_console(struct pcdp_vga *vga)
+setup_vga_console(struct pcdp_device *dev)
{
#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
- if (efi_mem_type(0xA0000) == EFI_CONVENTIONAL_MEMORY) {
+ u8 *if_ptr;
+
+ if_ptr = ((u8 *)dev + sizeof(struct pcdp_device));
+ if (if_ptr[0] == PCDP_IF_PCI) {
+ struct pcdp_if_pci if_pci;
+
+ /* struct copy since ifptr might not be correctly aligned */
+
+ memcpy(&if_pci, if_ptr, sizeof(if_pci));
+
+ if (if_pci.trans & PCDP_PCI_TRANS_IOPORT)
+ vga_console_iobase = if_pci.ioport_tra;
+
+ if (if_pci.trans & PCDP_PCI_TRANS_MMIO)
+ vga_console_membase = if_pci.mmio_tra;
+ }
+
+ if (efi_mem_type(vga_console_membase + 0xA0000) == EFI_CONVENTIONAL_MEMORY) {
printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n");
return -ENODEV;
}
@@ -92,7 +121,7 @@ efi_setup_pcdp_console(char *cmdline)
dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) {
if (dev->flags & PCDP_PRIMARY_CONSOLE) {
if (dev->type == PCDP_CONSOLE_VGA) {
- return setup_vga_console((struct pcdp_vga *) dev);
+ return setup_vga_console(dev);
}
}
}
diff --git a/drivers/firmware/pcdp.h b/drivers/firmware/pcdp.h
index 863bb6f768c..ce910d68bd1 100644
--- a/drivers/firmware/pcdp.h
+++ b/drivers/firmware/pcdp.h
@@ -2,7 +2,7 @@
* Definitions for PCDP-defined console devices
*
* v1.0a: http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf
- * v2.0: http://www.dig64.org/specifications/DIG64_HCDPv20_042804.pdf
+ * v2.0: http://www.dig64.org/specifications/DIG64_PCDPv20.pdf
*
* (c) Copyright 2002, 2004 Hewlett-Packard Development Company, L.P.
* Khalid Aziz <khalid.aziz@hp.com>
@@ -52,11 +52,36 @@ struct pcdp_uart {
u32 clock_rate;
u8 pci_prog_intfc;
u8 flags;
-};
+ u16 conout_index;
+ u32 reserved;
+} __attribute__((packed));
+
+#define PCDP_IF_PCI 1
+
+/* pcdp_if_pci.trans */
+#define PCDP_PCI_TRANS_IOPORT 0x02
+#define PCDP_PCI_TRANS_MMIO 0x01
+
+struct pcdp_if_pci {
+ u8 interconnect;
+ u8 reserved;
+ u16 length;
+ u8 segment;
+ u8 bus;
+ u8 dev;
+ u8 fun;
+ u16 dev_id;
+ u16 vendor_id;
+ u32 acpi_interrupt;
+ u64 mmio_tra;
+ u64 ioport_tra;
+ u8 flags;
+ u8 trans;
+} __attribute__((packed));
struct pcdp_vga {
u8 count; /* address space descriptors */
-};
+} __attribute__((packed));
/* pcdp_device.flags */
#define PCDP_PRIMARY_CONSOLE 1
@@ -66,7 +91,9 @@ struct pcdp_device {
u8 flags;
u16 length;
u16 efi_index;
-};
+ /* next data is pcdp_if_pci or pcdp_if_acpi (not yet supported) */
+ /* next data is device specific type (currently only pcdp_vga) */
+} __attribute__((packed));
struct pcdp {
u8 signature[4];
@@ -81,4 +108,4 @@ struct pcdp {
u32 num_uarts;
struct pcdp_uart uart[0]; /* actual size is num_uarts */
/* remainder of table is pcdp_device structures */
-};
+} __attribute__((packed));