Commit 69a2a4d9a5884a6f2d04a551308980d452b9b349

Authored by Sergei Trofimovich
Committed by Wolfgang Denk
1 parent b9d51fbb18

disk/part.c: 'usb storage' avoiding overflow when output capacity

Before:
    Marvell>> usb storage
      Device 0: Vendor: StoreJet Rev:  Prod:  Transcend
                Type: Hard Disk
                Capacity: 28759.9 MB = 28.0 GB (488397168 x 512)
After:
    Marvell>> usb storage
      Device 0: Vendor: StoreJet Rev:  Prod:  Transcend
                Type: Hard Disk
                Capacity: 238475.1 MB = 232.8 GB (488397168 x 512)

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>

Showing 1 changed file with 23 additions and 5 deletions Side-by-side Diff

... ... @@ -109,14 +109,31 @@
109 109 /*
110 110 * reports device info to the user
111 111 */
112   -void dev_print (block_dev_desc_t *dev_desc)
113   -{
  112 +
114 113 #ifdef CONFIG_LBA48
115   - uint64_t lba512; /* number of blocks if 512bytes block size */
  114 +typedef uint64_t lba512_t;
116 115 #else
117   - lbaint_t lba512;
  116 +typedef lbaint_t lba512_t;
118 117 #endif
119 118  
  119 +/*
  120 + * Overflowless variant of (block_count * mul_by / div_by)
  121 + * when div_by > mul_by
  122 + */
  123 +static lba512_t lba512_muldiv (lba512_t block_count, lba512_t mul_by, lba512_t div_by)
  124 +{
  125 + lba512_t bc_quot, bc_rem;
  126 +
  127 + /* x * m / d == x / d * m + (x % d) * m / d */
  128 + bc_quot = block_count / div_by;
  129 + bc_rem = block_count - div_by * bc_quot;
  130 + return bc_quot * mul_by + (bc_rem * mul_by) / div_by;
  131 +}
  132 +
  133 +void dev_print (block_dev_desc_t *dev_desc)
  134 +{
  135 + lba512_t lba512; /* number of blocks if 512bytes block size */
  136 +
120 137 if (dev_desc->type == DEV_TYPE_UNKNOWN) {
121 138 puts ("not available\n");
122 139 return;
123 140  
... ... @@ -184,8 +201,9 @@
184 201 lba = dev_desc->lba;
185 202  
186 203 lba512 = (lba * (dev_desc->blksz/512));
187   - mb = (10 * lba512) / 2048; /* 2048 = (1024 * 1024) / 512 MB */
188 204 /* round to 1 digit */
  205 + mb = lba512_muldiv(lba512, 10, 2048); /* 2048 = (1024 * 1024) / 512 MB */
  206 +
189 207 mb_quot = mb / 10;
190 208 mb_rem = mb - (10 * mb_quot);
191 209