2007-09-05 Robert Millan * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_test_flag): Detect SmartFirmware version updates (as released by Sven Luther), and avoid setting GRUB_IEEE1275_FLAG_NO_PARTITION_0 or GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS unless the running version is known broken. diff -ur grub2/kern/powerpc/ieee1275/cmain.c grub2.pegasos/kern/powerpc/ieee1275/cmain.c --- grub2/kern/powerpc/ieee1275/cmain.c 2007-07-22 11:16:51.000000000 +0200 +++ grub2.pegasos/kern/powerpc/ieee1275/cmain.c 2007-09-05 20:07:00.000000000 +0200 @@ -30,9 +30,9 @@ grub_ieee1275_phandle_t grub_ieee1275_chosen; static grub_uint32_t grub_ieee1275_flags; - + int grub_ieee1275_test_flag (enum grub_ieee1275_flag flag) { @@ -52,6 +52,8 @@ grub_ieee1275_phandle_t openprom; int rc; int realmode = 0; + char tmp[32]; + int is_smartfirmware = 0; grub_ieee1275_finddevice ("/options", &options); rc = grub_ieee1275_get_property (options, "real-mode?", &realmode, @@ -60,12 +62,42 @@ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE); grub_ieee1275_finddevice ("/openprom", &openprom); - rc = grub_ieee1275_get_property (openprom, "SmartFirmware-version", 0, 0, 0); - if (rc >= 0) + + rc = grub_ieee1275_get_property (openprom, "CodeGen-copyright", + tmp, sizeof (tmp), 0); +#define SF "SmartFirmware(tm)" + if (rc >= 0 && !grub_strncmp (tmp, SF, sizeof (SF) - 1)) + is_smartfirmware = 1; + + if (is_smartfirmware) { - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0); - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS); + /* Broken in all versions */ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT); + + /* There are two incompatible ways of checking the version number. Try + both. */ + rc = grub_ieee1275_get_property (openprom, "SmartFirmware-version", + tmp, sizeof (tmp), 0); + if (rc < 0) + rc = grub_ieee1275_get_property (openprom, "firmware-version", + tmp, sizeof (tmp), 0); + if (rc >= 0) + { + /* It is tempting to implement a version parser to fail for e.g. anything + below 1.3. However, there's a special situation here. 3rd party + updates which fix the partition bugs are common, and for some reason + their fixes aren't being merged into trunk. So for example we know + that 1.2 and 1.3 are broken, but there's 1.2.99 and 1.3.99 which are + known good (and appliing this workaround would cause breakage). */ + if (!grub_strcmp (tmp, "1.0") + || !grub_strcmp (tmp, "1.1") + || !grub_strcmp (tmp, "1.2") + || !grub_strcmp (tmp, "1.3")) + { + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0); + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS); + } + } } }