[U-Boot] [U-Boot PATCH V2 0/8] introduce Rockchip rockusb

rockusb is a protocol run between host pc and device. it help people get device info, flash image to device. this patch implement rockusb on device side
Eddie Cai (8): usb: ums: split macro and data struct in f_mass_storage.c usb: ums: merge storage_common.c into f_mass_storage.c usb: ums: remove static declaration of some ums functions usb: ums: add functions to set and get usb interface descriptor usb: ums: add do_extra_command cmd: add rockusb command rockchip: config: enable rockusb support on rk3288 based board rockusb: add a simple readme
cmd/Kconfig | 5 + cmd/Makefile | 1 + cmd/rockusb.c | 383 ++++++++++++++++++++++++++++++++++++ configs/evb-rk3288_defconfig | 2 + configs/fennec-rk3288_defconfig | 1 + configs/firefly-rk3288_defconfig | 1 + configs/miqi-rk3288_defconfig | 1 + configs/popmetal-rk3288_defconfig | 1 + configs/rock2_defconfig | 2 + configs/sandbox_defconfig | 1 + configs/tinker-rk3288_defconfig | 1 + doc/README.rockusb | 35 ++++ drivers/usb/gadget/f_mass_storage.c | 356 ++++++++++++++++++++++----------- drivers/usb/gadget/storage_common.c | 238 ---------------------- include/f_mass_storage.h | 117 +++++++++++ 15 files changed, 797 insertions(+), 348 deletions(-) create mode 100644 cmd/rockusb.c create mode 100644 doc/README.rockusb delete mode 100644 drivers/usb/gadget/storage_common.c

