From d1923dc8f21c2f3eea033aba4472b6c4e07ea71a Mon Sep 17 00:00:00 2001 From: hollisb Date: Wed, 13 Oct 2004 23:43:44 +0000 Subject: [PATCH] 2004-10-13 Hollis Blanchard * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_iterate): Call grub_children_iterate for device nodes of type `scsi', `ide', or `ata'. (grub_ofdisk_open): Remove manual device alias resolution. Fix memory leak when device cannot be opened. * include/grub/powerpc/ieee1275/ieee1275.h (grub_children_iterate): New prototype. * kern/powerpc/ieee1275/openfw.c (grub_children_iterate): New function. * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_get_property): Return -1 if args.size was -1. --- ChangeLog | 14 +++++++ boot/powerpc/ieee1275/ieee1275.c | 2 + disk/powerpc/ieee1275/ofdisk.c | 23 +++++----- include/grub/powerpc/ieee1275/ieee1275.h | 2 + kern/powerpc/ieee1275/openfw.c | 53 ++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index a0e3e40e0..485327fd5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2004-10-13 Hollis Blanchard + + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_iterate): + Call grub_children_iterate for device nodes of type `scsi', + `ide', or `ata'. + (grub_ofdisk_open): Remove manual device alias resolution. + Fix memory leak when device cannot be opened. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_children_iterate): New prototype. + * kern/powerpc/ieee1275/openfw.c (grub_children_iterate): + New function. + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_get_property): + Return -1 if args.size was -1. + 2004-10-11 Hollis Blanchard * boot/powerpc/ieee1275/cmain.c (grub_ieee1275_flags): New global. diff --git a/boot/powerpc/ieee1275/ieee1275.c b/boot/powerpc/ieee1275/ieee1275.c index 93bdfcfac..dcf88cd18 100644 --- a/boot/powerpc/ieee1275/ieee1275.c +++ b/boot/powerpc/ieee1275/ieee1275.c @@ -98,6 +98,8 @@ grub_ieee1275_get_property (grub_ieee1275_phandle_t handle, return -1; if (actual) *actual = args.size; + if (args.size == -1) + return -1; return 0; } diff --git a/disk/powerpc/ieee1275/ofdisk.c b/disk/powerpc/ieee1275/ofdisk.c index b70d89312..10334499d 100644 --- a/disk/powerpc/ieee1275/ofdisk.c +++ b/disk/powerpc/ieee1275/ofdisk.c @@ -30,6 +30,11 @@ grub_ofdisk_iterate (int (*hook) (const char *name)) { if (! grub_strcmp (alias->type, "block")) hook (alias->name); + else if ((! grub_strcmp (alias->type, "scsi")) + || (! grub_strcmp (alias->type, "ide")) + || (! grub_strcmp (alias->type, "ata"))) + /* Search for block-type children of these bus controllers. */ + grub_children_iterate (alias->name, dev_iterate); return 0; } @@ -40,31 +45,25 @@ grub_ofdisk_iterate (int (*hook) (const char *name)) static grub_err_t grub_ofdisk_open (const char *name, grub_disk_t disk) { - grub_ieee1275_phandle_t devalias; grub_ieee1275_phandle_t dev; grub_ieee1275_ihandle_t dev_ihandle = 0; char *devpath = 0; /* XXX: This should be large enough for any possible case. */ char prop[64]; - grub_size_t pathlen; int actual; - if (grub_ieee1275_finddevice ("/aliases", &devalias)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't read the aliases"); - - grub_ieee1275_get_property_length (devalias, name, &pathlen); - devpath = grub_malloc (pathlen); + devpath = grub_strndup (name, grub_strlen (devpath) + 2); if (! devpath) return grub_errno; - if (grub_ieee1275_get_property (devalias, name, devpath, pathlen, &actual)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device alias"); - /* To access the complete disk add `:0'. */ grub_strcat (devpath, ":0"); grub_ieee1275_open (devpath, &dev_ihandle); if (! dev_ihandle) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device"); + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device"); + goto fail; + } if (grub_ieee1275_finddevice (devpath, &dev)) { @@ -99,7 +98,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) disk->data = (void *) dev_ihandle; fail: - if (grub_errno) + if (grub_errno && dev_ihandle) grub_ieee1275_close (dev_ihandle); grub_free (devpath); return grub_errno; diff --git a/include/grub/powerpc/ieee1275/ieee1275.h b/include/grub/powerpc/ieee1275/ieee1275.h index 35ae94d71..cfcf286a7 100644 --- a/include/grub/powerpc/ieee1275/ieee1275.h +++ b/include/grub/powerpc/ieee1275/ieee1275.h @@ -101,6 +101,8 @@ int EXPORT_FUNC(grub_ieee1275_set_color) (grub_ieee1275_ihandle_t ihandle, grub_err_t EXPORT_FUNC(grub_devalias_iterate) (int (*hook) (struct grub_ieee1275_devalias *alias)); +grub_err_t EXPORT_FUNC(grub_children_iterate) (char *devpath, + int (*hook) (struct grub_ieee1275_devalias *alias)); #endif /* ! GRUB_IEEE1275_MACHINE_HEADER */ diff --git a/kern/powerpc/ieee1275/openfw.c b/kern/powerpc/ieee1275/openfw.c index eb741a7b1..43297835f 100644 --- a/kern/powerpc/ieee1275/openfw.c +++ b/kern/powerpc/ieee1275/openfw.c @@ -23,6 +23,59 @@ #include #include +/* Walk children of 'devpath', calling hook for each. */ +grub_err_t +grub_children_iterate (char *devpath, + int (*hook) (struct grub_ieee1275_devalias *alias)) +{ + grub_ieee1275_phandle_t dev; + grub_ieee1275_phandle_t child; + + grub_ieee1275_finddevice (devpath, &dev); + if (dev == -1) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown device"); + + grub_ieee1275_child (dev, &child); + if (child == -1) + return grub_error (GRUB_ERR_BAD_DEVICE, "Device has no children"); + + do + { + /* XXX: Don't use hardcoded path lengths. */ + char childtype[64]; + char childpath[64]; + char childname[64]; + char fullname[64]; + struct grub_ieee1275_devalias alias; + int actual; + + grub_ieee1275_get_property (child, "device_type", &childtype, + sizeof childtype, &actual); + if (actual == -1) + continue; + + grub_ieee1275_package_to_path (child, childpath, sizeof childpath, + &actual); + if (actual == -1) + continue; + + grub_ieee1275_get_property (child, "name", &childname, + sizeof childname, &actual); + if (actual == -1) + continue; + + grub_sprintf(fullname, "%s/%s", devpath, childname); + + alias.type = childtype; + alias.path = childpath; + alias.name = fullname; + hook (&alias); + } + while (grub_ieee1275_peer (child, &child)); + + return 0; +} + /* Iterate through all device aliasses. Thisfunction can be used to find a device of a specific type. */ grub_err_t