@@ -36,6 +36,8 @@
#define PROM_INVALID_HANDLE ((prom_handle)-1UL)
#define BOOTDEVSZ (2048) /* iscsi args can be in excess of 1040 bytes */
#define TOK_ISCSI "iscsi"
+#define BOOTLASTSZ 1024
+#define FW_NBR_REBOOTSZ 4
struct prom_args;
typedef int (*prom_entry)(struct prom_args *);
@@ -93,6 +95,7 @@
prom_handle prom_finddevice (char *name);
prom_handle prom_findpackage (char *path);
int prom_getprop (prom_handle dev, char *name, void *buf, int len);
+int prom_setprop (prom_handle dev, char *name, void *buf, int len);
int prom_get_devtype (char *device);
/* misc */
@@ -108,6 +111,7 @@
int prom_get_chosen (char *name, void *mem, int len);
int prom_get_options (char *name, void *mem, int len);
+int prom_set_options (char *name, void *mem, int len);
extern int prom_getms(void);
extern void prom_pause(void);
Only in yaboot-1.3.13/include: prom.h.orig
Only in yaboot-1.3.13/include: prom.h.rej
Only in yaboot-1.3.13/second: addnote
@@ -154,6 +154,13 @@
}
int
+prom_setprop (prom_handle pack, char *name, void *mem, int len)
+{
+ return (int)call_prom ("setprop", 4, 1, pack, name, mem, len);
+}
+
+
+int
prom_get_chosen (char *name, void *mem, int len)
{
return prom_getprop (prom_chosen, name, mem, len);
@@ -168,6 +175,15 @@
}
int
+prom_set_options (char *name, void *mem, int len)
+{
+ if (prom_options == (void *)-1)
+ return -1;
+ return prom_setprop (prom_options, name, mem, len);
+}
+
+
+int
prom_get_devtype (char *device)
{
phandle dev;
@@ -113,6 +113,9 @@
int useconf = 0;
char bootdevice[BOOTDEVSZ];
char bootargs[1024];
+char bootlastlabel[BOOTLASTSZ] = {0};
+char fw_nbr_reboots[FW_NBR_REBOOTSZ] = {0};
+long fw_reboot_cnt = 0;
char *password = NULL;
struct boot_fspec_t boot;
int _machine = _MACH_Pmac;
@@ -595,7 +598,7 @@
cmdinit();
- if (first) {
+ if (first && !fw_reboot_cnt) {
first = 0;
imagename = bootargs;
word_split(&imagename, ¶ms->args);
@@ -610,6 +613,13 @@
timeout = simple_strtol(q, NULL, 0);
}
+ /* If this is a reboot due to FW detecting CAS changes then
+ * set timeout to 1. The last kernel booted will be booted
+ * again automatically. It should seem seamless to the user
+ */
+ if (fw_reboot_cnt)
+ timeout = 1;
+
prom_printf("boot: ");
c = -1;
if (timeout != -1) {
@@ -644,6 +654,9 @@
if (c == '\n' || c == '\r') {
if (!imagename)
+ if (bootlastlabel[0] != 0)
+ imagename = bootlastlabel;
+ else
imagename = cfg_get_default();
if (imagename)
prom_printf("%s", imagename);
@@ -663,6 +676,9 @@
if ( useconf && (!imagename || imagename[0] == 0 ))
imagename = cfg_get_default();
+ /* write the imagename out so it can be reused on reboot if necessary */
+ prom_set_options("boot-last-label", imagename, strlen(imagename));
+
label = 0;
defdevice = boot.dev;
@@ -1447,6 +1463,7 @@
yaboot_main(void)
{
char *ptype;
+ char *endp;
int conf_given = 0;
char conf_path[1024];
@@ -1457,6 +1474,13 @@
DEBUG_F("/chosen/bootargs = %s\n", bootargs);
prom_get_chosen("bootpath", bootdevice, BOOTDEVSZ);
DEBUG_F("/chosen/bootpath = %s\n", bootdevice);
+ if (prom_get_options("ibm,client-architecture-support-reboot",fw_nbr_reboots, FW_NBR_REBOOTSZ) == -1 )
+ if (prom_get_options("ibm,fw-nbr-reboots",fw_nbr_reboots, FW_NBR_REBOOTSZ) == -1 )
+ fw_nbr_reboots[0] = NULL;
+
+ fw_reboot_cnt = simple_strtol(fw_nbr_reboots,&endp,10);
+ if (fw_reboot_cnt > 0L)
+ prom_get_options("boot-last-label", bootlastlabel, BOOTLASTSZ);
/* If conf= specified on command line, it overrides */
if (!strncmp(bootargs, "conf=", 5)) {