static void grub_ieee1275_net_config_real (const char *devpath, char **device, char **path) { struct grub_net_card *card; /* FIXME: Check that it's the right card. */ FOR_NET_CARDS (card) { char *bootp_response; char *cardpath; char *canon; grub_ssize_t size = -1; unsigned int i; if (card->driver != &ofdriver) continue; cardpath = ((struct grub_ofnetcard_data *) card->data)->path; canon = grub_ieee1275_canonicalise_devname (cardpath); if (grub_strcmp (devpath, canon) != 0) { grub_free (canon); continue; } grub_free (canon); for (i = 0; i < ARRAY_SIZE (bootp_response_properties); i++) if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, bootp_response_properties[i].name, &size) >= 0) break; if (size < 0) return; bootp_response = grub_malloc (size); if (!bootp_response) { grub_print_error (); return; } if (grub_ieee1275_get_property (grub_ieee1275_chosen, bootp_response_properties[i].name, bootp_response, size, 0) < 0) return; grub_net_configure_by_dhcp_ack (card->name, card, 0, (struct grub_net_bootp_packet *) &bootp_response + bootp_response_properties[i].offset, size - bootp_response_properties[i].offset, 1, device, path); return; } }
static void insert_bootpath (void) { char *bootpath; grub_ssize_t bootpath_size; char *type; if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath", &bootpath_size) || bootpath_size <= 0) { /* Should never happen. */ grub_printf ("/chosen/bootpath property missing!\n"); return; } bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); if (! bootpath) { grub_print_error (); return; } grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath, (grub_size_t) bootpath_size + 1, 0); bootpath[bootpath_size] = '\0'; /* Transform an OF device path to a GRUB path. */ type = grub_ieee1275_get_device_type (bootpath); if (!(type && grub_strcmp (type, "network") == 0)) { struct ofdisk_hash_ent *op; char *device = grub_ieee1275_get_devname (bootpath); op = ofdisk_hash_add (device, NULL); op->is_boot = 1; } grub_free (type); grub_free (bootpath); }
/* Iterate through all device aliases. This function can be used to find a device of a specific type. */ grub_err_t grub_devalias_iterate (int (*hook) (struct grub_ieee1275_devalias *alias)) { grub_ieee1275_phandle_t aliases; char aliasname[32]; int actual; struct grub_ieee1275_devalias alias; if (grub_ieee1275_finddevice ("/aliases", &aliases)) return -1; /* Find the first property. */ aliasname[0] = '\0'; while (grub_ieee1275_next_property (aliases, aliasname, aliasname)) { grub_ieee1275_phandle_t dev; grub_ssize_t pathlen; char *devpath; /* XXX: This should be large enough for any possible case. */ char devtype[64]; grub_dprintf ("devalias", "devalias name = %s\n", aliasname); grub_ieee1275_get_property_length (aliases, aliasname, &pathlen); /* The property `name' is a special case we should skip. */ if (!grub_strcmp (aliasname, "name")) continue; devpath = grub_malloc (pathlen); if (! devpath) return grub_errno; if (grub_ieee1275_get_property (aliases, aliasname, devpath, pathlen, &actual)) { grub_dprintf ("devalias", "get_property (%s) failed\n", aliasname); goto nextprop; } if (grub_ieee1275_finddevice (devpath, &dev)) { grub_dprintf ("devalias", "finddevice (%s) failed\n", devpath); goto nextprop; } if (grub_ieee1275_get_property (dev, "device_type", devtype, sizeof devtype, &actual)) { /* NAND device don't have device_type property. */ devtype[0] = 0; } alias.name = aliasname; alias.path = devpath; alias.type = devtype; hook (&alias); nextprop: grub_free (devpath); } return 0; }
/* Iterate through all device aliases. This function can be used to find a device of a specific type. */ int grub_devalias_iterate (int (*hook) (struct grub_ieee1275_devalias *alias, void *closure), void *closure) { grub_ieee1275_phandle_t aliases; char *aliasname, *devtype; grub_ssize_t actual; struct grub_ieee1275_devalias alias; int ret = 0; if (grub_ieee1275_finddevice ("/aliases", &aliases)) return 0; aliasname = grub_malloc (IEEE1275_MAX_PROP_LEN); if (!aliasname) return 0; devtype = grub_malloc (IEEE1275_MAX_PROP_LEN); if (!devtype) { grub_free (aliasname); return 0; } /* Find the first property. */ aliasname[0] = '\0'; while (grub_ieee1275_next_property (aliases, aliasname, aliasname) > 0) { grub_ieee1275_phandle_t dev; grub_ssize_t pathlen; char *devpath; if (! aliasname[0]) break; grub_dprintf ("devalias", "devalias name = %s\n", aliasname); grub_ieee1275_get_property_length (aliases, aliasname, &pathlen); /* The property `name' is a special case we should skip. */ if (!grub_strcmp (aliasname, "name")) continue; /* Sun's OpenBoot often doesn't zero terminate the device alias strings, so we will add a NULL byte at the end explicitly. */ pathlen += 1; devpath = grub_malloc (pathlen); if (! devpath) { grub_free (devtype); grub_free (aliasname); return 0; } if (grub_ieee1275_get_property (aliases, aliasname, devpath, pathlen, &actual)) { grub_dprintf ("devalias", "get_property (%s) failed\n", aliasname); goto nextprop; } devpath [actual] = '\0'; if (grub_ieee1275_finddevice (devpath, &dev)) { grub_dprintf ("devalias", "finddevice (%s) failed\n", devpath); goto nextprop; } if (grub_ieee1275_get_property (dev, "device_type", devtype, IEEE1275_MAX_PROP_LEN, &actual)) { /* NAND device don't have device_type property. */ devtype[0] = 0; } alias.name = aliasname; alias.path = devpath; alias.type = devtype; ret = hook (&alias, closure); nextprop: grub_free (devpath); if (ret) break; } grub_free (devtype); grub_free (aliasname); return ret; }
void grub_machine_get_bootlocation (char **device, char **path) { char *bootpath; grub_ssize_t bootpath_size; char *filename; char *type; if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath", &bootpath_size) || bootpath_size <= 0) { /* Should never happen. */ grub_printf ("/chosen/bootpath property missing!\n"); return; } bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); if (! bootpath) { grub_print_error (); return; } grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath, (grub_size_t) bootpath_size + 1, 0); bootpath[bootpath_size] = '\0'; /* Transform an OF device path to a GRUB path. */ type = grub_ieee1275_get_device_type (bootpath); if (type && grub_strcmp (type, "network") == 0) { char *dev, *canon; char *ptr; dev = grub_ieee1275_get_aliasdevname (bootpath); canon = grub_ieee1275_canonicalise_devname (dev); ptr = canon + grub_strlen (canon) - 1; while (ptr > canon && (*ptr == ',' || *ptr == ':')) ptr--; ptr++; *ptr = 0; if (grub_ieee1275_net_config) grub_ieee1275_net_config (canon, device, path, bootpath); grub_free (dev); grub_free (canon); } else *device = grub_ieee1275_encode_devname (bootpath); grub_free (type); filename = grub_ieee1275_get_filename (bootpath); if (filename) { char *lastslash = grub_strrchr (filename, '\\'); /* Truncate at last directory. */ if (lastslash) { *lastslash = '\0'; grub_translate_ieee1275_path (filename); *path = filename; } } grub_free (bootpath); }