]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.drivers/dmi-introduce-dmi_first_match
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / dmi-introduce-dmi_first_match
CommitLineData
00e5a55c
BS
1From 2969c7df1c1808d2a38a9adfbb158de7632a0cfb Mon Sep 17 00:00:00 2001
2From: Rafael J. Wysocki <rjw@sisk.pl>
3Date: Mon, 3 Nov 2008 19:01:03 +0900
4Subject: [PATCH] DMI: Introduce dmi_first_match to make the interface more flexible
5References: bnc#441721
6
7Some notebooks from HP have the problem that their BIOSes attempt to
8spin down hard drives before entering ACPI system states S4 and S5.
9This leads to a yo-yo effect during system power-off shutdown and the
10last phase of hibernation when the disk is first spun down by the
11kernel and then almost immediately turned on and off by the BIOS.
12This, in turn, may result in shortening the disk's life times.
13
14To prevent this from happening we can blacklist the affected systems
15using DMI information. However, only the on-board controlles should
16be blacklisted and their PCI slot numbers can be used for this
17purpose. Unfortunately the existing interface for checking DMI
18information of the system is not very convenient for this purpose,
19because to use it, we would have to define special callback functions
20or create a separate struct dmi_system_id table for each blacklisted
21system.
22
23To overcome this difficulty introduce a new function
24dmi_first_match() returning a pointer to the first entry in an array
25of struct dmi_system_id elements that matches the system DMI
26information. Then, we can use this pointer to access the entry's
27.driver_data field containing the additional information, such as
28the PCI slot number, allowing us to do the desired blacklisting.
29
30Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
31Signed-off-by: Tejun Heo <tj@kernel.org>
32Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
33Signed-off-by: Tejun Heo <teheo@suse.de>
34---
35 drivers/firmware/dmi_scan.c | 68 +++++++++++++++++++++++++++++++++-----------
36 include/linux/dmi.h | 3 +
37 2 files changed, 55 insertions(+), 16 deletions(-)
38
39--- a/drivers/firmware/dmi_scan.c
40+++ b/drivers/firmware/dmi_scan.c
41@@ -407,6 +407,27 @@ void __init dmi_scan_machine(void)
42 }
43
44 /**
45+ * dmi_match - check if dmi_system_id structure matches system DMI data
46+ * @dmi: pointer to the dmi_system_id structure to check
47+ */
48+static bool dmi_match(const struct dmi_system_id *dmi)
49+{
50+ int i;
51+
52+ for (i = 0; i < ARRAY_SIZE(dmi->matches); i++) {
53+ int s = dmi->matches[i].slot;
54+ if (s == DMI_NONE)
55+ continue;
56+ if (dmi_ident[s]
57+ && strstr(dmi_ident[s], dmi->matches[i].substr))
58+ continue;
59+ /* No match */
60+ return false;
61+ }
62+ return true;
63+}
64+
65+/**
66 * dmi_check_system - check system DMI data
67 * @list: array of dmi_system_id structures to match against
68 * All non-null elements of the list must match
69@@ -421,30 +442,45 @@ void __init dmi_scan_machine(void)
70 */
71 int dmi_check_system(const struct dmi_system_id *list)
72 {
73- int i, count = 0;
74- const struct dmi_system_id *d = list;
75+ int count = 0;
76+ const struct dmi_system_id *d;
77
78- while (d->ident) {
79- for (i = 0; i < ARRAY_SIZE(d->matches); i++) {
80- int s = d->matches[i].slot;
81- if (s == DMI_NONE)
82- continue;
83- if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
84- continue;
85- /* No match */
86- goto fail;
87+ for (d = list; d->ident; d++)
88+ if (dmi_match(d)) {
89+ count++;
90+ if (d->callback && d->callback(d))
91+ break;
92 }
93- count++;
94- if (d->callback && d->callback(d))
95- break;
96-fail: d++;
97- }
98
99 return count;
100 }
101 EXPORT_SYMBOL(dmi_check_system);
102
103 /**
104+ * dmi_first_match - find dmi_system_id structure matching system DMI data
105+ * @list: array of dmi_system_id structures to match against
106+ * All non-null elements of the list must match
107+ * their slot's (field index's) data (i.e., each
108+ * list string must be a substring of the specified
109+ * DMI slot's string data) to be considered a
110+ * successful match.
111+ *
112+ * Walk the blacklist table until the first match is found. Return the
113+ * pointer to the matching entry or NULL if there's no match.
114+ */
115+const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list)
116+{
117+ const struct dmi_system_id *d;
118+
119+ for (d = list; d->ident; d++)
120+ if (dmi_match(d))
121+ return d;
122+
123+ return NULL;
124+}
125+EXPORT_SYMBOL(dmi_first_match);
126+
127+/**
128 * dmi_get_system_info - return DMI data value
129 * @field: data index (see enum dmi_field)
130 *
131--- a/include/linux/dmi.h
132+++ b/include/linux/dmi.h
133@@ -75,6 +75,7 @@ struct dmi_device {
134 #ifdef CONFIG_DMI
135
136 extern int dmi_check_system(const struct dmi_system_id *list);
137+const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list);
138 extern const char * dmi_get_system_info(int field);
139 extern const struct dmi_device * dmi_find_device(int type, const char *name,
140 const struct dmi_device *from);
141@@ -88,6 +89,8 @@ extern int dmi_walk(void (*decode)(const
142 #else
143
144 static inline int dmi_check_system(const struct dmi_system_id *list) { return 0; }
145+static inline const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list)
146+ { return NULL; }
147 static inline const char * dmi_get_system_info(int field) { return NULL; }
148 static inline const struct dmi_device * dmi_find_device(int type, const char *name,
149 const struct dmi_device *from) { return NULL; }