introduce Rockchip rockusb
cover 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 (3):
drivers: usb: gadget: add the rockusb gadget
cmd: add rockusb command
rockchip: rk3288: enable rockusb support on rk3288 based device
cmd/Kconfig | 12 + cmd/Makefile | 1 + cmd/rockusb.c | 79 ++++ drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801 ++++++++++++++++++++++++++++++++++++++++ include/configs/rk3288_common.h | 4 + include/rockusb.h | 13 + 7 files changed, 911 insertions(+) create mode 100644 cmd/rockusb.c create mode 100644 drivers/usb/gadget/f_rockusb.c create mode 100644 include/rockusb.h
Signature · 1 line
2.7.4
PATCH 1/3 drivers: usb: gadget: add the rockusb gadget
this patch implement fastboot protocol on the device side. this is based on USB download gadget infrastructure. the rockusb function implements the rd, wl, rid commands. it can work with rkdeveloptool;
https://github.com/rockchip-linux/rkdeveloptool
--- drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 802 insertions(+) create mode 100644 drivers/usb/gadget/f_rockusb.c
drivers/usb/gadget/Makefile +1 -0
@@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o +obj-$(CONFIG_USB_FUNCTION_ROCKUSB) += f_rockusb.o endif endif ifdef CONFIG_USB_ETHER
drivers/usb/gadget/f_rockusb.c new file +801 -0
801 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH 1/3 drivers: usb: gadget: add the rockusb gadget
Hi Eddie,
I recommend you to use ums framework instead of fastboot, because
ums have dual-buffer which improve performance.
Thanks,
- Kever
Quoted 831 lines · Eddie Cai
this patch implement fastboot protocol on the device side. this is based on USB download gadget infrastructure. the rockusb function implements the rd, wl, rid commands. it can work with rkdeveloptool;
https://github.com/rockchip-linux/rkdeveloptoolSigned-off-by Eddie Cai <[email protected]>--- drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 802 insertions(+)create mode 100644
drivers/usb/gadget/f_rockusb.cdrivers/usb/gadget/Makefile +1
-0@@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o +obj-$(CONFIG_USB_FUNCTION_ROCKUSB) += f_rockusb.o endif endif ifdef CONFIG_USB_ETHERdrivers/usb/gadget/f_rockusb.c new file +801
-0@@ -0,0 +1,801 @@ +/* +* (C) Copyright 2017 +* +* Eddie Cai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <config.h> +#include <common.h> +#include <errno.h> +#include <malloc.h> +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> +#include <linux/usb/composite.h> +#include <linux/compiler.h> +#include <version.h> +#include <g_dnl.h> + +#define ROCKUSB_VERSION "0.1" + +#define ROCKUSB_INTERFACE_CLASS 0xff +#define ROCKUSB_INTERFACE_SUB_CLASS 0x06 +#define ROCKUSB_INTERFACE_PROTOCOL 0x05 + +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200) +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) +#define TX_ENDPOINT_MAXIMUM_PACKET_SIZE (0x0040) + +#define EP_BUFFER_SIZE 4096 +/* +* EP_BUFFER_SIZE must always be an integral multiple of maxpacket size +* (64 or 512 or 1024), else we break on certain controllers like DWC3 +* that expect bulk OUT requests to be divisible by maxpacket size. +*/ + +struct f_rockusb { +struct usb_function usb_function; + +/* IN/OUT EP's and corresponding requests */ +struct usb_ep *in_ep, *out_ep; +struct usb_request *in_req, *out_req; +}; + +static inline struct f_rockusb *func_to_rockusb (struct usb_function *f) +{ + return container_of(f, struct f_rockusb, usb_function); +} + +static struct f_rockusb *rockusb_func; + +static struct usb_endpoint_descriptor fs_ep_in = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_IN , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (64 ), +}; + +static struct usb_endpoint_descriptor fs_ep_out = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_OUT , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (64 ), +}; + +static struct usb_endpoint_descriptor hs_ep_in = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_IN , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (512 ), +}; + +static struct usb_endpoint_descriptor hs_ep_out = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_OUT , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (512 ), +}; + +static struct usb_interface_descriptor interface_desc = { + .bLength =USB_DT_INTERFACE_SIZE , + .bDescriptorType =USB_DT_INTERFACE , + .bInterfaceNumber =0x00 , + .bAlternateSetting =0x00 , + .bNumEndpoints =0x02 , + .bInterfaceClass =ROCKUSB_INTERFACE_CLASS , + .bInterfaceSubClass =ROCKUSB_INTERFACE_SUB_CLASS , + .bInterfaceProtocol =ROCKUSB_INTERFACE_PROTOCOL , +}; + +static struct usb_descriptor_header *rkusb_fs_function[] = { + (struct usb_descriptor_header *)&interface_desc, + (struct usb_descriptor_header *)&fs_ep_in, + (struct usb_descriptor_header *)&fs_ep_out, +}; + +static struct usb_descriptor_header *rkusb_hs_function[] = { + (struct usb_descriptor_header *)&interface_desc, + (struct usb_descriptor_header *)&hs_ep_in, + (struct usb_descriptor_header *)&hs_ep_out, +NULL , +}; + +static struct usb_endpoint_descriptor * +rkusb_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 +*/ +static const char rkusb_name[] ="Rockchip Rockusb" ; + +static struct usb_string rkusb_string_defs[] = { + [0 ].s = rkusb_name, + { }/* end of list */ +}; + +static struct usb_gadget_strings stringtab_rkusb = { + .language =0x0409 ,/* en-us */ + .strings = rkusb_string_defs, +}; + +static struct usb_gadget_strings *rkusb_strings[] = { + &stringtab_rkusb, +NULL , +}; + +static void rx_handler_command (struct usb_ep *ep,struct usb_request *req); +static int rockusb_tx_write_csw (u32 Tag,int residue,u8 Status,int size); + +static void rockusb_complete (struct usb_ep *ep,struct usb_request *req) +{ +int status = req->status; +if (!status) +return ; +debug ("status: %d ep '%s' trans: %d\n" , status, ep->name, req->actual); +} + +static int rockusb_bind (struct usb_configuration *c,struct usb_function *f) +{ +int id; +struct usb_gadget *gadget = c->cdev->gadget; +struct f_rockusb *f_rkusb =func_to_rockusb (f); +const char *s; + + id =usb_interface_id (c, f); +if (id <0 ) +return id; + interface_desc.bInterfaceNumber = id; + + id =usb_string_id (c->cdev); +if (id <0 ) +return id; + + rkusb_string_defs[0 ].id = id; + interface_desc.iInterface = id; + + f_rkusb->in_ep =usb_ep_autoconfig (gadget, &fs_ep_in); +if (!f_rkusb->in_ep) +return -ENODEV ; + f_rkusb->in_ep->driver_data = c->cdev; + + f_rkusb->out_ep =usb_ep_autoconfig (gadget, &fs_ep_out); +if (!f_rkusb->out_ep) +return -ENODEV ; + f_rkusb->out_ep->driver_data = c->cdev; + + f->descriptors = rkusb_fs_function; + +if (gadget_is_dualspeed (gadget)) { + hs_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress; + hs_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress; + f->hs_descriptors = rkusb_hs_function; + } + + s =getenv ("serial#" ); +if (s) +g_dnl_set_serialnumber ((char *)s); + +return 0 ; +} + +static void rockusb_unbind (struct usb_configuration *c,struct usb_function *f) +{ +memset (rockusb_func,0 ,sizeof (*rockusb_func)); +} + +static void rockusb_disable (struct usb_function *f) +{ +struct f_rockusb *f_rkusb =func_to_rockusb (f); + +usb_ep_disable (f_rkusb->out_ep); +usb_ep_disable (f_rkusb->in_ep); + +if (f_rkusb->out_req) { +free (f_rkusb->out_req->buf); +usb_ep_free_request (f_rkusb->out_ep, f_rkusb->out_req); + f_rkusb->out_req =NULL ; + } +if (f_rkusb->in_req) { +free (f_rkusb->in_req->buf); +usb_ep_free_request (f_rkusb->in_ep, f_rkusb->in_req); + f_rkusb->in_req =NULL ; + } +} + +static struct usb_request *rockusb_start_ep (struct usb_ep *ep) +{ +struct usb_request *req; + + req =usb_ep_alloc_request (ep,0 ); +if (!req) +return NULL ; + + req->length =EP_BUFFER_SIZE ; + req->buf =memalign (CONFIG_SYS_CACHELINE_SIZE ,EP_BUFFER_SIZE ); +if (!req->buf) { +usb_ep_free_request (ep, req); +return NULL ; + } + +memset (req->buf,0 , req->length); +return req; +} + +static int rockusb_set_alt (struct usb_function *f, +unsigned interface,unsigned alt) +{ +int ret; +struct usb_composite_dev *cdev = f->config->cdev; +struct usb_gadget *gadget = cdev->gadget; +struct f_rockusb *f_rkusb =func_to_rockusb (f); +const struct usb_endpoint_descriptor *d; + +debug ("%s: func: %s intf: %d alt: %d\n" , + __func__, f->name, interface, alt); + + d =rkusb_ep_desc (gadget, &fs_ep_out, &hs_ep_out); + ret =usb_ep_enable (f_rkusb->out_ep, d); +if (ret) { +puts ("failed to enable out ep\n" ); +return ret; + } + + f_rkusb->out_req =rockusb_start_ep (f_rkusb->out_ep); +if (!f_rkusb->out_req) { +puts ("failed to alloc out req\n" ); + ret = -EINVAL ; + goto err; + } + f_rkusb->out_req->complete = rx_handler_command; + + d =rkusb_ep_desc (gadget, &fs_ep_in, &hs_ep_in); + ret =usb_ep_enable (f_rkusb->in_ep, d); +if (ret) { +puts ("failed to enable in ep\n" ); + goto err; + } + + f_rkusb->in_req =rockusb_start_ep (f_rkusb->in_ep); +if (!f_rkusb->in_req) { +puts ("failed alloc req in\n" ); + ret = -EINVAL ; + goto err; + } + f_rkusb->in_req->complete = rockusb_complete; + + ret =usb_ep_queue (f_rkusb->out_ep, f_rkusb->out_req,0 ); +if (ret) + goto err; + +return 0 ; +err: +rockusb_disable (f); +return ret; +} + +static int rockusb_add (struct usb_configuration *c) +{ +struct f_rockusb *f_rkusb = rockusb_func; +int status; + +debug ("%s: cdev: 0x%p\n" , __func__, c->cdev); + +if (!f_rkusb) { + f_rkusb =memalign (CONFIG_SYS_CACHELINE_SIZE ,sizeof (*f_rkusb)); +if (!f_rkusb) +return -ENOMEM ; + + rockusb_func = f_rkusb; +memset (f_rkusb,0 ,sizeof (*f_rkusb)); + } + + f_rkusb->usb_function.name ="f_rockusb" ; + f_rkusb->usb_function.bind = rockusb_bind; + f_rkusb->usb_function.unbind = rockusb_unbind; + f_rkusb->usb_function.set_alt = rockusb_set_alt; + f_rkusb->usb_function.disable = rockusb_disable; + f_rkusb->usb_function.strings = rkusb_strings; + + status =usb_add_function (c, &f_rkusb->usb_function); +if (status) { +free (f_rkusb); + rockusb_func = f_rkusb; + } +return status; +} + +char *rockusb_dev_type =0 ; +int rockusb_dev_index =0 ; + +void rockusb_dev_init (char *dev_type,int dev_index) +{ + rockusb_dev_type = dev_type; + rockusb_dev_index = dev_index; +} + +DECLARE_GADGET_BIND_CALLBACK (usb_dnl_rockusb, rockusb_add); + +static int rockusb_tx_write (const char *buffer,unsigned int buffer_size) +{ +struct usb_request *in_req = rockusb_func->in_req; +int ret; + +memcpy (in_req->buf, buffer, buffer_size); + in_req->length = buffer_size; +usb_ep_dequeue (rockusb_func->in_ep, in_req); + ret =usb_ep_queue (rockusb_func->in_ep, in_req,0 ); +if (ret) +printf ("Error %d on queue\n" , ret); +return 0 ; +} + +static int rockusb_tx_write_str (const char *buffer) +{ +return rockusb_tx_write (buffer,strlen (buffer)); +} + +/* Bulk-only data structures */ + +/* Command Block Wrapper */ +struct fsg_bulk_cb_wrap { +__le32 Signature;/* Contains 'USBC' */ +u32 Tag;/* Unique per command id */ +__le32 DataTransferLength;/* Size of the data */ +u8 Flags;/* Direction in bit 7 */ +u8 Lun;/* LUN (normally 0) */ +u8 Length;/* Of the CDB, <= MAX_COMMAND_SIZE */ +u8 CDB[16 ];/* Command Data Block */ +}; + +#define USB_BULK_CB_WRAP_LEN 31 +#define USB_BULK_CB_SIG 0x43425355/* Spells out USBC */ +#define USB_BULK_IN_FLAG 0x80 + +/* Command Status Wrapper */ +struct bulk_cs_wrap { +__le32 Signature;/* Should = 'USBS' */ +u32 Tag;/* Same as original command */ +__le32 Residue;/* Amount not transferred */ +u8 Status;/* See below */ +}; + +#define USB_BULK_CS_WRAP_LEN 13 +#define USB_BULK_CS_SIG 0x53425355/* Spells out 'USBS' */ +#define USB_STATUS_PASS 0 +#define USB_STATUS_FAIL 1 +#define USB_STATUS_PHASE_ERROR 2 + + +#define CSW_GOOD 0x00 +#define CSW_FAIL 0x01 + +static void printcbw (char *buf) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DMA_MINALIGN))); + +memcpy ((char *)&cbw, buf,USB_BULK_CB_WRAP_LEN ); + +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 (char *buf) +{ + struct bulk_cs_wrap csw __attribute__((aligned(ARCH_DMA_MINALIGN))); + +memcpy ((char *)&csw, buf,USB_BULK_CS_WRAP_LEN ); +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); + +} + +static int rockusb_tx_write_csw (u32 Tag,int residue,u8 Status,int size) +{ + struct bulk_cs_wrap csw __attribute__((aligned(ARCH_DMA_MINALIGN))); + csw.Signature =cpu_to_le32 (USB_BULK_CS_SIG ); + csw.Tag = Tag; + csw.Residue =cpu_to_be32 (residue); + csw.Status = Status; +printcsw ((char *)&csw); +return rockusb_tx_write ((char *)&csw, size); +} + +int download_tag =0 ; +int download_lba =0 ; +static unsigned int download_size; +static unsigned int download_bytes; +struct blk_desc *download_desc =0 ; + +static unsigned int rx_bytes_expected (struct usb_ep *ep) +{ +int rx_remain = download_size - download_bytes; +unsigned int rem; +unsigned int maxpacket = ep->maxpacket; + +if (rx_remain <=0 ) +return 0 ; +else if (rx_remain >EP_BUFFER_SIZE ) +return EP_BUFFER_SIZE ; + + rem = rx_remain % maxpacket; +if (rem >0 ) + rx_remain = rx_remain + (maxpacket - rem); + +return rx_remain; +} + +static void rx_handler_dl_image (struct usb_ep *ep,struct usb_request *req) +{ +unsigned int transfer_size = download_size - download_bytes; +const unsigned char *buffer = req->buf; +unsigned int buffer_size = req->actual; + +if (!download_desc){ +printf ("rx_handler_dl_image blk_get_dev\n" ); + download_desc =blk_get_dev (rockusb_dev_type, rockusb_dev_index); +if (!download_desc || download_desc->type ==DEV_TYPE_UNKNOWN ){ +error ("invalid mmc device\n" ); +rockusb_tx_write_csw (download_tag,0 ,CSW_FAIL , +USB_BULK_CS_WRAP_LEN ); +return ; + } + } + +if (req->status !=0 ) { +printf ("Bad status: %d\n" , req->status); +rockusb_tx_write_csw (download_tag,0 , +CSW_FAIL ,USB_BULK_CS_WRAP_LEN ); +return ; + } + +if (buffer_size < transfer_size) + transfer_size = buffer_size; + +memcpy ((void *)CONFIG_FASTBOOT_BUF_ADDR + download_bytes, + buffer, transfer_size); + download_bytes += transfer_size; + +/* Check if transfer is done */ +if (download_bytes >= download_size) { +int blks =0 , blkcnt = download_size/512 ; +printf ("download %d bytes finished, start writing to lba %x\n" , + download_bytes, download_lba); + blks =blk_dwrite (download_desc, download_lba, blkcnt, + (char *)CONFIG_FASTBOOT_BUF_ADDR ); +if (blks != blkcnt) { +error ("failed writing to device %s: %d\n" , + rockusb_dev_type, rockusb_dev_index); +rockusb_tx_write_csw (download_tag,0 , +CSW_FAIL ,USB_BULK_CS_WRAP_LEN ); +return ; + } + + req->complete = rx_handler_command; + req->length =EP_BUFFER_SIZE ; + download_size =0 ; +printf ("done\n" ); +rockusb_tx_write_csw (download_tag,0 ,CSW_GOOD , +USB_BULK_CS_WRAP_LEN ); + }else { + req->length =rx_bytes_expected (ep); + } + + req->actual =0 ; +usb_ep_queue (ep, req,0 ); +} + +static void cb_test_unit_ready (struct usb_ep *ep,struct usb_request *req) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DMA_MINALIGN))); + +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + +rockusb_tx_write_csw (cbw.Tag, cbw.DataTransferLength, +CSW_GOOD ,USB_BULK_CS_WRAP_LEN ); + +} + +static void cb_read_storage_id (struct usb_ep *ep,struct usb_request *req) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DMA_MINALIGN))); +char emmc_id[] ="EMMC " ; + +printf ("cb_read_storage_id\n" ); +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +rockusb_tx_write_str (emmc_id);//only support emmc now +rockusb_tx_write_csw (cbw.Tag, cbw.DataTransferLength,CSW_GOOD , +USB_BULK_CS_WRAP_LEN ); +} + +static void cb_write_lba (struct usb_ep *ep,struct usb_request *req) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DMA_MINALIGN))); +int sector_count; + +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + sector_count = (int )get_unaligned_be16 (&cbw.CDB[7 ]); + download_lba =get_unaligned_be32 (&cbw.CDB[2 ]); + download_size = sector_count *512 ; + download_bytes =0 ; + download_tag = cbw.Tag; +if ((0 == download_size) || (download_size>CONFIG_FASTBOOT_BUF_SIZE )){ +rockusb_tx_write_csw (cbw.Tag, cbw.DataTransferLength, +CSW_FAIL ,USB_BULK_CS_WRAP_LEN ); + }else { + req->complete = rx_handler_dl_image; + req->length =rx_bytes_expected (ep); + } +} + +static int reboot_flag; + +int __weak rkusb_set_reboot_flag (int flag) +{ +printf ("rkusb_set_reboot_flag: %d\n" , reboot_flag); +return -ENOSYS ; +} + +static void compl_do_reset (struct usb_ep *ep,struct usb_request *req) +{ +rkusb_set_reboot_flag (reboot_flag); +do_reset (NULL ,0 ,0 ,NULL ); +} + +static void cb_reboot (struct usb_ep *ep,struct usb_request *req) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DMA_MINALIGN))); + reboot_flag =0 ; +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + reboot_flag = cbw.CDB[1 ]; + rockusb_func->in_req->complete = compl_do_reset; +rockusb_tx_write_csw (cbw.Tag, cbw.DataTransferLength,CSW_GOOD , +USB_BULK_CS_WRAP_LEN ); +} + +static void cb_not_support (struct usb_ep *ep,struct usb_request *req) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DMA_MINALIGN))); + +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +printf ("Rockusb command %x not support yet\n" , cbw.CDB[0 ]); +rockusb_tx_write_csw (cbw.Tag,0 ,CSW_FAIL ,USB_BULK_CS_WRAP_LEN ); +} + +#define RKUSB_STATUS_IDLE 0 +#define RKUSB_STATUS_CMD 1 +#define RKUSB_STATUS_RXDATA 2 +#define RKUSB_STATUS_TXDATA 3 +#define RKUSB_STATUS_CSW 4 +#define RKUSB_STATUS_RXDATA_PREPARE 5 +#define RKUSB_STATUS_TXDATA_PREPARE 6 + +typedef enum { +TEST_UNIT_READY =0 , +READ_FLASH_ID =0x01 , +TEST_BAD_BLOCK =0x03 , +READ_SECTOR =0x04 , +WRITE_SECTOR =0x05 , +ERASE_NORMAL =0x06 , +ERASE_FORCE =0x0B , +READ_LBA =0x14 , +WRITE_LBA =0x15 , +ERASE_SYSTEMDISK =0x16 , +READ_SDRAM =0x17 , +WRITE_SDRAM =0x18 , +EXECUTE_SDRAM =0x19 , +READ_FLASH_INFO =0x1A , +READ_CHIP_INFO =0x1B , +SET_RESET_FLAG =0x1E , +WRITE_EFUSE =0x1F , +READ_EFUSE =0x20 , +READ_SPI_FLASH =0x21 , +WRITE_SPI_FLASH =0x22 , +WRITE_NEW_EFUSE =0x23 , +READ_NEW_EFUSE =0x24 , +DEVICE_RESET =0xFF +}USB_OPERATION_CODE ; + +#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 CBW_DIRECTION_OUT 0x00 +#define CBW_DIRECTION_IN 0x80 + +struct cmd_dispatch_info { +int cmd; +void (*cb)(struct usb_ep *ep,struct usb_request *req); +}; + +static const struct cmd_dispatch_info cmd_dispatch_info[] = { + { + .cmd =K_FW_TEST_UNIT_READY , + .cb = cb_test_unit_ready, + }, + { + .cmd =K_FW_READ_FLASH_ID , + .cb = cb_read_storage_id, + }, + { + .cmd =K_FW_SET_DEVICE_ID , + .cb = cb_not_support, + }, + { + .cmd =K_FW_TEST_BAD_BLOCK , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_ERASE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_WRITE_SPARE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_SPARE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_ERASE_10_FORCE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_GET_VERSION , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LBA_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LBA_WRITE_10 , + .cb = cb_write_lba, + }, + { + .cmd =K_FW_ERASE_SYS_DISK , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_EXECUTE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_FLASH_INFO , + .cb = cb_not_support, + }, + { + .cmd =K_FW_GET_CHIP_VER , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LOW_FORMAT , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SET_RESET_FLAG , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SPI_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SPI_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SESSION , + .cb = cb_not_support, + }, + { + .cmd =K_FW_RESET , + .cb = cb_reboot, + }, +}; + + + +static void rx_handler_command (struct usb_ep *ep,struct usb_request *req) +{ +void (*func_cb)(struct usb_ep *ep,struct usb_request *req) =NULL ; + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DMA_MINALIGN))); +int i; +char *cmdbuf = req->buf; + +if (req->status !=0 || req->length ==0 ) +return ; + +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +printcbw (req->buf); + +for (i =0 ; i <ARRAY_SIZE (cmd_dispatch_info); i++) { +if (cmd_dispatch_info[i].cmd == cbw.CDB[0 ]) { + func_cb = cmd_dispatch_info[i].cb; +break ; + } + } + +if (!func_cb) { +error ("unknown command: %s" , (char *)req->buf); +rockusb_tx_write_str ("FAILunknown command" ); + }else { +if (req->actual < req->length) { +u8 *buf = (u8 *)req->buf; + buf[req->actual] =0 ; +func_cb (ep, req); + }else { +error ("buffer overflow" ); +rockusb_tx_write_str ("FAILbuffer overflow" ); + } + } + + *cmdbuf ='\0' ; + req->actual =0 ; +usb_ep_queue (ep, req,0 ); +}
PATCH 1/3 drivers: usb: gadget: add the rockusb gadget
2017-03-16 15:05 GMT+08:00 Kever Yang <[email protected]>:
Quoted 5 lines
Hi Eddie,
I recommend you to use ums framework instead of fastboot, because
ums have dual-buffer which improve performance.
I will try to add dual buffer support in next version
Quoted 874 lines
Thanks,
- KeverQuoted 865 lines · Eddie Cai
this patch implement fastboot protocol on the device side. this is based on USB
download gadget infrastructure. the rockusb function implements the rd, wl, rid
commands. it can work with rkdeveloptool;
https://github.com/rockchip-linux/rkdeveloptoolSigned-off-by Eddie Cai <[email protected]>--- drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801 ++++++++++++++++++++++++++++++ +++++++++++ 2 files changed, 802 insertions(+)create mode 100644
drivers/usb/gadget/f_rockusb.cdrivers/usb/gadget/Makefile +1
-0@@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o +obj-$(CONFIG_USB_FUNCTION_ROCKUSB) += f_rockusb.o endif endif ifdef CONFIG_USB_ETHERdrivers/usb/gadget/f_rockusb.c new file +137
-0@@ -0,0 +1,801 @@ +/* +* (C) Copyright 2017 +* +* Eddie Cai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <config.h> +#include <common.h> +#include <errno.h> +#include <malloc.h> +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> +#include <linux/usb/composite.h> +#include <linux/compiler.h> +#include <version.h> +#include <g_dnl.h> + +#define ROCKUSB_VERSION "0.1" + +#define ROCKUSB_INTERFACE_CLASS 0xff +#define ROCKUSB_INTERFACE_SUB_CLASS 0x06 +#define ROCKUSB_INTERFACE_PROTOCOL 0x05 + +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200) +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) +#define TX_ENDPOINT_MAXIMUM_PACKET_SIZE (0x0040) + +#define EP_BUFFER_SIZE 4096 +/* +* EP_BUFFER_SIZE must always be an integral multiple of maxpacket size +* (64 or 512 or 1024), else we break on certain controllers like DWC3 +* that expect bulk OUT requests to be divisible by maxpacket size. +*/ + +struct f_rockusb { +struct usb_function usb_function; + +/* IN/OUT EP's and corresponding requests */ +struct usb_ep *in_ep, *out_ep; +struct usb_request *in_req, *out_req; +}; + +static inline struct f_rockusb *func_to_rockusb (struct usb_function *f) +{ + return container_of(f, struct f_rockusb, usb_function); +} + +static struct f_rockusb *rockusb_func; + +static struct usb_endpoint_descriptor fs_ep_in = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_IN , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (64 ), +}; + +static struct usb_endpoint_descriptor fs_ep_out = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_OUT , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (64 ), +}; + +static struct usb_endpoint_descriptor hs_ep_in = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_IN , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (512 ), +}; + +static struct usb_endpoint_descriptor hs_ep_out = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_OUT , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (512 ), +}; + +static struct usb_interface_descriptor interface_desc = { + .bLength =USB_DT_INTERFACE_SIZE , + .bDescriptorType =USB_DT_INTERFACE , + .bInterfaceNumber =0x00 , + .bAlternateSetting =0x00 , + .bNumEndpoints =0x02 , + .bInterfaceClass =ROCKUSB_INTERFACE_CLASS , + .bInterfaceSubClass =ROCKUSB_INTERFACE_SUB_CLASS , + .bInterfaceProtocol =ROCKUSB_INTERFACE_PROTOCOL , +}; + +static struct usb_descriptor_header *rkusb_fs_function[] = { + (struct usb_descriptor_header *)&interface_desc, + (struct usb_descriptor_header *)&fs_ep_in, + (struct usb_descriptor_header *)&fs_ep_out, +}; + +static struct usb_descriptor_header *rkusb_hs_function[] = { + (struct usb_descriptor_header *)&interface_desc, + (struct usb_descriptor_header *)&hs_ep_in, + (struct usb_descriptor_header *)&hs_ep_out, +NULL , +}; + +static struct usb_endpoint_descriptor * +rkusb_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 +*/ +static const char rkusb_name[] ="Rockchip Rockusb" ; + +static struct usb_string rkusb_string_defs[] = { + [0 ].s = rkusb_name, + { }/* end of list */ +}; + +static struct usb_gadget_strings stringtab_rkusb = { + .language =0x0409 ,/* en-us */ + .strings = rkusb_string_defs, +}; + +static struct usb_gadget_strings *rkusb_strings[] = { + &stringtab_rkusb, +NULL , +}; + +static void rx_handler_command(struct usb_ep *ep, struct usb_request*req);
+static introckusb_tx_write_csw(u32 Tag, int residue, u8 Status, int size);drivers/usb/gadget/f_rockusb.c new file +7
-0+ +static void rockusb_complete (struct usb_ep *ep,struct usb_request *req) +{ +int status = req->status; +if (!status) +return ; + debug("status: %d ep '%s' trans: %d\n", status, ep->name,
req->actual);drivers/usb/gadget/f_rockusb.c new file +3
-0+} + +static int rockusb_bind(struct usb_configuration *c, struct usb_function*f)
drivers/usb/gadget/f_rockusb.c new file +44
-0+{ +int id; +struct usb_gadget *gadget = c->cdev->gadget; +struct f_rockusb *f_rkusb =func_to_rockusb (f); +const char *s; + + id =usb_interface_id (c, f); +if (id <0 ) +return id; + interface_desc.bInterfaceNumber = id; + + id =usb_string_id (c->cdev); +if (id <0 ) +return id; + + rkusb_string_defs[0 ].id = id; + interface_desc.iInterface = id; + + f_rkusb->in_ep =usb_ep_autoconfig (gadget, &fs_ep_in); +if (!f_rkusb->in_ep) +return -ENODEV ; + f_rkusb->in_ep->driver_data = c->cdev; + + f_rkusb->out_ep =usb_ep_autoconfig (gadget, &fs_ep_out); +if (!f_rkusb->out_ep) +return -ENODEV ; + f_rkusb->out_ep->driver_data = c->cdev; + + f->descriptors = rkusb_fs_function; + +if (gadget_is_dualspeed (gadget)) { + hs_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress; + hs_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress; + f->hs_descriptors = rkusb_hs_function; + } + + s =getenv ("serial#" ); +if (s) +g_dnl_set_serialnumber ((char *)s); + +return 0 ; +} + +static void rockusb_unbind(struct usb_configuration *c, struct
usb_function*f)drivers/usb/gadget/f_rockusb.c new file +103
-0+{ +memset (rockusb_func,0 ,sizeof (*rockusb_func)); +} + +static void rockusb_disable (struct usb_function *f) +{ +struct f_rockusb *f_rkusb =func_to_rockusb (f); + +usb_ep_disable (f_rkusb->out_ep); +usb_ep_disable (f_rkusb->in_ep); + +if (f_rkusb->out_req) { +free (f_rkusb->out_req->buf); +usb_ep_free_request (f_rkusb->out_ep, f_rkusb->out_req); + f_rkusb->out_req =NULL ; + } +if (f_rkusb->in_req) { +free (f_rkusb->in_req->buf); +usb_ep_free_request (f_rkusb->in_ep, f_rkusb->in_req); + f_rkusb->in_req =NULL ; + } +} + +static struct usb_request *rockusb_start_ep (struct usb_ep *ep) +{ +struct usb_request *req; + + req =usb_ep_alloc_request (ep,0 ); +if (!req) +return NULL ; + + req->length =EP_BUFFER_SIZE ; + req->buf =memalign (CONFIG_SYS_CACHELINE_SIZE ,EP_BUFFER_SIZE ); +if (!req->buf) { +usb_ep_free_request (ep, req); +return NULL ; + } + +memset (req->buf,0 , req->length); +return req; +} + +static int rockusb_set_alt (struct usb_function *f, +unsigned interface,unsigned alt) +{ +int ret; +struct usb_composite_dev *cdev = f->config->cdev; +struct usb_gadget *gadget = cdev->gadget; +struct f_rockusb *f_rkusb =func_to_rockusb (f); +const struct usb_endpoint_descriptor *d; + +debug ("%s: func: %s intf: %d alt: %d\n" , + __func__, f->name, interface, alt); + + d =rkusb_ep_desc (gadget, &fs_ep_out, &hs_ep_out); + ret =usb_ep_enable (f_rkusb->out_ep, d); +if (ret) { +puts ("failed to enable out ep\n" ); +return ret; + } + + f_rkusb->out_req =rockusb_start_ep (f_rkusb->out_ep); +if (!f_rkusb->out_req) { +puts ("failed to alloc out req\n" ); + ret = -EINVAL ; + goto err; + } + f_rkusb->out_req->complete = rx_handler_command; + + d =rkusb_ep_desc (gadget, &fs_ep_in, &hs_ep_in); + ret =usb_ep_enable (f_rkusb->in_ep, d); +if (ret) { +puts ("failed to enable in ep\n" ); + goto err; + } + + f_rkusb->in_req =rockusb_start_ep (f_rkusb->in_ep); +if (!f_rkusb->in_req) { +puts ("failed alloc req in\n" ); + ret = -EINVAL ; + goto err; + } + f_rkusb->in_req->complete = rockusb_complete; + + ret =usb_ep_queue (f_rkusb->out_ep, f_rkusb->out_req,0 ); +if (ret) + goto err; + +return 0 ; +err: +rockusb_disable (f); +return ret; +} + +static int rockusb_add (struct usb_configuration *c) +{ +struct f_rockusb *f_rkusb = rockusb_func; +int status; + +debug ("%s: cdev: 0x%p\n" , __func__, c->cdev); + +if (!f_rkusb) { + f_rkusb = memalign(CONFIG_SYS_CACHELINE_SIZE,
sizeof(*f_rkusb));drivers/usb/gadget/f_rockusb.c new file +62
-0+if (!f_rkusb) +return -ENOMEM ; + + rockusb_func = f_rkusb; +memset (f_rkusb,0 ,sizeof (*f_rkusb)); + } + + f_rkusb->usb_function.name ="f_rockusb" ; + f_rkusb->usb_function.bind = rockusb_bind; + f_rkusb->usb_function.unbind = rockusb_unbind; + f_rkusb->usb_function.set_alt = rockusb_set_alt; + f_rkusb->usb_function.disable = rockusb_disable; + f_rkusb->usb_function.strings = rkusb_strings; + + status =usb_add_function (c, &f_rkusb->usb_function); +if (status) { +free (f_rkusb); + rockusb_func = f_rkusb; + } +return status; +} + +char *rockusb_dev_type =0 ; +int rockusb_dev_index =0 ; + +void rockusb_dev_init (char *dev_type,int dev_index) +{ + rockusb_dev_type = dev_type; + rockusb_dev_index = dev_index; +} + +DECLARE_GADGET_BIND_CALLBACK (usb_dnl_rockusb, rockusb_add); + +static int rockusb_tx_write (const char *buffer,unsigned int buffer_size) +{ +struct usb_request *in_req = rockusb_func->in_req; +int ret; + +memcpy (in_req->buf, buffer, buffer_size); + in_req->length = buffer_size; +usb_ep_dequeue (rockusb_func->in_ep, in_req); + ret =usb_ep_queue (rockusb_func->in_ep, in_req,0 ); +if (ret) +printf ("Error %d on queue\n" , ret); +return 0 ; +} + +static int rockusb_tx_write_str (const char *buffer) +{ +return rockusb_tx_write (buffer,strlen (buffer)); +} + +/* Bulk-only data structures */ + +/* Command Block Wrapper */ +struct fsg_bulk_cb_wrap { +__le32 Signature;/* Contains 'USBC' */ +u32 Tag;/* Unique per command id */ +__le32 DataTransferLength;/* Size of the data */ +u8 Flags;/* Direction in bit 7 */ +u8 Lun;/* LUN (normally 0) */ +u8 Length;/* Of the CDB, <=
MAX_COMMAND_SIZE*/drivers/usb/gadget/f_rockusb.c new file +5
-0+u8 CDB [16 ];/* Command Data Block */ +}; + +#define USB_BULK_CB_WRAP_LEN 31 +#define USB_BULK_CB_SIG 0x43425355/* Spells out USBC */
drivers/usb/gadget/f_rockusb.c new file +12
-0+#define USB_BULK_IN_FLAG 0x80 + +/* Command Status Wrapper */ +struct bulk_cs_wrap { +__le32 Signature;/* Should = 'USBS' */ +u32 Tag;/* Same as original command */ +__le32 Residue;/* Amount not transferred */ +u8 Status;/* See below */ +}; + +#define USB_BULK_CS_WRAP_LEN 13 +#define USB_BULK_CS_SIG 0x53425355/* Spells out 'USBS' */
drivers/usb/gadget/f_rockusb.c new file +11
-0+#define USB_STATUS_PASS 0 +#define USB_STATUS_FAIL 1 +#define USB_STATUS_PHASE_ERROR 2 + + +#define CSW_GOOD 0x00 +#define CSW_FAIL 0x01 + +static void printcbw (char *buf) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +21
-0+ +memcpy ((char *)&cbw, buf,USB_BULK_CB_WRAP_LEN ); + +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 (char *buf) +{ + struct bulk_cs_wrap csw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +10
-0+ +memcpy ((char *)&csw, buf,USB_BULK_CS_WRAP_LEN ); +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); + +} + +static int rockusb_tx_write_csw(u32 Tag, int residue, u8 Status, intsize)
drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + struct bulk_cs_wrap csw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +33
-0+ csw.Signature =cpu_to_le32 (USB_BULK_CS_SIG ); + csw.Tag = Tag; + csw.Residue =cpu_to_be32 (residue); + csw.Status = Status; +printcsw ((char *)&csw); +return rockusb_tx_write ((char *)&csw, size); +} + +int download_tag =0 ; +int download_lba =0 ; +static unsigned int download_size; +static unsigned int download_bytes; +struct blk_desc *download_desc =0 ; + +static unsigned int rx_bytes_expected (struct usb_ep *ep) +{ +int rx_remain = download_size - download_bytes; +unsigned int rem; +unsigned int maxpacket = ep->maxpacket; + +if (rx_remain <=0 ) +return 0 ; +else if (rx_remain >EP_BUFFER_SIZE ) +return EP_BUFFER_SIZE ; + + rem = rx_remain % maxpacket; +if (rem >0 ) + rx_remain = rx_remain + (maxpacket - rem); + +return rx_remain; +} + +static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request*req)
drivers/usb/gadget/f_rockusb.c new file +8
-0+{ +unsigned int transfer_size = download_size - download_bytes; +const unsigned char *buffer = req->buf; +unsigned int buffer_size = req->actual; + +if (!download_desc){ +printf ("rx_handler_dl_image blk_get_dev\n" ); + download_desc = blk_get_dev(rockusb_dev_type,
rockusb_dev_index);
+ if (!download_desc ||download_desc->type==
DEV_TYPE_UNKNOWN){drivers/usb/gadget/f_rockusb.c new file +25
-0+error ("invalid mmc device\n" ); +rockusb_tx_write_csw (download_tag,0 ,CSW_FAIL , +USB_BULK_CS_WRAP_LEN ); +return ; + } + } + +if (req->status !=0 ) { +printf ("Bad status: %d\n" , req->status); +rockusb_tx_write_csw (download_tag,0 , +CSW_FAIL ,USB_BULK_CS_WRAP_LEN ); +return ; + } + +if (buffer_size < transfer_size) + transfer_size = buffer_size; + +memcpy ((void *)CONFIG_FASTBOOT_BUF_ADDR + download_bytes, + buffer, transfer_size); + download_bytes += transfer_size; + +/* Check if transfer is done */ +if (download_bytes >= download_size) { +int blks =0 , blkcnt = download_size/512 ; + printf("download %d bytes finished, start writing to lba%x\n",
drivers/usb/gadget/f_rockusb.c new file +8
-0+ download_bytes, download_lba); + blks =blk_dwrite (download_desc, download_lba, blkcnt, + (char *)CONFIG_FASTBOOT_BUF_ADDR ); +if (blks != blkcnt) { +error ("failed writing to device %s: %d\n" , + rockusb_dev_type, rockusb_dev_index); + rockusb_tx_write_csw(download_tag, 0, + CSW_FAIL,
USB_BULK_CS_WRAP_LEN);drivers/usb/gadget/f_rockusb.c new file +18
-0+return ; + } + + req->complete = rx_handler_command; + req->length =EP_BUFFER_SIZE ; + download_size =0 ; +printf ("done\n" ); +rockusb_tx_write_csw (download_tag,0 ,CSW_GOOD , +USB_BULK_CS_WRAP_LEN ); + }else { + req->length =rx_bytes_expected (ep); + } + + req->actual =0 ; +usb_ep_queue (ep, req,0 ); +} + +static void cb_test_unit_ready(struct usb_ep *ep, struct usb_request*req)
drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +9
-0+ +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + +rockusb_tx_write_csw (cbw.Tag, cbw.DataTransferLength, +CSW_GOOD ,USB_BULK_CS_WRAP_LEN ); + +} + +static void cb_read_storage_id(struct usb_ep *ep, struct usb_request*req)
drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +12
-0+char emmc_id[] ="EMMC " ; + +printf ("cb_read_storage_id\n" ); +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +rockusb_tx_write_str (emmc_id);//only support emmc now +rockusb_tx_write_csw (cbw.Tag, cbw.DataTransferLength,CSW_GOOD , +USB_BULK_CS_WRAP_LEN ); +} + +static void cb_write_lba (struct usb_ep *ep,struct usb_request *req) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +9
-0+int sector_count; + +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + sector_count = (int )get_unaligned_be16 (&cbw.CDB[7 ]); + download_lba =get_unaligned_be32 (&cbw.CDB[2 ]); + download_size = sector_count *512 ; + download_bytes =0 ; + download_tag = cbw.Tag; + if ((0 == download_size) || (download_size>CONFIG_FASTBOOT_BUF_SIZE)){
drivers/usb/gadget/f_rockusb.c new file +25
-0+rockusb_tx_write_csw (cbw.Tag, cbw.DataTransferLength, +CSW_FAIL ,USB_BULK_CS_WRAP_LEN ); + }else { + req->complete = rx_handler_dl_image; + req->length =rx_bytes_expected (ep); + } +} + +static int reboot_flag; + +int __weak rkusb_set_reboot_flag (int flag) +{ +printf ("rkusb_set_reboot_flag: %d\n" , reboot_flag); +return -ENOSYS ; +} + +static void compl_do_reset (struct usb_ep *ep,struct usb_request *req) +{ +rkusb_set_reboot_flag (reboot_flag); +do_reset (NULL ,0 ,0 ,NULL ); +} + +static void cb_reboot (struct usb_ep *ep,struct usb_request *req) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +11
-0+ reboot_flag =0 ; +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + reboot_flag = cbw.CDB[1 ]; + rockusb_func->in_req->complete = compl_do_reset; +rockusb_tx_write_csw (cbw.Tag, cbw.DataTransferLength,CSW_GOOD , +USB_BULK_CS_WRAP_LEN ); +} + +static void cb_not_support (struct usb_ep *ep,struct usb_request *req) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +183
-0+ +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +printf ("Rockusb command %x not support yet\n" , cbw.CDB[0 ]); +rockusb_tx_write_csw (cbw.Tag,0 ,CSW_FAIL ,USB_BULK_CS_WRAP_LEN ); +} + +#define RKUSB_STATUS_IDLE 0 +#define RKUSB_STATUS_CMD 1 +#define RKUSB_STATUS_RXDATA 2 +#define RKUSB_STATUS_TXDATA 3 +#define RKUSB_STATUS_CSW 4 +#define RKUSB_STATUS_RXDATA_PREPARE 5 +#define RKUSB_STATUS_TXDATA_PREPARE 6 + +typedef enum { +TEST_UNIT_READY =0 , +READ_FLASH_ID =0x01 , +TEST_BAD_BLOCK =0x03 , +READ_SECTOR =0x04 , +WRITE_SECTOR =0x05 , +ERASE_NORMAL =0x06 , +ERASE_FORCE =0x0B , +READ_LBA =0x14 , +WRITE_LBA =0x15 , +ERASE_SYSTEMDISK =0x16 , +READ_SDRAM =0x17 , +WRITE_SDRAM =0x18 , +EXECUTE_SDRAM =0x19 , +READ_FLASH_INFO =0x1A , +READ_CHIP_INFO =0x1B , +SET_RESET_FLAG =0x1E , +WRITE_EFUSE =0x1F , +READ_EFUSE =0x20 , +READ_SPI_FLASH =0x21 , +WRITE_SPI_FLASH =0x22 , +WRITE_NEW_EFUSE =0x23 , +READ_NEW_EFUSE =0x24 , +DEVICE_RESET =0xFF +}USB_OPERATION_CODE ; + +#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 CBW_DIRECTION_OUT 0x00 +#define CBW_DIRECTION_IN 0x80 + +struct cmd_dispatch_info { +int cmd; +void (*cb)(struct usb_ep *ep,struct usb_request *req); +}; + +static const struct cmd_dispatch_info cmd_dispatch_info[] = { + { + .cmd =K_FW_TEST_UNIT_READY , + .cb = cb_test_unit_ready, + }, + { + .cmd =K_FW_READ_FLASH_ID , + .cb = cb_read_storage_id, + }, + { + .cmd =K_FW_SET_DEVICE_ID , + .cb = cb_not_support, + }, + { + .cmd =K_FW_TEST_BAD_BLOCK , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_ERASE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_WRITE_SPARE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_SPARE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_ERASE_10_FORCE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_GET_VERSION , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LBA_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LBA_WRITE_10 , + .cb = cb_write_lba, + }, + { + .cmd =K_FW_ERASE_SYS_DISK , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_EXECUTE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_FLASH_INFO , + .cb = cb_not_support, + }, + { + .cmd =K_FW_GET_CHIP_VER , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LOW_FORMAT , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SET_RESET_FLAG , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SPI_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SPI_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SESSION , + .cb = cb_not_support, + }, + { + .cmd =K_FW_RESET , + .cb = cb_reboot, + }, +}; + + + +static void rx_handler_command(struct usb_ep *ep, struct usb_request*req)
drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + void (*func_cb)(struct usb_ep *ep, struct usb_request *req) =NULL;
+ structfsg_bulk_cb_wrapcbw __attribute__((aligned(ARCH_DMA_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +34
-0+int i; +char *cmdbuf = req->buf; + +if (req->status !=0 || req->length ==0 ) +return ; + +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +printcbw (req->buf); + +for (i =0 ; i <ARRAY_SIZE (cmd_dispatch_info); i++) { +if (cmd_dispatch_info[i].cmd == cbw.CDB[0 ]) { + func_cb = cmd_dispatch_info[i].cb; +break ; + } + } + +if (!func_cb) { +error ("unknown command: %s" , (char *)req->buf); +rockusb_tx_write_str ("FAILunknown command" ); + }else { +if (req->actual < req->length) { +u8 *buf = (u8 *)req->buf; + buf[req->actual] =0 ; +func_cb (ep, req); + }else { +error ("buffer overflow" ); +rockusb_tx_write_str ("FAILbuffer overflow" ); + } + } + + *cmdbuf ='\0' ; + req->actual =0 ; +usb_ep_queue (ep, req,0 ); +}
PATCH 1/3 drivers: usb: gadget: add the rockusb gadget
Hi Eddie,
Quoted 8 lines
2017-03-16 15:05 GMT+08:00 Kever Yang <[email protected]>:
Quoted 5 lines
Hi Eddie,
I recommend you to use ums framework instead of fastboot,
because ums have dual-buffer which improve performance.I will try to add dual buffer support in next version
If of course possible - please reuse as much code as possible.
Quoted 893 lines
Quoted 893 lines
Thanks,
- KeverQuoted 886 lines · Eddie Cai
this patch implement fastboot protocol on the device side. this is based on USB
download gadget infrastructure. the rockusb function implements the rd, wl, rid
commands. it can work with rkdeveloptool;
https://github.com/rockchip-linux/rkdeveloptoolSigned-off-by Eddie Cai <[email protected]>--- drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801 ++++++++++++++++++++++++++++++ +++++++++++ 2 files changed, 802 insertions(+)create mode 100644
drivers/usb/gadget/f_rockusb.c(quoted diff) +0
-0b/drivers/usb/gadget/Makefile index 0fbbb7c..0eb27a3 100644
drivers/usb/gadget/Makefile +1
-0@@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o +obj-$(CONFIG_USB_FUNCTION_ROCKUSB) += f_rockusb.o endif endif ifdef CONFIG_USB_ETHERdrivers/usb/gadget/f_rockusb.c new file +32
-0@@ -0,0 +1,801 @@ +/* +* (C) Copyright 2017 +* +* Eddie Cai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <config.h> +#include <common.h> +#include <errno.h> +#include <malloc.h> +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> +#include <linux/usb/composite.h> +#include <linux/compiler.h> +#include <version.h> +#include <g_dnl.h> + +#define ROCKUSB_VERSION "0.1" + +#define ROCKUSB_INTERFACE_CLASS 0xff +#define ROCKUSB_INTERFACE_SUB_CLASS 0x06 +#define ROCKUSB_INTERFACE_PROTOCOL 0x05 + +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200) +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) +#define TX_ENDPOINT_MAXIMUM_PACKET_SIZE (0x0040) + +#define EP_BUFFER_SIZE 4096 +/* +* EP_BUFFER_SIZE must always be an integral multiple of maxpacket size
+ * (64 or 512 or 1024), else we break on certain controllers like DWC3
+ * that expect bulk OUT requests to be divisible by maxpacket size.
+ */drivers/usb/gadget/f_rockusb.c new file +10
-0+ +struct f_rockusb { +struct usb_function usb_function; + +/* IN/OUT EP's and corresponding requests */ +struct usb_ep *in_ep, *out_ep; +struct usb_request *in_req, *out_req; +}; + +static inline struct f_rockusb *func_to_rockusb(struct
usb_function*f) +{drivers/usb/gadget/f_rockusb.c new file +63
-0+ return container_of(f, struct f_rockusb, usb_function); +} + +static struct f_rockusb *rockusb_func; + +static struct usb_endpoint_descriptor fs_ep_in = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_IN , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (64 ), +}; + +static struct usb_endpoint_descriptor fs_ep_out = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_OUT , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (64 ), +}; + +static struct usb_endpoint_descriptor hs_ep_in = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_IN , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (512 ), +}; + +static struct usb_endpoint_descriptor hs_ep_out = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_OUT , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (512 ), +}; + +static struct usb_interface_descriptor interface_desc = { + .bLength =USB_DT_INTERFACE_SIZE , + .bDescriptorType =USB_DT_INTERFACE , + .bInterfaceNumber =0x00 , + .bAlternateSetting =0x00 , + .bNumEndpoints =0x02 , + .bInterfaceClass =ROCKUSB_INTERFACE_CLASS , + .bInterfaceSubClass =ROCKUSB_INTERFACE_SUB_CLASS , + .bInterfaceProtocol =ROCKUSB_INTERFACE_PROTOCOL , +}; + +static struct usb_descriptor_header *rkusb_fs_function[] = { + (struct usb_descriptor_header *)&interface_desc, + (struct usb_descriptor_header *)&fs_ep_in, + (struct usb_descriptor_header *)&fs_ep_out, +}; + +static struct usb_descriptor_header *rkusb_hs_function[] = { + (struct usb_descriptor_header *)&interface_desc, + (struct usb_descriptor_header *)&hs_ep_in, + (struct usb_descriptor_header *)&hs_ep_out, +NULL , +}; + +static struct usb_endpoint_descriptor * +rkusb_ep_desc(struct usb_gadget *g, struct
usb_endpoint_descriptor*fs,drivers/usb/gadget/f_rockusb.c new file +28
-0+ struct usb_endpoint_descriptor *hs) +{ +if (gadget_is_dualspeed (g) && g->speed ==USB_SPEED_HIGH ) +return hs; +return fs; +} + +/* +* static strings, in UTF-8 +*/ +static const char rkusb_name[] ="Rockchip Rockusb" ; + +static struct usb_string rkusb_string_defs[] = { + [0 ].s = rkusb_name, + { }/* end of list */ +}; + +static struct usb_gadget_strings stringtab_rkusb = { + .language =0x0409 ,/* en-us */ + .strings = rkusb_string_defs, +}; + +static struct usb_gadget_strings *rkusb_strings[] = { + &stringtab_rkusb, +NULL , +}; + +static void rx_handler_command(struct usb_ep *ep, struct
usb_request*req);
+static introckusb_tx_write_csw(u32 Tag, int residue, u8 Status, int size);drivers/usb/gadget/f_rockusb.c new file +2
-0+ +static void rockusb_complete(struct usb_ep *ep, struct
usb_request*req) +{drivers/usb/gadget/f_rockusb.c new file +4
-0+int status = req->status; +if (!status) +return ; + debug("status: %d ep '%s' trans: %d\n", status, ep->name,
req->actual);drivers/usb/gadget/f_rockusb.c new file +3
-0+} + +static int rockusb_bind(struct usb_configuration *c, struct
usb_function*f)drivers/usb/gadget/f_rockusb.c new file +32
-0+{ +int id; +struct usb_gadget *gadget = c->cdev->gadget; +struct f_rockusb *f_rkusb =func_to_rockusb (f); +const char *s; + + id =usb_interface_id (c, f); +if (id <0 ) +return id; + interface_desc.bInterfaceNumber = id; + + id =usb_string_id (c->cdev); +if (id <0 ) +return id; + + rkusb_string_defs[0 ].id = id; + interface_desc.iInterface = id; + + f_rkusb->in_ep =usb_ep_autoconfig (gadget, &fs_ep_in); +if (!f_rkusb->in_ep) +return -ENODEV ; + f_rkusb->in_ep->driver_data = c->cdev; + + f_rkusb->out_ep =usb_ep_autoconfig (gadget, &fs_ep_out); +if (!f_rkusb->out_ep) +return -ENODEV ; + f_rkusb->out_ep->driver_data = c->cdev; + + f->descriptors = rkusb_fs_function; + +if (gadget_is_dualspeed (gadget)) { + hs_ep_in.bEndpointAddress =fs_ep_in.bEndpointAddress;
+ hs_ep_out.bEndpointAddress =
fs_ep_out.bEndpointAddress;drivers/usb/gadget/f_rockusb.c new file +11
-0+ f->hs_descriptors = rkusb_hs_function; + } + + s =getenv ("serial#" ); +if (s) +g_dnl_set_serialnumber ((char *)s); + +return 0 ; +} + +static void rockusb_unbind(struct usb_configuration *c, struct
usb_function*f)drivers/usb/gadget/f_rockusb.c new file +14
-0+{ +memset (rockusb_func,0 ,sizeof (*rockusb_func)); +} + +static void rockusb_disable (struct usb_function *f) +{ +struct f_rockusb *f_rkusb =func_to_rockusb (f); + +usb_ep_disable (f_rkusb->out_ep); +usb_ep_disable (f_rkusb->in_ep); + +if (f_rkusb->out_req) { +free (f_rkusb->out_req->buf); + usb_ep_free_request(f_rkusb->out_ep,
f_rkusb->out_req);drivers/usb/gadget/f_rockusb.c new file +5
-0+ f_rkusb->out_req =NULL ; + } +if (f_rkusb->in_req) { +free (f_rkusb->in_req->buf); + usb_ep_free_request(f_rkusb->in_ep,
f_rkusb->in_req);drivers/usb/gadget/f_rockusb.c new file +14
-0+ f_rkusb->in_req =NULL ; + } +} + +static struct usb_request *rockusb_start_ep (struct usb_ep *ep) +{ +struct usb_request *req; + + req =usb_ep_alloc_request (ep,0 ); +if (!req) +return NULL ; + + req->length =EP_BUFFER_SIZE ; + req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE,
EP_BUFFER_SIZE);drivers/usb/gadget/f_rockusb.c new file +70
-0+if (!req->buf) { +usb_ep_free_request (ep, req); +return NULL ; + } + +memset (req->buf,0 , req->length); +return req; +} + +static int rockusb_set_alt (struct usb_function *f, +unsigned interface,unsigned alt) +{ +int ret; +struct usb_composite_dev *cdev = f->config->cdev; +struct usb_gadget *gadget = cdev->gadget; +struct f_rockusb *f_rkusb =func_to_rockusb (f); +const struct usb_endpoint_descriptor *d; + +debug ("%s: func: %s intf: %d alt: %d\n" , + __func__, f->name, interface, alt); + + d =rkusb_ep_desc (gadget, &fs_ep_out, &hs_ep_out); + ret =usb_ep_enable (f_rkusb->out_ep, d); +if (ret) { +puts ("failed to enable out ep\n" ); +return ret; + } + + f_rkusb->out_req =rockusb_start_ep (f_rkusb->out_ep); +if (!f_rkusb->out_req) { +puts ("failed to alloc out req\n" ); + ret = -EINVAL ; + goto err; + } + f_rkusb->out_req->complete = rx_handler_command; + + d =rkusb_ep_desc (gadget, &fs_ep_in, &hs_ep_in); + ret =usb_ep_enable (f_rkusb->in_ep, d); +if (ret) { +puts ("failed to enable in ep\n" ); + goto err; + } + + f_rkusb->in_req =rockusb_start_ep (f_rkusb->in_ep); +if (!f_rkusb->in_req) { +puts ("failed alloc req in\n" ); + ret = -EINVAL ; + goto err; + } + f_rkusb->in_req->complete = rockusb_complete; + + ret =usb_ep_queue (f_rkusb->out_ep, f_rkusb->out_req,0 ); +if (ret) + goto err; + +return 0 ; +err: +rockusb_disable (f); +return ret; +} + +static int rockusb_add (struct usb_configuration *c) +{ +struct f_rockusb *f_rkusb = rockusb_func; +int status; + +debug ("%s: cdev: 0x%p\n" , __func__, c->cdev); + +if (!f_rkusb) { + f_rkusb = memalign(CONFIG_SYS_CACHELINE_SIZE,
sizeof(*f_rkusb));drivers/usb/gadget/f_rockusb.c new file +34
-0+if (!f_rkusb) +return -ENOMEM ; + + rockusb_func = f_rkusb; +memset (f_rkusb,0 ,sizeof (*f_rkusb)); + } + + f_rkusb->usb_function.name ="f_rockusb" ; + f_rkusb->usb_function.bind = rockusb_bind; + f_rkusb->usb_function.unbind = rockusb_unbind; + f_rkusb->usb_function.set_alt = rockusb_set_alt; + f_rkusb->usb_function.disable = rockusb_disable; + f_rkusb->usb_function.strings = rkusb_strings; + + status =usb_add_function (c, &f_rkusb->usb_function); +if (status) { +free (f_rkusb); + rockusb_func = f_rkusb; + } +return status; +} + +char *rockusb_dev_type =0 ; +int rockusb_dev_index =0 ; + +void rockusb_dev_init (char *dev_type,int dev_index) +{ + rockusb_dev_type = dev_type; + rockusb_dev_index = dev_index; +} + +DECLARE_GADGET_BIND_CALLBACK (usb_dnl_rockusb, rockusb_add); + +static int rockusb_tx_write(const char *buffer, unsigned int
buffer_size) +{drivers/usb/gadget/f_rockusb.c new file +27
-0+struct usb_request *in_req = rockusb_func->in_req; +int ret; + +memcpy (in_req->buf, buffer, buffer_size); + in_req->length = buffer_size; +usb_ep_dequeue (rockusb_func->in_ep, in_req); + ret =usb_ep_queue (rockusb_func->in_ep, in_req,0 ); +if (ret) +printf ("Error %d on queue\n" , ret); +return 0 ; +} + +static int rockusb_tx_write_str (const char *buffer) +{ +return rockusb_tx_write (buffer,strlen (buffer)); +} + +/* Bulk-only data structures */ + +/* Command Block Wrapper */ +struct fsg_bulk_cb_wrap { +__le32 Signature;/* Contains 'USBC' */ +u32 Tag;/* Unique per command id */ +__le32 DataTransferLength;/* Size of the data */ +u8 Flags;/* Direction in bit 7 */ +u8 Lun;/* LUN (normally 0) */ +u8 Length;/* Of the CDB, <=
MAX_COMMAND_SIZE*/drivers/usb/gadget/f_rockusb.c new file +5
-0+u8 CDB [16 ];/* Command Data Block */ +}; + +#define USB_BULK_CB_WRAP_LEN 31 +#define USB_BULK_CB_SIG 0x43425355/* Spells out USBC */
drivers/usb/gadget/f_rockusb.c new file +6
-0+#define USB_BULK_IN_FLAG 0x80 + +/* Command Status Wrapper */ +struct bulk_cs_wrap { +__le32 Signature;/* Should = 'USBS' */ +u32 Tag;/* Same as original command */
+__le32Residue; /* Amount not transferred
*/drivers/usb/gadget/f_rockusb.c new file +5
-0+u8 Status;/* See below */ +}; + +#define USB_BULK_CS_WRAP_LEN 13 +#define USB_BULK_CS_SIG 0x53425355/* Spells out 'USBS' */
drivers/usb/gadget/f_rockusb.c new file +11
-0+#define USB_STATUS_PASS 0 +#define USB_STATUS_FAIL 1 +#define USB_STATUS_PHASE_ERROR 2 + + +#define CSW_GOOD 0x00 +#define CSW_FAIL 0x01 + +static void printcbw (char *buf) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +6
-0+ +memcpy ((char *)&cbw, buf,USB_BULK_CB_WRAP_LEN ); + +debug ("cbw: Signature:%x\n" , cbw.Signature); +debug ("cbw: Tag=%x\n" , cbw.Tag); + debug("cbw: DataTransferLength=%d\n",cbw.DataTransferLength);
drivers/usb/gadget/f_rockusb.c new file +6
-0+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]);drivers/usb/gadget/f_rockusb.c new file +8
-0+debug ("cbw: ucReserved2=%x\n" , cbw.CDB[6 ]); +debug ("cbw: usLength:%x %x\n" , cbw.CDB[8 ], cbw.CDB[7 ]); + +} + +static void printcsw (char *buf) +{ + struct bulk_cs_wrap csw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +10
-0+ +memcpy ((char *)&csw, buf,USB_BULK_CS_WRAP_LEN ); +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); + +} + +static int rockusb_tx_write_csw(u32 Tag, int residue, u8 Status,int size)
drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + struct bulk_cs_wrap csw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +33
-0+ csw.Signature =cpu_to_le32 (USB_BULK_CS_SIG ); + csw.Tag = Tag; + csw.Residue =cpu_to_be32 (residue); + csw.Status = Status; +printcsw ((char *)&csw); +return rockusb_tx_write ((char *)&csw, size); +} + +int download_tag =0 ; +int download_lba =0 ; +static unsigned int download_size; +static unsigned int download_bytes; +struct blk_desc *download_desc =0 ; + +static unsigned int rx_bytes_expected (struct usb_ep *ep) +{ +int rx_remain = download_size - download_bytes; +unsigned int rem; +unsigned int maxpacket = ep->maxpacket; + +if (rx_remain <=0 ) +return 0 ; +else if (rx_remain >EP_BUFFER_SIZE ) +return EP_BUFFER_SIZE ; + + rem = rx_remain % maxpacket; +if (rem >0 ) + rx_remain = rx_remain + (maxpacket - rem); + +return rx_remain; +} + +static void rx_handler_dl_image(struct usb_ep *ep, struct
usb_request*req)drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + unsigned int transfer_size = download_size -
download_bytes;drivers/usb/gadget/f_rockusb.c new file +6
-0+const unsigned char *buffer = req->buf; +unsigned int buffer_size = req->actual; + +if (!download_desc){ +printf ("rx_handler_dl_image blk_get_dev\n" ); + download_desc = blk_get_dev(rockusb_dev_type,
rockusb_dev_index);
+ if (!download_desc ||download_desc->type==
DEV_TYPE_UNKNOWN){drivers/usb/gadget/f_rockusb.c new file +2
-0+error ("invalid mmc device\n" ); + rockusb_tx_write_csw(download_tag, 0,
CSW_FAIL,
+USB_BULK_CS_WRAP_LEN);drivers/usb/gadget/f_rockusb.c new file +8
-0+return ; + } + } + +if (req->status !=0 ) { +printf ("Bad status: %d\n" , req->status); + rockusb_tx_write_csw(download_tag, 0, + CSW_FAIL,
USB_BULK_CS_WRAP_LEN);drivers/usb/gadget/f_rockusb.c new file +14
-0+return ; + } + +if (buffer_size < transfer_size) + transfer_size = buffer_size; + +memcpy ((void *)CONFIG_FASTBOOT_BUF_ADDR + download_bytes, + buffer, transfer_size); + download_bytes += transfer_size; + +/* Check if transfer is done */ +if (download_bytes >= download_size) { +int blks =0 , blkcnt = download_size/512 ; + printf("download %d bytes finished, start writingto lba %x\n",
drivers/usb/gadget/f_rockusb.c new file +2
-0+ download_bytes, download_lba); + blks = blk_dwrite(download_desc, download_lba,blkcnt,
+
(char*)CONFIG_FASTBOOT_BUF_ADDR);drivers/usb/gadget/f_rockusb.c new file +3
-0+if (blks != blkcnt) { + error("failed writing to device %s: %d\n", + rockusb_dev_type,
rockusb_dev_index);drivers/usb/gadget/f_rockusb.c new file +2
-0+ rockusb_tx_write_csw(download_tag, 0, + CSW_FAIL,
USB_BULK_CS_WRAP_LEN);drivers/usb/gadget/f_rockusb.c new file +18
-0+return ; + } + + req->complete = rx_handler_command; + req->length =EP_BUFFER_SIZE ; + download_size =0 ; +printf ("done\n" ); +rockusb_tx_write_csw (download_tag,0 ,CSW_GOOD , +USB_BULK_CS_WRAP_LEN ); + }else { + req->length =rx_bytes_expected (ep); + } + + req->actual =0 ; +usb_ep_queue (ep, req,0 ); +} + +static void cb_test_unit_ready(struct usb_ep *ep, struct
usb_request*req)drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +9
-0+ +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + +rockusb_tx_write_csw (cbw.Tag, cbw.DataTransferLength, +CSW_GOOD ,USB_BULK_CS_WRAP_LEN ); + +} + +static void cb_read_storage_id(struct usb_ep *ep, struct
usb_request*req)drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +6
-0+char emmc_id[] ="EMMC " ; + +printf ("cb_read_storage_id\n" ); +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +rockusb_tx_write_str (emmc_id);//only support emmc now + rockusb_tx_write_csw(cbw.Tag, cbw.DataTransferLength,
CSW_GOOD,drivers/usb/gadget/f_rockusb.c new file +4
-0+ USB_BULK_CS_WRAP_LEN); +} + +static void cb_write_lba(struct usb_ep *ep, struct usb_request*req) +{
+ structfsg_bulk_cb_wrapcbw __attribute__((aligned(ARCH_DMA_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +9
-0+int sector_count; + +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + sector_count = (int )get_unaligned_be16 (&cbw.CDB[7 ]); + download_lba =get_unaligned_be32 (&cbw.CDB[2 ]); + download_size = sector_count *512 ; + download_bytes =0 ; + download_tag = cbw.Tag; + if ((0 == download_size) || (download_size>CONFIG_FASTBOOT_BUF_SIZE)){
+ rockusb_tx_write_csw(cbw.Tag,
cbw.DataTransferLength,
+CSW_FAIL,USB_BULK_CS_WRAP_LEN);drivers/usb/gadget/f_rockusb.c new file +15
-0+ }else { + req->complete = rx_handler_dl_image; + req->length =rx_bytes_expected (ep); + } +} + +static int reboot_flag; + +int __weak rkusb_set_reboot_flag (int flag) +{ +printf ("rkusb_set_reboot_flag: %d\n" , reboot_flag); +return -ENOSYS ; +} + +static void compl_do_reset(struct usb_ep *ep, struct usb_request*req) +{
drivers/usb/gadget/f_rockusb.c new file +7
-0+rkusb_set_reboot_flag (reboot_flag); +do_reset (NULL ,0 ,0 ,NULL ); +} + +static void cb_reboot (struct usb_ep *ep,struct usb_request *req) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +5
-0+ reboot_flag =0 ; +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + reboot_flag = cbw.CDB[1 ]; + rockusb_func->in_req->complete = compl_do_reset; + rockusb_tx_write_csw(cbw.Tag, cbw.DataTransferLength,
CSW_GOOD,drivers/usb/gadget/f_rockusb.c new file +4
-0+ USB_BULK_CS_WRAP_LEN); +} + +static void cb_not_support(struct usb_ep *ep, struct usb_request*req) +{
+ structfsg_bulk_cb_wrapcbw __attribute__((aligned(ARCH_DMA_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +4
-0+ +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +printf ("Rockusb command %x not support yet\n" , cbw.CDB[0 ]); + rockusb_tx_write_csw(cbw.Tag, 0, CSW_FAIL,
USB_BULK_CS_WRAP_LEN); +}drivers/usb/gadget/f_rockusb.c new file +178
-0+ +#define RKUSB_STATUS_IDLE 0 +#define RKUSB_STATUS_CMD 1 +#define RKUSB_STATUS_RXDATA 2 +#define RKUSB_STATUS_TXDATA 3 +#define RKUSB_STATUS_CSW 4 +#define RKUSB_STATUS_RXDATA_PREPARE 5 +#define RKUSB_STATUS_TXDATA_PREPARE 6 + +typedef enum { +TEST_UNIT_READY =0 , +READ_FLASH_ID =0x01 , +TEST_BAD_BLOCK =0x03 , +READ_SECTOR =0x04 , +WRITE_SECTOR =0x05 , +ERASE_NORMAL =0x06 , +ERASE_FORCE =0x0B , +READ_LBA =0x14 , +WRITE_LBA =0x15 , +ERASE_SYSTEMDISK =0x16 , +READ_SDRAM =0x17 , +WRITE_SDRAM =0x18 , +EXECUTE_SDRAM =0x19 , +READ_FLASH_INFO =0x1A , +READ_CHIP_INFO =0x1B , +SET_RESET_FLAG =0x1E , +WRITE_EFUSE =0x1F , +READ_EFUSE =0x20 , +READ_SPI_FLASH =0x21 , +WRITE_SPI_FLASH =0x22 , +WRITE_NEW_EFUSE =0x23 , +READ_NEW_EFUSE =0x24 , +DEVICE_RESET =0xFF +}USB_OPERATION_CODE ; + +#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 CBW_DIRECTION_OUT 0x00 +#define CBW_DIRECTION_IN 0x80 + +struct cmd_dispatch_info { +int cmd; +void (*cb)(struct usb_ep *ep,struct usb_request *req); +}; + +static const struct cmd_dispatch_info cmd_dispatch_info[] = { + { + .cmd =K_FW_TEST_UNIT_READY , + .cb = cb_test_unit_ready, + }, + { + .cmd =K_FW_READ_FLASH_ID , + .cb = cb_read_storage_id, + }, + { + .cmd =K_FW_SET_DEVICE_ID , + .cb = cb_not_support, + }, + { + .cmd =K_FW_TEST_BAD_BLOCK , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_ERASE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_WRITE_SPARE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_SPARE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_ERASE_10_FORCE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_GET_VERSION , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LBA_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LBA_WRITE_10 , + .cb = cb_write_lba, + }, + { + .cmd =K_FW_ERASE_SYS_DISK , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_EXECUTE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_FLASH_INFO , + .cb = cb_not_support, + }, + { + .cmd =K_FW_GET_CHIP_VER , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LOW_FORMAT , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SET_RESET_FLAG , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SPI_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SPI_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SESSION , + .cb = cb_not_support, + }, + { + .cmd =K_FW_RESET , + .cb = cb_reboot, + }, +}; + + + +static void rx_handler_command(struct usb_ep *ep, struct
usb_request*req)drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + void (*func_cb)(struct usb_ep *ep, struct usb_request*req) = NULL;
+ structfsg_bulk_cb_wrapcbw __attribute__((aligned(ARCH_DMA_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +27
-0+int i; +char *cmdbuf = req->buf; + +if (req->status !=0 || req->length ==0 ) +return ; + +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +printcbw (req->buf); + +for (i =0 ; i <ARRAY_SIZE (cmd_dispatch_info); i++) { +if (cmd_dispatch_info[i].cmd == cbw.CDB[0 ]) { + func_cb = cmd_dispatch_info[i].cb; +break ; + } + } + +if (!func_cb) { +error ("unknown command: %s" , (char *)req->buf); +rockusb_tx_write_str ("FAILunknown command" ); + }else { +if (req->actual < req->length) { +u8 *buf = (u8 *)req->buf; + buf[req->actual] =0 ; +func_cb (ep, req); + }else { +error ("buffer overflow" ); + rockusb_tx_write_str("FAILbufferoverflow");
drivers/usb/gadget/f_rockusb.c new file +3
-0+ } + } +
Quoted 8 lines
Quoted 8 lines
drivers/usb/gadget/f_rockusb.c line 801
Quoted 5 lines
drivers/usb/gadget/f_rockusb.c new file +4
-0+ *cmdbuf ='\0' ; + req->actual =0 ; +usb_ep_queue (ep, req,0 ); +}
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
PATCH 1/3 drivers: usb: gadget: add the rockusb gadget
Hi Lukasz
This is my V1 patch. let me know if you have some comment.
2017-03-20 16:37 GMT+08:00 Lukasz Majewski <[email protected]>:
Quoted 927 lines
Hi Eddie,
Quoted 8 lines
2017-03-16 15:05 GMT+08:00 Kever Yang <[email protected]>:
Quoted 5 lines
Hi Eddie,
I recommend you to use ums framework instead of fastboot,
because ums have dual-buffer which improve performance.I will try to add dual buffer support in next version
If of course possible - please reuse as much code as possible.
Quoted 893 lines
Quoted 893 lines
Thanks,
- KeverQuoted 886 lines · Eddie Cai
this patch implement fastboot protocol on the device side. this is based on USB
download gadget infrastructure. the rockusb function implements the rd, wl, rid
commands. it can work with rkdeveloptool;
https://github.com/rockchip-linux/rkdeveloptoolSigned-off-by Eddie Cai <[email protected]>--- drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801 ++++++++++++++++++++++++++++++ +++++++++++ 2 files changed, 802 insertions(+)create mode 100644
drivers/usb/gadget/f_rockusb.c(quoted diff) +0
-0b/drivers/usb/gadget/Makefile index 0fbbb7c..0eb27a3 100644
drivers/usb/gadget/Makefile +1
-0@@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o +obj-$(CONFIG_USB_FUNCTION_ROCKUSB) += f_rockusb.o endif endif ifdef CONFIG_USB_ETHERdrivers/usb/gadget/f_rockusb.c new file +32
-0@@ -0,0 +1,801 @@ +/* +* (C) Copyright 2017 +* +* Eddie Cai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <config.h> +#include <common.h> +#include <errno.h> +#include <malloc.h> +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> +#include <linux/usb/composite.h> +#include <linux/compiler.h> +#include <version.h> +#include <g_dnl.h> + +#define ROCKUSB_VERSION "0.1" + +#define ROCKUSB_INTERFACE_CLASS 0xff +#define ROCKUSB_INTERFACE_SUB_CLASS 0x06 +#define ROCKUSB_INTERFACE_PROTOCOL 0x05 + +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200) +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) +#define TX_ENDPOINT_MAXIMUM_PACKET_SIZE (0x0040) + +#define EP_BUFFER_SIZE 4096 +/* +* EP_BUFFER_SIZE must always be an integral multiple of maxpacket size
+ * (64 or 512 or 1024), else we break on certain controllers like DWC3
+ * that expect bulk OUT requests to be divisible by maxpacket size.
+ */drivers/usb/gadget/f_rockusb.c new file +10
-0+ +struct f_rockusb { +struct usb_function usb_function; + +/* IN/OUT EP's and corresponding requests */ +struct usb_ep *in_ep, *out_ep; +struct usb_request *in_req, *out_req; +}; + +static inline struct f_rockusb *func_to_rockusb(struct
usb_function*f) +{drivers/usb/gadget/f_rockusb.c new file +63
-0+ return container_of(f, struct f_rockusb, usb_function); +} + +static struct f_rockusb *rockusb_func; + +static struct usb_endpoint_descriptor fs_ep_in = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_IN , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (64 ), +}; + +static struct usb_endpoint_descriptor fs_ep_out = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_OUT , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (64 ), +}; + +static struct usb_endpoint_descriptor hs_ep_in = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_IN , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (512 ), +}; + +static struct usb_endpoint_descriptor hs_ep_out = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_OUT , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (512 ), +}; + +static struct usb_interface_descriptor interface_desc = { + .bLength =USB_DT_INTERFACE_SIZE , + .bDescriptorType =USB_DT_INTERFACE , + .bInterfaceNumber =0x00 , + .bAlternateSetting =0x00 , + .bNumEndpoints =0x02 , + .bInterfaceClass =ROCKUSB_INTERFACE_CLASS , + .bInterfaceSubClass =ROCKUSB_INTERFACE_SUB_CLASS , + .bInterfaceProtocol =ROCKUSB_INTERFACE_PROTOCOL , +}; + +static struct usb_descriptor_header *rkusb_fs_function[] = { + (struct usb_descriptor_header *)&interface_desc, + (struct usb_descriptor_header *)&fs_ep_in, + (struct usb_descriptor_header *)&fs_ep_out, +}; + +static struct usb_descriptor_header *rkusb_hs_function[] = { + (struct usb_descriptor_header *)&interface_desc, + (struct usb_descriptor_header *)&hs_ep_in, + (struct usb_descriptor_header *)&hs_ep_out, +NULL , +}; + +static struct usb_endpoint_descriptor * +rkusb_ep_desc(struct usb_gadget *g, struct
usb_endpoint_descriptor*fs,drivers/usb/gadget/f_rockusb.c new file +28
-0+ struct usb_endpoint_descriptor *hs) +{ +if (gadget_is_dualspeed (g) && g->speed ==USB_SPEED_HIGH ) +return hs; +return fs; +} + +/* +* static strings, in UTF-8 +*/ +static const char rkusb_name[] ="Rockchip Rockusb" ; + +static struct usb_string rkusb_string_defs[] = { + [0 ].s = rkusb_name, + { }/* end of list */ +}; + +static struct usb_gadget_strings stringtab_rkusb = { + .language =0x0409 ,/* en-us */ + .strings = rkusb_string_defs, +}; + +static struct usb_gadget_strings *rkusb_strings[] = { + &stringtab_rkusb, +NULL , +}; + +static void rx_handler_command(struct usb_ep *ep, struct
usb_request*req);
+static introckusb_tx_write_csw(u32 Tag, int residue, u8 Status, int size);drivers/usb/gadget/f_rockusb.c new file +2
-0+ +static void rockusb_complete(struct usb_ep *ep, struct
usb_request*req) +{drivers/usb/gadget/f_rockusb.c new file +4
-0+int status = req->status; +if (!status) +return ; + debug("status: %d ep '%s' trans: %d\n", status, ep->name,
req->actual);drivers/usb/gadget/f_rockusb.c new file +3
-0+} + +static int rockusb_bind(struct usb_configuration *c, struct
usb_function*f)drivers/usb/gadget/f_rockusb.c new file +32
-0+{ +int id; +struct usb_gadget *gadget = c->cdev->gadget; +struct f_rockusb *f_rkusb =func_to_rockusb (f); +const char *s; + + id =usb_interface_id (c, f); +if (id <0 ) +return id; + interface_desc.bInterfaceNumber = id; + + id =usb_string_id (c->cdev); +if (id <0 ) +return id; + + rkusb_string_defs[0 ].id = id; + interface_desc.iInterface = id; + + f_rkusb->in_ep =usb_ep_autoconfig (gadget, &fs_ep_in); +if (!f_rkusb->in_ep) +return -ENODEV ; + f_rkusb->in_ep->driver_data = c->cdev; + + f_rkusb->out_ep =usb_ep_autoconfig (gadget, &fs_ep_out); +if (!f_rkusb->out_ep) +return -ENODEV ; + f_rkusb->out_ep->driver_data = c->cdev; + + f->descriptors = rkusb_fs_function; + +if (gadget_is_dualspeed (gadget)) { + hs_ep_in.bEndpointAddress =fs_ep_in.bEndpointAddress;
+ hs_ep_out.bEndpointAddress =
fs_ep_out.bEndpointAddress;drivers/usb/gadget/f_rockusb.c new file +11
-0+ f->hs_descriptors = rkusb_hs_function; + } + + s =getenv ("serial#" ); +if (s) +g_dnl_set_serialnumber ((char *)s); + +return 0 ; +} + +static void rockusb_unbind(struct usb_configuration *c, struct
usb_function*f)drivers/usb/gadget/f_rockusb.c new file +14
-0+{ +memset (rockusb_func,0 ,sizeof (*rockusb_func)); +} + +static void rockusb_disable (struct usb_function *f) +{ +struct f_rockusb *f_rkusb =func_to_rockusb (f); + +usb_ep_disable (f_rkusb->out_ep); +usb_ep_disable (f_rkusb->in_ep); + +if (f_rkusb->out_req) { +free (f_rkusb->out_req->buf); + usb_ep_free_request(f_rkusb->out_ep,
f_rkusb->out_req);drivers/usb/gadget/f_rockusb.c new file +5
-0+ f_rkusb->out_req =NULL ; + } +if (f_rkusb->in_req) { +free (f_rkusb->in_req->buf); + usb_ep_free_request(f_rkusb->in_ep,
f_rkusb->in_req);drivers/usb/gadget/f_rockusb.c new file +14
-0+ f_rkusb->in_req =NULL ; + } +} + +static struct usb_request *rockusb_start_ep (struct usb_ep *ep) +{ +struct usb_request *req; + + req =usb_ep_alloc_request (ep,0 ); +if (!req) +return NULL ; + + req->length =EP_BUFFER_SIZE ; + req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE,
EP_BUFFER_SIZE);drivers/usb/gadget/f_rockusb.c new file +70
-0+if (!req->buf) { +usb_ep_free_request (ep, req); +return NULL ; + } + +memset (req->buf,0 , req->length); +return req; +} + +static int rockusb_set_alt (struct usb_function *f, +unsigned interface,unsigned alt) +{ +int ret; +struct usb_composite_dev *cdev = f->config->cdev; +struct usb_gadget *gadget = cdev->gadget; +struct f_rockusb *f_rkusb =func_to_rockusb (f); +const struct usb_endpoint_descriptor *d; + +debug ("%s: func: %s intf: %d alt: %d\n" , + __func__, f->name, interface, alt); + + d =rkusb_ep_desc (gadget, &fs_ep_out, &hs_ep_out); + ret =usb_ep_enable (f_rkusb->out_ep, d); +if (ret) { +puts ("failed to enable out ep\n" ); +return ret; + } + + f_rkusb->out_req =rockusb_start_ep (f_rkusb->out_ep); +if (!f_rkusb->out_req) { +puts ("failed to alloc out req\n" ); + ret = -EINVAL ; + goto err; + } + f_rkusb->out_req->complete = rx_handler_command; + + d =rkusb_ep_desc (gadget, &fs_ep_in, &hs_ep_in); + ret =usb_ep_enable (f_rkusb->in_ep, d); +if (ret) { +puts ("failed to enable in ep\n" ); + goto err; + } + + f_rkusb->in_req =rockusb_start_ep (f_rkusb->in_ep); +if (!f_rkusb->in_req) { +puts ("failed alloc req in\n" ); + ret = -EINVAL ; + goto err; + } + f_rkusb->in_req->complete = rockusb_complete; + + ret =usb_ep_queue (f_rkusb->out_ep, f_rkusb->out_req,0 ); +if (ret) + goto err; + +return 0 ; +err: +rockusb_disable (f); +return ret; +} + +static int rockusb_add (struct usb_configuration *c) +{ +struct f_rockusb *f_rkusb = rockusb_func; +int status; + +debug ("%s: cdev: 0x%p\n" , __func__, c->cdev); + +if (!f_rkusb) { + f_rkusb = memalign(CONFIG_SYS_CACHELINE_SIZE,
sizeof(*f_rkusb));drivers/usb/gadget/f_rockusb.c new file +34
-0+if (!f_rkusb) +return -ENOMEM ; + + rockusb_func = f_rkusb; +memset (f_rkusb,0 ,sizeof (*f_rkusb)); + } + + f_rkusb->usb_function.name ="f_rockusb" ; + f_rkusb->usb_function.bind = rockusb_bind; + f_rkusb->usb_function.unbind = rockusb_unbind; + f_rkusb->usb_function.set_alt = rockusb_set_alt; + f_rkusb->usb_function.disable = rockusb_disable; + f_rkusb->usb_function.strings = rkusb_strings; + + status =usb_add_function (c, &f_rkusb->usb_function); +if (status) { +free (f_rkusb); + rockusb_func = f_rkusb; + } +return status; +} + +char *rockusb_dev_type =0 ; +int rockusb_dev_index =0 ; + +void rockusb_dev_init (char *dev_type,int dev_index) +{ + rockusb_dev_type = dev_type; + rockusb_dev_index = dev_index; +} + +DECLARE_GADGET_BIND_CALLBACK (usb_dnl_rockusb, rockusb_add); + +static int rockusb_tx_write(const char *buffer, unsigned int
buffer_size) +{drivers/usb/gadget/f_rockusb.c new file +27
-0+struct usb_request *in_req = rockusb_func->in_req; +int ret; + +memcpy (in_req->buf, buffer, buffer_size); + in_req->length = buffer_size; +usb_ep_dequeue (rockusb_func->in_ep, in_req); + ret =usb_ep_queue (rockusb_func->in_ep, in_req,0 ); +if (ret) +printf ("Error %d on queue\n" , ret); +return 0 ; +} + +static int rockusb_tx_write_str (const char *buffer) +{ +return rockusb_tx_write (buffer,strlen (buffer)); +} + +/* Bulk-only data structures */ + +/* Command Block Wrapper */ +struct fsg_bulk_cb_wrap { +__le32 Signature;/* Contains 'USBC' */ +u32 Tag;/* Unique per command id */ +__le32 DataTransferLength;/* Size of the data */ +u8 Flags;/* Direction in bit 7 */ +u8 Lun;/* LUN (normally 0) */ +u8 Length;/* Of the CDB, <=
MAX_COMMAND_SIZE*/drivers/usb/gadget/f_rockusb.c new file +5
-0+u8 CDB [16 ];/* Command Data Block */ +}; + +#define USB_BULK_CB_WRAP_LEN 31 +#define USB_BULK_CB_SIG 0x43425355/* Spells out USBC */
drivers/usb/gadget/f_rockusb.c new file +6
-0+#define USB_BULK_IN_FLAG 0x80 + +/* Command Status Wrapper */ +struct bulk_cs_wrap { +__le32 Signature;/* Should = 'USBS' */ +u32 Tag;/* Same as original command */
+__le32Residue; /* Amount not transferred
*/drivers/usb/gadget/f_rockusb.c new file +5
-0+u8 Status;/* See below */ +}; + +#define USB_BULK_CS_WRAP_LEN 13 +#define USB_BULK_CS_SIG 0x53425355/* Spells out 'USBS' */
drivers/usb/gadget/f_rockusb.c new file +11
-0+#define USB_STATUS_PASS 0 +#define USB_STATUS_FAIL 1 +#define USB_STATUS_PHASE_ERROR 2 + + +#define CSW_GOOD 0x00 +#define CSW_FAIL 0x01 + +static void printcbw (char *buf) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +6
-0+ +memcpy ((char *)&cbw, buf,USB_BULK_CB_WRAP_LEN ); + +debug ("cbw: Signature:%x\n" , cbw.Signature); +debug ("cbw: Tag=%x\n" , cbw.Tag); + debug("cbw: DataTransferLength=%d\n",cbw.DataTransferLength);
drivers/usb/gadget/f_rockusb.c new file +6
-0+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]);drivers/usb/gadget/f_rockusb.c new file +8
-0+debug ("cbw: ucReserved2=%x\n" , cbw.CDB[6 ]); +debug ("cbw: usLength:%x %x\n" , cbw.CDB[8 ], cbw.CDB[7 ]); + +} + +static void printcsw (char *buf) +{ + struct bulk_cs_wrap csw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +10
-0+ +memcpy ((char *)&csw, buf,USB_BULK_CS_WRAP_LEN ); +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); + +} + +static int rockusb_tx_write_csw(u32 Tag, int residue, u8 Status,int size)
drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + struct bulk_cs_wrap csw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +33
-0+ csw.Signature =cpu_to_le32 (USB_BULK_CS_SIG ); + csw.Tag = Tag; + csw.Residue =cpu_to_be32 (residue); + csw.Status = Status; +printcsw ((char *)&csw); +return rockusb_tx_write ((char *)&csw, size); +} + +int download_tag =0 ; +int download_lba =0 ; +static unsigned int download_size; +static unsigned int download_bytes; +struct blk_desc *download_desc =0 ; + +static unsigned int rx_bytes_expected (struct usb_ep *ep) +{ +int rx_remain = download_size - download_bytes; +unsigned int rem; +unsigned int maxpacket = ep->maxpacket; + +if (rx_remain <=0 ) +return 0 ; +else if (rx_remain >EP_BUFFER_SIZE ) +return EP_BUFFER_SIZE ; + + rem = rx_remain % maxpacket; +if (rem >0 ) + rx_remain = rx_remain + (maxpacket - rem); + +return rx_remain; +} + +static void rx_handler_dl_image(struct usb_ep *ep, struct
usb_request*req)drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + unsigned int transfer_size = download_size -
download_bytes;drivers/usb/gadget/f_rockusb.c new file +6
-0+const unsigned char *buffer = req->buf; +unsigned int buffer_size = req->actual; + +if (!download_desc){ +printf ("rx_handler_dl_image blk_get_dev\n" ); + download_desc = blk_get_dev(rockusb_dev_type,
rockusb_dev_index);
+ if (!download_desc ||download_desc->type==
DEV_TYPE_UNKNOWN){drivers/usb/gadget/f_rockusb.c new file +2
-0+error ("invalid mmc device\n" ); + rockusb_tx_write_csw(download_tag, 0,
CSW_FAIL,
+USB_BULK_CS_WRAP_LEN);drivers/usb/gadget/f_rockusb.c new file +8
-0+return ; + } + } + +if (req->status !=0 ) { +printf ("Bad status: %d\n" , req->status); + rockusb_tx_write_csw(download_tag, 0, + CSW_FAIL,
USB_BULK_CS_WRAP_LEN);drivers/usb/gadget/f_rockusb.c new file +14
-0+return ; + } + +if (buffer_size < transfer_size) + transfer_size = buffer_size; + +memcpy ((void *)CONFIG_FASTBOOT_BUF_ADDR + download_bytes, + buffer, transfer_size); + download_bytes += transfer_size; + +/* Check if transfer is done */ +if (download_bytes >= download_size) { +int blks =0 , blkcnt = download_size/512 ; + printf("download %d bytes finished, start writingto lba %x\n",
drivers/usb/gadget/f_rockusb.c new file +2
-0+ download_bytes, download_lba); + blks = blk_dwrite(download_desc, download_lba,blkcnt,
+
(char*)CONFIG_FASTBOOT_BUF_ADDR);drivers/usb/gadget/f_rockusb.c new file +3
-0+if (blks != blkcnt) { + error("failed writing to device %s: %d\n", + rockusb_dev_type,
rockusb_dev_index);drivers/usb/gadget/f_rockusb.c new file +2
-0+ rockusb_tx_write_csw(download_tag, 0, + CSW_FAIL,
USB_BULK_CS_WRAP_LEN);drivers/usb/gadget/f_rockusb.c new file +18
-0+return ; + } + + req->complete = rx_handler_command; + req->length =EP_BUFFER_SIZE ; + download_size =0 ; +printf ("done\n" ); +rockusb_tx_write_csw (download_tag,0 ,CSW_GOOD , +USB_BULK_CS_WRAP_LEN ); + }else { + req->length =rx_bytes_expected (ep); + } + + req->actual =0 ; +usb_ep_queue (ep, req,0 ); +} + +static void cb_test_unit_ready(struct usb_ep *ep, struct
usb_request*req)drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +9
-0+ +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + +rockusb_tx_write_csw (cbw.Tag, cbw.DataTransferLength, +CSW_GOOD ,USB_BULK_CS_WRAP_LEN ); + +} + +static void cb_read_storage_id(struct usb_ep *ep, struct
usb_request*req)drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +6
-0+char emmc_id[] ="EMMC " ; + +printf ("cb_read_storage_id\n" ); +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +rockusb_tx_write_str (emmc_id);//only support emmc now + rockusb_tx_write_csw(cbw.Tag, cbw.DataTransferLength,
CSW_GOOD,drivers/usb/gadget/f_rockusb.c new file +4
-0+ USB_BULK_CS_WRAP_LEN); +} + +static void cb_write_lba(struct usb_ep *ep, struct usb_request*req) +{
+ structfsg_bulk_cb_wrapcbw __attribute__((aligned(ARCH_DMA_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +9
-0+int sector_count; + +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + sector_count = (int )get_unaligned_be16 (&cbw.CDB[7 ]); + download_lba =get_unaligned_be32 (&cbw.CDB[2 ]); + download_size = sector_count *512 ; + download_bytes =0 ; + download_tag = cbw.Tag; + if ((0 == download_size) || (download_size>CONFIG_FASTBOOT_BUF_SIZE)){
+ rockusb_tx_write_csw(cbw.Tag,
cbw.DataTransferLength,
+CSW_FAIL,USB_BULK_CS_WRAP_LEN);drivers/usb/gadget/f_rockusb.c new file +15
-0+ }else { + req->complete = rx_handler_dl_image; + req->length =rx_bytes_expected (ep); + } +} + +static int reboot_flag; + +int __weak rkusb_set_reboot_flag (int flag) +{ +printf ("rkusb_set_reboot_flag: %d\n" , reboot_flag); +return -ENOSYS ; +} + +static void compl_do_reset(struct usb_ep *ep, struct usb_request*req) +{
drivers/usb/gadget/f_rockusb.c new file +7
-0+rkusb_set_reboot_flag (reboot_flag); +do_reset (NULL ,0 ,0 ,NULL ); +} + +static void cb_reboot (struct usb_ep *ep,struct usb_request *req) +{ + struct fsg_bulk_cb_wrap cbw __attribute__((aligned(ARCH_DM
A_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +5
-0+ reboot_flag =0 ; +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + reboot_flag = cbw.CDB[1 ]; + rockusb_func->in_req->complete = compl_do_reset; + rockusb_tx_write_csw(cbw.Tag, cbw.DataTransferLength,
CSW_GOOD,drivers/usb/gadget/f_rockusb.c new file +4
-0+ USB_BULK_CS_WRAP_LEN); +} + +static void cb_not_support(struct usb_ep *ep, struct usb_request*req) +{
+ structfsg_bulk_cb_wrapcbw __attribute__((aligned(ARCH_DMA_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +4
-0+ +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +printf ("Rockusb command %x not support yet\n" , cbw.CDB[0 ]); + rockusb_tx_write_csw(cbw.Tag, 0, CSW_FAIL,
USB_BULK_CS_WRAP_LEN); +}drivers/usb/gadget/f_rockusb.c new file +178
-0+ +#define RKUSB_STATUS_IDLE 0 +#define RKUSB_STATUS_CMD 1 +#define RKUSB_STATUS_RXDATA 2 +#define RKUSB_STATUS_TXDATA 3 +#define RKUSB_STATUS_CSW 4 +#define RKUSB_STATUS_RXDATA_PREPARE 5 +#define RKUSB_STATUS_TXDATA_PREPARE 6 + +typedef enum { +TEST_UNIT_READY =0 , +READ_FLASH_ID =0x01 , +TEST_BAD_BLOCK =0x03 , +READ_SECTOR =0x04 , +WRITE_SECTOR =0x05 , +ERASE_NORMAL =0x06 , +ERASE_FORCE =0x0B , +READ_LBA =0x14 , +WRITE_LBA =0x15 , +ERASE_SYSTEMDISK =0x16 , +READ_SDRAM =0x17 , +WRITE_SDRAM =0x18 , +EXECUTE_SDRAM =0x19 , +READ_FLASH_INFO =0x1A , +READ_CHIP_INFO =0x1B , +SET_RESET_FLAG =0x1E , +WRITE_EFUSE =0x1F , +READ_EFUSE =0x20 , +READ_SPI_FLASH =0x21 , +WRITE_SPI_FLASH =0x22 , +WRITE_NEW_EFUSE =0x23 , +READ_NEW_EFUSE =0x24 , +DEVICE_RESET =0xFF +}USB_OPERATION_CODE ; + +#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 CBW_DIRECTION_OUT 0x00 +#define CBW_DIRECTION_IN 0x80 + +struct cmd_dispatch_info { +int cmd; +void (*cb)(struct usb_ep *ep,struct usb_request *req); +}; + +static const struct cmd_dispatch_info cmd_dispatch_info[] = { + { + .cmd =K_FW_TEST_UNIT_READY , + .cb = cb_test_unit_ready, + }, + { + .cmd =K_FW_READ_FLASH_ID , + .cb = cb_read_storage_id, + }, + { + .cmd =K_FW_SET_DEVICE_ID , + .cb = cb_not_support, + }, + { + .cmd =K_FW_TEST_BAD_BLOCK , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_ERASE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_WRITE_SPARE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_SPARE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_ERASE_10_FORCE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_GET_VERSION , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LBA_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LBA_WRITE_10 , + .cb = cb_write_lba, + }, + { + .cmd =K_FW_ERASE_SYS_DISK , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_EXECUTE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_FLASH_INFO , + .cb = cb_not_support, + }, + { + .cmd =K_FW_GET_CHIP_VER , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LOW_FORMAT , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SET_RESET_FLAG , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SPI_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SPI_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SESSION , + .cb = cb_not_support, + }, + { + .cmd =K_FW_RESET , + .cb = cb_reboot, + }, +}; + + + +static void rx_handler_command(struct usb_ep *ep, struct
usb_request*req)drivers/usb/gadget/f_rockusb.c new file +2
-0+{ + void (*func_cb)(struct usb_ep *ep, struct usb_request*req) = NULL;
+ structfsg_bulk_cb_wrapcbw __attribute__((aligned(ARCH_DMA_MINALIGN)));drivers/usb/gadget/f_rockusb.c new file +27
-0+int i; +char *cmdbuf = req->buf; + +if (req->status !=0 || req->length ==0 ) +return ; + +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +printcbw (req->buf); + +for (i =0 ; i <ARRAY_SIZE (cmd_dispatch_info); i++) { +if (cmd_dispatch_info[i].cmd == cbw.CDB[0 ]) { + func_cb = cmd_dispatch_info[i].cb; +break ; + } + } + +if (!func_cb) { +error ("unknown command: %s" , (char *)req->buf); +rockusb_tx_write_str ("FAILunknown command" ); + }else { +if (req->actual < req->length) { +u8 *buf = (u8 *)req->buf; + buf[req->actual] =0 ; +func_cb (ep, req); + }else { +error ("buffer overflow" ); + rockusb_tx_write_str("FAILbufferoverflow");
drivers/usb/gadget/f_rockusb.c new file +3
-0+ } + } +Quoted 8 lines
Quoted 8 lines
drivers/usb/gadget/f_rockusb.c line 801
Quoted 5 lines
drivers/usb/gadget/f_rockusb.c new file +4
-0+ *cmdbuf ='\0' ; + req->actual =0 ; +usb_ep_queue (ep, req,0 ); +}Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
PATCH 1/3 drivers: usb: gadget: add the rockusb gadget
In reply to Eddie CaiHi Eddie,
Quoted 62 lines
this patch implement fastboot protocol on the device side. this is based on USB download gadget infrastructure. the rockusb function implements the rd, wl, rid commands. it can work with rkdeveloptool;
https://github.com/rockchip-linux/rkdeveloptoolSigned-off-by Eddie Cai <[email protected]>--- drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801+++++++++++++++++++++++++++++++++++++++++ 2 files changed, 802 insertions(+) create mode 100644
drivers/usb/gadget/f_rockusb.cdrivers/usb/gadget/Makefile +1
-0@@ -28,6 +28,7 @@ obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o +obj-$(CONFIG_USB_FUNCTION_ROCKUSB) += f_rockusb.o endif endif ifdef CONFIG_USB_ETHER(quoted diff) +0
-0
b/drivers/usb/gadget/f_rockusb.cnew file mode 100644 index 0000000..a67cb35drivers/usb/gadget/f_rockusb.c new file +32
-0@@ -0,0 +1,801 @@ +/* +* (C) Copyright 2017 +* +* Eddie Cai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <config.h> +#include <common.h> +#include <errno.h> +#include <malloc.h> +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> +#include <linux/usb/composite.h> +#include <linux/compiler.h> +#include <version.h> +#include <g_dnl.h> + +#define ROCKUSB_VERSION "0.1" + +#define ROCKUSB_INTERFACE_CLASS 0xff +#define ROCKUSB_INTERFACE_SUB_CLASS 0x06 +#define ROCKUSB_INTERFACE_PROTOCOL 0x05 + +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200) +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) +#define TX_ENDPOINT_MAXIMUM_PACKET_SIZE (0x0040) + +#define EP_BUFFER_SIZE 4096 +/* +* EP_BUFFER_SIZE must always be an integral multiple of maxpacket
Quoted 6 lines
size
+ * (64 or 512 or 1024), else we break on certain controllers like DWC3
+ * that expect bulk OUT requests to be divisible by maxpacket size.
+ */
+
Maybe you could put those defines to f_rockchip.h file (which would be local to the f_rockchip.c)?
It could store defines and structs local to the rockchip protocol.
Quoted 386 lines
drivers/usb/gadget/f_rockusb.c new file +9
-0+struct f_rockusb { +struct usb_function usb_function; + +/* IN/OUT EP's and corresponding requests */ +struct usb_ep *in_ep, *out_ep; +struct usb_request *in_req, *out_req; +}; + +static inline struct f_rockusb *func_to_rockusb(struct usb_function*f) +{
drivers/usb/gadget/f_rockusb.c new file +63
-0+ return container_of(f, struct f_rockusb, usb_function); +} + +static struct f_rockusb *rockusb_func; + +static struct usb_endpoint_descriptor fs_ep_in = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_IN , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (64 ), +}; + +static struct usb_endpoint_descriptor fs_ep_out = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_OUT , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (64 ), +}; + +static struct usb_endpoint_descriptor hs_ep_in = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_IN , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (512 ), +}; + +static struct usb_endpoint_descriptor hs_ep_out = { + .bLength =USB_DT_ENDPOINT_SIZE , + .bDescriptorType =USB_DT_ENDPOINT , + .bEndpointAddress =USB_DIR_OUT , + .bmAttributes =USB_ENDPOINT_XFER_BULK , + .wMaxPacketSize =cpu_to_le16 (512 ), +}; + +static struct usb_interface_descriptor interface_desc = { + .bLength =USB_DT_INTERFACE_SIZE , + .bDescriptorType =USB_DT_INTERFACE , + .bInterfaceNumber =0x00 , + .bAlternateSetting =0x00 , + .bNumEndpoints =0x02 , + .bInterfaceClass =ROCKUSB_INTERFACE_CLASS , + .bInterfaceSubClass =ROCKUSB_INTERFACE_SUB_CLASS , + .bInterfaceProtocol =ROCKUSB_INTERFACE_PROTOCOL , +}; + +static struct usb_descriptor_header *rkusb_fs_function[] = { + (struct usb_descriptor_header *)&interface_desc, + (struct usb_descriptor_header *)&fs_ep_in, + (struct usb_descriptor_header *)&fs_ep_out, +}; + +static struct usb_descriptor_header *rkusb_hs_function[] = { + (struct usb_descriptor_header *)&interface_desc, + (struct usb_descriptor_header *)&hs_ep_in, + (struct usb_descriptor_header *)&hs_ep_out, +NULL , +}; + +static struct usb_endpoint_descriptor * +rkusb_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor*fs,
drivers/usb/gadget/f_rockusb.c new file +28
-0+ struct usb_endpoint_descriptor *hs) +{ +if (gadget_is_dualspeed (g) && g->speed ==USB_SPEED_HIGH ) +return hs; +return fs; +} + +/* +* static strings, in UTF-8 +*/ +static const char rkusb_name[] ="Rockchip Rockusb" ; + +static struct usb_string rkusb_string_defs[] = { + [0 ].s = rkusb_name, + { }/* end of list */ +}; + +static struct usb_gadget_strings stringtab_rkusb = { + .language =0x0409 ,/* en-us */ + .strings = rkusb_string_defs, +}; + +static struct usb_gadget_strings *rkusb_strings[] = { + &stringtab_rkusb, +NULL , +}; + +static void rx_handler_command(struct usb_ep *ep, struct usb_request*req); +static int
rockusb_tx_write_csw(u32 Tag, int residue, u8 Status, int size); +
+static voidrockusb_complete(struct usb_ep *ep, struct usb_request *req)+{drivers/usb/gadget/f_rockusb.c new file +4
-0+int status = req->status; +if (!status) +return ; + debug("status: %d ep '%s' trans: %d\n", status, ep->name,
req->actual); +}drivers/usb/gadget/f_rockusb.c new file +2
-0+ +static int rockusb_bind(struct usb_configuration *c, struct
usb_function*f) +{drivers/usb/gadget/f_rockusb.c new file +31
-0+int id; +struct usb_gadget *gadget = c->cdev->gadget; +struct f_rockusb *f_rkusb =func_to_rockusb (f); +const char *s; + + id =usb_interface_id (c, f); +if (id <0 ) +return id; + interface_desc.bInterfaceNumber = id; + + id =usb_string_id (c->cdev); +if (id <0 ) +return id; + + rkusb_string_defs[0 ].id = id; + interface_desc.iInterface = id; + + f_rkusb->in_ep =usb_ep_autoconfig (gadget, &fs_ep_in); +if (!f_rkusb->in_ep) +return -ENODEV ; + f_rkusb->in_ep->driver_data = c->cdev; + + f_rkusb->out_ep =usb_ep_autoconfig (gadget, &fs_ep_out); +if (!f_rkusb->out_ep) +return -ENODEV ; + f_rkusb->out_ep->driver_data = c->cdev; + + f->descriptors = rkusb_fs_function; + +if (gadget_is_dualspeed (gadget)) { + hs_ep_in.bEndpointAddress =fs_ep_in.bEndpointAddress;
drivers/usb/gadget/f_rockusb.c new file +1
-0+ hs_ep_out.bEndpointAddress =fs_ep_out.bEndpointAddress;
drivers/usb/gadget/f_rockusb.c new file +11
-0+ f->hs_descriptors = rkusb_hs_function; + } + + s =getenv ("serial#" ); +if (s) +g_dnl_set_serialnumber ((char *)s); + +return 0 ; +} + +static void rockusb_unbind(struct usb_configuration *c, struct
usb_function*f) +{drivers/usb/gadget/f_rockusb.c new file +13
-0+memset (rockusb_func,0 ,sizeof (*rockusb_func)); +} + +static void rockusb_disable (struct usb_function *f) +{ +struct f_rockusb *f_rkusb =func_to_rockusb (f); + +usb_ep_disable (f_rkusb->out_ep); +usb_ep_disable (f_rkusb->in_ep); + +if (f_rkusb->out_req) { +free (f_rkusb->out_req->buf); + usb_ep_free_request(f_rkusb->out_ep,
f_rkusb->out_req);drivers/usb/gadget/f_rockusb.c new file +19
-0+ f_rkusb->out_req =NULL ; + } +if (f_rkusb->in_req) { +free (f_rkusb->in_req->buf); +usb_ep_free_request (f_rkusb->in_ep, f_rkusb->in_req); + f_rkusb->in_req =NULL ; + } +} + +static struct usb_request *rockusb_start_ep (struct usb_ep *ep) +{ +struct usb_request *req; + + req =usb_ep_alloc_request (ep,0 ); +if (!req) +return NULL ; + + req->length =EP_BUFFER_SIZE ; + req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE,
EP_BUFFER_SIZE);drivers/usb/gadget/f_rockusb.c new file +70
-0+if (!req->buf) { +usb_ep_free_request (ep, req); +return NULL ; + } + +memset (req->buf,0 , req->length); +return req; +} + +static int rockusb_set_alt (struct usb_function *f, +unsigned interface,unsigned alt) +{ +int ret; +struct usb_composite_dev *cdev = f->config->cdev; +struct usb_gadget *gadget = cdev->gadget; +struct f_rockusb *f_rkusb =func_to_rockusb (f); +const struct usb_endpoint_descriptor *d; + +debug ("%s: func: %s intf: %d alt: %d\n" , + __func__, f->name, interface, alt); + + d =rkusb_ep_desc (gadget, &fs_ep_out, &hs_ep_out); + ret =usb_ep_enable (f_rkusb->out_ep, d); +if (ret) { +puts ("failed to enable out ep\n" ); +return ret; + } + + f_rkusb->out_req =rockusb_start_ep (f_rkusb->out_ep); +if (!f_rkusb->out_req) { +puts ("failed to alloc out req\n" ); + ret = -EINVAL ; + goto err; + } + f_rkusb->out_req->complete = rx_handler_command; + + d =rkusb_ep_desc (gadget, &fs_ep_in, &hs_ep_in); + ret =usb_ep_enable (f_rkusb->in_ep, d); +if (ret) { +puts ("failed to enable in ep\n" ); + goto err; + } + + f_rkusb->in_req =rockusb_start_ep (f_rkusb->in_ep); +if (!f_rkusb->in_req) { +puts ("failed alloc req in\n" ); + ret = -EINVAL ; + goto err; + } + f_rkusb->in_req->complete = rockusb_complete; + + ret =usb_ep_queue (f_rkusb->out_ep, f_rkusb->out_req,0 ); +if (ret) + goto err; + +return 0 ; +err: +rockusb_disable (f); +return ret; +} + +static int rockusb_add (struct usb_configuration *c) +{ +struct f_rockusb *f_rkusb = rockusb_func; +int status; + +debug ("%s: cdev: 0x%p\n" , __func__, c->cdev); + +if (!f_rkusb) { + f_rkusb = memalign(CONFIG_SYS_CACHELINE_SIZE,
sizeof(*f_rkusb));drivers/usb/gadget/f_rockusb.c new file +34
-0+if (!f_rkusb) +return -ENOMEM ; + + rockusb_func = f_rkusb; +memset (f_rkusb,0 ,sizeof (*f_rkusb)); + } + + f_rkusb->usb_function.name ="f_rockusb" ; + f_rkusb->usb_function.bind = rockusb_bind; + f_rkusb->usb_function.unbind = rockusb_unbind; + f_rkusb->usb_function.set_alt = rockusb_set_alt; + f_rkusb->usb_function.disable = rockusb_disable; + f_rkusb->usb_function.strings = rkusb_strings; + + status =usb_add_function (c, &f_rkusb->usb_function); +if (status) { +free (f_rkusb); + rockusb_func = f_rkusb; + } +return status; +} + +char *rockusb_dev_type =0 ; +int rockusb_dev_index =0 ; + +void rockusb_dev_init (char *dev_type,int dev_index) +{ + rockusb_dev_type = dev_type; + rockusb_dev_index = dev_index; +} + +DECLARE_GADGET_BIND_CALLBACK (usb_dnl_rockusb, rockusb_add); + +static int rockusb_tx_write(const char *buffer, unsigned int
buffer_size) +{drivers/usb/gadget/f_rockusb.c new file +23
-0+struct usb_request *in_req = rockusb_func->in_req; +int ret; + +memcpy (in_req->buf, buffer, buffer_size); + in_req->length = buffer_size; +usb_ep_dequeue (rockusb_func->in_ep, in_req); + ret =usb_ep_queue (rockusb_func->in_ep, in_req,0 ); +if (ret) +printf ("Error %d on queue\n" , ret); +return 0 ; +} + +static int rockusb_tx_write_str (const char *buffer) +{ +return rockusb_tx_write (buffer,strlen (buffer)); +} + +/* Bulk-only data structures */ + +/* Command Block Wrapper */ +struct fsg_bulk_cb_wrap { +__le32 Signature;/* Contains 'USBC' */ +u32 Tag;/* Unique per command id */
drivers/usb/gadget/f_rockusb.c new file +1
-0+__le32 DataTransferLength;/* Size of the data */
drivers/usb/gadget/f_rockusb.c new file +1
-0+u8 Flags;/* Direction in bit 7 */
drivers/usb/gadget/f_rockusb.c new file +2
-0+u8 Lun;/* LUN (normally 0) */ +u8 Length;/* Of the CDB, <=
MAX_COMMAND_SIZE*/drivers/usb/gadget/f_rockusb.c new file +5
-0+u8 CDB [16 ];/* Command Data Block */ +}; + +#define USB_BULK_CB_WRAP_LEN 31 +#define USB_BULK_CB_SIG 0x43425355/* Spells out USBC */ +#define
USB_BULK_IN_FLAG0x80drivers/usb/gadget/f_rockusb.c new file +5
-0+ +/* Command Status Wrapper */ +struct bulk_cs_wrap { +__le32 Signature;/* Should = 'USBS' */ +u32 Tag;/* Same as original command */
drivers/usb/gadget/f_rockusb.c new file +1
-0+__le32 Residue;/* Amount not transferred */
drivers/usb/gadget/f_rockusb.c new file +5
-0+u8 Status;/* See below */ +}; + +#define USB_BULK_CS_WRAP_LEN 13 +#define USB_BULK_CS_SIG 0x53425355/* Spells out 'USBS' */ +#define
USB_STATUS_PASS0drivers/usb/gadget/f_rockusb.c new file +10
-0+#define USB_STATUS_FAIL 1 +#define USB_STATUS_PHASE_ERROR 2 + + +#define CSW_GOOD 0x00 +#define CSW_FAIL 0x01 + +static void printcbw (char *buf) +{ +struct fsg_bulk_cb_wrap cbw__attribute__((aligned(ARCH_DMA_MINALIGN))); +
drivers/usb/gadget/f_rockusb.c new file +5
-0+memcpy ((char *)&cbw, buf,USB_BULK_CB_WRAP_LEN ); + +debug ("cbw: Signature:%x\n" , cbw.Signature); +debug ("cbw: Tag=%x\n" , cbw.Tag); + debug("cbw: DataTransferLength=%d\n",cbw.DataTransferLength);
drivers/usb/gadget/f_rockusb.c new file +6
-0+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],
drivers/usb/gadget/f_rockusb.c new file +1
-0+ cbw.CDB[3],cbw.CDB[2]);
drivers/usb/gadget/f_rockusb.c new file +8
-0+debug ("cbw: ucReserved2=%x\n" , cbw.CDB[6 ]); +debug ("cbw: usLength:%x %x\n" , cbw.CDB[8 ], cbw.CDB[7 ]); + +} + +static void printcsw (char *buf) +{ +struct bulk_cs_wrap csw__attribute__((aligned(ARCH_DMA_MINALIGN))); +
drivers/usb/gadget/f_rockusb.c line 414
Quoted 7 lines
drivers/usb/gadget/f_rockusb.c new file +7
-0+memcpy ((char *)&csw, buf,USB_BULK_CS_WRAP_LEN ); +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); + +}
Those debug functions should go to f_rockchip.h file and should be guarded with #ifdef DEBUG
Quoted 8 lines
drivers/usb/gadget/f_rockusb.c new file +2
-0+ +static int rockusb_tx_write_csw(u32 Tag, int residue, u8 Status, intsize) +{
drivers/usb/gadget/f_rockusb.c new file +1
-0+struct bulk_cs_wrap csw__attribute__((aligned(ARCH_DMA_MINALIGN)));
drivers/usb/gadget/f_rockusb.c new file +3
-0+ csw.Signature =cpu_to_le32 (USB_BULK_CS_SIG ); + csw.Tag = Tag; + csw.Residue =cpu_to_be32 (residue);
drivers/usb/gadget/f_rockusb.c line 431
Quoted 10 lines
drivers/usb/gadget/f_rockusb.c new file +10
-0+ csw.Status = Status; +printcsw ((char *)&csw); +return rockusb_tx_write ((char *)&csw, size); +} + +int download_tag =0 ; +int download_lba =0 ; +static unsigned int download_size; +static unsigned int download_bytes; +struct blk_desc *download_desc =0 ;
This pointer is allocated in BSS, so should be cleared (NULL'ed).
Quoted 45 lines
drivers/usb/gadget/f_rockusb.c new file +20
-0+ +static unsigned int rx_bytes_expected (struct usb_ep *ep) +{ +int rx_remain = download_size - download_bytes; +unsigned int rem; +unsigned int maxpacket = ep->maxpacket; + +if (rx_remain <=0 ) +return 0 ; +else if (rx_remain >EP_BUFFER_SIZE ) +return EP_BUFFER_SIZE ; + + rem = rx_remain % maxpacket; +if (rem >0 ) + rx_remain = rx_remain + (maxpacket - rem); + +return rx_remain; +} + +static void rx_handler_dl_image(struct usb_ep *ep, struct
usb_request*req) +{drivers/usb/gadget/f_rockusb.c new file +7
-0+unsigned int transfer_size = download_size - download_bytes; +const unsigned char *buffer = req->buf; +unsigned int buffer_size = req->actual; + +if (!download_desc){ +printf ("rx_handler_dl_image blk_get_dev\n" ); + download_desc = blk_get_dev(rockusb_dev_type,
rockusb_dev_index);drivers/usb/gadget/f_rockusb.c new file +1
-0+ if (!download_desc || download_desc->type ==DEV_TYPE_UNKNOWN){
drivers/usb/gadget/f_rockusb.c new file +2
-0+error ("invalid mmc device\n" ); + rockusb_tx_write_csw(download_tag, 0,
CSW_FAIL,
+USB_BULK_CS_WRAP_LEN);drivers/usb/gadget/f_rockusb.c new file +8
-0+return ; + } + } + +if (req->status !=0 ) { +printf ("Bad status: %d\n" , req->status); + rockusb_tx_write_csw(download_tag, 0, + CSW_FAIL,
USB_BULK_CS_WRAP_LEN);
drivers/usb/gadget/f_rockusb.c line 478
Quoted 7 lines
drivers/usb/gadget/f_rockusb.c new file +7
-0+return ; + } + +if (buffer_size < transfer_size) + transfer_size = buffer_size; + + memcpy((void *)CONFIG_FASTBOOT_BUF_ADDR + download_bytes,
Here we should have different name for CONFIG_*_BUF_ADDR
- e.g. CONFIG_ROCKCHIP_BUF_ADDR, which should be defined in Kconfig as well (with some default value).
Quoted 40 lines
drivers/usb/gadget/f_rockusb.c new file +7
-0+ buffer, transfer_size); + download_bytes += transfer_size; + +/* Check if transfer is done */ +if (download_bytes >= download_size) { +int blks =0 , blkcnt = download_size/512 ; + printf("download %d bytes finished, start writing tolba %x\n",
drivers/usb/gadget/f_rockusb.c new file +2
-0+ download_bytes, download_lba); + blks = blk_dwrite(download_desc, download_lba,blkcnt,
+
(char*)CONFIG_FASTBOOT_BUF_ADDR);drivers/usb/gadget/f_rockusb.c new file +5
-0+if (blks != blkcnt) { +error ("failed writing to device %s: %d\n" , + rockusb_dev_type, rockusb_dev_index); + rockusb_tx_write_csw(download_tag, 0, + CSW_FAIL,
USB_BULK_CS_WRAP_LEN);drivers/usb/gadget/f_rockusb.c new file +18
-0+return ; + } + + req->complete = rx_handler_command; + req->length =EP_BUFFER_SIZE ; + download_size =0 ; +printf ("done\n" ); +rockusb_tx_write_csw (download_tag,0 ,CSW_GOOD , +USB_BULK_CS_WRAP_LEN ); + }else { + req->length =rx_bytes_expected (ep); + } + + req->actual =0 ; +usb_ep_queue (ep, req,0 ); +} + +static void cb_test_unit_ready(struct usb_ep *ep, struct usb_request*req) +{
drivers/usb/gadget/f_rockusb.c new file +1
-0+struct fsg_bulk_cb_wrap cbw__attribute__((aligned(ARCH_DMA_MINALIGN))); +
drivers/usb/gadget/f_rockusb.c
Quoted 1 line
drivers/usb/gadget/f_rockusb.c new file +1
-0+memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN );
You can use ALLOC_CACHE_ALIGN_BUFFER() to define cache safe struct inside the function.
Please fix it globally.
For global cache safe allocations you can use DEFINE_CACHE_ALIGN_BUFFER (more info at ./include/memalign.h)
Quoted 78 lines
drivers/usb/gadget/f_rockusb.c new file +7
-0+ +rockusb_tx_write_csw (cbw.Tag, cbw.DataTransferLength, +CSW_GOOD ,USB_BULK_CS_WRAP_LEN ); + +} + +static void cb_read_storage_id(struct usb_ep *ep, struct usb_request*req) +{
drivers/usb/gadget/f_rockusb.c new file +1
-0+struct fsg_bulk_cb_wrap cbw__attribute__((aligned(ARCH_DMA_MINALIGN)));
drivers/usb/gadget/f_rockusb.c new file +6
-0+char emmc_id[] ="EMMC " ; + +printf ("cb_read_storage_id\n" ); +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +rockusb_tx_write_str (emmc_id);//only support emmc now + rockusb_tx_write_csw(cbw.Tag, cbw.DataTransferLength,
CSW_GOOD,drivers/usb/gadget/f_rockusb.c new file +6
-0+ USB_BULK_CS_WRAP_LEN); +} + +static void cb_write_lba (struct usb_ep *ep,struct usb_request *req) +{ +struct fsg_bulk_cb_wrap cbw__attribute__((aligned(ARCH_DMA_MINALIGN)));
drivers/usb/gadget/f_rockusb.c new file +9
-0+int sector_count; + +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + sector_count = (int )get_unaligned_be16 (&cbw.CDB[7 ]); + download_lba =get_unaligned_be32 (&cbw.CDB[2 ]); + download_size = sector_count *512 ; + download_bytes =0 ; + download_tag = cbw.Tag; + if ((0 == download_size) ||(download_size>CONFIG_FASTBOOT_BUF_SIZE)){
drivers/usb/gadget/f_rockusb.c new file +1
-0+ rockusb_tx_write_csw(cbw.Tag,cbw.DataTransferLength,
drivers/usb/gadget/f_rockusb.c new file +1
-0+ CSW_FAIL,
USB_BULK_CS_WRAP_LEN);drivers/usb/gadget/f_rockusb.c new file +15
-0+ }else { + req->complete = rx_handler_dl_image; + req->length =rx_bytes_expected (ep); + } +} + +static int reboot_flag; + +int __weak rkusb_set_reboot_flag (int flag) +{ +printf ("rkusb_set_reboot_flag: %d\n" , reboot_flag); +return -ENOSYS ; +} + +static void compl_do_reset(struct usb_ep *ep, struct usb_request*req) +{
drivers/usb/gadget/f_rockusb.c new file +7
-0+rkusb_set_reboot_flag (reboot_flag); +do_reset (NULL ,0 ,0 ,NULL ); +} + +static void cb_reboot (struct usb_ep *ep,struct usb_request *req) +{ +struct fsg_bulk_cb_wrap cbw__attribute__((aligned(ARCH_DMA_MINALIGN)));
drivers/usb/gadget/f_rockusb.c new file +5
-0+ reboot_flag =0 ; +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); + reboot_flag = cbw.CDB[1 ]; + rockusb_func->in_req->complete = compl_do_reset; + rockusb_tx_write_csw(cbw.Tag, cbw.DataTransferLength,
CSW_GOOD,drivers/usb/gadget/f_rockusb.c new file +4
-0+ USB_BULK_CS_WRAP_LEN); +} + +static void cb_not_support(struct usb_ep *ep, struct usb_request*req) +{
drivers/usb/gadget/f_rockusb.c new file +1
-0+struct fsg_bulk_cb_wrap cbw__attribute__((aligned(ARCH_DMA_MINALIGN))); +
drivers/usb/gadget/f_rockusb.c new file +3
-0+memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +printf ("Rockusb command %x not support yet\n" , cbw.CDB[0 ]); + rockusb_tx_write_csw(cbw.Tag, 0, CSW_FAIL,
Quoted 2 lines
USB_BULK_CS_WRAP_LEN); +}
+
------------------------>8--------------------------
Quoted 60 lines
drivers/usb/gadget/f_rockusb.c new file +60
-0+#define RKUSB_STATUS_IDLE 0 +#define RKUSB_STATUS_CMD 1 +#define RKUSB_STATUS_RXDATA 2 +#define RKUSB_STATUS_TXDATA 3 +#define RKUSB_STATUS_CSW 4 +#define RKUSB_STATUS_RXDATA_PREPARE 5 +#define RKUSB_STATUS_TXDATA_PREPARE 6 + +typedef enum { +TEST_UNIT_READY =0 , +READ_FLASH_ID =0x01 , +TEST_BAD_BLOCK =0x03 , +READ_SECTOR =0x04 , +WRITE_SECTOR =0x05 , +ERASE_NORMAL =0x06 , +ERASE_FORCE =0x0B , +READ_LBA =0x14 , +WRITE_LBA =0x15 , +ERASE_SYSTEMDISK =0x16 , +READ_SDRAM =0x17 , +WRITE_SDRAM =0x18 , +EXECUTE_SDRAM =0x19 , +READ_FLASH_INFO =0x1A , +READ_CHIP_INFO =0x1B , +SET_RESET_FLAG =0x1E , +WRITE_EFUSE =0x1F , +READ_EFUSE =0x20 , +READ_SPI_FLASH =0x21 , +WRITE_SPI_FLASH =0x22 , +WRITE_NEW_EFUSE =0x23 , +READ_NEW_EFUSE =0x24 , +DEVICE_RESET =0xFF +}USB_OPERATION_CODE ; + +#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 +
drivers/usb/gadget/f_rockusb.c line 657
Quoted 10 lines
drivers/usb/gadget/f_rockusb.c new file +10
-0+#define K_FW_SESSION 0X30 +#define K_FW_RESET 0xff + +#define CBW_DIRECTION_OUT 0x00 +#define CBW_DIRECTION_IN 0x80 + +struct cmd_dispatch_info { +int cmd; +void (*cb)(struct usb_ep *ep,struct usb_request *req); +};
----------------------8<---------------------------------------
This should go to f_rockchip.h file
Quoted 112 lines
drivers/usb/gadget/f_rockusb.c new file +107
-0+ +static const struct cmd_dispatch_info cmd_dispatch_info[] = { + { + .cmd =K_FW_TEST_UNIT_READY , + .cb = cb_test_unit_ready, + }, + { + .cmd =K_FW_READ_FLASH_ID , + .cb = cb_read_storage_id, + }, + { + .cmd =K_FW_SET_DEVICE_ID , + .cb = cb_not_support, + }, + { + .cmd =K_FW_TEST_BAD_BLOCK , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_ERASE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_WRITE_SPARE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_SPARE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_ERASE_10_FORCE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_GET_VERSION , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LBA_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LBA_WRITE_10 , + .cb = cb_write_lba, + }, + { + .cmd =K_FW_ERASE_SYS_DISK , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SDRAM_EXECUTE , + .cb = cb_not_support, + }, + { + .cmd =K_FW_READ_FLASH_INFO , + .cb = cb_not_support, + }, + { + .cmd =K_FW_GET_CHIP_VER , + .cb = cb_not_support, + }, + { + .cmd =K_FW_LOW_FORMAT , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SET_RESET_FLAG , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SPI_READ_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SPI_WRITE_10 , + .cb = cb_not_support, + }, + { + .cmd =K_FW_SESSION , + .cb = cb_not_support, + }, + { + .cmd =K_FW_RESET , + .cb = cb_reboot, + }, +}; + + + +static void rx_handler_command(struct usb_ep *ep, struct usb_request*req) +{
drivers/usb/gadget/f_rockusb.c new file +1
-0+void (*func_cb)(struct usb_ep *ep,struct usb_request *req)= NULL;
drivers/usb/gadget/f_rockusb.c new file +1
-0+struct fsg_bulk_cb_wrap cbw__attribute__((aligned(ARCH_DMA_MINALIGN)));
drivers/usb/gadget/f_rockusb.c line 771
Quoted 4 lines
drivers/usb/gadget/f_rockusb.c new file +4
-0+int i; +char *cmdbuf = req->buf; + +if (req->status !=0 || req->length ==0 )
^^^^^^^^^^^ req->status is enough
Quoted 20 lines
drivers/usb/gadget/f_rockusb.c new file +20
-0+return ; + +memcpy ((char *)&cbw, req->buf,USB_BULK_CB_WRAP_LEN ); +printcbw (req->buf); + +for (i =0 ; i <ARRAY_SIZE (cmd_dispatch_info); i++) { +if (cmd_dispatch_info[i].cmd == cbw.CDB[0 ]) { + func_cb = cmd_dispatch_info[i].cb; +break ; + } + } + +if (!func_cb) { +error ("unknown command: %s" , (char *)req->buf); +rockusb_tx_write_str ("FAILunknown command" ); + }else { +if (req->actual < req->length) { +u8 *buf = (u8 *)req->buf; + buf[req->actual] =0 ; +func_cb (ep, req);
drivers/usb/gadget/f_rockusb.c line 801
Quoted 10 lines
drivers/usb/gadget/f_rockusb.c new file +10
-0+ }else { +error ("buffer overflow" ); +rockusb_tx_write_str ("FAILbuffer overflow" ); + } + } + + *cmdbuf ='\0' ; + req->actual =0 ; +usb_ep_queue (ep, req,0 ); +}
Despite few minor comments - this is what I've expected.
Please add changelog when pasting your patches.
Also using patman (./tools/patman) could facilitate posting patches.
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
PATCH 2/3 cmd: add rockusb command
In reply to Eddie Caithis patch add rockusb command. the usage is
rockusb <USB_controller> [<devtype>] <devnum>
e.g. rockusb 0 mmc 0
--- cmd/Kconfig | 12 +++++++++ cmd/Makefile | 1 + cmd/rockusb.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/rockusb.h | 13 +++++++++ 4 files changed, 105 insertions(+) create mode 100644 cmd/rockusb.c create mode 100644 include/rockusb.h
cmd/Kconfig +12 -0
@@ -475,6 +475,18 @@ 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" + select USB_FUNCTION_ROCKUSB + help + Enables the command "rockusb" which is used to have U-Boot create a + Rockusb class device via USB. + +config USB_FUNCTION_ROCKUSB + bool "Enable USB rockusb gadget" + help + This enables the USB part of the rockusb gadget. + config CMD_USB_MASS_STORAGE bool "UMS usb mass storage" help
cmd/Makefile +1 -0
@@ -141,6 +141,7 @@ endif obj-$(CONFIG_CMD_USB) += usb.o disk.o obj-$(CONFIG_CMD_FASTBOOT) += fastboot.o +obj-$(CONFIG_CMD_ROCKUSB) += rockusb.o obj-$(CONFIG_CMD_FS_UUID) += fs_uuid.o obj-$(CONFIG_CMD_USB_MASS_STORAGE) += usb_mass_storage.o
cmd/rockusb.c new file +79 -0
79 lines not on this page · raw message
include/rockusb.h new file +13 -0
@@ -0,0 +1,13 @@ +/* +* (C) Copyright 2017 +* +* Eddie Cai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#ifndef _ROCKUSB_H_ +#define _ROCKUSB_H_ + +void rockusb_dev_init (char *dev_type,int dev_index); + +#endif /* _ROCKUSB_H_ */
Signature · 1 line
2.7.4
PATCH 2/3 cmd: add rockusb command
Hi Eddie,
Quoted 6 lines · Eddie Cai
this patch add rockusb command. the usage is
rockusb <USB_controller> [<devtype>] <devnum>
e.g. rockusb 0 mmc 0Signed-off-by Eddie Cai <[email protected]>
Quoted 8 lines
--- cmd/Kconfig | 12 +++++++++ cmd/Makefile | 1 + cmd/rockusb.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/rockusb.h | 13 +++++++++ 4 files changed, 105 insertions(+) create mode 100644 cmd/rockusb.c create mode 100644 include/rockusb.h
Can you please add some documentation on how to use this command and what host tools you need?
Quoted 6 lines
cmd/Kconfig +0
-0
cmd/Kconfig config CMD_DFU · line 483
Quoted 9 lines
cmd/Kconfig +6
-0@@ -475,6 +475,18 @@ 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" + select USB_FUNCTION_ROCKUSB + help + Enables the command "rockusb" which is used to have U-Boot create a + Rockusb class device via USB.
Does this mean Rockchip-class device?
Quoted 14 lines
cmd/Kconfig +6
-0+ +config USB_FUNCTION_ROCKUSB + bool "Enable USB rockusb gadget" + help + This enables the USB part of the rockusb gadget. + config CMD_USB_MASS_STORAGE bool "UMS usb mass storage" helpcmd/Makefile +0
-0
cmd/Makefile endif · line 145
Quoted 5 lines
cmd/Makefile +1
-0@@ -141,6 +141,7 @@ endif obj-$(CONFIG_CMD_USB) += usb.o disk.o obj-$(CONFIG_CMD_FASTBOOT) += fastboot.o +obj-$(CONFIG_CMD_ROCKUSB) += rockusb.o obj-$(CONFIG_CMD_FS_UUID) += fs_uuid.o
Can you put it in alphabetical order if possible?
Quoted 10 lines
cmd/Makefile +0
-0obj-$(CONFIG_CMD_USB_MASS_STORAGE) += usb_mass_storage.ocmd/rockusb.c new file +2
-0@@ -0,0 +1,79 @@ +/* +* Copyright (C) 2017 Eddie Cai <[email protected]>
cmd/rockusb.c line 12
Quoted 10 lines
cmd/rockusb.c new file +10
-0+* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <command.h> +#include <console.h> +#include <g_dnl.h> +#include <usb.h> +#include <rockusb.h>
Should go above usb.h
cmd/rockusb.c line 13
Quoted 1 line
cmd/rockusb.c new file +1
-0+
remove extra blank line
Quoted 14 lines
cmd/rockusb.c new file +14
-0+ +static int do_rockusb (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +int controller_index, dev_index; +char *usb_controller; +char *devtype; +char *devnum; +int ret; + +if (argc <2 ) +return CMD_RET_USAGE ; + + usb_controller = argv[1 ]; + controller_index =simple_strtoul (usb_controller,NULL ,0 );
cmd/rockusb.c line 37
Quoted 10 lines
cmd/rockusb.c new file +10
-0+ +if (argc >=4 ) { + devtype = argv[2 ]; + devnum = argv[3 ]; + }else { + devtype ="mmc" ; + devnum = argv[2 ]; + } + dev_index =simple_strtoul (devnum,NULL ,0 ); +rockusb_dev_init (devtype, dev_index);
Can this fail, e.g. if index is out of range?
cmd/rockusb.c line 48
Quoted 11 lines
cmd/rockusb.c new file +11
-0+ + ret =board_usb_init (controller_index,USB_INIT_DEVICE ); +if (ret) { +error ("USB init failed: %d" , ret); +return CMD_RET_FAILURE ; + } + +g_dnl_clear_detach (); + ret =g_dnl_register ("usb_dnl_rockusb" ); +if (ret) +return ret;
Commands should return either 0 or CMD_RET_FAILURE.
cmd/rockusb.c line 49
Quoted 1 line
cmd/rockusb.c new file +1
-0+printf ("do_rockusb1\n" );
Do you want this?
Quoted 5 lines
cmd/rockusb.c new file +5
-0+if (!g_dnl_board_usb_cable_connected ()) { +puts ("\rUSB cable not detected.\n" \ +"Command exit.\n" ); + ret =CMD_RET_FAILURE ; + goto exit;
cmd/rockusb.c line 64
Quoted 10 lines
cmd/rockusb.c new file +10
-0+ } + +while (1 ) { +if (g_dnl_detach ()) +break ; +if (ctrlc ()) +break ; +usb_gadget_handle_interrupts (controller_index); + } +printf ("do_rockusb2\n" );
Do you want this?
cmd/rockusb.c line 76
Quoted 12 lines
cmd/rockusb.c new file +12
-0+ ret =CMD_RET_SUCCESS ; + +exit: +g_dnl_unregister (); +g_dnl_clear_detach (); +board_usb_cleanup (controller_index,USB_INIT_DEVICE ); + +return ret; +} + +U_BOOT_CMD(rockusb, 4, 1, do_rockusb, + "Use the ROCKUSB",
Can you add a little more here?
include/rockusb.h
Quoted 8 lines
cmd/rockusb.c new file +3
-0+"rockusb <USB_controller> [<devtype>] <devnum> e.g. rockusb 0 mmc 0\n" +" devtype defaults to mmc" +);include/rockusb.h new file +0
-0
Can this go in include/asm instead?
include/rockusb.h line 11
Quoted 12 lines
include/rockusb.h new file +11
-0@@ -0,0 +1,13 @@ +/* +* (C) Copyright 2017 +* +* Eddie Cai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#ifndef _ROCKUSB_H_ +#define _ROCKUSB_H_ + +void rockusb_dev_init (char *dev_type,int dev_index);
Please add a function comment.
Quoted 5 lines
include/rockusb.h new file +2
-1+ +#endif /* _ROCKUSB_H_ */ --2.7.4
Regards,
Simon
PATCH 2/3 cmd: add rockusb command
Hi Simon
2017-03-20 10:29 GMT+08:00 Simon Glass <[email protected]>:
Quoted 13 lines
Hi Eddie,
Quoted 10 lines · Eddie Cai
this patch add rockusb command. the usage is
rockusb <USB_controller> [<devtype>] <devnum>
e.g. rockusb 0 mmc 0Signed-off-by Eddie Cai <[email protected]>--- cmd/Kconfig | 12 +++++++++ cmd/Makefile | 1 + cmd/rockusb.c | 79 ++++++++++++++++++++++++++++++
Quoted 9 lines
+++++++++++++++++++++++++
Quoted 4 lines
include/rockusb.h | 13 +++++++++ 4 files changed, 105 insertions(+) create mode 100644 cmd/rockusb.c create mode 100644 include/rockusb.hCan you please add some documentation on how to use this command and what host tools you need?
Sure, I will add README.rockusb in next version
Quoted 16 lines
cmd/Kconfig config CMD_DFU · line 475
Quoted 8 lines
cmd/Kconfig +0
-0@@ -475,6 +475,18 @@ config CMD_DFU Enables the command "dfu" which is used to have U-Boot createa DFU
cmd/Kconfig config CMD_DFU
Quoted 7 lines
cmd/Kconfig +5
-0class device via USB. +config CMD_ROCKUSB + bool "rockusb" + select USB_FUNCTION_ROCKUSB + help + Enables the command "rockusb" which is used to have U-Boot
Quoted 5 lines
create a
cmd/Kconfig config CMD_DFU · line 483
Quoted 1 line
cmd/Kconfig +1
-0+ Rockusb class device via USB.Does this mean Rockchip-class device?
Yes, This is vendor specific class.
Quoted 16 lines
Quoted 16 lines
cmd/Kconfig +6
-0+ +config USB_FUNCTION_ROCKUSB + bool "Enable USB rockusb gadget" + help + This enables the USB part of the rockusb gadget. + config CMD_USB_MASS_STORAGE bool "UMS usb mass storage" helpcmd/Makefile +0
-0@@ -141,6 +141,7 @@ endif
Quoted 7 lines
cmd/Makefile endif · line 145
Quoted 4 lines
cmd/Makefile +1
-0obj-$(CONFIG_CMD_USB) += usb.o disk.o obj-$(CONFIG_CMD_FASTBOOT) += fastboot.o +obj-$(CONFIG_CMD_ROCKUSB) += rockusb.o obj-$(CONFIG_CMD_FS_UUID) += fs_uuid.oCan you put it in alphabetical order if possible?
Sure, I will try to put it in alphabetical order in next version
Quoted 15 lines
Quoted 15 lines
cmd/Makefile +0
-0obj-$(CONFIG_CMD_USB_MASS_STORAGE) += usb_mass_storage.ocmd/rockusb.c new file +6
-0@@ -0,0 +1,79 @@ +/* +* Copyright (C) 2017 Eddie Cai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +
Quoted 9 lines
cmd/rockusb.c line 12
Quoted 6 lines
cmd/rockusb.c new file +6
-0+#include <common.h> +#include <command.h> +#include <console.h> +#include <g_dnl.h> +#include <usb.h> +#include <rockusb.h> Should go above
usb.h
done
Quoted 5 lines
cmd/rockusb.c line 13
Quoted 2 lines
cmd/rockusb.c new file +1
-0+remove extra blank line
done
Quoted 20 lines
cmd/rockusb.c line 15
Quoted 3 lines
cmd/rockusb.c new file +2
-0+ +static int do_rockusb(cmd_tbl_t *cmdtp, int flag, int argc, char *constargv[])
Quoted 16 lines
cmd/rockusb.c new file +16
-0+{ +int controller_index, dev_index; +char *usb_controller; +char *devtype; +char *devnum; +int ret; + +if (argc <2 ) +return CMD_RET_USAGE ; + + usb_controller = argv[1 ]; + controller_index =simple_strtoul (usb_controller,NULL ,0 ); + +if (argc >=4 ) { + devtype = argv[2 ]; + devnum = argv[3 ];
Quoted 9 lines
cmd/rockusb.c line 37
Quoted 6 lines
cmd/rockusb.c new file +6
-0+ }else { + devtype ="mmc" ; + devnum = argv[2 ]; + } + dev_index =simple_strtoul (devnum,NULL ,0 ); +rockusb_dev_init (devtype, dev_index);Can this fail, e.g. if index is out of range?
I will add a return value in next version
Quoted 15 lines
cmd/rockusb.c line 48
Quoted 12 lines
cmd/rockusb.c new file +11
-0+ + ret =board_usb_init (controller_index,USB_INIT_DEVICE ); +if (ret) { +error ("USB init failed: %d" , ret); +return CMD_RET_FAILURE ; + } + +g_dnl_clear_detach (); + ret =g_dnl_register ("usb_dnl_rockusb" ); +if (ret) +return ret;Commands should return either 0 or
CMD_RET_FAILURE.
OK, i will fix it in next version.
Quoted 5 lines
cmd/rockusb.c line 49
Quoted 2 lines
cmd/rockusb.c new file +1
-0+printf ("do_rockusb1\n" );Do you want this?
Oops, i will remove it in next version.
Quoted 17 lines
Quoted 6 lines
cmd/rockusb.c new file +5
-0+if (!g_dnl_board_usb_cable_connected ()) { +puts ("\rUSB cable not detected.\n" \ +"Command exit.\n" ); + ret =CMD_RET_FAILURE ; + goto exit;cmd/rockusb.c line 64
Quoted 10 lines
cmd/rockusb.c new file +10
-0+ } + +while (1 ) { +if (g_dnl_detach ()) +break ; +if (ctrlc ()) +break ; +usb_gadget_handle_interrupts (controller_index); + } +printf ("do_rockusb2\n" );
Quoted 2 lines
Do you want this?
i will remove it in next version.
Quoted 16 lines
cmd/rockusb.c line 76
Quoted 13 lines
cmd/rockusb.c new file +12
-0+ ret =CMD_RET_SUCCESS ; + +exit: +g_dnl_unregister (); +g_dnl_clear_detach (); +board_usb_cleanup (controller_index,USB_INIT_DEVICE ); + +return ret; +} + +U_BOOT_CMD(rockusb, 4, 1, do_rockusb, + "Use the ROCKUSB",Can you add a little more here?
sure
Quoted 13 lines
cmd/rockusb.c line 77
Quoted 2 lines
cmd/rockusb.c new file +1
-0+ "rockusb <USB_controller> [<devtype>] <devnum> e.g. rockusb 0mmc 0\n"
include/rockusb.h
Quoted 7 lines
cmd/rockusb.c new file +2
-0+" devtype defaults to mmc" +);include/rockusb.h new file +0
-0Can this go in
include/asminstead?
do you mean include/asm-generic ? may i know why ?
Quoted 16 lines
include/rockusb.h line 11
Quoted 13 lines
include/rockusb.h new file +11
-0@@ -0,0 +1,13 @@ +/* +* (C) Copyright 2017 +* +* Eddie Cai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#ifndef _ROCKUSB_H_ +#define _ROCKUSB_H_ + +void rockusb_dev_init (char *dev_type,int dev_index);Please add a function comment.
OK, i will add a function comment in next version .
Quoted 10 lines
Quoted 6 lines
include/rockusb.h new file +2
-1+ +#endif /* _ROCKUSB_H_ */ --2.7.4
Regards,
Simon
PATCH 2/3 cmd: add rockusb command
Hi Eddie,
Quoted 23 lines · Eddie Cai
Hi Simon
2017-03-20 10:29 GMT+08:00 Simon Glass <[email protected]>:
Quoted 20 lines
Hi Eddie,
Quoted 15 lines · Eddie Cai
this patch add rockusb command. the usage is
rockusb <USB_controller> [<devtype>] <devnum>
e.g. rockusb 0 mmc 0Signed-off-by Eddie Cai <[email protected]>--- cmd/Kconfig | 12 +++++++++ cmd/Makefile | 1 + cmd/rockusb.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/rockusb.h | 13 +++++++++ 4 files changed, 105 insertions(+) create mode 100644 cmd/rockusb.c create mode 100644 include/rockusb.h
[..]
Quoted 13 lines
Quoted 12 lines
include/rockusb.h
Quoted 10 lines
+ "rockusb <
USB_controller> [<devtype>] <devnum> e.g. rockusb 0
mmc 0\n"cmd/rockusb.c new file +2
-0+" devtype defaults to mmc" +);include/rockusb.h new file +0
-0Can this go in
include/asminstead?
Quoted 1 line
do you mean
include/asm-generic? may i know why ?
No I was thinking of arch/arm/include/asm/arch-rockchip. Because this is a rockchip-specific file, isn't it?
Regards,
Simon
PATCH 2/3 cmd: add rockusb command
In reply to Eddie CaiHi Eddie,
Quoted 60 lines
this patch add rockusb command. the usage is
rockusb <USB_controller> [<devtype>] <devnum>
e.g. rockusb 0 mmc 0Signed-off-by Eddie Cai <[email protected]>--- cmd/Kconfig | 12 +++++++++ cmd/Makefile | 1 + cmd/rockusb.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/rockusb.h | 13 +++++++++ 4 files changed, 105 insertions(+) create mode 100644 cmd/rockusb.c create mode 100644 include/rockusb.hcmd/Kconfig +0
-0@@ -475,6 +475,18 @@ config CMD_DFU Enables the command "dfu" which is used to have U-Bootcreate a DFU class device via USB.
cmd/Kconfig +5
-0+config CMD_ROCKUSB + bool "rockusb" + select USB_FUNCTION_ROCKUSB + help + Enables the command "rockusb" which is used to have U-Bootcreate a
cmd/Kconfig +7
-0+ Rockusb class device via USB. + +config USB_FUNCTION_ROCKUSB + bool "Enable USB rockusb gadget" + help + This enables the USB part of the rockusb gadget. + config CMD_USB_MASS_STORAGE bool "UMS usb mass storage" helpcmd/Makefile +1
-0@@ -141,6 +141,7 @@ endif obj-$(CONFIG_CMD_USB) += usb.o disk.o obj-$(CONFIG_CMD_FASTBOOT) += fastboot.o +obj-$(CONFIG_CMD_ROCKUSB) += rockusb.o obj-$(CONFIG_CMD_FS_UUID) += fs_uuid.o obj-$(CONFIG_CMD_USB_MASS_STORAGE) += usb_mass_storage.ocmd/rockusb.c new file +4
-0@@ -0,0 +1,79 @@ +/* +* Copyright (C) 2017 Eddie Cai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+
cmd/rockusb.c line 14
Quoted 10 lines
cmd/rockusb.c new file +10
-0+*/ + +#include <common.h> +#include <command.h> +#include <console.h> +#include <g_dnl.h> +#include <usb.h> +#include <rockusb.h> + +
Please remove the extra blank here. (also run your patches through ./scripts/checkpatch.pl before submission.
Quoted 11 lines
cmd/rockusb.c new file +1
-0+static int do_rockusb(cmd_tbl_t *cmdtp, int flag, int argc, char*const argv[]) +{
cmd/rockusb.c new file +9
-0+int controller_index, dev_index; +char *usb_controller; +char *devtype; +char *devnum; +int ret; + +if (argc <2 ) +return CMD_RET_USAGE ; +
cmd/rockusb.c line 35
Quoted 10 lines
cmd/rockusb.c new file +10
-0+ usb_controller = argv[1 ]; + controller_index =simple_strtoul (usb_controller,NULL ,0 ); + +if (argc >=4 ) { + devtype = argv[2 ]; + devnum = argv[3 ]; + }else { + devtype ="mmc" ; + devnum = argv[2 ]; + }
I would prefer to force the whole command syntax support:
"rockchip 0 mmc 0" to comply with other commands (like thor, dfu).
Instead of "rockchip 0 0" and imply the mmc.
Quoted 4 lines
cmd/rockusb.c new file +4
-0+ dev_index =simple_strtoul (devnum,NULL ,0 ); +rockusb_dev_init (devtype, dev_index); + + ret =board_usb_init (controller_index,USB_INIT_DEVICE );
cmd/rockusb.c line 49
Quoted 10 lines
cmd/rockusb.c new file +10
-0+if (ret) { +error ("USB init failed: %d" , ret); +return CMD_RET_FAILURE ; + } + +g_dnl_clear_detach (); + ret =g_dnl_register ("usb_dnl_rockusb" ); +if (ret) +return ret; +printf ("do_rockusb1\n" );
^^^^^^^^^^^^^^^^^^^^^^^^ this should be either removed or rewritten as "debug(...)".
Quoted 29 lines
cmd/rockusb.c new file +28
-0+if (!g_dnl_board_usb_cable_connected ()) { +puts ("\rUSB cable not detected.\n" \ +"Command exit.\n" ); + ret =CMD_RET_FAILURE ; + goto exit; + } + +while (1 ) { +if (g_dnl_detach ()) +break ; +if (ctrlc ()) +break ; +usb_gadget_handle_interrupts (controller_index); + } +printf ("do_rockusb2\n" ); + ret =CMD_RET_SUCCESS ; + +exit: +g_dnl_unregister (); +g_dnl_clear_detach (); +board_usb_cleanup (controller_index,USB_INIT_DEVICE ); + +return ret; +} + +U_BOOT_CMD(rockusb, 4, 1, do_rockusb, + "Use the ROCKUSB", + "rockusb <USB_controller> [<devtype>] <devnum> e.g. rockusb0 mmc 0\n"
cmd/rockusb.c line 78
Quoted 1 line
cmd/rockusb.c new file +1
-0+" devtype defaults to mmc"
[<devtype>] should be mandatory.
Quoted 10 lines
cmd/rockusb.c new file +1
-0+);include/rockusb.h new file +3
-0@@ -0,0 +1,13 @@ +/* +* (C) Copyright 2017 +*
include/rockusb.h line 13
Quoted 10 lines
include/rockusb.h new file +10
-0+* Eddie Cai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#ifndef _ROCKUSB_H_ +#define _ROCKUSB_H_ + +void rockusb_dev_init (char *dev_type,int dev_index); + +#endif /* _ROCKUSB_H_ */
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
PATCH 3/3 rockchip: rk3288: enable rockusb support on rk3288 based device
In reply to Eddie Caithis patch enable rockusb support on rk3288 based device.
--- include/configs/rk3288_common.h | 4 ++++ 1 file changed, 4 insertions(+)
include/configs/rk3288_common.h +4 -0
@@ -74,6 +74,10 @@#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR#define CONFIG_FASTBOOT_BUF_SIZE 0x08000000 +/* rockusb */ +#define CONFIG_CMD_ROCKUSB +#define CONFIG_USB_FUNCTION_ROCKUSB +/* usb mass storage */ #define CONFIG_USB_FUNCTION_MASS_STORAGE #define CONFIG_CMD_USB_MASS_STORAGE
Signature · 1 line
2.7.4
PATCH 3/3 rockchip: rk3288: enable rockusb support on rk3288 based device
Hi Eddie.
Quoted 6 lines · Eddie Cai
this patch enable rockusb support on rk3288 based device.
Signed-off-by Eddie Cai <[email protected]>--- include/configs/rk3288_common.h | 4 ++++ 1 file changed, 4 insertions(+)
I think this should be done in Kconfig.
Quoted 17 lines
include/configs/rk3288_common.h +4
-1@@ -74,6 +74,10 @@#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR#define CONFIG_FASTBOOT_BUF_SIZE 0x08000000 +/* rockusb */ +#define CONFIG_CMD_ROCKUSB +#define CONFIG_USB_FUNCTION_ROCKUSB +/* usb mass storage */ #define CONFIG_USB_FUNCTION_MASS_STORAGE #define CONFIG_CMD_USB_MASS_STORAGE --
Quoted 2 lines
2.7.4
Regards,
Simon
PATCH 3/3 rockchip: rk3288: enable rockusb support on rk3288 based device
Hi Simon
2017-03-20 10:30 GMT+08:00 Simon Glass <[email protected]>:
Quoted 12 lines
Hi Eddie.
Quoted 6 lines · Eddie Cai
this patch enable rockusb support on rk3288 based device.
Signed-off-by Eddie Cai <[email protected]>--- include/configs/rk3288_common.h | 4 ++++ 1 file changed, 4 insertions(+)I think this should be done in
Kconfig.
OK, I will move it to Kconfig.
Quoted 25 lines
include/configs/rk3288_
Quoted 3 lines
include/configs/rk3288_ renamed from include/configs/rk3288_common.h +0
-0
common.hQuoted 15 lines
index b5606d4..b19a34d 100644
include/configs/rk3288_common.h +4
-1@@ -74,6 +74,10 @@#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR#define CONFIG_FASTBOOT_BUF_SIZE 0x08000000 +/* rockusb */ +#define CONFIG_CMD_ROCKUSB +#define CONFIG_USB_FUNCTION_ROCKUSB +/* usb mass storage */ #define CONFIG_USB_FUNCTION_MASS_STORAGE #define CONFIG_CMD_USB_MASS_STORAGE --Quoted 2 lines
2.7.4
Regards,
Simon
PATCH 3/3 rockchip: rk3288: enable rockusb support on rk3288 based device
In reply to Simon GlassHi Simon
2017-03-20 10:30 GMT+08:00 Simon Glass <[email protected]>:
Quoted 11 lines
Hi Eddie.
Quoted 6 lines · Eddie Cai
this patch enable rockusb support on rk3288 based device.
Signed-off-by Eddie Cai <[email protected]>--- include/configs/rk3288_common.h | 4 ++++ 1 file changed, 4 insertions(+)I think this should be done in
Kconfig.
since rockusb used so widely on rockchip soc based devices. every rockchip soc based
device should support it. So I would like to put it in rk3288_common.h or even rockchip-common.h.
what do you think?
Quoted 23 lines
Quoted 18 lines
include/configs/rk3288_common.h +4
-1@@ -74,6 +74,10 @@#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR#define CONFIG_FASTBOOT_BUF_SIZE 0x08000000 +/* rockusb */ +#define CONFIG_CMD_ROCKUSB +#define CONFIG_USB_FUNCTION_ROCKUSB +/* usb mass storage */ #define CONFIG_USB_FUNCTION_MASS_STORAGE #define CONFIG_CMD_USB_MASS_STORAGE --Quoted 2 lines
2.7.4
Regards,
Simon
PATCH 3/3 rockchip: rk3288: enable rockusb support on rk3288 based device
Hi Eddie,
Quoted 12 lines · Eddie Cai
Hi Simon
2017-03-20 10:30 GMT+08:00 Simon Glass <[email protected]>:Quoted 10 lines
Hi Eddie.
Quoted 6 lines · Eddie Cai
this patch enable rockusb support on rk3288 based device.
Signed-off-by Eddie Cai <[email protected]>--- include/configs/rk3288_common.h | 4 ++++ 1 file changed, 4 insertions(+)
Quoted 6 lines
Quoted 1 line
I think this should be done in
Kconfig.since rockusb used so widely on rockchip soc based devices. every rockchip soc based
device should support it. So I would like to put it inrk3288_common.hor evenrockchip-common.h.
what do you think?
We are moving to removing the board config headers so cannot add new non-Kconfig CONFIG options.
You can add it to arch/arm/Kconfig - e.g. with 'imply CONFIG_....' under 'config ARCH_ROCKCHIP'.
Please help to remove any options you can from the headers.
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
include/configs/rk3288_common.h +0
-0@@ -74,6 +74,10 @@#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR#define CONFIG_FASTBOOT_BUF_SIZE 0x08000000
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
include/configs/rk3288_common.h +4
-1+/* rockusb */ +#define CONFIG_CMD_ROCKUSB +#define CONFIG_USB_FUNCTION_ROCKUSB +/* usb mass storage */ #define CONFIG_USB_FUNCTION_MASS_STORAGE #define CONFIG_CMD_USB_MASS_STORAGE --2.7.4
Regards,
Simon
PATCH 3/3 rockchip: rk3288: enable rockusb support on rk3288 based device
Hi Simon
2017-05-03 18:09 GMT+08:00 Simon Glass <[email protected]>:
Quoted 22 lines
Hi Eddie,
Quoted 12 lines · Eddie Cai
Hi Simon
2017-03-20 10:30 GMT+08:00 Simon Glass <[email protected]>:Quoted 10 lines
Hi Eddie.
Quoted 6 lines · Eddie Cai
this patch enable rockusb support on rk3288 based device.
Signed-off-by Eddie Cai <[email protected]>--- include/configs/rk3288_common.h | 4 ++++ 1 file changed, 4 insertions(+)Quoted 6 lines
Quoted 1 line
I think this should be done in
Kconfig.since rockusb used so widely on rockchip soc based devices. every rockchip soc based
device should support it. So I would like to put it inrk3288_common.hor evenrockchip-common.h.
what do you think?
Quoted 5 lines
We are moving to removing the board config headers so cannot add new non-Kconfig CONFIG options.
You can add it to
arch/arm/Kconfig- e.g. with 'implyCONFIG_....' under 'configARCH_ROCKCHIP'.
USB_FUNCTION_ROCKUSB depend on USB_GADGET, USB_GADGET_DOWNLOAD, CONFIG_G_DNL_VENDOR_NUM, CONFIG_G_DNL_PRODUCT_NUM should i move those config to arch/arm/Kconfig? how to define CONFIG_G_DNL_VENDOR_NUM
and CONFIG_G_DNL_PRODUCT_NUM when select it?
Quoted 25 lines
Please help to remove any options you can from the headers.
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
include/configs/rk3288_common.h +0
-0@@ -74,6 +74,10 @@#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR#define CONFIG_FASTBOOT_BUF_SIZE 0x08000000Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
include/configs/rk3288_common.h +4
-1+/* rockusb */ +#define CONFIG_CMD_ROCKUSB +#define CONFIG_USB_FUNCTION_ROCKUSB +/* usb mass storage */ #define CONFIG_USB_FUNCTION_MASS_STORAGE #define CONFIG_CMD_USB_MASS_STORAGE --2.7.4
Regards,
Simon
PATCH 3/3 rockchip: rk3288: enable rockusb support on rk3288 based device
Hi Eddie, Simon,
Quoted 29 lines
Hi Simon
2017-05-03 18:09 GMT+08:00 Simon Glass <[email protected]>:
Quoted 26 lines
Hi Eddie,
Quoted 13 lines · Eddie Cai
Hi Simon
2017-03-20 10:30 GMT+08:00 Simon Glass <[email protected]>:Quoted 11 lines
Hi Eddie.
Quoted 6 lines · Eddie Cai
this patch enable rockusb support on rk3288 based device.
Signed-off-by Eddie Cai <[email protected]>--- include/configs/rk3288_common.h | 4 ++++ 1 file changed, 4 insertions(+)Quoted 6 lines
Quoted 1 line
I think this should be done in
Kconfig.since rockusb used so widely on rockchip soc based devices. every rockchip soc based
device should support it. So I would like to put it inrk3288_common.hor evenrockchip-common.h.
what do you think?We are moving to removing the board config headers so cannot add new non-Kconfig CONFIG options.
Quoted 7 lines
Quoted 2 lines
You can add it to
arch/arm/Kconfig- e.g. with 'implyCONFIG_....' under 'configARCH_ROCKCHIP'.
USB_FUNCTION_ROCKUSBdepend onUSB_GADGET,USB_GADGET_DOWNLOAD,CONFIG_G_DNL_VENDOR_NUM,CONFIG_G_DNL_PRODUCT_NUMshould i move those config toarch/arm/Kconfig? how to defineCONFIG_G_DNL_VENDOR_NUM
andCONFIG_G_DNL_PRODUCT_NUMwhen select it?
I would prefer to keep those CONFIG options as they are now (and are in sync with other gadgets).
The problem here is that the gadget infrastructure is a bit "problematic" from the device model point of view.
It has his own "structure" borrowed from Linux kernel.
I've poked around and it seems like adding it to DM requires calling "g_dnl_register()" with embedded name of the gadget (like "usb_dnl_dfu").
And such call is required for each different gadget (like mass storage, dfu, fastboot).
Or maybe we should add "stub" DM support to only indicate supported gadgets (like dfu, ums, etc) and leave as much code untouched as possible?
Quoted 13 lines
Quoted 13 lines
Please help to remove any options you can from the headers.
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
(quoted diff) +0
-0
b/include/configs/rk3288_common.hindex b5606d4..b19a34d 100644include/configs/rk3288_common.h +0
-0@@ -74,6 +74,10 @@#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR#define CONFIG_FASTBOOT_BUF_SIZE 0x08000000
Quoted 12 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
include/configs/rk3288_common.h +4
-0+/* rockusb */ +#define CONFIG_CMD_ROCKUSB +#define CONFIG_USB_FUNCTION_ROCKUSB +Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
include/configs/rk3288_common.h +0
-1/* usb mass storage */ #define CONFIG_USB_FUNCTION_MASS_STORAGE #define CONFIG_CMD_USB_MASS_STORAGE --2.7.4
Regards,
Simon
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
PATCH 3/3 rockchip: rk3288: enable rockusb support on rk3288 based device
Hi,
Quoted 33 lines · Lukasz Majewski
Hi Eddie, Simon,
Quoted 31 lines
Hi Simon
2017-05-03 18:09 GMT+08:00 Simon Glass <[email protected]>:
Quoted 28 lines
Hi Eddie,
Quoted 13 lines · Eddie Cai
Hi Simon
2017-03-20 10:30 GMT+08:00 Simon Glass <[email protected]>:Quoted 11 lines
Hi Eddie.
Quoted 6 lines · Eddie Cai
this patch enable rockusb support on rk3288 based device.
Signed-off-by Eddie Cai <[email protected]>--- include/configs/rk3288_common.h | 4 ++++ 1 file changed, 4 insertions(+)Quoted 6 lines
Quoted 1 line
I think this should be done in
Kconfig.since rockusb used so widely on rockchip soc based devices. every rockchip soc based
device should support it. So I would like to put it inrk3288_common.hor evenrockchip-common.h.
what do you think?We are moving to removing the board config headers so cannot add new non-Kconfig CONFIG options.
You can add it to
arch/arm/Kconfig- e.g. with 'implyCONFIG_....' under 'configARCH_ROCKCHIP'.
Quoted 8 lines
Quoted 5 lines
USB_FUNCTION_ROCKUSBdepend onUSB_GADGET,USB_GADGET_DOWNLOAD,CONFIG_G_DNL_VENDOR_NUM,CONFIG_G_DNL_PRODUCT_NUMshould i move those config toarch/arm/Kconfig? how to defineCONFIG_G_DNL_VENDOR_NUM
andCONFIG_G_DNL_PRODUCT_NUMwhen select it?I would prefer to keep those CONFIG options as they are now (and are in sync with other gadgets).
These two are new though right?
CONFIG_CMD_ROCKUSBCONFIG_USB_FUNCTION_ROCKUSB
So they should be added to Kconfig. If they 'depend' on non-Kconfig options, that's fine IMO. We can't express that until the other options are converted.
Let's convert them soon!
Quoted 10 lines
The problem here is that the gadget infrastructure is a bit "problematic" from the device model point of view.
It has his own "structure" borrowed from Linux kernel.
I've poked around and it seems like adding it to DM requires calling "
g_dnl_register()" with embedded name of the gadget (like "usb_dnl_dfu").
Quoted 6 lines
And such call is required for each different gadget (like mass storage, dfu, fastboot).
Or maybe we should add "stub" DM support to only indicate supported gadgets (like dfu, ums, etc) and leave as much code untouched as possible?
I'm sure this can be resolved in some way. I admit I have not looked at it but was thinking of attacking usb_tty sometime, so perhaps might see if I can figure it out.
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Please help to remove any options you can from the headers.
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
(quoted diff) +0
-0
b/include/configs/rk3288_common.hindex b5606d4..b19a34d 100644include/configs/rk3288_common.h +0
-0@@ -74,6 +74,10 @@#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR#define CONFIG_FASTBOOT_BUF_SIZE 0x08000000
Quoted 12 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
include/configs/rk3288_common.h +4
-0+/* rockusb */ +#define CONFIG_CMD_ROCKUSB +#define CONFIG_USB_FUNCTION_ROCKUSB +Quoted 8 lines
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
include/configs/rk3288_common.h +0
-1/* usb mass storage */ #define CONFIG_USB_FUNCTION_MASS_STORAGE #define CONFIG_CMD_USB_MASS_STORAGE --2.7.4
Regards,
Simon
Regards,
Simon
PATCH 3/3 rockchip: rk3288: enable rockusb support on rk3288 based device
2017-05-05 0:49 GMT+08:00 Simon Glass <[email protected]>:
Quoted 47 lines
Hi,
Quoted 33 lines · Lukasz Majewski
Hi Eddie, Simon,
Quoted 31 lines
Hi Simon
2017-05-03 18:09 GMT+08:00 Simon Glass <[email protected]>:
Quoted 28 lines
Hi Eddie,
Quoted 13 lines · Eddie Cai
Hi Simon
2017-03-20 10:30 GMT+08:00 Simon Glass <[email protected]>:Quoted 11 lines
Hi Eddie.
Quoted 6 lines · Eddie Cai
this patch enable rockusb support on rk3288 based device.
Signed-off-by Eddie Cai <[email protected]>--- include/configs/rk3288_common.h | 4 ++++ 1 file changed, 4 insertions(+)Quoted 6 lines
Quoted 1 line
I think this should be done in
Kconfig.since rockusb used so widely on rockchip soc based devices. every rockchip soc based
device should support it. So I would like to put it inrk3288_common.hor evenrockchip-common.h.
what do you think?We are moving to removing the board config headers so cannot add new non-Kconfig CONFIG options.
You can add it to
arch/arm/Kconfig- e.g. with 'implyCONFIG_....' under 'configARCH_ROCKCHIP'.Quoted 8 lines
Quoted 5 lines
USB_FUNCTION_ROCKUSBdepend onUSB_GADGET,USB_GADGET_DOWNLOAD,CONFIG_G_DNL_VENDOR_NUM,CONFIG_G_DNL_PRODUCT_NUMshould i move those config toarch/arm/Kconfig? how to defineCONFIG_G_DNL_VENDOR_NUM
andCONFIG_G_DNL_PRODUCT_NUMwhen select it?I would prefer to keep those CONFIG options as they are now (and are in sync with other gadgets).
These two are new though right?
Quoted 8 lines
CONFIG_CMD_ROCKUSBCONFIG_USB_FUNCTION_ROCKUSBSo they should be added to
Kconfig. If they 'depend' on non-Kconfig options, that's fine IMO. We can't express that until the other options are converted.Let's convert them soon!
Does it means i can keep it in rk3288_common.h?
Quoted 51 lines
Quoted 11 lines
The problem here is that the gadget infrastructure is a bit "problematic" from the device model point of view.
It has his own "structure" borrowed from Linux kernel.
I've poked around and it seems like adding it to DM requires calling "
g_dnl_register()" with embedded name of the gadget (like "usb_dnl_dfu").Quoted 6 lines
And such call is required for each different gadget (like mass storage, dfu, fastboot).
Or maybe we should add "stub" DM support to only indicate supported gadgets (like dfu, ums, etc) and leave as much code untouched as possible?
I'm sure this can be resolved in some way. I admit I have not looked at it but was thinking of attacking
usb_ttysometime, so perhaps might see if I can figure it out.Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Please help to remove any options you can from the headers.
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
(quoted diff) +0
-0
b/include/configs/rk3288_common.hindex b5606d4..b19a34d 100644include/configs/rk3288_common.h +0
-0@@ -74,6 +74,10 @@#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR#define CONFIG_FASTBOOT_BUF_SIZE 0x08000000Quoted 12 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
include/configs/rk3288_common.h +4
-0+/* rockusb */ +#define CONFIG_CMD_ROCKUSB +#define CONFIG_USB_FUNCTION_ROCKUSB +Quoted 8 lines
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
include/configs/rk3288_common.h +0
-1/* usb mass storage */ #define CONFIG_USB_FUNCTION_MASS_STORAGE #define CONFIG_CMD_USB_MASS_STORAGE --2.7.4
Regards,
SimonRegards,
Simon
PATCH 3/3 rockchip: rk3288: enable rockusb support on rk3288 based device
Hi Eddie,
Quoted 51 lines · Eddie Cai
2017-05-05 0:49 GMT+08:00 Simon Glass <[email protected]>:
Quoted 50 lines
Hi,
Quoted 33 lines · Lukasz Majewski
Hi Eddie, Simon,
Quoted 31 lines
Hi Simon
2017-05-03 18:09 GMT+08:00 Simon Glass <[email protected]>:
Quoted 28 lines
Hi Eddie,
Quoted 13 lines · Eddie Cai
Hi Simon
2017-03-20 10:30 GMT+08:00 Simon Glass <[email protected]>:Quoted 11 lines
Hi Eddie.
Quoted 6 lines · Eddie Cai
this patch enable rockusb support on rk3288 based device.
Signed-off-by Eddie Cai <[email protected]>--- include/configs/rk3288_common.h | 4 ++++ 1 file changed, 4 insertions(+)Quoted 6 lines
Quoted 1 line
I think this should be done in
Kconfig.since rockusb used so widely on rockchip soc based devices. every rockchip soc based
device should support it. So I would like to put it inrk3288_common.hor evenrockchip-common.h.
what do you think?We are moving to removing the board config headers so cannot add new non-Kconfig CONFIG options.
You can add it to
arch/arm/Kconfig- e.g. with 'implyCONFIG_....' under 'configARCH_ROCKCHIP'.Quoted 8 lines
Quoted 5 lines
USB_FUNCTION_ROCKUSBdepend onUSB_GADGET,USB_GADGET_DOWNLOAD,CONFIG_G_DNL_VENDOR_NUM,CONFIG_G_DNL_PRODUCT_NUMshould i move those config toarch/arm/Kconfig? how to defineCONFIG_G_DNL_VENDOR_NUM
andCONFIG_G_DNL_PRODUCT_NUMwhen select it?I would prefer to keep those CONFIG options as they are now (and are in sync with other gadgets).
These two are new though right?
CONFIG_CMD_ROCKUSBCONFIG_USB_FUNCTION_ROCKUSB
Quoted 6 lines
Quoted 5 lines
So they should be added to
Kconfig. If they 'depend' on non-Kconfig options, that's fine IMO. We can't express that until the other options are converted.Let's convert them soon!
Does it means i can keep it in
rk3288_common.h?
Anything new you add must go into defconfig. If it depends on a non-Kconfig option, then just leave out the depend. We cannot add new things to the config whitelist, so you should get a build error if you try to add a new option outside Kconfig.
Quoted 49 lines
Quoted 49 lines
Quoted 11 lines
The problem here is that the gadget infrastructure is a bit "problematic" from the device model point of view.
It has his own "structure" borrowed from Linux kernel.
I've poked around and it seems like adding it to DM requires calling "
g_dnl_register()" with embedded name of the gadget (like "usb_dnl_dfu").Quoted 6 lines
And such call is required for each different gadget (like mass storage, dfu, fastboot).
Or maybe we should add "stub" DM support to only indicate supported gadgets (like dfu, ums, etc) and leave as much code untouched as possible?
I'm sure this can be resolved in some way. I admit I have not looked at it but was thinking of attacking
usb_ttysometime, so perhaps might see if I can figure it out.Quoted 26 lines
Quoted 26 lines
Quoted 26 lines
Please help to remove any options you can from the headers.
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
(quoted diff) +0
-0
b/include/configs/rk3288_common.hindex b5606d4..b19a34d 100644include/configs/rk3288_common.h +0
-0@@ -74,6 +74,10 @@#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR#define CONFIG_FASTBOOT_BUF_SIZE 0x08000000Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
include/configs/rk3288_common.h +4
-1+/* rockusb */ +#define CONFIG_CMD_ROCKUSB +#define CONFIG_USB_FUNCTION_ROCKUSB +/* usb mass storage */ #define CONFIG_USB_FUNCTION_MASS_STORAGE #define CONFIG_CMD_USB_MASS_STORAGE --2.7.4
Regards,
Simon
Quoted 2 lines
Quoted 2 lines
Regards,
Simon
Regards,
Simon
PATCH 3/3 rockchip: rk3288: enable rockusb support on rk3288 based device
Dear Simon, Eddie,
Quoted 8 lines
Quoted 3 lines
Quoted 2 lines
Let's convert them soon!
Does it means i can keep it in
rk3288_common.h?Anything new you add must go into defconfig. If it depends on a non-Kconfig option, then just leave out the depend. We cannot add new things to the config whitelist, so you should get a build error if you try to add a new option outside
Kconfig.
Ok. Then I will wait for next iteration....
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
PATCH 3/3 rockchip: rk3288: enable rockusb support on rk3288 based device
In reply to Eddie CaiHi Eddie,
Quoted 12 lines
this patch enable rockusb support on rk3288 based device.
Signed-off-by Eddie Cai <[email protected]>--- include/configs/rk3288_common.h | 4 ++++ 1 file changed, 4 insertions(+)(quoted diff) +0
-0
b/include/configs/rk3288_common.hindex b5606d4..b19a34d 100644
include/configs/rk3288_common.h line 83
Quoted 10 lines
include/configs/rk3288_common.h +4
-0@@ -74,6 +74,10 @@#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR#define CONFIG_FASTBOOT_BUF_SIZE 0x08000000 +/* rockusb */ +#define CONFIG_CMD_ROCKUSB +#define CONFIG_USB_FUNCTION_ROCKUSB +/* usb mass storage */ #define CONFIG_USB_FUNCTION_MASS_STORAGE #define CONFIG_CMD_USB_MASS_STORAGE
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
cover introduce Rockchip rockusb
In reply to Eddie CaiQuoted 3 lines · On Wed, 15 Mar 2017 15:56:02 +0800 Eddie Cai <[email protected]> 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.
Thank you for your patch. I will review it shortly.
If I might ask - is there any high-level documentation (pdf, webpage, etc) describing this protocol?
If yes, please add some very short entry to ./doc repository (e.g. ./doc/README.rockusb).
Quoted 11 lines
Eddie Cai (3):
drivers: usb: gadget: add the rockusb gadget
cmd: add rockusb command
rockchip: rk3288: enable rockusb support on rk3288 based devicecmd/Kconfig | 12 + cmd/Makefile | 1 + cmd/rockusb.c | 79 ++++ drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801
Quoted 7 lines
++++++++++++++++++++++++++++++++++++++++
include/configs/rk3288_common.h| 4 +include/rockusb.h| 13 + 7 files changed, 911
insertions(+) create mode 100644cmd/rockusb.ccreate mode 100644 drivers/usb/gadget/f_rockusb.c create mode 100644 include/rockusb.h
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
cover introduce Rockchip rockusb
Hi Lukasz
2017-03-15 17:06 GMT+08:00 Lukasz Majewski <[email protected]>:
Quoted 7 lines
Quoted 3 lines · On Wed, 15 Mar 2017 15:56:02 +0800 Eddie Cai <[email protected]> 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.
Quoted 8 lines
Thank you for your patch. I will review it shortly.
If I might ask - is there any high-level documentation (pdf, webpage, etc) describing this protocol?
If yes, please add some very short entry to ./doc repository (e.g. ./doc/README.rockusb).
Thanks for your quick reply. I will add README.rockusb in next version.
Quoted 31 lines
Quoted 12 lines
Eddie Cai (3):
drivers: usb: gadget: add the rockusb gadget
cmd: add rockusb command
rockchip: rk3288: enable rockusb support on rk3288 based devicecmd/Kconfig | 12 + cmd/Makefile | 1 + cmd/rockusb.c | 79 ++++ drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801Quoted 7 lines
++++++++++++++++++++++++++++++++++++++++
include/configs/rk3288_common.h| 4 +include/rockusb.h| 13 + 7 files changed, 911
insertions(+) create mode 100644cmd/rockusb.ccreate mode 100644 drivers/usb/gadget/f_rockusb.c create mode 100644 include/rockusb.hBest regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
cover introduce Rockchip rockusb
Quoted 13 lines · On Wed, 15 Mar 2017 17:31:27 +0800 Eddie Cai <[email protected]> wrote:
Hi Lukasz
2017-03-15 17:06 GMT+08:00 Lukasz Majewski <[email protected]>:
Quoted 9 lines
Quoted 3 lines · On Wed, 15 Mar 2017 15:56:02 +0800 Eddie Cai <[email protected]> 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.
Thank you for your patch. I will review it shortly.
Quoted 8 lines
Quoted 6 lines
If I might ask - is there any high-level documentation (pdf, webpage, etc) describing this protocol?
If yes, please add some very short entry to ./doc repository (e.g. ./doc/README.rockusb).
Thanks for your quick reply. I will add README.rockusb in next version.
Great :-)
As a reference, you can look to ./doc/README.dfutftp
Quoted 26 lines
Quoted 26 lines
Quoted 13 lines
Eddie Cai (3):
drivers: usb: gadget: add the rockusb gadget
cmd: add rockusb command
rockchip: rk3288: enable rockusb support on rk3288 based devicecmd/Kconfig | 12 + cmd/Makefile | 1 + cmd/rockusb.c | 79 ++++ drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801Quoted 7 lines
++++++++++++++++++++++++++++++++++++++++
include/configs/rk3288_common.h| 4 +include/rockusb.h| 13 + 7 files changed, 911
insertions(+) create mode 100644cmd/rockusb.ccreate mode 100644 drivers/usb/gadget/f_rockusb.c create mode 100644 include/rockusb.hBest regards,
Lukasz Majewski
Quoted 7 lines
Quoted 7 lines
--
DENX Software Engineering GmbH, Managing Director: Wolfgang
Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email:
wd at denx.de
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
cover introduce Rockchip rockusb
In reply to Eddie CaiQuoted 2 lines · Eddie Cai
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 is the benefit of this yet-another NIH protocol compared to ie. DFU/UMS/Thor/Fastboot ?
Quoted 17 lines
Eddie Cai (3):
drivers: usb: gadget: add the rockusb gadget
cmd: add rockusb command
rockchip: rk3288: enable rockusb support on rk3288 based devicecmd/Kconfig | 12 + cmd/Makefile | 1 + cmd/rockusb.c | 79 ++++ drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801 ++++++++++++++++++++++++++++++++++++++++ include/configs/rk3288_common.h | 4 + include/rockusb.h | 13 + 7 files changed, 911 insertions(+) create mode 100644 cmd/rockusb.c create mode 100644 drivers/usb/gadget/f_rockusb.c create mode 100644 include/rockusb.h
Signature · 2 lines
Best regards, Marek Vasut
cover introduce Rockchip rockusb
2017-03-17 5:26 GMT+08:00 Marek Vasut <[email protected]>:
Quoted 8 lines · Eddie Cai
Quoted 1 line
rockusb is a protocol run between host pc and device. it help people get
device
Quoted 1 line
info, flash image to device. this patch implement rockusb on device side.
What is the benefit of this yet-another NIH protocol compared to ie. DFU/UMS/Thor/Fastboot ?
This is mostly used on Rockchip chipset. All the rockchip SoC boot rom and develop tools implement this protocol.
So we want to use the same protocol which compatible with current tools.
Quoted 24 lines
Quoted 10 lines
Eddie Cai (3):
drivers: usb: gadget: add the rockusb gadget
cmd: add rockusb command
rockchip: rk3288: enable rockusb support on rk3288 based devicecmd/Kconfig | 12 + cmd/Makefile | 1 + cmd/rockusb.c | 79 ++++ drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801 ++++++++++++++++++++++++++++++++++++++++
Quoted 7 lines
include/configs/rk3288_common.h | 4 + include/rockusb.h | 13 + 7 files changed, 911 insertions(+) create mode 100644 cmd/rockusb.c create mode 100644 drivers/usb/gadget/f_rockusb.c create mode 100644 include/rockusb.h--
Best regards,
Marek Vasut
cover introduce Rockchip rockusb
Quoted 5 lines · Eddie Cai
2017-03-17 5:26 GMT+08:00 Marek Vasut <[email protected]>:
Quoted 3 lines · Eddie Cai
Quoted 1 line
rockusb is a protocol run between host pc and device. it help people get
device
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
info, flash image to device. this patch implement rockusb on device side.
What is the benefit of this yet-another NIH protocol compared to ie. DFU/UMS/Thor/Fastboot ?
This is mostly used on Rockchip chipset. All the rockchip SoC boot rom and develop tools implement this protocol.
So we want to use the same protocol which compatible with current tools.
This does not really answer my question. We have protocols which implement exactly this functionality already, why do we need another one ?
Signature · 2 lines
Best regards, Marek Vasut
cover introduce Rockchip rockusb
Hi Marek,
Quoted 11 lines · Marek Vasut
Quoted 10 lines · Eddie Cai
2017-03-17 5:26 GMT+08:00 Marek Vasut <[email protected]>:
Quoted 8 lines · Eddie Cai
Quoted 1 line
rockusb is a protocol run between host pc and device. it help people get
device
Quoted 1 line
info, flash image to device. this patch implement rockusb on device side.
What is the benefit of this yet-another NIH protocol compared to ie. DFU/UMS/Thor/Fastboot ?
Quoted 6 lines
Quoted 3 lines
This is mostly used on Rockchip chipset. All the rockchip SoC boot rom and develop tools implement this protocol.
So we want to use the same protocol which compatible with current tools.This does not really answer my question. We have protocols which implement exactly this functionality already, why do we need another one ?
I think the point is that this is widely used with Rockchip devices, and for mainline U-Boot to be fully useful it needs to support it.
However I do think it would be good to move to using DFU etc. if possible?
Regards,
Simon
cover introduce Rockchip rockusb
Quoted 18 lines · Simon Glass
Hi Marek,
Quoted 15 lines · Marek Vasut
Quoted 13 lines · Eddie Cai
2017-03-17 5:26 GMT+08:00 Marek Vasut <[email protected]>:
Quoted 8 lines · Eddie Cai
Quoted 1 line
rockusb is a protocol run between host pc and device. it help people get
device
Quoted 1 line
info, flash image to device. this patch implement rockusb on device side.
What is the benefit of this yet-another NIH protocol compared to ie. DFU/UMS/Thor/Fastboot ?
This is mostly used on Rockchip chipset. All the rockchip SoC boot rom and develop tools implement this protocol.
So we want to use the same protocol which compatible with current tools.
Quoted 5 lines
Quoted 2 lines
This does not really answer my question. We have protocols which implement exactly this functionality already, why do we need another one ?
I think the point is that this is widely used with Rockchip devices, and for mainline U-Boot to be fully useful it needs to support it.
OK, I'll leave that decision to Lukasz . I'm not a big fan of adding redundant functionality only because someone thought NIH is good before looking at standards.
Quoted 1 line
However I do think it would be good to move to using DFU etc. if possible?
Yes.
Signature · 2 lines
Best regards, Marek Vasut
cover introduce Rockchip rockusb
Hi Marek,
Quoted 17 lines · Marek Vasut
Quoted 16 lines · Simon Glass
Hi Marek,
Quoted 13 lines · Marek Vasut
Quoted 12 lines · Eddie Cai
2017-03-17 5:26 GMT+08:00 Marek Vasut <[email protected]>:
Quoted 7 lines · Eddie Cai
Quoted 1 line
rockusb is a protocol run between host pc and device. it help people get
device
Quoted 1 line
info, flash image to device. this patch implement rockusb on device side.
What is the benefit of this yet-another NIH protocol compared to ie. DFU/UMS/Thor/Fastboot ?
This is mostly used on Rockchip chipset. All the rockchip SoC boot rom and develop tools implement this protocol.
So we want to use the same protocol which compatible with current tools.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
This does not really answer my question. We have protocols which implement exactly this functionality already, why do we need another one ?
I think the point is that this is widely used with Rockchip devices, and for mainline U-Boot to be fully useful it needs to support it.
OK, I'll leave that decision to Lukasz . I'm not a big fan of adding redundant functionality only because someone thought NIH is good before looking at standards.
I don't know how you define "redundant functionality", from the gadget framework view,
yes, it's very similar to other storage based gadget, we may able to re-use the common part of the framework.
But it's definitely a different USB class driver which is used in Rockchip bootrom
and Rockchip loader, and some commands like RD(Reset device), DB(download boot)
are not able to use in ums or fastboot, but they are useful in Rockchip platform.
Thanks,
- Kever
Quoted 4 lines
Quoted 2 lines
However I do think it would be good to move to using DFU etc. if possible?
Yes.
cover introduce Rockchip rockusb
Quoted 28 lines · Kever Yang
Hi Marek,
Quoted 17 lines · Marek Vasut
Quoted 16 lines · Simon Glass
Hi Marek,
Quoted 13 lines · Marek Vasut
Quoted 12 lines · Eddie Cai
2017-03-17 5:26 GMT+08:00 Marek Vasut <[email protected]>:
Quoted 7 lines · Eddie Cai
Quoted 1 line
rockusb is a protocol run between host pc and device. it help people get
device
Quoted 1 line
info, flash image to device. this patch implement rockusb on device side.
What is the benefit of this yet-another NIH protocol compared to ie. DFU/UMS/Thor/Fastboot ?
This is mostly used on Rockchip chipset. All the rockchip SoC boot rom and develop tools implement this protocol.
So we want to use the same protocol which compatible with current tools.Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
This does not really answer my question. We have protocols which implement exactly this functionality already, why do we need another one ?
I think the point is that this is widely used with Rockchip devices, and for mainline U-Boot to be fully useful it needs to support it.
OK, I'll leave that decision to Lukasz . I'm not a big fan of adding redundant functionality only because someone thought NIH is good before looking at standards.
Quoted 10 lines
I don't know how you define "redundant functionality", from the gadget framework view,
yes, it's very similar to other storage based gadget, we may able to re-use the common part of the framework.
But it's definitely a different USB class driver which is used in Rockchip bootrom
and Rockchip loader, and some commands like RD(Reset device), DB(download boot)
are not able to use in ums or fastboot, but they are useful in Rockchip platform.
So here's my two cents. At the back end side of things, DFU, fastboot, UMS, Thor, rockusb and whatever comes down the pipe next should all be able to share a good bit of back end code, in a common way (and maybe we can even address DFU using the CLI rather than API to do things) as it all boils down to "take data via USB, write to defined location" or "do something then reset the board" and so on. And by that same token, while I wish more vendors used the same protocols, we need to support the world that exists, not the world we wish we had.
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170321/16ddc6b8/attachment.sig>
cover introduce Rockchip rockusb
In reply to Eddie CaiHI Eddie,
Quoted 3 lines
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.
I'm a bit confused, since I don't know if you work on v2 of those patches (as Kever Yang pointed out that UMS approach could be re-used here)?
(And just gentle reminder of the README.xxx file to describe this protocol).
Quoted 11 lines
Eddie Cai (3):
drivers: usb: gadget: add the rockusb gadget
cmd: add rockusb command
rockchip: rk3288: enable rockusb support on rk3288 based devicecmd/Kconfig | 12 + cmd/Makefile | 1 + cmd/rockusb.c | 79 ++++ drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801
Quoted 7 lines
++++++++++++++++++++++++++++++++++++++++
include/configs/rk3288_common.h| 4 +include/rockusb.h| 13 + 7 files changed, 911
insertions(+) create mode 100644cmd/rockusb.ccreate mode 100644 drivers/usb/gadget/f_rockusb.c create mode 100644 include/rockusb.h
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
cover introduce Rockchip rockusb
Hi Lukasz
2017-03-27 16:27 GMT+08:00 Lukasz Majewski <[email protected]>:
Quoted 6 lines
HI Eddie,
Quoted 3 lines
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.
Quoted 7 lines
I'm a bit confused, since I don't know if you work on v2 of those patches (as Kever Yang pointed out that UMS approach could be re-used here)?
(And just gentle reminder of the README.xxx file to describe this protocol).
I am working on V2 patch. It will reused ums function as more as possible. I won't forget README.rockusb
Quoted 31 lines
Quoted 12 lines
Eddie Cai (3):
drivers: usb: gadget: add the rockusb gadget
cmd: add rockusb command
rockchip: rk3288: enable rockusb support on rk3288 based devicecmd/Kconfig | 12 + cmd/Makefile | 1 + cmd/rockusb.c | 79 ++++ drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_rockusb.c | 801Quoted 7 lines
++++++++++++++++++++++++++++++++++++++++
include/configs/rk3288_common.h| 4 +include/rockusb.h| 13 + 7 files changed, 911
insertions(+) create mode 100644cmd/rockusb.ccreate mode 100644 drivers/usb/gadget/f_rockusb.c create mode 100644 include/rockusb.hBest regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de