diff options
author | Przemyslaw Marczak <p.marczak@samsung.com> | 2013-10-23 14:30:44 +0200 |
---|---|---|
committer | Marek Vasut <marex@denx.de> | 2013-11-08 20:46:19 +0100 |
commit | 0697f206dfbbb5821fbf03283dce0b96515167cf (patch) | |
tree | 44d1700294f8d9f53243fbf60786f541020adfaa | |
parent | f4dacf7b95e9f7d4246db00facdbe366b5c30a5a (diff) | |
download | u-boot-imx-0697f206dfbbb5821fbf03283dce0b96515167cf.zip u-boot-imx-0697f206dfbbb5821fbf03283dce0b96515167cf.tar.gz u-boot-imx-0697f206dfbbb5821fbf03283dce0b96515167cf.tar.bz2 |
usb: ums: fix disk capacity miscalculation and code cleanup
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@samsung.com>
Cc: Marek Vasut <marex@denx.de>
-rw-r--r-- | board/samsung/trats/trats.c | 49 | ||||
-rw-r--r-- | drivers/usb/gadget/storage_common.c | 26 | ||||
-rw-r--r-- | 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 7d91d88..dab790f 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; |