* ACPI patch queue for 2.6.27
@ 2008-06-20 7:43 Len Brown
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
2008-06-23 0:24 ` ACPI patch queue for 2.6.27 Jonathan Woithe
0 siblings, 2 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi
Here is the current ACPI queue for 2.6.27
fujitsu-laptop and compal-laptop are new.
I'll be impressed (and delighted) if Bjorn's PNP-v3 series
requires no modification before then.
We know it has a few checkpatch issues...
We cherry-picked the important patches out of the ACPICA
series into 2.6.26 already, so what remains here is
less exciting.
Per notes on the list, I expect some changes to
the idle= param patches, but here is what we have now.
I'd also like to see Rui's enhancement to /sys/firmware/acpi/interrupts
make 2.6.27 -- it is excluded here due to a conflict
with the ACPICA branch.
thanks,
-Len
^ permalink raw reply [flat|nested] 98+ messages in thread
* [PATCH 01/70] fix a deadlock issue when poking "eject" file
2008-06-20 7:43 ACPI patch queue for 2.6.27 Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 02/70] force offline the processor during hot-removal Len Brown
` (67 more replies)
2008-06-23 0:24 ` ACPI patch queue for 2.6.27 Jonathan Woithe
1 sibling, 68 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Zhang Rui, Len Brown
From: Zhang Rui <rui.zhang@intel.com>
"/sys/devices/LNXSYSTM:00/.../eject" is used to evaluate _EJx method
and eject a device in user space.
But system hangs when poking the "eject" file because that
the device hot-removal code invoke the driver .remove method which will
try to remove the "eject" file as a result.
Queues the hot-removal function for deferred execution in this patch.
http://bugzilla.kernel.org/show_bug.cgi?id=9772
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/scan.c | 56 +++++++++++++++++++++++++++++---------------------
1 files changed, 32 insertions(+), 24 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e6ce262..00ba4af 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -6,6 +6,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/acpi.h>
+#include <asm/signal.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acinterp.h> /* for acpi_ex_eisa_id_to_string() */
@@ -92,17 +93,37 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha
}
static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
-static int acpi_eject_operation(acpi_handle handle, int lockable)
+static int acpi_bus_hot_remove_device(void *context)
{
+ struct acpi_device *device;
+ acpi_handle handle = context;
struct acpi_object_list arg_list;
union acpi_object arg;
acpi_status status = AE_OK;
- /*
- * TBD: evaluate _PS3?
- */
+ if (acpi_bus_get_device(handle, &device))
+ return 0;
- if (lockable) {
+ if (!device)
+ return 0;
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Hot-removing device %s...\n", device->dev.bus_id));
+
+
+ if (acpi_bus_trim(device, 1)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Removing device failed\n"));
+ return -1;
+ }
+
+ /* power off device */
+ status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Power-off device failed\n"));
+
+ if (device->flags.lockable) {
arg_list.count = 1;
arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER;
@@ -118,24 +139,19 @@ static int acpi_eject_operation(acpi_handle handle, int lockable)
/*
* TBD: _EJD support.
*/
-
status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
- if (ACPI_FAILURE(status)) {
- return (-ENODEV);
- }
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
- return (0);
+ return 0;
}
static ssize_t
acpi_eject_store(struct device *d, struct device_attribute *attr,
const char *buf, size_t count)
{
- int result;
int ret = count;
- int islockable;
acpi_status status;
- acpi_handle handle;
acpi_object_type type = 0;
struct acpi_device *acpi_device = to_acpi_device(d);
@@ -154,17 +170,9 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
goto err;
}
- islockable = acpi_device->flags.lockable;
- handle = acpi_device->handle;
-
- result = acpi_bus_trim(acpi_device, 1);
-
- if (!result)
- result = acpi_eject_operation(handle, islockable);
-
- if (result) {
- ret = -EBUSY;
- }
+ /* remove the device in another thread to fix the deadlock issue */
+ ret = kernel_thread(acpi_bus_hot_remove_device,
+ acpi_device->handle, SIGCHLD);
err:
return ret;
}
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 02/70] force offline the processor during hot-removal
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 03/70] create sysfs link from acpi device to sysdev for cpu Len Brown
` (66 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Zhang Rui, Len Brown
From: Zhang Rui <rui.zhang@intel.com>
The ACPI device node for the cpu has already been unregistered
when acpi_processor_handle_eject is called.
Thus we should offline the cpu and continue, rather than a failure here.
http://bugzilla.kernel.org/show_bug.cgi?id=9772
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/processor_core.c | 6 +++---
kernel/cpu.c | 1 +
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index a825b43..3f90965 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -1016,9 +1016,9 @@ static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
static int acpi_processor_handle_eject(struct acpi_processor *pr)
{
- if (cpu_online(pr->id)) {
- return (-EINVAL);
- }
+ if (cpu_online(pr->id))
+ cpu_down(pr->id);
+
arch_unregister_cpu(pr->id);
acpi_unmap_lsapic(pr->id);
return (0);
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 2011ad8..380bce4 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -287,6 +287,7 @@ int cpu_down(unsigned int cpu)
cpu_maps_update_done();
return err;
}
+EXPORT_SYMBOL(cpu_down);
#endif /*CONFIG_HOTPLUG_CPU*/
/* Requires cpu_add_remove_lock to be held */
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 03/70] create sysfs link from acpi device to sysdev for cpu
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
2008-06-20 7:43 ` [PATCH 02/70] force offline the processor during hot-removal Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras Len Brown
` (65 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Zhang Rui, Len Brown
From: Zhang Rui <rui.zhang@intel.com>
Sys I/F under acpi device node and sysdev device node are both
needed for cpu hot-removal. User space need this link so that
they know they are poking the sys I/F for the same cpu.
http://bugzilla.kernel.org/show_bug.cgi?id=9772
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/processor_core.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 3f90965..e8f82d6 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -622,7 +622,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
int result = 0;
acpi_status status = AE_OK;
struct acpi_processor *pr;
-
+ struct sys_device *sysdev;
pr = acpi_driver_data(device);
@@ -653,6 +653,10 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
if (result)
goto end;
+ sysdev = get_cpu_sysdev(pr->id);
+ if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev"))
+ return -EFAULT;
+
status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
acpi_processor_notify, pr);
@@ -812,6 +816,8 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
acpi_processor_notify);
+ sysfs_remove_link(&device->dev.kobj, "sysdev");
+
acpi_processor_remove_fs(device);
if (pr->cdev) {
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
2008-06-20 7:43 ` [PATCH 02/70] force offline the processor during hot-removal Len Brown
2008-06-20 7:43 ` [PATCH 03/70] create sysfs link from acpi device to sysdev for cpu Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 10:13 ` Richard Purdie
2008-06-20 11:48 ` Matthew Garrett
2008-06-20 7:43 ` [PATCH 05/70] ACPI: change processors from array to per_cpu variable Len Brown
` (64 subsequent siblings)
67 siblings, 2 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi
Cc: Cezary Jackiewicz, Richard Purdie, Henrique de Moraes Holschuh,
Alexey Starikovskiy, Andrew Morton, Len Brown
From: Cezary Jackiewicz <cezary.jackiewicz@gmail.com>
This is driver for Compal Laptop: FL90/IFL90, based on MSI driver.
This driver exports a few files in /sys/devices/platform/compal-laptop/:
lcd_level - screen brightness: contains a single integer in the range 0..7 (rw)
wlan - wlan subsystem state: contains 0 or 1 (rw)
bluetooth - bluetooth subsystem state: contains 0 or 1 (rw)
raw - raw value taken from embedded controller register (ro)
In addition to these platform device attributes the driver registers itself
in the Linux backlight control subsystem and is available to userspace under
/sys/class/backlight/compal-laptop/.
Signed-off-by: Cezary Jackiewicz <cezary.jackiewicz@gmail.com>
Cc: Richard Purdie <rpurdie@rpsys.net>
Cc: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Len Brown <lenb@kernel.org>
Cc: Alexey Starikovskiy <aystarik@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
MAINTAINERS | 5 +
drivers/misc/Kconfig | 17 ++
drivers/misc/Makefile | 5 +-
drivers/misc/compal-laptop.c | 437 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 462 insertions(+), 2 deletions(-)
create mode 100644 drivers/misc/compal-laptop.c
diff --git a/MAINTAINERS b/MAINTAINERS
index cb71eb4..8c9a77c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1151,6 +1151,11 @@ M: scott@spiteful.org
L: pcihpd-discuss@lists.sourceforge.net
S: Supported
+COMPAL LAPTOP SUPPORT
+P: Cezary Jackiewicz
+M: cezary.jackiewicz@gmail.com
+S: Maintained
+
COMPUTONE INTELLIPORT MULTIPORT CARD
P: Michael H. Warfield
M: mhw@wittsend.com
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 636af28..9dd836e 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -219,6 +219,23 @@ config MSI_LAPTOP
If you have an MSI S270 laptop, say Y or M here.
+config COMPAL_LAPTOP
+ tristate "Compal Laptop Extras"
+ depends on X86
+ depends on ACPI_EC
+ depends on BACKLIGHT_CLASS_DEVICE
+ ---help---
+ This is a driver for laptops built by Compal:
+
+ Compal FL90/IFL90
+ Compal FL91/IFL91
+ Compal FL92/JFL92
+ Compal FT00/IFT00
+
+ It adds support for Bluetooth, WLAN and LCD brightness control.
+
+ If you have an Compal FL9x/IFL9x/FT00 laptop, say Y or M here.
+
config SONY_LAPTOP
tristate "Sony Laptop Extras"
depends on X86 && ACPI
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 1952875..a6dac6a 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -5,10 +5,11 @@ obj- := misc.o # Dummy rule to force built-in.o to be made
obj-$(CONFIG_IBM_ASM) += ibmasm/
obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
-obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
-obj-$(CONFIG_ACER_WMI) += acer-wmi.o
obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
+obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
+obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
+obj-$(CONFIG_ACER_WMI) += acer-wmi.o
obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
diff --git a/drivers/misc/compal-laptop.c b/drivers/misc/compal-laptop.c
new file mode 100644
index 0000000..b764c55
--- /dev/null
+++ b/drivers/misc/compal-laptop.c
@@ -0,0 +1,437 @@
+/*-*-linux-c-*-*/
+
+/*
+ Copyright (C) 2008 Cezary Jackiewicz <cezary.jackiewicz (at) gmail.com>
+
+ based on MSI driver
+
+ Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+ */
+
+/*
+ * comapl-laptop.c - Compal laptop support.
+ *
+ * This driver exports a few files in /sys/devices/platform/compal-laptop/:
+ *
+ * lcd_level - Screen brightness: contains a single integer in the
+ * range 0..7. (rw)
+ *
+ * wlan - wlan subsystem state: contains 0 or 1 (rw)
+ *
+ * bluetooth - Bluetooth subsystem state: contains 0 or 1 (rw)
+ *
+ * raw - raw value taken from embedded controller register (ro)
+ *
+ * In addition to these platform device attributes the driver
+ * registers itself in the Linux backlight control subsystem and is
+ * available to userspace under /sys/class/backlight/compal-laptop/.
+ *
+ * This driver might work on other laptops produced by Compal. If you
+ * want to try it you can pass force=1 as argument to the module which
+ * will force it to load even when the DMI data doesn't identify the
+ * laptop as IFL90.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <linux/autoconf.h>
+
+#define COMPAL_DRIVER_VERSION "0.2.5"
+
+#define COMPAL_LCD_LEVEL_MAX 8
+
+#define COMPAL_EC_COMMAND_WIRELESS 0xBB
+#define COMPAL_EC_COMMAND_LCD_LEVEL 0xB9
+
+#define KILLSWITCH_MASK 0x10
+#define WLAN_MASK 0x01
+#define BT_MASK 0x02
+
+static int force;
+module_param(force, bool, 0);
+MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
+
+/* Hardware access */
+
+static int set_lcd_level(int level)
+{
+ if (level < 0 || level >= COMPAL_LCD_LEVEL_MAX)
+ return -EINVAL;
+
+ ec_write(COMPAL_EC_COMMAND_LCD_LEVEL, level);
+
+ return 0;
+}
+
+static int get_lcd_level(void)
+{
+ u8 result;
+
+ ec_read(COMPAL_EC_COMMAND_LCD_LEVEL, &result);
+
+ return (int) result;
+}
+
+static int set_wlan_state(int state)
+{
+ u8 result, value;
+
+ ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
+
+ if ((result & KILLSWITCH_MASK) == 0)
+ return -EINVAL;
+ else {
+ if (state)
+ value = (u8) (result | WLAN_MASK);
+ else
+ value = (u8) (result & ~WLAN_MASK);
+ ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
+ }
+
+ return 0;
+}
+
+static int set_bluetooth_state(int state)
+{
+ u8 result, value;
+
+ ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
+
+ if ((result & KILLSWITCH_MASK) == 0)
+ return -EINVAL;
+ else {
+ if (state)
+ value = (u8) (result | BT_MASK);
+ else
+ value = (u8) (result & ~BT_MASK);
+ ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
+ }
+
+ return 0;
+}
+
+static int get_wireless_state(int *wlan, int *bluetooth)
+{
+ u8 result;
+
+ ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
+
+ if (wlan) {
+ if ((result & KILLSWITCH_MASK) == 0)
+ *wlan = 0;
+ else
+ *wlan = result & WLAN_MASK;
+ }
+
+ if (bluetooth) {
+ if ((result & KILLSWITCH_MASK) == 0)
+ *bluetooth = 0;
+ else
+ *bluetooth = (result & BT_MASK) >> 1;
+ }
+
+ return 0;
+}
+
+/* Backlight device stuff */
+
+static int bl_get_brightness(struct backlight_device *b)
+{
+ return get_lcd_level();
+}
+
+
+static int bl_update_status(struct backlight_device *b)
+{
+ return set_lcd_level(b->props.brightness);
+}
+
+static struct backlight_ops compalbl_ops = {
+ .get_brightness = bl_get_brightness,
+ .update_status = bl_update_status,
+};
+
+static struct backlight_device *compalbl_device;
+
+/* Platform device */
+
+static ssize_t show_wlan(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret, enabled;
+
+ ret = get_wireless_state(&enabled, NULL);
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%i\n", enabled);
+}
+
+static ssize_t show_raw(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u8 result;
+
+ ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
+
+ return sprintf(buf, "%i\n", result);
+}
+
+static ssize_t show_bluetooth(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret, enabled;
+
+ ret = get_wireless_state(NULL, &enabled);
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%i\n", enabled);
+}
+
+static ssize_t show_lcd_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret;
+
+ ret = get_lcd_level();
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%i\n", ret);
+}
+
+static ssize_t store_lcd_level(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int level, ret;
+
+ if (sscanf(buf, "%i", &level) != 1 ||
+ (level < 0 || level >= COMPAL_LCD_LEVEL_MAX))
+ return -EINVAL;
+
+ ret = set_lcd_level(level);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static ssize_t store_wlan_state(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int state, ret;
+
+ if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1))
+ return -EINVAL;
+
+ ret = set_wlan_state(state);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static ssize_t store_bluetooth_state(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int state, ret;
+
+ if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1))
+ return -EINVAL;
+
+ ret = set_bluetooth_state(state);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
+static DEVICE_ATTR(bluetooth, 0644, show_bluetooth, store_bluetooth_state);
+static DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan_state);
+static DEVICE_ATTR(raw, 0444, show_raw, NULL);
+
+static struct attribute *compal_attributes[] = {
+ &dev_attr_lcd_level.attr,
+ &dev_attr_bluetooth.attr,
+ &dev_attr_wlan.attr,
+ &dev_attr_raw.attr,
+ NULL
+};
+
+static struct attribute_group compal_attribute_group = {
+ .attrs = compal_attributes
+};
+
+static struct platform_driver compal_driver = {
+ .driver = {
+ .name = "compal-laptop",
+ .owner = THIS_MODULE,
+ }
+};
+
+static struct platform_device *compal_device;
+
+/* Initialization */
+
+static int dmi_check_cb(const struct dmi_system_id *id)
+{
+ printk(KERN_INFO "compal-laptop: Identified laptop model '%s'.\n",
+ id->ident);
+
+ return 0;
+}
+
+static struct dmi_system_id __initdata compal_dmi_table[] = {
+ {
+ .ident = "FL90/IFL90",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "IFL90"),
+ DMI_MATCH(DMI_BOARD_VERSION, "IFT00"),
+ },
+ .callback = dmi_check_cb
+ },
+ {
+ .ident = "FL90/IFL90",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "IFL90"),
+ DMI_MATCH(DMI_BOARD_VERSION, "REFERENCE"),
+ },
+ .callback = dmi_check_cb
+ },
+ {
+ .ident = "FL91/IFL91",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "IFL91"),
+ DMI_MATCH(DMI_BOARD_VERSION, "IFT00"),
+ },
+ .callback = dmi_check_cb
+ },
+ {
+ .ident = "FL92/JFL92",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "JFL92"),
+ DMI_MATCH(DMI_BOARD_VERSION, "IFT00"),
+ },
+ .callback = dmi_check_cb
+ },
+ {
+ .ident = "FT00/IFT00",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "IFT00"),
+ DMI_MATCH(DMI_BOARD_VERSION, "IFT00"),
+ },
+ .callback = dmi_check_cb
+ },
+ { }
+};
+
+static int __init compal_init(void)
+{
+ int ret;
+
+ if (acpi_disabled)
+ return -ENODEV;
+
+ if (!force && !dmi_check_system(compal_dmi_table))
+ return -ENODEV;
+
+ /* Register backlight stuff */
+
+ compalbl_device = backlight_device_register("compal-laptop", NULL, NULL,
+ &compalbl_ops);
+ if (IS_ERR(compalbl_device))
+ return PTR_ERR(compalbl_device);
+
+ compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1;
+
+ ret = platform_driver_register(&compal_driver);
+ if (ret)
+ goto fail_backlight;
+
+ /* Register platform stuff */
+
+ compal_device = platform_device_alloc("compal-laptop", -1);
+ if (!compal_device) {
+ ret = -ENOMEM;
+ goto fail_platform_driver;
+ }
+
+ ret = platform_device_add(compal_device);
+ if (ret)
+ goto fail_platform_device1;
+
+ ret = sysfs_create_group(&compal_device->dev.kobj,
+ &compal_attribute_group);
+ if (ret)
+ goto fail_platform_device2;
+
+ printk(KERN_INFO "compal-laptop: driver "COMPAL_DRIVER_VERSION
+ " successfully loaded.\n");
+
+ return 0;
+
+fail_platform_device2:
+
+ platform_device_del(compal_device);
+
+fail_platform_device1:
+
+ platform_device_put(compal_device);
+
+fail_platform_driver:
+
+ platform_driver_unregister(&compal_driver);
+
+fail_backlight:
+
+ backlight_device_unregister(compalbl_device);
+
+ return ret;
+}
+
+static void __exit compal_cleanup(void)
+{
+
+ sysfs_remove_group(&compal_device->dev.kobj, &compal_attribute_group);
+ platform_device_unregister(compal_device);
+ platform_driver_unregister(&compal_driver);
+ backlight_device_unregister(compalbl_device);
+
+ printk(KERN_INFO "compal-laptop: driver unloaded.\n");
+}
+
+module_init(compal_init);
+module_exit(compal_cleanup);
+
+MODULE_AUTHOR("Cezary Jackiewicz");
+MODULE_DESCRIPTION("Compal Laptop Support");
+MODULE_VERSION(COMPAL_DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+
+MODULE_ALIAS("dmi:*:rnIFL90:rvrIFT00:*");
+MODULE_ALIAS("dmi:*:rnIFL90:rvrREFERENCE:*");
+MODULE_ALIAS("dmi:*:rnIFL91:rvrIFT00:*");
+MODULE_ALIAS("dmi:*:rnJFL92:rvrIFT00:*");
+MODULE_ALIAS("dmi:*:rnIFT00:rvrIFT00:*");
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 05/70] ACPI: change processors from array to per_cpu variable
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (2 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 06/70] Fujitsu-laptop update Len Brown
` (63 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Mike Travis, Andrew Morton, Len Brown
From: Mike Travis <travis@sgi.com>
Change processors from an array sized by NR_CPUS to a per_cpu variable.
Signed-off-by: Mike Travis <travis@sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/processor_core.c | 20 +++++++++-----------
drivers/acpi/processor_idle.c | 8 ++++----
drivers/acpi/processor_perflib.c | 18 +++++++++---------
drivers/acpi/processor_throttling.c | 14 +++++++-------
include/acpi/processor.h | 2 +-
5 files changed, 30 insertions(+), 32 deletions(-)
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 386e5aa..776d453 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -119,7 +119,7 @@ static const struct file_operations acpi_processor_info_fops = {
.release = single_release,
};
-struct acpi_processor *processors[NR_CPUS];
+DEFINE_PER_CPU(struct acpi_processor *, processors);
struct acpi_processor_errata errata __read_mostly;
/* --------------------------------------------------------------------------
@@ -615,7 +615,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
return 0;
}
-static void *processor_device_array[NR_CPUS];
+static DEFINE_PER_CPU(void *, processor_device_array);
static int __cpuinit acpi_processor_start(struct acpi_device *device)
{
@@ -639,15 +639,15 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
* ACPI id of processors can be reported wrongly by the BIOS.
* Don't trust it blindly
*/
- if (processor_device_array[pr->id] != NULL &&
- processor_device_array[pr->id] != device) {
+ if (per_cpu(processor_device_array, pr->id) != NULL &&
+ per_cpu(processor_device_array, pr->id) != device) {
printk(KERN_WARNING "BIOS reported wrong ACPI id "
"for the processor\n");
return -ENODEV;
}
- processor_device_array[pr->id] = device;
+ per_cpu(processor_device_array, pr->id) = device;
- processors[pr->id] = pr;
+ per_cpu(processors, pr->id) = pr;
result = acpi_processor_add_fs(device);
if (result)
@@ -750,7 +750,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned long)hcpu;
- struct acpi_processor *pr = processors[cpu];
+ struct acpi_processor *pr = per_cpu(processors, cpu);
if (action == CPU_ONLINE && pr) {
acpi_processor_ppc_has_changed(pr);
@@ -820,8 +820,8 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
pr->cdev = NULL;
}
- processors[pr->id] = NULL;
- processor_device_array[pr->id] = NULL;
+ per_cpu(processors, pr->id) = NULL;
+ per_cpu(processor_device_array, pr->id) = NULL;
kfree(pr);
return 0;
@@ -1069,8 +1069,6 @@ static int __init acpi_processor_init(void)
{
int result = 0;
-
- memset(&processors, 0, sizeof(processors));
memset(&errata, 0, sizeof(errata));
#ifdef CONFIG_SMP
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 2dd2c1f..c6df957 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -401,7 +401,7 @@ static void acpi_processor_idle(void)
*/
local_irq_disable();
- pr = processors[smp_processor_id()];
+ pr = __get_cpu_var(processors);
if (!pr) {
local_irq_enable();
return;
@@ -1431,7 +1431,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- pr = processors[smp_processor_id()];
+ pr = __get_cpu_var(processors);
if (unlikely(!pr))
return 0;
@@ -1471,7 +1471,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
u32 t1, t2;
int sleep_ticks = 0;
- pr = processors[smp_processor_id()];
+ pr = __get_cpu_var(processors);
if (unlikely(!pr))
return 0;
@@ -1549,7 +1549,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
u32 t1, t2;
int sleep_ticks = 0;
- pr = processors[smp_processor_id()];
+ pr = __get_cpu_var(processors);
if (unlikely(!pr))
return 0;
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index d80b2d1..b474996 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -89,7 +89,7 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb,
if (event != CPUFREQ_INCOMPATIBLE)
goto out;
- pr = processors[policy->cpu];
+ pr = per_cpu(processors, policy->cpu);
if (!pr || !pr->performance)
goto out;
@@ -572,7 +572,7 @@ int acpi_processor_preregister_performance(
/* Call _PSD for all CPUs */
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr) {
/* Look only at processors in ACPI namespace */
continue;
@@ -603,7 +603,7 @@ int acpi_processor_preregister_performance(
* domain info.
*/
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr)
continue;
@@ -624,7 +624,7 @@ int acpi_processor_preregister_performance(
cpus_clear(covered_cpus);
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr)
continue;
@@ -651,7 +651,7 @@ int acpi_processor_preregister_performance(
if (i == j)
continue;
- match_pr = processors[j];
+ match_pr = per_cpu(processors, j);
if (!match_pr)
continue;
@@ -680,7 +680,7 @@ int acpi_processor_preregister_performance(
if (i == j)
continue;
- match_pr = processors[j];
+ match_pr = per_cpu(processors, j);
if (!match_pr)
continue;
@@ -697,7 +697,7 @@ int acpi_processor_preregister_performance(
err_ret:
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr || !pr->performance)
continue;
@@ -728,7 +728,7 @@ acpi_processor_register_performance(struct acpi_processor_performance
mutex_lock(&performance_mutex);
- pr = processors[cpu];
+ pr = per_cpu(processors, cpu);
if (!pr) {
mutex_unlock(&performance_mutex);
return -ENODEV;
@@ -766,7 +766,7 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
mutex_lock(&performance_mutex);
- pr = processors[cpu];
+ pr = per_cpu(processors, cpu);
if (!pr) {
mutex_unlock(&performance_mutex);
return;
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index bb06738..8728782 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -71,7 +71,7 @@ static int acpi_processor_update_tsd_coord(void)
* coordination between all CPUs.
*/
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr)
continue;
@@ -93,7 +93,7 @@ static int acpi_processor_update_tsd_coord(void)
cpus_clear(covered_cpus);
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr)
continue;
@@ -119,7 +119,7 @@ static int acpi_processor_update_tsd_coord(void)
if (i == j)
continue;
- match_pr = processors[j];
+ match_pr = per_cpu(processors, j);
if (!match_pr)
continue;
@@ -152,7 +152,7 @@ static int acpi_processor_update_tsd_coord(void)
if (i == j)
continue;
- match_pr = processors[j];
+ match_pr = per_cpu(processors, j);
if (!match_pr)
continue;
@@ -172,7 +172,7 @@ static int acpi_processor_update_tsd_coord(void)
err_ret:
for_each_possible_cpu(i) {
- pr = processors[i];
+ pr = per_cpu(processors, i);
if (!pr)
continue;
@@ -214,7 +214,7 @@ static int acpi_processor_throttling_notifier(unsigned long event, void *data)
struct acpi_processor_throttling *p_throttling;
cpu = p_tstate->cpu;
- pr = processors[cpu];
+ pr = per_cpu(processors, cpu);
if (!pr) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid pr pointer\n"));
return 0;
@@ -1035,7 +1035,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
* cpus.
*/
for_each_cpu_mask(i, online_throttling_cpus) {
- match_pr = processors[i];
+ match_pr = per_cpu(processors, i);
/*
* If the pointer is invalid, we will report the
* error message and continue.
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 06480bc..4a1b66a 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -255,7 +255,7 @@ extern void acpi_processor_unregister_performance(struct
int acpi_processor_notify_smm(struct module *calling_module);
/* for communication between multiple parts of the processor kernel module */
-extern struct acpi_processor *processors[NR_CPUS];
+DECLARE_PER_CPU(struct acpi_processor *, processors);
extern struct acpi_processor_errata errata;
void arch_acpi_processor_init_pdc(struct acpi_processor *pr);
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 06/70] Fujitsu-laptop update
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (3 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 05/70] ACPI: change processors from array to per_cpu variable Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 07/70] ACPI PM: acpi_pm_device_sleep_state() cleanup Len Brown
` (62 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Jonathan Woithe, Peter Gruber, Len Brown
From: Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
Add additional capabilities to the Fujitsu-laptop driver.
* Brightness hotkey actions are sent to userspace. This can be disabled
using a module parameter if it causes issues with models which handle
these keys transparently in the BIOS.
* Actions of additional hotkeys found on some Fujitsu models (eg: the
suspend key and the dedicated "power on passphrase" keys) are broadcast
to userspace.
* An alternative brightness control method used by some Fujitsu models
(for example, the S6410) is now supported, enabling software brightness
controls on models using this method.
* DMI-based module aliases are configured for the S6410 and S7020.
* The current LCD brightness after booting should now be reflected in the
standard backlight interface sysfs file (previously it was always set to
0). The platform brightness sysfs interface has always been fine.
Thanks go to Peter Gruber who provided a significant portion of this code
and tested various iterations of the patch on his S6410.
Signed-off-by: Peter Gruber <nokos@gmx.net>
Signed-off-by: Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
Signed-off-by: Len Brown <len.brown@intel.com>
---
MAINTAINERS | 6 +
drivers/misc/Kconfig | 13 +-
drivers/misc/fujitsu-laptop.c | 825 ++++++++++++++++++++++++++++++++++++++---
3 files changed, 792 insertions(+), 52 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index e3560df..7840d16 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1757,6 +1757,12 @@ P: David Howells
M: dhowells@redhat.com
S: Maintained
+FUJITSU LAPTOP EXTRAS
+P: Jonathan Woithe
+M: jwoithe@physics.adelaide.edu.au
+L: linux-acpi@vger.kernel.org
+S: Maintained
+
FUSE: FILESYSTEM IN USERSPACE
P: Miklos Szeredi
M: miklos@szeredi.hu
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 636af28..b4759ab 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -185,11 +185,22 @@ config FUJITSU_LAPTOP
* P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks
* Possibly other Fujitsu laptop models
+ * Tested with S6410 and S7020
- It adds support for LCD brightness control.
+ It adds support for LCD brightness control and some hotkeys.
If you have a Fujitsu laptop, say Y or M here.
+config FUJITSU_LAPTOP_DEBUG
+ bool "Verbose debug mode for Fujitsu Laptop Extras"
+ depends on FUJITSU_LAPTOP
+ default n
+ ---help---
+ Enables extra debug output from the fujitsu extras driver, at the
+ expense of a slight increase in driver size.
+
+ If you are not sure, say N here.
+
config TC1100_WMI
tristate "HP Compaq TC1100 Tablet WMI Extras (EXPERIMENTAL)"
depends on X86 && !X86_64
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c
index 6d14e8f..3601224 100644
--- a/drivers/misc/fujitsu-laptop.c
+++ b/drivers/misc/fujitsu-laptop.c
@@ -1,12 +1,14 @@
/*-*-linux-c-*-*/
/*
- Copyright (C) 2007 Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
+ Copyright (C) 2007,2008 Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
+ Copyright (C) 2008 Peter Gruber <nokos@gmx.net>
Based on earlier work:
Copyright (C) 2003 Shane Spencer <shane@bogomip.com>
Adrian Yee <brewt-fujitsu@brewt.org>
- Templated from msi-laptop.c which is copyright by its respective authors.
+ Templated from msi-laptop.c and thinkpad_acpi.c which is copyright
+ by its respective authors.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -39,8 +41,17 @@
* registers itself in the Linux backlight control subsystem and is
* available to userspace under /sys/class/backlight/fujitsu-laptop/.
*
- * This driver has been tested on a Fujitsu Lifebook S7020. It should
- * work on most P-series and S-series Lifebooks, but YMMV.
+ * Hotkeys present on certain Fujitsu laptops (eg: the S6xxx series) are
+ * also supported by this driver.
+ *
+ * This driver has been tested on a Fujitsu Lifebook S6410 and S7020. It
+ * should work on most P-series and S-series Lifebooks, but YMMV.
+ *
+ * The module parameter use_alt_lcd_levels switches between different ACPI
+ * brightness controls which are used by different Fujitsu laptops. In most
+ * cases the correct method is automatically detected. "use_alt_lcd_levels=1"
+ * is applicable for a Fujitsu Lifebook S6410 if autodetection fails.
+ *
*/
#include <linux/module.h>
@@ -49,30 +60,105 @@
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/backlight.h>
+#include <linux/input.h>
+#include <linux/kfifo.h>
+#include <linux/video_output.h>
#include <linux/platform_device.h>
-#define FUJITSU_DRIVER_VERSION "0.3"
+#define FUJITSU_DRIVER_VERSION "0.4.2"
#define FUJITSU_LCD_N_LEVELS 8
#define ACPI_FUJITSU_CLASS "fujitsu"
#define ACPI_FUJITSU_HID "FUJ02B1"
-#define ACPI_FUJITSU_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI extras driver"
+#define ACPI_FUJITSU_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI brightness driver"
#define ACPI_FUJITSU_DEVICE_NAME "Fujitsu FUJ02B1"
-
+#define ACPI_FUJITSU_HOTKEY_HID "FUJ02E3"
+#define ACPI_FUJITSU_HOTKEY_DRIVER_NAME "Fujitsu laptop FUJ02E3 ACPI hotkeys driver"
+#define ACPI_FUJITSU_HOTKEY_DEVICE_NAME "Fujitsu FUJ02E3"
+
+#define ACPI_FUJITSU_NOTIFY_CODE1 0x80
+
+#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
+#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
+
+/* Hotkey details */
+#define LOCK_KEY 0x410 /* codes for the keys in the GIRB register */
+#define DISPLAY_KEY 0x411 /* keys are mapped to KEY_SCREENLOCK (the key with the key symbol) */
+#define ENERGY_KEY 0x412 /* KEY_MEDIA (the key with the laptop symbol, KEY_EMAIL (E key)) */
+#define REST_KEY 0x413 /* KEY_SUSPEND (R key) */
+
+#define MAX_HOTKEY_RINGBUFFER_SIZE 100
+#define RINGBUFFERSIZE 40
+
+/* Debugging */
+#define FUJLAPTOP_LOG ACPI_FUJITSU_HID ": "
+#define FUJLAPTOP_ERR KERN_ERR FUJLAPTOP_LOG
+#define FUJLAPTOP_NOTICE KERN_NOTICE FUJLAPTOP_LOG
+#define FUJLAPTOP_INFO KERN_INFO FUJLAPTOP_LOG
+#define FUJLAPTOP_DEBUG KERN_DEBUG FUJLAPTOP_LOG
+
+#define FUJLAPTOP_DBG_ALL 0xffff
+#define FUJLAPTOP_DBG_ERROR 0x0001
+#define FUJLAPTOP_DBG_WARN 0x0002
+#define FUJLAPTOP_DBG_INFO 0x0004
+#define FUJLAPTOP_DBG_TRACE 0x0008
+
+#define dbg_printk(a_dbg_level, format, arg...) \
+ do { if (dbg_level & a_dbg_level) \
+ printk(FUJLAPTOP_DEBUG "%s: " format, __func__ , ## arg); \
+ } while (0)
+#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
+#define vdbg_printk(a_dbg_level, format, arg...) \
+ dbg_printk(a_dbg_level, format, ## arg)
+#else
+#define vdbg_printk(a_dbg_level, format, arg...)
+#endif
+
+/* Device controlling the backlight and associated keys */
struct fujitsu_t {
acpi_handle acpi_handle;
+ struct acpi_device *dev;
+ struct input_dev *input;
+ char phys[32];
struct backlight_device *bl_device;
struct platform_device *pf_device;
- unsigned long fuj02b1_state;
+ unsigned int max_brightness;
unsigned int brightness_changed;
unsigned int brightness_level;
};
static struct fujitsu_t *fujitsu;
+static int use_alt_lcd_levels = -1;
+static int disable_brightness_keys = -1;
+static int disable_brightness_adjust = -1;
+
+/* Device used to access other hotkeys on the laptop */
+struct fujitsu_hotkey_t {
+ acpi_handle acpi_handle;
+ struct acpi_device *dev;
+ struct input_dev *input;
+ char phys[32];
+ struct platform_device *pf_device;
+ struct kfifo *fifo;
+ spinlock_t fifo_lock;
+
+ unsigned int irb; /* info about the pressed buttons */
+};
-/* Hardware access */
+static struct fujitsu_hotkey_t *fujitsu_hotkey;
+
+static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
+ void *data);
+
+#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
+static u32 dbg_level = 0x03;
+#endif
+
+static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data);
+
+/* Hardware access for LCD brightness control */
static int set_lcd_level(int level)
{
@@ -81,7 +167,10 @@ static int set_lcd_level(int level)
struct acpi_object_list arg_list = { 1, &arg0 };
acpi_handle handle = NULL;
- if (level < 0 || level >= FUJITSU_LCD_N_LEVELS)
+ vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBLL [%d]\n",
+ level);
+
+ if (level < 0 || level >= fujitsu->max_brightness)
return -EINVAL;
if (!fujitsu)
@@ -89,7 +178,38 @@ static int set_lcd_level(int level)
status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle);
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SBLL not present\n"));
+ vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBLL not present\n");
+ return -ENODEV;
+ }
+
+ arg0.integer.value = level;
+
+ status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ return 0;
+}
+
+static int set_lcd_level_alt(int level)
+{
+ acpi_status status = AE_OK;
+ union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+ struct acpi_object_list arg_list = { 1, &arg0 };
+ acpi_handle handle = NULL;
+
+ vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBL2 [%d]\n",
+ level);
+
+ if (level < 0 || level >= fujitsu->max_brightness)
+ return -EINVAL;
+
+ if (!fujitsu)
+ return -EINVAL;
+
+ status = acpi_get_handle(fujitsu->acpi_handle, "SBL2", &handle);
+ if (ACPI_FAILURE(status)) {
+ vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBL2 not present\n");
return -ENODEV;
}
@@ -107,13 +227,52 @@ static int get_lcd_level(void)
unsigned long state = 0;
acpi_status status = AE_OK;
- // Get the Brightness
+ vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n");
+
status =
acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state);
if (status < 0)
return status;
- fujitsu->fuj02b1_state = state;
+ fujitsu->brightness_level = state & 0x0fffffff;
+
+ if (state & 0x80000000)
+ fujitsu->brightness_changed = 1;
+ else
+ fujitsu->brightness_changed = 0;
+
+ return fujitsu->brightness_level;
+}
+
+static int get_max_brightness(void)
+{
+ unsigned long state = 0;
+ acpi_status status = AE_OK;
+
+ vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n");
+
+ status =
+ acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state);
+ if (status < 0)
+ return status;
+
+ fujitsu->max_brightness = state;
+
+ return fujitsu->max_brightness;
+}
+
+static int get_lcd_level_alt(void)
+{
+ unsigned long state = 0;
+ acpi_status status = AE_OK;
+
+ vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLS\n");
+
+ status =
+ acpi_evaluate_integer(fujitsu->acpi_handle, "GBLS", NULL, &state);
+ if (status < 0)
+ return status;
+
fujitsu->brightness_level = state & 0x0fffffff;
if (state & 0x80000000)
@@ -128,12 +287,18 @@ static int get_lcd_level(void)
static int bl_get_brightness(struct backlight_device *b)
{
- return get_lcd_level();
+ if (use_alt_lcd_levels)
+ return get_lcd_level_alt();
+ else
+ return get_lcd_level();
}
static int bl_update_status(struct backlight_device *b)
{
- return set_lcd_level(b->props.brightness);
+ if (use_alt_lcd_levels)
+ return set_lcd_level_alt(b->props.brightness);
+ else
+ return set_lcd_level(b->props.brightness);
}
static struct backlight_ops fujitsubl_ops = {
@@ -141,7 +306,35 @@ static struct backlight_ops fujitsubl_ops = {
.update_status = bl_update_status,
};
-/* Platform device */
+/* Platform LCD brightness device */
+
+static ssize_t
+show_max_brightness(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+
+ int ret;
+
+ ret = get_max_brightness();
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%i\n", ret);
+}
+
+static ssize_t
+show_brightness_changed(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+
+ int ret;
+
+ ret = fujitsu->brightness_changed;
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%i\n", ret);
+}
static ssize_t show_lcd_level(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -149,7 +342,10 @@ static ssize_t show_lcd_level(struct device *dev,
int ret;
- ret = get_lcd_level();
+ if (use_alt_lcd_levels)
+ ret = get_lcd_level_alt();
+ else
+ ret = get_lcd_level();
if (ret < 0)
return ret;
@@ -164,19 +360,61 @@ static ssize_t store_lcd_level(struct device *dev,
int level, ret;
if (sscanf(buf, "%i", &level) != 1
- || (level < 0 || level >= FUJITSU_LCD_N_LEVELS))
+ || (level < 0 || level >= fujitsu->max_brightness))
return -EINVAL;
- ret = set_lcd_level(level);
+ if (use_alt_lcd_levels)
+ ret = set_lcd_level_alt(level);
+ else
+ ret = set_lcd_level(level);
+ if (ret < 0)
+ return ret;
+
+ if (use_alt_lcd_levels)
+ ret = get_lcd_level_alt();
+ else
+ ret = get_lcd_level();
if (ret < 0)
return ret;
return count;
}
+/* Hardware access for hotkey device */
+
+static int get_irb(void)
+{
+ unsigned long state = 0;
+ acpi_status status = AE_OK;
+
+ vdbg_printk(FUJLAPTOP_DBG_TRACE, "Get irb\n");
+
+ status =
+ acpi_evaluate_integer(fujitsu_hotkey->acpi_handle, "GIRB", NULL,
+ &state);
+ if (status < 0)
+ return status;
+
+ fujitsu_hotkey->irb = state;
+
+ return fujitsu_hotkey->irb;
+}
+
+static ssize_t
+ignore_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return count;
+}
+
+static DEVICE_ATTR(max_brightness, 0444, show_max_brightness, ignore_store);
+static DEVICE_ATTR(brightness_changed, 0444, show_brightness_changed,
+ ignore_store);
static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
static struct attribute *fujitsupf_attributes[] = {
+ &dev_attr_brightness_changed.attr,
+ &dev_attr_max_brightness.attr,
&dev_attr_lcd_level.attr,
NULL
};
@@ -192,14 +430,52 @@ static struct platform_driver fujitsupf_driver = {
}
};
-/* ACPI device */
+static int dmi_check_cb_s6410(const struct dmi_system_id *id)
+{
+ acpi_handle handle;
+ int have_blnf;
+ printk(KERN_INFO "fujitsu-laptop: Identified laptop model '%s'.\n",
+ id->ident);
+ have_blnf = ACPI_SUCCESS
+ (acpi_get_handle(NULL, "\\_SB.PCI0.GFX0.LCD.BLNF", &handle));
+ if (use_alt_lcd_levels == -1) {
+ vdbg_printk(FUJLAPTOP_DBG_TRACE, "auto-detecting usealt\n");
+ use_alt_lcd_levels = 1;
+ }
+ if (disable_brightness_keys == -1) {
+ vdbg_printk(FUJLAPTOP_DBG_TRACE,
+ "auto-detecting disable_keys\n");
+ disable_brightness_keys = have_blnf ? 1 : 0;
+ }
+ if (disable_brightness_adjust == -1) {
+ vdbg_printk(FUJLAPTOP_DBG_TRACE,
+ "auto-detecting disable_adjust\n");
+ disable_brightness_adjust = have_blnf ? 0 : 1;
+ }
+ return 0;
+}
+
+static struct dmi_system_id __initdata fujitsu_dmi_table[] = {
+ {
+ .ident = "Fujitsu Siemens",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6410"),
+ },
+ .callback = dmi_check_cb_s6410},
+ {}
+};
+
+/* ACPI device for LCD brightness control */
static int acpi_fujitsu_add(struct acpi_device *device)
{
+ acpi_status status;
+ acpi_handle handle;
int result = 0;
int state = 0;
-
- ACPI_FUNCTION_TRACE("acpi_fujitsu_add");
+ struct input_dev *input;
+ int error;
if (!device)
return -EINVAL;
@@ -209,10 +485,42 @@ static int acpi_fujitsu_add(struct acpi_device *device)
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
acpi_driver_data(device) = fujitsu;
+ status = acpi_install_notify_handler(device->handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_fujitsu_notify, fujitsu);
+
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR "Error installing notify handler\n");
+ error = -ENODEV;
+ goto err_stop;
+ }
+
+ fujitsu->input = input = input_allocate_device();
+ if (!input) {
+ error = -ENOMEM;
+ goto err_uninstall_notify;
+ }
+
+ snprintf(fujitsu->phys, sizeof(fujitsu->phys),
+ "%s/video/input0", acpi_device_hid(device));
+
+ input->name = acpi_device_name(device);
+ input->phys = fujitsu->phys;
+ input->id.bustype = BUS_HOST;
+ input->id.product = 0x06;
+ input->dev.parent = &device->dev;
+ input->evbit[0] = BIT(EV_KEY);
+ set_bit(KEY_BRIGHTNESSUP, input->keybit);
+ set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
+ set_bit(KEY_UNKNOWN, input->keybit);
+
+ error = input_register_device(input);
+ if (error)
+ goto err_free_input_dev;
+
result = acpi_bus_get_power(fujitsu->acpi_handle, &state);
if (result) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error reading power state\n"));
+ printk(KERN_ERR "Error reading power state\n");
goto end;
}
@@ -220,22 +528,373 @@ static int acpi_fujitsu_add(struct acpi_device *device)
acpi_device_name(device), acpi_device_bid(device),
!device->power.state ? "on" : "off");
- end:
+ fujitsu->dev = device;
+
+ if (ACPI_SUCCESS
+ (acpi_get_handle(device->handle, METHOD_NAME__INI, &handle))) {
+ vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n");
+ if (ACPI_FAILURE
+ (acpi_evaluate_object
+ (device->handle, METHOD_NAME__INI, NULL, NULL)))
+ printk(KERN_ERR "_INI Method failed\n");
+ }
+
+ /* do config (detect defaults) */
+ dmi_check_system(fujitsu_dmi_table);
+ use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0;
+ disable_brightness_keys = disable_brightness_keys == 1 ? 1 : 0;
+ disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0;
+ vdbg_printk(FUJLAPTOP_DBG_INFO,
+ "config: [alt interface: %d], [key disable: %d], [adjust disable: %d]\n",
+ use_alt_lcd_levels, disable_brightness_keys,
+ disable_brightness_adjust);
+
+ if (get_max_brightness() <= 0)
+ fujitsu->max_brightness = FUJITSU_LCD_N_LEVELS;
+ if (use_alt_lcd_levels)
+ get_lcd_level_alt();
+ else
+ get_lcd_level();
+
+ return result;
+
+end:
+err_free_input_dev:
+ input_free_device(input);
+err_uninstall_notify:
+ acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+ acpi_fujitsu_notify);
+err_stop:
return result;
}
static int acpi_fujitsu_remove(struct acpi_device *device, int type)
{
- ACPI_FUNCTION_TRACE("acpi_fujitsu_remove");
+ acpi_status status;
+ struct fujitsu_t *fujitsu = NULL;
if (!device || !acpi_driver_data(device))
return -EINVAL;
+
+ fujitsu = acpi_driver_data(device);
+
+ status = acpi_remove_notify_handler(fujitsu->acpi_handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_fujitsu_notify);
+
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+
fujitsu->acpi_handle = NULL;
return 0;
}
+/* Brightness notify */
+
+static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
+{
+ struct input_dev *input;
+ int keycode;
+ int oldb, newb;
+
+ input = fujitsu->input;
+
+ switch (event) {
+ case ACPI_FUJITSU_NOTIFY_CODE1:
+ keycode = 0;
+ oldb = fujitsu->brightness_level;
+ get_lcd_level(); /* the alt version always yields changed */
+ newb = fujitsu->brightness_level;
+
+ vdbg_printk(FUJLAPTOP_DBG_TRACE,
+ "brightness button event [%i -> %i (%i)]\n",
+ oldb, newb, fujitsu->brightness_changed);
+
+ if (oldb == newb && fujitsu->brightness_changed) {
+ keycode = 0;
+ if (disable_brightness_keys != 1) {
+ if (oldb == 0) {
+ acpi_bus_generate_proc_event(fujitsu->
+ dev,
+ ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
+ 0);
+ keycode = KEY_BRIGHTNESSDOWN;
+ } else if (oldb ==
+ (fujitsu->max_brightness) - 1) {
+ acpi_bus_generate_proc_event(fujitsu->
+ dev,
+ ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
+ 0);
+ keycode = KEY_BRIGHTNESSUP;
+ }
+ }
+ } else if (oldb < newb) {
+ if (disable_brightness_adjust != 1) {
+ if (use_alt_lcd_levels)
+ set_lcd_level_alt(newb);
+ else
+ set_lcd_level(newb);
+ }
+ if (disable_brightness_keys != 1) {
+ acpi_bus_generate_proc_event(fujitsu->dev,
+ ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
+ 0);
+ keycode = KEY_BRIGHTNESSUP;
+ }
+ } else if (oldb > newb) {
+ if (disable_brightness_adjust != 1) {
+ if (use_alt_lcd_levels)
+ set_lcd_level_alt(newb);
+ else
+ set_lcd_level(newb);
+ }
+ if (disable_brightness_keys != 1) {
+ acpi_bus_generate_proc_event(fujitsu->dev,
+ ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
+ 0);
+ keycode = KEY_BRIGHTNESSDOWN;
+ }
+ } else {
+ keycode = KEY_UNKNOWN;
+ }
+ break;
+ default:
+ keycode = KEY_UNKNOWN;
+ vdbg_printk(FUJLAPTOP_DBG_WARN,
+ "unsupported event [0x%x]\n", event);
+ break;
+ }
+
+ if (keycode != 0) {
+ input_report_key(input, keycode, 1);
+ input_sync(input);
+ input_report_key(input, keycode, 0);
+ input_sync(input);
+ }
+
+ return;
+}
+
+/* ACPI device for hotkey handling */
+
+static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
+{
+ acpi_status status;
+ acpi_handle handle;
+ int result = 0;
+ int state = 0;
+ struct input_dev *input;
+ int error;
+ int i;
+
+ if (!device)
+ return -EINVAL;
+
+ fujitsu_hotkey->acpi_handle = device->handle;
+ sprintf(acpi_device_name(device), "%s",
+ ACPI_FUJITSU_HOTKEY_DEVICE_NAME);
+ sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
+ acpi_driver_data(device) = fujitsu_hotkey;
+
+ status = acpi_install_notify_handler(device->handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_fujitsu_hotkey_notify,
+ fujitsu_hotkey);
+
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR "Error installing notify handler\n");
+ error = -ENODEV;
+ goto err_stop;
+ }
+
+ /* kfifo */
+ spin_lock_init(&fujitsu_hotkey->fifo_lock);
+ fujitsu_hotkey->fifo =
+ kfifo_alloc(RINGBUFFERSIZE * sizeof(int), GFP_KERNEL,
+ &fujitsu_hotkey->fifo_lock);
+ if (IS_ERR(fujitsu_hotkey->fifo)) {
+ printk(KERN_ERR "kfifo_alloc failed\n");
+ error = PTR_ERR(fujitsu_hotkey->fifo);
+ goto err_stop;
+ }
+
+ fujitsu_hotkey->input = input = input_allocate_device();
+ if (!input) {
+ error = -ENOMEM;
+ goto err_uninstall_notify;
+ }
+
+ snprintf(fujitsu_hotkey->phys, sizeof(fujitsu_hotkey->phys),
+ "%s/video/input0", acpi_device_hid(device));
+
+ input->name = acpi_device_name(device);
+ input->phys = fujitsu_hotkey->phys;
+ input->id.bustype = BUS_HOST;
+ input->id.product = 0x06;
+ input->dev.parent = &device->dev;
+ input->evbit[0] = BIT(EV_KEY);
+ set_bit(KEY_SCREENLOCK, input->keybit);
+ set_bit(KEY_MEDIA, input->keybit);
+ set_bit(KEY_EMAIL, input->keybit);
+ set_bit(KEY_SUSPEND, input->keybit);
+ set_bit(KEY_UNKNOWN, input->keybit);
+
+ error = input_register_device(input);
+ if (error)
+ goto err_free_input_dev;
+
+ result = acpi_bus_get_power(fujitsu_hotkey->acpi_handle, &state);
+ if (result) {
+ printk(KERN_ERR "Error reading power state\n");
+ goto end;
+ }
+
+ printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
+ acpi_device_name(device), acpi_device_bid(device),
+ !device->power.state ? "on" : "off");
+
+ fujitsu_hotkey->dev = device;
+
+ if (ACPI_SUCCESS
+ (acpi_get_handle(device->handle, METHOD_NAME__INI, &handle))) {
+ vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n");
+ if (ACPI_FAILURE
+ (acpi_evaluate_object
+ (device->handle, METHOD_NAME__INI, NULL, NULL)))
+ printk(KERN_ERR "_INI Method failed\n");
+ }
+
+ i = 0; /* Discard hotkey ringbuffer */
+ while (get_irb() != 0 && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) ;
+ vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i);
+
+ return result;
+
+end:
+err_free_input_dev:
+ input_free_device(input);
+err_uninstall_notify:
+ acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+ acpi_fujitsu_hotkey_notify);
+ kfifo_free(fujitsu_hotkey->fifo);
+err_stop:
+
+ return result;
+}
+
+static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
+{
+ acpi_status status;
+ struct fujitsu_hotkey_t *fujitsu_hotkey = NULL;
+
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+
+ fujitsu_hotkey = acpi_driver_data(device);
+
+ status = acpi_remove_notify_handler(fujitsu_hotkey->acpi_handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_fujitsu_hotkey_notify);
+
+ fujitsu_hotkey->acpi_handle = NULL;
+
+ kfifo_free(fujitsu_hotkey->fifo);
+
+ return 0;
+}
+
+static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
+ void *data)
+{
+ struct input_dev *input;
+ int keycode, keycode_r;
+ unsigned int irb = 1;
+ int i, status;
+
+ input = fujitsu_hotkey->input;
+
+ vdbg_printk(FUJLAPTOP_DBG_TRACE, "Hotkey event\n");
+
+ switch (event) {
+ case ACPI_FUJITSU_NOTIFY_CODE1:
+ i = 0;
+ while ((irb = get_irb()) != 0
+ && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) {
+ vdbg_printk(FUJLAPTOP_DBG_TRACE, "GIRB result [%x]\n",
+ irb);
+
+ switch (irb & 0x4ff) {
+ case LOCK_KEY:
+ keycode = KEY_SCREENLOCK;
+ break;
+ case DISPLAY_KEY:
+ keycode = KEY_MEDIA;
+ break;
+ case ENERGY_KEY:
+ keycode = KEY_EMAIL;
+ break;
+ case REST_KEY:
+ keycode = KEY_SUSPEND;
+ break;
+ case 0:
+ keycode = 0;
+ break;
+ default:
+ vdbg_printk(FUJLAPTOP_DBG_WARN,
+ "Unknown GIRB result [%x]\n", irb);
+ keycode = -1;
+ break;
+ }
+ if (keycode > 0) {
+ vdbg_printk(FUJLAPTOP_DBG_TRACE,
+ "Push keycode into ringbuffer [%d]\n",
+ keycode);
+ status = kfifo_put(fujitsu_hotkey->fifo,
+ (unsigned char *)&keycode,
+ sizeof(keycode));
+ if (status != sizeof(keycode)) {
+ vdbg_printk(FUJLAPTOP_DBG_WARN,
+ "Could not push keycode [0x%x]\n",
+ keycode);
+ } else {
+ input_report_key(input, keycode, 1);
+ input_sync(input);
+ }
+ } else if (keycode == 0) {
+ while ((status =
+ kfifo_get
+ (fujitsu_hotkey->fifo, (unsigned char *)
+ &keycode_r,
+ sizeof
+ (keycode_r))) == sizeof(keycode_r)) {
+ input_report_key(input, keycode_r, 0);
+ input_sync(input);
+ vdbg_printk(FUJLAPTOP_DBG_TRACE,
+ "Pop keycode from ringbuffer [%d]\n",
+ keycode_r);
+ }
+ }
+ }
+
+ break;
+ default:
+ keycode = KEY_UNKNOWN;
+ vdbg_printk(FUJLAPTOP_DBG_WARN,
+ "Unsupported event [0x%x]\n", event);
+ input_report_key(input, keycode, 1);
+ input_sync(input);
+ input_report_key(input, keycode, 0);
+ input_sync(input);
+ break;
+ }
+
+ return;
+}
+
+/* Initialization */
+
static const struct acpi_device_id fujitsu_device_ids[] = {
{ACPI_FUJITSU_HID, 0},
{"", 0},
@@ -251,11 +910,24 @@ static struct acpi_driver acpi_fujitsu_driver = {
},
};
-/* Initialization */
+static const struct acpi_device_id fujitsu_hotkey_device_ids[] = {
+ {ACPI_FUJITSU_HOTKEY_HID, 0},
+ {"", 0},
+};
+
+static struct acpi_driver acpi_fujitsu_hotkey_driver = {
+ .name = ACPI_FUJITSU_HOTKEY_DRIVER_NAME,
+ .class = ACPI_FUJITSU_CLASS,
+ .ids = fujitsu_hotkey_device_ids,
+ .ops = {
+ .add = acpi_fujitsu_hotkey_add,
+ .remove = acpi_fujitsu_hotkey_remove,
+ },
+};
static int __init fujitsu_init(void)
{
- int ret, result;
+ int ret, result, max_brightness;
if (acpi_disabled)
return -ENODEV;
@@ -271,19 +943,6 @@ static int __init fujitsu_init(void)
goto fail_acpi;
}
- /* Register backlight stuff */
-
- fujitsu->bl_device =
- backlight_device_register("fujitsu-laptop", NULL, NULL,
- &fujitsubl_ops);
- if (IS_ERR(fujitsu->bl_device))
- return PTR_ERR(fujitsu->bl_device);
-
- fujitsu->bl_device->props.max_brightness = FUJITSU_LCD_N_LEVELS - 1;
- ret = platform_driver_register(&fujitsupf_driver);
- if (ret)
- goto fail_backlight;
-
/* Register platform stuff */
fujitsu->pf_device = platform_device_alloc("fujitsu-laptop", -1);
@@ -302,28 +961,68 @@ static int __init fujitsu_init(void)
if (ret)
goto fail_platform_device2;
+ /* Register backlight stuff */
+
+ fujitsu->bl_device =
+ backlight_device_register("fujitsu-laptop", NULL, NULL,
+ &fujitsubl_ops);
+ if (IS_ERR(fujitsu->bl_device))
+ return PTR_ERR(fujitsu->bl_device);
+
+ max_brightness = fujitsu->max_brightness;
+
+ fujitsu->bl_device->props.max_brightness = max_brightness - 1;
+ fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
+
+ ret = platform_driver_register(&fujitsupf_driver);
+ if (ret)
+ goto fail_backlight;
+
+ /* Register hotkey driver */
+
+ fujitsu_hotkey = kmalloc(sizeof(struct fujitsu_hotkey_t), GFP_KERNEL);
+ if (!fujitsu_hotkey) {
+ ret = -ENOMEM;
+ goto fail_hotkey;
+ }
+ memset(fujitsu_hotkey, 0, sizeof(struct fujitsu_hotkey_t));
+
+ result = acpi_bus_register_driver(&acpi_fujitsu_hotkey_driver);
+ if (result < 0) {
+ ret = -ENODEV;
+ goto fail_hotkey1;
+ }
+
printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION
" successfully loaded.\n");
return 0;
- fail_platform_device2:
+fail_hotkey1:
- platform_device_del(fujitsu->pf_device);
-
- fail_platform_device1:
-
- platform_device_put(fujitsu->pf_device);
+ kfree(fujitsu_hotkey);
- fail_platform_driver:
+fail_hotkey:
platform_driver_unregister(&fujitsupf_driver);
- fail_backlight:
+fail_backlight:
backlight_device_unregister(fujitsu->bl_device);
- fail_acpi:
+fail_platform_device2:
+
+ platform_device_del(fujitsu->pf_device);
+
+fail_platform_device1:
+
+ platform_device_put(fujitsu->pf_device);
+
+fail_platform_driver:
+
+ acpi_bus_unregister_driver(&acpi_fujitsu_driver);
+
+fail_acpi:
kfree(fujitsu);
@@ -342,19 +1041,43 @@ static void __exit fujitsu_cleanup(void)
kfree(fujitsu);
+ acpi_bus_unregister_driver(&acpi_fujitsu_hotkey_driver);
+
+ kfree(fujitsu_hotkey);
+
printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n");
}
module_init(fujitsu_init);
module_exit(fujitsu_cleanup);
-MODULE_AUTHOR("Jonathan Woithe");
+module_param(use_alt_lcd_levels, uint, 0644);
+MODULE_PARM_DESC(use_alt_lcd_levels,
+ "Use alternative interface for lcd_levels (needed for Lifebook s6410).");
+module_param(disable_brightness_keys, uint, 0644);
+MODULE_PARM_DESC(disable_brightness_keys,
+ "Disable brightness keys (eg. if they are already handled by the generic ACPI_VIDEO device).");
+module_param(disable_brightness_adjust, uint, 0644);
+MODULE_PARM_DESC(disable_brightness_adjust, "Disable brightness adjustment .");
+#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
+module_param_named(debug, dbg_level, uint, 0644);
+MODULE_PARM_DESC(debug, "Sets debug level bit-mask");
+#endif
+
+MODULE_AUTHOR("Jonathan Woithe, Peter Gruber");
MODULE_DESCRIPTION("Fujitsu laptop extras support");
MODULE_VERSION(FUJITSU_DRIVER_VERSION);
MODULE_LICENSE("GPL");
+MODULE_ALIAS
+ ("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*");
+MODULE_ALIAS
+ ("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*");
+
static struct pnp_device_id pnp_ids[] = {
{ .id = "FUJ02bf" },
+ { .id = "FUJ02B1" },
+ { .id = "FUJ02E3" },
{ .id = "" }
};
MODULE_DEVICE_TABLE(pnp, pnp_ids);
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 07/70] ACPI PM: acpi_pm_device_sleep_state() cleanup
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (4 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 06/70] Fujitsu-laptop update Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 08/70] PCI ACPI: Drop the second argument of platform_pci_choose_state Len Brown
` (61 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: David Brownell, Rafael J. Wysocki, Len Brown
From: David Brownell <dbrownell@users.sourceforge.net>
Get rid of a superfluous acpi_pm_device_sleep_state() parameter. The
only legitimate value of that parameter must be derived from the first
parameter, which is what all the callers already do. (However, this
does not address the fact that ACPI still doesn't set up those flags.)
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/sleep/main.c | 8 ++++----
drivers/pci/pci-acpi.c | 3 +--
drivers/pnp/pnpacpi/core.c | 4 +---
include/acpi/acpi_bus.h | 4 ++--
4 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index c3b0cd8..fbd40e9 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -369,8 +369,8 @@ int acpi_suspend(u32 acpi_state)
/**
* acpi_pm_device_sleep_state - return preferred power state of ACPI device
* in the system sleep state given by %acpi_target_sleep_state
- * @dev: device to examine
- * @wake: if set, the device should be able to wake up the system
+ * @dev: device to examine; its driver model wakeup flags control
+ * whether it should be able to wake up the system
* @d_min_p: used to store the upper limit of allowed states range
* Return value: preferred power state of the device on success, -ENODEV on
* failure (ie. if there's no 'struct acpi_device' for @dev)
@@ -388,7 +388,7 @@ int acpi_suspend(u32 acpi_state)
* via @wake.
*/
-int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
+int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
{
acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
struct acpi_device *adev;
@@ -427,7 +427,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
* can wake the system. _S0W may be valid, too.
*/
if (acpi_target_sleep_state == ACPI_STATE_S0 ||
- (wake && adev->wakeup.state.enabled &&
+ (device_may_wakeup(dev) && adev->wakeup.state.enabled &&
adev->wakeup.sleep_state <= acpi_target_sleep_state)) {
acpi_status status;
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 9d6fc8e..caabf05 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -298,8 +298,7 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev,
{
int acpi_state;
- acpi_state = acpi_pm_device_sleep_state(&pdev->dev,
- device_may_wakeup(&pdev->dev), NULL);
+ acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL);
if (acpi_state < 0)
return PCI_POWER_ERROR;
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 5090277..c1b9ea3 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -117,9 +117,7 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
{
int power_state;
- power_state = acpi_pm_device_sleep_state(&dev->dev,
- device_may_wakeup(&dev->dev),
- NULL);
+ power_state = acpi_pm_device_sleep_state(&dev->dev, NULL);
if (power_state < 0)
power_state = (state.event == PM_EVENT_ON) ?
ACPI_STATE_D0 : ACPI_STATE_D3;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 2f1c68c..db90a74 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -376,9 +376,9 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle))
#ifdef CONFIG_PM_SLEEP
-int acpi_pm_device_sleep_state(struct device *, int, int *);
+int acpi_pm_device_sleep_state(struct device *, int *);
#else /* !CONFIG_PM_SLEEP */
-static inline int acpi_pm_device_sleep_state(struct device *d, int w, int *p)
+static inline int acpi_pm_device_sleep_state(struct device *d, int *p)
{
if (p)
*p = ACPI_STATE_D0;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 08/70] PCI ACPI: Drop the second argument of platform_pci_choose_state
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (5 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 07/70] ACPI PM: acpi_pm_device_sleep_state() cleanup Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 09/70] ACPI PM: Remove obsolete Toshiba workaround Len Brown
` (60 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Rafael J. Wysocki, Len Brown
From: Rafael J. Wysocki <rjw@sisk.pl>
Since the second argument of acpi_pci_choose_state() and
platform_pci_choose_state() is never used, remove it.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pci/pci-acpi.c | 3 +--
drivers/pci/pci.c | 4 ++--
drivers/pci/pci.h | 3 +--
3 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index caabf05..dab9d47 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -293,8 +293,7 @@ EXPORT_SYMBOL(pci_osc_control_set);
* choose highest power _SxD or any lower power
*/
-static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev,
- pm_message_t state)
+static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
{
int acpi_state;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e4548ab..75c6023 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -508,7 +508,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
return 0;
}
-pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
+pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev);
/**
* pci_choose_state - Choose the power state of a PCI device
@@ -528,7 +528,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
return PCI_D0;
if (platform_pci_choose_state) {
- ret = platform_pci_choose_state(dev, state);
+ ret = platform_pci_choose_state(dev);
if (ret != PCI_POWER_ERROR)
return ret;
}
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 0a497c1..ff30b3c 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -6,8 +6,7 @@ extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_cleanup_rom(struct pci_dev *dev);
/* Firmware callbacks */
-extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev,
- pm_message_t state);
+extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev);
extern int (*platform_pci_set_power_state)(struct pci_dev *dev,
pci_power_t state);
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 09/70] ACPI PM: Remove obsolete Toshiba workaround
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (6 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 08/70] PCI ACPI: Drop the second argument of platform_pci_choose_state Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 10/70] APM emulation: Notify about all suspend events, not just APM invoked ones (v2) Len Brown
` (59 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Rafael J. Wysocki, Len Brown
From: Rafael J. Wysocki <rjw@sisk.pl>
Remove the obsolete workaround for a Toshiba Satellite 4030cdt
S1 problem from drivers/acpi/sleep/main.c .
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/sleep/main.c | 31 -------------------------------
1 files changed, 0 insertions(+), 31 deletions(-)
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index fbd40e9..0f2caea 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -62,8 +62,6 @@ static u32 acpi_suspend_states[] = {
[PM_SUSPEND_MAX] = ACPI_STATE_S5
};
-static int init_8259A_after_S1;
-
/**
* acpi_suspend_begin - Set the target system sleep state to the state
* associated with given @pm_state, if supported.
@@ -186,13 +184,6 @@ static void acpi_suspend_finish(void)
acpi_set_firmware_waking_vector((acpi_physical_address) 0);
acpi_target_sleep_state = ACPI_STATE_S0;
-
-#ifdef CONFIG_X86
- if (init_8259A_after_S1) {
- printk("Broken toshiba laptop -> kicking interrupts\n");
- init_8259A(0);
- }
-#endif
}
/**
@@ -232,26 +223,6 @@ static struct platform_suspend_ops acpi_suspend_ops = {
.finish = acpi_suspend_finish,
.end = acpi_suspend_end,
};
-
-/*
- * Toshiba fails to preserve interrupts over S1, reinitialization
- * of 8259 is needed after S1 resume.
- */
-static int __init init_ints_after_s1(const struct dmi_system_id *d)
-{
- printk(KERN_WARNING "%s with broken S1 detected.\n", d->ident);
- init_8259A_after_S1 = 1;
- return 0;
-}
-
-static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
- {
- .callback = init_ints_after_s1,
- .ident = "Toshiba Satellite 4030cdt",
- .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
- },
- {},
-};
#endif /* CONFIG_SUSPEND */
#ifdef CONFIG_HIBERNATION
@@ -473,8 +444,6 @@ int __init acpi_sleep_init(void)
u8 type_a, type_b;
#ifdef CONFIG_SUSPEND
int i = 0;
-
- dmi_check_system(acpisleep_dmi_table);
#endif
if (acpi_disabled)
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 10/70] APM emulation: Notify about all suspend events, not just APM invoked ones (v2)
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (7 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 09/70] ACPI PM: Remove obsolete Toshiba workaround Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 11/70] Freezer: Introduce PF_FREEZER_NOSIG Len Brown
` (58 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Johannes Berg, Rafael J. Wysocki, Len Brown
From: Johannes Berg <johannes@sipsolutions.net>
This revamps the apm-emulation code to get suspend notifications
regardless of what way pm_suspend() was invoked, whether via the
apm ioctl or via /sys/power/state. Also do some code cleanup and
add comments while at it.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/char/apm-emulation.c | 346 +++++++++++++++++++++++++-----------------
1 files changed, 207 insertions(+), 139 deletions(-)
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c
index cdd876d..97e434e 100644
--- a/drivers/char/apm-emulation.c
+++ b/drivers/char/apm-emulation.c
@@ -58,6 +58,55 @@ struct apm_queue {
};
/*
+ * thread states (for threads using a writable /dev/apm_bios fd):
+ *
+ * SUSPEND_NONE: nothing happening
+ * SUSPEND_PENDING: suspend event queued for thread and pending to be read
+ * SUSPEND_READ: suspend event read, pending acknowledgement
+ * SUSPEND_ACKED: acknowledgement received from thread (via ioctl),
+ * waiting for resume
+ * SUSPEND_ACKTO: acknowledgement timeout
+ * SUSPEND_DONE: thread had acked suspend and is now notified of
+ * resume
+ *
+ * SUSPEND_WAIT: this thread invoked suspend and is waiting for resume
+ *
+ * A thread migrates in one of three paths:
+ * NONE -1-> PENDING -2-> READ -3-> ACKED -4-> DONE -5-> NONE
+ * -6-> ACKTO -7-> NONE
+ * NONE -8-> WAIT -9-> NONE
+ *
+ * While in PENDING or READ, the thread is accounted for in the
+ * suspend_acks_pending counter.
+ *
+ * The transitions are invoked as follows:
+ * 1: suspend event is signalled from the core PM code
+ * 2: the suspend event is read from the fd by the userspace thread
+ * 3: userspace thread issues the APM_IOC_SUSPEND ioctl (as ack)
+ * 4: core PM code signals that we have resumed
+ * 5: APM_IOC_SUSPEND ioctl returns
+ *
+ * 6: the notifier invoked from the core PM code timed out waiting
+ * for all relevant threds to enter ACKED state and puts those
+ * that haven't into ACKTO
+ * 7: those threads issue APM_IOC_SUSPEND ioctl too late,
+ * get an error
+ *
+ * 8: userspace thread issues the APM_IOC_SUSPEND ioctl (to suspend),
+ * ioctl code invokes pm_suspend()
+ * 9: pm_suspend() returns indicating resume
+ */
+enum apm_suspend_state {
+ SUSPEND_NONE,
+ SUSPEND_PENDING,
+ SUSPEND_READ,
+ SUSPEND_ACKED,
+ SUSPEND_ACKTO,
+ SUSPEND_WAIT,
+ SUSPEND_DONE,
+};
+
+/*
* The per-file APM data
*/
struct apm_user {
@@ -68,13 +117,7 @@ struct apm_user {
unsigned int reader: 1;
int suspend_result;
- unsigned int suspend_state;
-#define SUSPEND_NONE 0 /* no suspend pending */
-#define SUSPEND_PENDING 1 /* suspend pending read */
-#define SUSPEND_READ 2 /* suspend read, pending ack */
-#define SUSPEND_ACKED 3 /* suspend acked */
-#define SUSPEND_WAIT 4 /* waiting for suspend */
-#define SUSPEND_DONE 5 /* suspend completed */
+ enum apm_suspend_state suspend_state;
struct apm_queue queue;
};
@@ -82,7 +125,8 @@ struct apm_user {
/*
* Local variables
*/
-static int suspends_pending;
+static atomic_t suspend_acks_pending = ATOMIC_INIT(0);
+static atomic_t userspace_notification_inhibit = ATOMIC_INIT(0);
static int apm_disabled;
static struct task_struct *kapmd_tsk;
@@ -165,78 +209,6 @@ static void queue_event(apm_event_t event)
wake_up_interruptible(&apm_waitqueue);
}
-/*
- * queue_suspend_event - queue an APM suspend event.
- *
- * Check that we're in a state where we can suspend. If not,
- * return -EBUSY. Otherwise, queue an event to all "writer"
- * users. If there are no "writer" users, return '1' to
- * indicate that we can immediately suspend.
- */
-static int queue_suspend_event(apm_event_t event, struct apm_user *sender)
-{
- struct apm_user *as;
- int ret = 1;
-
- mutex_lock(&state_lock);
- down_read(&user_list_lock);
-
- /*
- * If a thread is still processing, we can't suspend, so reject
- * the request.
- */
- list_for_each_entry(as, &apm_user_list, list) {
- if (as != sender && as->reader && as->writer && as->suser &&
- as->suspend_state != SUSPEND_NONE) {
- ret = -EBUSY;
- goto out;
- }
- }
-
- list_for_each_entry(as, &apm_user_list, list) {
- if (as != sender && as->reader && as->writer && as->suser) {
- as->suspend_state = SUSPEND_PENDING;
- suspends_pending++;
- queue_add_event(&as->queue, event);
- ret = 0;
- }
- }
- out:
- up_read(&user_list_lock);
- mutex_unlock(&state_lock);
- wake_up_interruptible(&apm_waitqueue);
- return ret;
-}
-
-static void apm_suspend(void)
-{
- struct apm_user *as;
- int err = pm_suspend(PM_SUSPEND_MEM);
-
- /*
- * Anyone on the APM queues will think we're still suspended.
- * Send a message so everyone knows we're now awake again.
- */
- queue_event(APM_NORMAL_RESUME);
-
- /*
- * Finally, wake up anyone who is sleeping on the suspend.
- */
- mutex_lock(&state_lock);
- down_read(&user_list_lock);
- list_for_each_entry(as, &apm_user_list, list) {
- if (as->suspend_state == SUSPEND_WAIT ||
- as->suspend_state == SUSPEND_ACKED) {
- as->suspend_result = err;
- as->suspend_state = SUSPEND_DONE;
- }
- }
- up_read(&user_list_lock);
- mutex_unlock(&state_lock);
-
- wake_up(&apm_suspend_waitqueue);
-}
-
static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
{
struct apm_user *as = fp->private_data;
@@ -307,25 +279,22 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
as->suspend_result = -EINTR;
- if (as->suspend_state == SUSPEND_READ) {
- int pending;
-
+ switch (as->suspend_state) {
+ case SUSPEND_READ:
/*
* If we read a suspend command from /dev/apm_bios,
* then the corresponding APM_IOC_SUSPEND ioctl is
* interpreted as an acknowledge.
*/
as->suspend_state = SUSPEND_ACKED;
- suspends_pending--;
- pending = suspends_pending == 0;
+ atomic_dec(&suspend_acks_pending);
mutex_unlock(&state_lock);
/*
- * If there are no further acknowledges required,
- * suspend the system.
+ * suspend_acks_pending changed, the notifier needs to
+ * be woken up for this
*/
- if (pending)
- apm_suspend();
+ wake_up(&apm_suspend_waitqueue);
/*
* Wait for the suspend/resume to complete. If there
@@ -341,35 +310,21 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
* try_to_freeze() in freezer_count() will not trigger
*/
freezer_count();
- } else {
+ break;
+ case SUSPEND_ACKTO:
+ as->suspend_result = -ETIMEDOUT;
+ mutex_unlock(&state_lock);
+ break;
+ default:
as->suspend_state = SUSPEND_WAIT;
mutex_unlock(&state_lock);
/*
* Otherwise it is a request to suspend the system.
- * Queue an event for all readers, and expect an
- * acknowledge from all writers who haven't already
- * acknowledged.
- */
- err = queue_suspend_event(APM_USER_SUSPEND, as);
- if (err < 0) {
- /*
- * Avoid taking the lock here - this
- * should be fine.
- */
- as->suspend_state = SUSPEND_NONE;
- break;
- }
-
- if (err > 0)
- apm_suspend();
-
- /*
- * Wait for the suspend/resume to complete. If there
- * are pending acknowledges, we wait here for them.
+ * Just invoke pm_suspend(), we'll handle it from
+ * there via the notifier.
*/
- wait_event_freezable(apm_suspend_waitqueue,
- as->suspend_state == SUSPEND_DONE);
+ as->suspend_result = pm_suspend(PM_SUSPEND_MEM);
}
mutex_lock(&state_lock);
@@ -385,7 +340,6 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
static int apm_release(struct inode * inode, struct file * filp)
{
struct apm_user *as = filp->private_data;
- int pending = 0;
filp->private_data = NULL;
@@ -395,18 +349,15 @@ static int apm_release(struct inode * inode, struct file * filp)
/*
* We are now unhooked from the chain. As far as new
- * events are concerned, we no longer exist. However, we
- * need to balance suspends_pending, which means the
- * possibility of sleeping.
+ * events are concerned, we no longer exist.
*/
mutex_lock(&state_lock);
- if (as->suspend_state != SUSPEND_NONE) {
- suspends_pending -= 1;
- pending = suspends_pending == 0;
- }
+ if (as->suspend_state == SUSPEND_PENDING ||
+ as->suspend_state == SUSPEND_READ)
+ atomic_dec(&suspend_acks_pending);
mutex_unlock(&state_lock);
- if (pending)
- apm_suspend();
+
+ wake_up(&apm_suspend_waitqueue);
kfree(as);
return 0;
@@ -542,7 +493,6 @@ static int kapmd(void *arg)
{
do {
apm_event_t event;
- int ret;
wait_event_interruptible(kapmd_wait,
!queue_empty(&kapmd_queue) || kthread_should_stop());
@@ -567,20 +517,13 @@ static int kapmd(void *arg)
case APM_USER_SUSPEND:
case APM_SYS_SUSPEND:
- ret = queue_suspend_event(event, NULL);
- if (ret < 0) {
- /*
- * We were busy. Try again in 50ms.
- */
- queue_add_event(&kapmd_queue, event);
- msleep(50);
- }
- if (ret > 0)
- apm_suspend();
+ pm_suspend(PM_SUSPEND_MEM);
break;
case APM_CRITICAL_SUSPEND:
- apm_suspend();
+ atomic_inc(&userspace_notification_inhibit);
+ pm_suspend(PM_SUSPEND_MEM);
+ atomic_dec(&userspace_notification_inhibit);
break;
}
} while (1);
@@ -588,6 +531,120 @@ static int kapmd(void *arg)
return 0;
}
+static int apm_suspend_notifier(struct notifier_block *nb,
+ unsigned long event,
+ void *dummy)
+{
+ struct apm_user *as;
+ int err;
+
+ /* short-cut emergency suspends */
+ if (atomic_read(&userspace_notification_inhibit))
+ return NOTIFY_DONE;
+
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ /*
+ * Queue an event to all "writer" users that we want
+ * to suspend and need their ack.
+ */
+ mutex_lock(&state_lock);
+ down_read(&user_list_lock);
+
+ list_for_each_entry(as, &apm_user_list, list) {
+ if (as->suspend_state != SUSPEND_WAIT && as->reader &&
+ as->writer && as->suser) {
+ as->suspend_state = SUSPEND_PENDING;
+ atomic_inc(&suspend_acks_pending);
+ queue_add_event(&as->queue, APM_USER_SUSPEND);
+ }
+ }
+
+ up_read(&user_list_lock);
+ mutex_unlock(&state_lock);
+ wake_up_interruptible(&apm_waitqueue);
+
+ /*
+ * Wait for the the suspend_acks_pending variable to drop to
+ * zero, meaning everybody acked the suspend event (or the
+ * process was killed.)
+ *
+ * If the app won't answer within a short while we assume it
+ * locked up and ignore it.
+ */
+ err = wait_event_interruptible_timeout(
+ apm_suspend_waitqueue,
+ atomic_read(&suspend_acks_pending) == 0,
+ 5*HZ);
+
+ /* timed out */
+ if (err == 0) {
+ /*
+ * Move anybody who timed out to "ack timeout" state.
+ *
+ * We could time out and the userspace does the ACK
+ * right after we time out but before we enter the
+ * locked section here, but that's fine.
+ */
+ mutex_lock(&state_lock);
+ down_read(&user_list_lock);
+ list_for_each_entry(as, &apm_user_list, list) {
+ if (as->suspend_state == SUSPEND_PENDING ||
+ as->suspend_state == SUSPEND_READ) {
+ as->suspend_state = SUSPEND_ACKTO;
+ atomic_dec(&suspend_acks_pending);
+ }
+ }
+ up_read(&user_list_lock);
+ mutex_unlock(&state_lock);
+ }
+
+ /* let suspend proceed */
+ if (err >= 0)
+ return NOTIFY_OK;
+
+ /* interrupted by signal */
+ return NOTIFY_BAD;
+
+ case PM_POST_SUSPEND:
+ /*
+ * Anyone on the APM queues will think we're still suspended.
+ * Send a message so everyone knows we're now awake again.
+ */
+ queue_event(APM_NORMAL_RESUME);
+
+ /*
+ * Finally, wake up anyone who is sleeping on the suspend.
+ */
+ mutex_lock(&state_lock);
+ down_read(&user_list_lock);
+ list_for_each_entry(as, &apm_user_list, list) {
+ if (as->suspend_state == SUSPEND_ACKED) {
+ /*
+ * TODO: maybe grab error code, needs core
+ * changes to push the error to the notifier
+ * chain (could use the second parameter if
+ * implemented)
+ */
+ as->suspend_result = 0;
+ as->suspend_state = SUSPEND_DONE;
+ }
+ }
+ up_read(&user_list_lock);
+ mutex_unlock(&state_lock);
+
+ wake_up(&apm_suspend_waitqueue);
+ return NOTIFY_OK;
+
+ default:
+ return NOTIFY_DONE;
+ }
+}
+
+static struct notifier_block apm_notif_block = {
+ .notifier_call = apm_suspend_notifier,
+};
+
static int __init apm_init(void)
{
int ret;
@@ -601,7 +658,7 @@ static int __init apm_init(void)
if (IS_ERR(kapmd_tsk)) {
ret = PTR_ERR(kapmd_tsk);
kapmd_tsk = NULL;
- return ret;
+ goto out;
}
wake_up_process(kapmd_tsk);
@@ -610,16 +667,27 @@ static int __init apm_init(void)
#endif
ret = misc_register(&apm_device);
- if (ret != 0) {
- remove_proc_entry("apm", NULL);
- kthread_stop(kapmd_tsk);
- }
+ if (ret)
+ goto out_stop;
+ ret = register_pm_notifier(&apm_notif_block);
+ if (ret)
+ goto out_unregister;
+
+ return 0;
+
+ out_unregister:
+ misc_deregister(&apm_device);
+ out_stop:
+ remove_proc_entry("apm", NULL);
+ kthread_stop(kapmd_tsk);
+ out:
return ret;
}
static void __exit apm_exit(void)
{
+ unregister_pm_notifier(&apm_notif_block);
misc_deregister(&apm_device);
remove_proc_entry("apm", NULL);
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 11/70] Freezer: Introduce PF_FREEZER_NOSIG
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (8 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 10/70] APM emulation: Notify about all suspend events, not just APM invoked ones (v2) Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 12/70] snapshot: Push BKL down into ioctl handlers Len Brown
` (57 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Rafael J. Wysocki, Len Brown
From: Rafael J. Wysocki <rjw@sisk.pl>
The freezer currently attempts to distinguish kernel threads from
user space tasks by checking if their mm pointer is unset and it
does not send fake signals to kernel threads. However, there are
kernel threads, mostly related to networking, that behave like
user space tasks and may want to be sent a fake signal to be frozen.
Introduce the new process flag PF_FREEZER_NOSIG that will be set
by default for all kernel threads and make the freezer only send
fake signals to the tasks having PF_FREEZER_NOSIG unset. Provide
the set_freezable_with_signal() function to be called by the kernel
threads that want to be sent a fake signal for freezing.
This patch should not change the freezer's observable behavior.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
---
include/linux/freezer.h | 10 +++++
include/linux/sched.h | 1 +
kernel/kthread.c | 2 +-
kernel/power/process.c | 97 ++++++++++++++++++++--------------------------
4 files changed, 54 insertions(+), 56 deletions(-)
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index 0893499..deddeed 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -128,6 +128,15 @@ static inline void set_freezable(void)
}
/*
+ * Tell the freezer that the current task should be frozen by it and that it
+ * should send a fake signal to the task to freeze it.
+ */
+static inline void set_freezable_with_signal(void)
+{
+ current->flags &= ~(PF_NOFREEZE | PF_FREEZER_NOSIG);
+}
+
+/*
* Freezer-friendly wrappers around wait_event_interruptible() and
* wait_event_interruptible_timeout(), originally defined in <linux/wait.h>
*/
@@ -174,6 +183,7 @@ static inline void freezer_do_not_count(void) {}
static inline void freezer_count(void) {}
static inline int freezer_should_skip(struct task_struct *p) { return 0; }
static inline void set_freezable(void) {}
+static inline void set_freezable_with_signal(void) {}
#define wait_event_freezable(wq, condition) \
wait_event_interruptible(wq, condition)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index ae0be3c..7bfa876 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1507,6 +1507,7 @@ static inline void put_task_struct(struct task_struct *t)
#define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */
#define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */
#define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */
+#define PF_FREEZER_NOSIG 0x80000000 /* Freezer won't send signals to it */
/*
* Only the _current_ task can read/write to tsk->flags, but other
diff --git a/kernel/kthread.c b/kernel/kthread.c
index bd1b9ea..1113e92 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -234,7 +234,7 @@ int kthreadd(void *unused)
set_user_nice(tsk, KTHREAD_NICE_LEVEL);
set_cpus_allowed(tsk, CPU_MASK_ALL);
- current->flags |= PF_NOFREEZE;
+ current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG;
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
diff --git a/kernel/power/process.c b/kernel/power/process.c
index f1d0b34..5fb8765 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -19,9 +19,6 @@
*/
#define TIMEOUT (20 * HZ)
-#define FREEZER_KERNEL_THREADS 0
-#define FREEZER_USER_SPACE 1
-
static inline int freezeable(struct task_struct * p)
{
if ((p == current) ||
@@ -84,63 +81,53 @@ static void fake_signal_wake_up(struct task_struct *p)
spin_unlock_irqrestore(&p->sighand->siglock, flags);
}
-static int has_mm(struct task_struct *p)
+static inline bool should_send_signal(struct task_struct *p)
{
- return (p->mm && !(p->flags & PF_BORROWED_MM));
+ return !(p->flags & PF_FREEZER_NOSIG);
}
/**
* freeze_task - send a freeze request to given task
* @p: task to send the request to
- * @with_mm_only: if set, the request will only be sent if the task has its
- * own mm
- * Return value: 0, if @with_mm_only is set and the task has no mm of its
- * own or the task is frozen, 1, otherwise
+ * @sig_only: if set, the request will only be sent if the task has the
+ * PF_FREEZER_NOSIG flag unset
+ * Return value: 'false', if @sig_only is set and the task has
+ * PF_FREEZER_NOSIG set or the task is frozen, 'true', otherwise
*
- * The freeze request is sent by seting the tasks's TIF_FREEZE flag and
+ * The freeze request is sent by setting the tasks's TIF_FREEZE flag and
* either sending a fake signal to it or waking it up, depending on whether
- * or not it has its own mm (ie. it is a user land task). If @with_mm_only
- * is set and the task has no mm of its own (ie. it is a kernel thread),
- * its TIF_FREEZE flag should not be set.
- *
- * The task_lock() is necessary to prevent races with exit_mm() or
- * use_mm()/unuse_mm() from occuring.
+ * or not it has PF_FREEZER_NOSIG set. If @sig_only is set and the task
+ * has PF_FREEZER_NOSIG set (ie. it is a typical kernel thread), its
+ * TIF_FREEZE flag will not be set.
*/
-static int freeze_task(struct task_struct *p, int with_mm_only)
+static bool freeze_task(struct task_struct *p, bool sig_only)
{
- int ret = 1;
+ /*
+ * We first check if the task is freezing and next if it has already
+ * been frozen to avoid the race with frozen_process() which first marks
+ * the task as frozen and next clears its TIF_FREEZE.
+ */
+ if (!freezing(p)) {
+ rmb();
+ if (frozen(p))
+ return false;
- task_lock(p);
- if (freezing(p)) {
- if (has_mm(p)) {
- if (!signal_pending(p))
- fake_signal_wake_up(p);
- } else {
- if (with_mm_only)
- ret = 0;
- else
- wake_up_state(p, TASK_INTERRUPTIBLE);
- }
+ if (!sig_only || should_send_signal(p))
+ set_freeze_flag(p);
+ else
+ return false;
+ }
+
+ if (should_send_signal(p)) {
+ if (!signal_pending(p))
+ fake_signal_wake_up(p);
+ } else if (sig_only) {
+ return false;
} else {
- rmb();
- if (frozen(p)) {
- ret = 0;
- } else {
- if (has_mm(p)) {
- set_freeze_flag(p);
- fake_signal_wake_up(p);
- } else {
- if (with_mm_only) {
- ret = 0;
- } else {
- set_freeze_flag(p);
- wake_up_state(p, TASK_INTERRUPTIBLE);
- }
- }
- }
+ wake_up_state(p, TASK_INTERRUPTIBLE);
}
- task_unlock(p);
- return ret;
+
+ return true;
}
static void cancel_freezing(struct task_struct *p)
@@ -156,7 +143,7 @@ static void cancel_freezing(struct task_struct *p)
}
}
-static int try_to_freeze_tasks(int freeze_user_space)
+static int try_to_freeze_tasks(bool sig_only)
{
struct task_struct *g, *p;
unsigned long end_time;
@@ -175,7 +162,7 @@ static int try_to_freeze_tasks(int freeze_user_space)
if (frozen(p) || !freezeable(p))
continue;
- if (!freeze_task(p, freeze_user_space))
+ if (!freeze_task(p, sig_only))
continue;
/*
@@ -235,13 +222,13 @@ int freeze_processes(void)
int error;
printk("Freezing user space processes ... ");
- error = try_to_freeze_tasks(FREEZER_USER_SPACE);
+ error = try_to_freeze_tasks(true);
if (error)
goto Exit;
printk("done.\n");
printk("Freezing remaining freezable tasks ... ");
- error = try_to_freeze_tasks(FREEZER_KERNEL_THREADS);
+ error = try_to_freeze_tasks(false);
if (error)
goto Exit;
printk("done.");
@@ -251,7 +238,7 @@ int freeze_processes(void)
return error;
}
-static void thaw_tasks(int thaw_user_space)
+static void thaw_tasks(bool nosig_only)
{
struct task_struct *g, *p;
@@ -260,7 +247,7 @@ static void thaw_tasks(int thaw_user_space)
if (!freezeable(p))
continue;
- if (!p->mm == thaw_user_space)
+ if (nosig_only && should_send_signal(p))
continue;
thaw_process(p);
@@ -271,8 +258,8 @@ static void thaw_tasks(int thaw_user_space)
void thaw_processes(void)
{
printk("Restarting tasks ... ");
- thaw_tasks(FREEZER_KERNEL_THREADS);
- thaw_tasks(FREEZER_USER_SPACE);
+ thaw_tasks(true);
+ thaw_tasks(false);
schedule();
printk("done.\n");
}
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 12/70] snapshot: Push BKL down into ioctl handlers
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (9 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 11/70] Freezer: Introduce PF_FREEZER_NOSIG Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 13/70] snapshot: Use pm_mutex for mutual exclusion Len Brown
` (56 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Alan Cox, Rafael J. Wysocki, Len Brown
From: Alan Cox <alan@redhat.com>
Push BKL down into ioctl handlers - snapshot device.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
---
kernel/power/user.c | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/kernel/power/user.c b/kernel/power/user.c
index f5512cb..658262b 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -23,6 +23,7 @@
#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/freezer.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -164,8 +165,8 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
return res;
}
-static int snapshot_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static long snapshot_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
{
int error = 0;
struct snapshot_data *data;
@@ -181,6 +182,8 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
data = filp->private_data;
+ lock_kernel();
+
switch (cmd) {
case SNAPSHOT_FREEZE:
@@ -389,7 +392,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
error = -ENOTTY;
}
-
+ unlock_kernel();
return error;
}
@@ -399,7 +402,7 @@ static const struct file_operations snapshot_fops = {
.read = snapshot_read,
.write = snapshot_write,
.llseek = no_llseek,
- .ioctl = snapshot_ioctl,
+ .unlocked_ioctl = snapshot_ioctl,
};
static struct miscdevice snapshot_device = {
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 13/70] snapshot: Use pm_mutex for mutual exclusion
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (10 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 12/70] snapshot: Push BKL down into ioctl handlers Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 14/70] ACPICA: Add argument count checking to control method invocation via acpi_evaluate_object Len Brown
` (55 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Rafael J. Wysocki, Len Brown
From: Rafael J. Wysocki <rjw@sisk.pl>
We can avoid taking the BKL in snapshot_ioctl() if pm_mutex is used to prevent
the ioctls from being executed concurrently.
In addition, although it is only possible to open /dev/snapshot once, the task
which has done that may spawn a child that will inherit the open descriptor,
so in theory they can call snapshot_write(), snapshot_read() and
snapshot_release() concurrently. pm_mutex can also be used for mutual
exclusion in such cases.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
---
kernel/power/user.c | 68 +++++++++++++++++++++++++++++++-------------------
1 files changed, 42 insertions(+), 26 deletions(-)
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 658262b..a6332a3 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -70,16 +70,22 @@ static int snapshot_open(struct inode *inode, struct file *filp)
struct snapshot_data *data;
int error;
- if (!atomic_add_unless(&snapshot_device_available, -1, 0))
- return -EBUSY;
+ mutex_lock(&pm_mutex);
+
+ if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
+ error = -EBUSY;
+ goto Unlock;
+ }
if ((filp->f_flags & O_ACCMODE) == O_RDWR) {
atomic_inc(&snapshot_device_available);
- return -ENOSYS;
+ error = -ENOSYS;
+ goto Unlock;
}
if(create_basic_memory_bitmaps()) {
atomic_inc(&snapshot_device_available);
- return -ENOMEM;
+ error = -ENOMEM;
+ goto Unlock;
}
nonseekable_open(inode, filp);
data = &snapshot_state;
@@ -99,33 +105,36 @@ static int snapshot_open(struct inode *inode, struct file *filp)
if (error)
pm_notifier_call_chain(PM_POST_HIBERNATION);
}
- if (error) {
+ if (error)
atomic_inc(&snapshot_device_available);
- return error;
- }
data->frozen = 0;
data->ready = 0;
data->platform_support = 0;
- return 0;
+ Unlock:
+ mutex_unlock(&pm_mutex);
+
+ return error;
}
static int snapshot_release(struct inode *inode, struct file *filp)
{
struct snapshot_data *data;
+ mutex_lock(&pm_mutex);
+
swsusp_free();
free_basic_memory_bitmaps();
data = filp->private_data;
free_all_swap_pages(data->swap);
- if (data->frozen) {
- mutex_lock(&pm_mutex);
+ if (data->frozen)
thaw_processes();
- mutex_unlock(&pm_mutex);
- }
pm_notifier_call_chain(data->mode == O_WRONLY ?
PM_POST_HIBERNATION : PM_POST_RESTORE);
atomic_inc(&snapshot_device_available);
+
+ mutex_unlock(&pm_mutex);
+
return 0;
}
@@ -135,9 +144,13 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf,
struct snapshot_data *data;
ssize_t res;
+ mutex_lock(&pm_mutex);
+
data = filp->private_data;
- if (!data->ready)
- return -ENODATA;
+ if (!data->ready) {
+ res = -ENODATA;
+ goto Unlock;
+ }
res = snapshot_read_next(&data->handle, count);
if (res > 0) {
if (copy_to_user(buf, data_of(data->handle), res))
@@ -145,6 +158,10 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf,
else
*offp = data->handle.offset;
}
+
+ Unlock:
+ mutex_unlock(&pm_mutex);
+
return res;
}
@@ -154,6 +171,8 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
struct snapshot_data *data;
ssize_t res;
+ mutex_lock(&pm_mutex);
+
data = filp->private_data;
res = snapshot_write_next(&data->handle, count);
if (res > 0) {
@@ -162,6 +181,9 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
else
*offp = data->handle.offset;
}
+
+ mutex_unlock(&pm_mutex);
+
return res;
}
@@ -180,16 +202,16 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- data = filp->private_data;
+ if (!mutex_trylock(&pm_mutex))
+ return -EBUSY;
- lock_kernel();
+ data = filp->private_data;
switch (cmd) {
case SNAPSHOT_FREEZE:
if (data->frozen)
break;
- mutex_lock(&pm_mutex);
printk("Syncing filesystems ... ");
sys_sync();
printk("done.\n");
@@ -197,7 +219,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
error = freeze_processes();
if (error)
thaw_processes();
- mutex_unlock(&pm_mutex);
if (!error)
data->frozen = 1;
break;
@@ -205,9 +226,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
case SNAPSHOT_UNFREEZE:
if (!data->frozen || data->ready)
break;
- mutex_lock(&pm_mutex);
thaw_processes();
- mutex_unlock(&pm_mutex);
data->frozen = 0;
break;
@@ -310,16 +329,11 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
error = -EPERM;
break;
}
- if (!mutex_trylock(&pm_mutex)) {
- error = -EBUSY;
- break;
- }
/*
* Tasks are frozen and the notifiers have been called with
* PM_HIBERNATION_PREPARE
*/
error = suspend_devices_and_enter(PM_SUSPEND_MEM);
- mutex_unlock(&pm_mutex);
break;
case SNAPSHOT_PLATFORM_SUPPORT:
@@ -392,7 +406,9 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
error = -ENOTTY;
}
- unlock_kernel();
+
+ mutex_unlock(&pm_mutex);
+
return error;
}
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 14/70] ACPICA: Add argument count checking to control method invocation via acpi_evaluate_object
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (11 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 13/70] snapshot: Use pm_mutex for mutual exclusion Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 15/70] ACPICA: Fix for hang on GPE method invocation Len Brown
` (54 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
Error if too few arguments, warning if too many. This applies
only to external programmatic control method execution, not
method-to-method calls within the AML.
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/namespace/nseval.c | 35 +++++++++++++++++++++++++++++++++++
include/acpi/acexcep.h | 6 ++++--
include/acpi/acstruct.h | 1 +
3 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index 14bdfa9..d369164 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -138,6 +138,41 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
return_ACPI_STATUS(AE_NULL_OBJECT);
}
+ /*
+ * Calculate the number of arguments being passed to the method
+ */
+
+ info->param_count = 0;
+ if (info->parameters) {
+ while (info->parameters[info->param_count])
+ info->param_count++;
+ }
+
+ /* Error if too few arguments were passed in */
+
+ if (info->param_count < info->obj_desc->method.param_count) {
+ ACPI_ERROR((AE_INFO,
+ "Insufficient arguments - "
+ "method [%4.4s] needs %d, found %d",
+ acpi_ut_get_node_name(info->resolved_node),
+ info->obj_desc->method.param_count,
+ info->param_count));
+ return_ACPI_STATUS(AE_MISSING_ARGUMENTS);
+ }
+
+ /* Just a warning if too many arguments */
+
+ else if (info->param_count >
+ info->obj_desc->method.param_count) {
+ ACPI_WARNING((AE_INFO,
+ "Excess arguments - "
+ "method [%4.4s] needs %d, found %d",
+ acpi_ut_get_node_name(info->
+ resolved_node),
+ info->obj_desc->method.param_count,
+ info->param_count));
+ }
+
ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:",
ACPI_LV_INFO, _COMPONENT);
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index 1f59117..9c76c18 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -108,8 +108,9 @@
#define AE_BAD_HEX_CONSTANT (acpi_status) (0x0007 | AE_CODE_PROGRAMMER)
#define AE_BAD_OCTAL_CONSTANT (acpi_status) (0x0008 | AE_CODE_PROGRAMMER)
#define AE_BAD_DECIMAL_CONSTANT (acpi_status) (0x0009 | AE_CODE_PROGRAMMER)
+#define AE_MISSING_ARGUMENTS (acpi_status) (0x000A | AE_CODE_PROGRAMMER)
-#define AE_CODE_PGM_MAX 0x0009
+#define AE_CODE_PGM_MAX 0x000A
/*
* Acpi table exceptions
@@ -233,7 +234,8 @@ char const *acpi_gbl_exception_names_pgm[] = {
"AE_ALIGNMENT",
"AE_BAD_HEX_CONSTANT",
"AE_BAD_OCTAL_CONSTANT",
- "AE_BAD_DECIMAL_CONSTANT"
+ "AE_BAD_DECIMAL_CONSTANT",
+ "AE_MISSING_ARGUMENTS"
};
char const *acpi_gbl_exception_names_tbl[] = {
diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h
index a907c67..1cc7450 100644
--- a/include/acpi/acstruct.h
+++ b/include/acpi/acstruct.h
@@ -189,6 +189,7 @@ struct acpi_evaluate_info {
union acpi_operand_object **parameters;
struct acpi_namespace_node *resolved_node;
union acpi_operand_object *return_object;
+ u8 param_count;
u8 pass_number;
u8 parameter_type;
u8 return_object_type;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 15/70] ACPICA: Fix for hang on GPE method invocation
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (12 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 14/70] ACPICA: Add argument count checking to control method invocation via acpi_evaluate_object Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 16/70] ACPICA: Update tracking macros to reduce code/data size Len Brown
` (53 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
Fixes problem where the new method argument count validation mechanism
will enter an infinite loop when a GPE method is dispatched.
Problem fixed be removing the obsolete code that passes GPE block
information to the notify handler via the control method parameter pointer.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/dispatcher/dsmethod.c | 1 -
drivers/acpi/dispatcher/dswstate.c | 10 ++--------
drivers/acpi/events/evgpe.c | 4 ----
drivers/acpi/events/evregion.c | 1 -
drivers/acpi/namespace/nsinit.c | 1 -
drivers/acpi/namespace/nsxfeval.c | 1 -
drivers/acpi/parser/psxface.c | 2 +-
drivers/acpi/resources/rsutils.c | 1 -
drivers/acpi/utilities/uteval.c | 1 -
include/acpi/acstruct.h | 7 -------
10 files changed, 3 insertions(+), 26 deletions(-)
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 2509809..4613b9c 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -377,7 +377,6 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
}
info->parameters = &this_walk_state->operands[0];
- info->parameter_type = ACPI_PARAM_ARGS;
status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node,
obj_desc->method.aml_start,
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
index 1386ced..bda23ed 100644
--- a/drivers/acpi/dispatcher/dswstate.c
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -615,14 +615,8 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
walk_state->pass_number = pass_number;
if (info) {
- if (info->parameter_type == ACPI_PARAM_GPE) {
- walk_state->gpe_event_info =
- ACPI_CAST_PTR(struct acpi_gpe_event_info,
- info->parameters);
- } else {
- walk_state->params = info->parameters;
- walk_state->caller_return_desc = &info->return_object;
- }
+ walk_state->params = info->parameters;
+ walk_state->caller_return_desc = &info->return_object;
}
status = acpi_ps_init_scope(&walk_state->parser_state, op);
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index 5354be4..a68ec0c 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -555,10 +555,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
*/
info->prefix_node =
local_gpe_event_info.dispatch.method_node;
- info->parameters =
- ACPI_CAST_PTR(union acpi_operand_object *,
- gpe_event_info);
- info->parameter_type = ACPI_PARAM_GPE;
info->flags = ACPI_IGNORE_RETURN_VALUE;
status = acpi_ns_evaluate(info);
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index 1628f59..5ab4c01 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -219,7 +219,6 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
info->prefix_node = region_obj2->extra.method_REG;
info->pathname = NULL;
info->parameters = args;
- info->parameter_type = ACPI_PARAM_ARGS;
info->flags = ACPI_IGNORE_RETURN_VALUE;
/*
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index 6d6d930..e4c5751 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -542,7 +542,6 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
info->prefix_node = device_node;
info->pathname = METHOD_NAME__INI;
info->parameters = NULL;
- info->parameter_type = ACPI_PARAM_ARGS;
info->flags = ACPI_IGNORE_RETURN_VALUE;
/*
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index a8d5491..b4e135e 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -182,7 +182,6 @@ acpi_evaluate_object(acpi_handle handle,
}
info->pathname = pathname;
- info->parameter_type = ACPI_PARAM_ARGS;
/* Convert and validate the device handle */
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index 5258145..5ee09e1 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -335,7 +335,7 @@ acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
{
acpi_native_uint i;
- if ((info->parameter_type == ACPI_PARAM_ARGS) && (info->parameters)) {
+ if (info->parameters) {
/* Update reference count for each parameter */
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index befe230..90ed83d 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -679,7 +679,6 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
info->prefix_node = node;
info->pathname = METHOD_NAME__SRS;
info->parameters = args;
- info->parameter_type = ACPI_PARAM_ARGS;
info->flags = ACPI_IGNORE_RETURN_VALUE;
/*
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index 05e61be..7f1f634 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -217,7 +217,6 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
info->prefix_node = prefix_node;
info->pathname = path;
- info->parameter_type = ACPI_PARAM_ARGS;
/* Evaluate the object/method */
diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h
index 1cc7450..818c24d 100644
--- a/include/acpi/acstruct.h
+++ b/include/acpi/acstruct.h
@@ -108,7 +108,6 @@ struct acpi_walk_state {
union acpi_operand_object **caller_return_desc;
union acpi_generic_state *control_state; /* List of control states (nested IFs) */
struct acpi_namespace_node *deferred_node; /* Used when executing deferred opcodes */
- struct acpi_gpe_event_info *gpe_event_info; /* Info for GPE (_Lxx/_Exx methods only */
union acpi_operand_object *implicit_return_obj;
struct acpi_namespace_node *method_call_node; /* Called method Node */
union acpi_parse_object *method_call_op; /* method_call Op if running a method */
@@ -191,16 +190,10 @@ struct acpi_evaluate_info {
union acpi_operand_object *return_object;
u8 param_count;
u8 pass_number;
- u8 parameter_type;
u8 return_object_type;
u8 flags;
};
-/* Types for parameter_type above */
-
-#define ACPI_PARAM_ARGS 0
-#define ACPI_PARAM_GPE 1
-
/* Values for Flags above */
#define ACPI_IGNORE_RETURN_VALUE 1
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 16/70] ACPICA: Update tracking macros to reduce code/data size
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (13 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 15/70] ACPICA: Fix for hang on GPE method invocation Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 17/70] ACPICA: Fix possible negative array index in acpi_ut_validate_exception Len Brown
` (52 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Jan Beulich, Bob Moore, Lin Ming, Len Brown
From: Jan Beulich <jbeulich@novell.com>
Changed ACPI_MODULE_NAME and ACPI_FUNCTION_NAME to use arrays of
strings instead of pointers to static strings. Jan Beulich and
Bob Moore.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
include/acpi/acmacros.h | 10 ++++------
1 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
index fb41a3b..4e42f67 100644
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -414,7 +414,7 @@ struct acpi_integer_overlay {
* error messages. The __FILE__ macro is not very useful for this, because it
* often includes the entire pathname to the module
*/
-#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR *_acpi_module_name = name;
+#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR _acpi_module_name[] = name;
#else
#define ACPI_MODULE_NAME(name)
#endif
@@ -467,19 +467,17 @@ struct acpi_integer_overlay {
/*
* If ACPI_GET_FUNCTION_NAME was not defined in the compiler-dependent header,
* define it now. This is the case where there the compiler does not support
- * a __FUNCTION__ macro or equivalent. We save the function name on the
- * local stack.
+ * a __FUNCTION__ macro or equivalent.
*/
#ifndef ACPI_GET_FUNCTION_NAME
#define ACPI_GET_FUNCTION_NAME _acpi_function_name
/*
* The Name parameter should be the procedure name as a quoted string.
- * This is declared as a local string ("MyFunctionName") so that it can
- * be also used by the function exit macros below.
+ * The function name is also used by the function exit macros below.
* Note: (const char) is used to be compatible with the debug interfaces
* and macros such as __FUNCTION__.
*/
-#define ACPI_FUNCTION_NAME(name) const char *_acpi_function_name = #name;
+#define ACPI_FUNCTION_NAME(name) static const char _acpi_function_name[] = #name;
#else
/* Compiler supports __FUNCTION__ (or equivalent) -- Ignore this macro */
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 17/70] ACPICA: Fix possible negative array index in acpi_ut_validate_exception
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (14 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 16/70] ACPICA: Update tracking macros to reduce code/data size Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 18/70] ACPICA: Eliminate acpi_native_uint type Len Brown
` (51 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
Added NULL fields to the exception string arrays to eliminate
the -1 subtraction on the SubStatus field.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/utilities/utmisc.c | 14 +++++---------
include/acpi/acexcep.h | 4 ++++
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 1f057b7..47354d9 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -64,7 +64,7 @@ ACPI_MODULE_NAME("utmisc")
******************************************************************************/
const char *acpi_ut_validate_exception(acpi_status status)
{
- acpi_status sub_status;
+ u32 sub_status;
const char *exception = NULL;
ACPI_FUNCTION_ENTRY();
@@ -85,32 +85,28 @@ const char *acpi_ut_validate_exception(acpi_status status)
case AE_CODE_PROGRAMMER:
if (sub_status <= AE_CODE_PGM_MAX) {
- exception =
- acpi_gbl_exception_names_pgm[sub_status - 1];
+ exception = acpi_gbl_exception_names_pgm[sub_status];
}
break;
case AE_CODE_ACPI_TABLES:
if (sub_status <= AE_CODE_TBL_MAX) {
- exception =
- acpi_gbl_exception_names_tbl[sub_status - 1];
+ exception = acpi_gbl_exception_names_tbl[sub_status];
}
break;
case AE_CODE_AML:
if (sub_status <= AE_CODE_AML_MAX) {
- exception =
- acpi_gbl_exception_names_aml[sub_status - 1];
+ exception = acpi_gbl_exception_names_aml[sub_status];
}
break;
case AE_CODE_CONTROL:
if (sub_status <= AE_CODE_CTRL_MAX) {
- exception =
- acpi_gbl_exception_names_ctrl[sub_status - 1];
+ exception = acpi_gbl_exception_names_ctrl[sub_status];
}
break;
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index 9c76c18..772fe06 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -226,6 +226,7 @@ char const *acpi_gbl_exception_names_env[] = {
};
char const *acpi_gbl_exception_names_pgm[] = {
+ NULL,
"AE_BAD_PARAMETER",
"AE_BAD_CHARACTER",
"AE_BAD_PATHNAME",
@@ -239,6 +240,7 @@ char const *acpi_gbl_exception_names_pgm[] = {
};
char const *acpi_gbl_exception_names_tbl[] = {
+ NULL,
"AE_BAD_SIGNATURE",
"AE_BAD_HEADER",
"AE_BAD_CHECKSUM",
@@ -248,6 +250,7 @@ char const *acpi_gbl_exception_names_tbl[] = {
};
char const *acpi_gbl_exception_names_aml[] = {
+ NULL,
"AE_AML_ERROR",
"AE_AML_PARSE",
"AE_AML_BAD_OPCODE",
@@ -285,6 +288,7 @@ char const *acpi_gbl_exception_names_aml[] = {
};
char const *acpi_gbl_exception_names_ctrl[] = {
+ NULL,
"AE_CTRL_RETURN_VALUE",
"AE_CTRL_PENDING",
"AE_CTRL_TERMINATE",
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 18/70] ACPICA: Eliminate acpi_native_uint type
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (15 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 17/70] ACPICA: Fix possible negative array index in acpi_ut_validate_exception Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 19/70] ACPICA: Removed unused include files from source files Len Brown
` (50 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
No longer needed; replaced mostly with u32, but also acpi_size
where a type that changes 32/64 bit on 32/64-bit platforms is
required.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
arch/x86/kernel/srat_32.c | 2 +-
drivers/acpi/bus.c | 2 +-
drivers/acpi/dispatcher/dsinit.c | 2 +-
drivers/acpi/dispatcher/dsopcode.c | 2 +-
drivers/acpi/dispatcher/dswstate.c | 10 +++++-----
drivers/acpi/events/evevent.c | 6 +++---
drivers/acpi/events/evgpe.c | 14 ++++----------
drivers/acpi/events/evgpeblk.c | 18 ++++++++++--------
drivers/acpi/events/evmisc.c | 4 ++--
drivers/acpi/events/evregion.c | 4 ++--
drivers/acpi/events/evrgnini.c | 2 +-
drivers/acpi/executer/exconfig.c | 14 +++++++-------
drivers/acpi/executer/exconvrt.c | 12 ++++++------
drivers/acpi/executer/exdump.c | 2 +-
drivers/acpi/executer/exfldio.c | 9 +++++----
drivers/acpi/executer/exmisc.c | 8 ++++----
drivers/acpi/executer/exregion.c | 2 +-
drivers/acpi/namespace/nsdump.c | 2 +-
drivers/acpi/namespace/nsload.c | 3 +--
drivers/acpi/namespace/nsparse.c | 15 +++++++--------
drivers/acpi/namespace/nsutils.c | 26 ++++++++++++--------------
drivers/acpi/namespace/nsxfeval.c | 2 +-
drivers/acpi/parser/psargs.c | 4 ++--
drivers/acpi/parser/psxface.c | 2 +-
drivers/acpi/resources/rscalc.c | 4 ++--
drivers/acpi/resources/rsmisc.c | 2 +-
drivers/acpi/resources/rsutils.c | 12 ++++++------
drivers/acpi/tables/tbfadt.c | 6 +++---
drivers/acpi/tables/tbfind.c | 5 ++---
drivers/acpi/tables/tbinstal.c | 30 ++++++++++++++----------------
drivers/acpi/tables/tbutils.c | 15 +++++++--------
drivers/acpi/tables/tbxface.c | 28 +++++++++++++---------------
drivers/acpi/tables/tbxfroot.c | 4 ++--
drivers/acpi/utilities/utcopy.c | 4 ++--
drivers/acpi/utilities/utdebug.c | 28 +++++++++++++++++-----------
drivers/acpi/utilities/utdelete.c | 2 +-
drivers/acpi/utilities/uteval.c | 4 ++--
drivers/acpi/utilities/utmisc.c | 14 +++++++-------
drivers/acpi/utilities/utobject.c | 4 ++--
include/acpi/acdispat.h | 2 +-
include/acpi/acglobal.h | 2 +-
include/acpi/acmacros.h | 24 ++++++++++++------------
include/acpi/acnamesp.h | 10 ++++------
include/acpi/acpiosxf.h | 2 +-
include/acpi/acpixf.h | 8 ++++----
include/acpi/acstruct.h | 2 +-
include/acpi/actables.h | 27 ++++++++++++---------------
include/acpi/actypes.h | 16 ++++++----------
include/acpi/acutils.h | 4 ++--
49 files changed, 205 insertions(+), 221 deletions(-)
diff --git a/arch/x86/kernel/srat_32.c b/arch/x86/kernel/srat_32.c
index 70e4a37..a29192f 100644
--- a/arch/x86/kernel/srat_32.c
+++ b/arch/x86/kernel/srat_32.c
@@ -269,7 +269,7 @@ int __init get_memcfg_from_srat(void)
struct acpi_table_header *header = NULL;
struct acpi_table_rsdp *rsdp = NULL;
struct acpi_table_rsdt *rsdt = NULL;
- acpi_native_uint rsdp_address = 0;
+ u32 rsdp_address = 0;
struct acpi_static_rsdt saved_rsdt;
int tables = 0;
int i = 0;
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index a6dbcf4..afb3438 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -612,7 +612,7 @@ static int __init acpi_bus_init_irq(void)
return 0;
}
-acpi_native_uint acpi_gbl_permanent_mmap;
+u8 acpi_gbl_permanent_mmap;
void __init acpi_early_init(void)
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
index 610b1ee..949f7c7 100644
--- a/drivers/acpi/dispatcher/dsinit.c
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -151,7 +151,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
******************************************************************************/
acpi_status
-acpi_ds_initialize_objects(acpi_native_uint table_index,
+acpi_ds_initialize_objects(u32 table_index,
struct acpi_namespace_node * start_node)
{
acpi_status status;
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index a818e0d..ac0bfb1 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -848,7 +848,7 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
union acpi_operand_object **operand;
struct acpi_namespace_node *node;
union acpi_parse_object *next_op;
- acpi_native_uint table_index;
+ u32 table_index;
struct acpi_table_header *table;
ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
index bda23ed..b00d4af 100644
--- a/drivers/acpi/dispatcher/dswstate.c
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -70,7 +70,7 @@ acpi_status
acpi_ds_result_pop(union acpi_operand_object **object,
struct acpi_walk_state *walk_state)
{
- acpi_native_uint index;
+ u32 index;
union acpi_generic_state *state;
acpi_status status;
@@ -122,7 +122,7 @@ acpi_ds_result_pop(union acpi_operand_object **object,
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Obj=%p [%s] Index=%X State=%p Num=%X\n", *object,
acpi_ut_get_object_type_name(*object),
- (u32) index, walk_state, walk_state->result_count));
+ index, walk_state, walk_state->result_count));
return (AE_OK);
}
@@ -146,7 +146,7 @@ acpi_ds_result_push(union acpi_operand_object * object,
{
union acpi_generic_state *state;
acpi_status status;
- acpi_native_uint index;
+ u32 index;
ACPI_FUNCTION_NAME(ds_result_push);
@@ -400,7 +400,7 @@ void
acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
struct acpi_walk_state *walk_state)
{
- acpi_native_int i;
+ s32 i;
union acpi_operand_object *obj_desc;
ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete);
@@ -409,7 +409,7 @@ acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
return;
}
- for (i = (acpi_native_int) (pop_count - 1); i >= 0; i--) {
+ for (i = (s32) pop_count - 1; i >= 0; i--) {
if (walk_state->num_operands == 0) {
return;
}
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index 5d30e5b..c56c5c6 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -188,7 +188,7 @@ acpi_status acpi_ev_install_xrupt_handlers(void)
static acpi_status acpi_ev_fixed_event_initialize(void)
{
- acpi_native_uint i;
+ u32 i;
acpi_status status;
/*
@@ -231,7 +231,7 @@ u32 acpi_ev_fixed_event_detect(void)
u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
u32 fixed_status;
u32 fixed_enable;
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_NAME(ev_fixed_event_detect);
@@ -260,7 +260,7 @@ u32 acpi_ev_fixed_event_detect(void)
/* Found an active (signalled) event */
acpi_os_fixed_event_count(i);
- int_status |= acpi_ev_fixed_event_dispatch((u32) i);
+ int_status |= acpi_ev_fixed_event_dispatch(i);
}
}
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index a68ec0c..2a0014b 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -305,7 +305,7 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
{
union acpi_operand_object *obj_desc;
struct acpi_gpe_block_info *gpe_block;
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_ENTRY();
@@ -379,8 +379,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
u32 status_reg;
u32 enable_reg;
acpi_cpu_flags flags;
- acpi_native_uint i;
- acpi_native_uint j;
+ u32 i;
+ u32 j;
ACPI_FUNCTION_NAME(ev_gpe_detect);
@@ -462,13 +462,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
*/
int_status |=
acpi_ev_gpe_dispatch(&gpe_block->
- event_info[(i *
- ACPI_GPE_REGISTER_WIDTH)
- +
- j],
- (u32) j +
- gpe_register_info->
- base_gpe_number);
+ event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number);
}
}
}
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
index e6c4d4c..73c058e 100644
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -189,8 +189,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block)
{
struct acpi_gpe_event_info *gpe_event_info;
- acpi_native_uint i;
- acpi_native_uint j;
+ u32 i;
+ u32 j;
ACPI_FUNCTION_TRACE(ev_delete_gpe_handlers);
@@ -203,7 +203,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
gpe_event_info =
&gpe_block->
- event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];
+ event_info[((acpi_size) i *
+ ACPI_GPE_REGISTER_WIDTH) + j];
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER) {
@@ -744,8 +745,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
struct acpi_gpe_event_info *gpe_event_info = NULL;
struct acpi_gpe_event_info *this_event;
struct acpi_gpe_register_info *this_register;
- acpi_native_uint i;
- acpi_native_uint j;
+ u32 i;
+ u32 j;
acpi_status status;
ACPI_FUNCTION_TRACE(ev_create_gpe_info_blocks);
@@ -983,8 +984,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
struct acpi_gpe_walk_info gpe_info;
u32 wake_gpe_count;
u32 gpe_enabled_count;
- acpi_native_uint i;
- acpi_native_uint j;
+ u32 i;
+ u32 j;
ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);
@@ -1033,7 +1034,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
gpe_event_info =
&gpe_block->
- event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];
+ event_info[((acpi_size) i *
+ ACPI_GPE_REGISTER_WIDTH) + j];
if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_METHOD)
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 2113e58..1d5670b 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -575,7 +575,7 @@ acpi_status acpi_ev_release_global_lock(void)
void acpi_ev_terminate(void)
{
- acpi_native_uint i;
+ u32 i;
acpi_status status;
ACPI_FUNCTION_TRACE(ev_terminate);
@@ -589,7 +589,7 @@ void acpi_ev_terminate(void)
/* Disable all fixed events */
for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
- status = acpi_disable_event((u32) i, 0);
+ status = acpi_disable_event(i, 0);
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO,
"Could not disable fixed event %d",
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index 5ab4c01..236fbd1 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -81,7 +81,7 @@ acpi_ev_install_handler(acpi_handle obj_handle,
acpi_status acpi_ev_install_region_handlers(void)
{
acpi_status status;
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_TRACE(ev_install_region_handlers);
@@ -151,7 +151,7 @@ acpi_status acpi_ev_install_region_handlers(void)
acpi_status acpi_ev_initialize_op_regions(void)
{
acpi_status status;
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_TRACE(ev_initialize_op_regions);
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index 2e3d2c5..6b94b38 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -380,7 +380,7 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
acpi_status status;
struct acpica_device_id hid;
struct acpi_compatible_id_list *cid;
- acpi_native_uint i;
+ u32 i;
/*
* Get the _HID and check for a PCI Root Bridge
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 39d7421..b8ee161 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -53,7 +53,7 @@ ACPI_MODULE_NAME("exconfig")
/* Local prototypes */
static acpi_status
-acpi_ex_add_table(acpi_native_uint table_index,
+acpi_ex_add_table(u32 table_index,
struct acpi_namespace_node *parent_node,
union acpi_operand_object **ddb_handle);
@@ -73,7 +73,7 @@ acpi_ex_add_table(acpi_native_uint table_index,
******************************************************************************/
static acpi_status
-acpi_ex_add_table(acpi_native_uint table_index,
+acpi_ex_add_table(u32 table_index,
struct acpi_namespace_node *parent_node,
union acpi_operand_object **ddb_handle)
{
@@ -128,12 +128,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
{
acpi_status status;
union acpi_operand_object **operand = &walk_state->operands[0];
- acpi_native_uint table_index;
struct acpi_namespace_node *parent_node;
struct acpi_namespace_node *start_node;
struct acpi_namespace_node *parameter_node = NULL;
union acpi_operand_object *ddb_handle;
struct acpi_table_header *table;
+ u32 table_index;
ACPI_FUNCTION_TRACE(ex_load_table_op);
@@ -280,7 +280,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
{
union acpi_operand_object *ddb_handle;
struct acpi_table_desc table_desc;
- acpi_native_uint table_index;
+ u32 table_index;
acpi_status status;
u32 length;
@@ -437,7 +437,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
{
acpi_status status = AE_OK;
union acpi_operand_object *table_desc = ddb_handle;
- acpi_native_uint table_index;
+ u32 table_index;
struct acpi_table_header *table;
ACPI_FUNCTION_TRACE(ex_unload_table);
@@ -454,9 +454,9 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- /* Get the table index from the ddb_handle */
+ /* Get the table index from the ddb_handle (acpi_size for 64-bit case) */
- table_index = (acpi_native_uint) table_desc->reference.object;
+ table_index = (u32) (acpi_size) table_desc->reference.object;
/* Invoke table handler if present */
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
index fd954b4..261d975 100644
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -288,11 +288,11 @@ acpi_ex_convert_to_ascii(acpi_integer integer,
u16 base, u8 * string, u8 data_width)
{
acpi_integer digit;
- acpi_native_uint i;
- acpi_native_uint j;
- acpi_native_uint k = 0;
- acpi_native_uint hex_length;
- acpi_native_uint decimal_length;
+ u32 i;
+ u32 j;
+ u32 k = 0;
+ u32 hex_length;
+ u32 decimal_length;
u32 remainder;
u8 supress_zeros;
@@ -348,7 +348,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer,
/* hex_length: 2 ascii hex chars per data byte */
- hex_length = (acpi_native_uint) ACPI_MUL_2(data_width);
+ hex_length = ACPI_MUL_2(data_width);
for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) {
/* Get one hex digit, most significant digits first */
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index 74f1b22..976016f 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -775,7 +775,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands,
u32 num_levels,
char *note, char *module_name, u32 line_number)
{
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_NAME(ex_dump_operands);
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
index e336b5d..9ff9d1f 100644
--- a/drivers/acpi/executer/exfldio.c
+++ b/drivers/acpi/executer/exfldio.c
@@ -153,14 +153,15 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
/*
* Slack mode only: We will go ahead and allow access to this
* field if it is within the region length rounded up to the next
- * access width boundary.
+ * access width boundary. acpi_size cast for 64-bit compile.
*/
if (ACPI_ROUND_UP(rgn_desc->region.length,
obj_desc->common_field.
access_byte_width) >=
- (obj_desc->common_field.base_byte_offset +
- (acpi_native_uint) obj_desc->common_field.
- access_byte_width + field_datum_byte_offset)) {
+ ((acpi_size) obj_desc->common_field.
+ base_byte_offset +
+ obj_desc->common_field.access_byte_width +
+ field_datum_byte_offset)) {
return_ACPI_STATUS(AE_OK);
}
}
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
index cc956a5..731414a 100644
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -329,8 +329,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
/* Result of two Strings is a String */
- return_desc = acpi_ut_create_string_object((acpi_size)
- (operand0->string.
+ return_desc = acpi_ut_create_string_object(((acpi_size)
+ operand0->string.
length +
local_operand1->
string.length));
@@ -352,8 +352,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
/* Result of two Buffers is a Buffer */
- return_desc = acpi_ut_create_buffer_object((acpi_size)
- (operand0->buffer.
+ return_desc = acpi_ut_create_buffer_object(((acpi_size)
+ operand0->buffer.
length +
local_operand1->
buffer.length));
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
index 7cd8bb5..7a41c40 100644
--- a/drivers/acpi/executer/exregion.c
+++ b/drivers/acpi/executer/exregion.c
@@ -156,7 +156,7 @@ acpi_ex_system_memory_space_handler(u32 function,
/* Create a new mapping starting at the address given */
mem_info->mapped_logical_address =
- acpi_os_map_memory((acpi_native_uint) address, window_size);
+ acpi_os_map_memory((acpi_physical_address) address, window_size);
if (!mem_info->mapped_logical_address) {
ACPI_ERROR((AE_INFO,
"Could not map memory at %8.8X%8.8X, size %X",
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
index 5445751..904f951 100644
--- a/drivers/acpi/namespace/nsdump.c
+++ b/drivers/acpi/namespace/nsdump.c
@@ -73,7 +73,7 @@ acpi_ns_dump_one_device(acpi_handle obj_handle,
void acpi_ns_print_pathname(u32 num_segments, char *pathname)
{
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_NAME(ns_print_pathname);
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
index 2c92f6c..a4a412b 100644
--- a/drivers/acpi/namespace/nsload.c
+++ b/drivers/acpi/namespace/nsload.c
@@ -71,8 +71,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
******************************************************************************/
acpi_status
-acpi_ns_load_table(acpi_native_uint table_index,
- struct acpi_namespace_node *node)
+acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
{
acpi_status status;
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
index 46a79b0..a82271a 100644
--- a/drivers/acpi/namespace/nsparse.c
+++ b/drivers/acpi/namespace/nsparse.c
@@ -63,13 +63,13 @@ ACPI_MODULE_NAME("nsparse")
*
******************************************************************************/
acpi_status
-acpi_ns_one_complete_parse(acpi_native_uint pass_number,
- acpi_native_uint table_index,
- struct acpi_namespace_node * start_node)
+acpi_ns_one_complete_parse(u32 pass_number,
+ u32 table_index,
+ struct acpi_namespace_node *start_node)
{
union acpi_parse_object *parse_root;
acpi_status status;
- acpi_native_uint aml_length;
+ u32 aml_length;
u8 *aml_start;
struct acpi_walk_state *walk_state;
struct acpi_table_header *table;
@@ -112,8 +112,8 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number,
aml_start = (u8 *) table + sizeof(struct acpi_table_header);
aml_length = table->length - sizeof(struct acpi_table_header);
status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
- aml_start, (u32) aml_length,
- NULL, (u8) pass_number);
+ aml_start, aml_length, NULL,
+ (u8) pass_number);
}
if (ACPI_FAILURE(status)) {
@@ -158,8 +158,7 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number,
******************************************************************************/
acpi_status
-acpi_ns_parse_table(acpi_native_uint table_index,
- struct acpi_namespace_node *start_node)
+acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
{
acpi_status status;
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index 64c0398..5b5619c 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -365,7 +365,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
char *internal_name = info->internal_name;
char *external_name = info->next_external_char;
char *result = NULL;
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_TRACE(ns_build_internal_name);
@@ -400,12 +400,11 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
result = &internal_name[i];
} else if (num_segments == 2) {
internal_name[i] = AML_DUAL_NAME_PREFIX;
- result = &internal_name[(acpi_native_uint) (i + 1)];
+ result = &internal_name[(acpi_size) i + 1];
} else {
internal_name[i] = AML_MULTI_NAME_PREFIX_OP;
- internal_name[(acpi_native_uint) (i + 1)] =
- (char)num_segments;
- result = &internal_name[(acpi_native_uint) (i + 2)];
+ internal_name[(acpi_size) i + 1] = (char)num_segments;
+ result = &internal_name[(acpi_size) i + 2];
}
}
@@ -531,12 +530,12 @@ acpi_ns_externalize_name(u32 internal_name_length,
char *internal_name,
u32 * converted_name_length, char **converted_name)
{
- acpi_native_uint names_index = 0;
- acpi_native_uint num_segments = 0;
- acpi_native_uint required_length;
- acpi_native_uint prefix_length = 0;
- acpi_native_uint i = 0;
- acpi_native_uint j = 0;
+ u32 names_index = 0;
+ u32 num_segments = 0;
+ u32 required_length;
+ u32 prefix_length = 0;
+ u32 i = 0;
+ u32 j = 0;
ACPI_FUNCTION_TRACE(ns_externalize_name);
@@ -582,9 +581,8 @@ acpi_ns_externalize_name(u32 internal_name_length,
/* <count> 4-byte names */
names_index = prefix_length + 2;
- num_segments = (acpi_native_uint) (u8)
- internal_name[(acpi_native_uint)
- (prefix_length + 1)];
+ num_segments = (u8)
+ internal_name[(acpi_size) prefix_length + 1];
break;
case AML_DUAL_NAME_PREFIX:
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index b4e135e..38be586 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -441,7 +441,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
u32 flags;
struct acpica_device_id hid;
struct acpi_compatible_id_list *cid;
- acpi_native_uint i;
+ u32 i;
int found;
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index e944637..d830b29 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -76,7 +76,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
{
u8 *aml = parser_state->aml;
u32 package_length = 0;
- acpi_native_uint byte_count;
+ u32 byte_count;
u8 byte_zero_mask = 0x3F; /* Default [0:5] */
ACPI_FUNCTION_TRACE(ps_get_next_package_length);
@@ -86,7 +86,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
* used to encode the package length, either 0,1,2, or 3
*/
byte_count = (aml[0] >> 6);
- parser_state->aml += (byte_count + 1);
+ parser_state->aml += ((acpi_size) byte_count + 1);
/* Get bytes 3, 2, 1 as needed */
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index 5ee09e1..270469a 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -333,7 +333,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
static void
acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
{
- acpi_native_uint i;
+ u32 i;
if (info->parameters) {
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index 8a112d1..f61ebc6 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -73,7 +73,7 @@ acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length);
static u8 acpi_rs_count_set_bits(u16 bit_field)
{
- acpi_native_uint bits_set;
+ u8 bits_set;
ACPI_FUNCTION_ENTRY();
@@ -84,7 +84,7 @@ static u8 acpi_rs_count_set_bits(u16 bit_field)
bit_field &= (u16) (bit_field - 1);
}
- return ((u8) bits_set);
+ return bits_set;
}
/*******************************************************************************
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
index de1ac38..96a6c03 100644
--- a/drivers/acpi/resources/rsmisc.c
+++ b/drivers/acpi/resources/rsmisc.c
@@ -82,7 +82,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource);
- if (((acpi_native_uint) resource) & 0x3) {
+ if (((acpi_size) resource) & 0x3) {
/* Each internal resource struct is expected to be 32-bit aligned */
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index 90ed83d..f7b3bcd 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -62,7 +62,7 @@ ACPI_MODULE_NAME("rsutils")
******************************************************************************/
u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
{
- acpi_native_uint i;
+ u8 i;
u8 bit_count;
ACPI_FUNCTION_ENTRY();
@@ -71,7 +71,7 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
for (i = 0, bit_count = 0; mask; i++) {
if (mask & 0x0001) {
- list[bit_count] = (u8) i;
+ list[bit_count] = i;
bit_count++;
}
@@ -96,8 +96,8 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
{
- acpi_native_uint i;
- acpi_native_uint mask;
+ u32 i;
+ u16 mask;
ACPI_FUNCTION_ENTRY();
@@ -107,7 +107,7 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
mask |= (0x1 << list[i]);
}
- return ((u16) mask);
+ return mask;
}
/*******************************************************************************
@@ -130,7 +130,7 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
void
acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
{
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_ENTRY();
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c
index 949d411..a4a41ba 100644
--- a/drivers/acpi/tables/tbfadt.c
+++ b/drivers/acpi/tables/tbfadt.c
@@ -155,7 +155,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
*
******************************************************************************/
-void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags)
+void acpi_tb_parse_fadt(u32 table_index, u8 flags)
{
u32 length;
struct acpi_table_header *table;
@@ -280,7 +280,7 @@ static void acpi_tb_convert_fadt(void)
{
u8 pm1_register_length;
struct acpi_generic_address *target;
- acpi_native_uint i;
+ u32 i;
/* Update the local FADT table header length */
@@ -396,7 +396,7 @@ static void acpi_tb_validate_fadt(void)
u32 *address32;
struct acpi_generic_address *address64;
u8 length;
- acpi_native_uint i;
+ u32 i;
/* Examine all of the 64-bit extended address fields (X fields) */
diff --git a/drivers/acpi/tables/tbfind.c b/drivers/acpi/tables/tbfind.c
index 9ca3afc..531584d 100644
--- a/drivers/acpi/tables/tbfind.c
+++ b/drivers/acpi/tables/tbfind.c
@@ -65,10 +65,9 @@ ACPI_MODULE_NAME("tbfind")
******************************************************************************/
acpi_status
acpi_tb_find_table(char *signature,
- char *oem_id,
- char *oem_table_id, acpi_native_uint * table_index)
+ char *oem_id, char *oem_table_id, u32 *table_index)
{
- acpi_native_uint i;
+ u32 i;
acpi_status status;
struct acpi_table_header header;
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 5336ce8..b22185f 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -107,11 +107,10 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
******************************************************************************/
acpi_status
-acpi_tb_add_table(struct acpi_table_desc *table_desc,
- acpi_native_uint * table_index)
+acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
{
- acpi_native_uint i;
- acpi_native_uint length;
+ u32 i;
+ u32 length;
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE(tb_add_table);
@@ -207,8 +206,8 @@ acpi_status acpi_tb_resize_root_table_list(void)
/* Increase the Table Array size */
- tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size +
- ACPI_ROOT_TABLE_SIZE_INCREMENT)
+ tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
+ size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
* sizeof(struct acpi_table_desc));
if (!tables) {
ACPI_ERROR((AE_INFO,
@@ -220,7 +219,7 @@ acpi_status acpi_tb_resize_root_table_list(void)
if (acpi_gbl_root_table_list.tables) {
ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
- acpi_gbl_root_table_list.size *
+ (acpi_size) acpi_gbl_root_table_list.size *
sizeof(struct acpi_table_desc));
if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
@@ -253,7 +252,7 @@ acpi_status acpi_tb_resize_root_table_list(void)
acpi_status
acpi_tb_store_table(acpi_physical_address address,
struct acpi_table_header *table,
- u32 length, u8 flags, acpi_native_uint * table_index)
+ u32 length, u8 flags, u32 *table_index)
{
acpi_status status = AE_OK;
@@ -334,7 +333,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
void acpi_tb_terminate(void)
{
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_TRACE(tb_terminate);
@@ -374,7 +373,7 @@ void acpi_tb_terminate(void)
*
******************************************************************************/
-void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index)
+void acpi_tb_delete_namespace_by_owner(u32 table_index)
{
acpi_owner_id owner_id;
@@ -403,7 +402,7 @@ void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index)
*
******************************************************************************/
-acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index)
+acpi_status acpi_tb_allocate_owner_id(u32 table_index)
{
acpi_status status = AE_BAD_PARAMETER;
@@ -431,7 +430,7 @@ acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index)
*
******************************************************************************/
-acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index)
+acpi_status acpi_tb_release_owner_id(u32 table_index)
{
acpi_status status = AE_BAD_PARAMETER;
@@ -462,8 +461,7 @@ acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index)
*
******************************************************************************/
-acpi_status
-acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id)
+acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
{
acpi_status status = AE_BAD_PARAMETER;
@@ -490,7 +488,7 @@ acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id)
*
******************************************************************************/
-u8 acpi_tb_is_table_loaded(acpi_native_uint table_index)
+u8 acpi_tb_is_table_loaded(u32 table_index)
{
u8 is_loaded = FALSE;
@@ -518,7 +516,7 @@ u8 acpi_tb_is_table_loaded(acpi_native_uint table_index)
*
******************************************************************************/
-void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded)
+void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
{
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index bc019b9..0cc92ef 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -49,8 +49,8 @@ ACPI_MODULE_NAME("tbutils")
/* Local prototypes */
static acpi_physical_address
-acpi_tb_get_root_table_entry(u8 * table_entry,
- acpi_native_uint table_entry_size);
+acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size);
+
/*******************************************************************************
*
* FUNCTION: acpi_tb_check_xsdt
@@ -238,7 +238,7 @@ acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
*
******************************************************************************/
-u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length)
+u8 acpi_tb_checksum(u8 *buffer, u32 length)
{
u8 sum = 0;
u8 *end = buffer + length;
@@ -268,7 +268,7 @@ u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length)
void
acpi_tb_install_table(acpi_physical_address address,
- u8 flags, char *signature, acpi_native_uint table_index)
+ u8 flags, char *signature, u32 table_index)
{
struct acpi_table_header *table;
@@ -336,8 +336,7 @@ acpi_tb_install_table(acpi_physical_address address,
******************************************************************************/
static acpi_physical_address
-acpi_tb_get_root_table_entry(u8 * table_entry,
- acpi_native_uint table_entry_size)
+acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
{
u64 address64;
@@ -395,8 +394,8 @@ acpi_status __init
acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
{
struct acpi_table_rsdp *rsdp;
- acpi_native_uint table_entry_size;
- acpi_native_uint i;
+ u32 table_entry_size;
+ u32 i;
u32 table_count;
struct acpi_table_header *table;
acpi_physical_address address;
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 0e31960..fd7770a 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -125,7 +125,7 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
/* Root Table Array has been statically allocated by the host */
ACPI_MEMSET(initial_table_array, 0,
- initial_table_count *
+ (acpi_size) initial_table_count *
sizeof(struct acpi_table_desc));
acpi_gbl_root_table_list.tables = initial_table_array;
@@ -183,9 +183,9 @@ acpi_status acpi_reallocate_root_table(void)
return_ACPI_STATUS(AE_SUPPORT);
}
- new_size =
- (acpi_gbl_root_table_list.count +
- ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc);
+ new_size = ((acpi_size) acpi_gbl_root_table_list.count +
+ ACPI_ROOT_TABLE_SIZE_INCREMENT) *
+ sizeof(struct acpi_table_desc);
/* Create new array and copy the old array */
@@ -222,7 +222,7 @@ acpi_status acpi_reallocate_root_table(void)
acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
{
acpi_status status;
- acpi_native_uint table_index;
+ u32 table_index;
struct acpi_table_desc table_desc;
if (!table_ptr)
@@ -264,11 +264,10 @@ ACPI_EXPORT_SYMBOL(acpi_load_table)
*****************************************************************************/
acpi_status
acpi_get_table_header(char *signature,
- acpi_native_uint instance,
- struct acpi_table_header * out_table_header)
+ u32 instance, struct acpi_table_header *out_table_header)
{
- acpi_native_uint i;
- acpi_native_uint j;
+ u32 i;
+ u32 j;
struct acpi_table_header *header;
/* Parameter validation */
@@ -378,10 +377,10 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
*****************************************************************************/
acpi_status
acpi_get_table(char *signature,
- acpi_native_uint instance, struct acpi_table_header **out_table)
+ u32 instance, struct acpi_table_header **out_table)
{
- acpi_native_uint i;
- acpi_native_uint j;
+ u32 i;
+ u32 j;
acpi_status status;
/* Parameter validation */
@@ -435,8 +434,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table)
*
******************************************************************************/
acpi_status
-acpi_get_table_by_index(acpi_native_uint table_index,
- struct acpi_table_header ** table)
+acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table)
{
acpi_status status;
@@ -493,7 +491,7 @@ static acpi_status acpi_tb_load_namespace(void)
{
acpi_status status;
struct acpi_table_header *table;
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_TRACE(tb_load_namespace);
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
index b8c0dfa..2d157e0 100644
--- a/drivers/acpi/tables/tbxfroot.c
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -118,7 +118,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
*
******************************************************************************/
-acpi_status acpi_find_root_pointer(acpi_native_uint * table_address)
+acpi_status acpi_find_root_pointer(acpi_size *table_address)
{
u8 *table_ptr;
u8 *mem_rover;
@@ -153,7 +153,7 @@ acpi_status acpi_find_root_pointer(acpi_native_uint * table_address)
* 1b) Search EBDA paragraphs (EBDA is required to be a
* minimum of 1_k length)
*/
- table_ptr = acpi_os_map_memory((acpi_native_uint)
+ table_ptr = acpi_os_map_memory((acpi_physical_address)
physical_address,
ACPI_EBDA_WINDOW_SIZE);
if (!table_ptr) {
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
index 655c290..53499ac 100644
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -572,7 +572,7 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
acpi_status status = AE_OK;
union acpi_operand_object *package_object;
union acpi_operand_object **package_elements;
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);
@@ -599,7 +599,7 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
/* Truncate package and delete it */
- package_object->package.count = (u32) i;
+ package_object->package.count = i;
package_elements[i] = NULL;
acpi_ut_remove_reference(package_object);
return_ACPI_STATUS(status);
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index f938f46..3919fe5 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -519,8 +519,8 @@ acpi_ut_ptr_exit(u32 line_number,
void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
{
- acpi_native_uint i = 0;
- acpi_native_uint j;
+ u32 i = 0;
+ u32 j;
u32 temp32;
u8 buf_char;
@@ -539,7 +539,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
/* Print current offset */
- acpi_os_printf("%6.4X: ", (u32) i);
+ acpi_os_printf("%6.4X: ", i);
/* Print 16 hex chars */
@@ -549,7 +549,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
/* Dump fill spaces */
acpi_os_printf("%*s", ((display * 2) + 1), " ");
- j += (acpi_native_uint) display;
+ j += display;
continue;
}
@@ -557,32 +557,38 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
case DB_BYTE_DISPLAY:
default: /* Default is BYTE display */
- acpi_os_printf("%02X ", buffer[i + j]);
+ acpi_os_printf("%02X ",
+ buffer[(acpi_size) i + j]);
break;
case DB_WORD_DISPLAY:
- ACPI_MOVE_16_TO_32(&temp32, &buffer[i + j]);
+ ACPI_MOVE_16_TO_32(&temp32,
+ &buffer[(acpi_size) i + j]);
acpi_os_printf("%04X ", temp32);
break;
case DB_DWORD_DISPLAY:
- ACPI_MOVE_32_TO_32(&temp32, &buffer[i + j]);
+ ACPI_MOVE_32_TO_32(&temp32,
+ &buffer[(acpi_size) i + j]);
acpi_os_printf("%08X ", temp32);
break;
case DB_QWORD_DISPLAY:
- ACPI_MOVE_32_TO_32(&temp32, &buffer[i + j]);
+ ACPI_MOVE_32_TO_32(&temp32,
+ &buffer[(acpi_size) i + j]);
acpi_os_printf("%08X", temp32);
- ACPI_MOVE_32_TO_32(&temp32, &buffer[i + j + 4]);
+ ACPI_MOVE_32_TO_32(&temp32,
+ &buffer[(acpi_size) i + j +
+ 4]);
acpi_os_printf("%08X ", temp32);
break;
}
- j += (acpi_native_uint) display;
+ j += display;
}
/*
@@ -596,7 +602,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
return;
}
- buf_char = buffer[i + j];
+ buf_char = buffer[(acpi_size) i + j];
if (ACPI_IS_PRINT(buf_char)) {
acpi_os_printf("%c", buf_char);
} else {
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 1fbc351..c5c791a 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -442,7 +442,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
union acpi_generic_state *state_list = NULL;
union acpi_operand_object *next_object = NULL;
union acpi_generic_state *state;
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_TRACE_PTR(ut_update_object_reference, object);
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index 7f1f634..352747e 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -97,7 +97,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
acpi_status status;
union acpi_operand_object *string_desc;
union acpi_operand_object *return_desc;
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_TRACE(ut_osi_implementation);
@@ -513,7 +513,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
u32 count;
u32 size;
struct acpi_compatible_id_list *cid_list;
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_TRACE(ut_execute_CID);
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 47354d9..6175ca5 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -161,9 +161,9 @@ u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
{
- acpi_native_uint i;
- acpi_native_uint j;
- acpi_native_uint k;
+ u32 i;
+ u32 j;
+ u32 k;
acpi_status status;
ACPI_FUNCTION_TRACE(ut_allocate_owner_id);
@@ -269,7 +269,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
{
acpi_owner_id owner_id = *owner_id_ptr;
acpi_status status;
- acpi_native_uint index;
+ u32 index;
u32 bit;
ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id);
@@ -589,7 +589,7 @@ acpi_ut_display_init_pathname(u8 type,
*
******************************************************************************/
-u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position)
+u8 acpi_ut_valid_acpi_char(char character, u32 position)
{
if (!((character >= 'A' && character <= 'Z') ||
@@ -624,7 +624,7 @@ u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position)
u8 acpi_ut_valid_acpi_name(u32 name)
{
- acpi_native_uint i;
+ u32 i;
ACPI_FUNCTION_ENTRY();
@@ -653,7 +653,7 @@ u8 acpi_ut_valid_acpi_name(u32 name)
acpi_name acpi_ut_repair_name(char *name)
{
- acpi_native_uint i;
+ u32 i;
char new_name[ACPI_NAME_SIZE];
for (i = 0; i < ACPI_NAME_SIZE; i++) {
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index e68466d..ede6a80 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -175,8 +175,8 @@ union acpi_operand_object *acpi_ut_create_package_object(u32 count)
* Create the element array. Count+1 allows the array to be null
* terminated.
*/
- package_elements = ACPI_ALLOCATE_ZEROED((acpi_size)
- (count + 1) * sizeof(void *));
+ package_elements = ACPI_ALLOCATE_ZEROED(((acpi_size) count +
+ 1) * sizeof(void *));
if (!package_elements) {
acpi_ut_remove_reference(package_desc);
return_PTR(NULL);
diff --git a/include/acpi/acdispat.h b/include/acpi/acdispat.h
index 910f018..21a73a1 100644
--- a/include/acpi/acdispat.h
+++ b/include/acpi/acdispat.h
@@ -221,7 +221,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state);
* dsinit
*/
acpi_status
-acpi_ds_initialize_objects(acpi_native_uint table_index,
+acpi_ds_initialize_objects(u32 table_index,
struct acpi_namespace_node *start_node);
/*
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h
index 74ad971..15dda46 100644
--- a/include/acpi/acglobal.h
+++ b/include/acpi/acglobal.h
@@ -140,7 +140,7 @@ ACPI_EXTERN u32 acpi_gbl_trace_flags;
*/
ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list;
ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT;
-extern acpi_native_uint acpi_gbl_permanent_mmap;
+extern u8 acpi_gbl_permanent_mmap;
/* These addresses are calculated from FADT address values */
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
index 4e42f67..9039ea8 100644
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -80,12 +80,12 @@
*/
#define ACPI_CAST_PTR(t, p) ((t *) (acpi_uintptr_t) (p))
#define ACPI_CAST_INDIRECT_PTR(t, p) ((t **) (acpi_uintptr_t) (p))
-#define ACPI_ADD_PTR(t,a,b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8,(a)) + (acpi_native_uint)(b)))
-#define ACPI_PTR_DIFF(a,b) (acpi_native_uint) (ACPI_CAST_PTR (u8,(a)) - ACPI_CAST_PTR (u8,(b)))
+#define ACPI_ADD_PTR(t, a, b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8,(a)) + (acpi_size)(b)))
+#define ACPI_PTR_DIFF(a, b) (acpi_size) (ACPI_CAST_PTR (u8,(a)) - ACPI_CAST_PTR (u8,(b)))
/* Pointer/Integer type conversions */
-#define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void,(void *) NULL,(acpi_native_uint) i)
+#define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void, (void *) NULL, (acpi_size) i)
#define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p,(void *) NULL)
#define ACPI_OFFSET(d,f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL)
#define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i)
@@ -296,22 +296,22 @@ struct acpi_integer_overlay {
/*
* Rounding macros (Power of two boundaries only)
*/
-#define ACPI_ROUND_DOWN(value,boundary) (((acpi_native_uint)(value)) & \
- (~(((acpi_native_uint) boundary)-1)))
+#define ACPI_ROUND_DOWN(value, boundary) (((acpi_size)(value)) & \
+ (~(((acpi_size) boundary)-1)))
-#define ACPI_ROUND_UP(value,boundary) ((((acpi_native_uint)(value)) + \
- (((acpi_native_uint) boundary)-1)) & \
- (~(((acpi_native_uint) boundary)-1)))
+#define ACPI_ROUND_UP(value, boundary) ((((acpi_size)(value)) + \
+ (((acpi_size) boundary)-1)) & \
+ (~(((acpi_size) boundary)-1)))
-/* Note: sizeof(acpi_native_uint) evaluates to either 2, 4, or 8 */
+/* Note: sizeof(acpi_size) evaluates to either 4 or 8 (32- vs 64-bit mode) */
#define ACPI_ROUND_DOWN_TO_32BIT(a) ACPI_ROUND_DOWN(a,4)
#define ACPI_ROUND_DOWN_TO_64BIT(a) ACPI_ROUND_DOWN(a,8)
-#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a) ACPI_ROUND_DOWN(a,sizeof(acpi_native_uint))
+#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a) ACPI_ROUND_DOWN(a,sizeof(acpi_size))
#define ACPI_ROUND_UP_TO_32BIT(a) ACPI_ROUND_UP(a,4)
#define ACPI_ROUND_UP_TO_64BIT(a) ACPI_ROUND_UP(a,8)
-#define ACPI_ROUND_UP_TO_NATIVE_WORD(a) ACPI_ROUND_UP(a,sizeof(acpi_native_uint))
+#define ACPI_ROUND_UP_TO_NATIVE_WORD(a) ACPI_ROUND_UP(a,sizeof(acpi_size))
#define ACPI_ROUND_BITS_UP_TO_BYTES(a) ACPI_DIV_8((a) + 7)
#define ACPI_ROUND_BITS_DOWN_TO_BYTES(a) ACPI_DIV_8((a))
@@ -322,7 +322,7 @@ struct acpi_integer_overlay {
#define ACPI_ROUND_UP_TO(value,boundary) (((value) + ((boundary)-1)) / (boundary))
-#define ACPI_IS_MISALIGNED(value) (((acpi_native_uint)value) & (sizeof(acpi_native_uint)-1))
+#define ACPI_IS_MISALIGNED(value) (((acpi_size)value) & (sizeof(acpi_size)-1))
/*
* Bitmask creation
diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h
index 713b309..d622c30 100644
--- a/include/acpi/acnamesp.h
+++ b/include/acpi/acnamesp.h
@@ -86,8 +86,7 @@ acpi_status acpi_ns_initialize_devices(void);
acpi_status acpi_ns_load_namespace(void);
acpi_status
-acpi_ns_load_table(acpi_native_uint table_index,
- struct acpi_namespace_node *node);
+acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node);
/*
* nswalk - walk the namespace
@@ -108,12 +107,11 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct
* nsparse - table parsing
*/
acpi_status
-acpi_ns_parse_table(acpi_native_uint table_index,
- struct acpi_namespace_node *start_node);
+acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node);
acpi_status
-acpi_ns_one_complete_parse(acpi_native_uint pass_number,
- acpi_native_uint table_index,
+acpi_ns_one_complete_parse(u32 pass_number,
+ u32 table_index,
struct acpi_namespace_node *start_node);
/*
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index d4a560d..3f93a6b 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -144,7 +144,7 @@ void acpi_os_release_mutex(acpi_mutex handle);
void *acpi_os_allocate(acpi_size size);
void __iomem *acpi_os_map_memory(acpi_physical_address where,
- acpi_native_uint length);
+ acpi_size length);
void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size);
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 2c3806e..bd95ecc 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -98,7 +98,7 @@ void acpi_free(void *address);
*/
acpi_status acpi_reallocate_root_table(void);
-acpi_status acpi_find_root_pointer(acpi_native_uint * rsdp_address);
+acpi_status acpi_find_root_pointer(acpi_size *rsdp_address);
acpi_status acpi_load_tables(void);
@@ -108,15 +108,15 @@ acpi_status acpi_unload_table_id(acpi_owner_id id);
acpi_status
acpi_get_table_header(acpi_string signature,
- acpi_native_uint instance,
+ u32 instance,
struct acpi_table_header *out_table_header);
acpi_status
acpi_get_table(acpi_string signature,
- acpi_native_uint instance, struct acpi_table_header **out_table);
+ u32 instance, struct acpi_table_header **out_table);
acpi_status
-acpi_get_table_by_index(acpi_native_uint table_index,
+acpi_get_table_by_index(u32 table_index,
struct acpi_table_header **out_table);
acpi_status
diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h
index 818c24d..7980a26 100644
--- a/include/acpi/acstruct.h
+++ b/include/acpi/acstruct.h
@@ -142,7 +142,7 @@ struct acpi_init_walk_info {
u16 package_init;
u16 object_count;
acpi_owner_id owner_id;
- acpi_native_uint table_index;
+ u32 table_index;
};
struct acpi_get_devices_info {
diff --git a/include/acpi/actables.h b/include/acpi/actables.h
index 4b36a55..0cbe1b9 100644
--- a/include/acpi/actables.h
+++ b/include/acpi/actables.h
@@ -49,7 +49,7 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count);
/*
* tbfadt - FADT parse/convert/validate
*/
-void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags);
+void acpi_tb_parse_fadt(u32 table_index, u8 flags);
void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
@@ -58,8 +58,7 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
*/
acpi_status
acpi_tb_find_table(char *signature,
- char *oem_id,
- char *oem_table_id, acpi_native_uint * table_index);
+ char *oem_id, char *oem_table_id, u32 *table_index);
/*
* tbinstal - Table removal and deletion
@@ -69,30 +68,28 @@ acpi_status acpi_tb_resize_root_table_list(void);
acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc);
acpi_status
-acpi_tb_add_table(struct acpi_table_desc *table_desc,
- acpi_native_uint * table_index);
+acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index);
acpi_status
acpi_tb_store_table(acpi_physical_address address,
struct acpi_table_header *table,
- u32 length, u8 flags, acpi_native_uint * table_index);
+ u32 length, u8 flags, u32 *table_index);
void acpi_tb_delete_table(struct acpi_table_desc *table_desc);
void acpi_tb_terminate(void);
-void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index);
+void acpi_tb_delete_namespace_by_owner(u32 table_index);
-acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index);
+acpi_status acpi_tb_allocate_owner_id(u32 table_index);
-acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index);
+acpi_status acpi_tb_release_owner_id(u32 table_index);
-acpi_status
-acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id);
+acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id);
-u8 acpi_tb_is_table_loaded(acpi_native_uint table_index);
+u8 acpi_tb_is_table_loaded(u32 table_index);
-void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded);
+void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded);
/*
* tbutils - table manager utilities
@@ -103,14 +100,14 @@ void
acpi_tb_print_table_header(acpi_physical_address address,
struct acpi_table_header *header);
-u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length);
+u8 acpi_tb_checksum(u8 *buffer, u32 length);
acpi_status
acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length);
void
acpi_tb_install_table(acpi_physical_address address,
- u8 flags, char *signature, acpi_native_uint table_index);
+ u8 flags, char *signature, u32 table_index);
acpi_status
acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags);
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index dfea2d4..5126b83 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -110,10 +110,10 @@
* usually used for memory allocation, efficient loop counters, and array
* indexes. The types are similar to the size_t type in the C library and are
* required because there is no C type that consistently represents the native
- * data width.
+ * data width. ACPI_SIZE is needed because there is no guarantee that a
+ * kernel-level C library is present.
*
* ACPI_SIZE 16/32/64-bit unsigned value
- * ACPI_NATIVE_UINT 16/32/64-bit unsigned value
* ACPI_NATIVE_INT 16/32/64-bit signed value
*
*/
@@ -147,9 +147,9 @@ typedef int INT32;
/*! [End] no source code translation !*/
-typedef u64 acpi_native_uint;
typedef s64 acpi_native_int;
+typedef u64 acpi_size;
typedef u64 acpi_io_address;
typedef u64 acpi_physical_address;
@@ -186,9 +186,9 @@ typedef int INT32;
/*! [End] no source code translation !*/
-typedef u32 acpi_native_uint;
typedef s32 acpi_native_int;
+typedef u32 acpi_size;
typedef u32 acpi_io_address;
typedef u32 acpi_physical_address;
@@ -202,10 +202,6 @@ typedef u32 acpi_physical_address;
#error unknown ACPI_MACHINE_WIDTH
#endif
-/* Variable-width type, used instead of clib size_t */
-
-typedef acpi_native_uint acpi_size;
-
/*******************************************************************************
*
* OS-dependent and compiler-dependent types
@@ -219,7 +215,7 @@ typedef acpi_native_uint acpi_size;
/* Value returned by acpi_os_get_thread_id */
#ifndef acpi_thread_id
-#define acpi_thread_id acpi_native_uint
+#define acpi_thread_id acpi_size
#endif
/* Object returned from acpi_os_create_lock */
@@ -231,7 +227,7 @@ typedef acpi_native_uint acpi_size;
/* Flags for acpi_os_acquire_lock/acpi_os_release_lock */
#ifndef acpi_cpu_flags
-#define acpi_cpu_flags acpi_native_uint
+#define acpi_cpu_flags acpi_size
#endif
/* Object returned from acpi_os_create_cache */
diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h
index b42cadf..3f663a0 100644
--- a/include/acpi/acutils.h
+++ b/include/acpi/acutils.h
@@ -172,7 +172,7 @@ char *acpi_ut_strstr(char *string1, char *string2);
void *acpi_ut_memcpy(void *dest, const void *src, acpi_size count);
-void *acpi_ut_memset(void *dest, acpi_native_uint value, acpi_size count);
+void *acpi_ut_memset(void *dest, u8 value, acpi_size count);
int acpi_ut_to_upper(int c);
@@ -476,7 +476,7 @@ u8 acpi_ut_valid_acpi_name(u32 name);
acpi_name acpi_ut_repair_name(char *name);
-u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position);
+u8 acpi_ut_valid_acpi_char(char character, u32 position);
acpi_status
acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer);
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 19/70] ACPICA: Removed unused include files from source files
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (16 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 18/70] ACPICA: Eliminate acpi_native_uint type Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 20/70] ACPICA: Several lint changes, no functional changes Len Brown
` (49 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
>From lint.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/executer/excreate.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
index 60e62c4..ad09696 100644
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -45,8 +45,6 @@
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
#include <acpi/acnamesp.h>
-#include <acpi/acevents.h>
-#include <acpi/actables.h>
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME("excreate")
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 20/70] ACPICA: Several lint changes, no functional changes
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (17 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 19/70] ACPICA: Removed unused include files from source files Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 21/70] ACPICA: Add const qualifier for appropriate string constants Len Brown
` (48 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
Remove pointer cast warnings and fix for a debug printf.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/executer/exprep.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
index 3a2f8cd..5d438c3 100644
--- a/drivers/acpi/executer/exprep.c
+++ b/drivers/acpi/executer/exprep.c
@@ -503,11 +503,11 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
*/
second_desc = obj_desc->common.next_object;
second_desc->extra.aml_start =
- ((union acpi_parse_object *)(info->data_register_node))->
- named.data;
+ ACPI_CAST_PTR(union acpi_parse_object,
+ info->data_register_node)->named.data;
second_desc->extra.aml_length =
- ((union acpi_parse_object *)(info->data_register_node))->
- named.length;
+ ACPI_CAST_PTR(union acpi_parse_object,
+ info->data_register_node)->named.length;
break;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 21/70] ACPICA: Add const qualifier for appropriate string constants
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (18 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 20/70] ACPICA: Several lint changes, no functional changes Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 22/70] ACPICA: Update version to 20080514 Len Brown
` (47 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
Mostly MODULE_NAME and printf format strings.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/executer/exdump.c | 5 ++-
drivers/acpi/namespace/nsutils.c | 24 +++++++------
drivers/acpi/utilities/utalloc.c | 5 ++-
drivers/acpi/utilities/utdebug.c | 26 +++++++++-----
drivers/acpi/utilities/utmisc.c | 11 +++---
drivers/acpi/utilities/utobject.c | 5 ++-
include/acpi/acinterp.h | 5 ++-
include/acpi/aclocal.h | 4 +-
include/acpi/acmacros.h | 2 +-
include/acpi/acnamesp.h | 20 ++++++-----
include/acpi/acutils.h | 66 +++++++++++++++++++++---------------
11 files changed, 99 insertions(+), 74 deletions(-)
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index 976016f..c94638d 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -771,9 +771,10 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
void
acpi_ex_dump_operands(union acpi_operand_object **operands,
acpi_interpreter_mode interpreter_mode,
- char *ident,
+ const char *ident,
u32 num_levels,
- char *note, char *module_name, u32 line_number)
+ const char *note,
+ const char *module_name, u32 line_number)
{
u32 i;
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index 5b5619c..b0817e1 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -73,9 +73,9 @@ acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);
******************************************************************************/
void
-acpi_ns_report_error(char *module_name,
+acpi_ns_report_error(const char *module_name,
u32 line_number,
- char *internal_name, acpi_status lookup_status)
+ const char *internal_name, acpi_status lookup_status)
{
acpi_status status;
u32 bad_name;
@@ -130,11 +130,11 @@ acpi_ns_report_error(char *module_name,
******************************************************************************/
void
-acpi_ns_report_method_error(char *module_name,
+acpi_ns_report_method_error(const char *module_name,
u32 line_number,
- char *message,
+ const char *message,
struct acpi_namespace_node *prefix_node,
- char *path, acpi_status method_status)
+ const char *path, acpi_status method_status)
{
acpi_status status;
struct acpi_namespace_node *node = prefix_node;
@@ -167,7 +167,8 @@ acpi_ns_report_method_error(char *module_name,
******************************************************************************/
void
-acpi_ns_print_node_pathname(struct acpi_namespace_node *node, char *message)
+acpi_ns_print_node_pathname(struct acpi_namespace_node *node,
+ const char *message)
{
struct acpi_buffer buffer;
acpi_status status;
@@ -296,7 +297,7 @@ u32 acpi_ns_local(acpi_object_type type)
void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
{
- char *next_external_char;
+ const char *next_external_char;
u32 i;
ACPI_FUNCTION_ENTRY();
@@ -363,7 +364,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
{
u32 num_segments = info->num_segments;
char *internal_name = info->internal_name;
- char *external_name = info->next_external_char;
+ const char *external_name = info->next_external_char;
char *result = NULL;
u32 i;
@@ -471,7 +472,8 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
*
*******************************************************************************/
-acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name)
+acpi_status
+acpi_ns_internalize_name(const char *external_name, char **converted_name)
{
char *internal_name;
struct acpi_namestring_info info;
@@ -527,7 +529,7 @@ acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name)
acpi_status
acpi_ns_externalize_name(u32 internal_name_length,
- char *internal_name,
+ const char *internal_name,
u32 * converted_name_length, char **converted_name)
{
u32 names_index = 0;
@@ -821,7 +823,7 @@ u32 acpi_ns_opens_scope(acpi_object_type type)
acpi_status
acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
- char *pathname,
+ const char *pathname,
u32 flags, struct acpi_namespace_node **return_node)
{
union acpi_generic_state scope_info;
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index ede0848..3dfb8a4 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -309,7 +309,8 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
*
******************************************************************************/
-void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line)
+void *acpi_ut_allocate(acpi_size size,
+ u32 component, const char *module, u32 line)
{
void *allocation;
@@ -353,7 +354,7 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line)
******************************************************************************/
void *acpi_ut_allocate_zeroed(acpi_size size,
- u32 component, char *module, u32 line)
+ u32 component, const char *module, u32 line)
{
void *allocation;
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index 3919fe5..fd66ecb 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -157,7 +157,8 @@ void ACPI_INTERNAL_VAR_XFACE
acpi_ut_debug_print(u32 requested_debug_level,
u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, char *format, ...)
+ const char *module_name,
+ u32 component_id, const char *format, ...)
{
acpi_thread_id thread_id;
va_list args;
@@ -228,7 +229,8 @@ void ACPI_INTERNAL_VAR_XFACE
acpi_ut_debug_print_raw(u32 requested_debug_level,
u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, char *format, ...)
+ const char *module_name,
+ u32 component_id, const char *format, ...)
{
va_list args;
@@ -261,7 +263,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_debug_print_raw)
******************************************************************************/
void
acpi_ut_trace(u32 line_number,
- const char *function_name, char *module_name, u32 component_id)
+ const char *function_name,
+ const char *module_name, u32 component_id)
{
acpi_gbl_nesting_level++;
@@ -293,7 +296,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_trace)
void
acpi_ut_trace_ptr(u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, void *pointer)
+ const char *module_name, u32 component_id, void *pointer)
{
acpi_gbl_nesting_level++;
acpi_ut_track_stack_ptr();
@@ -324,7 +327,7 @@ acpi_ut_trace_ptr(u32 line_number,
void
acpi_ut_trace_str(u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, char *string)
+ const char *module_name, u32 component_id, char *string)
{
acpi_gbl_nesting_level++;
@@ -356,7 +359,7 @@ acpi_ut_trace_str(u32 line_number,
void
acpi_ut_trace_u32(u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, u32 integer)
+ const char *module_name, u32 component_id, u32 integer)
{
acpi_gbl_nesting_level++;
@@ -386,7 +389,8 @@ acpi_ut_trace_u32(u32 line_number,
void
acpi_ut_exit(u32 line_number,
- const char *function_name, char *module_name, u32 component_id)
+ const char *function_name,
+ const char *module_name, u32 component_id)
{
acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
@@ -417,7 +421,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_exit)
void
acpi_ut_status_exit(u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, acpi_status status)
+ const char *module_name,
+ u32 component_id, acpi_status status)
{
if (ACPI_SUCCESS(status)) {
@@ -458,7 +463,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_status_exit)
void
acpi_ut_value_exit(u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, acpi_integer value)
+ const char *module_name,
+ u32 component_id, acpi_integer value)
{
acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
@@ -490,7 +496,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_value_exit)
void
acpi_ut_ptr_exit(u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, u8 * ptr)
+ const char *module_name, u32 component_id, u8 *ptr)
{
acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 6175ca5..f34be67 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -1020,7 +1020,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
******************************************************************************/
void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_error(char *module_name, u32 line_number, char *format, ...)
+acpi_ut_error(const char *module_name, u32 line_number, const char *format, ...)
{
va_list args;
@@ -1033,8 +1033,8 @@ acpi_ut_error(char *module_name, u32 line_number, char *format, ...)
}
void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_exception(char *module_name,
- u32 line_number, acpi_status status, char *format, ...)
+acpi_ut_exception(const char *module_name,
+ u32 line_number, acpi_status status, const char *format, ...)
{
va_list args;
@@ -1050,7 +1050,8 @@ acpi_ut_exception(char *module_name,
EXPORT_SYMBOL(acpi_ut_exception);
void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_warning(char *module_name, u32 line_number, char *format, ...)
+acpi_ut_warning(const char *module_name,
+ u32 line_number, const char *format, ...)
{
va_list args;
@@ -1063,7 +1064,7 @@ acpi_ut_warning(char *module_name, u32 line_number, char *format, ...)
}
void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_info(char *module_name, u32 line_number, char *format, ...)
+acpi_ut_info(const char *module_name, u32 line_number, const char *format, ...)
{
va_list args;
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index ede6a80..e254844 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -83,7 +83,8 @@ acpi_ut_get_element_length(u8 object_type,
*
******************************************************************************/
-union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name,
+union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
+ *module_name,
u32 line_number,
u32 component_id,
acpi_object_type
@@ -347,7 +348,7 @@ u8 acpi_ut_valid_internal_object(void *object)
*
******************************************************************************/
-void *acpi_ut_allocate_object_desc_dbg(char *module_name,
+void *acpi_ut_allocate_object_desc_dbg(const char *module_name,
u32 line_number, u32 component_id)
{
union acpi_operand_object *object;
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
index e249ce5..accd120 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -367,9 +367,10 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth);
void
acpi_ex_dump_operands(union acpi_operand_object **operands,
acpi_interpreter_mode interpreter_mode,
- char *ident,
+ const char *ident,
u32 num_levels,
- char *note, char *module_name, u32 line_number);
+ const char *note,
+ const char *module_name, u32 line_number);
#ifdef ACPI_FUTURE_USAGE
void
diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h
index c5cdc32..39dcda7 100644
--- a/include/acpi/aclocal.h
+++ b/include/acpi/aclocal.h
@@ -282,8 +282,8 @@ struct acpi_predefined_names {
/* Info structure used to convert external<->internal namestrings */
struct acpi_namestring_info {
- char *external_name;
- char *next_external_char;
+ const char *external_name;
+ const char *next_external_char;
char *internal_name;
u32 length;
u32 num_segments;
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
index 9039ea8..fcdf709 100644
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -414,7 +414,7 @@ struct acpi_integer_overlay {
* error messages. The __FILE__ macro is not very useful for this, because it
* often includes the entire pathname to the module
*/
-#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR _acpi_module_name[] = name;
+#define ACPI_MODULE_NAME(name) static const char ACPI_UNUSED_VAR _acpi_module_name[] = name;
#else
#define ACPI_MODULE_NAME(name)
#endif
diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h
index d622c30..9ed70a0 100644
--- a/include/acpi/acnamesp.h
+++ b/include/acpi/acnamesp.h
@@ -199,7 +199,7 @@ acpi_ns_pattern_match(struct acpi_namespace_node *obj_node, char *search_for);
acpi_status
acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
- char *external_pathname,
+ const char *external_pathname,
u32 flags, struct acpi_namespace_node **out_node);
acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node);
@@ -263,28 +263,30 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node);
u32 acpi_ns_local(acpi_object_type type);
void
-acpi_ns_report_error(char *module_name,
+acpi_ns_report_error(const char *module_name,
u32 line_number,
- char *internal_name, acpi_status lookup_status);
+ const char *internal_name, acpi_status lookup_status);
void
-acpi_ns_report_method_error(char *module_name,
+acpi_ns_report_method_error(const char *module_name,
u32 line_number,
- char *message,
+ const char *message,
struct acpi_namespace_node *node,
- char *path, acpi_status lookup_status);
+ const char *path, acpi_status lookup_status);
-void acpi_ns_print_node_pathname(struct acpi_namespace_node *node, char *msg);
+void
+acpi_ns_print_node_pathname(struct acpi_namespace_node *node, const char *msg);
acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info);
void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info);
-acpi_status acpi_ns_internalize_name(char *dotted_name, char **converted_name);
+acpi_status
+acpi_ns_internalize_name(const char *dotted_name, char **converted_name);
acpi_status
acpi_ns_externalize_name(u32 internal_name_length,
- char *internal_name,
+ const char *internal_name,
u32 * converted_name_length, char **converted_name);
struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle);
diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h
index 3f663a0..69f8888 100644
--- a/include/acpi/acutils.h
+++ b/include/acpi/acutils.h
@@ -245,41 +245,45 @@ void acpi_ut_track_stack_ptr(void);
void
acpi_ut_trace(u32 line_number,
- const char *function_name, char *module_name, u32 component_id);
+ const char *function_name,
+ const char *module_name, u32 component_id);
void
acpi_ut_trace_ptr(u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, void *pointer);
+ const char *module_name, u32 component_id, void *pointer);
void
acpi_ut_trace_u32(u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, u32 integer);
+ const char *module_name, u32 component_id, u32 integer);
void
acpi_ut_trace_str(u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, char *string);
+ const char *module_name, u32 component_id, char *string);
void
acpi_ut_exit(u32 line_number,
- const char *function_name, char *module_name, u32 component_id);
+ const char *function_name,
+ const char *module_name, u32 component_id);
void
acpi_ut_status_exit(u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, acpi_status status);
+ const char *module_name,
+ u32 component_id, acpi_status status);
void
acpi_ut_value_exit(u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, acpi_integer value);
+ const char *module_name,
+ u32 component_id, acpi_integer value);
void
acpi_ut_ptr_exit(u32 line_number,
const char *function_name,
- char *module_name, u32 component_id, u8 * ptr);
+ const char *module_name, u32 component_id, u8 *ptr);
void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id);
@@ -297,33 +301,35 @@ void ACPI_INTERNAL_VAR_XFACE
acpi_ut_debug_print(u32 requested_debug_level,
u32 line_number,
const char *function_name,
- char *module_name,
- u32 component_id, char *format, ...) ACPI_PRINTF_LIKE(6);
+ const char *module_name,
+ u32 component_id,
+ const char *format, ...) ACPI_PRINTF_LIKE(6);
void ACPI_INTERNAL_VAR_XFACE
acpi_ut_debug_print_raw(u32 requested_debug_level,
u32 line_number,
const char *function_name,
- char *module_name,
+ const char *module_name,
u32 component_id,
- char *format, ...) ACPI_PRINTF_LIKE(6);
+ const char *format, ...) ACPI_PRINTF_LIKE(6);
void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_error(char *module_name,
- u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3);
+acpi_ut_error(const char *module_name,
+ u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3);
void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_exception(char *module_name,
+acpi_ut_exception(const char *module_name,
u32 line_number,
- acpi_status status, char *format, ...) ACPI_PRINTF_LIKE(4);
+ acpi_status status,
+ const char *format, ...) ACPI_PRINTF_LIKE(4);
void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_warning(char *module_name,
- u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3);
+acpi_ut_warning(const char *module_name,
+ u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3);
void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_info(char *module_name,
- u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3);
+acpi_ut_info(const char *module_name,
+ u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3);
/*
* utdelete - Object deletion and reference counts
@@ -376,13 +382,14 @@ acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest);
/*
* utobject - internal object create/delete/cache routines
*/
-union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name,
+union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
+ *module_name,
u32 line_number,
u32 component_id,
acpi_object_type
type);
-void *acpi_ut_allocate_object_desc_dbg(char *module_name,
+void *acpi_ut_allocate_object_desc_dbg(const char *module_name,
u32 line_number, u32 component_id);
#define acpi_ut_create_internal_object(t) acpi_ut_create_internal_object_dbg (_acpi_module_name,__LINE__,_COMPONENT,t)
@@ -543,26 +550,29 @@ acpi_status
acpi_ut_initialize_buffer(struct acpi_buffer *buffer,
acpi_size required_length);
-void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line);
+void *acpi_ut_allocate(acpi_size size,
+ u32 component, const char *module, u32 line);
void *acpi_ut_allocate_zeroed(acpi_size size,
- u32 component, char *module, u32 line);
+ u32 component, const char *module, u32 line);
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
void *acpi_ut_allocate_and_track(acpi_size size,
- u32 component, char *module, u32 line);
+ u32 component, const char *module, u32 line);
void *acpi_ut_allocate_zeroed_and_track(acpi_size size,
- u32 component, char *module, u32 line);
+ u32 component,
+ const char *module, u32 line);
void
-acpi_ut_free_and_track(void *address, u32 component, char *module, u32 line);
+acpi_ut_free_and_track(void *address,
+ u32 component, const char *module, u32 line);
#ifdef ACPI_FUTURE_USAGE
void acpi_ut_dump_allocation_info(void);
#endif /* ACPI_FUTURE_USAGE */
-void acpi_ut_dump_allocations(u32 component, char *module);
+void acpi_ut_dump_allocations(u32 component, const char *module);
acpi_status
acpi_ut_create_list(char *list_name,
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 22/70] ACPICA: Update version to 20080514
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (19 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 21/70] ACPICA: Add const qualifier for appropriate string constants Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 23/70] ACPICA: Workaround for reversed _PRT entries from BIOS Len Brown
` (46 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
Update version to 20080514
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
include/acpi/acconfig.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index 28fe8ba..2ced0e1 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -63,7 +63,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20080321
+#define ACPI_CA_VERSION 0x20080514
/*
* OS name, used for the _OS object. The _OS object is essentially obsolete,
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 23/70] ACPICA: Workaround for reversed _PRT entries from BIOS
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (20 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 22/70] ACPICA: Update version to 20080514 Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-07-01 8:33 ` Check for BIOS bugs - Original Subject: " Thomas Renninger
2008-06-20 7:43 ` [PATCH 24/70] ACPICA: Update DMAR and SRAT table definitions Len Brown
` (45 subsequent siblings)
67 siblings, 1 reply; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
Some BIOSs erroneously reverse the _PRT SourceName and the
SourceIndex. Detect and repair this problem. MS ACPI also allows
and repairs this problem, thus ACPICA must also.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/resources/rscreate.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
index faddaee..70c84ec 100644
--- a/drivers/acpi/resources/rscreate.c
+++ b/drivers/acpi/resources/rscreate.c
@@ -285,6 +285,23 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
}
/*
+ * If the BIOS has erroneously reversed the _PRT source_name (index 2)
+ * and the source_index (index 3), fix it. _PRT is important enough to
+ * workaround this BIOS error. This also provides compatibility with
+ * other ACPI implementations.
+ */
+ obj_desc = sub_object_list[3];
+ if (!obj_desc
+ || (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+ sub_object_list[3] = sub_object_list[2];
+ sub_object_list[2] = obj_desc;
+
+ ACPI_WARNING((AE_INFO,
+ "(PRT[%X].Source) SourceName and SourceIndex are reversed, fixed",
+ index));
+ }
+
+ /*
* 3) Third subobject: Dereference the PRT.source_name
* The name may be unresolved (slack mode), so allow a null object
*/
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 24/70] ACPICA: Update DMAR and SRAT table definitions
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (21 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 23/70] ACPICA: Workaround for reversed _PRT entries from BIOS Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 25/70] ACPICA: Update disassembler for DMAR table changes Len Brown
` (44 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
Synchronized tables with current specifications.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
arch/x86/kernel/srat_32.c | 3 +--
drivers/acpi/numa.c | 4 ++--
include/acpi/actbl1.h | 19 +++++++++++++++++--
3 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kernel/srat_32.c b/arch/x86/kernel/srat_32.c
index a29192f..0142476 100644
--- a/arch/x86/kernel/srat_32.c
+++ b/arch/x86/kernel/srat_32.c
@@ -126,9 +126,8 @@ static void __init parse_memory_affinity_structure (char *sratp)
num_memory_chunks++;
- printk("Memory range 0x%lX to 0x%lX (type 0x%X) in proximity domain 0x%02X %s\n",
+ printk("Memory range 0x%lX to 0x%lX in proximity domain 0x%02X %s\n",
start_pfn, end_pfn,
- memory_affinity->memory_type,
pxm,
((memory_affinity->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ?
"enabled and removable" : "enabled" ) );
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 658e5f3..cb9864e 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -120,10 +120,10 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
struct acpi_srat_mem_affinity *p =
(struct acpi_srat_mem_affinity *)header;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "SRAT Memory (0x%lx length 0x%lx type 0x%x) in proximity domain %d %s%s\n",
+ "SRAT Memory (0x%lx length 0x%lx) in proximity domain %d %s%s\n",
(unsigned long)p->base_address,
(unsigned long)p->length,
- p->memory_type, p->proximity_domain,
+ p->proximity_domain,
(p->flags & ACPI_SRAT_MEM_ENABLED)?
"enabled" : "disabled",
(p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)?
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index 9af239b..715a489 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -300,6 +300,7 @@ struct acpi_table_dbgp {
/*******************************************************************************
*
* DMAR - DMA Remapping table
+ * From "Intel Virtualization Technology for Directed I/O", Sept. 2007
*
******************************************************************************/
@@ -382,6 +383,20 @@ struct acpi_dmar_reserved_memory {
#define ACPI_DMAR_ALLOW_ALL (1)
+
+/* 2: Root Port ATS Capability Reporting Structure */
+
+struct acpi_dmar_atsr {
+ struct acpi_dmar_header header;
+ u8 flags;
+ u8 reserved;
+ u16 segment;
+};
+
+/* Flags */
+
+#define ACPI_DMAR_ALL_PORTS (1)
+
/*******************************************************************************
*
* ECDT - Embedded Controller Boot Resources Table
@@ -1156,9 +1171,9 @@ struct acpi_srat_mem_affinity {
u16 reserved; /* Reserved, must be zero */
u64 base_address;
u64 length;
- u32 memory_type; /* See acpi_address_range_id */
+ u32 reserved1;
u32 flags;
- u64 reserved1; /* Reserved, must be zero */
+ u64 reserved2; /* Reserved, must be zero */
};
/* Flags */
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 25/70] ACPICA: Update disassembler for DMAR table changes
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (22 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 24/70] ACPICA: Update DMAR and SRAT table definitions Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 11:52 ` Matthew Garrett
2008-06-20 19:49 ` Andi Kleen
2008-06-20 7:43 ` [PATCH 26/70] ACPICA: Fix for invalid large array index on 64-bit systems Len Brown
` (43 subsequent siblings)
67 siblings, 2 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
Now supports the 2007 intel Virtualization Technology for Directed
I/O specification.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
include/acpi/acdisasm.h | 1 +
include/acpi/actbl1.h | 4 ++++
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h
index 788f887..f53faca 100644
--- a/include/acpi/acdisasm.h
+++ b/include/acpi/acdisasm.h
@@ -162,6 +162,7 @@ extern struct acpi_dmtable_info acpi_dm_table_info_dmar_hdr[];
extern struct acpi_dmtable_info acpi_dm_table_info_dmar_scope[];
extern struct acpi_dmtable_info acpi_dm_table_info_dmar0[];
extern struct acpi_dmtable_info acpi_dm_table_info_dmar1[];
+extern struct acpi_dmtable_info acpi_dm_table_info_dmar2[];
extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[];
extern struct acpi_dmtable_info acpi_dm_table_info_einj[];
extern struct acpi_dmtable_info acpi_dm_table_info_einj0[];
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index 715a489..bc47ce5 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -311,6 +311,10 @@ struct acpi_table_dmar {
u8 reserved[10];
};
+/* Flags */
+
+#define ACPI_DMAR_INTR_REMAP (1)
+
/* DMAR subtable header */
struct acpi_dmar_header {
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 26/70] ACPICA: Fix for invalid large array index on 64-bit systems
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (23 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 25/70] ACPICA: Update disassembler for DMAR table changes Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 27/70] ACPICA: Cleanup debug operand dump mechanism Len Brown
` (42 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
This problem was introduced in 20080514 as a result of the
elimination of the acpi_native_uint type. Code uses a negative
array index, which should be eliminated.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/executer/exdump.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index c94638d..f337c3f 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -776,7 +776,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands,
const char *note,
const char *module_name, u32 line_number)
{
- u32 i;
+ s32 i;
ACPI_FUNCTION_NAME(ex_dump_operands);
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 27/70] ACPICA: Cleanup debug operand dump mechanism
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (24 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 26/70] ACPICA: Fix for invalid large array index on 64-bit systems Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 28/70] ACPICA: Cleanup of _PRT parsing code Len Brown
` (41 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
Eliminated unnecessary operands; eliminated use of negative index
in loop. Operands now displayed in correct order, not backwards.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/dispatcher/dsopcode.c | 20 +---------
drivers/acpi/dispatcher/dswexec.c | 8 ----
drivers/acpi/executer/exdump.c | 68 ++++++++++++++----------------------
drivers/acpi/executer/exresop.c | 4 ++
drivers/acpi/executer/exstore.c | 6 ---
drivers/acpi/namespace/nsdump.c | 4 +-
include/acpi/acinterp.h | 6 +---
include/acpi/acmacros.h | 4 +-
8 files changed, 37 insertions(+), 83 deletions(-)
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index ac0bfb1..6a81c44 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -691,12 +691,6 @@ acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state,
status = acpi_ex_resolve_operands(op->common.aml_opcode,
ACPI_WALK_OPERANDS, walk_state);
-
- ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
- acpi_ps_get_opcode_name(op->common.aml_opcode),
- walk_state->num_operands,
- "after AcpiExResolveOperands");
-
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO, "(%s) bad operand(s) (%X)",
acpi_ps_get_opcode_name(op->common.aml_opcode),
@@ -785,10 +779,6 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(status);
}
- ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
- acpi_ps_get_opcode_name(op->common.aml_opcode),
- 1, "after AcpiExResolveOperands");
-
obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
return_ACPI_STATUS(AE_NOT_EXIST);
@@ -882,10 +872,6 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(status);
}
- ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
- acpi_ps_get_opcode_name(op->common.aml_opcode),
- 1, "after AcpiExResolveOperands");
-
operand = &walk_state->operands[0];
/* Find the ACPI table */
@@ -1091,10 +1077,8 @@ acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(status);
}
- ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
- acpi_ps_get_opcode_name(op->common.aml_opcode),
- 1, "after AcpiExResolveOperands");
-
+ ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS,
+ acpi_ps_get_opcode_name(op->common.aml_opcode), 1);
/*
* Get the bank_value operand and save it
* (at Top of stack)
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index b246b96..b5072fa 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -408,14 +408,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
[walk_state->
num_operands - 1]),
walk_state);
- if (ACPI_SUCCESS(status)) {
- ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS,
- ACPI_IMODE_EXECUTE,
- acpi_ps_get_opcode_name
- (walk_state->opcode),
- walk_state->num_operands,
- "after ExResolveOperands");
- }
}
if (ACPI_SUCCESS(status)) {
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index f337c3f..3d10604 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -580,25 +580,22 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
case ACPI_TYPE_BUFFER:
- acpi_os_printf("Buffer len %X @ %p\n",
+ acpi_os_printf("Buffer length %.2X @ %p\n",
obj_desc->buffer.length,
obj_desc->buffer.pointer);
- length = obj_desc->buffer.length;
- if (length > 64) {
- length = 64;
- }
-
/* Debug only -- dump the buffer contents */
if (obj_desc->buffer.pointer) {
- acpi_os_printf("Buffer Contents: ");
-
- for (index = 0; index < length; index++) {
- acpi_os_printf(" %02x",
- obj_desc->buffer.pointer[index]);
+ length = obj_desc->buffer.length;
+ if (length > 128) {
+ length = 128;
}
- acpi_os_printf("\n");
+
+ acpi_os_printf
+ ("Buffer Contents: (displaying length 0x%.2X)\n",
+ length);
+ ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, length);
}
break;
@@ -756,55 +753,42 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
*
* FUNCTION: acpi_ex_dump_operands
*
- * PARAMETERS: Operands - Operand list
- * interpreter_mode - Load or Exec
- * Ident - Identification
- * num_levels - # of stack entries to dump above line
- * Note - Output notation
- * module_name - Caller's module name
- * line_number - Caller's invocation line number
+ * PARAMETERS: Operands - A list of Operand objects
+ * opcode_name - AML opcode name
+ * num_operands - Operand count for this opcode
*
- * DESCRIPTION: Dump the object stack
+ * DESCRIPTION: Dump the operands associated with the opcode
*
******************************************************************************/
void
acpi_ex_dump_operands(union acpi_operand_object **operands,
- acpi_interpreter_mode interpreter_mode,
- const char *ident,
- u32 num_levels,
- const char *note,
- const char *module_name, u32 line_number)
+ const char *opcode_name, u32 num_operands)
{
- s32 i;
-
ACPI_FUNCTION_NAME(ex_dump_operands);
- if (!ident) {
- ident = "?";
- }
-
- if (!note) {
- note = "?";
+ if (!opcode_name) {
+ opcode_name = "UNKNOWN";
}
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
- "************* Operand Stack Contents (Opcode [%s], %d Operands)\n",
- ident, num_levels));
+ "**** Start operand dump for opcode [%s], %d operands\n",
+ opcode_name, num_operands));
- if (num_levels == 0) {
- num_levels = 1;
+ if (num_operands == 0) {
+ num_operands = 1;
}
- /* Dump the operand stack starting at the top */
+ /* Dump the individual operands */
- for (i = 0; num_levels > 0; i--, num_levels--) {
- acpi_ex_dump_operand(operands[i], 0);
+ while (num_operands) {
+ acpi_ex_dump_operand(*operands, 0);
+ operands++;
+ num_operands--;
}
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
- "************* Operand Stack dump from %s(%d), %s\n",
- module_name, line_number, note));
+ "**** End operand dump for [%s]\n", opcode_name));
return;
}
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
index 73e29e5..54085f1 100644
--- a/drivers/acpi/executer/exresop.c
+++ b/drivers/acpi/executer/exresop.c
@@ -698,5 +698,9 @@ acpi_ex_resolve_operands(u16 opcode,
}
}
+ ACPI_DUMP_OPERANDS(walk_state->operands,
+ acpi_ps_get_opcode_name(opcode),
+ walk_state->num_operands);
+
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
index 76c875b..38b55e3 100644
--- a/drivers/acpi/executer/exstore.c
+++ b/drivers/acpi/executer/exstore.c
@@ -343,12 +343,6 @@ acpi_ex_store(union acpi_operand_object *source_desc,
acpi_ut_get_object_type_name(dest_desc),
dest_desc));
- ACPI_DUMP_STACK_ENTRY(source_desc);
- ACPI_DUMP_STACK_ENTRY(dest_desc);
- ACPI_DUMP_OPERANDS(&dest_desc, ACPI_IMODE_EXECUTE, "ExStore",
- 2,
- "Target is not a Reference or Constant object");
-
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
index 904f951..0ab2200 100644
--- a/drivers/acpi/namespace/nsdump.c
+++ b/drivers/acpi/namespace/nsdump.c
@@ -515,12 +515,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
if (obj_type > ACPI_TYPE_LOCAL_MAX) {
acpi_os_printf
- ("(Ptr to ACPI Object type %X [UNKNOWN])\n",
+ ("(Pointer to ACPI Object type %.2X [UNKNOWN])\n",
obj_type);
bytes_to_dump = 32;
} else {
acpi_os_printf
- ("(Ptr to ACPI Object type %X [%s])\n",
+ ("(Pointer to ACPI Object type %.2X [%s])\n",
obj_type, acpi_ut_get_type_name(obj_type));
bytes_to_dump =
sizeof(union acpi_operand_object);
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
index accd120..e8db7a3 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -366,11 +366,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth);
void
acpi_ex_dump_operands(union acpi_operand_object **operands,
- acpi_interpreter_mode interpreter_mode,
- const char *ident,
- u32 num_levels,
- const char *note,
- const char *module_name, u32 line_number);
+ const char *opcode_name, u32 num_opcodes);
#ifdef ACPI_FUTURE_USAGE
void
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
index fcdf709..6d18cd9 100644
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -597,7 +597,7 @@ struct acpi_integer_overlay {
/* Stack and buffer dumping */
#define ACPI_DUMP_STACK_ENTRY(a) acpi_ex_dump_operand((a),0)
-#define ACPI_DUMP_OPERANDS(a,b,c,d,e) acpi_ex_dump_operands(a,b,c,d,e,_acpi_module_name,__LINE__)
+#define ACPI_DUMP_OPERANDS(a,b,c) acpi_ex_dump_operands(a,b,c)
#define ACPI_DUMP_ENTRY(a,b) acpi_ns_dump_entry (a,b)
#define ACPI_DUMP_PATHNAME(a,b,c,d) acpi_ns_dump_pathname(a,b,c,d)
@@ -633,7 +633,7 @@ struct acpi_integer_overlay {
#define ACPI_FUNCTION_VALUE_EXIT(s) do { } while(0)
#define ACPI_FUNCTION_ENTRY() do { } while(0)
#define ACPI_DUMP_STACK_ENTRY(a) do { } while(0)
-#define ACPI_DUMP_OPERANDS(a,b,c,d,e) do { } while(0)
+#define ACPI_DUMP_OPERANDS(a,b,c) do { } while(0)
#define ACPI_DUMP_ENTRY(a,b) do { } while(0)
#define ACPI_DUMP_TABLES(a,b) do { } while(0)
#define ACPI_DUMP_PATHNAME(a,b,c,d) do { } while(0)
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 28/70] ACPICA: Cleanup of _PRT parsing code
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (25 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 27/70] ACPICA: Cleanup debug operand dump mechanism Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 29/70] ACPICA: Fix mutex debug code for wrong loop termination value Len Brown
` (40 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
Removed extraneous else clauses, other general cleanup.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/resources/rscreate.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
index 70c84ec..7804a8c 100644
--- a/drivers/acpi/resources/rscreate.c
+++ b/drivers/acpi/resources/rscreate.c
@@ -181,9 +181,9 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
}
/*
- * Loop through the ACPI_INTERNAL_OBJECTS - Each object
- * should be a package that in turn contains an
- * acpi_integer Address, a u8 Pin, a Name and a u8 source_index.
+ * Loop through the ACPI_INTERNAL_OBJECTS - Each object should be a
+ * package that in turn contains an acpi_integer Address, a u8 Pin,
+ * a Name, and a u8 source_index.
*/
top_object_list = package_object->package.elements;
number_of_elements = package_object->package.count;
@@ -240,9 +240,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 1) First subobject: Dereference the PRT.Address */
obj_desc = sub_object_list[0];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
- user_prt->address = obj_desc->integer.value;
- } else {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].Address) Need Integer, found %s",
index,
@@ -250,12 +248,12 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
return_ACPI_STATUS(AE_BAD_DATA);
}
+ user_prt->address = obj_desc->integer.value;
+
/* 2) Second subobject: Dereference the PRT.Pin */
obj_desc = sub_object_list[1];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
- user_prt->pin = (u32) obj_desc->integer.value;
- } else {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].Pin) Need Integer, found %s",
index,
@@ -284,6 +282,8 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
}
}
+ user_prt->pin = (u32) obj_desc->integer.value;
+
/*
* If the BIOS has erroneously reversed the _PRT source_name (index 2)
* and the source_index (index 3), fix it. _PRT is important enough to
@@ -381,9 +381,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 4) Fourth subobject: Dereference the PRT.source_index */
obj_desc = sub_object_list[source_index_index];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
- user_prt->source_index = (u32) obj_desc->integer.value;
- } else {
+ if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].SourceIndex) Need Integer, found %s",
index,
@@ -391,6 +389,8 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
return_ACPI_STATUS(AE_BAD_DATA);
}
+ user_prt->source_index = (u32) obj_desc->integer.value;
+
/* Point to the next union acpi_operand_object in the top level package */
top_object_list++;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 29/70] ACPICA: Fix mutex debug code for wrong loop termination value
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (26 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 28/70] ACPICA: Cleanup of _PRT parsing code Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 30/70] ACPICA: Update version to 20080609 Len Brown
` (39 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Lin Ming, Len Brown
From: Bob Moore <robert.moore@intel.com>
Loop was terminating one iteration early, missing one of the
debugger handshake mutexes. Linn Crosetto.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/utilities/utmutex.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c
index f7d602b..7331dde 100644
--- a/drivers/acpi/utilities/utmutex.c
+++ b/drivers/acpi/utilities/utmutex.c
@@ -218,7 +218,7 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
* the mutex ordering rule. This indicates a coding error somewhere in
* the ACPI subsystem code.
*/
- for (i = mutex_id; i < ACPI_MAX_MUTEX; i++) {
+ for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
if (i == mutex_id) {
ACPI_ERROR((AE_INFO,
@@ -315,7 +315,7 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
* ordering rule. This indicates a coding error somewhere in
* the ACPI subsystem code.
*/
- for (i = mutex_id; i < ACPI_MAX_MUTEX; i++) {
+ for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
if (i == mutex_id) {
continue;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 30/70] ACPICA: Update version to 20080609
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (27 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 29/70] ACPICA: Fix mutex debug code for wrong loop termination value Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 32/70] ACPI: fix checkpatch.pl complaints in scan.c Len Brown
` (38 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Len Brown
From: Bob Moore <robert.moore@intel.com>
Update version to 20080609.
Signed-off-by: Len Brown <len.brown@intel.com>
---
include/acpi/acconfig.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index 2ced0e1..e66aabd 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -63,7 +63,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20080514
+#define ACPI_CA_VERSION 0x20080609
/*
* OS name, used for the _OS object. The _OS object is essentially obsolete,
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 32/70] ACPI: fix checkpatch.pl complaints in scan.c
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (28 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 30/70] ACPICA: Update version to 20080609 Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 19:48 ` Andi Kleen
2008-06-20 7:43 ` [PATCH 33/70] ACPI: fix acpi fan state set error Len Brown
` (37 subsequent siblings)
67 siblings, 1 reply; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Alok N Kataria, Len Brown
From: Alok N Kataria <akataria@vmware.com>
http://bugzilla.kernel.org/show_bug.cgi?id=9772
Signed-off-by: Alok N Kataria <akataria@vmware.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/scan.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 00ba4af..fb0c07e 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -6,7 +6,8 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/acpi.h>
-#include <asm/signal.h>
+#include <linux/signal.h>
+#include <linux/kthread.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acinterp.h> /* for acpi_ex_eisa_id_to_string() */
@@ -154,6 +155,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
acpi_status status;
acpi_object_type type = 0;
struct acpi_device *acpi_device = to_acpi_device(d);
+ struct task_struct *task;
if ((!count) || (buf[0] != '1')) {
return -EINVAL;
@@ -171,9 +173,11 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
}
/* remove the device in another thread to fix the deadlock issue */
- ret = kernel_thread(acpi_bus_hot_remove_device,
- acpi_device->handle, SIGCHLD);
- err:
+ task = kthread_run(acpi_bus_hot_remove_device,
+ acpi_device->handle, "acpi_hot_remove_device");
+ if (IS_ERR(task))
+ ret = PTR_ERR(task);
+err:
return ret;
}
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 33/70] ACPI: fix acpi fan state set error
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (29 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 32/70] ACPI: fix checkpatch.pl complaints in scan.c Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 34/70] ACPI Exception (video-1721): UNKNOWN_STATUS_CODE, Cant attach device Len Brown
` (36 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Yi Yang, Len Brown
From: Yi Yang <yi.y.yang@intel.com>
Under /proc/acpi, there is a fan control interface, a user can
set 0 or 3 to /proc/acpi/fan/*/state, 0 denotes D0 state, 3
denotes D3 state, but in current implementation, a user can
set a fan to D1 state by any char excluding '1', '2' and '3'.
For example:
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost acpi]# echo "" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost acpi]# echo "3" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost acpi]# echo "xxxxx" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: on
Obviously, such inputs as "" and "xxxxx" are invalid for fan state.
This patch fixes this issue, it strictly limits fan state only to
accept 0, 1, 2 and 3, any other inputs are invalid.
Before applying this patch, the test result is:
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost acpi]# echo "" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost acpi]# echo "3" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost acpi]# echo "xxxxx" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost acpi]# echo "3" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost acpi]# echo "3x" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost acpi]# echo "-1x" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost acpi]#
After applying this patch, the test result is:
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost ~]# echo "" > /proc/acpi/fan/C31B/state
-bash: echo: write error: Invalid argument
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost ~]# echo "3" > /proc/acpi/fan/C31B/state
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost ~]# echo "xxxxx" > /proc/acpi/fan/C31B/state
-bash: echo: write error: Invalid argument
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost ~]# echo "-1x" > /proc/acpi/fan/C31B/state
-bash: echo: write error: Invalid argument
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost ~]# echo "0" > //proc/acpi/fan/C31B/state
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost ~]# echo "4" > //proc/acpi/fan/C31B/state
-bash: echo: write error: Invalid argument
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost ~]# echo "3" > //proc/acpi/fan/C31B/state
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost ~]# echo "0" > //proc/acpi/fan/C31B/state
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost ~]# echo "3x" > //proc/acpi/fan/C31B/state
-bash: echo: write error: Invalid argument
[root@localhost ~]#
Signed-off-by: Yi Yang <yi.y.yang@intel.com>
Acked-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/fan.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 6cf10cb..55c17af 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -148,7 +148,7 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
int result = 0;
struct seq_file *m = file->private_data;
struct acpi_device *device = m->private;
- char state_string[12] = { '\0' };
+ char state_string[3] = { '\0' };
if (count > sizeof(state_string) - 1)
return -EINVAL;
@@ -157,6 +157,12 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
return -EFAULT;
state_string[count] = '\0';
+ if ((state_string[0] < '0') || (state_string[0] > '3'))
+ return -EINVAL;
+ if (state_string[1] == '\n')
+ state_string[1] = '\0';
+ if (state_string[1] != '\0')
+ return -EINVAL;
result = acpi_bus_set_power(device->handle,
simple_strtoul(state_string, NULL, 0));
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 34/70] ACPI Exception (video-1721): UNKNOWN_STATUS_CODE, Cant attach device
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (30 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 33/70] ACPI: fix acpi fan state set error Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 35/70] ACPI: no AC status notification Len Brown
` (35 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Zhang Rui, Len Brown
From: Zhang Rui <rui.zhang@intel.com>
The child of a video bus device is not alway a video device.
It should be a warn message rather than an exception here.
http://bugzilla.kernel.org/show_bug.cgi?id=9761
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/video.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 5e5dda3..d089c45 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1713,7 +1713,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
status = acpi_video_bus_get_one_device(dev, video);
if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "Cant attach device"));
+ ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+ "Cant attach device"));
continue;
}
}
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 35/70] ACPI: no AC status notification
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (31 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 34/70] ACPI Exception (video-1721): UNKNOWN_STATUS_CODE, Cant attach device Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 36/70] ACPICA: Fixes warning from exconfig.c on 64-bit build Len Brown
` (34 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Len Brown
From: Len Brown <len.brown@intel.com>
http://bugzilla.kernel.org/show_bug.cgi?id=10695
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/ac.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 5b73f6a..831883b 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -233,6 +233,9 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
device = ac->device;
switch (event) {
+ default:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Unsupported event [0x%x]\n", event));
case ACPI_AC_NOTIFY_STATUS:
case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK:
@@ -244,11 +247,6 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
#ifdef CONFIG_ACPI_SYSFS_POWER
kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
#endif
- break;
- default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
- break;
}
return;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 36/70] ACPICA: Fixes warning from exconfig.c on 64-bit build.
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (32 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 35/70] ACPI: no AC status notification Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 37/70] ACPI: fix processor throttling set error Len Brown
` (33 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bob Moore, Len Brown
From: Bob Moore <robert.moore@intel.com>
drivers/acpi/executer/exconfig.c:99: warning: cast to pointer from integer of different size
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/executer/exconfig.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index dc62bfe..641ed8e 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -96,7 +96,7 @@ acpi_ex_add_table(u32 table_index,
/* Install the new table into the local data structures */
- obj_desc->reference.object = ACPI_CAST_PTR(void, table_index);
+ obj_desc->reference.object = ACPI_TO_POINTER(table_index);
/* Add the table to the namespace */
@@ -359,6 +359,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer,
length);
+ table_desc.address = ACPI_TO_INTEGER (table_desc.pointer);
table_desc.length = length;
table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
break;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 37/70] ACPI: fix processor throttling set error
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (33 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 36/70] ACPICA: Fixes warning from exconfig.c on 64-bit build Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 38/70] acpi: fix printk format warning Len Brown
` (32 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Yi Yang, Len Brown
From: Yi Yang <yi.y.yang@intel.com>
http://bugzilla.kernel.org/show_bug.cgi?id=9704
When echo some invalid values to /proc/acpi/processor/*/throttling,
there isn't any error info returned, on the contray, it sets
throttling value to some T* successfully, obviously, this is incorrect,
a correct way should be to let it fail and return error info.
This patch fixed the aforementioned issue, it also enables
/proc/acpi/processor/*/throttling to accept such values as 't0' and 'T0',
it also strictly limits /proc/acpi/processor/*/throttling only to accept
"*", "t*" and "T*", "*" is the throttling state value the processor can
support, current, it is 0 - 7.
Before applying this patch, the test result is below:
[root@localhost acpi]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T1
state available: T0 to T7
states:
T0: 100%
*T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
T7: 12%
[root@localhost acpi]# echo "1xxxxxx" > /proc/acpi/processor/CPU0/throttling
[root@localhost acpi]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T1
state available: T0 to T7
states:
T0: 100%
*T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
T7: 12%
[root@localhost acpi]# echo "0" > /proc/acpi/processor/CPU0/throttling
[root@localhost acpi]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T0
state available: T0 to T7
states:
*T0: 100%
T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
T7: 12%
[root@localhost acpi]# cd /
[root@localhost /]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T0
state available: T0 to T7
states:
*T0: 100%
T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
T7: 12%
[root@localhost /]# echo "T0" > /proc/acpi/processor/CPU0/throttling
[root@localhost /]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T0
state available: T0 to T7
states:
*T0: 100%
T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
T7: 12%
[root@localhost /]# echo "T7" > /proc/acpi/processor/CPU0/throttling
[root@localhost /]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T0
state available: T0 to T7
states:
*T0: 100%
T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
T7: 12%
[root@localhost /]# echo "T100" > /proc/acpi/processor/CPU0/throttling
[root@localhost /]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T0
state available: T0 to T7
states:
*T0: 100%
T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
T7: 12%
[root@localhost /]# echo "xxx" > /proc/acpi/processor/CPU0/throttling
[root@localhost /]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T0
state available: T0 to T7
states:
*T0: 100%
T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
T7: 12%
[root@localhost /]# echo "2xxxx" > /proc/acpi/processor/CPU0/throttling
[root@localhost /]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T2
state available: T0 to T7
states:
T0: 100%
T1: 87%
*T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
T7: 12%
[root@localhost /]# echo "" > /proc/acpi/processor/CPU0/throttling
[root@localhost /]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T0
state available: T0 to T7
states:
*T0: 100%
T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
T7: 12%
[root@localhost /]# echo "7777" > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost /]# echo "7xxx" > /proc/acpi/processor/CPU0/throttling
[root@localhost /]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T7
state available: T0 to T7
states:
T0: 100%
T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
*T7: 12%
[root@localhost /]#
After applying this patch, the test result is below:
[root@localhost linux-2.6.24-rc6]# echo > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost linux-2.6.24-rc6]# echo "" > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost linux-2.6.24-rc6]# echo "0" > /proc/acpi/processor/CPU0/throttling
[root@localhost linux-2.6.24-rc6]# echo "t0" > /proc/acpi/processor/CPU0/throttling
[root@localhost linux-2.6.24-rc6]# echo "T0" > /proc/acpi/processor/CPU0/throttling
[root@localhost linux-2.6.24-rc6]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T0
state available: T0 to T7
states:
*T0: 100%
T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
T7: 12%
[root@localhost linux-2.6.24-rc6]# echo "T7" > /proc/acpi/processor/CPU0/throttling
[root@localhost linux-2.6.24-rc6]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T7
state available: T0 to T7
states:
T0: 100%
T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
*T7: 12%
[root@localhost linux-2.6.24-rc6]# echo "T8" > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost linux-2.6.24-rc6]# vi drivers/acpi/processor_throttling.c
[root@localhost linux-2.6.24-rc6]# echo "T8" > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost linux-2.6.24-rc6]# echo "t7" > /proc/acpi/processor/CPU0/throttling
[root@localhost linux-2.6.24-rc6]# echo "t70" > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost linux-2.6.24-rc6]# echo "70" > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost linux-2.6.24-rc6]# echo "7000" > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost linux-2.6.24-rc6]# echo "70" > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost linux-2.6.24-rc6]# echo "xxx" > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost linux-2.6.24-rc6]# echo > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost linux-2.6.24-rc6]# echo -n > /proc/acpi/processor/CPU0/throttling
[root@localhost linux-2.6.24-rc6]# echo -n "" > /proc/acpi/processor/CPU0/throttling
[root@localhost linux-2.6.24-rc6]# echo $?
0
[root@localhost linux-2.6.24-rc6]# echo -n "" > /proc/acpi/processor/CPU0/throttling
[root@localhost linux-2.6.24-rc6]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T7
state available: T0 to T7
states:
T0: 100%
T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
*T7: 12%
[root@localhost linux-2.6.24-rc6]# echo -n "" > /proc/acpi/processor/CPU0/throttling
[root@localhost linux-2.6.24-rc6]# cat /proc/acpi/processor/CPU0/throttling
state count: 8
active state: T7
state available: T0 to T7
states:
T0: 100%
T1: 87%
T2: 75%
T3: 62%
T4: 50%
T5: 37%
T6: 25%
*T7: 12%
[root@localhost linux-2.6.24-rc6]# echo t0 > /proc/acpi/processor/CPU0/throttling
[root@localhost linux-2.6.24-rc6]# echo T0 > /proc/acpi/processor/CPU0/throttling
[root@localhost linux-2.6.24-rc6]# echo Tt0 > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost linux-2.6.24-rc6]# echo T > /proc/acpi/processor/CPU0/throttling
-bash: echo: write error: Invalid argument
[root@localhost linux-2.6.24-rc6]#
Signed-off-by: Yi Yang <yi.y.yang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/processor_throttling.c | 24 ++++++++++++++++++++----
1 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index bb06738..4d4d8d8 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -1232,7 +1232,10 @@ static ssize_t acpi_processor_write_throttling(struct file *file,
int result = 0;
struct seq_file *m = file->private_data;
struct acpi_processor *pr = m->private;
- char state_string[12] = { '\0' };
+ char state_string[5] = "";
+ char *charp = NULL;
+ size_t state_val = 0;
+ char tmpbuf[5] = "";
if (!pr || (count > sizeof(state_string) - 1))
return -EINVAL;
@@ -1241,10 +1244,23 @@ static ssize_t acpi_processor_write_throttling(struct file *file,
return -EFAULT;
state_string[count] = '\0';
+ if ((count > 0) && (state_string[count-1] == '\n'))
+ state_string[count-1] = '\0';
- result = acpi_processor_set_throttling(pr,
- simple_strtoul(state_string,
- NULL, 0));
+ charp = state_string;
+ if ((state_string[0] == 't') || (state_string[0] == 'T'))
+ charp++;
+
+ state_val = simple_strtoul(charp, NULL, 0);
+ if (state_val >= pr->throttling.state_count)
+ return -EINVAL;
+
+ snprintf(tmpbuf, 5, "%d", state_val);
+
+ if (strcmp(tmpbuf, charp) != 0)
+ return -EINVAL;
+
+ result = acpi_processor_set_throttling(pr, state_val);
if (result)
return result;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 38/70] acpi: fix printk format warning
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (34 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 37/70] ACPI: fix processor throttling set error Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 39/70] PNP: add detail to debug resource dump Len Brown
` (31 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Randy Dunlap, Len Brown
From: Randy Dunlap <randy.dunlap@oracle.com>
Fix printk format warning:
linux-next-20080617/drivers/acpi/processor_throttling.c:1258: warning: format '%d' expects type 'int', but argument 4 has type 'size_t'
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/processor_throttling.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 4d4d8d8..a078f3f 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -1255,7 +1255,7 @@ static ssize_t acpi_processor_write_throttling(struct file *file,
if (state_val >= pr->throttling.state_count)
return -EINVAL;
- snprintf(tmpbuf, 5, "%d", state_val);
+ snprintf(tmpbuf, 5, "%zu", state_val);
if (strcmp(tmpbuf, charp) != 0)
return -EINVAL;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 39/70] PNP: add detail to debug resource dump
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (35 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 38/70] acpi: fix printk format warning Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 40/70] PNP: remove pnp_resource.index Len Brown
` (30 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
In the debug resource dump, decode the flags and indicate when
a resource is disabled or has been automatically assigned.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/support.c | 34 ++++++++++++++++++++++++++--------
1 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index 95b076c..7f594cc 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -63,28 +63,46 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
for (i = 0; i < PNP_MAX_IRQ; i++) {
res = pnp_get_resource(dev, IORESOURCE_IRQ, i);
if (res && !(res->flags & IORESOURCE_UNSET))
- dev_dbg(&dev->dev, " irq %lld flags %#lx\n",
- (unsigned long long) res->start, res->flags);
+ dev_dbg(&dev->dev, " irq %lld flags %#lx%s%s\n",
+ (unsigned long long) res->start, res->flags,
+ res->flags & IORESOURCE_DISABLED ?
+ " DISABLED" : "",
+ res->flags & IORESOURCE_AUTO ?
+ " AUTO" : "");
}
for (i = 0; i < PNP_MAX_DMA; i++) {
res = pnp_get_resource(dev, IORESOURCE_DMA, i);
if (res && !(res->flags & IORESOURCE_UNSET))
- dev_dbg(&dev->dev, " dma %lld flags %#lx\n",
- (unsigned long long) res->start, res->flags);
+ dev_dbg(&dev->dev, " dma %lld flags %#lx%s%s\n",
+ (unsigned long long) res->start, res->flags,
+ res->flags & IORESOURCE_DISABLED ?
+ " DISABLED" : "",
+ res->flags & IORESOURCE_AUTO ?
+ " AUTO" : "");
}
for (i = 0; i < PNP_MAX_PORT; i++) {
res = pnp_get_resource(dev, IORESOURCE_IO, i);
if (res && !(res->flags & IORESOURCE_UNSET))
- dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx\n",
+ dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx"
+ "%s%s\n",
(unsigned long long) res->start,
- (unsigned long long) res->end, res->flags);
+ (unsigned long long) res->end, res->flags,
+ res->flags & IORESOURCE_DISABLED ?
+ " DISABLED" : "",
+ res->flags & IORESOURCE_AUTO ?
+ " AUTO" : "");
}
for (i = 0; i < PNP_MAX_MEM; i++) {
res = pnp_get_resource(dev, IORESOURCE_MEM, i);
if (res && !(res->flags & IORESOURCE_UNSET))
- dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx\n",
+ dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx"
+ "%s%s\n",
(unsigned long long) res->start,
- (unsigned long long) res->end, res->flags);
+ (unsigned long long) res->end, res->flags,
+ res->flags & IORESOURCE_DISABLED ?
+ " DISABLED" : "",
+ res->flags & IORESOURCE_AUTO ?
+ " AUTO" : "");
}
#endif
}
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 40/70] PNP: remove pnp_resource.index
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (36 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 39/70] PNP: add detail to debug resource dump Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 41/70] PNP: add pnp_resource_type() internal interface Len Brown
` (29 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
We used pnp_resource.index to keep track of which ISAPNP configuration
register a resource should be written to. We needed this only to
handle the case where a register is disabled but a subsequent register
in the same set is enabled.
Rather than explicitly maintaining the pnp_resource.index, this patch
adds a resource every time we read an ISAPNP configuration register
and marks the resource as IORESOURCE_DISABLED when appropriate. This
makes the position in the pnp_resource_table always correspond to the
config register index.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/base.h | 1 -
drivers/pnp/interface.c | 20 ++--------
drivers/pnp/isapnp/core.c | 84 +++++++++++++++-----------------------------
drivers/pnp/manager.c | 4 --
4 files changed, 33 insertions(+), 76 deletions(-)
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 886dac8..6f60097 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -57,7 +57,6 @@ struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
struct pnp_resource {
struct resource res;
- unsigned int index; /* ISAPNP config register index */
};
struct pnp_resource_table {
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 5695a79..3f8007a 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -320,7 +320,6 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
const char *ubuf, size_t count)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
- struct pnp_resource *pnp_res;
char *buf = (void *)ubuf;
int retval = 0;
resource_size_t start, end;
@@ -368,7 +367,6 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
goto done;
}
if (!strnicmp(buf, "set", 3)) {
- int nport = 0, nmem = 0, nirq = 0, ndma = 0;
if (dev->active)
goto done;
buf += 3;
@@ -391,10 +389,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
end = simple_strtoul(buf, &buf, 0);
} else
end = start;
- pnp_res = pnp_add_io_resource(dev, start, end,
- 0);
- if (pnp_res)
- pnp_res->index = nport++;
+ pnp_add_io_resource(dev, start, end, 0);
continue;
}
if (!strnicmp(buf, "mem", 3)) {
@@ -411,10 +406,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
end = simple_strtoul(buf, &buf, 0);
} else
end = start;
- pnp_res = pnp_add_mem_resource(dev, start, end,
- 0);
- if (pnp_res)
- pnp_res->index = nmem++;
+ pnp_add_mem_resource(dev, start, end, 0);
continue;
}
if (!strnicmp(buf, "irq", 3)) {
@@ -422,9 +414,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
while (isspace(*buf))
++buf;
start = simple_strtoul(buf, &buf, 0);
- pnp_res = pnp_add_irq_resource(dev, start, 0);
- if (pnp_res)
- pnp_res->index = nirq++;
+ pnp_add_irq_resource(dev, start, 0);
continue;
}
if (!strnicmp(buf, "dma", 3)) {
@@ -432,9 +422,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
while (isspace(*buf))
++buf;
start = simple_strtoul(buf, &buf, 0);
- pnp_res = pnp_add_dma_resource(dev, start, 0);
- if (pnp_res)
- pnp_res->index = ndma++;
+ pnp_add_dma_resource(dev, start, 0);
continue;
}
break;
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index f1bccdb..752b51f 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -928,7 +928,6 @@ EXPORT_SYMBOL(isapnp_write_byte);
static int isapnp_get_resources(struct pnp_dev *dev)
{
- struct pnp_resource *pnp_res;
int i, ret;
dev_dbg(&dev->dev, "get resources\n");
@@ -940,35 +939,23 @@ static int isapnp_get_resources(struct pnp_dev *dev)
for (i = 0; i < ISAPNP_MAX_PORT; i++) {
ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1));
- if (ret) {
- pnp_res = pnp_add_io_resource(dev, ret, ret, 0);
- if (pnp_res)
- pnp_res->index = i;
- }
+ pnp_add_io_resource(dev, ret, ret,
+ ret == 0 ? IORESOURCE_DISABLED : 0);
}
for (i = 0; i < ISAPNP_MAX_MEM; i++) {
ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8;
- if (ret) {
- pnp_res = pnp_add_mem_resource(dev, ret, ret, 0);
- if (pnp_res)
- pnp_res->index = i;
- }
+ pnp_add_mem_resource(dev, ret, ret,
+ ret == 0 ? IORESOURCE_DISABLED : 0);
}
for (i = 0; i < ISAPNP_MAX_IRQ; i++) {
ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8;
- if (ret) {
- pnp_res = pnp_add_irq_resource(dev, ret, 0);
- if (pnp_res)
- pnp_res->index = i;
- }
+ pnp_add_irq_resource(dev, ret,
+ ret == 0 ? IORESOURCE_DISABLED : 0);
}
for (i = 0; i < ISAPNP_MAX_DMA; i++) {
ret = isapnp_read_byte(ISAPNP_CFG_DMA + i);
- if (ret != 4) {
- pnp_res = pnp_add_dma_resource(dev, ret, 0);
- if (pnp_res)
- pnp_res->index = i;
- }
+ pnp_add_dma_resource(dev, ret,
+ ret == 4 ? IORESOURCE_DISABLED : 0);
}
__end:
@@ -978,62 +965,49 @@ __end:
static int isapnp_set_resources(struct pnp_dev *dev)
{
- struct pnp_resource *pnp_res;
struct resource *res;
- int tmp, index;
+ int tmp;
dev_dbg(&dev->dev, "set resources\n");
isapnp_cfg_begin(dev->card->number, dev->number);
dev->active = 1;
for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
- pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, tmp);
- if (!pnp_res)
- continue;
- res = &pnp_res->res;
- if (pnp_resource_valid(res)) {
- index = pnp_res->index;
+ res = pnp_get_resource(dev, IORESOURCE_IO, tmp);
+ if (res && pnp_resource_valid(res) &&
+ !(res->flags & IORESOURCE_DISABLED)) {
dev_dbg(&dev->dev, " set io %d to %#llx\n",
- index, (unsigned long long) res->start);
- isapnp_write_word(ISAPNP_CFG_PORT + (index << 1),
+ tmp, (unsigned long long) res->start);
+ isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
res->start);
}
}
for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
- pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, tmp);
- if (!pnp_res)
- continue;
- res = &pnp_res->res;
- if (pnp_resource_valid(res)) {
+ res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp);
+ if (res && pnp_resource_valid(res) &&
+ !(res->flags & IORESOURCE_DISABLED)) {
int irq = res->start;
if (irq == 2)
irq = 9;
- index = pnp_res->index;
- dev_dbg(&dev->dev, " set irq %d to %d\n", index, irq);
- isapnp_write_byte(ISAPNP_CFG_IRQ + (index << 1), irq);
+ dev_dbg(&dev->dev, " set irq %d to %d\n", tmp, irq);
+ isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq);
}
}
for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
- pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, tmp);
- if (!pnp_res)
- continue;
- res = &pnp_res->res;
- if (pnp_resource_valid(res)) {
- index = pnp_res->index;
+ res = pnp_get_resource(dev, IORESOURCE_DMA, tmp);
+ if (res && pnp_resource_valid(res) &&
+ !(res->flags & IORESOURCE_DISABLED)) {
dev_dbg(&dev->dev, " set dma %d to %lld\n",
- index, (unsigned long long) res->start);
- isapnp_write_byte(ISAPNP_CFG_DMA + index, res->start);
+ tmp, (unsigned long long) res->start);
+ isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start);
}
}
for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
- pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, tmp);
- if (!pnp_res)
- continue;
- res = &pnp_res->res;
- if (pnp_resource_valid(res)) {
- index = pnp_res->index;
+ res = pnp_get_resource(dev, IORESOURCE_MEM, tmp);
+ if (res && pnp_resource_valid(res) &&
+ !(res->flags & IORESOURCE_DISABLED)) {
dev_dbg(&dev->dev, " set mem %d to %#llx\n",
- index, (unsigned long long) res->start);
- isapnp_write_word(ISAPNP_CFG_MEM + (index << 3),
+ tmp, (unsigned long long) res->start);
+ isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
(res->start >> 8) & 0xffff);
}
}
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index bea0914..90bd9cb 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -40,7 +40,6 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
}
/* set the initial values */
- pnp_res->index = idx;
res->flags |= rule->flags | IORESOURCE_IO;
res->flags &= ~IORESOURCE_UNSET;
@@ -90,7 +89,6 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
}
/* set the initial values */
- pnp_res->index = idx;
res->flags |= rule->flags | IORESOURCE_MEM;
res->flags &= ~IORESOURCE_UNSET;
@@ -155,7 +153,6 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
}
/* set the initial values */
- pnp_res->index = idx;
res->flags |= rule->flags | IORESOURCE_IRQ;
res->flags &= ~IORESOURCE_UNSET;
@@ -214,7 +211,6 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
}
/* set the initial values */
- pnp_res->index = idx;
res->flags |= rule->flags | IORESOURCE_DMA;
res->flags &= ~IORESOURCE_UNSET;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 41/70] PNP: add pnp_resource_type() internal interface
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (37 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 40/70] PNP: remove pnp_resource.index Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 42/70] PNP: add pnp_resource_type_name() helper function Len Brown
` (28 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
Given a struct resource, this returns the type (IO, MEM, IRQ, DMA).
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/base.h | 1 +
drivers/pnp/resource.c | 6 ++++++
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 6f60097..4c2a625 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -46,6 +46,7 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res);
void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc);
void pnp_init_resource(struct resource *res);
+int pnp_resource_type(struct resource *res);
struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
unsigned int type, unsigned int num);
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 390b500..cce341f 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -499,6 +499,12 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
#endif
}
+int pnp_resource_type(struct resource *res)
+{
+ return res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
+ IORESOURCE_IRQ | IORESOURCE_DMA);
+}
+
struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
unsigned int type, unsigned int num)
{
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 42/70] PNP: add pnp_resource_type_name() helper function
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (38 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 41/70] PNP: add pnp_resource_type() internal interface Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 43/70] PNP: make pnp_{port,mem,etc}_start(), et al work for invalid resources Len Brown
` (27 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
This patch adds a "pnp_resource_type_name(struct resource *)" that
returns the string resource type. This will be used by the sysfs
"show resources" function and the debug resource dump function.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/base.h | 1 +
drivers/pnp/support.c | 15 +++++++++++++++
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 4c2a625..c913158 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -43,6 +43,7 @@ int pnp_check_mem(struct pnp_dev *dev, struct resource *res);
int pnp_check_irq(struct pnp_dev *dev, struct resource *res);
int pnp_check_dma(struct pnp_dev *dev, struct resource *res);
+char *pnp_resource_type_name(struct resource *res);
void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc);
void pnp_init_resource(struct resource *res);
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index 7f594cc..eb07345 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -52,6 +52,21 @@ void pnp_eisa_id_to_string(u32 id, char *str)
str[7] = '\0';
}
+char *pnp_resource_type_name(struct resource *res)
+{
+ switch (pnp_resource_type(res)) {
+ case IORESOURCE_IO:
+ return "io";
+ case IORESOURCE_MEM:
+ return "mem";
+ case IORESOURCE_IRQ:
+ return "irq";
+ case IORESOURCE_DMA:
+ return "dma";
+ }
+ return NULL;
+}
+
void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
{
#ifdef DEBUG
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 43/70] PNP: make pnp_{port,mem,etc}_start(), et al work for invalid resources
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (39 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 42/70] PNP: add pnp_resource_type_name() helper function Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 44/70] PNP: replace pnp_resource_table with dynamically allocated resources Len Brown
` (26 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
Some callers use pnp_port_start() and similar functions without
making sure the resource is valid. This patch makes us fall
back to returning the initial values if the resource is not
valid or not even present.
This mostly preserves the previous behavior, where we would just
return the initial values set by pnp_init_resource_table(). The
original 2.6.25 code didn't range-check the "bar", so it would
return garbage if the bar exceeded the table size. This code
returns sensible values instead.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
include/linux/pnp.h | 72 ++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 60 insertions(+), 12 deletions(-)
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 63b128d..8b607ae 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -40,19 +40,31 @@ static inline resource_size_t pnp_resource_len(struct resource *res)
static inline resource_size_t pnp_port_start(struct pnp_dev *dev,
unsigned int bar)
{
- return pnp_get_resource(dev, IORESOURCE_IO, bar)->start;
+ struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar);
+
+ if (pnp_resource_valid(res))
+ return res->start;
+ return 0;
}
static inline resource_size_t pnp_port_end(struct pnp_dev *dev,
unsigned int bar)
{
- return pnp_get_resource(dev, IORESOURCE_IO, bar)->end;
+ struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar);
+
+ if (pnp_resource_valid(res))
+ return res->end;
+ return 0;
}
static inline unsigned long pnp_port_flags(struct pnp_dev *dev,
unsigned int bar)
{
- return pnp_get_resource(dev, IORESOURCE_IO, bar)->flags;
+ struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar);
+
+ if (pnp_resource_valid(res))
+ return res->flags;
+ return IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
}
static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar)
@@ -63,25 +75,41 @@ static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar)
static inline resource_size_t pnp_port_len(struct pnp_dev *dev,
unsigned int bar)
{
- return pnp_resource_len(pnp_get_resource(dev, IORESOURCE_IO, bar));
+ struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar);
+
+ if (pnp_resource_valid(res))
+ return pnp_resource_len(res);
+ return 0;
}
static inline resource_size_t pnp_mem_start(struct pnp_dev *dev,
unsigned int bar)
{
- return pnp_get_resource(dev, IORESOURCE_MEM, bar)->start;
+ struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar);
+
+ if (pnp_resource_valid(res))
+ return res->start;
+ return 0;
}
static inline resource_size_t pnp_mem_end(struct pnp_dev *dev,
unsigned int bar)
{
- return pnp_get_resource(dev, IORESOURCE_MEM, bar)->end;
+ struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar);
+
+ if (pnp_resource_valid(res))
+ return res->end;
+ return 0;
}
static inline unsigned long pnp_mem_flags(struct pnp_dev *dev, unsigned int bar)
{
- return pnp_get_resource(dev, IORESOURCE_MEM, bar)->flags;
+ struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar);
+
+ if (pnp_resource_valid(res))
+ return res->flags;
+ return IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
}
static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar)
@@ -92,18 +120,30 @@ static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar)
static inline resource_size_t pnp_mem_len(struct pnp_dev *dev,
unsigned int bar)
{
- return pnp_resource_len(pnp_get_resource(dev, IORESOURCE_MEM, bar));
+ struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar);
+
+ if (pnp_resource_valid(res))
+ return pnp_resource_len(res);
+ return 0;
}
static inline resource_size_t pnp_irq(struct pnp_dev *dev, unsigned int bar)
{
- return pnp_get_resource(dev, IORESOURCE_IRQ, bar)->start;
+ struct resource *res = pnp_get_resource(dev, IORESOURCE_IRQ, bar);
+
+ if (pnp_resource_valid(res))
+ return res->start;
+ return -1;
}
static inline unsigned long pnp_irq_flags(struct pnp_dev *dev, unsigned int bar)
{
- return pnp_get_resource(dev, IORESOURCE_IRQ, bar)->flags;
+ struct resource *res = pnp_get_resource(dev, IORESOURCE_IRQ, bar);
+
+ if (pnp_resource_valid(res))
+ return res->flags;
+ return IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
}
static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar)
@@ -114,12 +154,20 @@ static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar)
static inline resource_size_t pnp_dma(struct pnp_dev *dev, unsigned int bar)
{
- return pnp_get_resource(dev, IORESOURCE_DMA, bar)->start;
+ struct resource *res = pnp_get_resource(dev, IORESOURCE_DMA, bar);
+
+ if (pnp_resource_valid(res))
+ return res->start;
+ return -1;
}
static inline unsigned long pnp_dma_flags(struct pnp_dev *dev, unsigned int bar)
{
- return pnp_get_resource(dev, IORESOURCE_DMA, bar)->flags;
+ struct resource *res = pnp_get_resource(dev, IORESOURCE_DMA, bar);
+
+ if (pnp_resource_valid(res))
+ return res->flags;
+ return IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
}
static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar)
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 44/70] PNP: replace pnp_resource_table with dynamically allocated resources
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (40 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 43/70] PNP: make pnp_{port,mem,etc}_start(), et al work for invalid resources Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 45/70] PNPACPI: keep disabled resources when parsing current config Len Brown
` (25 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
PNP used to have a fixed-size pnp_resource_table for tracking the
resources used by a device. This table often overflowed, so we've
had to increase the table size, which wastes memory because most
devices have very few resources.
This patch replaces the table with a linked list of resources where
the entries are allocated on demand.
This removes messages like these:
pnpacpi: exceeded the max number of IO resources
00:01: too many I/O port resources
References:
http://bugzilla.kernel.org/show_bug.cgi?id=9535
http://bugzilla.kernel.org/show_bug.cgi?id=9740
http://lkml.org/lkml/2007/11/30/110
This patch also changes the way PNP uses the IORESOURCE_UNSET,
IORESOURCE_AUTO, and IORESOURCE_DISABLED flags.
Prior to this patch, the pnp_resource_table entries used the flags
like this:
IORESOURCE_UNSET
This table entry is unused and available for use. When this flag
is set, we shouldn't look at anything else in the resource structure.
This flag is set when a resource table entry is initialized.
IORESOURCE_AUTO
This resource was assigned automatically by pnp_assign_{io,mem,etc}().
This flag is set when a resource table entry is initialized and
cleared whenever we discover a resource setting by reading an ISAPNP
config register, parsing a PNPBIOS resource data stream, parsing an
ACPI _CRS list, or interpreting a sysfs "set" command.
Resources marked IORESOURCE_AUTO are reinitialized and marked as
IORESOURCE_UNSET by pnp_clean_resource_table() in these cases:
- before we attempt to assign resources automatically,
- if we fail to assign resources automatically,
- after disabling a device
IORESOURCE_DISABLED
Set by pnp_assign_{io,mem,etc}() when automatic assignment fails.
Also set by PNPBIOS and PNPACPI for:
- invalid IRQs or GSI registration failures
- invalid DMA channels
- I/O ports above 0x10000
- mem ranges with negative length
After this patch, there is no pnp_resource_table, and the resource list
entries use the flags like this:
IORESOURCE_UNSET
This flag is no longer used in PNP. Instead of keeping
IORESOURCE_UNSET entries in the resource list, we remove
entries from the list and free them.
IORESOURCE_AUTO
No change in meaning: it still means the resource was assigned
automatically by pnp_assign_{port,mem,etc}(), but these functions
now set the bit explicitly.
We still "clean" a device's resource list in the same places,
but rather than reinitializing IORESOURCE_AUTO entries, we
just remove them from the list.
Note that IORESOURCE_AUTO entries are always at the end of the
list, so removing them doesn't reorder other list entries.
This is because non-IORESOURCE_AUTO entries are added by the
ISAPNP, PNPBIOS, or PNPACPI "get resources" methods and by the
sysfs "set" command. In each of these cases, we completely free
the resource list first.
IORESOURCE_DISABLED
In addition to the cases where we used to set this flag, ISAPNP now
adds an IORESOURCE_DISABLED resource when it reads a configuration
register with a "disabled" value.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/base.h | 18 +---
drivers/pnp/core.c | 25 +++--
drivers/pnp/interface.c | 60 +++++------
drivers/pnp/isapnp/core.c | 12 +--
drivers/pnp/manager.c | 220 ++++++++++------------------------------
drivers/pnp/pnpacpi/rsparser.c | 129 ++++++++++++++++--------
drivers/pnp/pnpbios/rsparser.c | 95 +++++++++++++-----
drivers/pnp/quirks.c | 3 +-
drivers/pnp/resource.c | 86 ++++------------
drivers/pnp/support.c | 72 +++++--------
drivers/pnp/system.c | 4 +-
include/linux/pnp.h | 20 +++--
12 files changed, 323 insertions(+), 421 deletions(-)
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index c913158..1667ac3 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -46,27 +46,15 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res);
char *pnp_resource_type_name(struct resource *res);
void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc);
-void pnp_init_resource(struct resource *res);
+void pnp_free_resources(struct pnp_dev *dev);
int pnp_resource_type(struct resource *res);
-struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
- unsigned int type, unsigned int num);
-
-#define PNP_MAX_PORT 40
-#define PNP_MAX_MEM 24
-#define PNP_MAX_IRQ 2
-#define PNP_MAX_DMA 2
-
struct pnp_resource {
+ struct list_head list;
struct resource res;
};
-struct pnp_resource_table {
- struct pnp_resource port[PNP_MAX_PORT];
- struct pnp_resource mem[PNP_MAX_MEM];
- struct pnp_resource dma[PNP_MAX_DMA];
- struct pnp_resource irq[PNP_MAX_IRQ];
-};
+void pnp_free_resource(struct pnp_resource *pnp_res);
struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
int flags);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 20771b7..7182da9 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -99,6 +99,21 @@ static void pnp_free_ids(struct pnp_dev *dev)
}
}
+void pnp_free_resource(struct pnp_resource *pnp_res)
+{
+ list_del(&pnp_res->list);
+ kfree(pnp_res);
+}
+
+void pnp_free_resources(struct pnp_dev *dev)
+{
+ struct pnp_resource *pnp_res, *tmp;
+
+ list_for_each_entry_safe(pnp_res, tmp, &dev->resources, list) {
+ pnp_free_resource(pnp_res);
+ }
+}
+
static void pnp_release_device(struct device *dmdev)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
@@ -106,7 +121,7 @@ static void pnp_release_device(struct device *dmdev)
pnp_free_option(dev->independent);
pnp_free_option(dev->dependent);
pnp_free_ids(dev);
- kfree(dev->res);
+ pnp_free_resources(dev);
kfree(dev);
}
@@ -119,12 +134,7 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
if (!dev)
return NULL;
- dev->res = kzalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
- if (!dev->res) {
- kfree(dev);
- return NULL;
- }
-
+ INIT_LIST_HEAD(&dev->resources);
dev->protocol = protocol;
dev->number = id;
dev->dma_mask = DMA_24BIT_MASK;
@@ -140,7 +150,6 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
dev_id = pnp_add_id(dev, pnpid);
if (!dev_id) {
- kfree(dev->res);
kfree(dev);
return NULL;
}
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 3f8007a..7fc86bb 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -269,46 +269,38 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
pnp_printf(buffer, "disabled\n");
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
- if (pnp_resource_valid(res)) {
- pnp_printf(buffer, "io");
- if (res->flags & IORESOURCE_DISABLED)
- pnp_printf(buffer, " disabled\n");
- else
- pnp_printf(buffer, " 0x%llx-0x%llx\n",
- (unsigned long long) res->start,
- (unsigned long long) res->end);
- }
+ pnp_printf(buffer, "io");
+ if (res->flags & IORESOURCE_DISABLED)
+ pnp_printf(buffer, " disabled\n");
+ else
+ pnp_printf(buffer, " 0x%llx-0x%llx\n",
+ (unsigned long long) res->start,
+ (unsigned long long) res->end);
}
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
- if (pnp_resource_valid(res)) {
- pnp_printf(buffer, "mem");
- if (res->flags & IORESOURCE_DISABLED)
- pnp_printf(buffer, " disabled\n");
- else
- pnp_printf(buffer, " 0x%llx-0x%llx\n",
- (unsigned long long) res->start,
- (unsigned long long) res->end);
- }
+ pnp_printf(buffer, "mem");
+ if (res->flags & IORESOURCE_DISABLED)
+ pnp_printf(buffer, " disabled\n");
+ else
+ pnp_printf(buffer, " 0x%llx-0x%llx\n",
+ (unsigned long long) res->start,
+ (unsigned long long) res->end);
}
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
- if (pnp_resource_valid(res)) {
- pnp_printf(buffer, "irq");
- if (res->flags & IORESOURCE_DISABLED)
- pnp_printf(buffer, " disabled\n");
- else
- pnp_printf(buffer, " %lld\n",
- (unsigned long long) res->start);
- }
+ pnp_printf(buffer, "irq");
+ if (res->flags & IORESOURCE_DISABLED)
+ pnp_printf(buffer, " disabled\n");
+ else
+ pnp_printf(buffer, " %lld\n",
+ (unsigned long long) res->start);
}
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) {
- if (pnp_resource_valid(res)) {
- pnp_printf(buffer, "dma");
- if (res->flags & IORESOURCE_DISABLED)
- pnp_printf(buffer, " disabled\n");
- else
- pnp_printf(buffer, " %lld\n",
- (unsigned long long) res->start);
- }
+ pnp_printf(buffer, "dma");
+ if (res->flags & IORESOURCE_DISABLED)
+ pnp_printf(buffer, " disabled\n");
+ else
+ pnp_printf(buffer, " %lld\n",
+ (unsigned long long) res->start);
}
ret = (buffer->curr - buf);
kfree(buffer);
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 752b51f..ca4457e 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -973,8 +973,7 @@ static int isapnp_set_resources(struct pnp_dev *dev)
dev->active = 1;
for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
res = pnp_get_resource(dev, IORESOURCE_IO, tmp);
- if (res && pnp_resource_valid(res) &&
- !(res->flags & IORESOURCE_DISABLED)) {
+ if (pnp_resource_enabled(res)) {
dev_dbg(&dev->dev, " set io %d to %#llx\n",
tmp, (unsigned long long) res->start);
isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
@@ -983,8 +982,7 @@ static int isapnp_set_resources(struct pnp_dev *dev)
}
for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp);
- if (res && pnp_resource_valid(res) &&
- !(res->flags & IORESOURCE_DISABLED)) {
+ if (pnp_resource_enabled(res)) {
int irq = res->start;
if (irq == 2)
irq = 9;
@@ -994,8 +992,7 @@ static int isapnp_set_resources(struct pnp_dev *dev)
}
for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
res = pnp_get_resource(dev, IORESOURCE_DMA, tmp);
- if (res && pnp_resource_valid(res) &&
- !(res->flags & IORESOURCE_DISABLED)) {
+ if (pnp_resource_enabled(res)) {
dev_dbg(&dev->dev, " set dma %d to %lld\n",
tmp, (unsigned long long) res->start);
isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start);
@@ -1003,8 +1000,7 @@ static int isapnp_set_resources(struct pnp_dev *dev)
}
for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
res = pnp_get_resource(dev, IORESOURCE_MEM, tmp);
- if (res && pnp_resource_valid(res) &&
- !(res->flags & IORESOURCE_DISABLED)) {
+ if (pnp_resource_enabled(res)) {
dev_dbg(&dev->dev, " set mem %d to %#llx\n",
tmp, (unsigned long long) res->start);
isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 90bd9cb..165b624 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -19,40 +19,30 @@ DEFINE_MUTEX(pnp_res_mutex);
static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
{
- struct pnp_resource *pnp_res;
- struct resource *res;
+ struct resource *res, local_res;
- pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, idx);
- if (!pnp_res) {
- dev_err(&dev->dev, "too many I/O port resources\n");
- /* pretend we were successful so at least the manager won't try again */
- return 1;
- }
-
- res = &pnp_res->res;
-
- /* check if this resource has been manually set, if so skip */
- if (!(res->flags & IORESOURCE_AUTO)) {
+ res = pnp_get_resource(dev, IORESOURCE_IO, idx);
+ if (res) {
dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
"flags %#lx\n", idx, (unsigned long long) res->start,
(unsigned long long) res->end, res->flags);
return 1;
}
- /* set the initial values */
- res->flags |= rule->flags | IORESOURCE_IO;
- res->flags &= ~IORESOURCE_UNSET;
+ res = &local_res;
+ res->flags = rule->flags | IORESOURCE_AUTO;
+ res->start = 0;
+ res->end = 0;
if (!rule->size) {
res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " io %d disabled\n", idx);
- return 1; /* skip disabled resource requests */
+ goto __add;
}
res->start = rule->min;
res->end = res->start + rule->size - 1;
- /* run through until pnp_check_port is happy */
while (!pnp_check_port(dev, res)) {
res->start += rule->align;
res->end = res->start + rule->size - 1;
@@ -61,38 +51,29 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
return 0;
}
}
- dev_dbg(&dev->dev, " assign io %d %#llx-%#llx\n", idx,
- (unsigned long long) res->start, (unsigned long long) res->end);
+
+__add:
+ pnp_add_io_resource(dev, res->start, res->end, res->flags);
return 1;
}
static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
{
- struct pnp_resource *pnp_res;
- struct resource *res;
+ struct resource *res, local_res;
- pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, idx);
- if (!pnp_res) {
- dev_err(&dev->dev, "too many memory resources\n");
- /* pretend we were successful so at least the manager won't try again */
- return 1;
- }
-
- res = &pnp_res->res;
-
- /* check if this resource has been manually set, if so skip */
- if (!(res->flags & IORESOURCE_AUTO)) {
+ res = pnp_get_resource(dev, IORESOURCE_MEM, idx);
+ if (res) {
dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
"flags %#lx\n", idx, (unsigned long long) res->start,
(unsigned long long) res->end, res->flags);
return 1;
}
- /* set the initial values */
- res->flags |= rule->flags | IORESOURCE_MEM;
- res->flags &= ~IORESOURCE_UNSET;
+ res = &local_res;
+ res->flags = rule->flags | IORESOURCE_AUTO;
+ res->start = 0;
+ res->end = 0;
- /* convert pnp flags to standard Linux flags */
if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
res->flags |= IORESOURCE_READONLY;
if (rule->flags & IORESOURCE_MEM_CACHEABLE)
@@ -105,13 +86,12 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
if (!rule->size) {
res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " mem %d disabled\n", idx);
- return 1; /* skip disabled resource requests */
+ goto __add;
}
res->start = rule->min;
res->end = res->start + rule->size - 1;
- /* run through until pnp_check_mem is happy */
while (!pnp_check_mem(dev, res)) {
res->start += rule->align;
res->end = res->start + rule->size - 1;
@@ -120,15 +100,15 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
return 0;
}
}
- dev_dbg(&dev->dev, " assign mem %d %#llx-%#llx\n", idx,
- (unsigned long long) res->start, (unsigned long long) res->end);
+
+__add:
+ pnp_add_mem_resource(dev, res->start, res->end, res->flags);
return 1;
}
static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
{
- struct pnp_resource *pnp_res;
- struct resource *res;
+ struct resource *res, local_res;
int i;
/* IRQ priority: this table is good for i386 */
@@ -136,58 +116,48 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
};
- pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, idx);
- if (!pnp_res) {
- dev_err(&dev->dev, "too many IRQ resources\n");
- /* pretend we were successful so at least the manager won't try again */
- return 1;
- }
-
- res = &pnp_res->res;
-
- /* check if this resource has been manually set, if so skip */
- if (!(res->flags & IORESOURCE_AUTO)) {
+ res = pnp_get_resource(dev, IORESOURCE_IRQ, idx);
+ if (res) {
dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
idx, (int) res->start, res->flags);
return 1;
}
- /* set the initial values */
- res->flags |= rule->flags | IORESOURCE_IRQ;
- res->flags &= ~IORESOURCE_UNSET;
+ res = &local_res;
+ res->flags = rule->flags | IORESOURCE_AUTO;
+ res->start = -1;
+ res->end = -1;
if (bitmap_empty(rule->map, PNP_IRQ_NR)) {
res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " irq %d disabled\n", idx);
- return 1; /* skip disabled resource requests */
+ goto __add;
}
/* TBD: need check for >16 IRQ */
res->start = find_next_bit(rule->map, PNP_IRQ_NR, 16);
if (res->start < PNP_IRQ_NR) {
res->end = res->start;
- dev_dbg(&dev->dev, " assign irq %d %d\n", idx,
- (int) res->start);
- return 1;
+ goto __add;
}
for (i = 0; i < 16; i++) {
if (test_bit(xtab[i], rule->map)) {
res->start = res->end = xtab[i];
- if (pnp_check_irq(dev, res)) {
- dev_dbg(&dev->dev, " assign irq %d %d\n", idx,
- (int) res->start);
- return 1;
- }
+ if (pnp_check_irq(dev, res))
+ goto __add;
}
}
dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx);
return 0;
+
+__add:
+ pnp_add_irq_resource(dev, res->start, res->flags);
+ return 1;
}
static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
{
- struct pnp_resource *pnp_res;
- struct resource *res;
+ struct resource *res, local_res;
int i;
/* DMA priority: this table is good for i386 */
@@ -195,127 +165,47 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
1, 3, 5, 6, 7, 0, 2, 4
};
- pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, idx);
- if (!pnp_res) {
- dev_err(&dev->dev, "too many DMA resources\n");
- return;
- }
-
- res = &pnp_res->res;
-
- /* check if this resource has been manually set, if so skip */
- if (!(res->flags & IORESOURCE_AUTO)) {
+ res = pnp_get_resource(dev, IORESOURCE_DMA, idx);
+ if (res) {
dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
idx, (int) res->start, res->flags);
return;
}
- /* set the initial values */
- res->flags |= rule->flags | IORESOURCE_DMA;
- res->flags &= ~IORESOURCE_UNSET;
+ res = &local_res;
+ res->flags = rule->flags | IORESOURCE_AUTO;
+ res->start = -1;
+ res->end = -1;
for (i = 0; i < 8; i++) {
if (rule->map & (1 << xtab[i])) {
res->start = res->end = xtab[i];
- if (pnp_check_dma(dev, res)) {
- dev_dbg(&dev->dev, " assign dma %d %d\n", idx,
- (int) res->start);
- return;
- }
+ if (pnp_check_dma(dev, res))
+ goto __add;
}
}
#ifdef MAX_DMA_CHANNELS
res->start = res->end = MAX_DMA_CHANNELS;
#endif
- res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
+ res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " disable dma %d\n", idx);
-}
-void pnp_init_resource(struct resource *res)
-{
- unsigned long type;
-
- type = res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
- IORESOURCE_IRQ | IORESOURCE_DMA);
-
- res->name = NULL;
- res->flags = type | IORESOURCE_AUTO | IORESOURCE_UNSET;
- if (type == IORESOURCE_IRQ || type == IORESOURCE_DMA) {
- res->start = -1;
- res->end = -1;
- } else {
- res->start = 0;
- res->end = 0;
- }
+__add:
+ pnp_add_dma_resource(dev, res->start, res->flags);
}
-/**
- * pnp_init_resources - Resets a resource table to default values.
- * @table: pointer to the desired resource table
- */
void pnp_init_resources(struct pnp_dev *dev)
{
- struct resource *res;
- int idx;
-
- for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
- res = &dev->res->irq[idx].res;
- res->flags = IORESOURCE_IRQ;
- pnp_init_resource(res);
- }
- for (idx = 0; idx < PNP_MAX_DMA; idx++) {
- res = &dev->res->dma[idx].res;
- res->flags = IORESOURCE_DMA;
- pnp_init_resource(res);
- }
- for (idx = 0; idx < PNP_MAX_PORT; idx++) {
- res = &dev->res->port[idx].res;
- res->flags = IORESOURCE_IO;
- pnp_init_resource(res);
- }
- for (idx = 0; idx < PNP_MAX_MEM; idx++) {
- res = &dev->res->mem[idx].res;
- res->flags = IORESOURCE_MEM;
- pnp_init_resource(res);
- }
+ pnp_free_resources(dev);
}
-/**
- * pnp_clean_resources - clears resources that were not manually set
- * @res: the resources to clean
- */
static void pnp_clean_resource_table(struct pnp_dev *dev)
{
- struct resource *res;
- int idx;
-
- for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
- res = &dev->res->irq[idx].res;
- if (res->flags & IORESOURCE_AUTO) {
- res->flags = IORESOURCE_IRQ;
- pnp_init_resource(res);
- }
- }
- for (idx = 0; idx < PNP_MAX_DMA; idx++) {
- res = &dev->res->dma[idx].res;
- if (res->flags & IORESOURCE_AUTO) {
- res->flags = IORESOURCE_DMA;
- pnp_init_resource(res);
- }
- }
- for (idx = 0; idx < PNP_MAX_PORT; idx++) {
- res = &dev->res->port[idx].res;
- if (res->flags & IORESOURCE_AUTO) {
- res->flags = IORESOURCE_IO;
- pnp_init_resource(res);
- }
- }
- for (idx = 0; idx < PNP_MAX_MEM; idx++) {
- res = &dev->res->mem[idx].res;
- if (res->flags & IORESOURCE_AUTO) {
- res->flags = IORESOURCE_MEM;
- pnp_init_resource(res);
- }
+ struct pnp_resource *pnp_res, *tmp;
+
+ list_for_each_entry_safe(pnp_res, tmp, &dev->resources, list) {
+ if (pnp_res->res.flags & IORESOURCE_AUTO)
+ pnp_free_resource(pnp_res);
}
}
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 46c791a..9a45c25 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -806,6 +806,13 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev,
struct acpi_resource_irq *irq = &resource->data.irq;
int triggering, polarity, shareable;
+ if (!pnp_resource_enabled(p)) {
+ irq->interrupt_count = 0;
+ dev_dbg(&dev->dev, " encode irq (%s)\n",
+ p ? "disabled" : "missing");
+ return;
+ }
+
decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
irq->triggering = triggering;
irq->polarity = polarity;
@@ -828,6 +835,13 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
int triggering, polarity, shareable;
+ if (!pnp_resource_enabled(p)) {
+ extended_irq->interrupt_count = 0;
+ dev_dbg(&dev->dev, " encode extended irq (%s)\n",
+ p ? "disabled" : "missing");
+ return;
+ }
+
decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
extended_irq->producer_consumer = ACPI_CONSUMER;
extended_irq->triggering = triggering;
@@ -848,6 +862,13 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev,
{
struct acpi_resource_dma *dma = &resource->data.dma;
+ if (!pnp_resource_enabled(p)) {
+ dma->channel_count = 0;
+ dev_dbg(&dev->dev, " encode dma (%s)\n",
+ p ? "disabled" : "missing");
+ return;
+ }
+
/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
case IORESOURCE_DMA_TYPEA:
@@ -889,17 +910,21 @@ static void pnpacpi_encode_io(struct pnp_dev *dev,
{
struct acpi_resource_io *io = &resource->data.io;
- /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
- io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
- ACPI_DECODE_16 : ACPI_DECODE_10;
- io->minimum = p->start;
- io->maximum = p->end;
- io->alignment = 0; /* Correct? */
- io->address_length = p->end - p->start + 1;
-
- dev_dbg(&dev->dev, " encode io %#llx-%#llx decode %#x\n",
- (unsigned long long) p->start, (unsigned long long) p->end,
- io->io_decode);
+ if (pnp_resource_enabled(p)) {
+ /* Note: pnp_assign_port copies pnp_port->flags into p->flags */
+ io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
+ ACPI_DECODE_16 : ACPI_DECODE_10;
+ io->minimum = p->start;
+ io->maximum = p->end;
+ io->alignment = 0; /* Correct? */
+ io->address_length = p->end - p->start + 1;
+ } else {
+ io->minimum = 0;
+ io->address_length = 0;
+ }
+
+ dev_dbg(&dev->dev, " encode io %#x-%#x decode %#x\n", io->minimum,
+ io->minimum + io->address_length - 1, io->io_decode);
}
static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
@@ -908,11 +933,16 @@ static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
{
struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;
- fixed_io->address = p->start;
- fixed_io->address_length = p->end - p->start + 1;
+ if (pnp_resource_enabled(p)) {
+ fixed_io->address = p->start;
+ fixed_io->address_length = p->end - p->start + 1;
+ } else {
+ fixed_io->address = 0;
+ fixed_io->address_length = 0;
+ }
- dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n",
- (unsigned long long) p->start, (unsigned long long) p->end);
+ dev_dbg(&dev->dev, " encode fixed_io %#x-%#x\n", fixed_io->address,
+ fixed_io->address + fixed_io->address_length - 1);
}
static void pnpacpi_encode_mem24(struct pnp_dev *dev,
@@ -921,17 +951,22 @@ static void pnpacpi_encode_mem24(struct pnp_dev *dev,
{
struct acpi_resource_memory24 *memory24 = &resource->data.memory24;
- /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
- memory24->write_protect =
- (p->flags & IORESOURCE_MEM_WRITEABLE) ?
- ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
- memory24->minimum = p->start;
- memory24->maximum = p->end;
- memory24->alignment = 0;
- memory24->address_length = p->end - p->start + 1;
-
- dev_dbg(&dev->dev, " encode mem24 %#llx-%#llx write_protect %#x\n",
- (unsigned long long) p->start, (unsigned long long) p->end,
+ if (pnp_resource_enabled(p)) {
+ /* Note: pnp_assign_mem copies pnp_mem->flags into p->flags */
+ memory24->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
+ ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
+ memory24->minimum = p->start;
+ memory24->maximum = p->end;
+ memory24->alignment = 0;
+ memory24->address_length = p->end - p->start + 1;
+ } else {
+ memory24->minimum = 0;
+ memory24->address_length = 0;
+ }
+
+ dev_dbg(&dev->dev, " encode mem24 %#x-%#x write_protect %#x\n",
+ memory24->minimum,
+ memory24->minimum + memory24->address_length - 1,
memory24->write_protect);
}
@@ -941,16 +976,21 @@ static void pnpacpi_encode_mem32(struct pnp_dev *dev,
{
struct acpi_resource_memory32 *memory32 = &resource->data.memory32;
- memory32->write_protect =
- (p->flags & IORESOURCE_MEM_WRITEABLE) ?
- ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
- memory32->minimum = p->start;
- memory32->maximum = p->end;
- memory32->alignment = 0;
- memory32->address_length = p->end - p->start + 1;
+ if (pnp_resource_enabled(p)) {
+ memory32->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
+ ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
+ memory32->minimum = p->start;
+ memory32->maximum = p->end;
+ memory32->alignment = 0;
+ memory32->address_length = p->end - p->start + 1;
+ } else {
+ memory32->minimum = 0;
+ memory32->alignment = 0;
+ }
- dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx write_protect %#x\n",
- (unsigned long long) p->start, (unsigned long long) p->end,
+ dev_dbg(&dev->dev, " encode mem32 %#x-%#x write_protect %#x\n",
+ memory32->minimum,
+ memory32->minimum + memory32->address_length - 1,
memory32->write_protect);
}
@@ -960,15 +1000,20 @@ static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
{
struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;
- fixed_memory32->write_protect =
- (p->flags & IORESOURCE_MEM_WRITEABLE) ?
- ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
- fixed_memory32->address = p->start;
- fixed_memory32->address_length = p->end - p->start + 1;
+ if (pnp_resource_enabled(p)) {
+ fixed_memory32->write_protect =
+ p->flags & IORESOURCE_MEM_WRITEABLE ?
+ ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
+ fixed_memory32->address = p->start;
+ fixed_memory32->address_length = p->end - p->start + 1;
+ } else {
+ fixed_memory32->address = 0;
+ fixed_memory32->address_length = 0;
+ }
- dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx "
- "write_protect %#x\n",
- (unsigned long long) p->start, (unsigned long long) p->end,
+ dev_dbg(&dev->dev, " encode fixed_mem32 %#x-%#x write_protect %#x\n",
+ fixed_memory32->address,
+ fixed_memory32->address + fixed_memory32->address_length - 1,
fixed_memory32->write_protect);
}
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index 5ff9a4c..01f0c3d 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -526,8 +526,16 @@ len_err:
static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
struct resource *res)
{
- unsigned long base = res->start;
- unsigned long len = res->end - res->start + 1;
+ unsigned long base;
+ unsigned long len;
+
+ if (pnp_resource_enabled(res)) {
+ base = res->start;
+ len = res->end - res->start + 1;
+ } else {
+ base = 0;
+ len = 0;
+ }
p[4] = (base >> 8) & 0xff;
p[5] = ((base >> 8) >> 8) & 0xff;
@@ -536,15 +544,22 @@ static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
p[10] = (len >> 8) & 0xff;
p[11] = ((len >> 8) >> 8) & 0xff;
- dev_dbg(&dev->dev, " encode mem %#llx-%#llx\n",
- (unsigned long long) res->start, (unsigned long long) res->end);
+ dev_dbg(&dev->dev, " encode mem %#lx-%#lx\n", base, base + len - 1);
}
static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
struct resource *res)
{
- unsigned long base = res->start;
- unsigned long len = res->end - res->start + 1;
+ unsigned long base;
+ unsigned long len;
+
+ if (pnp_resource_enabled(res)) {
+ base = res->start;
+ len = res->end - res->start + 1;
+ } else {
+ base = 0;
+ len = 0;
+ }
p[4] = base & 0xff;
p[5] = (base >> 8) & 0xff;
@@ -559,15 +574,22 @@ static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
p[18] = (len >> 16) & 0xff;
p[19] = (len >> 24) & 0xff;
- dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx\n",
- (unsigned long long) res->start, (unsigned long long) res->end);
+ dev_dbg(&dev->dev, " encode mem32 %#lx-%#lx\n", base, base + len - 1);
}
static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
struct resource *res)
{
- unsigned long base = res->start;
- unsigned long len = res->end - res->start + 1;
+ unsigned long base;
+ unsigned long len;
+
+ if (pnp_resource_enabled(res)) {
+ base = res->start;
+ len = res->end - res->start + 1;
+ } else {
+ base = 0;
+ len = 0;
+ }
p[4] = base & 0xff;
p[5] = (base >> 8) & 0xff;
@@ -578,40 +600,54 @@ static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
p[10] = (len >> 16) & 0xff;
p[11] = (len >> 24) & 0xff;
- dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx\n",
- (unsigned long long) res->start, (unsigned long long) res->end);
+ dev_dbg(&dev->dev, " encode fixed_mem32 %#lx-%#lx\n", base,
+ base + len - 1);
}
static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
struct resource *res)
{
- unsigned long map = 0;
+ unsigned long map;
+
+ if (pnp_resource_enabled(res))
+ map = 1 << res->start;
+ else
+ map = 0;
- map = 1 << res->start;
p[1] = map & 0xff;
p[2] = (map >> 8) & 0xff;
- dev_dbg(&dev->dev, " encode irq %llu\n",
- (unsigned long long)res->start);
+ dev_dbg(&dev->dev, " encode irq mask %#lx\n", map);
}
static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
struct resource *res)
{
- unsigned long map = 0;
+ unsigned long map;
+
+ if (pnp_resource_enabled(res))
+ map = 1 << res->start;
+ else
+ map = 0;
- map = 1 << res->start;
p[1] = map & 0xff;
- dev_dbg(&dev->dev, " encode dma %llu\n",
- (unsigned long long)res->start);
+ dev_dbg(&dev->dev, " encode dma mask %#lx\n", map);
}
static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
struct resource *res)
{
- unsigned long base = res->start;
- unsigned long len = res->end - res->start + 1;
+ unsigned long base;
+ unsigned long len;
+
+ if (pnp_resource_enabled(res)) {
+ base = res->start;
+ len = res->end - res->start + 1;
+ } else {
+ base = 0;
+ len = 0;
+ }
p[2] = base & 0xff;
p[3] = (base >> 8) & 0xff;
@@ -619,8 +655,7 @@ static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
p[5] = (base >> 8) & 0xff;
p[7] = len & 0xff;
- dev_dbg(&dev->dev, " encode io %#llx-%#llx\n",
- (unsigned long long) res->start, (unsigned long long) res->end);
+ dev_dbg(&dev->dev, " encode io %#lx-%#lx\n", base, base + len - 1);
}
static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
@@ -629,12 +664,20 @@ static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
unsigned long base = res->start;
unsigned long len = res->end - res->start + 1;
+ if (pnp_resource_enabled(res)) {
+ base = res->start;
+ len = res->end - res->start + 1;
+ } else {
+ base = 0;
+ len = 0;
+ }
+
p[1] = base & 0xff;
p[2] = (base >> 8) & 0xff;
p[3] = len & 0xff;
- dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n",
- (unsigned long long) res->start, (unsigned long long) res->end);
+ dev_dbg(&dev->dev, " encode fixed_io %#lx-%#lx\n", base,
+ base + len - 1);
}
static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 1ff3bb5..21acb54 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -248,8 +248,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
for (j = 0;
(res = pnp_get_resource(dev, IORESOURCE_MEM, j));
j++) {
- if (res->flags & IORESOURCE_UNSET ||
- (res->start == 0 && res->end == 0))
+ if (res->start == 0 && res->end == 0)
continue;
pnp_start = res->start;
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index cce341f..0797a77 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -237,7 +237,7 @@ void pnp_free_option(struct pnp_option *option)
!((*(enda) < *(startb)) || (*(endb) < *(starta)))
#define cannot_compare(flags) \
-((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED))
+((flags) & IORESOURCE_DISABLED)
int pnp_check_port(struct pnp_dev *dev, struct resource *res)
{
@@ -505,81 +505,31 @@ int pnp_resource_type(struct resource *res)
IORESOURCE_IRQ | IORESOURCE_DMA);
}
-struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
- unsigned int type, unsigned int num)
-{
- struct pnp_resource_table *res = dev->res;
-
- switch (type) {
- case IORESOURCE_IO:
- if (num >= PNP_MAX_PORT)
- return NULL;
- return &res->port[num];
- case IORESOURCE_MEM:
- if (num >= PNP_MAX_MEM)
- return NULL;
- return &res->mem[num];
- case IORESOURCE_IRQ:
- if (num >= PNP_MAX_IRQ)
- return NULL;
- return &res->irq[num];
- case IORESOURCE_DMA:
- if (num >= PNP_MAX_DMA)
- return NULL;
- return &res->dma[num];
- }
- return NULL;
-}
-
struct resource *pnp_get_resource(struct pnp_dev *dev,
unsigned int type, unsigned int num)
{
struct pnp_resource *pnp_res;
+ struct resource *res;
- pnp_res = pnp_get_pnp_resource(dev, type, num);
- if (pnp_res)
- return &pnp_res->res;
-
+ list_for_each_entry(pnp_res, &dev->resources, list) {
+ res = &pnp_res->res;
+ if (pnp_resource_type(res) == type && num-- == 0)
+ return res;
+ }
return NULL;
}
EXPORT_SYMBOL(pnp_get_resource);
-static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev, int type)
+static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev)
{
struct pnp_resource *pnp_res;
- int i;
- switch (type) {
- case IORESOURCE_IO:
- for (i = 0; i < PNP_MAX_PORT; i++) {
- pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, i);
- if (pnp_res && !pnp_resource_valid(&pnp_res->res))
- return pnp_res;
- }
- break;
- case IORESOURCE_MEM:
- for (i = 0; i < PNP_MAX_MEM; i++) {
- pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, i);
- if (pnp_res && !pnp_resource_valid(&pnp_res->res))
- return pnp_res;
- }
- break;
- case IORESOURCE_IRQ:
- for (i = 0; i < PNP_MAX_IRQ; i++) {
- pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, i);
- if (pnp_res && !pnp_resource_valid(&pnp_res->res))
- return pnp_res;
- }
- break;
- case IORESOURCE_DMA:
- for (i = 0; i < PNP_MAX_DMA; i++) {
- pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, i);
- if (pnp_res && !pnp_resource_valid(&pnp_res->res))
- return pnp_res;
- }
- break;
- }
- return NULL;
+ pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL);
+ if (!pnp_res)
+ return NULL;
+
+ list_add_tail(&pnp_res->list, &dev->resources);
+ return pnp_res;
}
struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
@@ -589,7 +539,7 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
struct resource *res;
static unsigned char warned;
- pnp_res = pnp_new_resource(dev, IORESOURCE_IRQ);
+ pnp_res = pnp_new_resource(dev);
if (!pnp_res) {
if (!warned) {
dev_err(&dev->dev, "can't add resource for IRQ %d\n",
@@ -615,7 +565,7 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
struct resource *res;
static unsigned char warned;
- pnp_res = pnp_new_resource(dev, IORESOURCE_DMA);
+ pnp_res = pnp_new_resource(dev);
if (!pnp_res) {
if (!warned) {
dev_err(&dev->dev, "can't add resource for DMA %d\n",
@@ -642,7 +592,7 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
struct resource *res;
static unsigned char warned;
- pnp_res = pnp_new_resource(dev, IORESOURCE_IO);
+ pnp_res = pnp_new_resource(dev);
if (!pnp_res) {
if (!warned) {
dev_err(&dev->dev, "can't add resource for IO "
@@ -671,7 +621,7 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
struct resource *res;
static unsigned char warned;
- pnp_res = pnp_new_resource(dev, IORESOURCE_MEM);
+ pnp_res = pnp_new_resource(dev);
if (!pnp_res) {
if (!warned) {
dev_err(&dev->dev, "can't add resource for MEM "
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index eb07345..2ff2d1e 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -16,6 +16,10 @@
*/
int pnp_is_active(struct pnp_dev *dev)
{
+ /*
+ * I don't think this is very reliable because pnp_disable_dev()
+ * only clears out auto-assigned resources.
+ */
if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 &&
!pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 &&
pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1)
@@ -70,54 +74,34 @@ char *pnp_resource_type_name(struct resource *res)
void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
{
#ifdef DEBUG
+ struct pnp_resource *pnp_res;
struct resource *res;
- int i;
dev_dbg(&dev->dev, "current resources: %s\n", desc);
+ list_for_each_entry(pnp_res, &dev->resources, list) {
+ res = &pnp_res->res;
- for (i = 0; i < PNP_MAX_IRQ; i++) {
- res = pnp_get_resource(dev, IORESOURCE_IRQ, i);
- if (res && !(res->flags & IORESOURCE_UNSET))
- dev_dbg(&dev->dev, " irq %lld flags %#lx%s%s\n",
- (unsigned long long) res->start, res->flags,
- res->flags & IORESOURCE_DISABLED ?
- " DISABLED" : "",
- res->flags & IORESOURCE_AUTO ?
- " AUTO" : "");
- }
- for (i = 0; i < PNP_MAX_DMA; i++) {
- res = pnp_get_resource(dev, IORESOURCE_DMA, i);
- if (res && !(res->flags & IORESOURCE_UNSET))
- dev_dbg(&dev->dev, " dma %lld flags %#lx%s%s\n",
- (unsigned long long) res->start, res->flags,
- res->flags & IORESOURCE_DISABLED ?
- " DISABLED" : "",
- res->flags & IORESOURCE_AUTO ?
- " AUTO" : "");
- }
- for (i = 0; i < PNP_MAX_PORT; i++) {
- res = pnp_get_resource(dev, IORESOURCE_IO, i);
- if (res && !(res->flags & IORESOURCE_UNSET))
- dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx"
- "%s%s\n",
- (unsigned long long) res->start,
- (unsigned long long) res->end, res->flags,
- res->flags & IORESOURCE_DISABLED ?
- " DISABLED" : "",
- res->flags & IORESOURCE_AUTO ?
- " AUTO" : "");
- }
- for (i = 0; i < PNP_MAX_MEM; i++) {
- res = pnp_get_resource(dev, IORESOURCE_MEM, i);
- if (res && !(res->flags & IORESOURCE_UNSET))
- dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx"
- "%s%s\n",
- (unsigned long long) res->start,
- (unsigned long long) res->end, res->flags,
- res->flags & IORESOURCE_DISABLED ?
- " DISABLED" : "",
- res->flags & IORESOURCE_AUTO ?
- " AUTO" : "");
+ dev_dbg(&dev->dev, " %-3s ", pnp_resource_type_name(res));
+
+ if (res->flags & IORESOURCE_DISABLED) {
+ printk("disabled\n");
+ continue;
+ }
+
+ switch (pnp_resource_type(res)) {
+ case IORESOURCE_IO:
+ case IORESOURCE_MEM:
+ printk("%#llx-%#llx flags %#lx",
+ (unsigned long long) res->start,
+ (unsigned long long) res->end, res->flags);
+ break;
+ case IORESOURCE_IRQ:
+ case IORESOURCE_DMA:
+ printk("%lld flags %#lx",
+ (unsigned long long) res->start, res->flags);
+ break;
+ }
+ printk("\n");
}
#endif
}
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c
index cf4e07b..764f3a3 100644
--- a/drivers/pnp/system.c
+++ b/drivers/pnp/system.c
@@ -60,7 +60,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev)
int i;
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
- if (res->flags & IORESOURCE_UNSET)
+ if (res->flags & IORESOURCE_DISABLED)
continue;
if (res->start == 0)
continue; /* disabled */
@@ -81,7 +81,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev)
}
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
- if (res->flags & (IORESOURCE_UNSET | IORESOURCE_DISABLED))
+ if (res->flags & IORESOURCE_DISABLED)
continue;
reserve_range(dev, res->start, res->end, 0);
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 8b607ae..dfaa567 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -15,7 +15,6 @@
struct pnp_protocol;
struct pnp_dev;
-struct pnp_resource_table;
/*
* Resource Management
@@ -24,7 +23,14 @@ struct resource *pnp_get_resource(struct pnp_dev *, unsigned int, unsigned int);
static inline int pnp_resource_valid(struct resource *res)
{
- if (res && !(res->flags & IORESOURCE_UNSET))
+ if (res)
+ return 1;
+ return 0;
+}
+
+static inline int pnp_resource_enabled(struct resource *res)
+{
+ if (res && !(res->flags & IORESOURCE_DISABLED))
return 1;
return 0;
}
@@ -64,7 +70,7 @@ static inline unsigned long pnp_port_flags(struct pnp_dev *dev,
if (pnp_resource_valid(res))
return res->flags;
- return IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
+ return IORESOURCE_IO | IORESOURCE_AUTO;
}
static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar)
@@ -109,7 +115,7 @@ static inline unsigned long pnp_mem_flags(struct pnp_dev *dev, unsigned int bar)
if (pnp_resource_valid(res))
return res->flags;
- return IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
+ return IORESOURCE_MEM | IORESOURCE_AUTO;
}
static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar)
@@ -143,7 +149,7 @@ static inline unsigned long pnp_irq_flags(struct pnp_dev *dev, unsigned int bar)
if (pnp_resource_valid(res))
return res->flags;
- return IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
+ return IORESOURCE_IRQ | IORESOURCE_AUTO;
}
static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar)
@@ -167,7 +173,7 @@ static inline unsigned long pnp_dma_flags(struct pnp_dev *dev, unsigned int bar)
if (pnp_resource_valid(res))
return res->flags;
- return IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
+ return IORESOURCE_DMA | IORESOURCE_AUTO;
}
static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar)
@@ -296,7 +302,7 @@ struct pnp_dev {
int capabilities;
struct pnp_option *independent;
struct pnp_option *dependent;
- struct pnp_resource_table *res;
+ struct list_head resources;
char name[PNP_NAME_LEN]; /* contains a human-readable name */
int flags; /* used by protocols */
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 45/70] PNPACPI: keep disabled resources when parsing current config
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (41 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 44/70] PNP: replace pnp_resource_table with dynamically allocated resources Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 46/70] PNP: remove ratelimit on add resource failures Len Brown
` (24 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
When we parse a device's _CRS data (the current resource settings),
we should keep track of everything we find, even if it's currently
disabled or invalid.
This is what we already do for ISAPNP and PNPBIOS, and it helps
keep things matched up when we subsequently re-encode resources.
For example, consider a device with (mem, irq0, irq1, io), where
irq0 is disabled. If we drop irq0 when parsing the _CRS, we will
mistakenly put irq1 in the irq0 slot when we encode resources
for an _SRS call.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/pnpacpi/rsparser.c | 70 +++++++++++++++++++++++++++++----------
1 files changed, 52 insertions(+), 18 deletions(-)
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 9a45c25..595252b 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -98,8 +98,10 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
int irq, flags;
int p, t;
- if (!valid_IRQ(gsi))
+ if (!valid_IRQ(gsi)) {
+ pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED);
return;
+ }
/*
* in IO-APIC mode, use overrided attribute. Two reasons:
@@ -248,24 +250,39 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
* _CRS, but some firmware violates this, so parse them all.
*/
irq = &res->data.irq;
- for (i = 0; i < irq->interrupt_count; i++) {
- pnpacpi_parse_allocated_irqresource(dev,
- irq->interrupts[i],
- irq->triggering,
- irq->polarity,
- irq->sharable);
+ if (irq->interrupt_count == 0)
+ pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
+ else {
+ for (i = 0; i < irq->interrupt_count; i++) {
+ pnpacpi_parse_allocated_irqresource(dev,
+ irq->interrupts[i],
+ irq->triggering,
+ irq->polarity,
+ irq->sharable);
+ }
+
+ /*
+ * The IRQ encoder puts a single interrupt in each
+ * descriptor, so if a _CRS descriptor has more than
+ * one interrupt, we won't be able to re-encode it.
+ */
+ if (pnp_can_write(dev) && irq->interrupt_count > 1) {
+ dev_warn(&dev->dev, "multiple interrupts in "
+ "_CRS descriptor; configuration can't "
+ "be changed\n");
+ dev->capabilities &= ~PNP_WRITE;
+ }
}
break;
case ACPI_RESOURCE_TYPE_DMA:
dma = &res->data.dma;
- if (dma->channel_count > 0) {
+ if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
flags = dma_flags(dma->type, dma->bus_master,
dma->transfer);
- if (dma->channels[0] == (u8) -1)
- flags |= IORESOURCE_DISABLED;
- pnp_add_dma_resource(dev, dma->channels[0], flags);
- }
+ else
+ flags = IORESOURCE_DISABLED;
+ pnp_add_dma_resource(dev, dma->channels[0], flags);
break;
case ACPI_RESOURCE_TYPE_IO:
@@ -331,12 +348,29 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
if (extended_irq->producer_consumer == ACPI_PRODUCER)
return AE_OK;
- for (i = 0; i < extended_irq->interrupt_count; i++) {
- pnpacpi_parse_allocated_irqresource(dev,
- extended_irq->interrupts[i],
- extended_irq->triggering,
- extended_irq->polarity,
- extended_irq->sharable);
+ if (extended_irq->interrupt_count == 0)
+ pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
+ else {
+ for (i = 0; i < extended_irq->interrupt_count; i++) {
+ pnpacpi_parse_allocated_irqresource(dev,
+ extended_irq->interrupts[i],
+ extended_irq->triggering,
+ extended_irq->polarity,
+ extended_irq->sharable);
+ }
+
+ /*
+ * The IRQ encoder puts a single interrupt in each
+ * descriptor, so if a _CRS descriptor has more than
+ * one interrupt, we won't be able to re-encode it.
+ */
+ if (pnp_can_write(dev) &&
+ extended_irq->interrupt_count > 1) {
+ dev_warn(&dev->dev, "multiple interrupts in "
+ "_CRS descriptor; configuration can't "
+ "be changed\n");
+ dev->capabilities &= ~PNP_WRITE;
+ }
}
break;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 46/70] PNP: remove ratelimit on add resource failures
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (42 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 45/70] PNPACPI: keep disabled resources when parsing current config Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 47/70] PNP: dont sort by type in /sys/.../resources Len Brown
` (23 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
We used to have a fixed-size resource table. If a device had
twenty resources when the table only had space for ten, we didn't
need ten warnings, so we added the ratelimit.
Now that we can dynamically allocate new resources, we should
only get failures if the allocation fails. That should be
rare enough that we don't need to ratelimit the messages.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/resource.c | 34 ++++++++--------------------------
1 files changed, 8 insertions(+), 26 deletions(-)
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 0797a77..ff79aa6 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -537,15 +537,10 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
{
struct pnp_resource *pnp_res;
struct resource *res;
- static unsigned char warned;
pnp_res = pnp_new_resource(dev);
if (!pnp_res) {
- if (!warned) {
- dev_err(&dev->dev, "can't add resource for IRQ %d\n",
- irq);
- warned = 1;
- }
+ dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq);
return NULL;
}
@@ -563,15 +558,10 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
{
struct pnp_resource *pnp_res;
struct resource *res;
- static unsigned char warned;
pnp_res = pnp_new_resource(dev);
if (!pnp_res) {
- if (!warned) {
- dev_err(&dev->dev, "can't add resource for DMA %d\n",
- dma);
- warned = 1;
- }
+ dev_err(&dev->dev, "can't add resource for DMA %d\n", dma);
return NULL;
}
@@ -590,16 +580,12 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
{
struct pnp_resource *pnp_res;
struct resource *res;
- static unsigned char warned;
pnp_res = pnp_new_resource(dev);
if (!pnp_res) {
- if (!warned) {
- dev_err(&dev->dev, "can't add resource for IO "
- "%#llx-%#llx\n",(unsigned long long) start,
- (unsigned long long) end);
- warned = 1;
- }
+ dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n",
+ (unsigned long long) start,
+ (unsigned long long) end);
return NULL;
}
@@ -619,16 +605,12 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
{
struct pnp_resource *pnp_res;
struct resource *res;
- static unsigned char warned;
pnp_res = pnp_new_resource(dev);
if (!pnp_res) {
- if (!warned) {
- dev_err(&dev->dev, "can't add resource for MEM "
- "%#llx-%#llx\n",(unsigned long long) start,
- (unsigned long long) end);
- warned = 1;
- }
+ dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n",
+ (unsigned long long) start,
+ (unsigned long long) end);
return NULL;
}
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 47/70] PNP: dont sort by type in /sys/.../resources
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (43 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 46/70] PNP: remove ratelimit on add resource failures Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 48/70] PNP: add pnp_possible_config() -- can a device could be configured this way? Len Brown
` (22 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
Rather than stepping through all IO resources, then stepping through
all MMIO resources, etc., we can just iterate over the resource list
once directly.
This can change the order in /sys, e.g.,
# cat /sys/devices/pnp0/00:07/resources # OLD
state = active
io 0x3f8-0x3ff
irq 4
# cat /sys/devices/pnp0/00:07/resources # NEW
state = active
irq 4
io 0x3f8-0x3ff
The old code artificially sorted resources by type; the new code
just lists them in the order we read them from the ISAPNP hardware
or the BIOS.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/interface.c | 56 ++++++++++++++++++----------------------------
1 files changed, 22 insertions(+), 34 deletions(-)
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 7fc86bb..674e8ba 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -248,8 +248,9 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
char *buf)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
+ struct pnp_resource *pnp_res;
struct resource *res;
- int i, ret;
+ int ret;
pnp_info_buffer_t *buffer;
if (!dev)
@@ -262,46 +263,33 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
buffer->buffer = buf;
buffer->curr = buffer->buffer;
- pnp_printf(buffer, "state = ");
- if (dev->active)
- pnp_printf(buffer, "active\n");
- else
- pnp_printf(buffer, "disabled\n");
+ pnp_printf(buffer, "state = %s\n", dev->active ? "active" : "disabled");
- for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
- pnp_printf(buffer, "io");
- if (res->flags & IORESOURCE_DISABLED)
- pnp_printf(buffer, " disabled\n");
- else
- pnp_printf(buffer, " 0x%llx-0x%llx\n",
- (unsigned long long) res->start,
- (unsigned long long) res->end);
- }
- for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
- pnp_printf(buffer, "mem");
- if (res->flags & IORESOURCE_DISABLED)
+ list_for_each_entry(pnp_res, &dev->resources, list) {
+ res = &pnp_res->res;
+
+ pnp_printf(buffer, pnp_resource_type_name(res));
+
+ if (res->flags & IORESOURCE_DISABLED) {
pnp_printf(buffer, " disabled\n");
- else
- pnp_printf(buffer, " 0x%llx-0x%llx\n",
+ continue;
+ }
+
+ switch (pnp_resource_type(res)) {
+ case IORESOURCE_IO:
+ case IORESOURCE_MEM:
+ pnp_printf(buffer, " %#llx-%#llx\n",
(unsigned long long) res->start,
(unsigned long long) res->end);
- }
- for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
- pnp_printf(buffer, "irq");
- if (res->flags & IORESOURCE_DISABLED)
- pnp_printf(buffer, " disabled\n");
- else
- pnp_printf(buffer, " %lld\n",
- (unsigned long long) res->start);
- }
- for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) {
- pnp_printf(buffer, "dma");
- if (res->flags & IORESOURCE_DISABLED)
- pnp_printf(buffer, " disabled\n");
- else
+ break;
+ case IORESOURCE_IRQ:
+ case IORESOURCE_DMA:
pnp_printf(buffer, " %lld\n",
(unsigned long long) res->start);
+ break;
+ }
}
+
ret = (buffer->curr - buf);
kfree(buffer);
return ret;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 48/70] PNP: add pnp_possible_config() -- can a device could be configured this way?
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (44 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 47/70] PNP: dont sort by type in /sys/.../resources Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 49/70] PNP: whitespace/coding style fixes Len Brown
` (21 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
As part of a heuristic to identify modem devices, 8250_pnp.c
checks to see whether a device can be configured at any of the
legacy COM port addresses.
This patch moves the code that traverses the PNP "possible resource
options" from 8250_pnp.c to the PNP subsystem. This encapsulation
is important because a future patch will change the implementation
of those resource options.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/resource.c | 62 +++++++++++++++++++++++++++++++++++++++++++++
drivers/serial/8250_pnp.c | 24 +++++------------
include/linux/pnp.h | 3 ++
3 files changed, 72 insertions(+), 17 deletions(-)
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index ff79aa6..786fd35 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -624,6 +624,68 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
return pnp_res;
}
+static int pnp_possible_option(struct pnp_option *option, int type,
+ resource_size_t start, resource_size_t size)
+{
+ struct pnp_option *tmp;
+ struct pnp_port *port;
+ struct pnp_mem *mem;
+ struct pnp_irq *irq;
+ struct pnp_dma *dma;
+
+ if (!option)
+ return 0;
+
+ for (tmp = option; tmp; tmp = tmp->next) {
+ switch (type) {
+ case IORESOURCE_IO:
+ for (port = tmp->port; port; port = port->next) {
+ if (port->min == start && port->size == size)
+ return 1;
+ }
+ break;
+ case IORESOURCE_MEM:
+ for (mem = tmp->mem; mem; mem = mem->next) {
+ if (mem->min == start && mem->size == size)
+ return 1;
+ }
+ break;
+ case IORESOURCE_IRQ:
+ for (irq = tmp->irq; irq; irq = irq->next) {
+ if (start < PNP_IRQ_NR &&
+ test_bit(start, irq->map))
+ return 1;
+ }
+ break;
+ case IORESOURCE_DMA:
+ for (dma = tmp->dma; dma; dma = dma->next) {
+ if (dma->map & (1 << start))
+ return 1;
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Determine whether the specified resource is a possible configuration
+ * for this device.
+ */
+int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
+ resource_size_t size)
+{
+ if (pnp_possible_option(dev->independent, type, start, size))
+ return 1;
+
+ if (pnp_possible_option(dev->dependent, type, start, size))
+ return 1;
+
+ return 0;
+}
+EXPORT_SYMBOL(pnp_possible_config);
+
/* format is: pnp_reserve_irq=irq1[,irq2] .... */
static int __init pnp_setup_reserve_irq(char *str)
{
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 97c68d0..638b686 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -383,21 +383,14 @@ static int __devinit check_name(char *name)
return 0;
}
-static int __devinit check_resources(struct pnp_option *option)
+static int __devinit check_resources(struct pnp_dev *dev)
{
- struct pnp_option *tmp;
- if (!option)
- return 0;
+ resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
+ int i;
- for (tmp = option; tmp; tmp = tmp->next) {
- struct pnp_port *port;
- for (port = tmp->port; port; port = port->next)
- if ((port->size == 8) &&
- ((port->min == 0x2f8) ||
- (port->min == 0x3f8) ||
- (port->min == 0x2e8) ||
- (port->min == 0x3e8)))
- return 1;
+ for (i = 0; i < ARRAY_SIZE(base); i++) {
+ if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8))
+ return 1;
}
return 0;
@@ -420,10 +413,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
(dev->card && check_name(dev->card->name))))
return -ENODEV;
- if (check_resources(dev->independent))
- return 0;
-
- if (check_resources(dev->dependent))
+ if (check_resources(dev))
return 0;
return -ENODEV;
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index dfaa567..86e0e1d 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -479,6 +479,8 @@ void pnp_unregister_card_driver(struct pnp_card_driver *drv);
extern struct list_head pnp_cards;
/* resource management */
+int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t base,
+ resource_size_t size);
int pnp_auto_config_dev(struct pnp_dev *dev);
int pnp_start_dev(struct pnp_dev *dev);
int pnp_stop_dev(struct pnp_dev *dev);
@@ -506,6 +508,7 @@ static inline int pnp_register_card_driver(struct pnp_card_driver *drv) { return
static inline void pnp_unregister_card_driver(struct pnp_card_driver *drv) { }
/* resource management */
+static inline int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t base, resource_size_t size) { return 0; }
static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; }
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 49/70] PNP: whitespace/coding style fixes
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (45 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 48/70] PNP: add pnp_possible_config() -- can a device could be configured this way? Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 50/70] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM Len Brown
` (20 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
No functional change; just make a couple declarations
consistent with the rest of the file.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/interface.c | 15 ++++++++-------
1 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 674e8ba..239923a 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -216,12 +216,12 @@ static ssize_t pnp_show_options(struct device *dmdev,
struct device_attribute *attr, char *buf)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
+ pnp_info_buffer_t *buffer;
struct pnp_option *independent = dev->independent;
struct pnp_option *dependent = dev->dependent;
int ret, dep = 1;
- pnp_info_buffer_t *buffer = (pnp_info_buffer_t *)
- pnp_alloc(sizeof(pnp_info_buffer_t));
+ buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
if (!buffer)
return -ENOMEM;
@@ -248,17 +248,18 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
char *buf)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
+ pnp_info_buffer_t *buffer;
struct pnp_resource *pnp_res;
struct resource *res;
int ret;
- pnp_info_buffer_t *buffer;
if (!dev)
return -EINVAL;
- buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t));
+ buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
if (!buffer)
return -ENOMEM;
+
buffer->len = PAGE_SIZE;
buffer->buffer = buf;
buffer->curr = buffer->buffer;
@@ -295,9 +296,9 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
return ret;
}
-static ssize_t
-pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
- const char *ubuf, size_t count)
+static ssize_t pnp_set_current_resources(struct device *dmdev,
+ struct device_attribute *attr,
+ const char *ubuf, size_t count)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
char *buf = (void *)ubuf;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 50/70] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (46 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 49/70] PNP: whitespace/coding style fixes Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 51/70] PNP: make resource option structures private to PNP subsystem Len Brown
` (19 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
PNP previously defined PNP_PORT_FLAG_16BITADDR and PNP_PORT_FLAG_FIXED
in a private header file, but put those flags in struct resource.flags
fields. Better to make them IORESOURCE_IO_* flags like the existing
IRQ, DMA, and MEM flags.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/interface.c | 2 +-
drivers/pnp/isapnp/core.c | 4 ++--
drivers/pnp/pnpacpi/rsparser.c | 10 +++++-----
drivers/pnp/pnpbios/rsparser.c | 4 ++--
include/linux/ioport.h | 4 ++++
include/linux/pnp.h | 3 ---
6 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 239923a..c172b6d 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -57,7 +57,7 @@ static void pnp_print_port(pnp_info_buffer_t * buffer, char *space,
"%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n",
space, port->min, port->max,
port->align ? (port->align - 1) : 0, port->size,
- port->flags & PNP_PORT_FLAG_16BITADDR ? 16 : 10);
+ port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10);
}
static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index ca4457e..c5b9252 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -486,7 +486,7 @@ static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
port->max = (tmp[4] << 8) | tmp[3];
port->align = tmp[5];
port->size = tmp[6];
- port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
+ port->flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
pnp_register_port_resource(dev, option, port);
}
@@ -507,7 +507,7 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
port->min = port->max = (tmp[1] << 8) | tmp[0];
port->size = tmp[2];
port->align = 0;
- port->flags = PNP_PORT_FLAG_FIXED;
+ port->flags = IORESOURCE_IO_FIXED;
pnp_register_port_resource(dev, option, port);
}
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 595252b..46069e6 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -180,7 +180,7 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
u64 end = start + len - 1;
if (io_decode == ACPI_DECODE_16)
- flags |= PNP_PORT_FLAG_16BITADDR;
+ flags |= IORESOURCE_IO_16BIT_ADDR;
if (len == 0 || end >= 0x10003)
flags |= IORESOURCE_DISABLED;
@@ -485,7 +485,7 @@ static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
port->align = io->alignment;
port->size = io->address_length;
port->flags = ACPI_DECODE_16 == io->io_decode ?
- PNP_PORT_FLAG_16BITADDR : 0;
+ IORESOURCE_IO_16BIT_ADDR : 0;
pnp_register_port_resource(dev, option, port);
}
@@ -503,7 +503,7 @@ static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
port->min = port->max = io->address;
port->size = io->address_length;
port->align = 0;
- port->flags = PNP_PORT_FLAG_FIXED;
+ port->flags = IORESOURCE_IO_FIXED;
pnp_register_port_resource(dev, option, port);
}
@@ -609,7 +609,7 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
port->min = port->max = p->minimum;
port->size = p->address_length;
port->align = 0;
- port->flags = PNP_PORT_FLAG_FIXED;
+ port->flags = IORESOURCE_IO_FIXED;
pnp_register_port_resource(dev, option, port);
}
}
@@ -946,7 +946,7 @@ static void pnpacpi_encode_io(struct pnp_dev *dev,
if (pnp_resource_enabled(p)) {
/* Note: pnp_assign_port copies pnp_port->flags into p->flags */
- io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
+ io->io_decode = (p->flags & IORESOURCE_IO_16BIT_ADDR) ?
ACPI_DECODE_16 : ACPI_DECODE_10;
io->minimum = p->start;
io->maximum = p->end;
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index 01f0c3d..489fec3 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -310,7 +310,7 @@ static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
port->max = (p[5] << 8) | p[4];
port->align = p[6];
port->size = p[7];
- port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0;
+ port->flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0;
pnp_register_port_resource(dev, option, port);
}
@@ -326,7 +326,7 @@ static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
port->min = port->max = (p[2] << 8) | p[1];
port->size = p[3];
port->align = 0;
- port->flags = PNP_PORT_FLAG_FIXED;
+ port->flags = IORESOURCE_IO_FIXED;
pnp_register_port_resource(dev, option, port);
}
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index c6801bf..39db059 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -88,6 +88,10 @@ struct resource_list {
#define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */
#define IORESOURCE_MEM_EXPANSIONROM (1<<6)
+/* PnP I/O specific bits (IORESOURCE_BITS) */
+#define IORESOURCE_IO_16BIT_ADDR (1<<0)
+#define IORESOURCE_IO_FIXED (1<<1)
+
/* PCI ROM control bits (IORESOURCE_BITS) */
#define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
#define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 86e0e1d..b690edb 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -182,9 +182,6 @@ static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar)
}
-#define PNP_PORT_FLAG_16BITADDR (1<<0)
-#define PNP_PORT_FLAG_FIXED (1<<1)
-
struct pnp_port {
unsigned short min; /* min base number */
unsigned short max; /* max base number */
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 51/70] PNP: make resource option structures private to PNP subsystem
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (47 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 50/70] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 52/70] PNP: introduce pnp_irq_mask_t typedef Len Brown
` (18 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
Nothing outside the PNP subsystem should need access to a
device's resource options, so this patch moves the option
structure declarations to a private header file.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/base.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/pnp.h | 48 ------------------------------------------------
2 files changed, 48 insertions(+), 48 deletions(-)
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 1667ac3..3126e45 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -19,6 +19,54 @@ void pnp_remove_card(struct pnp_card *card);
int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
void pnp_remove_card_device(struct pnp_dev *dev);
+struct pnp_port {
+ unsigned short min; /* min base number */
+ unsigned short max; /* max base number */
+ unsigned char align; /* align boundary */
+ unsigned char size; /* size of range */
+ unsigned char flags; /* port flags */
+ unsigned char pad; /* pad */
+ struct pnp_port *next; /* next port */
+};
+
+#define PNP_IRQ_NR 256
+struct pnp_irq {
+ DECLARE_BITMAP(map, PNP_IRQ_NR); /* bitmask for IRQ lines */
+ unsigned char flags; /* IRQ flags */
+ unsigned char pad; /* pad */
+ struct pnp_irq *next; /* next IRQ */
+};
+
+struct pnp_dma {
+ unsigned char map; /* bitmask for DMA channels */
+ unsigned char flags; /* DMA flags */
+ struct pnp_dma *next; /* next port */
+};
+
+struct pnp_mem {
+ unsigned int min; /* min base number */
+ unsigned int max; /* max base number */
+ unsigned int align; /* align boundary */
+ unsigned int size; /* size of range */
+ unsigned char flags; /* memory flags */
+ unsigned char pad; /* pad */
+ struct pnp_mem *next; /* next memory resource */
+};
+
+#define PNP_RES_PRIORITY_PREFERRED 0
+#define PNP_RES_PRIORITY_ACCEPTABLE 1
+#define PNP_RES_PRIORITY_FUNCTIONAL 2
+#define PNP_RES_PRIORITY_INVALID 65535
+
+struct pnp_option {
+ unsigned short priority; /* priority */
+ struct pnp_port *port; /* first port */
+ struct pnp_irq *irq; /* first IRQ */
+ struct pnp_dma *dma; /* first DMA */
+ struct pnp_mem *mem; /* first memory resource */
+ struct pnp_option *next; /* used to chain dependent resources */
+};
+
struct pnp_option *pnp_build_option(int priority);
struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index b690edb..00fe020 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -182,54 +182,6 @@ static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar)
}
-struct pnp_port {
- unsigned short min; /* min base number */
- unsigned short max; /* max base number */
- unsigned char align; /* align boundary */
- unsigned char size; /* size of range */
- unsigned char flags; /* port flags */
- unsigned char pad; /* pad */
- struct pnp_port *next; /* next port */
-};
-
-#define PNP_IRQ_NR 256
-struct pnp_irq {
- DECLARE_BITMAP(map, PNP_IRQ_NR); /* bitmask for IRQ lines */
- unsigned char flags; /* IRQ flags */
- unsigned char pad; /* pad */
- struct pnp_irq *next; /* next IRQ */
-};
-
-struct pnp_dma {
- unsigned char map; /* bitmask for DMA channels */
- unsigned char flags; /* DMA flags */
- struct pnp_dma *next; /* next port */
-};
-
-struct pnp_mem {
- unsigned int min; /* min base number */
- unsigned int max; /* max base number */
- unsigned int align; /* align boundary */
- unsigned int size; /* size of range */
- unsigned char flags; /* memory flags */
- unsigned char pad; /* pad */
- struct pnp_mem *next; /* next memory resource */
-};
-
-#define PNP_RES_PRIORITY_PREFERRED 0
-#define PNP_RES_PRIORITY_ACCEPTABLE 1
-#define PNP_RES_PRIORITY_FUNCTIONAL 2
-#define PNP_RES_PRIORITY_INVALID 65535
-
-struct pnp_option {
- unsigned short priority; /* priority */
- struct pnp_port *port; /* first port */
- struct pnp_irq *irq; /* first IRQ */
- struct pnp_dma *dma; /* first DMA */
- struct pnp_mem *mem; /* first memory resource */
- struct pnp_option *next; /* used to chain dependent resources */
-};
-
/*
* Device Management
*/
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 52/70] PNP: introduce pnp_irq_mask_t typedef
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (48 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 51/70] PNP: make resource option structures private to PNP subsystem Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 53/70] PNP: increase I/O port & memory option address sizes Len Brown
` (17 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
This adds a typedef for the IRQ bitmap, which should cause
no functional change, but will make it easier to pass a
pointer to a bitmap to pnp_register_irq_resource().
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/base.h | 4 +++-
drivers/pnp/interface.c | 4 ++--
drivers/pnp/isapnp/core.c | 2 +-
drivers/pnp/manager.c | 6 +++---
drivers/pnp/pnpacpi/rsparser.c | 4 ++--
drivers/pnp/pnpbios/rsparser.c | 2 +-
drivers/pnp/quirks.c | 4 ++--
drivers/pnp/resource.c | 6 +++---
8 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 3126e45..a9ee0a9 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -30,8 +30,10 @@ struct pnp_port {
};
#define PNP_IRQ_NR 256
+typedef struct { DECLARE_BITMAP(bits, PNP_IRQ_NR); } pnp_irq_mask_t;
+
struct pnp_irq {
- DECLARE_BITMAP(map, PNP_IRQ_NR); /* bitmask for IRQ lines */
+ pnp_irq_mask_t map; /* bitmap for IRQ lines */
unsigned char flags; /* IRQ flags */
unsigned char pad; /* pad */
struct pnp_irq *next; /* next IRQ */
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index c172b6d..249b407 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -67,7 +67,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
pnp_printf(buffer, "%sirq ", space);
for (i = 0; i < PNP_IRQ_NR; i++)
- if (test_bit(i, irq->map)) {
+ if (test_bit(i, irq->map.bits)) {
if (!first) {
pnp_printf(buffer, ",");
} else {
@@ -78,7 +78,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
else
pnp_printf(buffer, "%i", i);
}
- if (bitmap_empty(irq->map, PNP_IRQ_NR))
+ if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
pnp_printf(buffer, "<none>");
if (irq->flags & IORESOURCE_IRQ_HIGHEDGE)
pnp_printf(buffer, " High-Edge");
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index c5b9252..e0caa71 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -441,7 +441,7 @@ static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
if (!irq)
return;
bits = (tmp[1] << 8) | tmp[0];
- bitmap_copy(irq->map, &bits, 16);
+ bitmap_copy(irq->map.bits, &bits, 16);
if (size > 2)
irq->flags = tmp[2];
else
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 165b624..e758dd2 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -128,20 +128,20 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
res->start = -1;
res->end = -1;
- if (bitmap_empty(rule->map, PNP_IRQ_NR)) {
+ if (bitmap_empty(rule->map.bits, PNP_IRQ_NR)) {
res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " irq %d disabled\n", idx);
goto __add;
}
/* TBD: need check for >16 IRQ */
- res->start = find_next_bit(rule->map, PNP_IRQ_NR, 16);
+ res->start = find_next_bit(rule->map.bits, PNP_IRQ_NR, 16);
if (res->start < PNP_IRQ_NR) {
res->end = res->start;
goto __add;
}
for (i = 0; i < 16; i++) {
- if (test_bit(xtab[i], rule->map)) {
+ if (test_bit(xtab[i], rule->map.bits)) {
res->start = res->end = xtab[i];
if (pnp_check_irq(dev, res))
goto __add;
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 46069e6..ae65454 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -442,7 +442,7 @@ static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
for (i = 0; i < p->interrupt_count; i++)
if (p->interrupts[i])
- __set_bit(p->interrupts[i], irq->map);
+ __set_bit(p->interrupts[i], irq->map.bits);
irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
pnp_register_irq_resource(dev, option, irq);
@@ -463,7 +463,7 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
for (i = 0; i < p->interrupt_count; i++)
if (p->interrupts[i])
- __set_bit(p->interrupts[i], irq->map);
+ __set_bit(p->interrupts[i], irq->map.bits);
irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
pnp_register_irq_resource(dev, option, irq);
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index 489fec3..dd2ea7b 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -275,7 +275,7 @@ static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
if (!irq)
return;
bits = (p[2] << 8) | p[1];
- bitmap_copy(irq->map, &bits, 16);
+ bitmap_copy(irq->map.bits, &bits, 16);
if (size > 2)
irq->flags = p[3];
else
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 21acb54..c3ab348 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -68,7 +68,7 @@ static void quirk_cmi8330_resources(struct pnp_dev *dev)
for (irq = res->irq; irq; irq = irq->next) { // Valid irqs are 5, 7, 10
tmp = 0x04A0;
- bitmap_copy(irq->map, &tmp, 16); // 0000 0100 1010 0000
+ bitmap_copy(irq->map.bits, &tmp, 16); // 0000 0100 1010 0000
}
for (dma = res->dma; dma; dma = dma->next) // Valid 8bit dma channels are 1,3
@@ -187,7 +187,7 @@ static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
if (!copy)
break;
- memcpy(copy->map, irq->map, sizeof copy->map);
+ bitmap_copy(copy->map.bits, irq->map.bits, PNP_IRQ_NR);
copy->flags = irq->flags;
copy->next = res->irq; /* Yes, this is NULL */
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 786fd35..55a57cd 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -98,13 +98,13 @@ int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
int i;
for (i = 0; i < 16; i++)
- if (test_bit(i, data->map))
+ if (test_bit(i, data->map.bits))
pcibios_penalize_isa_irq(i, 0);
}
#endif
#ifdef DEBUG
- bitmap_scnprintf(buf, sizeof(buf), data->map, PNP_IRQ_NR);
+ bitmap_scnprintf(buf, sizeof(buf), data->map.bits, PNP_IRQ_NR);
dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf,
data->flags);
#endif
@@ -653,7 +653,7 @@ static int pnp_possible_option(struct pnp_option *option, int type,
case IORESOURCE_IRQ:
for (irq = tmp->irq; irq; irq = irq->next) {
if (start < PNP_IRQ_NR &&
- test_bit(start, irq->map))
+ test_bit(start, irq->map.bits))
return 1;
}
break;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 53/70] PNP: increase I/O port & memory option address sizes
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (49 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 52/70] PNP: introduce pnp_irq_mask_t typedef Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 54/70] PNP: improve resource assignment debug Len Brown
` (16 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
ACPI Address Space Descriptors can be up to 64 bits wide.
We should keep track of the whole thing when parsing resource
options, so this patch changes PNP port and mem option
fields from "unsigned short" and "unsigned int" to
"resource_size_t".
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/base.h | 16 ++++++++--------
drivers/pnp/interface.c | 17 +++++++++++------
drivers/pnp/resource.c | 14 ++++++++++----
3 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index a9ee0a9..afbeee5 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -20,10 +20,10 @@ int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
void pnp_remove_card_device(struct pnp_dev *dev);
struct pnp_port {
- unsigned short min; /* min base number */
- unsigned short max; /* max base number */
- unsigned char align; /* align boundary */
- unsigned char size; /* size of range */
+ resource_size_t min; /* min base number */
+ resource_size_t max; /* max base number */
+ resource_size_t align; /* align boundary */
+ resource_size_t size; /* size of range */
unsigned char flags; /* port flags */
unsigned char pad; /* pad */
struct pnp_port *next; /* next port */
@@ -46,10 +46,10 @@ struct pnp_dma {
};
struct pnp_mem {
- unsigned int min; /* min base number */
- unsigned int max; /* max base number */
- unsigned int align; /* align boundary */
- unsigned int size; /* size of range */
+ resource_size_t min; /* min base number */
+ resource_size_t max; /* max base number */
+ resource_size_t align; /* align boundary */
+ resource_size_t size; /* size of range */
unsigned char flags; /* memory flags */
unsigned char pad; /* pad */
struct pnp_mem *next; /* next memory resource */
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 249b407..b09f67d 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -53,10 +53,12 @@ static int pnp_printf(pnp_info_buffer_t * buffer, char *fmt, ...)
static void pnp_print_port(pnp_info_buffer_t * buffer, char *space,
struct pnp_port *port)
{
- pnp_printf(buffer,
- "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n",
- space, port->min, port->max,
- port->align ? (port->align - 1) : 0, port->size,
+ pnp_printf(buffer, "%sport %#llx-%#llx, align %#llx, size %#llx, "
+ "%i-bit address decoding\n", space,
+ (unsigned long long) port->min,
+ (unsigned long long) port->max,
+ port->align ? ((unsigned long long) port->align - 1) : 0,
+ (unsigned long long) port->size,
port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10);
}
@@ -148,8 +150,11 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
{
char *s;
- pnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x",
- space, mem->min, mem->max, mem->align, mem->size);
+ pnp_printf(buffer, "%sMemory %#llx-%#llx, align %#llx, size %#llx",
+ space, (unsigned long long) mem->min,
+ (unsigned long long) mem->max,
+ (unsigned long long) mem->align,
+ (unsigned long long) mem->size);
if (mem->flags & IORESOURCE_MEM_WRITEABLE)
pnp_printf(buffer, ", writeable");
if (mem->flags & IORESOURCE_MEM_CACHEABLE)
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 55a57cd..391828c 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -143,8 +143,11 @@ int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
option->port = data;
dev_dbg(&dev->dev, " io "
- "min %#x max %#x align %d size %d flags %#x\n",
- data->min, data->max, data->align, data->size, data->flags);
+ "min %#llx max %#llx align %lld size %lld flags %#x\n",
+ (unsigned long long) data->min,
+ (unsigned long long) data->max,
+ (unsigned long long) data->align,
+ (unsigned long long) data->size, data->flags);
return 0;
}
@@ -162,8 +165,11 @@ int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
option->mem = data;
dev_dbg(&dev->dev, " mem "
- "min %#x max %#x align %d size %d flags %#x\n",
- data->min, data->max, data->align, data->size, data->flags);
+ "min %#llx max %#llx align %lld size %lld flags %#x\n",
+ (unsigned long long) data->min,
+ (unsigned long long) data->max,
+ (unsigned long long) data->align,
+ (unsigned long long) data->size, data->flags);
return 0;
}
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 54/70] PNP: improve resource assignment debug
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (50 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 53/70] PNP: increase I/O port & memory option address sizes Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 55/70] PNP: in debug resource dump, make empty list obvious Len Brown
` (15 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
When we fail to assign an I/O or MEM resource, include the min/max
in the debug output to help match it with the options.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/manager.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index e758dd2..c706dd2 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -47,7 +47,10 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
res->start += rule->align;
res->end = res->start + rule->size - 1;
if (res->start > rule->max || !rule->align) {
- dev_dbg(&dev->dev, " couldn't assign io %d\n", idx);
+ dev_dbg(&dev->dev, " couldn't assign io %d "
+ "(min %#llx max %#llx)\n", idx,
+ (unsigned long long) rule->min,
+ (unsigned long long) rule->max);
return 0;
}
}
@@ -96,7 +99,10 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
res->start += rule->align;
res->end = res->start + rule->size - 1;
if (res->start > rule->max || !rule->align) {
- dev_dbg(&dev->dev, " couldn't assign mem %d\n", idx);
+ dev_dbg(&dev->dev, " couldn't assign mem %d "
+ "(min %#llx max %#llx)\n", idx,
+ (unsigned long long) rule->min,
+ (unsigned long long) rule->max);
return 0;
}
}
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 55/70] PNP: in debug resource dump, make empty list obvious
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (51 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 54/70] PNP: improve resource assignment debug Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 56/70] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure) Len Brown
` (14 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
If the resource list is empty, say that explicitly. Previously,
it was confusing because often the heading was followed by zero
resource lines, then some "add resource" lines from auto-assignment,
so the "add" lines looked like current resources.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/support.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index 2ff2d1e..4beeabd 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -77,7 +77,12 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
struct pnp_resource *pnp_res;
struct resource *res;
- dev_dbg(&dev->dev, "current resources: %s\n", desc);
+ if (list_empty(&dev->resources)) {
+ dev_dbg(&dev->dev, "%s: no current resources\n", desc);
+ return;
+ }
+
+ dev_dbg(&dev->dev, "%s: current resources:\n", desc);
list_for_each_entry(pnp_res, &dev->resources, list) {
res = &pnp_res->res;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 56/70] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure)
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (52 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 55/70] PNP: in debug resource dump, make empty list obvious Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:43 ` [PATCH 57/70] PNP: remove redundant pnp_can_configure() check Len Brown
` (13 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
This patch doesn't change any behavior; it just makes the return
values more conventional.
This changes pnp_assign_dma() from a void function to one that
returns an int, just like the other assignment functions. For
now, at least, pnp_assign_dma() always returns 0 (success), so
it appears to never fail, just like before.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/manager.c | 41 ++++++++++++++++++++++-------------------
1 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index c706dd2..1adc83f 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -26,7 +26,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
"flags %#lx\n", idx, (unsigned long long) res->start,
(unsigned long long) res->end, res->flags);
- return 1;
+ return 0;
}
res = &local_res;
@@ -51,13 +51,13 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
"(min %#llx max %#llx)\n", idx,
(unsigned long long) rule->min,
(unsigned long long) rule->max);
- return 0;
+ return -EBUSY;
}
}
__add:
pnp_add_io_resource(dev, res->start, res->end, res->flags);
- return 1;
+ return 0;
}
static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
@@ -69,7 +69,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
"flags %#lx\n", idx, (unsigned long long) res->start,
(unsigned long long) res->end, res->flags);
- return 1;
+ return 0;
}
res = &local_res;
@@ -103,13 +103,13 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
"(min %#llx max %#llx)\n", idx,
(unsigned long long) rule->min,
(unsigned long long) rule->max);
- return 0;
+ return -EBUSY;
}
}
__add:
pnp_add_mem_resource(dev, res->start, res->end, res->flags);
- return 1;
+ return 0;
}
static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
@@ -126,7 +126,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
if (res) {
dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
idx, (int) res->start, res->flags);
- return 1;
+ return 0;
}
res = &local_res;
@@ -154,14 +154,14 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
}
}
dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx);
- return 0;
+ return -EBUSY;
__add:
pnp_add_irq_resource(dev, res->start, res->flags);
- return 1;
+ return 0;
}
-static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
+static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
{
struct resource *res, local_res;
int i;
@@ -175,7 +175,7 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
if (res) {
dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
idx, (int) res->start, res->flags);
- return;
+ return 0;
}
res = &local_res;
@@ -198,6 +198,7 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
__add:
pnp_add_dma_resource(dev, res->start, res->flags);
+ return 0;
}
void pnp_init_resources(struct pnp_dev *dev)
@@ -243,25 +244,26 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
irq = dev->independent->irq;
dma = dev->independent->dma;
while (port) {
- if (!pnp_assign_port(dev, port, nport))
+ if (pnp_assign_port(dev, port, nport) < 0)
goto fail;
nport++;
port = port->next;
}
while (mem) {
- if (!pnp_assign_mem(dev, mem, nmem))
+ if (pnp_assign_mem(dev, mem, nmem) < 0)
goto fail;
nmem++;
mem = mem->next;
}
while (irq) {
- if (!pnp_assign_irq(dev, irq, nirq))
+ if (pnp_assign_irq(dev, irq, nirq) < 0)
goto fail;
nirq++;
irq = irq->next;
}
while (dma) {
- pnp_assign_dma(dev, dma, ndma);
+ if (pnp_assign_dma(dev, dma, ndma) < 0)
+ goto fail;
ndma++;
dma = dma->next;
}
@@ -281,25 +283,26 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
irq = dep->irq;
dma = dep->dma;
while (port) {
- if (!pnp_assign_port(dev, port, nport))
+ if (pnp_assign_port(dev, port, nport) < 0)
goto fail;
nport++;
port = port->next;
}
while (mem) {
- if (!pnp_assign_mem(dev, mem, nmem))
+ if (pnp_assign_mem(dev, mem, nmem) < 0)
goto fail;
nmem++;
mem = mem->next;
}
while (irq) {
- if (!pnp_assign_irq(dev, irq, nirq))
+ if (pnp_assign_irq(dev, irq, nirq) < 0)
goto fail;
nirq++;
irq = irq->next;
}
while (dma) {
- pnp_assign_dma(dev, dma, ndma);
+ if (pnp_assign_dma(dev, dma, ndma) < 0)
+ goto fail;
ndma++;
dma = dma->next;
}
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 57/70] PNP: remove redundant pnp_can_configure() check
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (53 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 56/70] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure) Len Brown
@ 2008-06-20 7:43 ` Len Brown
2008-06-20 7:44 ` [PATCH 58/70] PNP: centralize resource option allocations Len Brown
` (12 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:43 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
pnp_assign_resources() is static and the only caller checks
pnp_can_configure() before calling it, so no need to do it
again.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/manager.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 1adc83f..7ea9e1e 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -231,9 +231,6 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
struct pnp_dma *dma;
int nport = 0, nmem = 0, nirq = 0, ndma = 0;
- if (!pnp_can_configure(dev))
- return -ENODEV;
-
dbg_pnp_show_resources(dev, "before pnp_assign_resources");
mutex_lock(&pnp_res_mutex);
pnp_clean_resource_table(dev);
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 58/70] PNP: centralize resource option allocations
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (54 preceding siblings ...)
2008-06-20 7:43 ` [PATCH 57/70] PNP: remove redundant pnp_can_configure() check Len Brown
@ 2008-06-20 7:44 ` Len Brown
2008-06-20 7:44 ` [PATCH 59/70] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR Len Brown
` (11 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
This patch moves all the option allocations (pnp_mem, pnp_port, etc)
into the pnp_register_{mem,port,irq,dma}_resource() functions. This
will make it easier to rework the option data structures.
The non-trivial part of this patch is the IRQ handling. The backends
have to allocate a local pnp_irq_mask_t bitmap, populate it, and pass
a pointer to pnp_register_irq_resource().
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/base.h | 12 ++-
drivers/pnp/isapnp/core.c | 112 ++++++++++++------------------
drivers/pnp/pnpacpi/rsparser.c | 149 +++++++++++++---------------------------
drivers/pnp/pnpbios/rsparser.c | 120 +++++++++++++-------------------
drivers/pnp/resource.c | 54 ++++++++++++--
5 files changed, 198 insertions(+), 249 deletions(-)
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index afbeee5..360c638 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -74,13 +74,17 @@ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
int priority);
int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
- struct pnp_irq *data);
+ pnp_irq_mask_t *map, unsigned char flags);
int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
- struct pnp_dma *data);
+ unsigned char map, unsigned char flags);
int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
- struct pnp_port *data);
+ resource_size_t min, resource_size_t max,
+ resource_size_t align, resource_size_t size,
+ unsigned char flags);
int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
- struct pnp_mem *data);
+ resource_size_t min, resource_size_t max,
+ resource_size_t align, resource_size_t size,
+ unsigned char flags);
void pnp_init_resources(struct pnp_dev *dev);
void pnp_fixup_device(struct pnp_dev *dev);
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index e0caa71..3f75fdb 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -433,20 +433,20 @@ static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
int size)
{
unsigned char tmp[3];
- struct pnp_irq *irq;
unsigned long bits;
+ pnp_irq_mask_t map;
+ unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
isapnp_peek(tmp, size);
- irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
- if (!irq)
- return;
bits = (tmp[1] << 8) | tmp[0];
- bitmap_copy(irq->map.bits, &bits, 16);
+
+ bitmap_zero(map.bits, PNP_IRQ_NR);
+ bitmap_copy(map.bits, &bits, 16);
+
if (size > 2)
- irq->flags = tmp[2];
- else
- irq->flags = IORESOURCE_IRQ_HIGHEDGE;
- pnp_register_irq_resource(dev, option, irq);
+ flags = tmp[2];
+
+ pnp_register_irq_resource(dev, option, &map, flags);
}
/*
@@ -457,15 +457,9 @@ static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
int size)
{
unsigned char tmp[2];
- struct pnp_dma *dma;
isapnp_peek(tmp, size);
- dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
- if (!dma)
- return;
- dma->map = tmp[0];
- dma->flags = tmp[1];
- pnp_register_dma_resource(dev, option, dma);
+ pnp_register_dma_resource(dev, option, tmp[0], tmp[1]);
}
/*
@@ -476,18 +470,16 @@ static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
int size)
{
unsigned char tmp[7];
- struct pnp_port *port;
+ resource_size_t min, max, align, len;
+ unsigned char flags;
isapnp_peek(tmp, size);
- port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
- if (!port)
- return;
- port->min = (tmp[2] << 8) | tmp[1];
- port->max = (tmp[4] << 8) | tmp[3];
- port->align = tmp[5];
- port->size = tmp[6];
- port->flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
- pnp_register_port_resource(dev, option, port);
+ min = (tmp[2] << 8) | tmp[1];
+ max = (tmp[4] << 8) | tmp[3];
+ align = tmp[5];
+ len = tmp[6];
+ flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
+ pnp_register_port_resource(dev, option, min, max, align, len, flags);
}
/*
@@ -498,17 +490,13 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
int size)
{
unsigned char tmp[3];
- struct pnp_port *port;
+ resource_size_t base, len;
isapnp_peek(tmp, size);
- port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
- if (!port)
- return;
- port->min = port->max = (tmp[1] << 8) | tmp[0];
- port->size = tmp[2];
- port->align = 0;
- port->flags = IORESOURCE_IO_FIXED;
- pnp_register_port_resource(dev, option, port);
+ base = (tmp[1] << 8) | tmp[0];
+ len = tmp[2];
+ pnp_register_port_resource(dev, option, base, base, 0, len,
+ IORESOURCE_IO_FIXED);
}
/*
@@ -519,18 +507,16 @@ static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
int size)
{
unsigned char tmp[9];
- struct pnp_mem *mem;
+ resource_size_t min, max, align, len;
+ unsigned char flags;
isapnp_peek(tmp, size);
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = ((tmp[2] << 8) | tmp[1]) << 8;
- mem->max = ((tmp[4] << 8) | tmp[3]) << 8;
- mem->align = (tmp[6] << 8) | tmp[5];
- mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
- mem->flags = tmp[0];
- pnp_register_mem_resource(dev, option, mem);
+ min = ((tmp[2] << 8) | tmp[1]) << 8;
+ max = ((tmp[4] << 8) | tmp[3]) << 8;
+ align = (tmp[6] << 8) | tmp[5];
+ len = ((tmp[8] << 8) | tmp[7]) << 8;
+ flags = tmp[0];
+ pnp_register_mem_resource(dev, option, min, max, align, len, flags);
}
/*
@@ -541,20 +527,16 @@ static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
int size)
{
unsigned char tmp[17];
- struct pnp_mem *mem;
+ resource_size_t min, max, align, len;
+ unsigned char flags;
isapnp_peek(tmp, size);
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
- mem->max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
- mem->align =
- (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
- mem->size =
- (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
- mem->flags = tmp[0];
- pnp_register_mem_resource(dev, option, mem);
+ min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
+ max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
+ align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
+ len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
+ flags = tmp[0];
+ pnp_register_mem_resource(dev, option, min, max, align, len, flags);
}
/*
@@ -565,18 +547,14 @@ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
int size)
{
unsigned char tmp[9];
- struct pnp_mem *mem;
+ resource_size_t base, len;
+ unsigned char flags;
isapnp_peek(tmp, size);
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = mem->max =
- (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
- mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
- mem->align = 0;
- mem->flags = tmp[0];
- pnp_register_mem_resource(dev, option, mem);
+ base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
+ len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
+ flags = tmp[0];
+ pnp_register_mem_resource(dev, option, base, base, 0, len, flags);
}
/*
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index ae65454..3aaf406 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -411,20 +411,16 @@ static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
struct acpi_resource_dma *p)
{
int i;
- struct pnp_dma *dma;
+ unsigned char map = 0, flags;
if (p->channel_count == 0)
return;
- dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
- if (!dma)
- return;
for (i = 0; i < p->channel_count; i++)
- dma->map |= 1 << p->channels[i];
-
- dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
+ map |= 1 << p->channels[i];
- pnp_register_dma_resource(dev, option, dma);
+ flags = dma_flags(p->type, p->bus_master, p->transfer);
+ pnp_register_dma_resource(dev, option, map, flags);
}
static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
@@ -432,20 +428,19 @@ static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
struct acpi_resource_irq *p)
{
int i;
- struct pnp_irq *irq;
+ pnp_irq_mask_t map;
+ unsigned char flags;
if (p->interrupt_count == 0)
return;
- irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
- if (!irq)
- return;
+ bitmap_zero(map.bits, PNP_IRQ_NR);
for (i = 0; i < p->interrupt_count; i++)
if (p->interrupts[i])
- __set_bit(p->interrupts[i], irq->map.bits);
- irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
+ __set_bit(p->interrupts[i], map.bits);
- pnp_register_irq_resource(dev, option, irq);
+ flags = irq_flags(p->triggering, p->polarity, p->sharable);
+ pnp_register_irq_resource(dev, option, &map, flags);
}
static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
@@ -453,123 +448,90 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
struct acpi_resource_extended_irq *p)
{
int i;
- struct pnp_irq *irq;
+ pnp_irq_mask_t map;
+ unsigned char flags;
if (p->interrupt_count == 0)
return;
- irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
- if (!irq)
- return;
+ bitmap_zero(map.bits, PNP_IRQ_NR);
for (i = 0; i < p->interrupt_count; i++)
if (p->interrupts[i])
- __set_bit(p->interrupts[i], irq->map.bits);
- irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
+ __set_bit(p->interrupts[i], map.bits);
- pnp_register_irq_resource(dev, option, irq);
+ flags = irq_flags(p->triggering, p->polarity, p->sharable);
+ pnp_register_irq_resource(dev, option, &map, flags);
}
static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
struct pnp_option *option,
struct acpi_resource_io *io)
{
- struct pnp_port *port;
+ unsigned char flags = 0;
if (io->address_length == 0)
return;
- port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
- if (!port)
- return;
- port->min = io->minimum;
- port->max = io->maximum;
- port->align = io->alignment;
- port->size = io->address_length;
- port->flags = ACPI_DECODE_16 == io->io_decode ?
- IORESOURCE_IO_16BIT_ADDR : 0;
- pnp_register_port_resource(dev, option, port);
+
+ if (io->io_decode == ACPI_DECODE_16)
+ flags = IORESOURCE_IO_16BIT_ADDR;
+ pnp_register_port_resource(dev, option, io->minimum, io->maximum,
+ io->alignment, io->address_length, flags);
}
static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
struct pnp_option *option,
struct acpi_resource_fixed_io *io)
{
- struct pnp_port *port;
-
if (io->address_length == 0)
return;
- port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
- if (!port)
- return;
- port->min = port->max = io->address;
- port->size = io->address_length;
- port->align = 0;
- port->flags = IORESOURCE_IO_FIXED;
- pnp_register_port_resource(dev, option, port);
+
+ pnp_register_port_resource(dev, option, io->address, io->address, 0,
+ io->address_length, IORESOURCE_IO_FIXED);
}
static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
struct pnp_option *option,
struct acpi_resource_memory24 *p)
{
- struct pnp_mem *mem;
+ unsigned char flags = 0;
if (p->address_length == 0)
return;
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = p->minimum;
- mem->max = p->maximum;
- mem->align = p->alignment;
- mem->size = p->address_length;
- mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
- IORESOURCE_MEM_WRITEABLE : 0;
-
- pnp_register_mem_resource(dev, option, mem);
+ if (p->write_protect == ACPI_READ_WRITE_MEMORY)
+ flags = IORESOURCE_MEM_WRITEABLE;
+ pnp_register_mem_resource(dev, option, p->minimum, p->maximum,
+ p->alignment, p->address_length, flags);
}
static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
struct pnp_option *option,
struct acpi_resource_memory32 *p)
{
- struct pnp_mem *mem;
+ unsigned char flags = 0;
if (p->address_length == 0)
return;
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = p->minimum;
- mem->max = p->maximum;
- mem->align = p->alignment;
- mem->size = p->address_length;
- mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
- IORESOURCE_MEM_WRITEABLE : 0;
-
- pnp_register_mem_resource(dev, option, mem);
+ if (p->write_protect == ACPI_READ_WRITE_MEMORY)
+ flags = IORESOURCE_MEM_WRITEABLE;
+ pnp_register_mem_resource(dev, option, p->minimum, p->maximum,
+ p->alignment, p->address_length, flags);
}
static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
struct pnp_option *option,
struct acpi_resource_fixed_memory32 *p)
{
- struct pnp_mem *mem;
+ unsigned char flags = 0;
if (p->address_length == 0)
return;
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = mem->max = p->address;
- mem->size = p->address_length;
- mem->align = 0;
- mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
- IORESOURCE_MEM_WRITEABLE : 0;
-
- pnp_register_mem_resource(dev, option, mem);
+ if (p->write_protect == ACPI_READ_WRITE_MEMORY)
+ flags = IORESOURCE_MEM_WRITEABLE;
+ pnp_register_mem_resource(dev, option, p->address, p->address,
+ 0, p->address_length, flags);
}
static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
@@ -578,8 +540,7 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
{
struct acpi_resource_address64 addr, *p = &addr;
acpi_status status;
- struct pnp_mem *mem;
- struct pnp_port *port;
+ unsigned char flags = 0;
status = acpi_resource_to_address64(r, p);
if (!ACPI_SUCCESS(status)) {
@@ -592,26 +553,14 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
return;
if (p->resource_type == ACPI_MEMORY_RANGE) {
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = mem->max = p->minimum;
- mem->size = p->address_length;
- mem->align = 0;
- mem->flags = (p->info.mem.write_protect ==
- ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE
- : 0;
- pnp_register_mem_resource(dev, option, mem);
- } else if (p->resource_type == ACPI_IO_RANGE) {
- port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
- if (!port)
- return;
- port->min = port->max = p->minimum;
- port->size = p->address_length;
- port->align = 0;
- port->flags = IORESOURCE_IO_FIXED;
- pnp_register_port_resource(dev, option, port);
- }
+ if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
+ flags = IORESOURCE_MEM_WRITEABLE;
+ pnp_register_mem_resource(dev, option, p->minimum, p->minimum,
+ 0, p->address_length, flags);
+ } else if (p->resource_type == ACPI_IO_RANGE)
+ pnp_register_port_resource(dev, option, p->minimum, p->minimum,
+ 0, p->address_length,
+ IORESOURCE_IO_FIXED);
}
struct acpipnp_parse_option_s {
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index dd2ea7b..26fb04c 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -218,116 +218,96 @@ static __init void pnpbios_parse_mem_option(struct pnp_dev *dev,
unsigned char *p, int size,
struct pnp_option *option)
{
- struct pnp_mem *mem;
-
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = ((p[5] << 8) | p[4]) << 8;
- mem->max = ((p[7] << 8) | p[6]) << 8;
- mem->align = (p[9] << 8) | p[8];
- mem->size = ((p[11] << 8) | p[10]) << 8;
- mem->flags = p[3];
- pnp_register_mem_resource(dev, option, mem);
+ resource_size_t min, max, align, len;
+ unsigned char flags;
+
+ min = ((p[5] << 8) | p[4]) << 8;
+ max = ((p[7] << 8) | p[6]) << 8;
+ align = (p[9] << 8) | p[8];
+ len = ((p[11] << 8) | p[10]) << 8;
+ flags = p[3];
+ pnp_register_mem_resource(dev, option, min, max, align, len, flags);
}
static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
unsigned char *p, int size,
struct pnp_option *option)
{
- struct pnp_mem *mem;
-
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
- mem->max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
- mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
- mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
- mem->flags = p[3];
- pnp_register_mem_resource(dev, option, mem);
+ resource_size_t min, max, align, len;
+ unsigned char flags;
+
+ min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
+ max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
+ align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
+ len = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
+ flags = p[3];
+ pnp_register_mem_resource(dev, option, min, max, align, len, flags);
}
static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
unsigned char *p, int size,
struct pnp_option *option)
{
- struct pnp_mem *mem;
-
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
- return;
- mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
- mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
- mem->align = 0;
- mem->flags = p[3];
- pnp_register_mem_resource(dev, option, mem);
+ resource_size_t base, len;
+ unsigned char flags;
+
+ base = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
+ len = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
+ flags = p[3];
+ pnp_register_mem_resource(dev, option, base, base, 0, len, flags);
}
static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
unsigned char *p, int size,
struct pnp_option *option)
{
- struct pnp_irq *irq;
unsigned long bits;
+ pnp_irq_mask_t map;
+ unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
- irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
- if (!irq)
- return;
bits = (p[2] << 8) | p[1];
- bitmap_copy(irq->map.bits, &bits, 16);
+
+ bitmap_zero(map.bits, PNP_IRQ_NR);
+ bitmap_copy(map.bits, &bits, 16);
+
if (size > 2)
- irq->flags = p[3];
- else
- irq->flags = IORESOURCE_IRQ_HIGHEDGE;
- pnp_register_irq_resource(dev, option, irq);
+ flags = p[3];
+
+ pnp_register_irq_resource(dev, option, &map, flags);
}
static __init void pnpbios_parse_dma_option(struct pnp_dev *dev,
unsigned char *p, int size,
struct pnp_option *option)
{
- struct pnp_dma *dma;
-
- dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
- if (!dma)
- return;
- dma->map = p[1];
- dma->flags = p[2];
- pnp_register_dma_resource(dev, option, dma);
+ pnp_register_dma_resource(dev, option, p[1], p[2]);
}
static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
unsigned char *p, int size,
struct pnp_option *option)
{
- struct pnp_port *port;
-
- port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
- if (!port)
- return;
- port->min = (p[3] << 8) | p[2];
- port->max = (p[5] << 8) | p[4];
- port->align = p[6];
- port->size = p[7];
- port->flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0;
- pnp_register_port_resource(dev, option, port);
+ resource_size_t min, max, align, len;
+ unsigned char flags;
+
+ min = (p[3] << 8) | p[2];
+ max = (p[5] << 8) | p[4];
+ align = p[6];
+ len = p[7];
+ flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0;
+ pnp_register_port_resource(dev, option, min, max, align, len, flags);
}
static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
unsigned char *p, int size,
struct pnp_option *option)
{
- struct pnp_port *port;
-
- port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
- if (!port)
- return;
- port->min = port->max = (p[2] << 8) | p[1];
- port->size = p[3];
- port->align = 0;
- port->flags = IORESOURCE_IO_FIXED;
- pnp_register_port_resource(dev, option, port);
+ resource_size_t base, len;
+
+ base = (p[2] << 8) | p[1];
+ len = p[3];
+ pnp_register_port_resource(dev, option, base, base, 0, len,
+ IORESOURCE_IO_FIXED);
}
static __init unsigned char *
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 391828c..6114549 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -78,13 +78,20 @@ struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
}
int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
- struct pnp_irq *data)
+ pnp_irq_mask_t *map, unsigned char flags)
{
- struct pnp_irq *ptr;
+ struct pnp_irq *data, *ptr;
#ifdef DEBUG
char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */
#endif
+ data = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->map = *map;
+ data->flags = flags;
+
ptr = option->irq;
while (ptr && ptr->next)
ptr = ptr->next;
@@ -112,9 +119,16 @@ int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
}
int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
- struct pnp_dma *data)
+ unsigned char map, unsigned char flags)
{
- struct pnp_dma *ptr;
+ struct pnp_dma *data, *ptr;
+
+ data = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->map = map;
+ data->flags = flags;
ptr = option->dma;
while (ptr && ptr->next)
@@ -130,9 +144,21 @@ int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
}
int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
- struct pnp_port *data)
+ resource_size_t min, resource_size_t max,
+ resource_size_t align, resource_size_t size,
+ unsigned char flags)
{
- struct pnp_port *ptr;
+ struct pnp_port *data, *ptr;
+
+ data = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->min = min;
+ data->max = max;
+ data->align = align;
+ data->size = size;
+ data->flags = flags;
ptr = option->port;
while (ptr && ptr->next)
@@ -152,9 +178,21 @@ int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
}
int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
- struct pnp_mem *data)
+ resource_size_t min, resource_size_t max,
+ resource_size_t align, resource_size_t size,
+ unsigned char flags)
{
- struct pnp_mem *ptr;
+ struct pnp_mem *data, *ptr;
+
+ data = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->min = min;
+ data->max = max;
+ data->align = align;
+ data->size = size;
+ data->flags = flags;
ptr = option->mem;
while (ptr && ptr->next)
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 59/70] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (55 preceding siblings ...)
2008-06-20 7:44 ` [PATCH 58/70] PNP: centralize resource option allocations Len Brown
@ 2008-06-20 7:44 ` Len Brown
2008-06-20 7:44 ` [PATCH 60/70] PNP: rename pnp_register_*_resource() local variables Len Brown
` (10 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
ACPI Extended Interrupt Descriptors can encode 32-bit interrupt
numbers, so an interrupt number may exceed the size of the bitmap
we use to track possible IRQ settings.
To avoid corrupting memory, complain and ignore too-large interrupt
numbers.
There's similar code in pnpacpi_parse_irq_option(), but I didn't
change that because the small IRQ descriptor can only encode
IRQs 0-15, which do not exceed bitmap size.
In the future, we could handle IRQ numbers greater than PNP_IRQ_NR
by replacing the bitmap with a table or list.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/pnpacpi/rsparser.c | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 3aaf406..3808a8f 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -435,9 +435,16 @@ static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
return;
bitmap_zero(map.bits, PNP_IRQ_NR);
- for (i = 0; i < p->interrupt_count; i++)
- if (p->interrupts[i])
- __set_bit(p->interrupts[i], map.bits);
+ for (i = 0; i < p->interrupt_count; i++) {
+ if (p->interrupts[i]) {
+ if (p->interrupts[i] < PNP_IRQ_NR)
+ __set_bit(p->interrupts[i], map.bits);
+ else
+ dev_err(&dev->dev, "ignoring IRQ %d option "
+ "(too large for %d entry bitmap)\n",
+ p->interrupts[i], PNP_IRQ_NR);
+ }
+ }
flags = irq_flags(p->triggering, p->polarity, p->sharable);
pnp_register_irq_resource(dev, option, &map, flags);
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 60/70] PNP: rename pnp_register_*_resource() local variables
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (56 preceding siblings ...)
2008-06-20 7:44 ` [PATCH 59/70] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR Len Brown
@ 2008-06-20 7:44 ` Len Brown
2008-06-20 7:44 ` [PATCH 61/70] PNP: support optional IRQ resources Len Brown
` (9 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
No functional change; just rename "data" to something more
descriptive.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/resource.c | 94 ++++++++++++++++++++++++------------------------
1 files changed, 47 insertions(+), 47 deletions(-)
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 6114549..a795864 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -80,40 +80,40 @@ struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
pnp_irq_mask_t *map, unsigned char flags)
{
- struct pnp_irq *data, *ptr;
+ struct pnp_irq *irq, *ptr;
#ifdef DEBUG
char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */
#endif
- data = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
- if (!data)
+ irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
+ if (!irq)
return -ENOMEM;
- data->map = *map;
- data->flags = flags;
+ irq->map = *map;
+ irq->flags = flags;
ptr = option->irq;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
- ptr->next = data;
+ ptr->next = irq;
else
- option->irq = data;
+ option->irq = irq;
#ifdef CONFIG_PCI
{
int i;
for (i = 0; i < 16; i++)
- if (test_bit(i, data->map.bits))
+ if (test_bit(i, irq->map.bits))
pcibios_penalize_isa_irq(i, 0);
}
#endif
#ifdef DEBUG
- bitmap_scnprintf(buf, sizeof(buf), data->map.bits, PNP_IRQ_NR);
+ bitmap_scnprintf(buf, sizeof(buf), irq->map.bits, PNP_IRQ_NR);
dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf,
- data->flags);
+ irq->flags);
#endif
return 0;
}
@@ -121,25 +121,25 @@ int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
unsigned char map, unsigned char flags)
{
- struct pnp_dma *data, *ptr;
+ struct pnp_dma *dma, *ptr;
- data = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
- if (!data)
+ dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
+ if (!dma)
return -ENOMEM;
- data->map = map;
- data->flags = flags;
+ dma->map = map;
+ dma->flags = flags;
ptr = option->dma;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
- ptr->next = data;
+ ptr->next = dma;
else
- option->dma = data;
+ option->dma = dma;
- dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", data->map,
- data->flags);
+ dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", dma->map,
+ dma->flags);
return 0;
}
@@ -148,32 +148,32 @@ int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
resource_size_t align, resource_size_t size,
unsigned char flags)
{
- struct pnp_port *data, *ptr;
+ struct pnp_port *port, *ptr;
- data = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
- if (!data)
+ port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
+ if (!port)
return -ENOMEM;
- data->min = min;
- data->max = max;
- data->align = align;
- data->size = size;
- data->flags = flags;
+ port->min = min;
+ port->max = max;
+ port->align = align;
+ port->size = size;
+ port->flags = flags;
ptr = option->port;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
- ptr->next = data;
+ ptr->next = port;
else
- option->port = data;
+ option->port = port;
dev_dbg(&dev->dev, " io "
"min %#llx max %#llx align %lld size %lld flags %#x\n",
- (unsigned long long) data->min,
- (unsigned long long) data->max,
- (unsigned long long) data->align,
- (unsigned long long) data->size, data->flags);
+ (unsigned long long) port->min,
+ (unsigned long long) port->max,
+ (unsigned long long) port->align,
+ (unsigned long long) port->size, port->flags);
return 0;
}
@@ -182,32 +182,32 @@ int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
resource_size_t align, resource_size_t size,
unsigned char flags)
{
- struct pnp_mem *data, *ptr;
+ struct pnp_mem *mem, *ptr;
- data = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!data)
+ mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
+ if (!mem)
return -ENOMEM;
- data->min = min;
- data->max = max;
- data->align = align;
- data->size = size;
- data->flags = flags;
+ mem->min = min;
+ mem->max = max;
+ mem->align = align;
+ mem->size = size;
+ mem->flags = flags;
ptr = option->mem;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
- ptr->next = data;
+ ptr->next = mem;
else
- option->mem = data;
+ option->mem = mem;
dev_dbg(&dev->dev, " mem "
"min %#llx max %#llx align %lld size %lld flags %#x\n",
- (unsigned long long) data->min,
- (unsigned long long) data->max,
- (unsigned long long) data->align,
- (unsigned long long) data->size, data->flags);
+ (unsigned long long) mem->min,
+ (unsigned long long) mem->max,
+ (unsigned long long) mem->align,
+ (unsigned long long) mem->size, mem->flags);
return 0;
}
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 61/70] PNP: support optional IRQ resources
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (57 preceding siblings ...)
2008-06-20 7:44 ` [PATCH 60/70] PNP: rename pnp_register_*_resource() local variables Len Brown
@ 2008-06-20 7:44 ` Len Brown
2008-06-20 7:44 ` [PATCH 62/70] PNP: remove extra 0x100 bit from option priority Len Brown
` (8 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
This patch adds an IORESOURCE_IRQ_OPTIONAL flag for use when
assigning resources to a device. If the flag is set and we are
unable to assign an IRQ to the device, we can leave the IRQ
disabled but allow the overall resource allocation to succeed.
Some devices request an IRQ, but can run without an IRQ
(possibly with degraded performance). This flag lets us run
the device without the IRQ instead of just leaving the
device disabled.
This is a reimplementation of this previous change by Rene
Herman <rene.herman@gmail.com>:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b73a223661ed137c5d3d2635f954382e94f5a43
I reimplemented this for two reasons:
- to prepare for converting all resource options into a single linked
list, as opposed to the per-resource-type lists we have now, and
- to preserve the order and number of resource options.
In PNPBIOS and ACPI, we configure a device by giving firmware a
list of resource assignments. It is important that this list
has exactly the same number of resources, in the same order,
as the "template" list we got from the firmware in the first
place.
The problem of a sound card MPU401 being left disabled for want of
an IRQ was reported by Uwe Bugla <uwe.bugla@gmx.de>.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/interface.c | 2 +
drivers/pnp/manager.c | 9 ++++++
drivers/pnp/quirks.c | 71 ++++++++++++++++++-----------------------------
include/linux/ioport.h | 1 +
4 files changed, 39 insertions(+), 44 deletions(-)
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index b09f67d..7a9fb55 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -90,6 +90,8 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
pnp_printf(buffer, " High-Level");
if (irq->flags & IORESOURCE_IRQ_LOWLEVEL)
pnp_printf(buffer, " Low-Level");
+ if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
+ pnp_printf(buffer, " (optional)");
pnp_printf(buffer, "\n");
}
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 7ea9e1e..a20accb 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -153,6 +153,15 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
goto __add;
}
}
+
+ if (rule->flags & IORESOURCE_IRQ_OPTIONAL) {
+ res->start = -1;
+ res->end = -1;
+ res->flags |= IORESOURCE_DISABLED;
+ dev_dbg(&dev->dev, " irq %d disabled (optional)\n", idx);
+ goto __add;
+ }
+
dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx);
return -EBUSY;
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index c3ab348..3a93fcf 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -118,34 +118,46 @@ static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev)
struct pnp_option *res;
/*
- * Build a functional IRQ-less variant of each MPU option.
+ * Build a functional IRQ-optional variant of each MPU option.
*/
for (res = dev->dependent; res; res = res->next) {
struct pnp_option *curr;
struct pnp_port *port;
- struct pnp_port *copy;
+ struct pnp_port *copy_port;
+ struct pnp_irq *irq;
+ struct pnp_irq *copy_irq;
port = res->port;
- if (!port || !res->irq)
+ irq = res->irq;
+ if (!port || !irq)
continue;
- copy = pnp_alloc(sizeof *copy);
- if (!copy)
+ copy_port = pnp_alloc(sizeof *copy_port);
+ if (!copy_port)
+ break;
+
+ copy_irq = pnp_alloc(sizeof *copy_irq);
+ if (!copy_irq) {
+ kfree(copy_port);
break;
+ }
+
+ *copy_port = *port;
+ copy_port->next = NULL;
- copy->min = port->min;
- copy->max = port->max;
- copy->align = port->align;
- copy->size = port->size;
- copy->flags = port->flags;
+ *copy_irq = *irq;
+ copy_irq->flags |= IORESOURCE_IRQ_OPTIONAL;
+ copy_irq->next = NULL;
curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL);
if (!curr) {
- kfree(copy);
+ kfree(copy_port);
+ kfree(copy_irq);
break;
}
- curr->port = copy;
+ curr->port = copy_port;
+ curr->irq = copy_irq;
if (prev)
prev->next = curr;
@@ -154,7 +166,7 @@ static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev)
prev = curr;
}
if (head)
- dev_info(&dev->dev, "adding IRQ-less MPU options\n");
+ dev_info(&dev->dev, "adding IRQ-optional MPU options\n");
return head;
}
@@ -164,10 +176,6 @@ static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
struct pnp_option *res;
struct pnp_irq *irq;
- /*
- * Distribute the independent IRQ over the dependent options
- */
-
res = dev->independent;
if (!res)
return;
@@ -176,33 +184,8 @@ static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
if (!irq || irq->next)
return;
- res = dev->dependent;
- if (!res)
- return;
-
- while (1) {
- struct pnp_irq *copy;
-
- copy = pnp_alloc(sizeof *copy);
- if (!copy)
- break;
-
- bitmap_copy(copy->map.bits, irq->map.bits, PNP_IRQ_NR);
- copy->flags = irq->flags;
-
- copy->next = res->irq; /* Yes, this is NULL */
- res->irq = copy;
-
- if (!res->next)
- break;
- res = res->next;
- }
- kfree(irq);
-
- res->next = quirk_isapnp_mpu_options(dev);
-
- res = dev->independent;
- res->irq = NULL;
+ irq->flags |= IORESOURCE_IRQ_OPTIONAL;
+ dev_info(&dev->dev, "made independent IRQ optional\n");
}
static void quirk_isapnp_mpu_resources(struct pnp_dev *dev)
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 39db059..08c825b 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -59,6 +59,7 @@ struct resource_list {
#define IORESOURCE_IRQ_HIGHLEVEL (1<<2)
#define IORESOURCE_IRQ_LOWLEVEL (1<<3)
#define IORESOURCE_IRQ_SHAREABLE (1<<4)
+#define IORESOURCE_IRQ_OPTIONAL (1<<5)
/* PnP DMA specific bits (IORESOURCE_BITS) */
#define IORESOURCE_DMA_TYPE_MASK (3<<0)
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 62/70] PNP: remove extra 0x100 bit from option priority
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (58 preceding siblings ...)
2008-06-20 7:44 ` [PATCH 61/70] PNP: support optional IRQ resources Len Brown
@ 2008-06-20 7:44 ` Len Brown
2008-06-20 7:44 ` [PATCH 63/70] ISAPNP: handle independent options following dependent ones Len Brown
` (7 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
When building resource options, ISAPNP and PNPBIOS set the priority
to something like "0x100 | PNP_RES_PRIORITY_ACCEPTABLE", but we
immediately mask off the 0x100 again in pnp_build_option(), so that
bit looks superfluous.
Thanks to Rene Herman <rene.herman@gmail.com> for pointing this out.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/isapnp/core.c | 8 +++-----
drivers/pnp/pnpacpi/rsparser.c | 2 +-
drivers/pnp/pnpbios/rsparser.c | 6 +++---
3 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 3f75fdb..90718be 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -582,7 +582,7 @@ isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
static int __init isapnp_create_device(struct pnp_card *card,
unsigned short size)
{
- int number = 0, skip = 0, priority = 0, compat = 0;
+ int number = 0, skip = 0, priority, compat = 0;
unsigned char type, tmp[17];
struct pnp_option *option;
struct pnp_dev *dev;
@@ -621,7 +621,6 @@ static int __init isapnp_create_device(struct pnp_card *card,
} else {
skip = 1;
}
- priority = 0;
compat = 0;
break;
case _STAG_COMPATDEVID:
@@ -650,10 +649,10 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _STAG_STARTDEP:
if (size > 1)
goto __skip;
- priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
+ priority = PNP_RES_PRIORITY_ACCEPTABLE;
if (size > 0) {
isapnp_peek(tmp, size);
- priority = 0x100 | tmp[0];
+ priority = tmp[0];
size = 0;
}
option = pnp_register_dependent_option(dev, priority);
@@ -663,7 +662,6 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _STAG_ENDDEP:
if (size != 0)
goto __skip;
- priority = 0;
dev_dbg(&dev->dev, "end dependent options\n");
break;
case _STAG_IOPORT:
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 3808a8f..e6bd14d 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -579,7 +579,7 @@ struct acpipnp_parse_option_s {
static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
void *data)
{
- int priority = 0;
+ int priority;
struct acpipnp_parse_option_s *parse_data = data;
struct pnp_dev *dev = parse_data->dev;
struct pnp_option *option = parse_data->option;
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index 26fb04c..db23ba7 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -315,7 +315,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
struct pnp_dev *dev)
{
unsigned int len, tag;
- int priority = 0;
+ int priority;
struct pnp_option *option, *option_independent;
if (!p)
@@ -389,9 +389,9 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
case SMALL_TAG_STARTDEP:
if (len > 1)
goto len_err;
- priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
+ priority = PNP_RES_PRIORITY_ACCEPTABLE;
if (len > 0)
- priority = 0x100 | p[1];
+ priority = p[1];
option = pnp_register_dependent_option(dev, priority);
if (!option)
return NULL;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 63/70] ISAPNP: handle independent options following dependent ones
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (59 preceding siblings ...)
2008-06-20 7:44 ` [PATCH 62/70] PNP: remove extra 0x100 bit from option priority Len Brown
@ 2008-06-20 7:44 ` Len Brown
2008-06-20 7:44 ` [PATCH 64/70] PNP: convert resource options to single linked list Len Brown
` (6 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
The ISAPNP spec recommends that independent options precede
dependent ones, but this is not actually required. The current
ISAPNP code incorrectly puts such trailing independent options
at the end of the last dependent option list.
This patch fixes that bug by resetting the current option list
to the independent list when we see an "End Dependent Functions"
tag. PNPBIOS and PNPACPI handle this the same way.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/isapnp/core.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 90718be..53cc4d6 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -584,14 +584,14 @@ static int __init isapnp_create_device(struct pnp_card *card,
{
int number = 0, skip = 0, priority, compat = 0;
unsigned char type, tmp[17];
- struct pnp_option *option;
+ struct pnp_option *option, *option_independent;
struct pnp_dev *dev;
u32 eisa_id;
char id[8];
if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
return 1;
- option = pnp_register_independent_option(dev);
+ option_independent = option = pnp_register_independent_option(dev);
if (!option) {
kfree(dev);
return 1;
@@ -613,6 +613,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
size = 0;
skip = 0;
option = pnp_register_independent_option(dev);
+ option_independent = option;
if (!option) {
kfree(dev);
return 1;
@@ -662,6 +663,10 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _STAG_ENDDEP:
if (size != 0)
goto __skip;
+ if (option_independent == option)
+ dev_warn(&dev->dev, "missing "
+ "_STAG_STARTDEP tag\n");
+ option = option_independent;
dev_dbg(&dev->dev, "end dependent options\n");
break;
case _STAG_IOPORT:
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 64/70] PNP: convert resource options to single linked list
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (60 preceding siblings ...)
2008-06-20 7:44 ` [PATCH 63/70] ISAPNP: handle independent options following dependent ones Len Brown
@ 2008-06-20 7:44 ` Len Brown
2008-06-20 7:44 ` [PATCH 65/70] PNP: avoid legacy IDE IRQs Len Brown
` (5 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
ISAPNP, PNPBIOS, and ACPI describe the "possible resource settings" of
a device, i.e., the possibilities an OS bus driver has when it assigns
I/O port, MMIO, and other resources to the device.
PNP used to maintain this "possible resource setting" information in
one independent option structure and a list of dependent option
structures for each device. Each of these option structures had lists
of I/O, memory, IRQ, and DMA resources, for example:
dev
independent options
ind-io0 -> ind-io1 ...
ind-mem0 -> ind-mem1 ...
...
dependent option set 0
dep0-io0 -> dep0-io1 ...
dep0-mem0 -> dep0-mem1 ...
...
dependent option set 1
dep1-io0 -> dep1-io1 ...
dep1-mem0 -> dep1-mem1 ...
...
...
This data structure was designed for ISAPNP, where the OS configures
device resource settings by writing directly to configuration
registers. The OS can write the registers in arbitrary order much
like it writes PCI BARs.
However, for PNPBIOS and ACPI devices, the OS uses firmware interfaces
that perform device configuration, and it is important to pass the
desired settings to those interfaces in the correct order. The OS
learns the correct order by using firmware interfaces that return the
"current resource settings" and "possible resource settings," but the
option structures above doesn't store the ordering information.
This patch replaces the independent and dependent lists with a single
list of options. For example, a device might have possible resource
settings like this:
dev
options
ind-io0 -> dep0-io0 -> dep1->io0 -> ind-io1 ...
All the possible settings are in the same list, in the order they
come from the firmware "possible resource settings" list. Each entry
is tagged with an independent/dependent flag. Dependent entries also
have a "set number" and an optional priority value. All dependent
entries must be assigned from the same set. For example, the OS can
use all the entries from dependent set 0, or all the entries from
dependent set 1, but it cannot mix entries from set 0 with entries
from set 1.
Prior to this patch PNP didn't keep track of the order of this list,
and it assigned all independent options first, then all dependent
ones. Using the example above, that resulted in a "desired
configuration" list like this:
ind->io0 -> ind->io1 -> depN-io0 ...
instead of the list the firmware expects, which looks like this:
ind->io0 -> depN-io0 -> ind-io1 ...
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Acked-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/base.h | 93 ++++++++++---
drivers/pnp/core.c | 4 +-
drivers/pnp/interface.c | 75 +++++------
drivers/pnp/isapnp/core.c | 72 +++++------
drivers/pnp/manager.c | 145 +++++++--------------
drivers/pnp/pnpacpi/rsparser.c | 93 ++++++--------
drivers/pnp/pnpbios/rsparser.c | 67 +++++-----
drivers/pnp/quirks.c | 289 +++++++++++++++++++++------------------
drivers/pnp/resource.c | 268 +++++++++----------------------------
drivers/pnp/support.c | 79 +++++++++++
include/linux/pnp.h | 6 +-
11 files changed, 559 insertions(+), 632 deletions(-)
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 360c638..e3fa9a2 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -1,3 +1,8 @@
+/*
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
+ */
+
extern spinlock_t pnp_lock;
void *pnp_alloc(long size);
@@ -25,8 +30,6 @@ struct pnp_port {
resource_size_t align; /* align boundary */
resource_size_t size; /* size of range */
unsigned char flags; /* port flags */
- unsigned char pad; /* pad */
- struct pnp_port *next; /* next port */
};
#define PNP_IRQ_NR 256
@@ -35,14 +38,11 @@ typedef struct { DECLARE_BITMAP(bits, PNP_IRQ_NR); } pnp_irq_mask_t;
struct pnp_irq {
pnp_irq_mask_t map; /* bitmap for IRQ lines */
unsigned char flags; /* IRQ flags */
- unsigned char pad; /* pad */
- struct pnp_irq *next; /* next IRQ */
};
struct pnp_dma {
unsigned char map; /* bitmask for DMA channels */
unsigned char flags; /* DMA flags */
- struct pnp_dma *next; /* next port */
};
struct pnp_mem {
@@ -51,44 +51,91 @@ struct pnp_mem {
resource_size_t align; /* align boundary */
resource_size_t size; /* size of range */
unsigned char flags; /* memory flags */
- unsigned char pad; /* pad */
- struct pnp_mem *next; /* next memory resource */
};
+#define PNP_OPTION_DEPENDENT 0x80000000
+#define PNP_OPTION_SET_MASK 0xffff
+#define PNP_OPTION_SET_SHIFT 12
+#define PNP_OPTION_PRIORITY_MASK 0xfff
+#define PNP_OPTION_PRIORITY_SHIFT 0
+
#define PNP_RES_PRIORITY_PREFERRED 0
#define PNP_RES_PRIORITY_ACCEPTABLE 1
#define PNP_RES_PRIORITY_FUNCTIONAL 2
-#define PNP_RES_PRIORITY_INVALID 65535
+#define PNP_RES_PRIORITY_INVALID PNP_OPTION_PRIORITY_MASK
struct pnp_option {
- unsigned short priority; /* priority */
- struct pnp_port *port; /* first port */
- struct pnp_irq *irq; /* first IRQ */
- struct pnp_dma *dma; /* first DMA */
- struct pnp_mem *mem; /* first memory resource */
- struct pnp_option *next; /* used to chain dependent resources */
+ struct list_head list;
+ unsigned int flags; /* independent/dependent, set, priority */
+
+ unsigned long type; /* IORESOURCE_{IO,MEM,IRQ,DMA} */
+ union {
+ struct pnp_port port;
+ struct pnp_irq irq;
+ struct pnp_dma dma;
+ struct pnp_mem mem;
+ } u;
};
-struct pnp_option *pnp_build_option(int priority);
-struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
-struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
- int priority);
-int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags,
pnp_irq_mask_t *map, unsigned char flags);
-int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags,
unsigned char map, unsigned char flags);
-int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags,
resource_size_t min, resource_size_t max,
resource_size_t align, resource_size_t size,
unsigned char flags);
-int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags,
resource_size_t min, resource_size_t max,
resource_size_t align, resource_size_t size,
unsigned char flags);
+
+static inline int pnp_option_is_dependent(struct pnp_option *option)
+{
+ return option->flags & PNP_OPTION_DEPENDENT ? 1 : 0;
+}
+
+static inline unsigned int pnp_option_set(struct pnp_option *option)
+{
+ return (option->flags >> PNP_OPTION_SET_SHIFT) & PNP_OPTION_SET_MASK;
+}
+
+static inline unsigned int pnp_option_priority(struct pnp_option *option)
+{
+ return (option->flags >> PNP_OPTION_PRIORITY_SHIFT) &
+ PNP_OPTION_PRIORITY_MASK;
+}
+
+static inline unsigned int pnp_new_dependent_set(struct pnp_dev *dev,
+ int priority)
+{
+ unsigned int flags;
+
+ if (priority > PNP_RES_PRIORITY_FUNCTIONAL) {
+ dev_warn(&dev->dev, "invalid dependent option priority %d "
+ "clipped to %d", priority,
+ PNP_RES_PRIORITY_INVALID);
+ priority = PNP_RES_PRIORITY_INVALID;
+ }
+
+ flags = PNP_OPTION_DEPENDENT |
+ ((dev->num_dependent_sets & PNP_OPTION_SET_MASK) <<
+ PNP_OPTION_SET_SHIFT) |
+ ((priority & PNP_OPTION_PRIORITY_MASK) <<
+ PNP_OPTION_PRIORITY_SHIFT);
+
+ dev->num_dependent_sets++;
+
+ return flags;
+}
+
+char *pnp_option_priority_name(struct pnp_option *option);
+void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option);
+
void pnp_init_resources(struct pnp_dev *dev);
void pnp_fixup_device(struct pnp_dev *dev);
-void pnp_free_option(struct pnp_option *option);
+void pnp_free_options(struct pnp_dev *dev);
int __pnp_add_device(struct pnp_dev *dev);
void __pnp_remove_device(struct pnp_dev *dev);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 7182da9..a411582 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -118,10 +118,9 @@ static void pnp_release_device(struct device *dmdev)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
- pnp_free_option(dev->independent);
- pnp_free_option(dev->dependent);
pnp_free_ids(dev);
pnp_free_resources(dev);
+ pnp_free_options(dev);
kfree(dev);
}
@@ -135,6 +134,7 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
return NULL;
INIT_LIST_HEAD(&dev->resources);
+ INIT_LIST_HEAD(&dev->options);
dev->protocol = protocol;
dev->number = id;
dev->dma_mask = DMA_24BIT_MASK;
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 7a9fb55..a876ecf 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -3,6 +3,8 @@
*
* Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz>
* Copyright 2002 Adam Belay <ambx1@neo.rr.com>
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
*/
#include <linux/pnp.h>
@@ -184,39 +186,22 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
}
static void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
- struct pnp_option *option, int dep)
+ struct pnp_option *option)
{
- char *s;
- struct pnp_port *port;
- struct pnp_irq *irq;
- struct pnp_dma *dma;
- struct pnp_mem *mem;
-
- if (dep) {
- switch (option->priority) {
- case PNP_RES_PRIORITY_PREFERRED:
- s = "preferred";
- break;
- case PNP_RES_PRIORITY_ACCEPTABLE:
- s = "acceptable";
- break;
- case PNP_RES_PRIORITY_FUNCTIONAL:
- s = "functional";
- break;
- default:
- s = "invalid";
- }
- pnp_printf(buffer, "Dependent: %02i - Priority %s\n", dep, s);
+ switch (option->type) {
+ case IORESOURCE_IO:
+ pnp_print_port(buffer, space, &option->u.port);
+ break;
+ case IORESOURCE_MEM:
+ pnp_print_mem(buffer, space, &option->u.mem);
+ break;
+ case IORESOURCE_IRQ:
+ pnp_print_irq(buffer, space, &option->u.irq);
+ break;
+ case IORESOURCE_DMA:
+ pnp_print_dma(buffer, space, &option->u.dma);
+ break;
}
-
- for (port = option->port; port; port = port->next)
- pnp_print_port(buffer, space, port);
- for (irq = option->irq; irq; irq = irq->next)
- pnp_print_irq(buffer, space, irq);
- for (dma = option->dma; dma; dma = dma->next)
- pnp_print_dma(buffer, space, dma);
- for (mem = option->mem; mem; mem = mem->next)
- pnp_print_mem(buffer, space, mem);
}
static ssize_t pnp_show_options(struct device *dmdev,
@@ -224,9 +209,9 @@ static ssize_t pnp_show_options(struct device *dmdev,
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
pnp_info_buffer_t *buffer;
- struct pnp_option *independent = dev->independent;
- struct pnp_option *dependent = dev->dependent;
- int ret, dep = 1;
+ struct pnp_option *option;
+ int ret, dep = 0, set = 0;
+ char *indent;
buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
if (!buffer)
@@ -235,14 +220,24 @@ static ssize_t pnp_show_options(struct device *dmdev,
buffer->len = PAGE_SIZE;
buffer->buffer = buf;
buffer->curr = buffer->buffer;
- if (independent)
- pnp_print_option(buffer, "", independent, 0);
- while (dependent) {
- pnp_print_option(buffer, " ", dependent, dep);
- dependent = dependent->next;
- dep++;
+ list_for_each_entry(option, &dev->options, list) {
+ if (pnp_option_is_dependent(option)) {
+ indent = " ";
+ if (!dep || pnp_option_set(option) != set) {
+ set = pnp_option_set(option);
+ dep = 1;
+ pnp_printf(buffer, "Dependent: %02i - "
+ "Priority %s\n", set,
+ pnp_option_priority_name(option));
+ }
+ } else {
+ dep = 0;
+ indent = "";
+ }
+ pnp_print_option(buffer, indent, option);
}
+
ret = (buffer->curr - buf);
kfree(buffer);
return ret;
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 53cc4d6..101a835 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -429,7 +429,7 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
* Add IRQ resource to resources list.
*/
static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[3];
@@ -446,27 +446,27 @@ static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
if (size > 2)
flags = tmp[2];
- pnp_register_irq_resource(dev, option, &map, flags);
+ pnp_register_irq_resource(dev, option_flags, &map, flags);
}
/*
* Add DMA resource to resources list.
*/
static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[2];
isapnp_peek(tmp, size);
- pnp_register_dma_resource(dev, option, tmp[0], tmp[1]);
+ pnp_register_dma_resource(dev, option_flags, tmp[0], tmp[1]);
}
/*
* Add port resource to resources list.
*/
static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[7];
@@ -479,14 +479,15 @@ static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
align = tmp[5];
len = tmp[6];
flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
- pnp_register_port_resource(dev, option, min, max, align, len, flags);
+ pnp_register_port_resource(dev, option_flags,
+ min, max, align, len, flags);
}
/*
* Add fixed port resource to resources list.
*/
static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[3];
@@ -495,7 +496,7 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
isapnp_peek(tmp, size);
base = (tmp[1] << 8) | tmp[0];
len = tmp[2];
- pnp_register_port_resource(dev, option, base, base, 0, len,
+ pnp_register_port_resource(dev, option_flags, base, base, 0, len,
IORESOURCE_IO_FIXED);
}
@@ -503,7 +504,7 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
* Add memory resource to resources list.
*/
static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[9];
@@ -516,14 +517,15 @@ static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
align = (tmp[6] << 8) | tmp[5];
len = ((tmp[8] << 8) | tmp[7]) << 8;
flags = tmp[0];
- pnp_register_mem_resource(dev, option, min, max, align, len, flags);
+ pnp_register_mem_resource(dev, option_flags,
+ min, max, align, len, flags);
}
/*
* Add 32-bit memory resource to resources list.
*/
static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[17];
@@ -536,14 +538,15 @@ static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
flags = tmp[0];
- pnp_register_mem_resource(dev, option, min, max, align, len, flags);
+ pnp_register_mem_resource(dev, option_flags,
+ min, max, align, len, flags);
}
/*
* Add 32-bit fixed memory resource to resources list.
*/
static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
int size)
{
unsigned char tmp[9];
@@ -554,7 +557,7 @@ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
flags = tmp[0];
- pnp_register_mem_resource(dev, option, base, base, 0, len, flags);
+ pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
}
/*
@@ -584,18 +587,14 @@ static int __init isapnp_create_device(struct pnp_card *card,
{
int number = 0, skip = 0, priority, compat = 0;
unsigned char type, tmp[17];
- struct pnp_option *option, *option_independent;
+ unsigned int option_flags;
struct pnp_dev *dev;
u32 eisa_id;
char id[8];
if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
return 1;
- option_independent = option = pnp_register_independent_option(dev);
- if (!option) {
- kfree(dev);
- return 1;
- }
+ option_flags = 0;
pnp_add_card_device(card, dev);
while (1) {
@@ -612,12 +611,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
return 1;
size = 0;
skip = 0;
- option = pnp_register_independent_option(dev);
- option_independent = option;
- if (!option) {
- kfree(dev);
- return 1;
- }
+ option_flags = 0;
pnp_add_card_device(card, dev);
} else {
skip = 1;
@@ -638,13 +632,13 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _STAG_IRQ:
if (size < 2 || size > 3)
goto __skip;
- isapnp_parse_irq_resource(dev, option, size);
+ isapnp_parse_irq_resource(dev, option_flags, size);
size = 0;
break;
case _STAG_DMA:
if (size != 2)
goto __skip;
- isapnp_parse_dma_resource(dev, option, size);
+ isapnp_parse_dma_resource(dev, option_flags, size);
size = 0;
break;
case _STAG_STARTDEP:
@@ -656,29 +650,24 @@ static int __init isapnp_create_device(struct pnp_card *card,
priority = tmp[0];
size = 0;
}
- option = pnp_register_dependent_option(dev, priority);
- if (!option)
- return 1;
+ option_flags = pnp_new_dependent_set(dev, priority);
break;
case _STAG_ENDDEP:
if (size != 0)
goto __skip;
- if (option_independent == option)
- dev_warn(&dev->dev, "missing "
- "_STAG_STARTDEP tag\n");
- option = option_independent;
- dev_dbg(&dev->dev, "end dependent options\n");
+ option_flags = 0;
break;
case _STAG_IOPORT:
if (size != 7)
goto __skip;
- isapnp_parse_port_resource(dev, option, size);
+ isapnp_parse_port_resource(dev, option_flags, size);
size = 0;
break;
case _STAG_FIXEDIO:
if (size != 3)
goto __skip;
- isapnp_parse_fixed_port_resource(dev, option, size);
+ isapnp_parse_fixed_port_resource(dev, option_flags,
+ size);
size = 0;
break;
case _STAG_VENDOR:
@@ -686,7 +675,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _LTAG_MEMRANGE:
if (size != 9)
goto __skip;
- isapnp_parse_mem_resource(dev, option, size);
+ isapnp_parse_mem_resource(dev, option_flags, size);
size = 0;
break;
case _LTAG_ANSISTR:
@@ -701,13 +690,14 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _LTAG_MEM32RANGE:
if (size != 17)
goto __skip;
- isapnp_parse_mem32_resource(dev, option, size);
+ isapnp_parse_mem32_resource(dev, option_flags, size);
size = 0;
break;
case _LTAG_FIXEDMEM32RANGE:
if (size != 9)
goto __skip;
- isapnp_parse_fixed_mem32_resource(dev, option, size);
+ isapnp_parse_fixed_mem32_resource(dev, option_flags,
+ size);
size = 0;
break;
case _STAG_END:
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index a20accb..b526eaa 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -3,6 +3,8 @@
*
* based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
* Copyright 2003 Adam Belay <ambx1@neo.rr.com>
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
*/
#include <linux/errno.h>
@@ -228,102 +230,51 @@ static void pnp_clean_resource_table(struct pnp_dev *dev)
/**
* pnp_assign_resources - assigns resources to the device based on the specified dependent number
* @dev: pointer to the desired device
- * @depnum: the dependent function number
- *
- * Only set depnum to 0 if the device does not have dependent options.
+ * @set: the dependent function number
*/
-static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
+static int pnp_assign_resources(struct pnp_dev *dev, int set)
{
- struct pnp_port *port;
- struct pnp_mem *mem;
- struct pnp_irq *irq;
- struct pnp_dma *dma;
+ struct pnp_option *option;
int nport = 0, nmem = 0, nirq = 0, ndma = 0;
+ int ret = 0;
- dbg_pnp_show_resources(dev, "before pnp_assign_resources");
+ dev_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set);
mutex_lock(&pnp_res_mutex);
pnp_clean_resource_table(dev);
- if (dev->independent) {
- dev_dbg(&dev->dev, "assigning independent options\n");
- port = dev->independent->port;
- mem = dev->independent->mem;
- irq = dev->independent->irq;
- dma = dev->independent->dma;
- while (port) {
- if (pnp_assign_port(dev, port, nport) < 0)
- goto fail;
- nport++;
- port = port->next;
- }
- while (mem) {
- if (pnp_assign_mem(dev, mem, nmem) < 0)
- goto fail;
- nmem++;
- mem = mem->next;
- }
- while (irq) {
- if (pnp_assign_irq(dev, irq, nirq) < 0)
- goto fail;
- nirq++;
- irq = irq->next;
- }
- while (dma) {
- if (pnp_assign_dma(dev, dma, ndma) < 0)
- goto fail;
- ndma++;
- dma = dma->next;
- }
- }
- if (depnum) {
- struct pnp_option *dep;
- int i;
-
- dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum);
- for (i = 1, dep = dev->dependent; i < depnum;
- i++, dep = dep->next)
- if (!dep)
- goto fail;
- port = dep->port;
- mem = dep->mem;
- irq = dep->irq;
- dma = dep->dma;
- while (port) {
- if (pnp_assign_port(dev, port, nport) < 0)
- goto fail;
- nport++;
- port = port->next;
- }
- while (mem) {
- if (pnp_assign_mem(dev, mem, nmem) < 0)
- goto fail;
- nmem++;
- mem = mem->next;
- }
- while (irq) {
- if (pnp_assign_irq(dev, irq, nirq) < 0)
- goto fail;
- nirq++;
- irq = irq->next;
- }
- while (dma) {
- if (pnp_assign_dma(dev, dma, ndma) < 0)
- goto fail;
- ndma++;
- dma = dma->next;
+ list_for_each_entry(option, &dev->options, list) {
+ if (pnp_option_is_dependent(option) &&
+ pnp_option_set(option) != set)
+ continue;
+
+ switch (option->type) {
+ case IORESOURCE_IO:
+ ret = pnp_assign_port(dev, &option->u.port, nport++);
+ break;
+ case IORESOURCE_MEM:
+ ret = pnp_assign_mem(dev, &option->u.mem, nmem++);
+ break;
+ case IORESOURCE_IRQ:
+ ret = pnp_assign_irq(dev, &option->u.irq, nirq++);
+ break;
+ case IORESOURCE_DMA:
+ ret = pnp_assign_dma(dev, &option->u.dma, ndma++);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
}
- } else if (dev->dependent)
- goto fail;
-
- mutex_unlock(&pnp_res_mutex);
- dbg_pnp_show_resources(dev, "after pnp_assign_resources");
- return 1;
+ if (ret < 0)
+ break;
+ }
-fail:
- pnp_clean_resource_table(dev);
mutex_unlock(&pnp_res_mutex);
- dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)");
- return 0;
+ if (ret < 0) {
+ dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
+ pnp_clean_resource_table(dev);
+ } else
+ dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded");
+ return ret;
}
/**
@@ -332,29 +283,25 @@ fail:
*/
int pnp_auto_config_dev(struct pnp_dev *dev)
{
- struct pnp_option *dep;
- int i = 1;
+ int i, ret;
if (!pnp_can_configure(dev)) {
dev_dbg(&dev->dev, "configuration not supported\n");
return -ENODEV;
}
- if (!dev->dependent) {
- if (pnp_assign_resources(dev, 0))
+ ret = pnp_assign_resources(dev, 0);
+ if (ret == 0)
+ return 0;
+
+ for (i = 1; i < dev->num_dependent_sets; i++) {
+ ret = pnp_assign_resources(dev, i);
+ if (ret == 0)
return 0;
- } else {
- dep = dev->dependent;
- do {
- if (pnp_assign_resources(dev, i))
- return 0;
- dep = dep->next;
- i++;
- } while (dep);
}
dev_err(&dev->dev, "unable to assign resources\n");
- return -EBUSY;
+ return ret;
}
/**
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index e6bd14d..826683f 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -407,7 +407,7 @@ int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
}
static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
struct acpi_resource_dma *p)
{
int i;
@@ -420,11 +420,11 @@ static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
map |= 1 << p->channels[i];
flags = dma_flags(p->type, p->bus_master, p->transfer);
- pnp_register_dma_resource(dev, option, map, flags);
+ pnp_register_dma_resource(dev, option_flags, map, flags);
}
static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
struct acpi_resource_irq *p)
{
int i;
@@ -447,11 +447,11 @@ static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
}
flags = irq_flags(p->triggering, p->polarity, p->sharable);
- pnp_register_irq_resource(dev, option, &map, flags);
+ pnp_register_irq_resource(dev, option_flags, &map, flags);
}
static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
struct acpi_resource_extended_irq *p)
{
int i;
@@ -467,11 +467,11 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
__set_bit(p->interrupts[i], map.bits);
flags = irq_flags(p->triggering, p->polarity, p->sharable);
- pnp_register_irq_resource(dev, option, &map, flags);
+ pnp_register_irq_resource(dev, option_flags, &map, flags);
}
static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
struct acpi_resource_io *io)
{
unsigned char flags = 0;
@@ -481,23 +481,23 @@ static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
if (io->io_decode == ACPI_DECODE_16)
flags = IORESOURCE_IO_16BIT_ADDR;
- pnp_register_port_resource(dev, option, io->minimum, io->maximum,
+ pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum,
io->alignment, io->address_length, flags);
}
static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
struct acpi_resource_fixed_io *io)
{
if (io->address_length == 0)
return;
- pnp_register_port_resource(dev, option, io->address, io->address, 0,
- io->address_length, IORESOURCE_IO_FIXED);
+ pnp_register_port_resource(dev, option_flags, io->address, io->address,
+ 0, io->address_length, IORESOURCE_IO_FIXED);
}
static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
struct acpi_resource_memory24 *p)
{
unsigned char flags = 0;
@@ -507,12 +507,12 @@ static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
if (p->write_protect == ACPI_READ_WRITE_MEMORY)
flags = IORESOURCE_MEM_WRITEABLE;
- pnp_register_mem_resource(dev, option, p->minimum, p->maximum,
+ pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
p->alignment, p->address_length, flags);
}
static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
struct acpi_resource_memory32 *p)
{
unsigned char flags = 0;
@@ -522,12 +522,12 @@ static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
if (p->write_protect == ACPI_READ_WRITE_MEMORY)
flags = IORESOURCE_MEM_WRITEABLE;
- pnp_register_mem_resource(dev, option, p->minimum, p->maximum,
+ pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
p->alignment, p->address_length, flags);
}
static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
struct acpi_resource_fixed_memory32 *p)
{
unsigned char flags = 0;
@@ -537,12 +537,12 @@ static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
if (p->write_protect == ACPI_READ_WRITE_MEMORY)
flags = IORESOURCE_MEM_WRITEABLE;
- pnp_register_mem_resource(dev, option, p->address, p->address,
+ pnp_register_mem_resource(dev, option_flags, p->address, p->address,
0, p->address_length, flags);
}
static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
- struct pnp_option *option,
+ unsigned int option_flags,
struct acpi_resource *r)
{
struct acpi_resource_address64 addr, *p = &addr;
@@ -562,18 +562,18 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
if (p->resource_type == ACPI_MEMORY_RANGE) {
if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
flags = IORESOURCE_MEM_WRITEABLE;
- pnp_register_mem_resource(dev, option, p->minimum, p->minimum,
- 0, p->address_length, flags);
+ pnp_register_mem_resource(dev, option_flags, p->minimum,
+ p->minimum, 0, p->address_length,
+ flags);
} else if (p->resource_type == ACPI_IO_RANGE)
- pnp_register_port_resource(dev, option, p->minimum, p->minimum,
- 0, p->address_length,
+ pnp_register_port_resource(dev, option_flags, p->minimum,
+ p->minimum, 0, p->address_length,
IORESOURCE_IO_FIXED);
}
struct acpipnp_parse_option_s {
- struct pnp_option *option;
- struct pnp_option *option_independent;
struct pnp_dev *dev;
+ unsigned int option_flags;
};
static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
@@ -582,15 +582,15 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
int priority;
struct acpipnp_parse_option_s *parse_data = data;
struct pnp_dev *dev = parse_data->dev;
- struct pnp_option *option = parse_data->option;
+ unsigned int option_flags = parse_data->option_flags;
switch (res->type) {
case ACPI_RESOURCE_TYPE_IRQ:
- pnpacpi_parse_irq_option(dev, option, &res->data.irq);
+ pnpacpi_parse_irq_option(dev, option_flags, &res->data.irq);
break;
case ACPI_RESOURCE_TYPE_DMA:
- pnpacpi_parse_dma_option(dev, option, &res->data.dma);
+ pnpacpi_parse_dma_option(dev, option_flags, &res->data.dma);
break;
case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -610,31 +610,19 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
priority = PNP_RES_PRIORITY_INVALID;
break;
}
- /* TBD: Consider performance/robustness bits */
- option = pnp_register_dependent_option(dev, priority);
- if (!option)
- return AE_ERROR;
- parse_data->option = option;
+ parse_data->option_flags = pnp_new_dependent_set(dev, priority);
break;
case ACPI_RESOURCE_TYPE_END_DEPENDENT:
- /*only one EndDependentFn is allowed */
- if (!parse_data->option_independent) {
- dev_warn(&dev->dev, "more than one EndDependentFn "
- "in _PRS\n");
- return AE_ERROR;
- }
- parse_data->option = parse_data->option_independent;
- parse_data->option_independent = NULL;
- dev_dbg(&dev->dev, "end dependent options\n");
+ parse_data->option_flags = 0;
break;
case ACPI_RESOURCE_TYPE_IO:
- pnpacpi_parse_port_option(dev, option, &res->data.io);
+ pnpacpi_parse_port_option(dev, option_flags, &res->data.io);
break;
case ACPI_RESOURCE_TYPE_FIXED_IO:
- pnpacpi_parse_fixed_port_option(dev, option,
+ pnpacpi_parse_fixed_port_option(dev, option_flags,
&res->data.fixed_io);
break;
@@ -643,29 +631,31 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
break;
case ACPI_RESOURCE_TYPE_MEMORY24:
- pnpacpi_parse_mem24_option(dev, option, &res->data.memory24);
+ pnpacpi_parse_mem24_option(dev, option_flags,
+ &res->data.memory24);
break;
case ACPI_RESOURCE_TYPE_MEMORY32:
- pnpacpi_parse_mem32_option(dev, option, &res->data.memory32);
+ pnpacpi_parse_mem32_option(dev, option_flags,
+ &res->data.memory32);
break;
case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
- pnpacpi_parse_fixed_mem32_option(dev, option,
+ pnpacpi_parse_fixed_mem32_option(dev, option_flags,
&res->data.fixed_memory32);
break;
case ACPI_RESOURCE_TYPE_ADDRESS16:
case ACPI_RESOURCE_TYPE_ADDRESS32:
case ACPI_RESOURCE_TYPE_ADDRESS64:
- pnpacpi_parse_address_option(dev, option, res);
+ pnpacpi_parse_address_option(dev, option_flags, res);
break;
case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
break;
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
- pnpacpi_parse_ext_irq_option(dev, option,
+ pnpacpi_parse_ext_irq_option(dev, option_flags,
&res->data.extended_irq);
break;
@@ -689,12 +679,9 @@ int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
dev_dbg(&dev->dev, "parse resource options\n");
- parse_data.option = pnp_register_independent_option(dev);
- if (!parse_data.option)
- return -ENOMEM;
-
- parse_data.option_independent = parse_data.option;
parse_data.dev = dev;
+ parse_data.option_flags = 0;
+
status = acpi_walk_resources(handle, METHOD_NAME__PRS,
pnpacpi_option_resource, &parse_data);
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index db23ba7..ca56767 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -216,7 +216,7 @@ len_err:
static __init void pnpbios_parse_mem_option(struct pnp_dev *dev,
unsigned char *p, int size,
- struct pnp_option *option)
+ unsigned int option_flags)
{
resource_size_t min, max, align, len;
unsigned char flags;
@@ -226,12 +226,13 @@ static __init void pnpbios_parse_mem_option(struct pnp_dev *dev,
align = (p[9] << 8) | p[8];
len = ((p[11] << 8) | p[10]) << 8;
flags = p[3];
- pnp_register_mem_resource(dev, option, min, max, align, len, flags);
+ pnp_register_mem_resource(dev, option_flags, min, max, align, len,
+ flags);
}
static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
unsigned char *p, int size,
- struct pnp_option *option)
+ unsigned int option_flags)
{
resource_size_t min, max, align, len;
unsigned char flags;
@@ -241,12 +242,13 @@ static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
len = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
flags = p[3];
- pnp_register_mem_resource(dev, option, min, max, align, len, flags);
+ pnp_register_mem_resource(dev, option_flags, min, max, align, len,
+ flags);
}
static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
unsigned char *p, int size,
- struct pnp_option *option)
+ unsigned int option_flags)
{
resource_size_t base, len;
unsigned char flags;
@@ -254,12 +256,12 @@ static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
base = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
len = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
flags = p[3];
- pnp_register_mem_resource(dev, option, base, base, 0, len, flags);
+ pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
}
static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
unsigned char *p, int size,
- struct pnp_option *option)
+ unsigned int option_flags)
{
unsigned long bits;
pnp_irq_mask_t map;
@@ -273,19 +275,19 @@ static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
if (size > 2)
flags = p[3];
- pnp_register_irq_resource(dev, option, &map, flags);
+ pnp_register_irq_resource(dev, option_flags, &map, flags);
}
static __init void pnpbios_parse_dma_option(struct pnp_dev *dev,
unsigned char *p, int size,
- struct pnp_option *option)
+ unsigned int option_flags)
{
- pnp_register_dma_resource(dev, option, p[1], p[2]);
+ pnp_register_dma_resource(dev, option_flags, p[1], p[2]);
}
static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
unsigned char *p, int size,
- struct pnp_option *option)
+ unsigned int option_flags)
{
resource_size_t min, max, align, len;
unsigned char flags;
@@ -295,38 +297,35 @@ static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
align = p[6];
len = p[7];
flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0;
- pnp_register_port_resource(dev, option, min, max, align, len, flags);
+ pnp_register_port_resource(dev, option_flags, min, max, align, len,
+ flags);
}
static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
unsigned char *p, int size,
- struct pnp_option *option)
+ unsigned int option_flags)
{
resource_size_t base, len;
base = (p[2] << 8) | p[1];
len = p[3];
- pnp_register_port_resource(dev, option, base, base, 0, len,
+ pnp_register_port_resource(dev, option_flags, base, base, 0, len,
IORESOURCE_IO_FIXED);
}
static __init unsigned char *
pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
- struct pnp_dev *dev)
+ struct pnp_dev *dev)
{
unsigned int len, tag;
int priority;
- struct pnp_option *option, *option_independent;
+ unsigned int option_flags;
if (!p)
return NULL;
dev_dbg(&dev->dev, "parse resource options\n");
-
- option_independent = option = pnp_register_independent_option(dev);
- if (!option)
- return NULL;
-
+ option_flags = 0;
while ((char *)p < (char *)end) {
/* determine the type of tag */
@@ -343,37 +342,38 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
case LARGE_TAG_MEM:
if (len != 9)
goto len_err;
- pnpbios_parse_mem_option(dev, p, len, option);
+ pnpbios_parse_mem_option(dev, p, len, option_flags);
break;
case LARGE_TAG_MEM32:
if (len != 17)
goto len_err;
- pnpbios_parse_mem32_option(dev, p, len, option);
+ pnpbios_parse_mem32_option(dev, p, len, option_flags);
break;
case LARGE_TAG_FIXEDMEM32:
if (len != 9)
goto len_err;
- pnpbios_parse_fixed_mem32_option(dev, p, len, option);
+ pnpbios_parse_fixed_mem32_option(dev, p, len,
+ option_flags);
break;
case SMALL_TAG_IRQ:
if (len < 2 || len > 3)
goto len_err;
- pnpbios_parse_irq_option(dev, p, len, option);
+ pnpbios_parse_irq_option(dev, p, len, option_flags);
break;
case SMALL_TAG_DMA:
if (len != 2)
goto len_err;
- pnpbios_parse_dma_option(dev, p, len, option);
+ pnpbios_parse_dma_option(dev, p, len, option_flags);
break;
case SMALL_TAG_PORT:
if (len != 7)
goto len_err;
- pnpbios_parse_port_option(dev, p, len, option);
+ pnpbios_parse_port_option(dev, p, len, option_flags);
break;
case SMALL_TAG_VENDOR:
@@ -383,7 +383,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
case SMALL_TAG_FIXEDPORT:
if (len != 3)
goto len_err;
- pnpbios_parse_fixed_port_option(dev, p, len, option);
+ pnpbios_parse_fixed_port_option(dev, p, len,
+ option_flags);
break;
case SMALL_TAG_STARTDEP:
@@ -392,19 +393,13 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
priority = PNP_RES_PRIORITY_ACCEPTABLE;
if (len > 0)
priority = p[1];
- option = pnp_register_dependent_option(dev, priority);
- if (!option)
- return NULL;
+ option_flags = pnp_new_dependent_set(dev, priority);
break;
case SMALL_TAG_ENDDEP:
if (len != 0)
goto len_err;
- if (option_independent == option)
- dev_warn(&dev->dev, "missing "
- "SMALL_TAG_STARTDEP tag\n");
- option = option_independent;
- dev_dbg(&dev->dev, "end dependent options\n");
+ option_flags = 0;
break;
case SMALL_TAG_END:
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 3a93fcf..55f55ed 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -5,6 +5,8 @@
* when building up the resource structure for the first time.
*
* Copyright (c) 2000 Peter Denison <peterd@pnd-pc.demon.co.uk>
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
*
* Heavily based on PCI quirks handling which is
*
@@ -20,186 +22,207 @@
#include <linux/kallsyms.h>
#include "base.h"
+static void quirk_awe32_add_ports(struct pnp_dev *dev,
+ struct pnp_option *option,
+ unsigned int offset)
+{
+ struct pnp_option *new_option;
+
+ new_option = kmalloc(sizeof(struct pnp_option), GFP_KERNEL);
+ if (!new_option) {
+ dev_err(&dev->dev, "couldn't add ioport region to option set "
+ "%d\n", pnp_option_set(option));
+ return;
+ }
+
+ *new_option = *option;
+ new_option->u.port.min += offset;
+ new_option->u.port.max += offset;
+ list_add(&new_option->list, &option->list);
+
+ dev_info(&dev->dev, "added ioport region %#llx-%#llx to set %d\n",
+ (unsigned long long) new_option->u.port.min,
+ (unsigned long long) new_option->u.port.max,
+ pnp_option_set(option));
+}
+
static void quirk_awe32_resources(struct pnp_dev *dev)
{
- struct pnp_port *port, *port2, *port3;
- struct pnp_option *res = dev->dependent;
+ struct pnp_option *option;
+ unsigned int set = ~0;
/*
- * Unfortunately the isapnp_add_port_resource is too tightly bound
- * into the PnP discovery sequence, and cannot be used. Link in the
- * two extra ports (at offset 0x400 and 0x800 from the one given) by
- * hand.
+ * Add two extra ioport regions (at offset 0x400 and 0x800 from the
+ * one given) to every dependent option set.
*/
- for (; res; res = res->next) {
- port2 = pnp_alloc(sizeof(struct pnp_port));
- if (!port2)
- return;
- port3 = pnp_alloc(sizeof(struct pnp_port));
- if (!port3) {
- kfree(port2);
- return;
+ list_for_each_entry(option, &dev->options, list) {
+ if (pnp_option_is_dependent(option) &&
+ pnp_option_set(option) != set) {
+ set = pnp_option_set(option);
+ quirk_awe32_add_ports(dev, option, 0x800);
+ quirk_awe32_add_ports(dev, option, 0x400);
}
- port = res->port;
- memcpy(port2, port, sizeof(struct pnp_port));
- memcpy(port3, port, sizeof(struct pnp_port));
- port->next = port2;
- port2->next = port3;
- port2->min += 0x400;
- port2->max += 0x400;
- port3->min += 0x800;
- port3->max += 0x800;
- dev_info(&dev->dev,
- "AWE32 quirk - added ioports 0x%lx and 0x%lx\n",
- (unsigned long)port2->min,
- (unsigned long)port3->min);
}
}
static void quirk_cmi8330_resources(struct pnp_dev *dev)
{
- struct pnp_option *res = dev->dependent;
- unsigned long tmp;
-
- for (; res; res = res->next) {
-
- struct pnp_irq *irq;
- struct pnp_dma *dma;
+ struct pnp_option *option;
+ struct pnp_irq *irq;
+ struct pnp_dma *dma;
- for (irq = res->irq; irq; irq = irq->next) { // Valid irqs are 5, 7, 10
- tmp = 0x04A0;
- bitmap_copy(irq->map.bits, &tmp, 16); // 0000 0100 1010 0000
- }
+ list_for_each_entry(option, &dev->options, list) {
+ if (!pnp_option_is_dependent(option))
+ continue;
- for (dma = res->dma; dma; dma = dma->next) // Valid 8bit dma channels are 1,3
+ if (option->type == IORESOURCE_IRQ) {
+ irq = &option->u.irq;
+ bitmap_zero(irq->map.bits, PNP_IRQ_NR);
+ __set_bit(5, irq->map.bits);
+ __set_bit(7, irq->map.bits);
+ __set_bit(10, irq->map.bits);
+ dev_info(&dev->dev, "set possible IRQs in "
+ "option set %d to 5, 7, 10\n",
+ pnp_option_set(option));
+ } else if (option->type == IORESOURCE_DMA) {
+ dma = &option->u.dma;
if ((dma->flags & IORESOURCE_DMA_TYPE_MASK) ==
- IORESOURCE_DMA_8BIT)
- dma->map = 0x000A;
+ IORESOURCE_DMA_8BIT &&
+ dma->map != 0x0A) {
+ dev_info(&dev->dev, "changing possible "
+ "DMA channel mask in option set %d "
+ "from %#02x to 0x0A (1, 3)\n",
+ pnp_option_set(option), dma->map);
+ dma->map = 0x0A;
+ }
+ }
}
- dev_info(&dev->dev, "CMI8330 quirk - forced possible IRQs to 5, 7, 10 "
- "and DMA channels to 1, 3\n");
}
static void quirk_sb16audio_resources(struct pnp_dev *dev)
{
+ struct pnp_option *option;
+ unsigned int prev_option_flags = ~0, n = 0;
struct pnp_port *port;
- struct pnp_option *res = dev->dependent;
- int changed = 0;
/*
- * The default range on the mpu port for these devices is 0x388-0x388.
+ * The default range on the OPL port for these devices is 0x388-0x388.
* Here we increase that range so that two such cards can be
* auto-configured.
*/
+ list_for_each_entry(option, &dev->options, list) {
+ if (prev_option_flags != option->flags) {
+ prev_option_flags = option->flags;
+ n = 0;
+ }
- for (; res; res = res->next) {
- port = res->port;
- if (!port)
- continue;
- port = port->next;
- if (!port)
- continue;
- port = port->next;
- if (!port)
- continue;
- if (port->min != port->max)
- continue;
- port->max += 0x70;
- changed = 1;
+ if (pnp_option_is_dependent(option) &&
+ option->type == IORESOURCE_IO) {
+ n++;
+ port = &option->u.port;
+ if (n == 3 && port->min == port->max) {
+ port->max += 0x70;
+ dev_info(&dev->dev, "increased option port "
+ "range from %#llx-%#llx to "
+ "%#llx-%#llx\n",
+ (unsigned long long) port->min,
+ (unsigned long long) port->min,
+ (unsigned long long) port->min,
+ (unsigned long long) port->max);
+ }
+ }
}
- if (changed)
- dev_info(&dev->dev, "SB audio device quirk - increased port range\n");
}
-static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev)
+static struct pnp_option *pnp_clone_dependent_set(struct pnp_dev *dev,
+ unsigned int set)
{
- struct pnp_option *head = NULL;
- struct pnp_option *prev = NULL;
- struct pnp_option *res;
+ struct pnp_option *tail = NULL, *first_new_option = NULL;
+ struct pnp_option *option, *new_option;
+ unsigned int flags;
- /*
- * Build a functional IRQ-optional variant of each MPU option.
- */
-
- for (res = dev->dependent; res; res = res->next) {
- struct pnp_option *curr;
- struct pnp_port *port;
- struct pnp_port *copy_port;
- struct pnp_irq *irq;
- struct pnp_irq *copy_irq;
-
- port = res->port;
- irq = res->irq;
- if (!port || !irq)
- continue;
-
- copy_port = pnp_alloc(sizeof *copy_port);
- if (!copy_port)
- break;
-
- copy_irq = pnp_alloc(sizeof *copy_irq);
- if (!copy_irq) {
- kfree(copy_port);
- break;
- }
+ list_for_each_entry(option, &dev->options, list) {
+ if (pnp_option_is_dependent(option))
+ tail = option;
+ }
+ if (!tail) {
+ dev_err(&dev->dev, "no dependent option sets\n");
+ return NULL;
+ }
- *copy_port = *port;
- copy_port->next = NULL;
+ flags = pnp_new_dependent_set(dev, PNP_RES_PRIORITY_FUNCTIONAL);
+ list_for_each_entry(option, &dev->options, list) {
+ if (pnp_option_is_dependent(option) &&
+ pnp_option_set(option) == set) {
+ new_option = kmalloc(sizeof(struct pnp_option),
+ GFP_KERNEL);
+ if (!new_option) {
+ dev_err(&dev->dev, "couldn't clone dependent "
+ "set %d\n", set);
+ return NULL;
+ }
- *copy_irq = *irq;
- copy_irq->flags |= IORESOURCE_IRQ_OPTIONAL;
- copy_irq->next = NULL;
+ *new_option = *option;
+ new_option->flags = flags;
+ if (!first_new_option)
+ first_new_option = new_option;
- curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL);
- if (!curr) {
- kfree(copy_port);
- kfree(copy_irq);
- break;
+ list_add(&new_option->list, &tail->list);
+ tail = new_option;
}
- curr->port = copy_port;
- curr->irq = copy_irq;
-
- if (prev)
- prev->next = curr;
- else
- head = curr;
- prev = curr;
}
- if (head)
- dev_info(&dev->dev, "adding IRQ-optional MPU options\n");
- return head;
+ return first_new_option;
}
-static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
+
+static void quirk_add_irq_optional_dependent_sets(struct pnp_dev *dev)
{
- struct pnp_option *res;
+ struct pnp_option *new_option;
+ unsigned int num_sets, i, set;
struct pnp_irq *irq;
- res = dev->independent;
- if (!res)
- return;
+ num_sets = dev->num_dependent_sets;
+ for (i = 0; i < num_sets; i++) {
+ new_option = pnp_clone_dependent_set(dev, i);
+ if (!new_option)
+ return;
- irq = res->irq;
- if (!irq || irq->next)
- return;
+ set = pnp_option_set(new_option);
+ while (new_option && pnp_option_set(new_option) == set) {
+ if (new_option->type == IORESOURCE_IRQ) {
+ irq = &new_option->u.irq;
+ irq->flags |= IORESOURCE_IRQ_OPTIONAL;
+ }
+ dbg_pnp_show_option(dev, new_option);
+ new_option = list_entry(new_option->list.next,
+ struct pnp_option, list);
+ }
- irq->flags |= IORESOURCE_IRQ_OPTIONAL;
- dev_info(&dev->dev, "made independent IRQ optional\n");
+ dev_info(&dev->dev, "added dependent option set %d (same as "
+ "set %d except IRQ optional)\n", set, i);
+ }
}
-static void quirk_isapnp_mpu_resources(struct pnp_dev *dev)
+static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
{
- struct pnp_option *res;
+ struct pnp_option *option;
+ struct pnp_irq *irq = NULL;
+ unsigned int independent_irqs = 0;
+
+ list_for_each_entry(option, &dev->options, list) {
+ if (option->type == IORESOURCE_IRQ &&
+ !pnp_option_is_dependent(option)) {
+ independent_irqs++;
+ irq = &option->u.irq;
+ }
+ }
- res = dev->dependent;
- if (!res)
+ if (independent_irqs != 1)
return;
- while (res->next)
- res = res->next;
-
- res->next = quirk_isapnp_mpu_options(dev);
+ irq->flags |= IORESOURCE_IRQ_OPTIONAL;
+ dev_info(&dev->dev, "made independent IRQ optional\n");
}
#include <linux/pci.h>
@@ -294,10 +317,10 @@ static struct pnp_fixup pnp_fixups[] = {
{"CTL0043", quirk_sb16audio_resources},
{"CTL0044", quirk_sb16audio_resources},
{"CTL0045", quirk_sb16audio_resources},
- /* Add IRQ-less MPU options */
+ /* Add IRQ-optional MPU options */
{"ADS7151", quirk_ad1815_mpu_resources},
- {"ADS7181", quirk_isapnp_mpu_resources},
- {"AZT0002", quirk_isapnp_mpu_resources},
+ {"ADS7181", quirk_add_irq_optional_dependent_sets},
+ {"AZT0002", quirk_add_irq_optional_dependent_sets},
/* PnP resources that might overlap PCI BARs */
{"PNP0c01", quirk_system_pci_resources},
{"PNP0c02", quirk_system_pci_resources},
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index a795864..d638897 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -3,6 +3,8 @@
*
* based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
* Copyright 2003 Adam Belay <ambx1@neo.rr.com>
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
*/
#include <linux/module.h>
@@ -28,78 +30,36 @@ static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some
* option registration
*/
-struct pnp_option *pnp_build_option(int priority)
+struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type,
+ unsigned int option_flags)
{
- struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option));
+ struct pnp_option *option;
+ option = kzalloc(sizeof(struct pnp_option), GFP_KERNEL);
if (!option)
return NULL;
- option->priority = priority & 0xff;
- /* make sure the priority is valid */
- if (option->priority > PNP_RES_PRIORITY_FUNCTIONAL)
- option->priority = PNP_RES_PRIORITY_INVALID;
-
- return option;
-}
-
-struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev)
-{
- struct pnp_option *option;
-
- option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED);
-
- /* this should never happen but if it does we'll try to continue */
- if (dev->independent)
- dev_err(&dev->dev, "independent resource already registered\n");
- dev->independent = option;
-
- dev_dbg(&dev->dev, "new independent option\n");
- return option;
-}
-
-struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
- int priority)
-{
- struct pnp_option *option;
+ option->flags = option_flags;
+ option->type = type;
- option = pnp_build_option(priority);
-
- if (dev->dependent) {
- struct pnp_option *parent = dev->dependent;
- while (parent->next)
- parent = parent->next;
- parent->next = option;
- } else
- dev->dependent = option;
-
- dev_dbg(&dev->dev, "new dependent option (priority %#x)\n", priority);
+ list_add_tail(&option->list, &dev->options);
return option;
}
-int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags,
pnp_irq_mask_t *map, unsigned char flags)
{
- struct pnp_irq *irq, *ptr;
-#ifdef DEBUG
- char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */
-#endif
+ struct pnp_option *option;
+ struct pnp_irq *irq;
- irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
- if (!irq)
+ option = pnp_build_option(dev, IORESOURCE_IRQ, option_flags);
+ if (!option)
return -ENOMEM;
+ irq = &option->u.irq;
irq->map = *map;
irq->flags = flags;
- ptr = option->irq;
- while (ptr && ptr->next)
- ptr = ptr->next;
- if (ptr)
- ptr->next = irq;
- else
- option->irq = irq;
-
#ifdef CONFIG_PCI
{
int i;
@@ -110,163 +70,81 @@ int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
}
#endif
-#ifdef DEBUG
- bitmap_scnprintf(buf, sizeof(buf), irq->map.bits, PNP_IRQ_NR);
- dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf,
- irq->flags);
-#endif
+ dbg_pnp_show_option(dev, option);
return 0;
}
-int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags,
unsigned char map, unsigned char flags)
{
- struct pnp_dma *dma, *ptr;
+ struct pnp_option *option;
+ struct pnp_dma *dma;
- dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
- if (!dma)
+ option = pnp_build_option(dev, IORESOURCE_DMA, option_flags);
+ if (!option)
return -ENOMEM;
+ dma = &option->u.dma;
dma->map = map;
dma->flags = flags;
- ptr = option->dma;
- while (ptr && ptr->next)
- ptr = ptr->next;
- if (ptr)
- ptr->next = dma;
- else
- option->dma = dma;
-
- dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", dma->map,
- dma->flags);
+ dbg_pnp_show_option(dev, option);
return 0;
}
-int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags,
resource_size_t min, resource_size_t max,
resource_size_t align, resource_size_t size,
unsigned char flags)
{
- struct pnp_port *port, *ptr;
+ struct pnp_option *option;
+ struct pnp_port *port;
- port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
- if (!port)
+ option = pnp_build_option(dev, IORESOURCE_IO, option_flags);
+ if (!option)
return -ENOMEM;
+ port = &option->u.port;
port->min = min;
port->max = max;
port->align = align;
port->size = size;
port->flags = flags;
- ptr = option->port;
- while (ptr && ptr->next)
- ptr = ptr->next;
- if (ptr)
- ptr->next = port;
- else
- option->port = port;
-
- dev_dbg(&dev->dev, " io "
- "min %#llx max %#llx align %lld size %lld flags %#x\n",
- (unsigned long long) port->min,
- (unsigned long long) port->max,
- (unsigned long long) port->align,
- (unsigned long long) port->size, port->flags);
+ dbg_pnp_show_option(dev, option);
return 0;
}
-int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
+int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags,
resource_size_t min, resource_size_t max,
resource_size_t align, resource_size_t size,
unsigned char flags)
{
- struct pnp_mem *mem, *ptr;
+ struct pnp_option *option;
+ struct pnp_mem *mem;
- mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
- if (!mem)
+ option = pnp_build_option(dev, IORESOURCE_MEM, option_flags);
+ if (!option)
return -ENOMEM;
+ mem = &option->u.mem;
mem->min = min;
mem->max = max;
mem->align = align;
mem->size = size;
mem->flags = flags;
- ptr = option->mem;
- while (ptr && ptr->next)
- ptr = ptr->next;
- if (ptr)
- ptr->next = mem;
- else
- option->mem = mem;
-
- dev_dbg(&dev->dev, " mem "
- "min %#llx max %#llx align %lld size %lld flags %#x\n",
- (unsigned long long) mem->min,
- (unsigned long long) mem->max,
- (unsigned long long) mem->align,
- (unsigned long long) mem->size, mem->flags);
+ dbg_pnp_show_option(dev, option);
return 0;
}
-static void pnp_free_port(struct pnp_port *port)
-{
- struct pnp_port *next;
-
- while (port) {
- next = port->next;
- kfree(port);
- port = next;
- }
-}
-
-static void pnp_free_irq(struct pnp_irq *irq)
-{
- struct pnp_irq *next;
-
- while (irq) {
- next = irq->next;
- kfree(irq);
- irq = next;
- }
-}
-
-static void pnp_free_dma(struct pnp_dma *dma)
-{
- struct pnp_dma *next;
-
- while (dma) {
- next = dma->next;
- kfree(dma);
- dma = next;
- }
-}
-
-static void pnp_free_mem(struct pnp_mem *mem)
+void pnp_free_options(struct pnp_dev *dev)
{
- struct pnp_mem *next;
-
- while (mem) {
- next = mem->next;
- kfree(mem);
- mem = next;
- }
-}
+ struct pnp_option *option, *tmp;
-void pnp_free_option(struct pnp_option *option)
-{
- struct pnp_option *next;
-
- while (option) {
- next = option->next;
- pnp_free_port(option->port);
- pnp_free_irq(option->irq);
- pnp_free_dma(option->dma);
- pnp_free_mem(option->mem);
+ list_for_each_entry_safe(option, tmp, &dev->options, list) {
+ list_del(&option->list);
kfree(option);
- option = next;
}
}
@@ -668,66 +546,50 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
return pnp_res;
}
-static int pnp_possible_option(struct pnp_option *option, int type,
- resource_size_t start, resource_size_t size)
+/*
+ * Determine whether the specified resource is a possible configuration
+ * for this device.
+ */
+int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
+ resource_size_t size)
{
- struct pnp_option *tmp;
+ struct pnp_option *option;
struct pnp_port *port;
struct pnp_mem *mem;
struct pnp_irq *irq;
struct pnp_dma *dma;
- if (!option)
- return 0;
+ list_for_each_entry(option, &dev->options, list) {
+ if (option->type != type)
+ continue;
- for (tmp = option; tmp; tmp = tmp->next) {
- switch (type) {
+ switch (option->type) {
case IORESOURCE_IO:
- for (port = tmp->port; port; port = port->next) {
- if (port->min == start && port->size == size)
- return 1;
- }
+ port = &option->u.port;
+ if (port->min == start && port->size == size)
+ return 1;
break;
case IORESOURCE_MEM:
- for (mem = tmp->mem; mem; mem = mem->next) {
- if (mem->min == start && mem->size == size)
- return 1;
- }
+ mem = &option->u.mem;
+ if (mem->min == start && mem->size == size)
+ return 1;
break;
case IORESOURCE_IRQ:
- for (irq = tmp->irq; irq; irq = irq->next) {
- if (start < PNP_IRQ_NR &&
- test_bit(start, irq->map.bits))
- return 1;
- }
+ irq = &option->u.irq;
+ if (start < PNP_IRQ_NR &&
+ test_bit(start, irq->map.bits))
+ return 1;
break;
case IORESOURCE_DMA:
- for (dma = tmp->dma; dma; dma = dma->next) {
- if (dma->map & (1 << start))
- return 1;
- }
+ dma = &option->u.dma;
+ if (dma->map & (1 << start))
+ return 1;
break;
}
}
return 0;
}
-
-/*
- * Determine whether the specified resource is a possible configuration
- * for this device.
- */
-int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
- resource_size_t size)
-{
- if (pnp_possible_option(dev->independent, type, start, size))
- return 1;
-
- if (pnp_possible_option(dev->dependent, type, start, size))
- return 1;
-
- return 0;
-}
EXPORT_SYMBOL(pnp_possible_config);
/* format is: pnp_reserve_irq=irq1[,irq2] .... */
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index 4beeabd..e406710 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -2,6 +2,8 @@
* support.c - standard functions for the use of pnp protocol drivers
*
* Copyright 2003 Adam Belay <ambx1@neo.rr.com>
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
*/
#include <linux/module.h>
@@ -110,3 +112,80 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
}
#endif
}
+
+char *pnp_option_priority_name(struct pnp_option *option)
+{
+ switch (pnp_option_priority(option)) {
+ case PNP_RES_PRIORITY_PREFERRED:
+ return "preferred";
+ case PNP_RES_PRIORITY_ACCEPTABLE:
+ return "acceptable";
+ case PNP_RES_PRIORITY_FUNCTIONAL:
+ return "functional";
+ }
+ return "invalid";
+}
+
+void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option)
+{
+#ifdef DEBUG
+ struct pnp_port *port;
+ struct pnp_mem *mem;
+ struct pnp_irq *irq;
+ struct pnp_dma *dma;
+ int i;
+
+ if (pnp_option_is_dependent(option))
+ dev_dbg(&dev->dev, " dependent set %d (%s) ",
+ pnp_option_set(option),
+ pnp_option_priority_name(option));
+ else
+ dev_dbg(&dev->dev, " independent ");
+
+ switch (option->type) {
+ case IORESOURCE_IO:
+ port = &option->u.port;
+ printk("io min %#llx max %#llx align %lld size %lld flags %#x",
+ (unsigned long long) port->min,
+ (unsigned long long) port->max,
+ (unsigned long long) port->align,
+ (unsigned long long) port->size, port->flags);
+ break;
+ case IORESOURCE_MEM:
+ mem = &option->u.mem;
+ printk("mem min %#llx max %#llx align %lld size %lld flags %#x",
+ (unsigned long long) mem->min,
+ (unsigned long long) mem->max,
+ (unsigned long long) mem->align,
+ (unsigned long long) mem->size, mem->flags);
+ break;
+ case IORESOURCE_IRQ:
+ irq = &option->u.irq;
+ printk("irq");
+ if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
+ printk(" <none>");
+ else {
+ for (i = 0; i < PNP_IRQ_NR; i++)
+ if (test_bit(i, irq->map.bits))
+ printk(" %d", i);
+ }
+ printk(" flags %#x", irq->flags);
+ if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
+ printk(" (optional)");
+ break;
+ case IORESOURCE_DMA:
+ dma = &option->u.dma;
+ printk("dma");
+ if (!dma->map)
+ printk(" <none>");
+ else {
+ for (i = 0; i < 8; i++)
+ if (dma->map & (1 << i))
+ printk(" %d", i);
+ }
+ printk(" (bitmask %#x) flags %#x", dma->map, dma->flags);
+ break;
+ }
+ printk("\n");
+#endif
+}
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 00fe020..116abdc 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -1,6 +1,8 @@
/*
* Linux Plug and Play Support
* Copyright by Adam Belay <ambx1@neo.rr.com>
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
*/
#ifndef _LINUX_PNP_H
@@ -249,9 +251,9 @@ struct pnp_dev {
int active;
int capabilities;
- struct pnp_option *independent;
- struct pnp_option *dependent;
+ unsigned int num_dependent_sets;
struct list_head resources;
+ struct list_head options;
char name[PNP_NAME_LEN]; /* contains a human-readable name */
int flags; /* used by protocols */
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 65/70] PNP: avoid legacy IDE IRQs
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (61 preceding siblings ...)
2008-06-20 7:44 ` [PATCH 64/70] PNP: convert resource options to single linked list Len Brown
@ 2008-06-20 7:44 ` Len Brown
2008-06-20 7:44 ` [PATCH 66/70] PNPACPI: add support for HP vendor-specific CCSR descriptors Len Brown
` (4 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
If an IDE controller is in compatibility mode, it expects to use
IRQs 14 and 15, so PNP should avoid them.
This patch should resolve this problem report:
parallel driver grabs IRQ14 preventing legacy SFF ATA controller from working
https://bugzilla.novell.com/show_bug.cgi?id=375836
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/resource.c | 69 ++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index d638897..e0e853d 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -17,6 +17,7 @@
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/libata.h>
#include <linux/pnp.h>
#include "base.h"
@@ -286,6 +287,61 @@ static irqreturn_t pnp_test_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
+#ifdef CONFIG_PCI
+static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,
+ unsigned int irq)
+{
+ u32 class;
+ u8 progif;
+
+ if (pci->irq == irq) {
+ dev_dbg(&pnp->dev, "device %s using irq %d\n",
+ pci_name(pci), irq);
+ return 1;
+ }
+
+ /*
+ * See pci_setup_device() and ata_pci_sff_activate_host() for
+ * similar IDE legacy detection.
+ */
+ pci_read_config_dword(pci, PCI_CLASS_REVISION, &class);
+ class >>= 8; /* discard revision ID */
+ progif = class & 0xff;
+ class >>= 8;
+
+ if (class == PCI_CLASS_STORAGE_IDE) {
+ /*
+ * Unless both channels are native-PCI mode only,
+ * treat the compatibility IRQs as busy.
+ */
+ if ((progif & 0x5) != 0x5)
+ if (ATA_PRIMARY_IRQ(pci) == irq ||
+ ATA_SECONDARY_IRQ(pci) == irq) {
+ dev_dbg(&pnp->dev, "legacy IDE device %s "
+ "using irq %d\n", pci_name(pci), irq);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+static int pci_uses_irq(struct pnp_dev *pnp, unsigned int irq)
+{
+#ifdef CONFIG_PCI
+ struct pci_dev *pci = NULL;
+
+ for_each_pci_dev(pci) {
+ if (pci_dev_uses_irq(pnp, pci, irq)) {
+ pci_dev_put(pci);
+ return 1;
+ }
+ }
+#endif
+ return 0;
+}
+
int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
{
int i;
@@ -317,18 +373,9 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
}
}
-#ifdef CONFIG_PCI
/* check if the resource is being used by a pci device */
- {
- struct pci_dev *pci = NULL;
- for_each_pci_dev(pci) {
- if (pci->irq == *irq) {
- pci_dev_put(pci);
- return 0;
- }
- }
- }
-#endif
+ if (pci_uses_irq(dev, *irq))
+ return 0;
/* check if the resource is already in use, skip if the
* device is active because it itself may be in use */
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 66/70] PNPACPI: add support for HP vendor-specific CCSR descriptors
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (62 preceding siblings ...)
2008-06-20 7:44 ` [PATCH 65/70] PNP: avoid legacy IDE IRQs Len Brown
@ 2008-06-20 7:44 ` Len Brown
2008-06-20 7:44 ` [PATCH 67/70] ACPI: Disable the C2C3_FFH access mode HW has no MWAIT support Len Brown
` (3 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Bjorn Helgaas, Len Brown
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
The HP CCSR descriptor describes MMIO address space that should appear
as a MEM resource. This patch adds support for parsing these descriptors
in the _CRS data.
The visible effect of this is that these MEM resources will appear
in /sys/devices/pnp0/.../resources, which means that "lspnp -v" will
report it, user applications can use this to locate device CSR space,
and kernel drivers can use the normal PNP resource accessors to
locate them.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/pnp/pnpacpi/rsparser.c | 60 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 826683f..d2abc87 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -3,6 +3,8 @@
*
* Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
* Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -187,6 +189,61 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
pnp_add_io_resource(dev, start, end, flags);
}
+/*
+ * Device CSRs that do not appear in PCI config space should be described
+ * via ACPI. This would normally be done with Address Space Descriptors
+ * marked as "consumer-only," but old versions of Windows and Linux ignore
+ * the producer/consumer flag, so HP invented a vendor-defined resource to
+ * describe the location and size of CSR space.
+ */
+static struct acpi_vendor_uuid hp_ccsr_uuid = {
+ .subtype = 2,
+ .data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a,
+ 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad },
+};
+
+static int vendor_resource_matches(struct pnp_dev *dev,
+ struct acpi_resource_vendor_typed *vendor,
+ struct acpi_vendor_uuid *match,
+ int expected_len)
+{
+ int uuid_len = sizeof(vendor->uuid);
+ u8 uuid_subtype = vendor->uuid_subtype;
+ u8 *uuid = vendor->uuid;
+ int actual_len;
+
+ /* byte_length includes uuid_subtype and uuid */
+ actual_len = vendor->byte_length - uuid_len - 1;
+
+ if (uuid_subtype == match->subtype &&
+ uuid_len == sizeof(match->data) &&
+ memcmp(uuid, match->data, uuid_len) == 0) {
+ if (expected_len && expected_len != actual_len) {
+ dev_err(&dev->dev, "wrong vendor descriptor size; "
+ "expected %d, found %d bytes\n",
+ expected_len, actual_len);
+ return 0;
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev,
+ struct acpi_resource_vendor_typed *vendor)
+{
+ if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, 16)) {
+ u64 start, length;
+
+ memcpy(&start, vendor->byte_data, sizeof(start));
+ memcpy(&length, vendor->byte_data + 8, sizeof(length));
+
+ pnp_add_mem_resource(dev, start, start + length - 1, 0);
+ }
+}
+
static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
u64 start, u64 len,
int write_protect)
@@ -237,6 +294,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
struct acpi_resource_dma *dma;
struct acpi_resource_io *io;
struct acpi_resource_fixed_io *fixed_io;
+ struct acpi_resource_vendor_typed *vendor_typed;
struct acpi_resource_memory24 *memory24;
struct acpi_resource_memory32 *memory32;
struct acpi_resource_fixed_memory32 *fixed_memory32;
@@ -306,6 +364,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
break;
case ACPI_RESOURCE_TYPE_VENDOR:
+ vendor_typed = &res->data.vendor_typed;
+ pnpacpi_parse_allocated_vendor(dev, vendor_typed);
break;
case ACPI_RESOURCE_TYPE_END_TAG:
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 67/70] ACPI: Disable the C2C3_FFH access mode HW has no MWAIT support
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (63 preceding siblings ...)
2008-06-20 7:44 ` [PATCH 66/70] PNPACPI: add support for HP vendor-specific CCSR descriptors Len Brown
@ 2008-06-20 7:44 ` Len Brown
2008-06-20 7:44 ` [PATCH 68/70] ACPI: Create "idle=halt" boot parameter Len Brown
` (2 subsequent siblings)
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Zhao Yakui, Li Shaohua, Len Brown
From: Zhao Yakui <yakui.zhao@intel.com>
991528d7348667924176f3e29addea0675298944
(ACPI: Processor native C-states using MWAIT)
started passing C2C3_FFH to _PDC to tell the BIOS
that Linux supports MWAIT for deep C-states.
However, we should first double check with the hardware
that it actually supports MWAIT before potentially exposing
a BIOS bug of an MWAIT _CST on HW that doesn't support MWAIT.
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Li Shaohua <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
arch/x86/kernel/acpi/processor.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c
index de2d2e4..7c074ee 100644
--- a/arch/x86/kernel/acpi/processor.c
+++ b/arch/x86/kernel/acpi/processor.c
@@ -56,6 +56,12 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_ACPI))
buf[2] |= ACPI_PDC_T_FFH;
+ /*
+ * If mwait/monitor is unsupported, C2/C3_FFH will be disabled
+ */
+ if (!cpu_has(c, X86_FEATURE_MWAIT))
+ buf[2] &= ~(ACPI_PDC_C_C2C3_FFH);
+
obj->type = ACPI_TYPE_BUFFER;
obj->buffer.length = 12;
obj->buffer.pointer = (u8 *) buf;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 68/70] ACPI: Create "idle=halt" boot parameter
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (64 preceding siblings ...)
2008-06-20 7:44 ` [PATCH 67/70] ACPI: Disable the C2C3_FFH access mode HW has no MWAIT support Len Brown
@ 2008-06-20 7:44 ` Len Brown
2008-06-20 7:44 ` [PATCH 69/70] ACPI : Create "idle=nomwait" bootparam Len Brown
2008-06-20 7:44 ` [PATCH 70/70] ACPI : Add DMI check to disable mwait on broken Compal Len Brown
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Zhao Yakui, Len Brown
From: Zhao Yakui <yakui.zhao@intel.com>
"idle=halt" forces Linux to use only HLT for the idle loop.
This disables all fancy idle features, such as MWAIT
and C-states deeper than C1. However, it is not as extreme
as "idle=poll", which disabled all idle power savings features.
While those fancy features save power, this option
is useful when there are either platform or Linux bugs,
or suspected latency issues related to those features.
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
Documentation/kernel-parameters.txt | 4 +++-
arch/x86/kernel/process.c | 3 +++
2 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index e07c432..1623c2f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -785,7 +785,7 @@ and is between 256 and 4096 characters. It is defined in the file
See Documentation/ide/ide.txt.
idle= [X86]
- Format: idle=poll or idle=mwait
+ Format: idle=poll or idle=mwait, idle = halt
Poll forces a polling idle loop that can slightly improves the performance
of waking up a idle CPU, but will use a lot of power and make the system
run hot. Not recommended.
@@ -793,6 +793,8 @@ and is between 256 and 4096 characters. It is defined in the file
to not use it because it doesn't save as much power as a normal idle
loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same
as idle=poll.
+ idle = halt . Halt is forced to be used for CPU idle.
+ In such case C2/C3 won't be used again.
ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
Claim all unknown PCI IDE storage controllers.
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index ba370dc..6a35c7d 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -6,6 +6,7 @@
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/pm.h>
+#include <asm/system.h>
struct kmem_cache *task_xstate_cachep;
@@ -169,6 +170,8 @@ static int __init idle_setup(char *str)
pm_idle = poll_idle;
} else if (!strcmp(str, "mwait"))
force_mwait = 1;
+ else if (!strcmp(str, "halt"))
+ pm_idle = default_idle;
else
return -1;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 69/70] ACPI : Create "idle=nomwait" bootparam
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (65 preceding siblings ...)
2008-06-20 7:44 ` [PATCH 68/70] ACPI: Create "idle=halt" boot parameter Len Brown
@ 2008-06-20 7:44 ` Len Brown
2008-06-20 15:02 ` Randy Dunlap
2008-06-20 7:44 ` [PATCH 70/70] ACPI : Add DMI check to disable mwait on broken Compal Len Brown
67 siblings, 1 reply; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Zhao Yakui, Li Shaohua, Len Brown
From: Zhao Yakui <yakui.zhao@intel.com>
Add the boot option of "idle=nomwait" to disable Mwait for CPU C-states.
If the boot option of "idle=nomwait" is added , Linux should not
use mwait for cpu idle even when the mwait is supported. In such case the
C2C3_FFH access mode will be disabled.
http://bugzilla.kernel.org/show_bug.cgi?id=10807
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Li Shaohua <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
Documentation/kernel-parameters.txt | 4 +++-
arch/ia64/kernel/process.c | 2 ++
arch/x86/kernel/process.c | 14 ++++++++++++++
drivers/acpi/processor_core.c | 12 ++++++++++++
include/asm-ia64/processor.h | 1 +
include/asm-x86/processor.h | 1 +
6 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 1623c2f..39baaba 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -785,7 +785,7 @@ and is between 256 and 4096 characters. It is defined in the file
See Documentation/ide/ide.txt.
idle= [X86]
- Format: idle=poll or idle=mwait, idle = halt
+ Format: idle=poll or idle=mwait, idle = halt, idle=nomwait
Poll forces a polling idle loop that can slightly improves the performance
of waking up a idle CPU, but will use a lot of power and make the system
run hot. Not recommended.
@@ -795,6 +795,8 @@ and is between 256 and 4096 characters. It is defined in the file
as idle=poll.
idle = halt . Halt is forced to be used for CPU idle.
In such case C2/C3 won't be used again.
+ idle = nomwait. disable Mwait for CPU C-state.
+ In such case C2C3_FFH access mode will be disabled.
ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
Claim all unknown PCI IDE storage controllers.
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index a3a34b4..34249b2 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -55,6 +55,8 @@ void (*ia64_mark_idle)(int);
unsigned long boot_option_idle_override = 0;
EXPORT_SYMBOL(boot_option_idle_override);
+unsigned long idle_nomwait;
+EXPORT_SYMBOL(idle_nomwait);
void
ia64_do_show_stack (struct unw_frame_info *info, void *arg)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 6a35c7d..9ec16e7 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -7,6 +7,10 @@
#include <linux/module.h>
#include <linux/pm.h>
#include <asm/system.h>
+#include <asm/processor.h>
+
+unsigned long idle_nomwait;
+EXPORT_SYMBOL(idle_nomwait);
struct kmem_cache *task_xstate_cachep;
@@ -172,6 +176,16 @@ static int __init idle_setup(char *str)
force_mwait = 1;
else if (!strcmp(str, "halt"))
pm_idle = default_idle;
+ else if (!strcmp(str, "nomwait")) {
+ /*
+ * If the boot option of "idle=nomwait" is added,
+ * it means that mwait will be disabled for CPU C2/C3
+ * states. In such case it won't touch the variable
+ * of boot_option_idle_override.
+ */
+ idle_nomwait = 1;
+ return 0;
+ }
else
return -1;
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 9dd0fa9..9e3c168 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -266,6 +266,18 @@ static int acpi_processor_set_pdc(struct acpi_processor *pr)
if (!pdc_in)
return status;
+ if (idle_nomwait) {
+ /*
+ * If mwait is disabled for CPU C-states, the C2C3_FFH access
+ * mode will be disabled in the parameter of _PDC object.
+ */
+ union acpi_object *obj;
+ u32 *buffer = NULL;
+
+ obj = pdc_in->pointer;
+ buffer = (u32 *)(obj->buffer.pointer);
+ buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH);
+ }
status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL);
if (ACPI_FAILURE(status))
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
index 6aff126..8d893bb 100644
--- a/include/asm-ia64/processor.h
+++ b/include/asm-ia64/processor.h
@@ -763,6 +763,7 @@ prefetchw (const void *x)
#define spin_lock_prefetch(x) prefetchw(x)
extern unsigned long boot_option_idle_override;
+extern unsigned long idle_nomwait;
#endif /* !__ASSEMBLY__ */
diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h
index 5591052..33353cf 100644
--- a/include/asm-x86/processor.h
+++ b/include/asm-x86/processor.h
@@ -732,6 +732,7 @@ extern int force_mwait;
extern void select_idle_routine(const struct cpuinfo_x86 *c);
extern unsigned long boot_option_idle_override;
+extern unsigned long idle_nomwait;
extern void enable_sep_cpu(void);
extern int sysenter_setup(void);
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* [PATCH 70/70] ACPI : Add DMI check to disable mwait on broken Compal
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
` (66 preceding siblings ...)
2008-06-20 7:44 ` [PATCH 69/70] ACPI : Create "idle=nomwait" bootparam Len Brown
@ 2008-06-20 7:44 ` Len Brown
67 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 7:44 UTC (permalink / raw)
To: linux-acpi; +Cc: Zhao Yakui, Li Shaohua, Len Brown
From: Zhao Yakui <yakui.zhao@intel.com>
Add the DMI check to disable mwait for CPU C-states.
If the board is matched with DMI table, OSPM should not use mwait for CPU
C-states even when mwait is supported. In such case the C2C3_FFH access mode
will be disabled.
http://bugzilla.kernel.org/show_bug.cgi?id=10807
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Li Shaohua <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
drivers/acpi/processor_core.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 9e3c168..67455ad 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -120,6 +120,23 @@ static const struct file_operations acpi_processor_info_fops = {
struct acpi_processor *processors[NR_CPUS];
struct acpi_processor_errata errata __read_mostly;
+static int set_no_mwait(const struct dmi_system_id *id)
+{
+ printk(KERN_NOTICE PREFIX "%s detected - "
+ "disable mwait for CPU C-stetes\n", id->ident);
+ idle_nomwait = 1;
+ return 0;
+}
+
+static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
+ {
+ set_no_mwait, "IFL91 board", {
+ DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
+ DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
+ DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
+ {},
+};
/* --------------------------------------------------------------------------
Errata Handling
@@ -1095,6 +1112,11 @@ static int __init acpi_processor_init(void)
return -ENOMEM;
acpi_processor_dir->owner = THIS_MODULE;
+ /*
+ * Check whether the system is DMI table. If yes, OSPM
+ * should not use mwait for CPU-states.
+ */
+ dmi_check_system(processor_idle_dmi_table);
result = cpuidle_register_driver(&acpi_idle_driver);
if (result < 0)
goto out_proc;
--
1.5.6
^ permalink raw reply related [flat|nested] 98+ messages in thread
* Re: [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras
2008-06-20 7:43 ` [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras Len Brown
@ 2008-06-20 10:13 ` Richard Purdie
2008-06-20 18:48 ` Len Brown
2008-06-20 11:48 ` Matthew Garrett
1 sibling, 1 reply; 98+ messages in thread
From: Richard Purdie @ 2008-06-20 10:13 UTC (permalink / raw)
To: Len Brown
Cc: linux-acpi, Cezary Jackiewicz, Henrique de Moraes Holschuh,
Alexey Starikovskiy, Andrew Morton, Len Brown
On Fri, 2008-06-20 at 03:43 -0400, Len Brown wrote:
> From: Cezary Jackiewicz <cezary.jackiewicz@gmail.com>
>
> This is driver for Compal Laptop: FL90/IFL90, based on MSI driver.
>
> This driver exports a few files in /sys/devices/platform/compal-laptop/:
> lcd_level - screen brightness: contains a single integer in the range 0..7 (rw)
> wlan - wlan subsystem state: contains 0 or 1 (rw)
> bluetooth - bluetooth subsystem state: contains 0 or 1 (rw)
> raw - raw value taken from embedded controller register (ro)
>
> In addition to these platform device attributes the driver registers itself
> in the Linux backlight control subsystem and is available to userspace under
> /sys/class/backlight/compal-laptop/.
>
> Signed-off-by: Cezary Jackiewicz <cezary.jackiewicz@gmail.com>
> Cc: Richard Purdie <rpurdie@rpsys.net>
> Cc: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
> Cc: Len Brown <lenb@kernel.org>
> Cc: Alexey Starikovskiy <aystarik@gmail.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Len Brown <len.brown@intel.com>
There was an update to this patch which dropped the lcd_level attribute
which might as well be applied before merging since the backlight class
handles all of that and there is no point in duplicating it.
Cheers,
Richard
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras
2008-06-20 7:43 ` [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras Len Brown
2008-06-20 10:13 ` Richard Purdie
@ 2008-06-20 11:48 ` Matthew Garrett
2008-06-20 18:52 ` Len Brown
2008-06-20 19:27 ` Henrique de Moraes Holschuh
1 sibling, 2 replies; 98+ messages in thread
From: Matthew Garrett @ 2008-06-20 11:48 UTC (permalink / raw)
To: Len Brown
Cc: linux-acpi, Cezary Jackiewicz, Richard Purdie,
Henrique de Moraes Holschuh, Alexey Starikovskiy, Andrew Morton,
Len Brown
On Fri, Jun 20, 2008 at 03:43:06AM -0400, Len Brown wrote:
> wlan - wlan subsystem state: contains 0 or 1 (rw)
> bluetooth - bluetooth subsystem state: contains 0 or 1 (rw)
Could we please not add any more drivers with custom radio control
options? rfkill is a pretty small amount of code.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 25/70] ACPICA: Update disassembler for DMAR table changes
2008-06-20 7:43 ` [PATCH 25/70] ACPICA: Update disassembler for DMAR table changes Len Brown
@ 2008-06-20 11:52 ` Matthew Garrett
2008-06-20 18:41 ` Len Brown
2008-06-20 19:49 ` Andi Kleen
1 sibling, 1 reply; 98+ messages in thread
From: Matthew Garrett @ 2008-06-20 11:52 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi, Bob Moore, Lin Ming, Len Brown
On Fri, Jun 20, 2008 at 03:43:27AM -0400, Len Brown wrote:
> extern struct acpi_dmtable_info acpi_dm_table_info_dmar1[];
> +extern struct acpi_dmtable_info acpi_dm_table_info_dmar2[];
> extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[];
Maybe I'm missing something here, but we don't actually seem to have the
disassembler code in Linux? It would be nice if we did (as a debug
option) - I'd love to be able to dump a disassembled version of what's
actually getting executed in response to events.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 69/70] ACPI : Create "idle=nomwait" bootparam
2008-06-20 7:44 ` [PATCH 69/70] ACPI : Create "idle=nomwait" bootparam Len Brown
@ 2008-06-20 15:02 ` Randy Dunlap
0 siblings, 0 replies; 98+ messages in thread
From: Randy Dunlap @ 2008-06-20 15:02 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi, Zhao Yakui, Li Shaohua, Len Brown
On Fri, 20 Jun 2008 03:44:11 -0400 Len Brown wrote:
> From: Zhao Yakui <yakui.zhao@intel.com>
>
> Add the boot option of "idle=nomwait" to disable Mwait for CPU C-states.
> If the boot option of "idle=nomwait" is added , Linux should not
> use mwait for cpu idle even when the mwait is supported. In such case the
> C2C3_FFH access mode will be disabled.
>
> http://bugzilla.kernel.org/show_bug.cgi?id=10807
>
> Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
> Signed-off-by: Li Shaohua <shaohua.li@intel.com>
> Signed-off-by: Len Brown <len.brown@intel.com>
> ---
> Documentation/kernel-parameters.txt | 4 +++-
> arch/ia64/kernel/process.c | 2 ++
> arch/x86/kernel/process.c | 14 ++++++++++++++
> drivers/acpi/processor_core.c | 12 ++++++++++++
> include/asm-ia64/processor.h | 1 +
> include/asm-x86/processor.h | 1 +
> 6 files changed, 33 insertions(+), 1 deletions(-)
>
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 1623c2f..39baaba 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -785,7 +785,7 @@ and is between 256 and 4096 characters. It is defined in the file
> See Documentation/ide/ide.txt.
>
> idle= [X86]
> - Format: idle=poll or idle=mwait, idle = halt
> + Format: idle=poll or idle=mwait, idle = halt, idle=nomwait
idle=halt [no spaces]
> Poll forces a polling idle loop that can slightly improves the performance
> of waking up a idle CPU, but will use a lot of power and make the system
> run hot. Not recommended.
> @@ -795,6 +795,8 @@ and is between 256 and 4096 characters. It is defined in the file
> as idle=poll.
> idle = halt . Halt is forced to be used for CPU idle.
idle=halt .
(no spaces allowed in command line parsing AFAIK)
> In such case C2/C3 won't be used again.
> + idle = nomwait. disable Mwait for CPU C-state.
> + In such case C2C3_FFH access mode will be disabled.
>
> ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
> Claim all unknown PCI IDE storage controllers.
---
~Randy
Linux Plumbers Conference, 17-19 September 2008, Portland, Oregon USA
http://linuxplumbersconf.org/
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 25/70] ACPICA: Update disassembler for DMAR table changes
2008-06-20 11:52 ` Matthew Garrett
@ 2008-06-20 18:41 ` Len Brown
2008-06-20 19:50 ` Andi Kleen
0 siblings, 1 reply; 98+ messages in thread
From: Len Brown @ 2008-06-20 18:41 UTC (permalink / raw)
To: Matthew Garrett; +Cc: linux-acpi, Bob Moore, Lin Ming, luming.yu
On Fri, 20 Jun 2008, Matthew Garrett wrote:
> On Fri, Jun 20, 2008 at 03:43:27AM -0400, Len Brown wrote:
> > extern struct acpi_dmtable_info acpi_dm_table_info_dmar1[];
> > +extern struct acpi_dmtable_info acpi_dm_table_info_dmar2[];
> > extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[];
>
> Maybe I'm missing something here, but we don't actually seem to have the
> disassembler code in Linux? It would be nice if we did (as a debug
> option) - I'd love to be able to dump a disassembled version of what's
> actually getting executed in response to events.
this patch and others like it are obviously just to keep Linux
in sync with ACPICA to minimize the diff we must track.
But there is actually quite a bit in ACPICA that is not in Linux.
The most useful, from a debugging point of view, might be the
hooking the ACPICA debug code into the kernel debugger --
something that Luming did about 2 years ago. However, as the
debugger was not part of the Linux kernel tree, the changes
didn't really have a good path to a customer...
-Len
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras
2008-06-20 10:13 ` Richard Purdie
@ 2008-06-20 18:48 ` Len Brown
0 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-20 18:48 UTC (permalink / raw)
To: Richard Purdie
Cc: linux-acpi, Cezary Jackiewicz, Henrique de Moraes Holschuh,
Alexey Starikovskiy, Andrew Morton
> There was an update to this patch which dropped the lcd_level attribute
> which might as well be applied before merging since the backlight class
> handles all of that and there is no point in duplicating it.
oh good, i had forgotton about that - i've got it now.
Subject: [PATCH -mm 1/1] misc,acpi,backlight: Compal Laptop Extras -
remove unnecessary attribute
thanks,
-Len
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras
2008-06-20 11:48 ` Matthew Garrett
@ 2008-06-20 18:52 ` Len Brown
2008-06-20 19:26 ` Matthew Garrett
2008-06-20 19:27 ` Henrique de Moraes Holschuh
1 sibling, 1 reply; 98+ messages in thread
From: Len Brown @ 2008-06-20 18:52 UTC (permalink / raw)
To: Matthew Garrett
Cc: linux-acpi, Cezary Jackiewicz, Richard Purdie,
Henrique de Moraes Holschuh, Alexey Starikovskiy, Andrew Morton,
Len Brown
> > wlan - wlan subsystem state: contains 0 or 1 (rw)
> > bluetooth - bluetooth subsystem state: contains 0 or 1 (rw)
> Could we please not add any more drivers with custom radio control
> options? rfkill is a pretty small amount of code.
good catch Matthew,
I agree, we never want to add custom knobs to platform drivers when
we've (finally) succeeded in adding a generic API.
What do you suggest for the best example of rfkill implementation
that should be copied here?
Cezary,
I'm okay with just deleting these custom knobs to get this driver
moving along, if the generic hooks are not ready before
the merge window.
thanks,
-Len
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras
2008-06-20 18:52 ` Len Brown
@ 2008-06-20 19:26 ` Matthew Garrett
2008-06-20 21:59 ` Henrique de Moraes Holschuh
0 siblings, 1 reply; 98+ messages in thread
From: Matthew Garrett @ 2008-06-20 19:26 UTC (permalink / raw)
To: Len Brown
Cc: linux-acpi, Cezary Jackiewicz, Richard Purdie,
Henrique de Moraes Holschuh, Alexey Starikovskiy, Andrew Morton,
Len Brown
On Fri, Jun 20, 2008 at 02:52:30PM -0400, Len Brown wrote:
> What do you suggest for the best example of rfkill implementation
> that should be copied here?
Either thinkpad-acpi or hp-wmi are pretty straightforward.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras
2008-06-20 11:48 ` Matthew Garrett
2008-06-20 18:52 ` Len Brown
@ 2008-06-20 19:27 ` Henrique de Moraes Holschuh
1 sibling, 0 replies; 98+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-06-20 19:27 UTC (permalink / raw)
To: Matthew Garrett
Cc: Len Brown, linux-acpi, Cezary Jackiewicz, Richard Purdie,
Alexey Starikovskiy, Andrew Morton, Len Brown
Hi Matthew!
On Fri, 20 Jun 2008, Matthew Garrett wrote:
> On Fri, Jun 20, 2008 at 03:43:06AM -0400, Len Brown wrote:
> > wlan - wlan subsystem state: contains 0 or 1 (rw)
> > bluetooth - bluetooth subsystem state: contains 0 or 1 (rw)
>
> Could we please not add any more drivers with custom radio control
> options? rfkill is a pretty small amount of code.
Agreed. Although it would help a great deal if the patches I sent to
linux-wireless got applied. Otherwise you really can't use rfkill properly
for platform drivers, as they almost always need read/write support, and
currently rfkill lacks that.
I will see if I manage to resend the patch stack with one or two minor
fixes, mostly people had a lot to talk about but none of it required any
changes to the patches (just further patches that need not go in yet, if
anything).
--
"One disk to rule them all, One disk to find them. One disk to bring
them all and in the darkness grind them. In the Land of Redmond
where the shadows lie." -- The Silicon Valley Tarot
Henrique Holschuh
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 32/70] ACPI: fix checkpatch.pl complaints in scan.c
2008-06-20 7:43 ` [PATCH 32/70] ACPI: fix checkpatch.pl complaints in scan.c Len Brown
@ 2008-06-20 19:48 ` Andi Kleen
2008-06-20 20:32 ` Alok Kataria
0 siblings, 1 reply; 98+ messages in thread
From: Andi Kleen @ 2008-06-20 19:48 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi, Alok N Kataria, Len Brown
Len Brown <lenb@kernel.org> writes:
> From: Alok N Kataria <akataria@vmware.com>
>
> http://bugzilla.kernel.org/show_bug.cgi?id=9772
This bug has nothing to do with the patch?
"This patch fixes the return value of acpi_eject_store()"
-Andi
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 25/70] ACPICA: Update disassembler for DMAR table changes
2008-06-20 7:43 ` [PATCH 25/70] ACPICA: Update disassembler for DMAR table changes Len Brown
2008-06-20 11:52 ` Matthew Garrett
@ 2008-06-20 19:49 ` Andi Kleen
2008-06-21 5:56 ` Brown, Len
1 sibling, 1 reply; 98+ messages in thread
From: Andi Kleen @ 2008-06-20 19:49 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi, Bob Moore, Lin Ming, Len Brown
Len Brown <lenb@kernel.org> writes:
> From: Bob Moore <robert.moore@intel.com>
>
> Now supports the 2007 intel Virtualization Technology for Directed
> I/O specification.
This patch does nothing? It just adds declarations and unused symbols
-Andi
>
> Signed-off-by: Bob Moore <robert.moore@intel.com>
> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
> Signed-off-by: Len Brown <len.brown@intel.com>
> ---
> include/acpi/acdisasm.h | 1 +
> include/acpi/actbl1.h | 4 ++++
> 2 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h
> index 788f887..f53faca 100644
> --- a/include/acpi/acdisasm.h
> +++ b/include/acpi/acdisasm.h
> @@ -162,6 +162,7 @@ extern struct acpi_dmtable_info acpi_dm_table_info_dmar_hdr[];
> extern struct acpi_dmtable_info acpi_dm_table_info_dmar_scope[];
> extern struct acpi_dmtable_info acpi_dm_table_info_dmar0[];
> extern struct acpi_dmtable_info acpi_dm_table_info_dmar1[];
> +extern struct acpi_dmtable_info acpi_dm_table_info_dmar2[];
> extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[];
> extern struct acpi_dmtable_info acpi_dm_table_info_einj[];
> extern struct acpi_dmtable_info acpi_dm_table_info_einj0[];
> diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
> index 715a489..bc47ce5 100644
> --- a/include/acpi/actbl1.h
> +++ b/include/acpi/actbl1.h
> @@ -311,6 +311,10 @@ struct acpi_table_dmar {
> u8 reserved[10];
> };
>
> +/* Flags */
> +
> +#define ACPI_DMAR_INTR_REMAP (1)
> +
> /* DMAR subtable header */
>
> struct acpi_dmar_header {
> --
> 1.5.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 25/70] ACPICA: Update disassembler for DMAR table changes
2008-06-20 18:41 ` Len Brown
@ 2008-06-20 19:50 ` Andi Kleen
2008-06-26 4:41 ` Len Brown
0 siblings, 1 reply; 98+ messages in thread
From: Andi Kleen @ 2008-06-20 19:50 UTC (permalink / raw)
To: Len Brown; +Cc: Matthew Garrett, linux-acpi, Bob Moore, Lin Ming, luming.yu
Len Brown <lenb@kernel.org> writes:
>
> But there is actually quite a bit in ACPICA that is not in Linux.
> The most useful, from a debugging point of view, might be the
> hooking the ACPICA debug code into the kernel debugger --
> something that Luming did about 2 years ago. However, as the
> debugger was not part of the Linux kernel tree, the changes
> didn't really have a good path to a customer...
kgdb supports remote function calls, so if you just make a callable
interface and perhaps supply a standard macro file users could call
it.
-Andi
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 32/70] ACPI: fix checkpatch.pl complaints in scan.c
2008-06-20 19:48 ` Andi Kleen
@ 2008-06-20 20:32 ` Alok Kataria
2008-06-20 20:39 ` Andi Kleen
0 siblings, 1 reply; 98+ messages in thread
From: Alok Kataria @ 2008-06-20 20:32 UTC (permalink / raw)
To: Andi Kleen; +Cc: Len Brown, linux-acpi@vger.kernel.org, Len Brown
On Fri, 2008-06-20 at 12:48 -0700, Andi Kleen wrote:
> Len Brown <lenb@kernel.org> writes:
>
> > From: Alok N Kataria <akataria@vmware.com>
> >
> > http://bugzilla.kernel.org/show_bug.cgi?id=9772
>
> This bug has nothing to do with the patch?
>
> "This patch fixes the return value of acpi_eject_store()"
>
This patch fixes the checkpatch.pl complaints introduced by patch in
comment 23 in that bug.
Please look here for the checkpatch.pl complaints..
http://bugzilla.kernel.org/show_bug.cgi?id=9772#c33
Thanks,
Alok
> -Andi
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 32/70] ACPI: fix checkpatch.pl complaints in scan.c
2008-06-20 20:32 ` Alok Kataria
@ 2008-06-20 20:39 ` Andi Kleen
2008-06-20 20:59 ` Alok Kataria
0 siblings, 1 reply; 98+ messages in thread
From: Andi Kleen @ 2008-06-20 20:39 UTC (permalink / raw)
To: akataria; +Cc: Len Brown, linux-acpi@vger.kernel.org, Len Brown
Alok Kataria wrote:
> On Fri, 2008-06-20 at 12:48 -0700, Andi Kleen wrote:
>> Len Brown <lenb@kernel.org> writes:
>>
>>> From: Alok N Kataria <akataria@vmware.com>
>>>
>>> http://bugzilla.kernel.org/show_bug.cgi?id=9772
>> This bug has nothing to do with the patch?
>>
>> "This patch fixes the return value of acpi_eject_store()"
>>
>
> This patch fixes the checkpatch.pl complaints introduced by patch in
> comment 23 in that bug.
> Please look here for the checkpatch.pl complaints..
> http://bugzilla.kernel.org/show_bug.cgi?id=9772#c33
Well that's still not a very useful description, given that you fix
a real bug here, not just the usual checkpatch whitspace nops.
Not sure why Len also didn't fast track it. It seems to me like
something .26-worthy.
-Andi
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 32/70] ACPI: fix checkpatch.pl complaints in scan.c
2008-06-20 20:39 ` Andi Kleen
@ 2008-06-20 20:59 ` Alok Kataria
2008-06-21 14:50 ` Andi Kleen
0 siblings, 1 reply; 98+ messages in thread
From: Alok Kataria @ 2008-06-20 20:59 UTC (permalink / raw)
To: Andi Kleen; +Cc: Len Brown, linux-acpi@vger.kernel.org, Len Brown
On Fri, 2008-06-20 at 13:39 -0700, Andi Kleen wrote:
> Alok Kataria wrote:
> > On Fri, 2008-06-20 at 12:48 -0700, Andi Kleen wrote:
> >> Len Brown <lenb@kernel.org> writes:
> >>
> >>> From: Alok N Kataria <akataria@vmware.com>
> >>>
> >>> http://bugzilla.kernel.org/show_bug.cgi?id=9772
> >> This bug has nothing to do with the patch?
> >>
> >> "This patch fixes the return value of acpi_eject_store()"
> >>
> >
> > This patch fixes the checkpatch.pl complaints introduced by patch in
> > comment 23 in that bug.
> > Please look here for the checkpatch.pl complaints..
> > http://bugzilla.kernel.org/show_bug.cgi?id=9772#c33
>
> Well that's still not a very useful description, given that you fix
> a real bug here, not just the usual checkpatch whitspace nops.
>
Maybe I am overlooking what you are trying to say over here.
but, Which real bug ?
> Not sure why Len also didn't fast track it. It seems to me like
> something .26-worthy.
>
This patch modifies the code to use kthread_run instead of
kernel_thread. The kernel_thread call was introduced by an earlier patch
from Zhang Rui which is in comment 23.
Since the patch from Zhang has not reached mainline yet, i fail to
understand how can this patch be worthy of .26 ?
Thanks,
Alok
> -Andi
>
>
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras
2008-06-20 19:26 ` Matthew Garrett
@ 2008-06-20 21:59 ` Henrique de Moraes Holschuh
2008-06-20 22:10 ` Matthew Garrett
0 siblings, 1 reply; 98+ messages in thread
From: Henrique de Moraes Holschuh @ 2008-06-20 21:59 UTC (permalink / raw)
To: Matthew Garrett
Cc: Len Brown, linux-acpi, Cezary Jackiewicz, Richard Purdie,
Alexey Starikovskiy, Andrew Morton, Len Brown
On Fri, 20 Jun 2008, Matthew Garrett wrote:
> On Fri, Jun 20, 2008 at 02:52:30PM -0400, Len Brown wrote:
> > What do you suggest for the best example of rfkill implementation
> > that should be copied here?
>
> Either thinkpad-acpi or hp-wmi are pretty straightforward.
I haven't sent the thinkpad-acpi rfkill implementation yet. And I have
not reviewed hp-wmi to check if it is correct. If it uses the input
polldev, I can give you 100% assurance that it is broken.
You pretty much have to wait for my rfkill patches to get merged before
you can do something right with rfkill and stuff like thinkpad-acpi that
has read/write rfkill registers.
Anyway, if anyone wants to look at the rfkill patches and the
thinkpad-acpi rfkill implementation, which *is* straightforward like
Matthew said, please refer to the thinkpad-acpi git trees at:
git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
branches devel and rfkill.
Note that both branches are in risk of being rebased/rewound, as they
are tips of stgit branches. Get whatever you need from them, but don't
base anything on them without talking to me first. rfkill, in
particular, will have to be rebased to the wireless-testing tree soon.
Also, if anyone wants/needs to be added to the cc list for the rfkill
stuff I am trying to get merged (e.g. because you will also need it for
your driver), drop me a note.
I am planning to submit the thinkpad-acpi rfkill conversion only after
the rfkill stuff gets merged in -next or some other tree, but real life
is getting in the way.
--
"One disk to rule them all, One disk to find them. One disk to bring
them all and in the darkness grind them. In the Land of Redmond
where the shadows lie." -- The Silicon Valley Tarot
Henrique Holschuh
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras
2008-06-20 21:59 ` Henrique de Moraes Holschuh
@ 2008-06-20 22:10 ` Matthew Garrett
0 siblings, 0 replies; 98+ messages in thread
From: Matthew Garrett @ 2008-06-20 22:10 UTC (permalink / raw)
To: Henrique de Moraes Holschuh
Cc: Len Brown, linux-acpi, Cezary Jackiewicz, Richard Purdie,
Alexey Starikovskiy, Andrew Morton, Len Brown
On Fri, Jun 20, 2008 at 06:59:45PM -0300, Henrique de Moraes Holschuh wrote:
> I haven't sent the thinkpad-acpi rfkill implementation yet. And I have
> not reviewed hp-wmi to check if it is correct. If it uses the input
> polldev, I can give you 100% assurance that it is broken.
It doesn't.
> You pretty much have to wait for my rfkill patches to get merged before
> you can do something right with rfkill and stuff like thinkpad-acpi that
> has read/write rfkill registers.
Ah. I get an event whenever the state changes in hardware, which means I
can update the rfkill state automatically (the event's purely internal,
I never send it out to userspace)
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 98+ messages in thread
* RE: [PATCH 25/70] ACPICA: Update disassembler for DMAR table changes
2008-06-20 19:49 ` Andi Kleen
@ 2008-06-21 5:56 ` Brown, Len
0 siblings, 0 replies; 98+ messages in thread
From: Brown, Len @ 2008-06-21 5:56 UTC (permalink / raw)
To: Andi Kleen, Len Brown; +Cc: linux-acpi, Moore, Robert, Lin, Ming M
>This patch does nothing? It just adds declarations and unused symbols
That's right.
this patch is from an upstream ACPICA patch --
but Linux doesn't use all of ACPICA's files.
The reason we apply these is to keep upstream ACPICA
and downstream Linux shared files as close as possible
because manging divergence is extremely labor intensive.
-Len
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 32/70] ACPI: fix checkpatch.pl complaints in scan.c
2008-06-20 20:59 ` Alok Kataria
@ 2008-06-21 14:50 ` Andi Kleen
0 siblings, 0 replies; 98+ messages in thread
From: Andi Kleen @ 2008-06-21 14:50 UTC (permalink / raw)
To: akataria; +Cc: Len Brown, linux-acpi@vger.kernel.org, Len Brown
Alok Kataria <akataria@vmware.com> writes:
I misread the patch sorry. It looked like you added error checking,
but I didn't notice that the function call had changed too.
Len was right of course.
-Andi
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: ACPI patch queue for 2.6.27
2008-06-20 7:43 ACPI patch queue for 2.6.27 Len Brown
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
@ 2008-06-23 0:24 ` Jonathan Woithe
1 sibling, 0 replies; 98+ messages in thread
From: Jonathan Woithe @ 2008-06-23 0:24 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi
Hi Len
> Here is the current ACPI queue for 2.6.27
> fujitsu-laptop and compal-laptop are new.
A minor nitpick: fujitsu-laptop isn't new in 2.6.27 (it was new in 2.6.24 I
think). It is just getting some major new features in 2.6.27. Maybe that's
what you meant.
Regards
jonathan
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: [PATCH 25/70] ACPICA: Update disassembler for DMAR table changes
2008-06-20 19:50 ` Andi Kleen
@ 2008-06-26 4:41 ` Len Brown
0 siblings, 0 replies; 98+ messages in thread
From: Len Brown @ 2008-06-26 4:41 UTC (permalink / raw)
To: Andi Kleen; +Cc: Matthew Garrett, linux-acpi, Bob Moore, Lin Ming, luming.yu
On Fri, 20 Jun 2008, Andi Kleen wrote:
> Len Brown <lenb@kernel.org> writes:
> >
> > But there is actually quite a bit in ACPICA that is not in Linux.
> > The most useful, from a debugging point of view, might be the
> > hooking the ACPICA debug code into the kernel debugger --
> > something that Luming did about 2 years ago. However, as the
> > debugger was not part of the Linux kernel tree, the changes
> > didn't really have a good path to a customer...
>
> kgdb supports remote function calls, so if you just make a callable
> interface and perhaps supply a standard macro file users could call
> it.
at some point we need to seriously consider "productizing"
the ACPICA hooks to kgdb. I guess this is one for the to-do list.
-len
^ permalink raw reply [flat|nested] 98+ messages in thread
* Check for BIOS bugs - Original Subject: Re: [PATCH 23/70] ACPICA: Workaround for reversed _PRT entries from BIOS
2008-06-20 7:43 ` [PATCH 23/70] ACPICA: Workaround for reversed _PRT entries from BIOS Len Brown
@ 2008-07-01 8:33 ` Thomas Renninger
2008-07-07 11:12 ` Pavel Machek
0 siblings, 1 reply; 98+ messages in thread
From: Thomas Renninger @ 2008-07-01 8:33 UTC (permalink / raw)
To: Len Brown
Cc: linux-acpi, Bob Moore, Lin Ming, Len Brown, Bjorn Helgaas,
Huang Cheng, firmwarekit-discuss, Arjan van de Ven,
Linux Kernel Mailing List
On Friday 20 June 2008 09:43:25 Len Brown wrote:
> From: Bob Moore <robert.moore@intel.com>
>
> Some BIOSs erroneously reverse the _PRT SourceName and the
> SourceIndex. Detect and repair this problem. MS ACPI also allows
> and repairs this problem, thus ACPICA must also.
It would be great to have an interface to report this as a BIOS defect.
Something like:
FIRMWARE_BUG_ON(FIRM_WARN, "erroneously reversed the _PRT source_name", ACPI_
Bug);
FIRMWARE_BUG_ON(severity, description, component);
If say CONFIG_FIRMWARE_DEBUG is set this could send a netlink event to
userspace and e.g. linuxfirmwarekit can grab it.
linuxfirmwarekit currently implements it's own scripts and even worse, parses
dmesg to find BIOS bugs, which is not really maintenable.
IMO the kernel developers themselves need an interface where they can report
bugs while seeing and fixing them.
Huang Cheng posted a nice patch on the linuxfirmwarekit list a while ago
(unfortunately the patch was attached not inlined):
http://www.bughost.org/pipermail/firmwarekit-discuss/2008-March/000166.html
I mean it needs some cleanup (e.g. the file name was the bug number, there
need to be a general interface created, e.g. as shown above, etc.).
But this is IMO a good idea and might be worth adding to the kernel (when
written :) ).
Comments?
Thomas
PS: I added Bjorn as in the PNP parts BIOSes are pretty much messed up.
One reason is that AFAIK ACPI parts are glued together. Having dozens/hundreds
of device declarations in a BIOS of which huge parts have not been written by
yourself, it is very hard for vendors to check for correctness.
While Bjorn and others are adding quirks and workarounds for specific devices,
machines or general BIOS bugs it would be great to be able to point vendors
to these bugs by a simple tool.
> Signed-off-by: Bob Moore <robert.moore@intel.com>
> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
> Signed-off-by: Len Brown <len.brown@intel.com>
> ---
> drivers/acpi/resources/rscreate.c | 17 +++++++++++++++++
> 1 files changed, 17 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/acpi/resources/rscreate.c
> b/drivers/acpi/resources/rscreate.c index faddaee..70c84ec 100644
> --- a/drivers/acpi/resources/rscreate.c
> +++ b/drivers/acpi/resources/rscreate.c
> @@ -285,6 +285,23 @@ acpi_rs_create_pci_routing_table(union
> acpi_operand_object *package_object, }
>
> /*
> + * If the BIOS has erroneously reversed the _PRT source_name (index 2)
> + * and the source_index (index 3), fix it. _PRT is important enough to
> + * workaround this BIOS error. This also provides compatibility with
> + * other ACPI implementations.
> + */
> + obj_desc = sub_object_list[3];
> + if (!obj_desc
> + || (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
> + sub_object_list[3] = sub_object_list[2];
> + sub_object_list[2] = obj_desc;
> +
> + ACPI_WARNING((AE_INFO,
> + "(PRT[%X].Source) SourceName and SourceIndex are reversed,
> fixed", + index));
> + }
> +
> + /*
> * 3) Third subobject: Dereference the PRT.source_name
> * The name may be unresolved (slack mode), so allow a null object
> */
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: Check for BIOS bugs - Original Subject: Re: [PATCH 23/70] ACPICA: Workaround for reversed _PRT entries from BIOS
2008-07-01 8:33 ` Check for BIOS bugs - Original Subject: " Thomas Renninger
@ 2008-07-07 11:12 ` Pavel Machek
2008-07-08 15:40 ` Arjan van de Ven
0 siblings, 1 reply; 98+ messages in thread
From: Pavel Machek @ 2008-07-07 11:12 UTC (permalink / raw)
To: Thomas Renninger
Cc: Len Brown, linux-acpi, Bob Moore, Lin Ming, Len Brown,
Bjorn Helgaas, Huang Cheng, firmwarekit-discuss, Arjan van de Ven,
Linux Kernel Mailing List
Hi!
> > Some BIOSs erroneously reverse the _PRT SourceName and the
> > SourceIndex. Detect and repair this problem. MS ACPI also allows
> > and repairs this problem, thus ACPICA must also.
>
> It would be great to have an interface to report this as a BIOS defect.
>
> Something like:
>
> FIRMWARE_BUG_ON(FIRM_WARN, "erroneously reversed the _PRT source_name", ACPI_
> Bug);
>
> FIRMWARE_BUG_ON(severity, description, component);
Yes, please.
I'd also like HARDWARE_BUG_ON(), with similar usage.
With all the preload-linux-on-foo project, we have some chance to make
BIOS vendors fix their stuff if we can easily diagnose errors in
there.
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: Check for BIOS bugs - Original Subject: Re: [PATCH 23/70] ACPICA: Workaround for reversed _PRT entries from BIOS
2008-07-07 11:12 ` Pavel Machek
@ 2008-07-08 15:40 ` Arjan van de Ven
2008-07-08 19:34 ` Brown, Len
0 siblings, 1 reply; 98+ messages in thread
From: Arjan van de Ven @ 2008-07-08 15:40 UTC (permalink / raw)
To: Pavel Machek
Cc: Thomas Renninger, Len Brown, linux-acpi, Bob Moore, Lin Ming,
Len Brown, Bjorn Helgaas, Huang Cheng, firmwarekit-discuss,
Linux Kernel Mailing List
Pavel Machek wrote:
> Hi!
>
>>> Some BIOSs erroneously reverse the _PRT SourceName and the
>>> SourceIndex. Detect and repair this problem. MS ACPI also allows
>>> and repairs this problem, thus ACPICA must also.
>> It would be great to have an interface to report this as a BIOS defect.
>>
>> Something like:
>>
>> FIRMWARE_BUG_ON(FIRM_WARN, "erroneously reversed the _PRT source_name", ACPI_
>> Bug);
>>
>> FIRMWARE_BUG_ON(severity, description, component);
>
> Yes, please.
>
> I'd also like HARDWARE_BUG_ON(), with similar usage.
>
> With all the preload-linux-on-foo project, we have some chance to make
> BIOS vendors fix their stuff if we can easily diagnose errors in
> there.
also we can tie this to kerneloops.org to make a list of top known firmware/hardware bugs, seperate from the kernel code bugs
>
^ permalink raw reply [flat|nested] 98+ messages in thread
* RE: Check for BIOS bugs - Original Subject: Re: [PATCH 23/70] ACPICA: Workaround for reversed _PRT entries from BIOS
2008-07-08 15:40 ` Arjan van de Ven
@ 2008-07-08 19:34 ` Brown, Len
2008-07-08 22:11 ` Pavel Machek
2008-07-09 8:51 ` Thomas Renninger
0 siblings, 2 replies; 98+ messages in thread
From: Brown, Len @ 2008-07-08 19:34 UTC (permalink / raw)
To: Arjan van de Ven, Pavel Machek
Cc: Thomas Renninger, Len Brown, linux-acpi, Moore, Robert,
Lin, Ming M, Bjorn Helgaas, Huang Cheng, firmwarekit-discuss,
Linux Kernel Mailing List
>>>> Some BIOSs erroneously reverse the _PRT SourceName and the
>>>> SourceIndex. Detect and repair this problem. MS ACPI also allows
>>>> and repairs this problem, thus ACPICA must also.
>>> It would be great to have an interface to report this as a
>BIOS defect.
>>>
>>> Something like:
>>>
>>> FIRMWARE_BUG_ON(FIRM_WARN, "erroneously reversed the _PRT
>source_name", ACPI_
>>> Bug);
>>>
>>> FIRMWARE_BUG_ON(severity, description, component);
>>
>> Yes, please.
I'm not excited about maintaining
maintaining linux-as-a-firmware-diagnostic --
particularly when...
1. it clutters the code for normail machines
2. finding the bug is pointless, because even
if you fix one machine, you are guaranteed to
not fix all machines and thus must maintain
the workaround anyway.
>> I'd also like HARDWARE_BUG_ON(), with similar usage.
>>
>> With all the preload-linux-on-foo project, we have some
>> chance to make
>> BIOS vendors fix their stuff if we can easily diagnose errors in
>> there.
These customers should be running
http://linuxfirmwarekit.org/
We do maintain some degree of "high-road ACPI spec checking"
with the "acpi=strict" boot option. If we do more of this,
I think it should stay under that option.
thanks,
-Len
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: Check for BIOS bugs - Original Subject: Re: [PATCH 23/70] ACPICA: Workaround for reversed _PRT entries from BIOS
2008-07-08 19:34 ` Brown, Len
@ 2008-07-08 22:11 ` Pavel Machek
2008-07-09 8:51 ` Thomas Renninger
1 sibling, 0 replies; 98+ messages in thread
From: Pavel Machek @ 2008-07-08 22:11 UTC (permalink / raw)
To: Brown, Len
Cc: Arjan van de Ven, Thomas Renninger, Len Brown, linux-acpi,
Moore, Robert, Lin, Ming M, Bjorn Helgaas, Huang Cheng,
firmwarekit-discuss, Linux Kernel Mailing List
Hi!
> >>> FIRMWARE_BUG_ON(severity, description, component);
> >>
> >> Yes, please.
>
> I'm not excited about maintaining
> maintaining linux-as-a-firmware-diagnostic --
> particularly when...
>
> 1. it clutters the code for normail machines
> 2. finding the bug is pointless, because even
> if you fix one machine, you are guaranteed to
> not fix all machines and thus must maintain
> the workaround anyway.
Well, at least we can make sure new machines are okay.
Plus, it is nice to know how common hw/BIOS problems are.
> >> I'd also like HARDWARE_BUG_ON(), with similar usage.
> >>
> >> With all the preload-linux-on-foo project, we have some
> >> chance to make
> >> BIOS vendors fix their stuff if we can easily diagnose errors in
> >> there.
>
> These customers should be running
> http://linuxfirmwarekit.org/
>
> We do maintain some degree of "high-road ACPI spec checking"
> with the "acpi=strict" boot option. If we do more of this,
> I think it should stay under that option.
That's okay with me, but it would be nice to have printk() markup, so
that we can tell BIOS/hw bugs from normal kernel messages.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 98+ messages in thread
* Re: Check for BIOS bugs - Original Subject: Re: [PATCH 23/70] ACPICA: Workaround for reversed _PRT entries from BIOS
2008-07-08 19:34 ` Brown, Len
2008-07-08 22:11 ` Pavel Machek
@ 2008-07-09 8:51 ` Thomas Renninger
2008-07-17 20:31 ` Brown, Len
1 sibling, 1 reply; 98+ messages in thread
From: Thomas Renninger @ 2008-07-09 8:51 UTC (permalink / raw)
To: Brown, Len
Cc: Arjan van de Ven, Pavel Machek, Len Brown, linux-acpi,
Moore, Robert, Lin, Ming M, Bjorn Helgaas, Huang Cheng,
firmwarekit-discuss, Linux Kernel Mailing List
On Tuesday 08 July 2008 21:34:55 Brown, Len wrote:
> >>>> Some BIOSs erroneously reverse the _PRT SourceName and the
> >>>> SourceIndex. Detect and repair this problem. MS ACPI also allows
> >>>> and repairs this problem, thus ACPICA must also.
> >>>
> >>> It would be great to have an interface to report this as a
> >
> >BIOS defect.
> >
> >>> Something like:
> >>>
> >>> FIRMWARE_BUG_ON(FIRM_WARN, "erroneously reversed the _PRT
> >
> >source_name", ACPI_
> >
> >>> Bug);
> >>>
> >>> FIRMWARE_BUG_ON(severity, description, component);
> >>
> >> Yes, please.
>
> I'm not excited about maintaining
> maintaining linux-as-a-firmware-diagnostic --
> particularly when...
Above is not for ACPI only. But ACPI is probably a candidate which should make
use of it.
>
> 1. it clutters the code for normail machines
It is the only disadvantage, "cluttering" the code.
On the other hand, this is an advantage.
While comments like "/* this must not happen, out of spec, etc. */"
should normally be added,
kernel developers tend to return -ENODEV and that's it.
A FIRMWARE_BUG("Description") would be compiled out on a
production kernel, compiled in for a kernel on which linuxfirmwarekit
boots or other debug kernels and would nicely document,
not clutter the code.
> 2. finding the bug is pointless,
No.
> because even
> if you fix one machine, you are guaranteed to
> not fix all machines and thus must maintain
> the workaround anyway.
I expect you want HP to fix their critical shut down temperature of 256 C?
If we would have known this, we had made them fix this and a lot other things
also.
This is one of dozens of examples...
> >> I'd also like HARDWARE_BUG_ON(), with similar usage.
> >>
> >> With all the preload-linux-on-foo project, we have some
> >> chance to make
> >> BIOS vendors fix their stuff if we can easily diagnose errors in
> >> there.
>
> These customers should be running
> http://linuxfirmwarekit.org/
It is not worth much.
At least currently and a firmware bug interface to the kernel is about to
change this.
1) linuxfirmwarekit is parsing dmesg..., these messages are changing
all the time in the kernel.
S390 AFAIK currently indexes all printks to avoid a simple space cleanup
to mix up messges. It is not needed to go that far...
2) The rest is done through userspace plugins written in shell/perl or C.
But most firmware bugs are absorbed by the kernel already. So there
is nothing we could tell OEMs they should correct.
3) 2+3 is unmaintainable. There is enough work in the kernel, now we should
write a linuxfirmwarekit plugin for every firmwarebug we find?!?
4) I tried to convince our kernel people to write linuxfirmwarekit plugins
with exactly zero response. Hmm wrong, Frank wrote a thermal zone
checker, some hundred lines of fragile shell code, it would have been less
than ten lines in the kernel, just add some FIRMWARE_BUG(..) in the right
if/else conditions. And it's not worth much anymore as soon as
thermal_zone is moving to sysfs.
> We do maintain some degree of "high-road ACPI spec checking"
> with the "acpi=strict" boot option. If we do more of this,
> I think it should stay under that option.
In the linuxfirmwarekit the ACPI tables are dumped, disassembled and
recompiled. The errors and warnings are printed out as ACPI BIOS errors.
This works out.
The iasl compiler still is a bit too noisy and cannot disassemble SSDTs
correctly (maybe it got fixed, don't know), but this can work out.
The problem is that you only find syntactical bugs.
But there are *a lot* bugs like e.g. critical temperature of 256 C. Or If this
object exists, that object must exist. Logic ACPI BIOS bugs can only be found
in the kernel itself at runtime.
Ahh Bjorn is in CC..., Wrong opregion declarations and PNP resource
declarations are rather common. I mean theoretically you can find this in
userspace. Not with disassembling and recompiling but with interpreting the
tables in userspace... Again unmaintainable and who should do the checking?
The guy who writes the kernel code...
I really like the idea of the linuxfirmwarekit and tried to push it, but I do
not see any future for it without kernel support.
Thomas
^ permalink raw reply [flat|nested] 98+ messages in thread
* RE: Check for BIOS bugs - Original Subject: Re: [PATCH 23/70] ACPICA: Workaround for reversed _PRT entries from BIOS
2008-07-09 8:51 ` Thomas Renninger
@ 2008-07-17 20:31 ` Brown, Len
0 siblings, 0 replies; 98+ messages in thread
From: Brown, Len @ 2008-07-17 20:31 UTC (permalink / raw)
To: Thomas Renninger
Cc: Arjan van de Ven, Pavel Machek, Len Brown, linux-acpi,
Moore, Robert, Lin, Ming M, Bjorn Helgaas, Huang Cheng,
firmwarekit-discuss, Linux Kernel Mailing List
>> I'm not excited about maintaining
>> maintaining linux-as-a-firmware-diagnostic --
>> particularly when...
>Above is not for ACPI only. But ACPI is probably a candidate
>which should make use of it.
Sure, there may be justification for doing something like this
in the kernel, but the issue that started this thread isn't it.
The issue that started this thread can be diagnosed by user-space
in linuxfirmwarekit. Multiple machines have this bug, which means
that it is "common industry practice" and the kernel has to work
around it (silently) if we like it or not.
ie. the issue, now that it is debugged and worked around,
is effectly just firmware lint.
thanks,
-Len
^ permalink raw reply [flat|nested] 98+ messages in thread
end of thread, other threads:[~2008-07-17 20:31 UTC | newest]
Thread overview: 98+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-20 7:43 ACPI patch queue for 2.6.27 Len Brown
2008-06-20 7:43 ` [PATCH 01/70] fix a deadlock issue when poking "eject" file Len Brown
2008-06-20 7:43 ` [PATCH 02/70] force offline the processor during hot-removal Len Brown
2008-06-20 7:43 ` [PATCH 03/70] create sysfs link from acpi device to sysdev for cpu Len Brown
2008-06-20 7:43 ` [PATCH 04/70] misc,acpi,backlight: compal Laptop Extras Len Brown
2008-06-20 10:13 ` Richard Purdie
2008-06-20 18:48 ` Len Brown
2008-06-20 11:48 ` Matthew Garrett
2008-06-20 18:52 ` Len Brown
2008-06-20 19:26 ` Matthew Garrett
2008-06-20 21:59 ` Henrique de Moraes Holschuh
2008-06-20 22:10 ` Matthew Garrett
2008-06-20 19:27 ` Henrique de Moraes Holschuh
2008-06-20 7:43 ` [PATCH 05/70] ACPI: change processors from array to per_cpu variable Len Brown
2008-06-20 7:43 ` [PATCH 06/70] Fujitsu-laptop update Len Brown
2008-06-20 7:43 ` [PATCH 07/70] ACPI PM: acpi_pm_device_sleep_state() cleanup Len Brown
2008-06-20 7:43 ` [PATCH 08/70] PCI ACPI: Drop the second argument of platform_pci_choose_state Len Brown
2008-06-20 7:43 ` [PATCH 09/70] ACPI PM: Remove obsolete Toshiba workaround Len Brown
2008-06-20 7:43 ` [PATCH 10/70] APM emulation: Notify about all suspend events, not just APM invoked ones (v2) Len Brown
2008-06-20 7:43 ` [PATCH 11/70] Freezer: Introduce PF_FREEZER_NOSIG Len Brown
2008-06-20 7:43 ` [PATCH 12/70] snapshot: Push BKL down into ioctl handlers Len Brown
2008-06-20 7:43 ` [PATCH 13/70] snapshot: Use pm_mutex for mutual exclusion Len Brown
2008-06-20 7:43 ` [PATCH 14/70] ACPICA: Add argument count checking to control method invocation via acpi_evaluate_object Len Brown
2008-06-20 7:43 ` [PATCH 15/70] ACPICA: Fix for hang on GPE method invocation Len Brown
2008-06-20 7:43 ` [PATCH 16/70] ACPICA: Update tracking macros to reduce code/data size Len Brown
2008-06-20 7:43 ` [PATCH 17/70] ACPICA: Fix possible negative array index in acpi_ut_validate_exception Len Brown
2008-06-20 7:43 ` [PATCH 18/70] ACPICA: Eliminate acpi_native_uint type Len Brown
2008-06-20 7:43 ` [PATCH 19/70] ACPICA: Removed unused include files from source files Len Brown
2008-06-20 7:43 ` [PATCH 20/70] ACPICA: Several lint changes, no functional changes Len Brown
2008-06-20 7:43 ` [PATCH 21/70] ACPICA: Add const qualifier for appropriate string constants Len Brown
2008-06-20 7:43 ` [PATCH 22/70] ACPICA: Update version to 20080514 Len Brown
2008-06-20 7:43 ` [PATCH 23/70] ACPICA: Workaround for reversed _PRT entries from BIOS Len Brown
2008-07-01 8:33 ` Check for BIOS bugs - Original Subject: " Thomas Renninger
2008-07-07 11:12 ` Pavel Machek
2008-07-08 15:40 ` Arjan van de Ven
2008-07-08 19:34 ` Brown, Len
2008-07-08 22:11 ` Pavel Machek
2008-07-09 8:51 ` Thomas Renninger
2008-07-17 20:31 ` Brown, Len
2008-06-20 7:43 ` [PATCH 24/70] ACPICA: Update DMAR and SRAT table definitions Len Brown
2008-06-20 7:43 ` [PATCH 25/70] ACPICA: Update disassembler for DMAR table changes Len Brown
2008-06-20 11:52 ` Matthew Garrett
2008-06-20 18:41 ` Len Brown
2008-06-20 19:50 ` Andi Kleen
2008-06-26 4:41 ` Len Brown
2008-06-20 19:49 ` Andi Kleen
2008-06-21 5:56 ` Brown, Len
2008-06-20 7:43 ` [PATCH 26/70] ACPICA: Fix for invalid large array index on 64-bit systems Len Brown
2008-06-20 7:43 ` [PATCH 27/70] ACPICA: Cleanup debug operand dump mechanism Len Brown
2008-06-20 7:43 ` [PATCH 28/70] ACPICA: Cleanup of _PRT parsing code Len Brown
2008-06-20 7:43 ` [PATCH 29/70] ACPICA: Fix mutex debug code for wrong loop termination value Len Brown
2008-06-20 7:43 ` [PATCH 30/70] ACPICA: Update version to 20080609 Len Brown
2008-06-20 7:43 ` [PATCH 32/70] ACPI: fix checkpatch.pl complaints in scan.c Len Brown
2008-06-20 19:48 ` Andi Kleen
2008-06-20 20:32 ` Alok Kataria
2008-06-20 20:39 ` Andi Kleen
2008-06-20 20:59 ` Alok Kataria
2008-06-21 14:50 ` Andi Kleen
2008-06-20 7:43 ` [PATCH 33/70] ACPI: fix acpi fan state set error Len Brown
2008-06-20 7:43 ` [PATCH 34/70] ACPI Exception (video-1721): UNKNOWN_STATUS_CODE, Cant attach device Len Brown
2008-06-20 7:43 ` [PATCH 35/70] ACPI: no AC status notification Len Brown
2008-06-20 7:43 ` [PATCH 36/70] ACPICA: Fixes warning from exconfig.c on 64-bit build Len Brown
2008-06-20 7:43 ` [PATCH 37/70] ACPI: fix processor throttling set error Len Brown
2008-06-20 7:43 ` [PATCH 38/70] acpi: fix printk format warning Len Brown
2008-06-20 7:43 ` [PATCH 39/70] PNP: add detail to debug resource dump Len Brown
2008-06-20 7:43 ` [PATCH 40/70] PNP: remove pnp_resource.index Len Brown
2008-06-20 7:43 ` [PATCH 41/70] PNP: add pnp_resource_type() internal interface Len Brown
2008-06-20 7:43 ` [PATCH 42/70] PNP: add pnp_resource_type_name() helper function Len Brown
2008-06-20 7:43 ` [PATCH 43/70] PNP: make pnp_{port,mem,etc}_start(), et al work for invalid resources Len Brown
2008-06-20 7:43 ` [PATCH 44/70] PNP: replace pnp_resource_table with dynamically allocated resources Len Brown
2008-06-20 7:43 ` [PATCH 45/70] PNPACPI: keep disabled resources when parsing current config Len Brown
2008-06-20 7:43 ` [PATCH 46/70] PNP: remove ratelimit on add resource failures Len Brown
2008-06-20 7:43 ` [PATCH 47/70] PNP: dont sort by type in /sys/.../resources Len Brown
2008-06-20 7:43 ` [PATCH 48/70] PNP: add pnp_possible_config() -- can a device could be configured this way? Len Brown
2008-06-20 7:43 ` [PATCH 49/70] PNP: whitespace/coding style fixes Len Brown
2008-06-20 7:43 ` [PATCH 50/70] PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM Len Brown
2008-06-20 7:43 ` [PATCH 51/70] PNP: make resource option structures private to PNP subsystem Len Brown
2008-06-20 7:43 ` [PATCH 52/70] PNP: introduce pnp_irq_mask_t typedef Len Brown
2008-06-20 7:43 ` [PATCH 53/70] PNP: increase I/O port & memory option address sizes Len Brown
2008-06-20 7:43 ` [PATCH 54/70] PNP: improve resource assignment debug Len Brown
2008-06-20 7:43 ` [PATCH 55/70] PNP: in debug resource dump, make empty list obvious Len Brown
2008-06-20 7:43 ` [PATCH 56/70] PNP: make resource assignment functions return 0 (success) or -EBUSY (failure) Len Brown
2008-06-20 7:43 ` [PATCH 57/70] PNP: remove redundant pnp_can_configure() check Len Brown
2008-06-20 7:44 ` [PATCH 58/70] PNP: centralize resource option allocations Len Brown
2008-06-20 7:44 ` [PATCH 59/70] PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR Len Brown
2008-06-20 7:44 ` [PATCH 60/70] PNP: rename pnp_register_*_resource() local variables Len Brown
2008-06-20 7:44 ` [PATCH 61/70] PNP: support optional IRQ resources Len Brown
2008-06-20 7:44 ` [PATCH 62/70] PNP: remove extra 0x100 bit from option priority Len Brown
2008-06-20 7:44 ` [PATCH 63/70] ISAPNP: handle independent options following dependent ones Len Brown
2008-06-20 7:44 ` [PATCH 64/70] PNP: convert resource options to single linked list Len Brown
2008-06-20 7:44 ` [PATCH 65/70] PNP: avoid legacy IDE IRQs Len Brown
2008-06-20 7:44 ` [PATCH 66/70] PNPACPI: add support for HP vendor-specific CCSR descriptors Len Brown
2008-06-20 7:44 ` [PATCH 67/70] ACPI: Disable the C2C3_FFH access mode HW has no MWAIT support Len Brown
2008-06-20 7:44 ` [PATCH 68/70] ACPI: Create "idle=halt" boot parameter Len Brown
2008-06-20 7:44 ` [PATCH 69/70] ACPI : Create "idle=nomwait" bootparam Len Brown
2008-06-20 15:02 ` Randy Dunlap
2008-06-20 7:44 ` [PATCH 70/70] ACPI : Add DMI check to disable mwait on broken Compal Len Brown
2008-06-23 0:24 ` ACPI patch queue for 2.6.27 Jonathan Woithe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).