aboutsummaryrefslogtreecommitdiffstats
path: root/disk
diff options
context:
space:
mode:
authorSergei Trofimovich2010-08-08 07:05:39 -0500
committerWolfgang Denk2010-08-10 16:08:55 -0500
commit69a2a4d9a5884a6f2d04a551308980d452b9b349 (patch)
treeb2784e2ad2d08056a8bb904e42c2197c8070e176 /disk
parentb9d51fbb18097975ff86d3a7b4a21a92a1b345f0 (diff)
downloadu-boot-69a2a4d9a5884a6f2d04a551308980d452b9b349.tar.gz
u-boot-69a2a4d9a5884a6f2d04a551308980d452b9b349.tar.xz
u-boot-69a2a4d9a5884a6f2d04a551308980d452b9b349.zip
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>
Diffstat (limited to 'disk')
-rw-r--r--disk/part.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/disk/part.c b/disk/part.c
index b6bae17940..3ba88c7e81 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -109,14 +109,31 @@ block_dev_desc_t *get_dev(char* ifname, int dev)
109/* 109/*
110 * reports device info to the user 110 * reports device info to the user
111 */ 111 */
112void dev_print (block_dev_desc_t *dev_desc) 112
113{
114#ifdef CONFIG_LBA48 113#ifdef CONFIG_LBA48
115 uint64_t lba512; /* number of blocks if 512bytes block size */ 114typedef uint64_t lba512_t;
116#else 115#else
117 lbaint_t lba512; 116typedef lbaint_t lba512_t;
118#endif 117#endif
119 118
119/*
120 * Overflowless variant of (block_count * mul_by / div_by)
121 * when div_by > mul_by
122 */
123static 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
133void dev_print (block_dev_desc_t *dev_desc)
134{
135 lba512_t lba512; /* number of blocks if 512bytes block size */
136
120 if (dev_desc->type == DEV_TYPE_UNKNOWN) { 137 if (dev_desc->type == DEV_TYPE_UNKNOWN) {
121 puts ("not available\n"); 138 puts ("not available\n");
122 return; 139 return;
@@ -184,8 +201,9 @@ void dev_print (block_dev_desc_t *dev_desc)
184 lba = dev_desc->lba; 201 lba = dev_desc->lba;
185 202
186 lba512 = (lba * (dev_desc->blksz/512)); 203 lba512 = (lba * (dev_desc->blksz/512));
187 mb = (10 * lba512) / 2048; /* 2048 = (1024 * 1024) / 512 MB */
188 /* round to 1 digit */ 204 /* round to 1 digit */
205 mb = lba512_muldiv(lba512, 10, 2048); /* 2048 = (1024 * 1024) / 512 MB */
206
189 mb_quot = mb / 10; 207 mb_quot = mb / 10;
190 mb_rem = mb - (10 * mb_quot); 208 mb_rem = mb - (10 * mb_quot);
191 209