From patchwork Sat May 30 16:25:05 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Henrique de Moraes Holschuh X-Patchwork-Id: 27057 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n4UGPPXI016404 for ; Sat, 30 May 2009 16:25:26 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751815AbZE3QZW (ORCPT ); Sat, 30 May 2009 12:25:22 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1759766AbZE3QZT (ORCPT ); Sat, 30 May 2009 12:25:19 -0400 Received: from out4.smtp.messagingengine.com ([66.111.4.28]:59680 "EHLO out4.smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751815AbZE3QZR (ORCPT ); Sat, 30 May 2009 12:25:17 -0400 Received: from compute2.internal (compute2.internal [10.202.2.42]) by out1.messagingengine.com (Postfix) with ESMTP id A10F93477D2; Sat, 30 May 2009 12:25:18 -0400 (EDT) Received: from heartbeat2.messagingengine.com ([10.202.2.161]) by compute2.internal (MEProxy); Sat, 30 May 2009 12:25:18 -0400 X-Sasl-enc: bFbNZFTypaO123j2S1mZ1TyFT8NE7UN8iUgGM61fpjWd 1243700718 Received: from khazad-dum.debian.net (unknown [201.82.166.239]) by mail.messagingengine.com (Postfix) with ESMTPSA id 2782833A85; Sat, 30 May 2009 12:25:18 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by localhost.khazad-dum.debian.net (Postfix) with ESMTP id 8D1A828271; Sat, 30 May 2009 13:25:16 -0300 (BRT) X-Virus-Scanned: Debian amavisd-new at khazad-dum.debian.net Received: from khazad-dum.debian.net ([127.0.0.1]) by localhost (khazad-dum.debian.net [127.0.0.1]) (amavisd-new, port 10024) with LMTP id kuhMzR2vv33P; Sat, 30 May 2009 13:25:15 -0300 (BRT) Received: by khazad-dum.debian.net (Postfix, from userid 1000) id 696F42826B; Sat, 30 May 2009 13:25:15 -0300 (BRT) From: Henrique de Moraes Holschuh To: Len Brown Cc: linux-acpi@vger.kernel.org, ibm-acpi-devel@lists.sourceforge.net, Henrique de Moraes Holschuh Subject: [PATCH 1/5] thinkpad-acpi: store fw version with strict checking Date: Sat, 30 May 2009 13:25:05 -0300 Message-Id: <1243700709-25977-2-git-send-email-hmh@hmh.eng.br> X-Mailer: git-send-email 1.6.3.1 In-Reply-To: <1243700709-25977-1-git-send-email-hmh@hmh.eng.br> References: <1243700709-25977-1-git-send-email-hmh@hmh.eng.br> Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org Extend the thinkpad model and firmware identification data with the release serial number for the BIOS and firmware (when available), as that is easier to parse and compare than the version strings. We're going to greatly extend the use of the ThinkPad DMI data through quirk lists, so it is best to be quite strict and make sure what we get from DMI is exactly what we expect, otherwise quirk matching may result in quite insane things. IBM (and Lenovo, at least for the ThinkPad line) uses this schema for firmware versioning and model: Firmware model: Two digits, [0-9A-Z] Firmware version: AABBCCDD, where AA = firmware model, see above BB = "ET" for BIOS, "HT" for EC CC = release version, two digits, [0-9A-Z], "00" < "09" < "0A" < "10" < "A0" < "ZZ" DD = "WW" Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 46 +++++++++++++++++++++++++++++++--- 1 files changed, 42 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 912be65..d2a0ef8 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -284,8 +284,10 @@ struct thinkpad_id_data { char *bios_version_str; /* Something like 1ZET51WW (1.03z) */ char *ec_version_str; /* Something like 1ZHT51WW-1.04a */ - u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */ + u16 bios_model; /* 1Y = 0x5931, 0 = unknown */ u16 ec_model; + u16 bios_release; /* 1ZETK1WW = 0x314b, 0 = unknown */ + u16 ec_release; char *model_str; /* ThinkPad T43 */ char *nummodel_str; /* 9384A9C for a 9384-A9C model */ @@ -7357,6 +7359,24 @@ err_out: /* Probing */ +static bool __pure __init tpacpi_is_fw_digit(const char c) +{ + return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z'); +} + +/* Most models: xxyTkkWW (#.##c); Ancient 570/600 and -SL lacks (#.##c) */ +static bool __pure __init tpacpi_is_valid_fw_id(const char* const s, + const char t) +{ + return s && strlen(s) >= 8 && + tpacpi_is_fw_digit(s[0]) && + tpacpi_is_fw_digit(s[1]) && + s[2] == t && s[3] == 'T' && + tpacpi_is_fw_digit(s[4]) && + tpacpi_is_fw_digit(s[5]) && + s[6] == 'W' && s[7] == 'W'; +} + /* returns 0 - probe ok, or < 0 - probe error. * Probe ok doesn't mean thinkpad found. * On error, kfree() cleanup on tp->* is not performed, caller must do it */ @@ -7383,10 +7403,15 @@ static int __must_check __init get_thinkpad_model_data( tp->bios_version_str = kstrdup(s, GFP_KERNEL); if (s && !tp->bios_version_str) return -ENOMEM; - if (!tp->bios_version_str) + + /* Really ancient ThinkPad 240X will fail this, which is fine */ + if (!tpacpi_is_valid_fw_id(tp->bios_version_str, 'E')) return 0; + tp->bios_model = tp->bios_version_str[0] | (tp->bios_version_str[1] << 8); + tp->bios_release = (tp->bios_version_str[4] << 8) + | tp->bios_version_str[5]; /* * ThinkPad T23 or newer, A31 or newer, R50e or newer, @@ -7405,8 +7430,21 @@ static int __must_check __init get_thinkpad_model_data( tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL); if (!tp->ec_version_str) return -ENOMEM; - tp->ec_model = ec_fw_string[0] - | (ec_fw_string[1] << 8); + + if (tpacpi_is_valid_fw_id(ec_fw_string, 'H')) { + tp->ec_model = ec_fw_string[0] + | (ec_fw_string[1] << 8); + tp->ec_release = (ec_fw_string[4] << 8) + | ec_fw_string[5]; + } else { + printk(TPACPI_NOTICE + "ThinkPad firmware release %s " + "doesn't match the known patterns\n", + ec_fw_string); + printk(TPACPI_NOTICE + "please report this to %s\n", + TPACPI_MAIL); + } break; } }