split the macro and data struct in f_mass_storage.c to f_mass_storage.h
Signed-off-by: Eddie Cai eddie.cai.linux@gmail.com --- drivers/usb/gadget/f_mass_storage.c | 108 --------------------------------- include/f_mass_storage.h | 116 ++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 108 deletions(-)
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 1ecb92a..7164655 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -274,15 +274,6 @@ static const char fsg_string_interface[] = "Mass Storage";
/*-------------------------------------------------------------------------*/
-#define GFP_ATOMIC ((gfp_t) 0) -#define PAGE_CACHE_SHIFT 12 -#define PAGE_CACHE_SIZE (1 << PAGE_CACHE_SHIFT) -#define kthread_create(...) __builtin_return_address(0) -#define wait_for_completion(...) do {} while (0) - -struct kref {int x; }; -struct completion {int x; }; - inline void set_bit(int nr, volatile void *addr) { int mask; @@ -303,105 +294,6 @@ inline void clear_bit(int nr, volatile void *addr) *a &= ~mask; }
-struct fsg_dev; -struct fsg_common; - -/* Data shared by all the FSG instances. */ -struct fsg_common { - struct usb_gadget *gadget; - struct fsg_dev *fsg, *new_fsg; - - struct usb_ep *ep0; /* Copy of gadget->ep0 */ - struct usb_request *ep0req; /* Copy of cdev->req */ - unsigned int ep0_req_tag; - - struct fsg_buffhd *next_buffhd_to_fill; - struct fsg_buffhd *next_buffhd_to_drain; - struct fsg_buffhd buffhds[FSG_NUM_BUFFERS]; - - int cmnd_size; - u8 cmnd[MAX_COMMAND_SIZE]; - - unsigned int nluns; - unsigned int lun; - struct fsg_lun luns[FSG_MAX_LUNS]; - - unsigned int bulk_out_maxpacket; - enum fsg_state state; /* For exception handling */ - unsigned int exception_req_tag; - - enum data_direction data_dir; - u32 data_size; - u32 data_size_from_cmnd; - u32 tag; - u32 residue; - u32 usb_amount_left; - - unsigned int can_stall:1; - unsigned int free_storage_on_release:1; - unsigned int phase_error:1; - unsigned int short_packet_received:1; - unsigned int bad_lun_okay:1; - unsigned int running:1; - - int thread_wakeup_needed; - struct completion thread_notifier; - struct task_struct *thread_task; - - /* Callback functions. */ - const struct fsg_operations *ops; - /* Gadget's private data. */ - void *private_data; - - const char *vendor_name; /* 8 characters or less */ - const char *product_name; /* 16 characters or less */ - u16 release; - - /* Vendor (8 chars), product (16 chars), release (4 - * hexadecimal digits) and NUL byte */ - char inquiry_string[8 + 16 + 4 + 1]; - - struct kref ref; -}; - -struct fsg_config { - unsigned nluns; - struct fsg_lun_config { - const char *filename; - char ro; - char removable; - char cdrom; - char nofua; - } luns[FSG_MAX_LUNS]; - - /* Callback functions. */ - const struct fsg_operations *ops; - /* Gadget's private data. */ - void *private_data; - - const char *vendor_name; /* 8 characters or less */ - const char *product_name; /* 16 characters or less */ - - char can_stall; -}; - -struct fsg_dev { - struct usb_function function; - struct usb_gadget *gadget; /* Copy of cdev->gadget */ - struct fsg_common *common; - - u16 interface_number; - - unsigned int bulk_in_enabled:1; - unsigned int bulk_out_enabled:1; - - unsigned long atomic_bitflags; -#define IGNORE_BULK_OUT 0 - - struct usb_ep *bulk_in; - struct usb_ep *bulk_out; -}; -
static inline int __fsg_is_set(struct fsg_common *common, const char *func, unsigned line) diff --git a/include/f_mass_storage.h b/include/f_mass_storage.h index 679f242..620af06 100644 --- a/include/f_mass_storage.h +++ b/include/f_mass_storage.h @@ -390,4 +390,120 @@ fsg_otg_desc = { }; #endif
+ + + + +#define GFP_ATOMIC ((gfp_t) 0) +#define PAGE_CACHE_SHIFT 12 +#define PAGE_CACHE_SIZE (1 << PAGE_CACHE_SHIFT) +#define kthread_create(...) __builtin_return_address(0) +#define wait_for_completion(...) do {} while (0) + +struct kref {int x; }; +struct completion {int x; }; + + +struct fsg_dev; +struct fsg_common; + +/* Data shared by all the FSG instances. */ +struct fsg_common { + struct usb_gadget *gadget; + struct fsg_dev *fsg, *new_fsg; + + struct usb_ep *ep0; /* Copy of gadget->ep0 */ + struct usb_request *ep0req; /* Copy of cdev->req */ + unsigned int ep0_req_tag; + + struct fsg_buffhd *next_buffhd_to_fill; + struct fsg_buffhd *next_buffhd_to_drain; + struct fsg_buffhd buffhds[FSG_NUM_BUFFERS]; + + int cmnd_size; + u8 cmnd[MAX_COMMAND_SIZE]; + + unsigned int nluns; + unsigned int lun; + struct fsg_lun luns[FSG_MAX_LUNS]; + + unsigned int bulk_out_maxpacket; + enum fsg_state state; /* For exception handling */ + unsigned int exception_req_tag; + + enum data_direction data_dir; + u32 data_size; + u32 data_size_from_cmnd; + u32 tag; + u32 residue; + u32 usb_amount_left; + + unsigned int can_stall:1; + unsigned int free_storage_on_release:1; + unsigned int phase_error:1; + unsigned int short_packet_received:1; + unsigned int bad_lun_okay:1; + unsigned int running:1; + + int thread_wakeup_needed; + struct completion thread_notifier; + struct task_struct *thread_task; + + /* Callback functions. */ + const struct fsg_operations *ops; + /* Gadget's private data. */ + void *private_data; + + const char *vendor_name; /* 8 characters or less */ + const char *product_name; /* 16 characters or less */ + u16 release; + + /* Vendor (8 chars), product (16 chars), release (4 + * hexadecimal digits) and NUL byte */ + char inquiry_string[8 + 16 + 4 + 1]; + + struct kref ref; +}; + +struct fsg_config { + unsigned nluns; + struct fsg_lun_config { + const char *filename; + char ro; + char removable; + char cdrom; + char nofua; + } luns[FSG_MAX_LUNS]; + + /* Callback functions. */ + const struct fsg_operations *ops; + /* Gadget's private data. */ + void *private_data; + + const char *vendor_name; /* 8 characters or less */ + const char *product_name; /* 16 characters or less */ + + char can_stall; +}; + +struct fsg_dev { + struct usb_function function; + struct usb_gadget *gadget; /* Copy of cdev->gadget */ + struct fsg_common *common; + + u16 interface_number; + + unsigned int bulk_in_enabled:1; + unsigned int bulk_out_enabled:1; + + unsigned long atomic_bitflags; +#define IGNORE_BULK_OUT 0 + + struct usb_ep *bulk_in; + struct usb_ep *bulk_out; +}; + #endif /* __F_MASS_STORAGE_H_ */ + + +

Hi Eddie
Please add a cover letter that describe your changes. Comments follow
On Sun, Apr 16, 2017 at 5:48 PM, Eddie Cai eddie.cai.linux@gmail.com wrote:
split the macro and data struct in f_mass_storage.c to f_mass_storage.h
Signed-off-by: Eddie Cai eddie.cai.linux@gmail.com
drivers/usb/gadget/f_mass_storage.c | 108 --------------------------------- include/f_mass_storage.h | 116 ++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 108 deletions(-)
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 1ecb92a..7164655 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -274,15 +274,6 @@ static const char fsg_string_interface[] = "Mass Storage";
/*-------------------------------------------------------------------------*/
-#define GFP_ATOMIC ((gfp_t) 0) -#define PAGE_CACHE_SHIFT 12 -#define PAGE_CACHE_SIZE (1 << PAGE_CACHE_SHIFT) -#define kthread_create(...) __builtin_return_address(0) -#define wait_for_completion(...) do {} while (0)
-struct kref {int x; }; -struct completion {int x; };
inline void set_bit(int nr, volatile void *addr) { int mask; @@ -303,105 +294,6 @@ inline void clear_bit(int nr, volatile void *addr) *a &= ~mask; }
-struct fsg_dev; -struct fsg_common;
-/* Data shared by all the FSG instances. */ -struct fsg_common {
struct usb_gadget *gadget;
struct fsg_dev *fsg, *new_fsg;
struct usb_ep *ep0; /* Copy of gadget->ep0 */
struct usb_request *ep0req; /* Copy of cdev->req */
unsigned int ep0_req_tag;
struct fsg_buffhd *next_buffhd_to_fill;
struct fsg_buffhd *next_buffhd_to_drain;
struct fsg_buffhd buffhds[FSG_NUM_BUFFERS];
int cmnd_size;
u8 cmnd[MAX_COMMAND_SIZE];
unsigned int nluns;
unsigned int lun;
struct fsg_lun luns[FSG_MAX_LUNS];
unsigned int bulk_out_maxpacket;
enum fsg_state state; /* For exception handling */
unsigned int exception_req_tag;
enum data_direction data_dir;
u32 data_size;
u32 data_size_from_cmnd;
u32 tag;
u32 residue;
u32 usb_amount_left;
unsigned int can_stall:1;
unsigned int free_storage_on_release:1;
unsigned int phase_error:1;
unsigned int short_packet_received:1;
unsigned int bad_lun_okay:1;
unsigned int running:1;
int thread_wakeup_needed;
struct completion thread_notifier;
struct task_struct *thread_task;
/* Callback functions. */
const struct fsg_operations *ops;
/* Gadget's private data. */
void *private_data;
const char *vendor_name; /* 8 characters or less */
const char *product_name; /* 16 characters or less */
u16 release;
/* Vendor (8 chars), product (16 chars), release (4
* hexadecimal digits) and NUL byte */
char inquiry_string[8 + 16 + 4 + 1];
struct kref ref;
-};
-struct fsg_config {
unsigned nluns;
struct fsg_lun_config {
const char *filename;
char ro;
char removable;
char cdrom;
char nofua;
} luns[FSG_MAX_LUNS];
/* Callback functions. */
const struct fsg_operations *ops;
/* Gadget's private data. */
void *private_data;
const char *vendor_name; /* 8 characters or less */
const char *product_name; /* 16 characters or less */
char can_stall;
-};
-struct fsg_dev {
struct usb_function function;
struct usb_gadget *gadget; /* Copy of cdev->gadget */
struct fsg_common *common;
u16 interface_number;
unsigned int bulk_in_enabled:1;
unsigned int bulk_out_enabled:1;
unsigned long atomic_bitflags;
-#define IGNORE_BULK_OUT 0
struct usb_ep *bulk_in;
struct usb_ep *bulk_out;
-};
static inline int __fsg_is_set(struct fsg_common *common, const char *func, unsigned line) diff --git a/include/f_mass_storage.h b/include/f_mass_storage.h index 679f242..620af06 100644 --- a/include/f_mass_storage.h +++ b/include/f_mass_storage.h @@ -390,4 +390,120 @@ fsg_otg_desc = { }; #endif
Remove empty lines
+#define GFP_ATOMIC ((gfp_t) 0) +#define PAGE_CACHE_SHIFT 12 +#define PAGE_CACHE_SIZE (1 << PAGE_CACHE_SHIFT) +#define kthread_create(...) __builtin_return_address(0) +#define wait_for_completion(...) do {} while (0)
+struct kref {int x; }; +struct completion {int x; };
ditto
+struct fsg_dev; +struct fsg_common;
+/* Data shared by all the FSG instances. */ +struct fsg_common {
struct usb_gadget *gadget;
struct fsg_dev *fsg, *new_fsg;
struct usb_ep *ep0; /* Copy of gadget->ep0 */
struct usb_request *ep0req; /* Copy of cdev->req */
unsigned int ep0_req_tag;
struct fsg_buffhd *next_buffhd_to_fill;
struct fsg_buffhd *next_buffhd_to_drain;
struct fsg_buffhd buffhds[FSG_NUM_BUFFERS];
int cmnd_size;
u8 cmnd[MAX_COMMAND_SIZE];
unsigned int nluns;
unsigned int lun;
struct fsg_lun luns[FSG_MAX_LUNS];
unsigned int bulk_out_maxpacket;
enum fsg_state state; /* For exception handling */
unsigned int exception_req_tag;
enum data_direction data_dir;
u32 data_size;
u32 data_size_from_cmnd;
u32 tag;
u32 residue;
u32 usb_amount_left;
unsigned int can_stall:1;
unsigned int free_storage_on_release:1;
unsigned int phase_error:1;
unsigned int short_packet_received:1;
unsigned int bad_lun_okay:1;
unsigned int running:1;
int thread_wakeup_needed;
struct completion thread_notifier;
struct task_struct *thread_task;
/* Callback functions. */
const struct fsg_operations *ops;
/* Gadget's private data. */
void *private_data;
const char *vendor_name; /* 8 characters or less */
const char *product_name; /* 16 characters or less */
u16 release;
/* Vendor (8 chars), product (16 chars), release (4
* hexadecimal digits) and NUL byte */
char inquiry_string[8 + 16 + 4 + 1];
struct kref ref;
+};
+struct fsg_config {
unsigned nluns;
struct fsg_lun_config {
const char *filename;
char ro;
char removable;
char cdrom;
char nofua;
} luns[FSG_MAX_LUNS];
/* Callback functions. */
const struct fsg_operations *ops;
/* Gadget's private data. */
void *private_data;
const char *vendor_name; /* 8 characters or less */
const char *product_name; /* 16 characters or less */
char can_stall;
+};
+struct fsg_dev {
struct usb_function function;
struct usb_gadget *gadget; /* Copy of cdev->gadget */
struct fsg_common *common;
u16 interface_number;
unsigned int bulk_in_enabled:1;
unsigned int bulk_out_enabled:1;
unsigned long atomic_bitflags;
+#define IGNORE_BULK_OUT 0
struct usb_ep *bulk_in;
struct usb_ep *bulk_out;
+};
#endif /* __F_MASS_STORAGE_H_ */
ditto
Michael
-- 2.10.2
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

storage_common.c is only used by f_mass_storage. so merge it.
Signed-off-by: Eddie Cai eddie.cai.linux@gmail.com --- drivers/usb/gadget/f_mass_storage.c | 222 ++++++++++++++++++++++++++++++++- drivers/usb/gadget/storage_common.c | 238 ------------------------------------ 2 files changed, 221 insertions(+), 239 deletions(-) delete mode 100644 drivers/usb/gadget/storage_common.c
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 7164655..eb2ff82 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -270,7 +270,227 @@ static const char fsg_string_interface[] = "Mass Storage"; #define FSG_NO_OTG 1 #define FSG_NO_INTR_EP 1
-#include "storage_common.c" +#include <f_mass_storage.h> + +/* There is only one interface. */ + +static struct usb_interface_descriptor +fsg_intf_desc = { + .bLength = sizeof(fsg_intf_desc), + .bDescriptorType = USB_DT_INTERFACE, + + .bNumEndpoints = 2, /* Adjusted during fsg_bind() */ + .bInterfaceClass = USB_CLASS_MASS_STORAGE, + .bInterfaceSubClass = USB_SC_SCSI, /* Adjusted during fsg_bind() */ + .bInterfaceProtocol = USB_PR_BULK, /* Adjusted during fsg_bind() */ + .iInterface = FSG_STRING_INTERFACE, +}; + +/* + * Three full-speed endpoint descriptors: bulk-in, bulk-out, and + * interrupt-in. + */ + +static struct usb_endpoint_descriptor +fsg_fs_bulk_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + /* wMaxPacketSize set by autoconfiguration */ +}; + +static struct usb_endpoint_descriptor +fsg_fs_bulk_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + /* wMaxPacketSize set by autoconfiguration */ +}; + +#ifndef FSG_NO_INTR_EP + +static struct usb_endpoint_descriptor +fsg_fs_intr_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = cpu_to_le16(2), + .bInterval = 32, /* frames -> 32 ms */ +}; + +#ifndef FSG_NO_OTG +# define FSG_FS_FUNCTION_PRE_EP_ENTRIES 2 +#else +# define FSG_FS_FUNCTION_PRE_EP_ENTRIES 1 +#endif + +#endif + +static struct usb_descriptor_header *fsg_fs_function[] = { +#ifndef FSG_NO_OTG + (struct usb_descriptor_header *)&fsg_otg_desc, +#endif + (struct usb_descriptor_header *)&fsg_intf_desc, + (struct usb_descriptor_header *)&fsg_fs_bulk_in_desc, + (struct usb_descriptor_header *)&fsg_fs_bulk_out_desc, +#ifndef FSG_NO_INTR_EP + (struct usb_descriptor_header *)&fsg_fs_intr_in_desc, +#endif + NULL, +}; + +/* + * USB 2.0 devices need to expose both high speed and full speed + * descriptors, unless they only run at full speed. + * + * That means alternate endpoint descriptors (bigger packets) + * and a "device qualifier" ... plus more construction options + * for the configuration descriptor. + */ +static struct usb_endpoint_descriptor +fsg_hs_bulk_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(512), +}; + +static struct usb_endpoint_descriptor +fsg_hs_bulk_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(512), + .bInterval = 1, /* NAK every 1 uframe */ +}; + +#ifndef FSG_NO_INTR_EP + +static struct usb_endpoint_descriptor +fsg_hs_intr_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = cpu_to_le16(2), + .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */ +}; + +#ifndef FSG_NO_OTG +# define FSG_HS_FUNCTION_PRE_EP_ENTRIES 2 +#else +# define FSG_HS_FUNCTION_PRE_EP_ENTRIES 1 +#endif + +#endif + +static struct usb_descriptor_header *fsg_hs_function[] = { +#ifndef FSG_NO_OTG + (struct usb_descriptor_header *)&fsg_otg_desc, +#endif + (struct usb_descriptor_header *)&fsg_intf_desc, + (struct usb_descriptor_header *)&fsg_hs_bulk_in_desc, + (struct usb_descriptor_header *)&fsg_hs_bulk_out_desc, +#ifndef FSG_NO_INTR_EP + (struct usb_descriptor_header *)&fsg_hs_intr_in_desc, +#endif + NULL, +}; + +/* Maxpacket and other transfer characteristics vary by speed. */ +static struct usb_endpoint_descriptor *fsg_ep_desc( + struct usb_gadget *g, + struct usb_endpoint_descriptor *fs, + struct usb_endpoint_descriptor *hs) +{ + if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) + return hs; + return fs; +} + +/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ +static struct usb_string fsg_strings[] = { +#ifndef FSG_NO_DEVICE_STRINGS + {FSG_STRING_MANUFACTURER, fsg_string_manufacturer}, + {FSG_STRING_PRODUCT, fsg_string_product}, + {FSG_STRING_SERIAL, fsg_string_serial}, + {FSG_STRING_CONFIG, fsg_string_config}, +#endif + {FSG_STRING_INTERFACE, fsg_string_interface}, + {} +}; + +static struct usb_gadget_strings fsg_stringtab = { + .language = 0x0409, /* en-us */ + .strings = fsg_strings, +}; + +/*-------------------------------------------------------------------------*/ + +/* + * If the next two routines are called while the gadget is registered, + * the caller must own fsg->filesem for writing. + */ + +static int fsg_lun_open(struct fsg_lun *curlun, unsigned int num_sectors, + const char *filename) +{ + int ro; + + /* R/W if we can, R/O if we must */ + ro = curlun->initially_ro; + + curlun->ro = ro; + curlun->file_length = num_sectors << 9; + curlun->num_sectors = num_sectors; + debug("open backing file: %s\n", filename); + + return 0; +} + +static void fsg_lun_close(struct fsg_lun *curlun) +{ +} + +/*-------------------------------------------------------------------------*/ + +/* + * Sync the file data, don't bother with the metadata. + * This code was copied from fs/buffer.c:sys_fdatasync(). + */ +static int fsg_lun_fsync_sub(struct fsg_lun *curlun) +{ + return 0; +} + +static void store_cdrom_address(u8 *dest, int msf, u32 addr) +{ + if (msf) { + /* Convert to Minutes-Seconds-Frames */ + addr >>= 2; /* Convert to 2048-byte frames */ + addr += 2*75; /* Lead-in occupies 2 seconds */ + dest[3] = addr % 75; /* Frames */ + addr /= 75; + dest[2] = addr % 60; /* Seconds */ + addr /= 60; + dest[1] = addr; /* Minutes */ + dest[0] = 0; /* Reserved */ + } else { + /* Absolute sector */ + put_unaligned_be32(addr, dest); + } +}
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c deleted file mode 100644 index bea7607..0000000 --- a/drivers/usb/gadget/storage_common.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * storage_common.c -- Common definitions for mass storage functionality - * - * Copyright (C) 2003-2008 Alan Stern - * Copyeight (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) - * - * Ported to u-boot: - * Andrzej Pietrasiewicz andrzej.p@samsung.com - * - * Code refactoring & cleanup: - * Ćukasz Majewski l.majewski@samsung.com - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <f_mass_storage.h> - -/* There is only one interface. */ - -static struct usb_interface_descriptor -fsg_intf_desc = { - .bLength = sizeof fsg_intf_desc, - .bDescriptorType = USB_DT_INTERFACE, - - .bNumEndpoints = 2, /* Adjusted during fsg_bind() */ - .bInterfaceClass = USB_CLASS_MASS_STORAGE, - .bInterfaceSubClass = USB_SC_SCSI, /* Adjusted during fsg_bind() */ - .bInterfaceProtocol = USB_PR_BULK, /* Adjusted during fsg_bind() */ - .iInterface = FSG_STRING_INTERFACE, -}; - -/* - * Three full-speed endpoint descriptors: bulk-in, bulk-out, and - * interrupt-in. - */ - -static struct usb_endpoint_descriptor -fsg_fs_bulk_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - /* wMaxPacketSize set by autoconfiguration */ -}; - -static struct usb_endpoint_descriptor -fsg_fs_bulk_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - /* wMaxPacketSize set by autoconfiguration */ -}; - -#ifndef FSG_NO_INTR_EP - -static struct usb_endpoint_descriptor -fsg_fs_intr_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(2), - .bInterval = 32, /* frames -> 32 ms */ -}; - -#ifndef FSG_NO_OTG -# define FSG_FS_FUNCTION_PRE_EP_ENTRIES 2 -#else -# define FSG_FS_FUNCTION_PRE_EP_ENTRIES 1 -#endif - -#endif - -static struct usb_descriptor_header *fsg_fs_function[] = { -#ifndef FSG_NO_OTG - (struct usb_descriptor_header *) &fsg_otg_desc, -#endif - (struct usb_descriptor_header *) &fsg_intf_desc, - (struct usb_descriptor_header *) &fsg_fs_bulk_in_desc, - (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc, -#ifndef FSG_NO_INTR_EP - (struct usb_descriptor_header *) &fsg_fs_intr_in_desc, -#endif - NULL, -}; - -/* - * USB 2.0 devices need to expose both high speed and full speed - * descriptors, unless they only run at full speed. - * - * That means alternate endpoint descriptors (bigger packets) - * and a "device qualifier" ... plus more construction options - * for the configuration descriptor. - */ -static struct usb_endpoint_descriptor -fsg_hs_bulk_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), -}; - -static struct usb_endpoint_descriptor -fsg_hs_bulk_out_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), - .bInterval = 1, /* NAK every 1 uframe */ -}; - -#ifndef FSG_NO_INTR_EP - -static struct usb_endpoint_descriptor -fsg_hs_intr_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(2), - .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */ -}; - -#ifndef FSG_NO_OTG -# define FSG_HS_FUNCTION_PRE_EP_ENTRIES 2 -#else -# define FSG_HS_FUNCTION_PRE_EP_ENTRIES 1 -#endif - -#endif - -static struct usb_descriptor_header *fsg_hs_function[] = { -#ifndef FSG_NO_OTG - (struct usb_descriptor_header *) &fsg_otg_desc, -#endif - (struct usb_descriptor_header *) &fsg_intf_desc, - (struct usb_descriptor_header *) &fsg_hs_bulk_in_desc, - (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc, -#ifndef FSG_NO_INTR_EP - (struct usb_descriptor_header *) &fsg_hs_intr_in_desc, -#endif - NULL, -}; - -/* Maxpacket and other transfer characteristics vary by speed. */ -static struct usb_endpoint_descriptor * -fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, - struct usb_endpoint_descriptor *hs) -{ - if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) - return hs; - return fs; -} - -/* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ -static struct usb_string fsg_strings[] = { -#ifndef FSG_NO_DEVICE_STRINGS - {FSG_STRING_MANUFACTURER, fsg_string_manufacturer}, - {FSG_STRING_PRODUCT, fsg_string_product}, - {FSG_STRING_SERIAL, fsg_string_serial}, - {FSG_STRING_CONFIG, fsg_string_config}, -#endif - {FSG_STRING_INTERFACE, fsg_string_interface}, - {} -}; - -static struct usb_gadget_strings fsg_stringtab = { - .language = 0x0409, /* en-us */ - .strings = fsg_strings, -}; - -/*-------------------------------------------------------------------------*/ - -/* - * If the next two routines are called while the gadget is registered, - * the caller must own fsg->filesem for writing. - */ - -static int fsg_lun_open(struct fsg_lun *curlun, unsigned int num_sectors, - const char *filename) -{ - int ro; - - /* R/W if we can, R/O if we must */ - ro = curlun->initially_ro; - - curlun->ro = ro; - curlun->file_length = num_sectors << 9; - curlun->num_sectors = num_sectors; - debug("open backing file: %s\n", filename); - - return 0; -} - -static void fsg_lun_close(struct fsg_lun *curlun) -{ -} - -/*-------------------------------------------------------------------------*/ - -/* - * Sync the file data, don't bother with the metadata. - * This code was copied from fs/buffer.c:sys_fdatasync(). - */ -static int fsg_lun_fsync_sub(struct fsg_lun *curlun) -{ - return 0; -} - -static void store_cdrom_address(u8 *dest, int msf, u32 addr) -{ - if (msf) { - /* Convert to Minutes-Seconds-Frames */ - addr >>= 2; /* Convert to 2048-byte frames */ - addr += 2*75; /* Lead-in occupies 2 seconds */ - dest[3] = addr % 75; /* Frames */ - addr /= 75; - dest[2] = addr % 60; /* Seconds */ - addr /= 60; - dest[1] = addr; /* Minutes */ - dest[0] = 0; /* Reserved */ - } else { - /* Absolute sector */ - put_unaligned_be32(addr, dest); - } -} - -/*-------------------------------------------------------------------------*/

