From: Tejun Heo <tj@kernel.org>
To: jeff@garzik.org, linux-ide@vger.kernel.org
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>, Tejun Heo <tj@kernel.org>
Subject: [PATCH 2/8] DMI: Introduce dmi_first_match to make the interface more flexible
Date: Mon, 3 Nov 2008 19:01:03 +0900 [thread overview]
Message-ID: <1225706469-27870-3-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1225706469-27870-1-git-send-email-tj@kernel.org>
From: Rafael J. Wysocki <rjw@sisk.pl>
Some notebooks from HP have the problem that their BIOSes attempt to
spin down hard drives before entering ACPI system states S4 and S5.
This leads to a yo-yo effect during system power-off shutdown and the
last phase of hibernation when the disk is first spun down by the
kernel and then almost immediately turned on and off by the BIOS.
This, in turn, may result in shortening the disk's life times.
To prevent this from happening we can blacklist the affected systems
using DMI information. However, only the on-board controlles should
be blacklisted and their PCI slot numbers can be used for this
purpose. Unfortunately the existing interface for checking DMI
information of the system is not very convenient for this purpose,
because to use it, we would have to define special callback functions
or create a separate struct dmi_system_id table for each blacklisted
system.
To overcome this difficulty introduce a new function
dmi_first_match() returning a pointer to the first entry in an array
of struct dmi_system_id elements that matches the system DMI
information. Then, we can use this pointer to access the entry's
.driver_data field containing the additional information, such as
the PCI slot number, allowing us to do the desired blacklisting.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/firmware/dmi_scan.c | 74 ++++++++++++++++++++++++++++++++-----------
include/linux/dmi.h | 1 +
2 files changed, 56 insertions(+), 19 deletions(-)
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 3e526b6..6e88b99 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -415,6 +415,27 @@ void __init dmi_scan_machine(void)
}
/**
+ * dmi_match - check if dmi_system_id structure matches system DMI data
+ * @dmi: pointer to the dmi_system_id structure to check
+ */
+static bool dmi_match(const struct dmi_system_id *dmi)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dmi->matches); i++) {
+ int s = dmi->matches[i].slot;
+ if (s == DMI_NONE)
+ continue;
+ if (dmi_ident[s]
+ && strstr(dmi_ident[s], dmi->matches[i].substr))
+ continue;
+ /* No match */
+ return false;
+ }
+ return true;
+}
+
+/**
* dmi_check_system - check system DMI data
* @list: array of dmi_system_id structures to match against
* All non-null elements of the list must match
@@ -429,32 +450,47 @@ void __init dmi_scan_machine(void)
*/
int dmi_check_system(const struct dmi_system_id *list)
{
- int i, count = 0;
- const struct dmi_system_id *d = list;
-
- WARN(!dmi_initialized, KERN_ERR "dmi check: not initialized yet.\n");
-
- while (d->ident) {
- for (i = 0; i < ARRAY_SIZE(d->matches); i++) {
- int s = d->matches[i].slot;
- if (s == DMI_NONE)
- continue;
- if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
- continue;
- /* No match */
- goto fail;
+ int count = 0;
+ const struct dmi_system_id *d;
+
+ for (d = list; d->ident; d++)
+ if (dmi_match(d)) {
+ count++;
+ if (d->callback && d->callback(d))
+ break;
}
- count++;
- if (d->callback && d->callback(d))
- break;
-fail: d++;
- }
return count;
}
EXPORT_SYMBOL(dmi_check_system);
/**
+ * dmi_first_match - find dmi_system_id structure matching system DMI data
+ * @list: array of dmi_system_id structures to match against
+ * All non-null elements of the list must match
+ * their slot's (field index's) data (i.e., each
+ * list string must be a substring of the specified
+ * DMI slot's string data) to be considered a
+ * successful match.
+ *
+ * Walk the blacklist table until the first match is found. Return the
+ * pointer to the matching entry or NULL if there's no match.
+ */
+const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list)
+{
+ const struct dmi_system_id *d;
+
+ WARN(!dmi_initialized, KERN_ERR "dmi check: not initialized yet.\n");
+
+ for (d = list; d->ident; d++)
+ if (dmi_match(d))
+ return d;
+
+ return NULL;
+}
+EXPORT_SYMBOL(dmi_first_match);
+
+/**
* dmi_get_system_info - return DMI data value
* @field: data index (see enum dmi_field)
*
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index e5084eb..6e20820 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -38,6 +38,7 @@ struct dmi_device {
#ifdef CONFIG_DMI
extern int dmi_check_system(const struct dmi_system_id *list);
+const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list);
extern const char * dmi_get_system_info(int field);
extern const struct dmi_device * dmi_find_device(int type, const char *name,
const struct dmi_device *from);
--
1.5.4.5
next prev parent reply other threads:[~2008-11-03 10:01 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-03 10:01 [PATCHSET #upstream-fixes] patches which fell off the crack during maintainership handover Tejun Heo
2008-11-03 10:01 ` [PATCH 1/8] Hibernation: Introduce system_entering_hibernation Tejun Heo
2008-11-04 6:14 ` Jeff Garzik
2008-11-03 10:01 ` Tejun Heo [this message]
2008-11-03 10:01 ` [PATCH 3/8] SATA: Blacklisting of systems that spin off disks during ACPI power off (rev. 2) Tejun Heo
2008-11-03 10:01 ` [PATCH 4/8] SATA AHCI: Blacklist system that spins off disks during ACPI power off Tejun Heo
2008-11-03 10:01 ` [PATCH 5/8] SATA Sil: " Tejun Heo
2008-11-03 10:01 ` [PATCH 6/8] SATA PIIX: " Tejun Heo
2008-11-03 10:01 ` [PATCH 7/8] libata: Fix a potential race condition in ata_scsi_park_show() Tejun Heo
2008-11-04 6:10 ` Jeff Garzik
2008-11-03 10:01 ` [PATCH 8/8] libata: implement ATA_HORKAGE_ATAPI_MOD16_DMA and apply it Tejun Heo
2008-11-04 6:11 ` Jeff Garzik
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1225706469-27870-3-git-send-email-tj@kernel.org \
--to=tj@kernel.org \
--cc=jeff@garzik.org \
--cc=linux-ide@vger.kernel.org \
--cc=rjw@sisk.pl \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).