Fix deadlock when probing USB deives on i386-ieee1275. Detailed explanation
is in patch itself (C comment).
Comments?
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
* 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.
diff -urp grub2/disk/ieee1275/ofdisk.c usb/disk/ieee1275/ofdisk.c
--- grub2/disk/ieee1275/ofdisk.c 2008-01-14 05:16:20.000000000 +0100
+++ usb/disk/ieee1275/ofdisk.c 2008-01-20 22:14:55.000000000 +0100
@@ -30,6 +30,33 @@ grub_ofdisk_iterate (int (*hook) (const
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"))
diff -urp grub2/include/grub/ieee1275/ieee1275.h usb/include/grub/ieee1275/ieee1275.h
--- grub2/include/grub/ieee1275/ieee1275.h 2008-01-20 15:08:14.000000000 +0100
+++ usb/include/grub/ieee1275/ieee1275.h 2008-01-20 22:14:55.000000000 +0100
@@ -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);
diff -urp grub2/kern/powerpc/ieee1275/cmain.c usb/kern/powerpc/ieee1275/cmain.c
--- grub2/kern/powerpc/ieee1275/cmain.c 2008-01-20 15:08:14.000000000 +0100
+++ usb/kern/powerpc/ieee1275/cmain.c 2008-01-20 22:14:55.000000000 +0100
@@ -49,27 +49,35 @@ grub_ieee1275_set_flag (enum grub_ieee12
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);
_______________________________________________
Grub-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/grub-devel