OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. | 2 * Copyright (C) 2010 Google Inc. |
3 * | 3 * |
4 * This program is free software; you can redistribute it and/or | 4 * This program is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU General Public License | 5 * modify it under the terms of the GNU General Public License |
6 * as published by the Free Software Foundation; either version 2 | 6 * as published by the Free Software Foundation; either version 2 |
7 * of the License, or (at your option) any later version. | 7 * of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "lib/flashrom.h" | 27 #include "lib/flashrom.h" |
28 #include "lib/fmap.h" | 28 #include "lib/fmap.h" |
29 #include "lib/lib_vpd.h" | 29 #include "lib/lib_vpd.h" |
30 #include "lib/lib_smbios.h" | 30 #include "lib/lib_smbios.h" |
31 #include "lib/vpd.h" | 31 #include "lib/vpd.h" |
32 #include "lib/vpd_tables.h" | 32 #include "lib/vpd_tables.h" |
33 | 33 |
34 /* The buffer length. Right now the VPD partition size on flash is 128KB. */ | 34 /* The buffer length. Right now the VPD partition size on flash is 128KB. */ |
35 #define BUF_LEN (128 * 1024) | 35 #define BUF_LEN (128 * 1024) |
36 | 36 |
37 static uint8_t flashrom_tmp_file[] = "/tmp/vpd.flashrom.XXXXXX"; | 37 /* temp filename for partial read area. */ |
| 38 static uint8_t tmp_part_file[] = "/tmp/vpd.flashrom.XXXXXX"; |
| 39 /* temp filename for the full flash content (actually only partial content |
| 40 * is available). But for flashrom -w to match flash size, we need to keep this |
| 41 * file from flashromRead() to writeFlashrom(). */ |
| 42 static uint8_t tmp_full_file[] = "/tmp/vpd.flashrom.XXXXXX"; |
38 | 43 |
39 /* 2 containers: | 44 /* 2 containers: |
40 * file: stores decoded pairs from file. | 45 * file: stores decoded pairs from file. |
41 * argument: stores parsed pairs from command arguments. | 46 * argument: stores parsed pairs from command arguments. |
42 */ | 47 */ |
43 struct PairContainer file; | 48 struct PairContainer file; |
44 struct PairContainer argument; | 49 struct PairContainer argument; |
45 | 50 |
46 /* The current padding length value. | 51 /* The current padding length value. |
47 * Default: VPD_AS_LONG_AS | 52 * Default: VPD_AS_LONG_AS |
48 */ | 53 */ |
49 int pad_value_len = VPD_AS_LONG_AS; | 54 int pad_value_len = VPD_AS_LONG_AS; |
50 | 55 |
51 /* The output buffer */ | 56 /* The output buffer */ |
52 unsigned char buf[BUF_LEN]; | 57 unsigned char buf[BUF_LEN]; |
53 int buf_len = 0; | 58 int buf_len = 0; |
54 int max_buf_len = sizeof(buf); | 59 int max_buf_len = sizeof(buf); |
55 | 60 |
56 /* The EPS base address used to fill the EPS table entry. | 61 /* The EPS base address used to fill the EPS table entry. |
57 * If the VPD partition can be found in fmap, this points to the starting | 62 * If the VPD partition can be found in fmap, this points to the starting |
58 * offset of VPD partition. If not found, this is used to be the base address | 63 * offset of VPD partition. If not found, this is used to be the base address |
59 * to increase SPD and VPD 2.0 offset fields. | 64 * to increase SPD and VPD 2.0 offset fields. |
60 * | 65 * |
61 * User can overwrite this by -E argument. | 66 * User can overwrite this by -E argument. |
62 */ | 67 */ |
63 uint32_t eps_base = GOOGLE_EPS_BASE; | 68 uint32_t eps_base = GOOGLE_EPS_BASE; |
| 69 int eps_base_force_specified = 0; /* a bool value to indicate if -E argument |
| 70 * is given. */ |
64 | 71 |
65 /* the fmap name of VPD. */ | 72 /* the fmap name of VPD. */ |
66 uint8_t fmap_vpd_area_name[FMAP_STRLEN] = "RO VPD"; | 73 uint8_t fmap_vpd_area_name[FMAP_STRLEN] = "RO_VPD"; |
67 | 74 |
68 /* If found_vpd, replace the VPD partition when saveFile(). | 75 /* If found_vpd, replace the VPD partition when saveFile(). |
69 * If not found, always create new file when saveFlie(). */ | 76 * If not found, always create new file when saveFlie(). */ |
70 int found_vpd = 0; | 77 int found_vpd = 0; |
71 | 78 |
72 /* The VPD partition offset and size in buf[]. The whole partition includes: | 79 /* The VPD partition offset and size in buf[]. The whole partition includes: |
73 * | 80 * |
74 * SMBIOS EPS | 81 * SMBIOS EPS |
75 * SMBIOS tables[] | 82 * SMBIOS tables[] |
76 * SPD | 83 * SPD |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 struct vpd_entry *eps; | 226 struct vpd_entry *eps; |
220 struct vpd_header *header; | 227 struct vpd_header *header; |
221 struct vpd_table_binary_blob_pointer *data; | 228 struct vpd_table_binary_blob_pointer *data; |
222 uint8_t spd_uuid[16], vpd_2_0_uuid[16]; | 229 uint8_t spd_uuid[16], vpd_2_0_uuid[16]; |
223 int expected_handle = 0; | 230 int expected_handle = 0; |
224 int table_len; | 231 int table_len; |
225 int index; | 232 int index; |
226 int retval = 0; | 233 int retval = 0; |
227 | 234 |
228 if (!(fp = fopen(filename, "r"))) { | 235 if (!(fp = fopen(filename, "r"))) { |
229 fprintf(stderr, "[WARN] File [%s] cannot be opened for read. Ignored.\n", | 236 fprintf(stderr, "[WARN] File [%s] cannot be opened for read. It's fine.\n", |
230 filename); | 237 filename); |
231 return 0; | 238 return 0; |
232 } | 239 } |
233 /* get file size */ | 240 /* get file size */ |
234 fseek(fp, 0, SEEK_END); | 241 fseek(fp, 0, SEEK_END); |
235 file_size = ftell(fp); | 242 file_size = ftell(fp); |
236 | 243 |
237 /* read file content */ | 244 /* read file content */ |
238 fseek(fp, 0, SEEK_SET); | 245 fseek(fp, 0, SEEK_SET); |
239 read_buf = malloc(file_size); | 246 read_buf = malloc(file_size); |
(...skipping 11 matching lines...) Expand all Loading... |
251 /* FMAP signature is not found, assume it is pure VPD partition. */ | 258 /* FMAP signature is not found, assume it is pure VPD partition. */ |
252 vpd_buf = read_buf; | 259 vpd_buf = read_buf; |
253 eps = (struct vpd_entry *)vpd_buf; | 260 eps = (struct vpd_entry *)vpd_buf; |
254 | 261 |
255 /* In overwrite mode, ignore all existing data. */ | 262 /* In overwrite mode, ignore all existing data. */ |
256 if (overwrite_it) { | 263 if (overwrite_it) { |
257 retval = 0; | 264 retval = 0; |
258 goto teardown; | 265 goto teardown; |
259 } | 266 } |
260 } else { | 267 } else { |
| 268 /* FMAP signature is found, try to search the partition name in table. */ |
261 int i; | 269 int i; |
262 | 270 |
263 fmap = (struct fmap *)&read_buf[sig_offset]; | 271 fmap = (struct fmap *)&read_buf[sig_offset]; |
264 for(i = 0; i < fmap->nareas; i++) { | 272 for(i = 0; i < fmap->nareas; i++) { |
265 fmapNormalizeAreaName(fmap->areas[i].name); | 273 fmapNormalizeAreaName(fmap->areas[i].name); |
266 } | 274 } |
267 | 275 |
268 if (FMAP_OK == fmapGetArea(fmap_vpd_area_name, fmap, | 276 if (FMAP_OK == fmapGetArea(fmap_vpd_area_name, fmap, |
269 &vpd_offset, &vpd_size)) { | 277 &vpd_offset, &vpd_size)) { |
270 found_vpd = 1; /* Mark found here then saveFile() knows where to | 278 found_vpd = 1; /* Mark found here then saveFile() knows where to |
(...skipping 11 matching lines...) Expand all Loading... |
282 fprintf(stderr, "The VPD partition [%s] is not found.\n", | 290 fprintf(stderr, "The VPD partition [%s] is not found.\n", |
283 fmap_vpd_area_name); | 291 fmap_vpd_area_name); |
284 retval = 1; | 292 retval = 1; |
285 goto teardown; | 293 goto teardown; |
286 } | 294 } |
287 } | 295 } |
288 /* Now, vpd_buf points to the VPD partition in buffer. | 296 /* Now, vpd_buf points to the VPD partition in buffer. |
289 * eps points to the EPS structure, which is usually equal to vpd_buf. */ | 297 * eps points to the EPS structure, which is usually equal to vpd_buf. */ |
290 eps_offset = (uint8_t*)eps - vpd_buf; | 298 eps_offset = (uint8_t*)eps - vpd_buf; |
291 | 299 |
| 300 /* check if ups_base variable needs to be updated. */ |
| 301 if (!eps_base_force_specified) { |
| 302 if (eps->table_address > file_size) { |
| 303 /* If the table address field of EPS indicates the position exceeding |
| 304 * the file size, that means some how this field needs to be shifted. |
| 305 * A special case is 0xFFFFFFFF, which means unkowns address. But this |
| 306 * is okay because the later offset of structure table are counted |
| 307 * related to this value. */ |
| 308 eps_base = eps->table_address - sizeof(*eps); |
| 309 fprintf(stderr, "[INFO] we guess eps_base is 0x%x.\n", eps_base); |
| 310 } |
| 311 } |
| 312 |
292 /* jump if the VPD partition is not recognized. */ | 313 /* jump if the VPD partition is not recognized. */ |
293 if (memcmp(VPD_ENTRY_MAGIC, eps, sizeof(VPD_ENTRY_MAGIC) - 1)) { | 314 if (memcmp(VPD_ENTRY_MAGIC, eps, sizeof(VPD_ENTRY_MAGIC) - 1)) { |
294 /* But OKAY if the VPD partition is all-FF, which is un-used. */ | 315 /* But OKAY if the VPD partition is all-FF, which is un-used. */ |
295 if (memcmp("\xff\xff\xff\xff", eps, sizeof(VPD_ENTRY_MAGIC) - 1)) { | 316 if (!memcmp("\xff\xff\xff\xff", eps, sizeof(VPD_ENTRY_MAGIC) - 1)) { |
| 317 fprintf(stderr, "[WARN] VPD partition not formatted. It's fine.\n"); |
| 318 retval = 0; |
| 319 goto teardown; |
| 320 } else { |
296 fprintf(stderr, "SMBIOS signature is not matched.\n"); | 321 fprintf(stderr, "SMBIOS signature is not matched.\n"); |
297 fprintf(stderr, "You may use -O to overwrite the data.\n"); | 322 fprintf(stderr, "You may use -O to overwrite the data.\n"); |
298 retval = 1; | 323 retval = 1; |
299 goto teardown; | 324 goto teardown; |
300 } | 325 } |
301 /* TODO(yjlou): need more EPS sanity checks here. */ | 326 /* TODO(yjlou): need more EPS sanity checks here. */ |
302 } | 327 } |
303 /* EPS is done above. Parse structure tables below. */ | 328 /* EPS is done above. Parse structure tables below. */ |
304 /* Get the first type 241 blob, at the tail of EPS. */ | 329 /* Get the first type 241 blob, at the tail of EPS. */ |
305 header = (struct vpd_header*)(((uint8_t*)eps) + eps->entry_length); | 330 header = (struct vpd_header*)(((uint8_t*)eps) + eps->entry_length); |
306 data = (struct vpd_table_binary_blob_pointer *) | 331 data = (struct vpd_table_binary_blob_pointer *) |
307 ((uint8_t *)header + sizeof(*header)); | 332 ((uint8_t *)header + sizeof(*header)); |
308 | 333 |
309 /* TODO(yjlou): Re-factor the parsing code to support more SMBIOS entries. | 334 /* TODO(yjlou): Re-factor the parsing code to support more SMBIOS entries. |
310 * The current code only supports 2 combinations: | 335 * The current code only supports 2 combinations: |
311 * 1. Type 241 (SPD) + Type 241 (VPD 2.0) + Type 127 | 336 * 1. Type 241 (SPD) + Type 241 (VPD 2.0) + Type 127 |
312 * 2. Type 241 (VPD 2.0) + Type 127 | 337 * 2. Type 241 (VPD 2.0) + Type 127 |
313 */ | 338 */ |
314 | 339 |
315 /* Now header points to the first SMBIOS entry, and data points to the | 340 /* Now header points to the first SMBIOS entry, and data points to the |
316 * first BBP entry. The first entry could be SPD data. We don't care. */ | 341 * first BBP entry. The first entry could be SPD data. We don't care. */ |
317 if (header->handle != expected_handle) { | 342 if (header->handle != expected_handle) { |
318 fprintf(stderr, "The first handle value must be 0, but is %d.\n", | 343 fprintf(stderr, "[ERROR] The first handle value must be 0, but is %d.\n" |
| 344 " Use -O option to re-format.\n", |
319 header->handle); | 345 header->handle); |
320 retval = 1; | 346 retval = 1; |
321 goto teardown; | 347 goto teardown; |
322 } | 348 } |
323 if (header->type != VPD_TYPE_BINARY_BLOB_POINTER) { | 349 if (header->type != VPD_TYPE_BINARY_BLOB_POINTER) { |
324 fprintf(stderr, "Expect first entry is type Binary Blob Pointer (241)," | 350 fprintf(stderr, "Expect first entry is type Binary Blob Pointer (241)," |
325 " but actually is %d\n", header->type); | 351 " but actually is %d\n", header->type); |
326 fprintf(stderr, "You may use -O to overwrite the data.\n"); | 352 fprintf(stderr, "You may use -O to overwrite the data.\n"); |
327 retval = 1; | 353 retval = 1; |
328 goto teardown; | 354 goto teardown; |
(...skipping 26 matching lines...) Expand all Loading... |
355 retval = 1; | 381 retval = 1; |
356 goto teardown; | 382 goto teardown; |
357 } | 383 } |
358 header = (struct vpd_header*)((uint8_t*)header + table_len); | 384 header = (struct vpd_header*)((uint8_t*)header + table_len); |
359 data = (struct vpd_table_binary_blob_pointer *) | 385 data = (struct vpd_table_binary_blob_pointer *) |
360 ((uint8_t *)header + sizeof(*header)); | 386 ((uint8_t *)header + sizeof(*header)); |
361 } | 387 } |
362 | 388 |
363 /* The 2nd could be VPD 2.0 data or End Of Table. */ | 389 /* The 2nd could be VPD 2.0 data or End Of Table. */ |
364 if (header->handle != expected_handle) { | 390 if (header->handle != expected_handle) { |
365 fprintf(stderr, "The second handle value must be 1, but is %d.\n", | 391 fprintf(stderr, "[ERROR] The second handle value must be 1, but is %d.\n" |
| 392 " Use -O option to re-format.\n", |
366 header->handle); | 393 header->handle); |
367 retval = 1; | 394 retval = 1; |
368 goto teardown; | 395 goto teardown; |
369 } | 396 } |
370 uuid_parse(GOOGLE_VPD_2_0_UUID, vpd_2_0_uuid); | 397 uuid_parse(GOOGLE_VPD_2_0_UUID, vpd_2_0_uuid); |
371 if (header->type == VPD_TYPE_BINARY_BLOB_POINTER && | 398 if (header->type == VPD_TYPE_BINARY_BLOB_POINTER && |
372 !memcmp(data->uuid, vpd_2_0_uuid, sizeof(data->uuid))) { | 399 !memcmp(data->uuid, vpd_2_0_uuid, sizeof(data->uuid))) { |
373 ++expected_handle; | 400 ++expected_handle; |
374 | 401 |
375 /* iterate all pairs */ | 402 /* iterate all pairs */ |
(...skipping 16 matching lines...) Expand all Loading... |
392 header = (struct vpd_header*)((uint8_t*)header + table_len); | 419 header = (struct vpd_header*)((uint8_t*)header + table_len); |
393 data = (struct vpd_table_binary_blob_pointer *) | 420 data = (struct vpd_table_binary_blob_pointer *) |
394 ((uint8_t *)header + sizeof(*header)); | 421 ((uint8_t *)header + sizeof(*header)); |
395 } else { | 422 } else { |
396 fprintf(stderr, "[WARN] no VPD 2.0 BBP is found, ignored.\n"); | 423 fprintf(stderr, "[WARN] no VPD 2.0 BBP is found, ignored.\n"); |
397 retval = 0; | 424 retval = 0; |
398 goto teardown; | 425 goto teardown; |
399 } | 426 } |
400 | 427 |
401 if (header->type != VPD_TYPE_END) { | 428 if (header->type != VPD_TYPE_END) { |
402 fprintf(stderr, "[WARN] we expect the last one is type 127. Ignored.\n"); | 429 fprintf(stderr, "[WARN] we expect the last one is type 127. It's fine.\n"); |
403 } | 430 } |
404 | 431 |
405 teardown: | 432 teardown: |
406 free(read_buf); | 433 free(read_buf); |
407 | 434 |
408 return retval; | 435 return retval; |
409 } | 436 } |
410 | 437 |
411 | 438 |
412 int saveFile(const struct PairContainer *container, const char *filename) { | 439 int saveFile(const struct PairContainer *container, const char *filename) { |
413 FILE *fp; | 440 FILE *fp; |
414 unsigned char eps[1024]; | 441 unsigned char eps[1024]; |
415 int eps_len = 0; | 442 int eps_len = 0; |
416 int retval = 0; | 443 int retval = 0; |
417 | 444 |
418 memset(eps, 0, sizeof(eps)); | 445 memset(eps, 0xff, sizeof(eps)); |
419 | 446 |
420 /* encode into buffer */ | 447 /* encode into buffer */ |
421 if (VPD_OK != encodeContainer(&file, max_buf_len, buf, &buf_len)) { | 448 if (VPD_OK != encodeContainer(&file, max_buf_len, buf, &buf_len)) { |
422 fprintf(stderr, "encodeContainer() error.\n"); | 449 fprintf(stderr, "encodeContainer() error.\n"); |
423 retval = 1; | 450 retval = 1; |
424 goto teardown; | 451 goto teardown; |
425 } | 452 } |
426 if (VPD_OK != encodeVpdTerminator(max_buf_len, buf, &buf_len)) { | 453 if (VPD_OK != encodeVpdTerminator(max_buf_len, buf, &buf_len)) { |
427 fprintf(stderr, "Out of space for terminator.\n"); | 454 fprintf(stderr, "Out of space for terminator.\n"); |
428 retval = 1; | 455 retval = 1; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 fprintf(stderr, "fwrite(VPD 2.0) error (%s)\n", strerror(errno)); | 510 fprintf(stderr, "fwrite(VPD 2.0) error (%s)\n", strerror(errno)); |
484 retval = 1; | 511 retval = 1; |
485 goto teardown; | 512 goto teardown; |
486 } | 513 } |
487 fclose(fp); | 514 fclose(fp); |
488 | 515 |
489 teardown: | 516 teardown: |
490 return retval; | 517 return retval; |
491 } | 518 } |
492 | 519 |
| 520 int myMkTemp(uint8_t *tmp_file) { |
| 521 int fd; |
| 522 fd = mkstemp(tmp_file); |
| 523 if (fd < 0) { |
| 524 fprintf(stderr, "mkstemp(%s) failed\n", tmp_file); |
| 525 } |
| 526 return fd; |
| 527 } |
| 528 |
| 529 int generateTempFilenames(void) { |
| 530 if (myMkTemp(tmp_part_file) < 0) return -1; |
| 531 if (myMkTemp(tmp_full_file) < 0) return -1; |
| 532 return 0; |
| 533 } |
493 | 534 |
494 static void usage(const char *progname) { | 535 static void usage(const char *progname) { |
495 printf("Chrome OS VPD 2.0 utility --\n"); | 536 printf("Chrome OS VPD 2.0 utility --\n"); |
496 #ifdef VPD_VERSION | 537 #ifdef VPD_VERSION |
497 printf("%s\n", VPD_VERSION); | 538 printf("%s\n", VPD_VERSION); |
498 #endif | 539 #endif |
499 printf("\n"); | 540 printf("\n"); |
500 printf("Usage: %s [OPTION] ...\n", progname); | 541 printf("Usage: %s [OPTION] ...\n", progname); |
501 printf(" OPTIONs include:\n"); | 542 printf(" OPTIONs include:\n"); |
502 printf(" -h This help page and version.\n"); | 543 printf(" -h This help page and version.\n"); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 goto teardown; | 585 goto teardown; |
545 break; | 586 break; |
546 | 587 |
547 case 'f': | 588 case 'f': |
548 filename = strdup(optarg); | 589 filename = strdup(optarg); |
549 break; | 590 break; |
550 | 591 |
551 case 'E': | 592 case 'E': |
552 errno = 0; | 593 errno = 0; |
553 eps_base = strtoul(optarg, (char **) NULL, 0); | 594 eps_base = strtoul(optarg, (char **) NULL, 0); |
| 595 eps_base_force_specified = 1; |
554 | 596 |
555 /* FIXME: this is not a stable way to detect error because | 597 /* FIXME: this is not a stable way to detect error because |
556 * implementation may (or may not) assign errno. */ | 598 * implementation may (or may not) assign errno. */ |
557 if (!eps_base && errno == EINVAL) { | 599 if (!eps_base && errno == EINVAL) { |
558 fprintf(stderr, "Not a number for EPS base address: %s\n", optarg); | 600 fprintf(stderr, "Not a number for EPS base address: %s\n", optarg); |
559 retval = 1; | 601 retval = 1; |
560 goto teardown; | 602 goto teardown; |
561 } | 603 } |
562 break; | 604 break; |
563 | 605 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 break; | 640 break; |
599 | 641 |
600 default: | 642 default: |
601 fprintf(stderr, "Invalid option, use --help for usage.\n"); | 643 fprintf(stderr, "Invalid option, use --help for usage.\n"); |
602 retval = 1; | 644 retval = 1; |
603 goto teardown; | 645 goto teardown; |
604 break; | 646 break; |
605 } | 647 } |
606 } | 648 } |
607 | 649 |
608 fd = mkstemp(flashrom_tmp_file); | 650 if (optind < argc) { |
609 if (fd < 0) { | 651 fprintf(stderr, "[ERROR] unexpected argument: %s\n\n", argv[optind]); |
610 fprintf(stderr, "mkstemp(%s) failed\n", flashrom_tmp_file); | 652 usage(argv[0]); |
611 retval = 1; | 653 retval = 1; |
612 goto teardown; | 654 goto teardown; |
613 } | 655 } |
| 656 |
| 657 if (generateTempFilenames() < 0) { |
| 658 retval = 1; |
| 659 goto teardown; |
| 660 } |
614 | 661 |
615 /* to avoid malicious attack, we replace suspicious chars. */ | 662 /* to avoid malicious attack, we replace suspicious chars. */ |
616 fmapNormalizeAreaName(fmap_vpd_area_name); | 663 fmapNormalizeAreaName(fmap_vpd_area_name); |
617 | 664 |
618 /* if no filename is specified, call flashrom to read from flash. */ | 665 /* if no filename is specified, call flashrom to read from flash. */ |
619 if (!filename) { | 666 if (!filename) { |
620 if (FLASHROM_OK != flashromRead(flashrom_tmp_file)) { | 667 if (FLASHROM_OK != flashromRead(tmp_part_file, tmp_full_file, |
| 668 fmap_vpd_area_name)) { |
621 fprintf(stderr, "flashromRead() error!\n"); | 669 fprintf(stderr, "flashromRead() error!\n"); |
622 retval = 1; | 670 retval = 1; |
623 goto teardown; | 671 goto teardown; |
624 } | 672 } |
625 write_back_to_flash = 1; | 673 write_back_to_flash = 1; |
626 filename = strdup(flashrom_tmp_file); | 674 filename = strdup(tmp_part_file); |
627 } | 675 } |
628 | 676 |
629 if (retval = loadFile(filename, &file, overwrite_it)) { | 677 if (retval = loadFile(filename, &file, overwrite_it)) { |
630 fprintf(stderr, "loadFile('%s') error.\n", filename); | 678 fprintf(stderr, "loadFile('%s') error.\n", filename); |
631 goto teardown; | 679 goto teardown; |
632 } | 680 } |
633 | 681 |
634 mergeContainer(&file, &argument); | 682 mergeContainer(&file, &argument); |
635 | 683 |
636 if (list_it) { | 684 if (list_it) { |
(...skipping 11 matching lines...) Expand all Loading... |
648 printf("%s", list_buf); | 696 printf("%s", list_buf); |
649 } | 697 } |
650 | 698 |
651 if (modified) { | 699 if (modified) { |
652 if (retval = saveFile(&file, filename)) { | 700 if (retval = saveFile(&file, filename)) { |
653 fprintf(stderr, "saveFile('%s') error.\n", filename); | 701 fprintf(stderr, "saveFile('%s') error.\n", filename); |
654 goto teardown; | 702 goto teardown; |
655 } | 703 } |
656 | 704 |
657 if (write_back_to_flash) { | 705 if (write_back_to_flash) { |
658 if (FLASHROM_OK != flashromPartialWrite(filename, vpd_offset, vpd_size)) { | 706 if (FLASHROM_OK != flashromPartialWrite(filename, tmp_full_file, |
| 707 fmap_vpd_area_name)) { |
659 fprintf(stderr, "flashromPartialWrite() error.\n"); | 708 fprintf(stderr, "flashromPartialWrite() error.\n"); |
660 retval = 1; | 709 retval = 1; |
661 goto teardown; | 710 goto teardown; |
662 } | 711 } |
663 } | 712 } |
664 } | 713 } |
665 | 714 |
666 teardown: | 715 teardown: |
667 if (spd_data) free(spd_data); | 716 if (spd_data) free(spd_data); |
668 if (filename) free(filename); | 717 if (filename) free(filename); |
669 destroyContainer(&file); | 718 destroyContainer(&file); |
670 destroyContainer(&argument); | 719 destroyContainer(&argument); |
671 | 720 |
672 return retval; | 721 return retval; |
673 } | 722 } |
OLD | NEW |