usb: ums: fix disk capacity miscalculation and code cleanup
authorPrzemyslaw Marczak <p.marczak@samsung.com>
Wed, 23 Oct 2013 12:30:44 +0000 (14:30 +0200)
committerMarek Vasut <marex@denx.de>
Fri, 8 Nov 2013 19:46:19 +0000 (20:46 +0100)
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>
board/samsung/trats/trats.c
drivers/usb/gadget/storage_common.c
include/usb_mass_storage.h

index 7d91d88879bb111fcc124278f88f256f17fe5bbe..dab790fab0ac9b7b79a700a5875a7d862a07e9d7 100644 (file)
@@ -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
index c2c5424f515698721af7e1cb2507f40d33c438b2..02803df23c52faf2f6a84c7fa69f95f5cc0c2ca1 100644 (file)
@@ -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)
index 674ca70c59a09c03270e39dbae65f79d9638df77..9df3adcf2a8e042bcc3b953c0f357a9c5945d9d5 100644 (file)
@@ -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;