From 93c813b3ac4b23df891992f93252c59231dec388 Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Wed, 23 Oct 2013 14:30:42 +0200 Subject: usb: ums: code refactoring to improve reusability on other boards. This patch introduces some cleanups to ums code. Changes: ums common: - introduce UMS_START_SECTOR and UMS_NUM_SECTORS as defined in usb_mass_storage.h both default values as 0 if board config doesn't define them common cleanup changes: - change name of struct "ums_board_info" to "ums" - "ums_device" fields are moved to struct ums and "dev_num" is removed - change function name: board_ums_init to ums_init - remove "extern" prefixes from usb_mass_storage.h cmd_usb_mass_storage: - change error() to printf() if need to print info message - change return values to command_ret_t type at ums command code - add command usage string Changes v2: ums common: - always returns number of read/write sectors - coding style clean-up ums gadget: - calculate amount of read/write from device returned value. Signed-off-by: Przemyslaw Marczak Cc: Marek Vasut --- board/samsung/trats/trats.c | 51 +++++++++++++++---------------------- common/cmd_usb_mass_storage.c | 27 ++++++++------------ drivers/usb/gadget/f_mass_storage.c | 43 ++++++++++++++++--------------- drivers/usb/gadget/storage_common.c | 3 +-- include/usb_mass_storage.h | 33 +++++++++++++----------- 5 files changed, 73 insertions(+), 84 deletions(-) diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index d31d511..7d91d88 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -774,63 +774,54 @@ void init_panel_info(vidinfo_t *vid) } #ifdef CONFIG_USB_GADGET_MASS_STORAGE -static int ums_read_sector(struct ums_device *ums_dev, +static int ums_read_sector(struct ums *ums_dev, ulong start, lbaint_t blkcnt, void *buf) { - if (ums_dev->mmc->block_dev.block_read(ums_dev->dev_num, - start + ums_dev->offset, blkcnt, buf) != blkcnt) - return -1; + block_dev_desc_t *block_dev = &ums_dev->mmc->block_dev; + lbaint_t blkstart = start + ums_dev->offset; + int dev_num = block_dev->dev; - return 0; + return block_dev->block_read(dev_num, blkstart, blkcnt, buf); } -static int ums_write_sector(struct ums_device *ums_dev, +static int ums_write_sector(struct ums *ums_dev, ulong start, lbaint_t blkcnt, const void *buf) { - if (ums_dev->mmc->block_dev.block_write(ums_dev->dev_num, - start + ums_dev->offset, blkcnt, buf) != blkcnt) - return -1; + block_dev_desc_t *block_dev = &ums_dev->mmc->block_dev; + lbaint_t blkstart = start + ums_dev->offset; + int dev_num = block_dev->dev; - return 0; + return block_dev->block_write(dev_num, blkstart, blkcnt, buf); } -static void ums_get_capacity(struct ums_device *ums_dev, - long long int *capacity) +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); + tmp_capacity = (long long int)((ums_dev->offset + ums_dev->part_size) + * SECTOR_SIZE); *capacity = ums_dev->mmc->capacity - tmp_capacity; } -static struct ums_board_info ums_board = { +static struct ums ums_dev = { .read_sector = ums_read_sector, .write_sector = ums_write_sector, .get_capacity = ums_get_capacity, - .name = "TRATS UMS disk", - .ums_dev = { - .mmc = NULL, - .dev_num = 0, - .offset = 0, - .part_size = 0. - }, + .name = "UMS disk", + .offset = UMS_START_SECTOR, + .part_size = UMS_NUM_SECTORS, }; -struct ums_board_info *board_ums_init(unsigned int dev_num, unsigned int offset, - unsigned int part_size) +struct ums *ums_init(unsigned int dev_num) { - struct mmc *mmc; + struct mmc *mmc = NULL; mmc = find_mmc_device(dev_num); if (!mmc) return NULL; - ums_board.ums_dev.mmc = mmc; - ums_board.ums_dev.dev_num = dev_num; - ums_board.ums_dev.offset = offset; - ums_board.ums_dev.part_size = part_size; + ums_dev.mmc = mmc; - return &ums_board; + return &ums_dev; } #endif diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c index f583caf..f6ceba7 100644 --- a/common/cmd_usb_mass_storage.c +++ b/common/cmd_usb_mass_storage.c @@ -22,28 +22,26 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, unsigned int dev_num = (unsigned int)(simple_strtoul(mmc_devstring, NULL, 0)); - if (dev_num) { - error("Set eMMC device to 0! - e.g. ums 0"); - goto fail; - } + if (dev_num) + return CMD_RET_USAGE; unsigned int controller_index = (unsigned int)(simple_strtoul( usb_controller, NULL, 0)); if (board_usb_init(controller_index, USB_INIT_DEVICE)) { error("Couldn't init USB controller."); - goto fail; + return CMD_RET_FAILURE; } - struct ums_board_info *ums_info = board_ums_init(dev_num, 0, 0); - if (!ums_info) { - error("MMC: %d -> NOT available", dev_num); - goto fail; + struct ums *ums = ums_init(dev_num); + if (!ums) { + printf("MMC: %u no such device\n", dev_num); + return CMD_RET_FAILURE; } - int rc = fsg_init(ums_info); + int rc = fsg_init(ums); if (rc) { error("fsg_init failed"); - goto fail; + return CMD_RET_FAILURE; } g_dnl_register("ums"); @@ -62,13 +60,10 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, } exit: g_dnl_unregister(); - return 0; - -fail: - return -1; + return CMD_RET_SUCCESS; } U_BOOT_CMD(ums, CONFIG_SYS_MAXARGS, 1, do_usb_mass_storage, "Use the UMS [User Mass Storage]", - " " + "ums e.g. ums 0 0" ); diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 6ecdea3..be6b418 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -441,7 +441,7 @@ static void set_bulk_out_req_length(struct fsg_common *common, /*-------------------------------------------------------------------------*/ -struct ums_board_info *ums_info; +struct ums *ums; struct fsg_common *the_fsg_common; static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) @@ -757,14 +757,14 @@ static int do_read(struct fsg_common *common) } /* Perform the read */ - nread = 0; - rc = ums_info->read_sector(&(ums_info->ums_dev), - file_offset / SECTOR_SIZE, - amount / SECTOR_SIZE, - (char __user *)bh->buf); - if (rc) + rc = ums->read_sector(ums, + file_offset / SECTOR_SIZE, + amount / SECTOR_SIZE, + (char __user *)bh->buf); + if (!rc) return -EIO; - nread = amount; + + nread = rc * SECTOR_SIZE; VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, @@ -931,13 +931,13 @@ static int do_write(struct fsg_common *common) amount = bh->outreq->actual; /* Perform the write */ - rc = ums_info->write_sector(&(ums_info->ums_dev), + rc = ums->write_sector(ums, file_offset / SECTOR_SIZE, amount / SECTOR_SIZE, (char __user *)bh->buf); - if (rc) + if (!rc) return -EIO; - nwritten = amount; + nwritten = rc * SECTOR_SIZE; VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, @@ -959,6 +959,8 @@ static int do_write(struct fsg_common *common) /* If an error occurred, report it and its position */ if (nwritten < amount) { + printf("nwritten:%d amount:%d\n", nwritten, + amount); curlun->sense_data = SS_WRITE_ERROR; curlun->info_valid = 1; break; @@ -1045,14 +1047,13 @@ static int do_verify(struct fsg_common *common) } /* Perform the read */ - nread = 0; - rc = ums_info->read_sector(&(ums_info->ums_dev), - file_offset / SECTOR_SIZE, - amount / SECTOR_SIZE, - (char __user *)bh->buf); - if (rc) + rc = ums->read_sector(ums, + file_offset / SECTOR_SIZE, + amount / SECTOR_SIZE, + (char __user *)bh->buf); + if (!rc) return -EIO; - nread = amount; + nread = rc * SECTOR_SIZE; VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, @@ -1100,7 +1101,7 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh) buf[4] = 31; /* Additional length */ /* No special options */ sprintf((char *) (buf + 8), "%-8s%-16s%04x", (char*) vendor_id , - ums_info->name, (u16) 0xffff); + ums->name, (u16) 0xffff); return 36; } @@ -2753,9 +2754,9 @@ int fsg_add(struct usb_configuration *c) return fsg_bind_config(c->cdev, c, fsg_common); } -int fsg_init(struct ums_board_info *ums) +int fsg_init(struct ums *ums_dev) { - ums_info = ums; + ums = ums_dev; return 0; } diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 866e7c7..c2c5424 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -275,7 +275,6 @@ struct rw_semaphore { int i; }; #define ETOOSMALL 525 #include -extern struct ums_board_info *ums_info; /*-------------------------------------------------------------------------*/ @@ -581,7 +580,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) /* R/W if we can, R/O if we must */ ro = curlun->initially_ro; - ums_info->get_capacity(&(ums_info->ums_dev), &size); + ums->get_capacity(ums, &size); if (size < 0) { printf("unable to find file size: %s\n", filename); rc = (int) size; diff --git a/include/usb_mass_storage.h b/include/usb_mass_storage.h index 13f535c..674ca70 100644 --- a/include/usb_mass_storage.h +++ b/include/usb_mass_storage.h @@ -9,32 +9,35 @@ #define __USB_MASS_STORAGE_H__ #define SECTOR_SIZE 0x200 - #include #include -struct ums_device { - struct mmc *mmc; - int dev_num; - int offset; - int part_size; -}; +#ifndef UMS_START_SECTOR +#define UMS_START_SECTOR 0 +#endif -struct ums_board_info { - int (*read_sector)(struct ums_device *ums_dev, +#ifndef UMS_NUM_SECTORS +#define UMS_NUM_SECTORS 0 +#endif + +struct ums { + int (*read_sector)(struct ums *ums_dev, ulong start, lbaint_t blkcnt, void *buf); - int (*write_sector)(struct ums_device *ums_dev, + int (*write_sector)(struct ums *ums_dev, ulong start, lbaint_t blkcnt, const void *buf); - void (*get_capacity)(struct ums_device *ums_dev, + void (*get_capacity)(struct ums *ums_dev, long long int *capacity); const char *name; - struct ums_device ums_dev; + struct mmc *mmc; + int offset; + int part_size; }; -int fsg_init(struct ums_board_info *); +extern struct ums *ums; + +int fsg_init(struct ums *); void fsg_cleanup(void); -struct ums_board_info *board_ums_init(unsigned int, unsigned int, - unsigned int); +struct ums *ums_init(unsigned int); int fsg_main_thread(void *); #ifdef CONFIG_USB_GADGET_MASS_STORAGE -- cgit v1.1 From f4dacf7b95e9f7d4246db00facdbe366b5c30a5a Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Wed, 23 Oct 2013 14:30:43 +0200 Subject: usb: ums: allows using every mmc device with ums. Before this change ums command only allowed use of mmc 0. Now this argument can be set. Changes: - remove mmc device number checking because it is always positive number - remove printing "no such device" - it is done by find_mmc_device() Change-Id: I767e45151ad515c7bef19e6c13087374f5e23c11 Signed-off-by: Przemyslaw Marczak Cc: Marek Vasut --- common/cmd_usb_mass_storage.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c index f6ceba7..4d3bbd8 100644 --- a/common/cmd_usb_mass_storage.c +++ b/common/cmd_usb_mass_storage.c @@ -20,10 +20,11 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, const char *usb_controller = argv[1]; const char *mmc_devstring = argv[2]; - unsigned int dev_num = (unsigned int)(simple_strtoul(mmc_devstring, - NULL, 0)); - if (dev_num) - return CMD_RET_USAGE; + unsigned int dev_num = simple_strtoul(mmc_devstring, NULL, 0); + + struct ums *ums = ums_init(dev_num); + if (!ums) + return CMD_RET_FAILURE; unsigned int controller_index = (unsigned int)(simple_strtoul( usb_controller, NULL, 0)); @@ -32,12 +33,6 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, return CMD_RET_FAILURE; } - struct ums *ums = ums_init(dev_num); - if (!ums) { - printf("MMC: %u no such device\n", dev_num); - return CMD_RET_FAILURE; - } - int rc = fsg_init(ums); if (rc) { error("fsg_init failed"); -- cgit v1.1 From 0697f206dfbbb5821fbf03283dce0b96515167cf Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Wed, 23 Oct 2013 14:30:44 +0200 Subject: 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 Cc: Marek Vasut --- 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 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; -- cgit v1.1 From 4b19ed6c765eb7f8a8873ab05db5c2dfca7f554a Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Wed, 23 Oct 2013 14:30:45 +0200 Subject: usb: ums: move ums code from trats to Samsung common directory UMS init was implemented in trats board file but mostly it comprises common code. Due to that it has been moved to common/ums.c to avoid code duplication in the future. Changes: - move ums initialization code from trats to common/ums.c - remove unused CONFIG_USB_GADGET_MASS_STORAGE from trats.h Changes v2: - move this patch at the top of code cleanups patches Signed-off-by: Przemyslaw Marczak Cc: Marek Vasut Cc: Minkyu Kang --- board/samsung/common/Makefile | 1 + board/samsung/common/ums.c | 76 +++++++++++++++++++++++++++++++++++++++++++ board/samsung/trats/trats.c | 68 -------------------------------------- include/configs/trats.h | 2 -- 4 files changed, 77 insertions(+), 70 deletions(-) create mode 100644 board/samsung/common/ums.c diff --git a/board/samsung/common/Makefile b/board/samsung/common/Makefile index ca7032c..501d974 100644 --- a/board/samsung/common/Makefile +++ b/board/samsung/common/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_SOFT_I2C_MULTI_BUS) += multi_i2c.o obj-$(CONFIG_THOR_FUNCTION) += thor.o +obj-$(CONFIG_CMD_USB_MASS_STORAGE) += ums.o diff --git a/board/samsung/common/ums.c b/board/samsung/common/ums.c new file mode 100644 index 0000000..dc155ad --- /dev/null +++ b/board/samsung/common/ums.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * Lukasz Majewski + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +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->start_sector; + int dev_num = block_dev->dev; + + return block_dev->block_read(dev_num, blkstart, blkcnt, buf); +} + +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->start_sector; + int dev_num = block_dev->dev; + + return block_dev->block_write(dev_num, blkstart, blkcnt, buf); +} + +static struct ums ums_dev = { + .read_sector = ums_read_sector, + .write_sector = ums_write_sector, + .name = "UMS disk", +}; + +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; + + mmc = find_mmc_device(dev_num); + if (!mmc) + return NULL; + + return ums_disk_init(mmc); +} diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index dab790f..7012c13 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -772,71 +772,3 @@ void init_panel_info(vidinfo_t *vid) setenv("lcdinfo", "lcd=s6e8ax0"); } - -#ifdef CONFIG_USB_GADGET_MASS_STORAGE -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->start_sector; - int dev_num = block_dev->dev; - - return block_dev->block_read(dev_num, blkstart, blkcnt, buf); -} - -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->start_sector; - int dev_num = block_dev->dev; - - return block_dev->block_write(dev_num, blkstart, blkcnt, buf); -} - -static struct ums ums_dev = { - .read_sector = ums_read_sector, - .write_sector = ums_write_sector, - .name = "UMS disk", -}; - -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; - - mmc = find_mmc_device(dev_num); - if (!mmc) - return NULL; - - return ums_disk_init(mmc); -} -#endif diff --git a/include/configs/trats.h b/include/configs/trats.h index 6ed3313..3d080c4 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -321,9 +321,7 @@ #define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE ((500 * 120 * 4) + (1 << 12)) #define CONFIG_CMD_USB_MASS_STORAGE -#if defined(CONFIG_CMD_USB_MASS_STORAGE) #define CONFIG_USB_GADGET_MASS_STORAGE -#endif /* Pass open firmware flat tree */ #define CONFIG_OF_LIBFDT 1 -- cgit v1.1 From 351e9b206934c2d4a6a0acd1547caf077e4e675c Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Wed, 23 Oct 2013 14:30:46 +0200 Subject: usb: ums: add ums exit feature by ctrl+c or by detach usb cable This patch allows exiting from UMS mode to u-boot prompt by detaching usb cable or by pressing ctrl+c. Add new config: CONFIG_USB_CABLE_CHECK. If defined then board file should provide function: usb_cable_connected() (include/usb.h) that return 1 if cable is connected and 0 otherwise. Changes v2: - add a note to the README Signed-off-by: Przemyslaw Marczak Cc: Marek Vasut --- README | 7 +++++++ common/cmd_usb_mass_storage.c | 21 +++++++++++++-------- drivers/usb/gadget/f_mass_storage.c | 24 +++++++++++++++++++++--- include/usb.h | 10 ++++++++++ 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/README b/README index 91c3ac0..b0c2fdc 100644 --- a/README +++ b/README @@ -1367,6 +1367,13 @@ The following options need to be configured: for your device - CONFIG_USBD_PRODUCTID 0xFFFF + Some USB device drivers may need to check USB cable attachment. + In this case you can enable following config in BoardName.h: + CONFIG_USB_CABLE_CHECK + This enables function definition: + - usb_cable_connected() in include/usb.h + Implementation of this function is board-specific. + - ULPI Layer Support: The ULPI (UTMI Low Pin (count) Interface) PHYs are supported via the generic ULPI layer. The generic layer accesses the ULPI PHY diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c index 4d3bbd8..99487f4 100644 --- a/common/cmd_usb_mass_storage.c +++ b/common/cmd_usb_mass_storage.c @@ -5,6 +5,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ +#include #include #include #include @@ -42,16 +43,20 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, g_dnl_register("ums"); while (1) { - /* Handle control-c and timeouts */ - if (ctrlc()) { - error("The remote end did not respond in time."); - goto exit; - } - usb_gadget_handle_interrupts(); - /* Check if USB cable has been detached */ - if (fsg_main_thread(NULL) == EIO) + + rc = fsg_main_thread(NULL); + if (rc) { + /* Check I/O error */ + if (rc == -EIO) + printf("\rCheck USB cable connection\n"); + + /* Check CTRL+C */ + if (rc == -EPIPE) + printf("\rCTRL+C - Operation aborted\n"); + goto exit; + } } exit: g_dnl_unregister(); diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index be6b418..b1fe8bd 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -243,6 +243,7 @@ #include #include #include +#include #include #include @@ -675,6 +676,18 @@ static int sleep_thread(struct fsg_common *common) k++; } + if (k == 10) { + /* Handle CTRL+C */ + if (ctrlc()) + return -EPIPE; +#ifdef CONFIG_USB_CABLE_CHECK + /* Check cable connection */ + if (!usb_cable_connected()) + return -EIO; +#endif + k = 0; + } + usb_gadget_handle_interrupts(); } common->thread_wakeup_needed = 0; @@ -2387,6 +2400,7 @@ static void handle_exception(struct fsg_common *common) int fsg_main_thread(void *common_) { + int ret; struct fsg_common *common = the_fsg_common; /* The main loop */ do { @@ -2396,12 +2410,16 @@ int fsg_main_thread(void *common_) } if (!common->running) { - sleep_thread(common); + ret = sleep_thread(common); + if (ret) + return ret; + continue; } - if (get_next_command(common)) - continue; + ret = get_next_command(common); + if (ret) + return ret; if (!exception_in_progress(common)) common->state = FSG_STATE_DATA_PHASE; diff --git a/include/usb.h b/include/usb.h index d9fedee..736730e 100644 --- a/include/usb.h +++ b/include/usb.h @@ -197,6 +197,16 @@ int board_usb_init(int index, enum usb_init_type init); */ int board_usb_cleanup(int index, enum usb_init_type init); +/* + * If CONFIG_USB_CABLE_CHECK is set then this function + * should be defined in board file. + * + * @return 1 if cable is connected and 0 otherwise. + */ +#ifdef CONFIG_USB_CABLE_CHECK +int usb_cable_connected(void); +#endif + #ifdef CONFIG_USB_STORAGE #define USB_MAX_STOR_DEV 5 -- cgit v1.1 From 522c95647df3251ffda2749ded207f30964c8866 Mon Sep 17 00:00:00 2001 From: Mateusz Kulikowski Date: Wed, 23 Oct 2013 20:26:27 +0200 Subject: usb: ohci-hcd: submit_common_msg: report actual_length properly submit_common_msg should report amount of data passed from/to device. Instead, it always returned size requested by Host. Signed-off-by: Mateusz Kulikowski --- drivers/usb/host/ohci-hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 4ed07da..219d182 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1548,7 +1548,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, } dev->status = stat; - dev->act_len = transfer_len; + dev->act_len = urb->actual_length; #ifdef DEBUG pkt_print(urb, dev, pipe, buffer, transfer_len, -- cgit v1.1 From c2617bc77323e75f68cc7aa6ce54bf39771f1e7a Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Wed, 16 Oct 2013 17:26:37 +0800 Subject: usb: dfu: decrease dfu->r_left along with the transfer The value of dfu->r_left need decrease along with the transfer Signed-off-by: Bo Shen --- drivers/dfu/dfu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index 4a8804e..cccc044 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -229,6 +229,7 @@ static int dfu_read_buffer_fill(struct dfu_entity *dfu, void *buf, int size) dfu->crc = crc32(dfu->crc, buf, chunk); dfu->i_buf += chunk; dfu->b_left -= chunk; + dfu->r_left -= chunk; size -= chunk; buf += chunk; readn += chunk; -- cgit v1.1 From 31bae4c5d9e5e7eca70d64152441bc8290016560 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Wed, 16 Oct 2013 17:26:38 +0800 Subject: usb: dfu: correct dfu buffer inited value After dfu buffer is initialized, the buffer should be all available, while not 0. Initialize its value to min(dfu_buf_size, dfu->r_left). Signed-off-by: Bo Shen Tested-by: Lukasz Majewski Acked-by: Lukasz Majewski --- drivers/dfu/dfu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index cccc044..1eb92e5 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -288,7 +288,7 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) dfu->offset = 0; dfu->i_buf_end = dfu_get_buf() + dfu_buf_size; dfu->i_buf = dfu->i_buf_start; - dfu->b_left = 0; + dfu->b_left = min(dfu_buf_size, dfu->r_left); dfu->bad_skip = 0; -- cgit v1.1 From ec9002e4fa9a1fcb769d39f54c62d661c810543b Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 4 Nov 2013 14:05:01 +0100 Subject: usb, g_dnl: make iSerialNumber board configurable add the possibility to set the iSerialNumber board specific. Default value for iSerialNumber is 0x0. This value can changed board specific through the new function g_dnl_set_serialnumber() which must be called from the board specific function g_dnl_bind_fixup(). Signed-off-by: Heiko Schocher Cc: Marek Vasut Cc: Lukasz Majewski Cc: Kyungmin Park Tested-by: Lukasz Majewski --- drivers/usb/gadget/g_dnl.c | 20 ++++++++++++++++++++ include/g_dnl.h | 1 + 2 files changed, 21 insertions(+) diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c index 43f413a..8dc3d9f 100644 --- a/drivers/usb/gadget/g_dnl.c +++ b/drivers/usb/gadget/g_dnl.c @@ -33,6 +33,9 @@ #define STRING_PRODUCT 2 /* Index of String Descriptor describing this configuration */ #define STRING_USBDOWN 2 +/* Index of String serial */ +#define STRING_SERIAL 3 +#define MAX_STRING_SERIAL 32 /* Number of supported configurations */ #define CONFIGURATION_NUMBER 1 @@ -40,8 +43,16 @@ static const char shortname[] = "usb_dnl_"; static const char product[] = "USB download gadget"; +static char g_dnl_serial[MAX_STRING_SERIAL]; static const char manufacturer[] = CONFIG_G_DNL_MANUFACTURER; +void g_dnl_set_serialnumber(char *s) +{ + memset(g_dnl_serial, 0, MAX_STRING_SERIAL); + if (strlen(s) < MAX_STRING_SERIAL) + strncpy(g_dnl_serial, s, strlen(s)); +} + static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, @@ -53,6 +64,7 @@ static struct usb_device_descriptor device_desc = { .idVendor = __constant_cpu_to_le16(CONFIG_G_DNL_VENDOR_NUM), .idProduct = __constant_cpu_to_le16(CONFIG_G_DNL_PRODUCT_NUM), .iProduct = STRING_PRODUCT, + .iSerialNumber = STRING_SERIAL, .bNumConfigurations = 1, }; @@ -63,6 +75,7 @@ static struct usb_device_descriptor device_desc = { static struct usb_string g_dnl_string_defs[] = { {.s = manufacturer}, {.s = product}, + {.s = g_dnl_serial}, { } /* end of list */ }; @@ -156,6 +169,13 @@ static int g_dnl_bind(struct usb_composite_dev *cdev) g_dnl_string_defs[1].id = id; device_desc.iProduct = id; + id = usb_string_id(cdev); + if (id < 0) + return id; + + g_dnl_string_defs[2].id = id; + device_desc.iSerialNumber = id; + g_dnl_bind_fixup(&device_desc, cdev->driver->name); ret = g_dnl_config_register(cdev); if (ret) diff --git a/include/g_dnl.h b/include/g_dnl.h index de669fb..8f813c2 100644 --- a/include/g_dnl.h +++ b/include/g_dnl.h @@ -13,5 +13,6 @@ int g_dnl_bind_fixup(struct usb_device_descriptor *, const char *); int g_dnl_register(const char *s); void g_dnl_unregister(void); +void g_dnl_set_serialnumber(char *); #endif /* __G_DOWNLOAD_H_ */ -- cgit v1.1 From 47d79deb996797dddd0984cef8b48a566c82180e Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Thu, 7 Nov 2013 14:29:41 +0800 Subject: usb: dfu: make nand upload working Nowhere pass a value to len, which always 0, make no transfer which cause uploading failed. This patch make nand upload working. However it needs enough malloc buffer to store read data, that means the buffer at least equal to the upload partition size, or else it doesn't work. Signed-off-by: Bo Shen --- drivers/dfu/dfu_nand.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dfu/dfu_nand.c b/drivers/dfu/dfu_nand.c index edbf5a9..2d07097 100644 --- a/drivers/dfu/dfu_nand.c +++ b/drivers/dfu/dfu_nand.c @@ -121,6 +121,7 @@ static int dfu_read_medium_nand(struct dfu_entity *dfu, u64 offset, void *buf, switch (dfu->layout) { case DFU_RAW_ADDR: + *len = dfu->data.nand.size; ret = nand_block_read(dfu, offset, buf, len); break; default: -- cgit v1.1