[PATCH] powerpc: fix large nvram access
Olaf Hering
olh at suse.de
Wed Jan 11 23:20:20 EST 2006
On Wed, Jan 11, Olaf Hering wrote:
> > I think this has uncovered a bug that has been in nvsetenv for a long time.
I made this change.
Index: pmac-utils-2.1/nvsetenv.c
===================================================================
--- pmac-utils-2.1.orig/nvsetenv.c
+++ pmac-utils-2.1/nvsetenv.c
@@ -110,12 +110,21 @@ int nvcsum( void )
static void nvload( int nvfd )
{
int s;
+ ssize_t r, toread = 0;
+ char *buf = (char *)&nvbuf;
- if (lseek(nvfd, NVSTART, 0) < 0
- || read(nvfd, &nvbuf, NVSIZE) != NVSIZE) {
- perror("Error reading /dev/nvram");
+ if ((off_t)-1 == lseek(nvfd, NVSTART, 0)) {
+ perror("Error seeking /dev/nvram");
exit(EXIT_FAILURE);
}
+ do {
+ r = read(nvfd, buf + toread, NVSIZE - toread);
+ if (r < 0) {
+ perror("Error reading /dev/nvram");
+ exit(EXIT_FAILURE);
+ }
+ toread += r;
+ } while (toread < NVSIZE && r);
if (nvbuf.nv.magic != NVMAGIC)
(void) fprintf(stderr, "Warning: Bad magic number %x\n",
nvbuf.nv.magic);
@@ -127,11 +136,21 @@ static void nvload( int nvfd )
static void nvstore(int nvfd)
{
- if (lseek(nvfd, NVSTART, 0) < 0
- || write(nvfd, &nvbuf, NVSIZE) != NVSIZE) {
- perror("Error writing /dev/nvram");
+ char *p = (char *)&nvbuf;
+ size_t count = 0;
+ off_t w;
+ if (lseek(nvfd, NVSTART, 0) < 0) {
+ perror("Error seeking /dev/nvram");
exit(EXIT_FAILURE);
}
+ do {
+ w = write(nvfd, p + count, NVSIZE - count);
+ if (w < 0) {
+ perror("Error writing /dev/nvram");
+ exit(EXIT_FAILURE);
+ }
+ count += w;
+ } while (count < NVSIZE);
}
void nvunpack( void )
Index: pmac-utils-2.1/nwnvsetenv.c
===================================================================
--- pmac-utils-2.1.orig/nwnvsetenv.c
+++ pmac-utils-2.1/nwnvsetenv.c
@@ -88,15 +88,20 @@ int nvscan(int nvfd, chrp_header* chrph,
static char* nvload( int nvfd , int nvsize)
{
char* nvbuf = malloc(nvsize);
+ ssize_t r, toread = 0;
if (!nvbuf) {
perror("Error allocating buffer");
exit(EXIT_FAILURE);
}
- if (read(nvfd, nvbuf, nvsize) != nvsize) {
- perror("Error reading /dev/nvram");
- exit(EXIT_FAILURE);
- }
+ do {
+ r = read(nvfd, nvbuf + toread, nvsize - toread);
+ if (r < 0) {
+ perror("Error reading /dev/nvram");
+ exit(EXIT_FAILURE);
+ }
+ toread += r;
+ } while (toread < nvsize && r);
return nvbuf;
}
@@ -182,6 +187,7 @@ print_var(char* nvbuf, int nvsize, char*
printf("%s\n",buf);
}
+#if 0
/* This fucntion is not used here, it is left
her for the curious */
@@ -197,26 +203,28 @@ unsigned short chrp_checksum(chrp_header
sum = (sum & 0xFF) + (sum>>8);
return sum;
}
+#endif
static void
nvstore(int nvfd, chrp_header* chrph, char* nvbuf, int nvstart, int nvsize)
{
// mmh, the checksum is calculated for the header only
// since we did not modify the header we can just ignore it.
- ssize_t written;
- ssize_t seek = nvstart + sizeof(chrp_header);
- written = lseek(nvfd, seek, SEEK_SET);
- if (written != seek)
- {
+ size_t count = 0;
+ off_t w, seek = nvstart + sizeof(chrp_header);
+ w = lseek(nvfd, seek, SEEK_SET);
+ if (w != seek) {
fprintf(stderr,"Error seeking /dev/nvram\n");
exit(EXIT_FAILURE);
}
- written = write(nvfd, nvbuf, nvsize);
- if (written != nvsize)
- {
- fprintf(stderr,"Error writing /dev/nvram %x %x\n", nvsize, seek);
- exit(EXIT_FAILURE);
- }
+ do {
+ w = write(nvfd, nvbuf + count, nvsize - count);
+ if (w < 0) {
+ perror("Error writing /dev/nvram");
+ exit(EXIT_FAILURE);
+ }
+ count += w;
+ } while (count < (size_t)nvsize);
}
/* print / set the New World NVRAM */
--
short story of a lazy sysadmin:
alias appserv=wotan
More information about the Linuxppc-dev
mailing list