]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2008-01-22 Robert Millan <rmh@aybabtu.com>
authorrobertmh <robertmh@localhost>
Tue, 22 Jan 2008 20:13:14 +0000 (20:13 +0000)
committerrobertmh <robertmh@localhost>
Tue, 22 Jan 2008 20:13:14 +0000 (20:13 +0000)
        * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): When
        `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' flag is set, skip any
        device that doesn't look like an SD card.
        * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): Add
        `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' flag.
        * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_set_flag): Detect
        OLPC laptop, and set `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' when
        found.

ChangeLog
disk/ieee1275/ofdisk.c
include/grub/ieee1275/ieee1275.h
kern/powerpc/ieee1275/cmain.c

index ea293f27aea699365b3f51f3e9ed104dcab687bb..1a57fff208d969f21c7ae7139bbf7ba9945c45ca 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2008-01-22  Robert Millan  <rmh@aybabtu.com>
+
+       * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): When
+       `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' flag is set, skip any
+       device that doesn't look like an SD card.
+       * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): Add
+       `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' flag.
+       * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_set_flag): Detect
+       OLPC laptop, and set `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' when
+       found.
+
 2008-01-22  Robert Millan  <rmh@aybabtu.com>
 
        * kern/powerpc/ieee1275/init.c (grub_claim_heap): Add sanity check to
index e1b31b6d0d81c503e936960f3095ce75e73bbf68..d86d9532713f45ea82acd009ba7a68242b996e67 100644 (file)
@@ -30,6 +30,33 @@ grub_ofdisk_iterate (int (*hook) (const char *name))
 
   int dev_iterate (struct grub_ieee1275_devalias *alias)
     {
+      grub_dprintf ("disk", "disk name = %s\n", alias->name);
+
+      if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY))
+       {
+         grub_ieee1275_phandle_t dev;
+         char tmp[8];
+
+         if (grub_ieee1275_finddevice (alias->path, &dev))
+           {
+             grub_dprintf ("disk", "finddevice (%s) failed\n", alias->path);
+             return 0;
+           }
+
+         if (grub_ieee1275_get_property (dev, "iconname", tmp,
+                                         sizeof tmp, 0))
+           {
+             grub_dprintf ("disk", "get iconname failed\n");
+             return 0;
+           }
+
+         if (grub_strcmp (tmp, "sdmmc"))
+           {
+             grub_dprintf ("disk", "device is not an SD card\n");
+             return 0;
+           }
+       }
+
       if (! grub_strcmp (alias->type, "block"))
        hook (alias->name);
       else if ((! grub_strcmp (alias->type, "scsi"))
index e1cf0c4ba7ae2b6b49b82cbf05ff532872d744f1..008a114f6147974681c2a8f7ba957bb54eb74429 100644 (file)
@@ -83,6 +83,9 @@ enum grub_ieee1275_flag
 
   /* CodeGen firmware does not correctly implement "output-device output" */
   GRUB_IEEE1275_FLAG_BROKEN_OUTPUT,
+
+  /* OLPC / XO firmware hangs when accessing USB devices.  */
+  GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY,
 };
 
 extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag);
index 91e22b374693a56ab120d6e76f05badcd097bf2a..2b7cce56c6f6a4bc8ac4ddccf63324592ae53a4b 100644 (file)
@@ -49,27 +49,35 @@ grub_ieee1275_set_flag (enum grub_ieee1275_flag flag)
 static void
 grub_ieee1275_find_options (void)
 {
+  grub_ieee1275_phandle_t root;
   grub_ieee1275_phandle_t options;
   grub_ieee1275_phandle_t openprom;
   int rc;
   int realmode = 0;
   char tmp[32];
   int is_smartfirmware = 0;
+  int is_olpc = 0;
 
+  grub_ieee1275_finddevice ("/", &root);
   grub_ieee1275_finddevice ("/options", &options);
+  grub_ieee1275_finddevice ("/openprom", &openprom);
+
   rc = grub_ieee1275_get_integer_property (options, "real-mode?", &realmode,
                                           sizeof realmode, 0);
   if (((rc >= 0) && realmode) || (grub_ieee1275_mmu == 0))
     grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE);
 
-  grub_ieee1275_finddevice ("/openprom", &openprom);
-
   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;
 
+  rc = grub_ieee1275_get_property (root, "architecture",
+                                  tmp, sizeof (tmp), 0);
+  if (rc >= 0 && !grub_strcmp (tmp, "OLPC"))
+    is_olpc = 1;
+
   if (is_smartfirmware)
     {
       /* Broken in all versions */
@@ -101,6 +109,30 @@ grub_ieee1275_find_options (void)
            }
        }
     }
+
+  if (is_olpc)
+    {
+      /* OLPC / XO laptops have three kinds of storage devices:
+
+        - NAND flash.  These are accessible via OFW callbacks, but:
+          - Follow strange semantics, imposed by hardware constraints.
+          - Its ABI is undocumented, and not stable.
+          They lack "device_type" property, which conveniently makes GRUB
+          skip them.
+
+        - USB drives.  Not accessible, because OFW shuts down the controller
+          in order to prevent collisions with applications accessing it
+          directly.  Even worse, attempts to access it will NOT return
+          control to the caller, so we have to avoid probing them.
+
+        - SD cards.  These work fine.
+
+        To avoid brekage, we only need to skip USB probing.  However,
+        since detecting SD cards is more reliable, we do that instead.
+      */
+
+      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY);
+    }
 }
 
 void cmain (void);