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 --- drivers/usb/gadget/f_mass_storage.c | 43 +++++++++++++++++++------------------ drivers/usb/gadget/storage_common.c | 3 +-- 2 files changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers') 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; -- 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 --- drivers/usb/gadget/storage_common.c | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) (limited to 'drivers') 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) -- 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 --- drivers/usb/gadget/f_mass_storage.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'drivers') 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; -- 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(-) (limited to 'drivers') 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(+) (limited to 'drivers') 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(-) (limited to 'drivers') 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 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers') 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) -- 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(+) (limited to 'drivers') 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