[ltp] FYI: ThinkPad firmware model numbering

Henrique de Moraes Holschuh linux-thinkpad@linux-thinkpad.org
Thu, 19 Oct 2006 12:30:28 -0300


I have commited since yesterday some changes to ThinkWiki pages to help
driver developers group ThinkPads from a "it uses the same BIOS and EC
binaries" point of view.

If you want, you can refer to ThinkPads by their firmware model when it
makes sense to do so (which is almost always when you are writing a driver
:-)).  Note that for HDAPS accelerometer orientation, it may well be that it
does not help and we will have to go even more specific and match on DMI
baseboard-product-name or system-product-name.

The firmware model is the kind of stuff we should use in HDAPS, tp_smapi,
and ibm-acpi quirk/white/black lists dealing with behaviour specific to
certain firmware versions, though.  After all, there are in fact two
different things called "T43", and two different things called "R52".

The firmware model is nothing more than the three characters "TP-", followed
by the first two characters of the BIOS (or EC firmware -- it is the same as
the BIOS) version.  The "TP-" prefix comes from the ACPI OEM Table ID in the
ACPI DSDT table.  AFAIK, it stands for "ThinkPad".

When we find a software bug that applies to the T43 18xx, it is in fact a
bug on BIOS 70ET??WW and/or EC firmware 70HT??WW, i.e. on firmware model
TP-70.  This means the R52 models 1858, 1859, 1860, 1861, 1862, 1863 would
also be affected by the same bug, as they are also model TP-70.

Here's some interesting links for helpful information re. ThinkPad firmware:
http://thinkwiki.org/wiki/List_of_DMI_IDs (dmi information table)
http://www.thinkwiki.org/wiki/BIOS_Upgrade_Downloads (very good model list)
http://www.thinkwiki.org/wiki/Embedded_Controller_Firmware (firmware bugs)

Drive writer notes: you can find the firmware model from DMI information.
You should use either the bios version field (when dealing with ACPI DSDT,
or other BIOS things) or the thinkpad embedded controller field (when
dealing with the EC).

Here's some example (Linux kernel 2.6.19-rc) code to extract the Embedded
Controller firmware version.  Extracting the BIOS version is left as an
exercise to the reader.

char* check_dmi_for_ec(void)
{
        struct dmi_device *dev = NULL;
        char ec_fw_string[18];

        /*
         * ThinkPad T23 or newer, A31 or newer, R50e or newer,
         * X32 or newer, all Z series;  Some models must have an
         * up-to-date BIOS or they will not be detected.
         *
         * See http://thinkwiki.org/wiki/List_of_DMI_IDs
         */
        while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
                if (sscanf(dev->name,
                                "IBM ThinkPad Embedded Controller -[%17c",
                                ec_fw_string) == 1) {
                        ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
                        ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
                        return kstrdup(ec_fw_string, GFP_KERNEL);
                }
        }
        return NULL;
}

When using EC version strings for matches, keep in mind that they are on the
following format:

	xxyyzzkk-<version>

	Where:	xx is the firmware model. Always match on it.
		yy is "HT" for all firmware. Better match on it.
		zz is the public build number.  It is better to
			use <version> instead when doing matches.
		kk is some crap to be ignored. So far, only "WW"
			has been seen (maybe it is different on
			beta versions and non-public versions).
		<version> is a regular numeric version string,
			followed by an optional letter (usually in
			low caps) denoting a patch level. 

	So far, all known <version> strings match the regexp
		[0-9][.][0-9][0-9][a-z ]
		(Note the space used as placeholder if no patch
		level is present!)

When using BIOS version strings for matches, keep in mind that they are on
the following format:

	xxyyzzkk (<version>)

	Where:
		yy is "ET" for all BIOS. Better match on it.

		everything else is the same as in the EC version
		string. Note that <version> is between (),
		and that it *does* include the placeholder space
		for the patch level inside the ().

-- 
  "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