Fix some issues with LBA vs byte offsets

In several places the existing code assumes LBA, but was improperly converted
to use byte offsets, so multiply by the sector size to correct it and maintain
the same interface between MTD & GPT.

Also, since we will need to cgpt create on /dev/fts, which isn't a stat()able
device, allow providing the disk size on the commandline.

BRANCH=none
BUG=chromium:221745
TEST=make runtests; cgpt create -s 12345 on MTD image

Original-Change-Id: Icc89a4505aba9a3dfc39b176a372f6e12d106aed
Reviewed-on: https://gerrit.chromium.org/gerrit/62675
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Tested-by: Albert Chaulk <achaulk@chromium.org>
Commit-Queue: Albert Chaulk <achaulk@chromium.org>
(cherry picked from commit 494646dbadedae88776d6fced396e3ee8af38e54)

Change-Id: Ic7ee0b97f9a34df1c331bad010a0c3307d520512
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/64226
diff --git a/cgpt/cgpt_add.c b/cgpt/cgpt_add.c
index a93c60c..fc40ebc 100644
--- a/cgpt/cgpt_add.c
+++ b/cgpt/cgpt_add.c
@@ -102,13 +102,15 @@
   MtdDiskPartition *entry;
 
   entry = MtdGetEntry(&drive->mtd, PRIMARY, index);
-  if (params->set_begin)
-    memcpy(&entry->starting_offset, &params->begin, sizeof(params->begin));
+  if (params->set_begin) {
+    uint64_t start = params->begin * drive->mtd.sector_bytes;
+    memcpy(&entry->starting_offset, &start, sizeof(params->begin));
+  }
   if (params->set_size) {
     uint64_t start;
     uint64_t end;
     MtdGetPartitionSize(entry, &start, NULL, NULL);
-    end = start + params->size - 1;
+    end = start + params->size * drive->mtd.sector_bytes - 1;
     memcpy(&entry->ending_offset, &end, sizeof(end));
   }
   if (params->set_type)
diff --git a/cgpt/cgpt_create.c b/cgpt/cgpt_create.c
index e7cbadf..90b746c 100644
--- a/cgpt/cgpt_create.c
+++ b/cgpt/cgpt_create.c
@@ -64,6 +64,14 @@
     h->last_offset = (drive->mtd.drive_sectors * drive->mtd.sector_bytes) - 1;
     h->crc32 = MtdHeaderCrc(h);
   }
+  if (params->size) {
+    h->last_offset = params->size - 1;
+    drive->size = params->size;
+    drive->mtd.drive_sectors = drive->size / drive->mtd.sector_bytes;
+  } else if (!drive->mtd.drive_sectors) {
+    Error("MTD create with params->size == 0 && drive->mtd.drive_sectors == 0");
+    return -1;
+  }
 
   return 0;
 }
diff --git a/cgpt/cgpt_show.c b/cgpt/cgpt_show.c
index 41f9d00..082a5c7 100644
--- a/cgpt/cgpt_show.c
+++ b/cgpt/cgpt_show.c
@@ -73,9 +73,9 @@
   printf("%sSize: %d\n", indent, header->size);
   printf("%sCRC: 0x%08x %s\n", indent, header->crc32,
          (MtdHeaderCrc(header) != header->crc32) ? "(INVALID)" : "");
-  printf("%sFirst LBA: %llu\n", indent,
+  printf("%sFirst offset: %llu\n", indent,
     (unsigned long long)header->first_offset);
-  printf("%sLast LBA: %llu\n", indent,
+  printf("%sLast offset: %llu\n", indent,
     (unsigned long long)header->last_offset);
 }
 
diff --git a/cgpt/cmd_create.c b/cgpt/cmd_create.c
index 0d91b08..4f04220 100644
--- a/cgpt/cmd_create.c
+++ b/cgpt/cmd_create.c
@@ -14,6 +14,7 @@
          "Create or reset an empty GPT.\n\n"
          "Options:\n"
          "  -z           Zero the sectors of the GPT table and entries\n"
+         "  -s           Size (in byes) of the disk (MTD only)\n"
          "\n", progname);
 }
 
@@ -23,15 +24,19 @@
 
   int c;
   int errorcnt = 0;
+  char *e = 0;
 
   opterr = 0;                     // quiet, you
-  while ((c=getopt(argc, argv, ":hz")) != -1)
+  while ((c=getopt(argc, argv, ":hzs:")) != -1)
   {
     switch (c)
     {
     case 'z':
       params.zap = 1;
       break;
+    case 's':
+      params.size = strtoull(optarg, &e, 0);
+      break;
 
     case 'h':
       Usage();
diff --git a/host/include/cgpt_params.h b/host/include/cgpt_params.h
index 14e380a..72de99d 100644
--- a/host/include/cgpt_params.h
+++ b/host/include/cgpt_params.h
@@ -16,6 +16,7 @@
 typedef struct CgptCreateParams {
   char *drive_name;
   int zap;
+  uint64_t size;
 } CgptCreateParams;
 
 typedef struct CgptAddParams {