[U-Boot] [PATCH v2 3/5] usb: ums: fix disk capacity miscalculation and code cleanup

Przemyslaw Marczak p.marczak at samsung.com
Wed Oct 23 14:30:44 CEST 2013


This patch prevents:
- ums disk capacity miscalculation because of integer overflow

Changes v2:
- Prevents passing zero size disk capacity to ums gadget driver
- Change function ums_get_capacity() to ums_disk_init() and do ums disk
  initialization before gadget init
- Remove unnecessary code from mass storage driver

Signed-off-by: Przemyslaw Marczak <p.marczak at samsung.com>
Cc: Marek Vasut <marex at denx.de>
---
 board/samsung/trats/trats.c         |   49 +++++++++++++++++++++++------------
 drivers/usb/gadget/storage_common.c |   26 +++----------------
 include/usb_mass_storage.h          |    6 ++---
 3 files changed, 37 insertions(+), 44 deletions(-)

diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c
index 0b58b00..7e0e31e 100644
--- a/board/samsung/trats/trats.c
+++ b/board/samsung/trats/trats.c
@@ -778,7 +778,7 @@ static int ums_read_sector(struct ums *ums_dev,
 			   ulong start, lbaint_t blkcnt, void *buf)
 {
 	block_dev_desc_t *block_dev = &ums_dev->mmc->block_dev;
-	lbaint_t blkstart = start + ums_dev->offset;
+	lbaint_t blkstart = start + ums_dev->start_sector;
 	int dev_num = block_dev->dev;
 
 	return block_dev->block_read(dev_num, blkstart, blkcnt, buf);
@@ -788,30 +788,47 @@ static int ums_write_sector(struct ums *ums_dev,
 			    ulong start, lbaint_t blkcnt, const void *buf)
 {
 	block_dev_desc_t *block_dev = &ums_dev->mmc->block_dev;
-	lbaint_t blkstart = start + ums_dev->offset;
+	lbaint_t blkstart = start + ums_dev->start_sector;
 	int dev_num = block_dev->dev;
 
 	return block_dev->block_write(dev_num, blkstart, blkcnt, buf);
 }
 
-static void ums_get_capacity(struct ums *ums_dev, long long int *capacity)
-{
-	long long int tmp_capacity;
-
-	tmp_capacity = (long long int)((ums_dev->offset + ums_dev->part_size)
-				       * SECTOR_SIZE);
-	*capacity = ums_dev->mmc->capacity - tmp_capacity;
-}
-
 static struct ums ums_dev = {
 	.read_sector = ums_read_sector,
 	.write_sector = ums_write_sector,
-	.get_capacity = ums_get_capacity,
 	.name = "UMS disk",
-	.offset = UMS_START_SECTOR,
-	.part_size = UMS_NUM_SECTORS,
 };
 
+static struct ums *ums_disk_init(struct mmc *mmc)
+{
+	uint64_t mmc_end_sector = mmc->capacity / SECTOR_SIZE;
+	uint64_t ums_end_sector = UMS_NUM_SECTORS + UMS_START_SECTOR;
+
+	if (!mmc_end_sector) {
+		error("MMC capacity is not valid");
+		return NULL;
+	}
+
+	ums_dev.mmc = mmc;
+
+	if (ums_end_sector <= mmc_end_sector) {
+		ums_dev.start_sector = UMS_START_SECTOR;
+		if (UMS_NUM_SECTORS)
+			ums_dev.num_sectors = UMS_NUM_SECTORS;
+		else
+			ums_dev.num_sectors = mmc_end_sector - UMS_START_SECTOR;
+	} else {
+		ums_dev.num_sectors = mmc_end_sector;
+		puts("UMS: defined bad disk parameters. Using default.\n");
+	}
+
+	printf("UMS: disk start sector: %#x, count: %#x\n",
+	       ums_dev.start_sector, ums_dev.num_sectors);
+
+	return &ums_dev;
+}
+
 struct ums *ums_init(unsigned int dev_num)
 {
 	struct mmc *mmc = NULL;
@@ -820,8 +837,6 @@ struct ums *ums_init(unsigned int dev_num)
 	if (!mmc)
 		return NULL;
 
-	ums_dev.mmc = mmc;
-
-	return &ums_dev;
+	return ums_disk_init(mmc);
 }
 #endif
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index c2c5424..02803df 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -572,36 +572,16 @@ static struct usb_gadget_strings	fsg_stringtab = {
 static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
 {
 	int				ro;
-	int				rc = -EINVAL;
-	loff_t				size;
-	loff_t				num_sectors;
-	loff_t				min_sectors;
 
 	/* R/W if we can, R/O if we must */
 	ro = curlun->initially_ro;
 
-	ums->get_capacity(ums, &size);
-	if (size < 0) {
-		printf("unable to find file size: %s\n", filename);
-		rc = (int) size;
-		goto out;
-	}
-	num_sectors = size >> 9;	/* File size in 512-byte blocks */
-	min_sectors = 1;
-	if (num_sectors < min_sectors) {
-		printf("file too small: %s\n", filename);
-		rc = -ETOOSMALL;
-		goto out;
-	}
-
 	curlun->ro = ro;
-	curlun->file_length = size;
-	curlun->num_sectors = num_sectors;
+	curlun->file_length = ums->num_sectors << 9;
+	curlun->num_sectors = ums->num_sectors;
 	debug("open backing file: %s\n", filename);
-	rc = 0;
 
-out:
-	return rc;
+	return 0;
 }
 
 static void fsg_lun_close(struct fsg_lun *curlun)
diff --git a/include/usb_mass_storage.h b/include/usb_mass_storage.h
index 674ca70..9df3adc 100644
--- a/include/usb_mass_storage.h
+++ b/include/usb_mass_storage.h
@@ -25,12 +25,10 @@ struct ums {
 			   ulong start, lbaint_t blkcnt, void *buf);
 	int (*write_sector)(struct ums *ums_dev,
 			    ulong start, lbaint_t blkcnt, const void *buf);
-	void (*get_capacity)(struct ums *ums_dev,
-			     long long int *capacity);
+	unsigned int start_sector;
+	unsigned int num_sectors;
 	const char *name;
 	struct mmc *mmc;
-	int offset;
-	int part_size;
 };
 
 extern struct ums *ums;
-- 
1.7.9.5



More information about the U-Boot mailing list