From d41000ed64bb144704fcbf2db3db840de30d069d Mon Sep 17 00:00:00 2001 From: Albert Chaulk Date: Fri, 19 Jul 2013 11:12:42 -0700 Subject: Don't always enable MTD mode unless MTD device is specified On MTD devices, don't always enable MTD mode - the installer needs to be able to access both the GPT disk and the MTD disk, so only enable it if we install to /dev/fts BRANCH=none BUG=chromium:221745 TEST=make runtests Change-Id: I7688e6bc758ef47cfb9d468c1224ef43b2043d02 Reviewed-on: https://gerrit.chromium.org/gerrit/62662 Reviewed-by: Randall Spangler Commit-Queue: Albert Chaulk Tested-by: Albert Chaulk --- cgpt/cgpt.c | 22 +++++++------- cgpt/cgpt.h | 5 ++-- cgpt/cgpt_add.c | 2 -- cgpt/cgpt_common.c | 88 ++++++++++++++++++++++++++++++++++-------------------- 4 files changed, 69 insertions(+), 48 deletions(-) diff --git a/cgpt/cgpt.c b/cgpt/cgpt.c index e02bf4d6..e49d430f 100644 --- a/cgpt/cgpt.c +++ b/cgpt/cgpt.c @@ -18,8 +18,6 @@ const char* progname; const char* command; void (*uuid_generator)(uint8_t* buffer); -extern struct nand_layout nand; - struct { const char *name; int (*fp)(int argc, char *argv[]); @@ -54,33 +52,37 @@ static int is_pow2(size_t v) { } static int parse_nand_option(const char *arg) { + int bytes_per_page, pages_per_block, fts_block_offset, fts_block_size; + if ('=' != arg[0]) return -1; arg++; - nand.bytes_per_page = atoi(arg); + bytes_per_page = atoi(arg); arg = strchr(arg, ','); if (!arg) return -1; arg++; - nand.pages_per_block = atoi(arg); + pages_per_block = atoi(arg); arg = strchr(arg, ','); if (!arg) return -1; arg++; - nand.fts_block_offset = atoi(arg); + fts_block_offset = atoi(arg); arg = strchr(arg, ','); if (!arg) return -1; arg++; - nand.fts_block_size = atoi(arg); - if (nand.fts_block_size == 0 || !is_pow2(nand.pages_per_block) || - !is_pow2(nand.bytes_per_page) || nand.bytes_per_page < 512) { + fts_block_size = atoi(arg); + if (fts_block_size == 0 || !is_pow2(pages_per_block) || + !is_pow2(bytes_per_page) || bytes_per_page < 512) { return -1; } + EnableNandImage(bytes_per_page, pages_per_block, fts_block_offset, + fts_block_size); return 0; } @@ -98,12 +100,10 @@ int main(int argc, char *argv[]) { progname = argv[0]; - memset(&nand, 0, sizeof(nand)); for (i = 1; i < argc; ++i) { if (0 == strncmp(argv[i], "-N", 2)) { if (!parse_nand_option(argv[i] + 2)) { int j; - nand.enabled = 1; // Remove it form the list. for (j = i; j < argc - 1; j++) @@ -118,8 +118,6 @@ int main(int argc, char *argv[]) { } } - TryInitMtd(); - if (argc < 2) { Usage(); return CGPT_FAILED; diff --git a/cgpt/cgpt.h b/cgpt/cgpt.h index 038a6d49..c6b0b9b4 100644 --- a/cgpt/cgpt.h +++ b/cgpt/cgpt.h @@ -58,14 +58,15 @@ struct nand_layout { int bytes_per_page, pages_per_block, fts_block_offset, fts_block_size; }; +/* Write a NAND/MTD image instead of GPT. */ +void EnableNandImage(int bytes_per_page, int pages_per_block, + int fts_block_offset, int fts_block_size); /* mode should be O_RDONLY or O_RDWR */ int DriveOpen(const char *drive_path, struct drive *drive, int mode); int DriveClose(struct drive *drive, int update_as_needed); int CheckValid(const struct drive *drive); -void TryInitMtd(void); - /* Loads sectors from 'drive'. * *buf is pointed to an allocated memory when returned, and should be * freed. diff --git a/cgpt/cgpt_add.c b/cgpt/cgpt_add.c index 117b4a11..e0e24b81 100644 --- a/cgpt/cgpt_add.c +++ b/cgpt/cgpt_add.c @@ -203,7 +203,6 @@ int CgptSetAttributes(CgptAddParams *params) { if (params == NULL) return CGPT_FAILED; - TryInitMtd(); if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) return CGPT_FAILED; @@ -241,7 +240,6 @@ int CgptGetPartitionDetails(CgptAddParams *params) { if (params == NULL) return CGPT_FAILED; - TryInitMtd(); if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR)) return CGPT_FAILED; diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c index 8b3b8a45..1a1c9e86 100644 --- a/cgpt/cgpt_common.c +++ b/cgpt/cgpt_common.c @@ -27,9 +27,16 @@ #include "flash_ts_api.h" #include "vboot_host.h" -struct nand_layout nand = { - 0, 0, 0, 0, 0 -}; +struct nand_layout nand; + +void EnableNandImage(int bytes_per_page, int pages_per_block, + int fts_block_offset, int fts_block_size) { + nand.enabled = 1; + nand.bytes_per_page = bytes_per_page; + nand.pages_per_block = pages_per_block; + nand.fts_block_offset = fts_block_offset; + nand.fts_block_size = fts_block_size; +} void Error(const char *format, ...) { va_list ap; @@ -150,20 +157,23 @@ static int get_hex_char_value(char ch) { return -1; } -void TryInitMtd(void) { +int TryInitMtd(const char *dev) { static int already_inited = 0; - if (nand.enabled || already_inited) - return; + if (already_inited) + return nand.use_host_ioctl; already_inited = 1; /* If we're running on the live system, we can just use /dev/fts and not - * actually need the specific parameters. + * actually need the specific parameters. This needs to be accessed via + * ioctl and not normal I/O. */ - if (!access(FTS_DEVICE, R_OK | W_OK)) { + if (!strcmp(dev, FTS_DEVICE) && !access(FTS_DEVICE, R_OK | W_OK)) { nand.enabled = 1; nand.use_host_ioctl = 1; + return 1; } + return 0; } int FlashGet(const char *key, uint8_t *data, uint32_t *bufsz) { @@ -174,7 +184,7 @@ int FlashGet(const char *key, uint8_t *data, uint32_t *bufsz) { if (nand.use_host_ioctl) { struct flash_ts_io_req req; strncpy(req.key, key, sizeof(req.key)); - int fd = open("/dev/fts", O_RDWR); + int fd = open(FTS_DEVICE, O_RDWR); if (fd < 0) return -1; if (ioctl(fd, FLASH_TS_IO_GET, &req)) @@ -220,7 +230,7 @@ int FlashSet(const char *key, const uint8_t *data, uint32_t bufsz) { strncpy(req.key, key, sizeof(req.key)); strncpy(req.val, hex, sizeof(req.val)); free(hex); - int fd = open("/dev/fts", O_RDWR); + int fd = open(FTS_DEVICE, O_RDWR); if (fd < 0) return -1; if (ioctl(fd, FLASH_TS_IO_SET, &req)) @@ -248,9 +258,9 @@ int MtdLoad(struct drive *drive, int sector_bytes) { mtd->flash_block_bytes, mtd->sector_bytes, /* Needed for Load() and Save() */ drive); + if (ret) + return ret; } - if (ret) - return ret; memset(&mtd->primary, 0, sizeof(mtd->primary)); sz = sizeof(mtd->primary); @@ -262,6 +272,14 @@ int MtdLoad(struct drive *drive, int sector_bytes) { if (sz < MTD_DRIVE_V1_SIZE) memset(&mtd->primary, 0, sizeof(mtd->primary)); + if (nand.use_host_ioctl) { + /* If we are using /dev/fts, we can't stat() the size, so re-use + * our internal value to set it. + */ + drive->size = mtd->primary.last_offset + 1; + mtd->drive_sectors = drive->size / mtd->sector_bytes; + } + mtd->current_kernel = -1; mtd->current_priority = 0; mtd->modified = 0; @@ -384,31 +402,37 @@ int DriveOpen(const char *drive_path, struct drive *drive, int mode) { // Clear struct for proper error handling. memset(drive, 0, sizeof(struct drive)); - drive->is_mtd = is_mtd; - drive->fd = open(drive_path, mode | O_LARGEFILE | O_NOFOLLOW); - if (drive->fd == -1) { - Error("Can't open %s: %s\n", drive_path, strerror(errno)); - return CGPT_FAILED; - } + if (TryInitMtd(drive_path)) { + is_mtd = 1; + sector_bytes = 512; /* bytes */ + } else { + drive->fd = open(drive_path, mode | O_LARGEFILE | O_NOFOLLOW); + if (drive->fd == -1) { + Error("Can't open %s: %s\n", drive_path, strerror(errno)); + return CGPT_FAILED; + } - if (fstat(drive->fd, &stat) == -1) { - Error("Can't fstat %s: %s\n", drive_path, strerror(errno)); - goto error_close; - } - if ((stat.st_mode & S_IFMT) != S_IFREG) { - if (ioctl(drive->fd, BLKGETSIZE64, &drive->size) < 0) { - Error("Can't read drive size from %s: %s\n", drive_path, strerror(errno)); + if (fstat(drive->fd, &stat) == -1) { + Error("Can't fstat %s: %s\n", drive_path, strerror(errno)); goto error_close; } - if (ioctl(drive->fd, BLKSSZGET, §or_bytes) < 0) { - Error("Can't read sector size from %s: %s\n", - drive_path, strerror(errno)); - goto error_close; + if ((stat.st_mode & S_IFMT) != S_IFREG) { + if (ioctl(drive->fd, BLKGETSIZE64, &drive->size) < 0) { + Error("Can't read drive size from %s: %s\n", drive_path, + strerror(errno)); + goto error_close; + } + if (ioctl(drive->fd, BLKSSZGET, §or_bytes) < 0) { + Error("Can't read sector size from %s: %s\n", + drive_path, strerror(errno)); + goto error_close; + } + } else { + sector_bytes = 512; /* bytes */ + drive->size = stat.st_size; } - } else { - sector_bytes = 512; /* bytes */ - drive->size = stat.st_size; } + drive->is_mtd = is_mtd; if (is_mtd) { drive->mtd.fts_block_offset = nand.fts_block_offset; -- cgit v1.2.1