Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: vpd.c

Issue 6646016: leverage flashrom fast partial read function to speed up VPD read. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vpd.git@master
Patch Set: refine code to handle corner case of eps->table_address. Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/fmap.c ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « lib/fmap.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698