remove static declaration of some functions. so these functions can be called by other module
Signed-off-by: Eddie Cai eddie.cai.linux@gmail.com --- drivers/usb/gadget/f_mass_storage.c | 4 ++-- include/f_mass_storage.h | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index eb2ff82..faf875e 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -775,7 +775,7 @@ static void busy_indicator(void) state = 0; }
-static int sleep_thread(struct fsg_common *common) +int sleep_thread(struct fsg_common *common) { int rc = 0; int i = 0, k = 0; @@ -1899,7 +1899,7 @@ static int check_command(struct fsg_common *common, int cmnd_size, }
-static int do_scsi_command(struct fsg_common *common) +int do_scsi_command(struct fsg_common *common) { struct fsg_buffhd *bh; int rc; diff --git a/include/f_mass_storage.h b/include/f_mass_storage.h index 620af06..df6ea33 100644 --- a/include/f_mass_storage.h +++ b/include/f_mass_storage.h @@ -391,9 +391,6 @@ fsg_otg_desc = { #endif
- - - #define GFP_ATOMIC ((gfp_t) 0) #define PAGE_CACHE_SHIFT 12 #define PAGE_CACHE_SIZE (1 << PAGE_CACHE_SHIFT) @@ -503,7 +500,9 @@ struct fsg_dev { struct usb_ep *bulk_out; };
-#endif /* __F_MASS_STORAGE_H_ */ +int sleep_thread(struct fsg_common *common); +int do_scsi_command(struct fsg_common *common);
+#endif /* __F_MASS_STORAGE_H_ */

add functions to set and get usb interface descriptor, so people can customize usb interface descriptor
Signed-off-by: Eddie Cai eddie.cai.linux@gmail.com --- drivers/usb/gadget/f_mass_storage.c | 18 ++++++++++++++++++ include/f_mass_storage.h | 2 ++ 2 files changed, 20 insertions(+)
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index faf875e..333f069 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2870,6 +2870,24 @@ static int fsg_bind_config(struct usb_composite_dev *cdev, return rc; }
+struct usb_interface_descriptor *fsg_get_usb_interface_descriptor(void) +{ + return &fsg_intf_desc; +} + +void fsg_set_usb_interface_descriptor(struct usb_interface_descriptor *desc) +{ + if (desc) { + fsg_intf_desc.bLength = desc->bLength; + fsg_intf_desc.bDescriptorType = desc->bDescriptorType; + fsg_intf_desc.bNumEndpoints = desc->bNumEndpoints; + fsg_intf_desc.bInterfaceClass = desc->bInterfaceClass; + fsg_intf_desc.bInterfaceSubClass = desc->bInterfaceSubClass; + fsg_intf_desc.bInterfaceProtocol = desc->bInterfaceProtocol; + fsg_intf_desc.iInterface = desc->iInterface; + } +} + int fsg_add(struct usb_configuration *c) { struct fsg_common *fsg_common; diff --git a/include/f_mass_storage.h b/include/f_mass_storage.h index df6ea33..0cf29df 100644 --- a/include/f_mass_storage.h +++ b/include/f_mass_storage.h @@ -500,6 +500,8 @@ struct fsg_dev { struct usb_ep *bulk_out; };
+struct usb_interface_descriptor *fsg_get_usb_interface_descriptor(void); +void fsg_set_usb_interface_descriptor(struct usb_interface_descriptor *desc); int sleep_thread(struct fsg_common *common); int do_scsi_command(struct fsg_common *common);

add do_extra_command to let people deal with customized command
Signed-off-by: Eddie Cai eddie.cai.linux@gmail.com --- drivers/usb/gadget/f_mass_storage.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 333f069..d431e53 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2168,6 +2168,10 @@ unknown_cmnd: return 0; }
+int __weak do_extra_command(struct fsg_common *common) +{ + return -EINVAL; +} /*-------------------------------------------------------------------------*/
static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) @@ -2540,8 +2544,10 @@ int fsg_main_thread(void *common_) if (!exception_in_progress(common)) common->state = FSG_STATE_DATA_PHASE;
- if (do_scsi_command(common) || finish_reply(common)) + if ((do_extra_command(common) && do_scsi_command(common)) || + finish_reply(common)) { continue; + }
if (!exception_in_progress(common)) common->state = FSG_STATE_STATUS_PHASE;

this patch add rockusb command. the usage is rockusb <USB_controller> [<devtype>] <devnum> e.g. rockusb 0 mmc 0
Signed-off-by: Eddie Cai eddie.cai.linux@gmail.com --- cmd/Kconfig | 5 + cmd/Makefile | 1 + cmd/rockusb.c | 383 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 389 insertions(+) create mode 100644 cmd/rockusb.c
diff --git a/cmd/Kconfig b/cmd/Kconfig index 661ae7a..c94f509 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -509,6 +509,11 @@ config CMD_DFU Enables the command "dfu" which is used to have U-Boot create a DFU class device via USB.
+config CMD_ROCKUSB + bool "rockusb" + help + enables the rockusb command. + config CMD_USB_MASS_STORAGE bool "UMS usb mass storage" help diff --git a/cmd/Makefile b/cmd/Makefile index ef1406b..9111ba3 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -112,6 +112,7 @@ obj-$(CONFIG_CMD_READ) += read.o obj-$(CONFIG_CMD_REGINFO) += reginfo.o obj-$(CONFIG_CMD_REISER) += reiser.o obj-$(CONFIG_CMD_REMOTEPROC) += remoteproc.o +obj-$(CONFIG_CMD_ROCKUSB) += rockusb.o obj-$(CONFIG_SANDBOX) += host.o obj-$(CONFIG_CMD_SATA) += sata.o obj-$(CONFIG_CMD_SF) += sf.o diff --git a/cmd/rockusb.c b/cmd/rockusb.c new file mode 100644 index 0000000..883db09 --- /dev/null +++ b/cmd/rockusb.c @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2017 Eddie Cai eddie.cai.linux@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <console.h> +#include <f_mass_storage.h> +#include <g_dnl.h> +#include <usb.h> +#include <usb_mass_storage.h> + +#define K_FW_TEST_UNIT_READY 0x00 +#define K_FW_READ_FLASH_ID 0x01 +#define K_FW_SET_DEVICE_ID 0x02 +#define K_FW_TEST_BAD_BLOCK 0x03 +#define K_FW_READ_10 0x04 +#define K_FW_WRITE_10 0x05 +#define K_FW_ERASE_10 0x06 +#define K_FW_WRITE_SPARE 0x07 +#define K_FW_READ_SPARE 0x08 + +#define K_FW_ERASE_10_FORCE 0x0b +#define K_FW_GET_VERSION 0x0c + +#define K_FW_LBA_READ_10 0x14 +#define K_FW_LBA_WRITE_10 0x15 +#define K_FW_ERASE_SYS_DISK 0x16 +#define K_FW_SDRAM_READ_10 0x17 +#define K_FW_SDRAM_WRITE_10 0x18 +#define K_FW_SDRAM_EXECUTE 0x19 +#define K_FW_READ_FLASH_INFO 0x1A +#define K_FW_GET_CHIP_VER 0x1B +#define K_FW_LOW_FORMAT 0x1C +#define K_FW_SET_RESET_FLAG 0x1E +#define K_FW_SPI_READ_10 0x21 +#define K_FW_SPI_WRITE_10 0x22 + +#define K_FW_SESSION 0X30 +#define K_FW_RESET 0xff + +#define ROCKUSB_INTERFACE_CLASS 0xff +#define ROCKUSB_INTERFACE_SUB_CLASS 0x06 +#define ROCKUSB_INTERFACE_PROTOCOL 0x05 + +static struct usb_interface_descriptor rockusb_desc = { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bNumEndpoints = 0x02, + .bInterfaceClass = ROCKUSB_INTERFACE_CLASS, + .bInterfaceSubClass = ROCKUSB_INTERFACE_SUB_CLASS, + .bInterfaceProtocol = ROCKUSB_INTERFACE_PROTOCOL, + .iInterface = FSG_STRING_INTERFACE, +}; + +int __weak rkusb_set_reboot_flag(int flag) +{ + printf("rkusb_set_reboot_flag: %d\n", flag); + return -ENOSYS; +} + +static void rkusb_do_reset(struct usb_ep *ep, struct usb_request *req) +{ + do_reset(NULL, 0, 0, NULL); +} + +#ifdef DEBUG +static void printcbw(struct fsg_bulk_cb_wrap *cbw) +{ + debug("cbw: Signature:%x\n", cbw->Signature); + debug("cbw: Tag=%x\n", cbw->Tag); + debug("cbw: DataTransferLength=%d\n", cbw->DataTransferLength); + debug("cbw: Flags=%x\n", cbw->Flags); + debug("cbw: Lun=%d\n", cbw->Lun); + debug("cbw: Length=%d\n", cbw->Length); + debug("cbw: ucOperCode=%x\n", cbw->CDB[0]); + debug("cbw: ucReserved=%x\n", cbw->CDB[1]); + debug( + "cbw: dwAddress:%x %x %x %x\n", + cbw->CDB[5], cbw->CDB[4], cbw->CDB[3], cbw->CDB[2]); + debug("cbw: ucReserved2=%x\n", cbw->CDB[6]); + debug("cbw: usLength:%x %x\n", cbw->CDB[8], cbw->CDB[7]); +} + +static void printcsw(struct bulk_cs_wrap *csw) +{ + debug("csw: Signature:%x\n", csw->Signature); + debug("csw: Tag:%x\n", csw->Tag); + debug("csw: Residue:%x\n", csw->Residue); + debug("csw: Status:%x\n", csw->Status); +} +#endif + +int do_extra_command(struct fsg_common *common) +{ + struct fsg_buffhd *bh; + int rc, reply = -EINVAL; + struct usb_interface_descriptor *desc; + + desc = fsg_get_usb_interface_descriptor(); + /* make sure we are dealing with rockusb protocol */ + if (desc->bInterfaceClass != ROCKUSB_INTERFACE_CLASS || + desc->bInterfaceSubClass != ROCKUSB_INTERFACE_SUB_CLASS || + desc->bInterfaceProtocol != ROCKUSB_INTERFACE_PROTOCOL){ + return reply; + } + + /* Wait for the next buffer to become available for data or status */ + bh = common->next_buffhd_to_fill; + common->next_buffhd_to_drain = bh; +#ifdef DEBUG + struct usb_request *req; + struct fsg_bulk_cb_wrap *cbw; + req = bh->outreq; + cbw = req->buf; + printcbw(cbw); +#endif + debug("%s: cmd=%d\n", __func__, common->cmnd[0]); + while (bh->state != BUF_STATE_EMPTY) { + rc = sleep_thread(common); + if (rc) + return rc; + } + common->phase_error = 0; + common->short_packet_received = 0; + + switch (common->cmnd[0]) { + case K_FW_RESET: + common->data_size_from_cmnd = common->cmnd[4]; + rkusb_set_reboot_flag(common->cmnd[1]); + bh->inreq->complete = rkusb_do_reset; + bh->state = BUF_STATE_EMPTY; + bh->inreq->length = USB_BULK_CS_WRAP_LEN; + common->residue -= USB_BULK_CS_WRAP_LEN; + return 0; + case K_FW_LBA_WRITE_10: + common->cmnd[0] = SC_WRITE_10; + common->data_dir = DATA_DIR_FROM_HOST; + common->data_size_from_cmnd = + get_unaligned_be16(&common->cmnd[7]) << 9; + common->data_size = common->data_size_from_cmnd; + do_scsi_command(common); + return 0; + default: + return reply; + } + return reply; +} + +static int rkusb_read_sector(struct ums *rkusb_dev, + ulong start, lbaint_t blkcnt, void *buf) +{ + struct blk_desc *block_dev = &rkusb_dev->block_dev; + lbaint_t blkstart = start + rkusb_dev->start_sector; + + return blk_dread(block_dev, blkstart, blkcnt, buf); +} + +static int rkusb_write_sector(struct ums *rkusb_dev, + ulong start, lbaint_t blkcnt, const void *buf) +{ + struct blk_desc *block_dev = &rkusb_dev->block_dev; + lbaint_t blkstart = start + rkusb_dev->start_sector; + + return blk_dwrite(block_dev, blkstart, blkcnt, buf); +} + +static struct ums *rkusb; +static int rkusb_count; + +static void rkusb_fini(void) +{ + int i; + + for (i = 0; i < rkusb_count; i++) + free((void *)rkusb[i].name); + free(rkusb); + rkusb = 0; + rkusb_count = 0; +} + +#define ROCKUSB_NAME_LEN 16 + +static int rkusb_init(const char *devtype, const char *devnrkusb_part_str) +{ + char *s, *t, *devnum_part_str, *name; + struct blk_desc *block_dev; + disk_partition_t info; + int partnum; + int ret = -1; + struct ums *rkusb_new; + + s = strdup(devnrkusb_part_str); + if (!s) + return -1; + + t = s; + rkusb_count = 0; + + for (;;) { + devnum_part_str = strsep(&t, ","); + if (!devnum_part_str) + break; + + partnum = blk_get_device_part_str(devtype, devnum_part_str, + &block_dev, &info, 1); + + if (partnum < 0) + goto cleanup; + + /* Check if the argument is in legacy format. If yes, + * expose all partitions by setting the partnum = 0 + * e.g. rkusb 0 mmc 0 + */ + if (!strchr(devnum_part_str, ':')) + partnum = 0; + + /* f_mass_storage.c assumes SECTOR_SIZE sectors */ + if (block_dev->blksz != SECTOR_SIZE) + goto cleanup; + + rkusb_new = realloc(rkusb, (rkusb_count + 1) * sizeof(*rkusb)); + if (!rkusb_new) + goto cleanup; + rkusb = rkusb_new; + + /* if partnum = 0, expose all partitions */ + if (partnum == 0) { + rkusb[rkusb_count].start_sector = 0; + rkusb[rkusb_count].num_sectors = block_dev->lba; + } else { + rkusb[rkusb_count].start_sector = info.start; + rkusb[rkusb_count].num_sectors = info.size; + } + + rkusb[rkusb_count].read_sector = rkusb_read_sector; + rkusb[rkusb_count].write_sector = rkusb_write_sector; + + name = malloc(ROCKUSB_NAME_LEN); + if (!name) + goto cleanup; + snprintf(name, ROCKUSB_NAME_LEN, "rkusb disk %d", rkusb_count); + rkusb[rkusb_count].name = name; + rkusb[rkusb_count].block_dev = *block_dev; + + printf("ROCKUSB: LUN %d, dev %d, hwpart %d, sector %#x, count %#x\n", + rkusb_count, rkusb[rkusb_count].block_dev.devnum, + rkusb[rkusb_count].block_dev.hwpart, + rkusb[rkusb_count].start_sector, + rkusb[rkusb_count].num_sectors); + + rkusb_count++; + } + + if (rkusb_count) + ret = 0; + +cleanup: + free(s); + + if (ret < 0) + rkusb_fini(); + + return ret; +} + +static int do_rockusb(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + const char *usb_controller; + const char *devtype; + const char *devnum; + unsigned int controller_index; + int rc; + int cable_ready_timeout __maybe_unused; + struct usb_interface_descriptor desc; + + if (argc < 3) + return CMD_RET_USAGE; + + usb_controller = argv[1]; + if (argc >= 4) { + devtype = argv[2]; + devnum = argv[3]; + } else { + devtype = "mmc"; + devnum = argv[2]; + } + + rc = rkusb_init(devtype, devnum); + if (rc < 0) + return CMD_RET_FAILURE; + + 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."); + rc = CMD_RET_FAILURE; + goto cleanup_rkusb_init; + } + + rc = fsg_init(rkusb, rkusb_count); + if (rc) { + error("fsg_init failed"); + rc = CMD_RET_FAILURE; + goto cleanup_board; + } + + memcpy(&desc, fsg_get_usb_interface_descriptor(), + sizeof(struct usb_interface_descriptor)); + fsg_set_usb_interface_descriptor(&rockusb_desc); + rc = g_dnl_register("usb_dnl_ums"); + if (rc) { + error("g_dnl_register failed"); + rc = CMD_RET_FAILURE; + goto cleanup_board; + } + + /* Timeout unit: seconds */ + cable_ready_timeout = UMS_CABLE_READY_TIMEOUT; + + if (!g_dnl_board_usb_cable_connected()) { + /* + * Won't execute if we don't know whether the cable is + * connected. + */ + puts("Please connect USB cable.\n"); + + while (!g_dnl_board_usb_cable_connected()) { + if (ctrlc()) { + puts("\rCTRL+C - Operation aborted.\n"); + rc = CMD_RET_SUCCESS; + goto cleanup_register; + } + if (!cable_ready_timeout) { + puts("\rUSB cable not detected.Command exit.\n"); + rc = CMD_RET_SUCCESS; + goto cleanup_register; + } + + printf("\rAuto exit in: %.2d s.", cable_ready_timeout); + mdelay(1000); + cable_ready_timeout--; + } + puts("\r\n"); + } + + while (1) { + usb_gadget_handle_interrupts(controller_index); + + 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"); + + rc = CMD_RET_SUCCESS; + goto cleanup_register; + } + } + +cleanup_register: + g_dnl_unregister(); +cleanup_board: + board_usb_cleanup(controller_index, USB_INIT_DEVICE); + fsg_set_usb_interface_descriptor(&desc); +cleanup_rkusb_init: + rkusb_fini(); + + return rc; +} + +U_BOOT_CMD( + rockusb, 4, 1, do_rockusb, + "use the ROCKUSB protocol", + "rockusb <USB_controller> [<devtype>] <devnum> e.g. rockusb 0 mmc 0\n" + " devtype defaults to mmc" +);

all rk3288 based boards support rockusb, so enable it
Signed-off-by: Eddie Cai eddie.cai.linux@gmail.com --- configs/evb-rk3288_defconfig | 2 ++ configs/fennec-rk3288_defconfig | 1 + configs/firefly-rk3288_defconfig | 1 + configs/miqi-rk3288_defconfig | 1 + configs/popmetal-rk3288_defconfig | 1 + configs/rock2_defconfig | 2 ++ configs/sandbox_defconfig | 1 + configs/tinker-rk3288_defconfig | 1 + 8 files changed, 10 insertions(+)
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig index aad2533..6be46fb 100644 --- a/configs/evb-rk3288_defconfig +++ b/configs/evb-rk3288_defconfig @@ -17,6 +17,8 @@ CONFIG_CMD_MMC=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_I2C=y +CONFIG_CMD_USB=y +CONFIG_CMD_ROCKUSB=y CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_CACHE=y diff --git a/configs/fennec-rk3288_defconfig b/configs/fennec-rk3288_defconfig index d1b0ffc..ba8a356 100644 --- a/configs/fennec-rk3288_defconfig +++ b/configs/fennec-rk3288_defconfig @@ -18,6 +18,7 @@ CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_I2C=y CONFIG_CMD_USB=y +CONFIG_CMD_ROCKUSB=y CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_CACHE=y diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig index b0741d7..c860c06 100644 --- a/configs/firefly-rk3288_defconfig +++ b/configs/firefly-rk3288_defconfig @@ -17,6 +17,7 @@ CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_I2C=y CONFIG_CMD_USB=y +CONFIG_CMD_ROCKUSB=y CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_CACHE=y diff --git a/configs/miqi-rk3288_defconfig b/configs/miqi-rk3288_defconfig index 203824b..3c42d99 100644 --- a/configs/miqi-rk3288_defconfig +++ b/configs/miqi-rk3288_defconfig @@ -17,6 +17,7 @@ CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_I2C=y CONFIG_CMD_USB=y +CONFIG_CMD_ROCKUSB=y CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_CACHE=y diff --git a/configs/popmetal-rk3288_defconfig b/configs/popmetal-rk3288_defconfig index dfc84b9..ddf6062 100644 --- a/configs/popmetal-rk3288_defconfig +++ b/configs/popmetal-rk3288_defconfig @@ -18,6 +18,7 @@ CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_I2C=y CONFIG_CMD_USB=y +CONFIG_CMD_ROCKUSB=y CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_CACHE=y diff --git a/configs/rock2_defconfig b/configs/rock2_defconfig index e9a32a9..365bc90 100644 --- a/configs/rock2_defconfig +++ b/configs/rock2_defconfig @@ -16,6 +16,8 @@ CONFIG_CMD_MMC=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_I2C=y +CONFIG_CMD_USB=y +CONFIG_CMD_ROCKUSB=y CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_CACHE=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 7f3f5ac..9350d51 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -33,6 +33,7 @@ CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_I2C=y CONFIG_CMD_USB=y +CONFIG_CMD_ROCKUSB=y CONFIG_CMD_REMOTEPROC=y CONFIG_CMD_GPIO=y CONFIG_CMD_TFTPPUT=y diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig index cec3938..d96d7d3 100644 --- a/configs/tinker-rk3288_defconfig +++ b/configs/tinker-rk3288_defconfig @@ -18,6 +18,7 @@ CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_I2C=y CONFIG_CMD_USB=y +CONFIG_CMD_ROCKUSB=y CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_CACHE=y

add a simple readme to introduce rockusb and tell people how to use it
Signed-off-by: Eddie Cai eddie.cai.linux@gmail.com --- doc/README.rockusb | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 doc/README.rockusb
diff --git a/doc/README.rockusb b/doc/README.rockusb new file mode 100644 index 0000000..13893d9 --- /dev/null +++ b/doc/README.rockusb @@ -0,0 +1,35 @@ +Rockusb (Rockchip USB protocol) +===================================================== + +Overview +-------- + +Rockusb protocol is widely used with Rockchip devices. +It can read/write info, image to/from devices. This +document briefly describes how to use Rockusb for upgrading +firmware (e.g. kernel, u-boot, rootfs, etc.). + +Tools +-------- +There are many tools can support Rockusb protocol. rkdeveloptool +is open source, It is maintained by Rockchip. + +Usage +-------- +The Usage of Rockusb command is +rockusb <USB_controller> [<devtype>] <devnum> +e.g. rockusb 0 mmc 0 +rockusb 0 usb 0 +On your U-Boot console, type this command to enter rockusb mode. +On your host PC. use lsusb command. you should see a usb device +using 0x2207 as its USB verdor id. Then use rkdeveloptool +sudo rkdeveloptool wl <BeginSec> <File> +to flash U-Boot image use command +sudo rkdeveloptool wl 64 <U-Boot binary> +There are plenty of Rockusb command. but wl(write lba) and +rd(reboot) command. These two command can let people flash +image to device. + +To do +----- +* Fully support Rockusb protocol

Hi
On Sun, Apr 16, 2017 at 5:48 PM, Eddie Cai eddie.cai.linux@gmail.com wrote:
rockusb is a protocol run between host pc and device. it help people get device info, flash image to device. this patch implement rockusb on device side
Eddie Cai (8): usb: ums: split macro and data struct in f_mass_storage.c usb: ums: merge storage_common.c into f_mass_storage.c usb: ums: remove static declaration of some ums functions usb: ums: add functions to set and get usb interface descriptor usb: ums: add do_extra_command cmd: add rockusb command rockchip: config: enable rockusb support on rk3288 based board rockusb: add a simple readme
Sorry cover email arrive now ;)
Michael
cmd/Kconfig | 5 + cmd/Makefile | 1 + cmd/rockusb.c | 383 ++++++++++++++++++++++++++++++++++++ configs/evb-rk3288_defconfig | 2 + configs/fennec-rk3288_defconfig | 1 + configs/firefly-rk3288_defconfig | 1 + configs/miqi-rk3288_defconfig | 1 + configs/popmetal-rk3288_defconfig | 1 + configs/rock2_defconfig | 2 + configs/sandbox_defconfig | 1 + configs/tinker-rk3288_defconfig | 1 + doc/README.rockusb | 35 ++++ drivers/usb/gadget/f_mass_storage.c | 356 ++++++++++++++++++++++----------- drivers/usb/gadget/storage_common.c | 238 ---------------------- include/f_mass_storage.h | 117 +++++++++++ 15 files changed, 797 insertions(+), 348 deletions(-) create mode 100644 cmd/rockusb.c create mode 100644 doc/README.rockusb delete mode 100644 drivers/usb/gadget/storage_common.c
-- 2.10.2
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot

On 04/16/2017 05:48 PM, Eddie Cai wrote:
rockusb is a protocol run between host pc and device. it help people get device info, flash image to device. this patch implement rockusb on device side
What's the difference between these two series? [U-Boot PATCH V2 0/9] introduce Rockchip rockusb [U-Boot PATCH V2 0/8] introduce Rockchip rockusb
Eddie Cai (8): usb: ums: split macro and data struct in f_mass_storage.c usb: ums: merge storage_common.c into f_mass_storage.c usb: ums: remove static declaration of some ums functions usb: ums: add functions to set and get usb interface descriptor usb: ums: add do_extra_command cmd: add rockusb command rockchip: config: enable rockusb support on rk3288 based board rockusb: add a simple readme
cmd/Kconfig | 5 + cmd/Makefile | 1 + cmd/rockusb.c | 383 ++++++++++++++++++++++++++++++++++++ configs/evb-rk3288_defconfig | 2 + configs/fennec-rk3288_defconfig | 1 + configs/firefly-rk3288_defconfig | 1 + configs/miqi-rk3288_defconfig | 1 + configs/popmetal-rk3288_defconfig | 1 + configs/rock2_defconfig | 2 + configs/sandbox_defconfig | 1 + configs/tinker-rk3288_defconfig | 1 + doc/README.rockusb | 35 ++++ drivers/usb/gadget/f_mass_storage.c | 356 ++++++++++++++++++++++----------- drivers/usb/gadget/storage_common.c | 238 ---------------------- include/f_mass_storage.h | 117 +++++++++++ 15 files changed, 797 insertions(+), 348 deletions(-) create mode 100644 cmd/rockusb.c create mode 100644 doc/README.rockusb delete mode 100644 drivers/usb/gadget/storage_common.c
participants (3)
-
Eddie Cai
-
Marek Vasut
-
Michael Nazzareno Trimarchi