/* * OPAL update flash */ static int opal_flash_update(int op) { struct opal_sg_list *list; unsigned long addr; int64_t rc = OPAL_PARAMETER; if (op == FLASH_UPDATE_CANCEL) { pr_alert("FLASH: Image update cancelled\n"); addr = '\0'; goto flash; } list = opal_vmalloc_to_sg_list(image_data.data, image_data.size); if (!list) goto invalid_img; /* First entry address */ addr = __pa(list); flash: rc = opal_update_flash(addr); invalid_img: return rc; }
/* * OPAL update flash */ static int opal_flash_update(int op) { struct opal_sg_list *sg, *list, *next; unsigned long addr; int64_t rc = OPAL_PARAMETER; if (op == FLASH_UPDATE_CANCEL) { pr_alert("FLASH: Image update cancelled\n"); addr = '\0'; goto flash; } list = image_data_to_sglist(); if (!list) goto invalid_img; /* First entry address */ addr = __pa(list); /* Translate sg list address to absolute */ for (sg = list; sg; sg = next) { next = sg->next; /* Don't translate NULL pointer for last entry */ if (sg->next) sg->next = (struct opal_sg_list *)__pa(sg->next); else sg->next = NULL; /* * Convert num_entries to version/length format * to satisfy OPAL. */ sg->num_entries = (SG_LIST_VERSION << 56) | (sg->num_entries * sizeof(struct opal_sg_entry) + 16); } pr_alert("FLASH: Image is %u bytes\n", image_data.size); pr_alert("FLASH: Image update requested\n"); pr_alert("FLASH: Image will be updated during system reboot\n"); pr_alert("FLASH: This will take several minutes. Do not power off!\n"); flash: rc = opal_update_flash(addr); invalid_img: return rc; }