[U-Boot] [PATCH v1 2/7] usb: gadget: add SDP driver

2017-08-04 Thread Stefan Agner
From: Stefan Agner 

Add SDP (Serial Downloader Protocol) implementation for U-Boot. The
protocol is used in NXP SoC's boot ROM and allows to download program
images. Beside that, it can also be used to read/write registers and
download complete Device Configuration Data (DCD) sets. This basic
implementation supports downloading images with the imx header format
and reading registers.

Signed-off-by: Stefan Agner 
---

 drivers/usb/gadget/Kconfig  |   7 +
 drivers/usb/gadget/Makefile |   1 +
 drivers/usb/gadget/f_sdp.c  | 723 
 include/sdp.h   |  16 +
 4 files changed, 747 insertions(+)
 create mode 100644 drivers/usb/gadget/f_sdp.c
 create mode 100644 include/sdp.h

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 261ed128ac..225b66bc95 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -103,6 +103,13 @@ config USB_GADGET_DOWNLOAD
 
 if USB_GADGET_DOWNLOAD
 
+config USB_FUNCTION_SDP
+   bool "Enable USB SDP (Serial Download Protocol)"
+   help
+ Enable Serial Download Protocol (SDP) device support in U-Boot. This
+ allows to download images into memory and execute (jump to) them
+ using the same protocol as implemented by the i.MX family's boot ROM.
+
 config G_DNL_MANUFACTURER
string "Vendor name of USB device"
 
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 5e316a7cff..6a007d1bcb 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -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_SDP) += f_sdp.o
 endif
 endif
 ifdef CONFIG_USB_ETHER
diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c
new file mode 100644
index 00..eb89695aaf
--- /dev/null
+++ b/drivers/usb/gadget/f_sdp.c
@@ -0,0 +1,723 @@
+/*
+ * f_sdp.c -- USB HID Serial Download Protocol
+ *
+ * Copyright (C) 2016 Toradex
+ * Author: Stefan Agner 
+ *
+ * This file implements the Serial Download Protocol (SDP) as specified in
+ * the i.MX 6 Reference Manual. The SDP is a USB HID based protocol and
+ * allows to download images directly to memory. The implementation
+ * works with the imx_loader (imx_usb) USB client software on host side.
+ *
+ * Not all commands are implemented, e.g. WRITE_REGISTER, DCD_WRITE and
+ * SKIP_DCD_HEADER are only stubs.
+ *
+ * Parts of the implementation are based on f_dfu and f_thor.
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define HID_REPORT_ID_MASK 0x00ff
+
+/*
+ * HID class requests
+ */
+#define HID_REQ_GET_REPORT 0x01
+#define HID_REQ_GET_IDLE   0x02
+#define HID_REQ_GET_PROTOCOL   0x03
+#define HID_REQ_SET_REPORT 0x09
+#define HID_REQ_SET_IDLE   0x0A
+#define HID_REQ_SET_PROTOCOL   0x0B
+
+#define HID_USAGE_PAGE_LEN 76
+
+struct hid_report {
+   u8 usage_page[HID_USAGE_PAGE_LEN];
+} __packed;
+
+#define SDP_READ_REGISTER  0x0101
+#define SDP_WRITE_REGISTER 0x0202
+#define SDP_WRITE_FILE 0x0404
+#define SDP_ERROR_STATUS   0x0505
+#define SDP_DCD_WRITE  0x0a0a
+#define SDP_JUMP_ADDRESS   0x0b0b
+#define SDP_SKIP_DCD_HEADER0x0c0c
+
+#define SDP_WRITE_FILE_COMPLETE0x
+#define SDP_WRITE_REGISTER_COMPLETE0x128A8A12
+#define SDP_SKIP_DCD_HEADER_COMPLETE   0x900DD009
+#define SDP_ERROR_IMXHEADER0x000a0533
+
+#define SDP_COMMAND_LEN16
+
+struct sdp_command {
+   u16 cmd;
+   u32 addr;
+   u8 format;
+   u32 cnt;
+   u32 data;
+   u8 rsvd;
+} __packed;
+
+enum sdp_state {
+   SDP_STATE_IDLE,
+   SDP_STATE_RX_DCD_DATA,
+   SDP_STATE_RX_FILE_DATA,
+   SDP_STATE_TX_SEC_CONF,
+   SDP_STATE_TX_SEC_CONF_BUSY,
+   SDP_STATE_TX_REGISTER,
+   SDP_STATE_TX_REGISTER_BUSY,
+   SDP_STATE_TX_STATUS,
+   SDP_STATE_TX_STATUS_BUSY,
+   SDP_STATE_JUMP,
+};
+
+struct f_sdp {
+   struct usb_function usb_function;
+
+   struct usb_descriptor_header**function;
+
+   u8  altsetting;
+   enum sdp_state  state;
+   enum sdp_state  next_state;
+   u32 dnl_address;
+   u32 dnl_bytes_remaining;
+   u32 jmp_address;
+   boolalways_send_status;
+   u32 error_status;
+
+   /* EP0 request */
+   struct usb_request  *req;
+
+   /* EP1 IN */
+   struct usb_ep   *in_ep;
+

Re: [U-Boot] [PATCH v1 2/7] usb: gadget: add SDP driver

2017-08-08 Thread Lothar Waßmann
Hi,

On Fri,  4 Aug 2017 16:38:08 -0700 Stefan Agner wrote:
> From: Stefan Agner 
> 
> Add SDP (Serial Downloader Protocol) implementation for U-Boot. The
> protocol is used in NXP SoC's boot ROM and allows to download program
> images. Beside that, it can also be used to read/write registers and
> download complete Device Configuration Data (DCD) sets. This basic
> implementation supports downloading images with the imx header format
> and reading registers.
> 
> Signed-off-by: Stefan Agner 
> ---
> 
>  drivers/usb/gadget/Kconfig  |   7 +
>  drivers/usb/gadget/Makefile |   1 +
>  drivers/usb/gadget/f_sdp.c  | 723 
> 
>  include/sdp.h   |  16 +
>  4 files changed, 747 insertions(+)
>  create mode 100644 drivers/usb/gadget/f_sdp.c
>  create mode 100644 include/sdp.h
> 
> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
> index 261ed128ac..225b66bc95 100644
> --- a/drivers/usb/gadget/Kconfig
> +++ b/drivers/usb/gadget/Kconfig
> @@ -103,6 +103,13 @@ config USB_GADGET_DOWNLOAD
>  
>  if USB_GADGET_DOWNLOAD
>  
> +config USB_FUNCTION_SDP
> + bool "Enable USB SDP (Serial Download Protocol)"
> + help
> +   Enable Serial Download Protocol (SDP) device support in U-Boot. This
> +   allows to download images into memory and execute (jump to) them
> +   using the same protocol as implemented by the i.MX family's boot ROM.
> +
>  config G_DNL_MANUFACTURER
>   string "Vendor name of USB device"
>  
> diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
> index 5e316a7cff..6a007d1bcb 100644
> --- a/drivers/usb/gadget/Makefile
> +++ b/drivers/usb/gadget/Makefile
> @@ -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_SDP) += f_sdp.o
>  endif
>  endif
>  ifdef CONFIG_USB_ETHER
> diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c
> new file mode 100644
> index 00..eb89695aaf
> --- /dev/null
> +++ b/drivers/usb/gadget/f_sdp.c
> @@ -0,0 +1,723 @@
> +/*
> + * f_sdp.c -- USB HID Serial Download Protocol
> + *
> + * Copyright (C) 2016 Toradex
> + * Author: Stefan Agner 
> + *
> + * This file implements the Serial Download Protocol (SDP) as specified in
> + * the i.MX 6 Reference Manual. The SDP is a USB HID based protocol and
> + * allows to download images directly to memory. The implementation
> + * works with the imx_loader (imx_usb) USB client software on host side.
> + *
> + * Not all commands are implemented, e.g. WRITE_REGISTER, DCD_WRITE and
> + * SKIP_DCD_HEADER are only stubs.
> + *
> + * Parts of the implementation are based on f_dfu and f_thor.
> + *
> + * SPDX-License-Identifier:  GPL-2.0+
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define HID_REPORT_ID_MASK   0x00ff
> +
> +/*
> + * HID class requests
> + */
> +#define HID_REQ_GET_REPORT   0x01
> +#define HID_REQ_GET_IDLE 0x02
> +#define HID_REQ_GET_PROTOCOL 0x03
> +#define HID_REQ_SET_REPORT   0x09
> +#define HID_REQ_SET_IDLE 0x0A
> +#define HID_REQ_SET_PROTOCOL 0x0B
> +
> +#define HID_USAGE_PAGE_LEN   76
> +
> +struct hid_report {
> + u8 usage_page[HID_USAGE_PAGE_LEN];
> +} __packed;
> +
> +#define SDP_READ_REGISTER0x0101
> +#define SDP_WRITE_REGISTER   0x0202
> +#define SDP_WRITE_FILE   0x0404
> +#define SDP_ERROR_STATUS 0x0505
> +#define SDP_DCD_WRITE0x0a0a
> +#define SDP_JUMP_ADDRESS 0x0b0b
> +#define SDP_SKIP_DCD_HEADER  0x0c0c
> +
> +#define SDP_WRITE_FILE_COMPLETE  0x
> +#define SDP_WRITE_REGISTER_COMPLETE  0x128A8A12
> +#define SDP_SKIP_DCD_HEADER_COMPLETE 0x900DD009
> +#define SDP_ERROR_IMXHEADER  0x000a0533
> +
> +#define SDP_COMMAND_LEN  16
> +
> +struct sdp_command {
> + u16 cmd;
> + u32 addr;
> + u8 format;
> + u32 cnt;
> + u32 data;
> + u8 rsvd;
> +} __packed;
> +
> +enum sdp_state {
> + SDP_STATE_IDLE,
> + SDP_STATE_RX_DCD_DATA,
> + SDP_STATE_RX_FILE_DATA,
> + SDP_STATE_TX_SEC_CONF,
> + SDP_STATE_TX_SEC_CONF_BUSY,
> + SDP_STATE_TX_REGISTER,
> + SDP_STATE_TX_REGISTER_BUSY,
> + SDP_STATE_TX_STATUS,
> + SDP_STATE_TX_STATUS_BUSY,
> + SDP_STATE_JUMP,
> +};
> +
> +struct f_sdp {
> + struct usb_function usb_function;
> +
> + struct usb_descriptor_header**function;
> +
> + u8  altsetting;
> + enum sdp_state  state;
> + enum sdp_state  next_state;
> + u32 dnl_address;
> + u32 dnl_bytes_remaining;
> + u32 

Re: [U-Boot] [PATCH v1 2/7] usb: gadget: add SDP driver

2017-08-08 Thread Łukasz Majewski

Hi Stefan,


From: Stefan Agner 

Add SDP (Serial Downloader Protocol) implementation for U-Boot. The
protocol is used in NXP SoC's boot ROM and allows to download program
images. Beside that, it can also be used to read/write registers and
download complete Device Configuration Data (DCD) sets. This basic
implementation supports downloading images with the imx header format
and reading registers.

Signed-off-by: Stefan Agner 


Just some minor comments (despite comments from Lothar).


---

 drivers/usb/gadget/Kconfig  |   7 +
 drivers/usb/gadget/Makefile |   1 +
 drivers/usb/gadget/f_sdp.c  | 723 
 include/sdp.h   |  16 +
 4 files changed, 747 insertions(+)
 create mode 100644 drivers/usb/gadget/f_sdp.c
 create mode 100644 include/sdp.h

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 261ed128ac..225b66bc95 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -103,6 +103,13 @@ config USB_GADGET_DOWNLOAD

 if USB_GADGET_DOWNLOAD

+config USB_FUNCTION_SDP
+   bool "Enable USB SDP (Serial Download Protocol)"
+   help
+ Enable Serial Download Protocol (SDP) device support in U-Boot. This
+ allows to download images into memory and execute (jump to) them
+ using the same protocol as implemented by the i.MX family's boot ROM.
+
 config G_DNL_MANUFACTURER
string "Vendor name of USB device"

diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 5e316a7cff..6a007d1bcb 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -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_SDP) += f_sdp.o
 endif
 endif
 ifdef CONFIG_USB_ETHER
diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c
new file mode 100644
index 00..eb89695aaf
--- /dev/null
+++ b/drivers/usb/gadget/f_sdp.c
@@ -0,0 +1,723 @@
+/*
+ * f_sdp.c -- USB HID Serial Download Protocol
+ *
+ * Copyright (C) 2016 Toradex
		 - minor -> If you are going to prepare v2, please update the 
date.



+ * Author: Stefan Agner 
+ *
+ * This file implements the Serial Download Protocol (SDP) as specified in
+ * the i.MX 6 Reference Manual. The SDP is a USB HID based protocol and
+ * allows to download images directly to memory. The implementation
+ * works with the imx_loader (imx_usb) USB client software on host side.
+ *
+ * Not all commands are implemented, e.g. WRITE_REGISTER, DCD_WRITE and
+ * SKIP_DCD_HEADER are only stubs.
+ *
+ * Parts of the implementation are based on f_dfu and f_thor.
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define HID_REPORT_ID_MASK 0x00ff
+
+/*
+ * HID class requests
+ */
+#define HID_REQ_GET_REPORT 0x01
+#define HID_REQ_GET_IDLE   0x02
+#define HID_REQ_GET_PROTOCOL   0x03
+#define HID_REQ_SET_REPORT 0x09
+#define HID_REQ_SET_IDLE   0x0A
+#define HID_REQ_SET_PROTOCOL   0x0B
+
+#define HID_USAGE_PAGE_LEN 76
+
+struct hid_report {
+   u8 usage_page[HID_USAGE_PAGE_LEN];
+} __packed;
+
+#define SDP_READ_REGISTER  0x0101
+#define SDP_WRITE_REGISTER 0x0202
+#define SDP_WRITE_FILE 0x0404
+#define SDP_ERROR_STATUS   0x0505
+#define SDP_DCD_WRITE  0x0a0a
+#define SDP_JUMP_ADDRESS   0x0b0b
+#define SDP_SKIP_DCD_HEADER0x0c0c
+
+#define SDP_WRITE_FILE_COMPLETE0x
+#define SDP_WRITE_REGISTER_COMPLETE0x128A8A12
+#define SDP_SKIP_DCD_HEADER_COMPLETE   0x900DD009
+#define SDP_ERROR_IMXHEADER0x000a0533
+
+#define SDP_COMMAND_LEN16
+
+struct sdp_command {
+   u16 cmd;
+   u32 addr;
+   u8 format;
+   u32 cnt;
+   u32 data;
+   u8 rsvd;
+} __packed;
+
+enum sdp_state {
+   SDP_STATE_IDLE,
+   SDP_STATE_RX_DCD_DATA,
+   SDP_STATE_RX_FILE_DATA,
+   SDP_STATE_TX_SEC_CONF,
+   SDP_STATE_TX_SEC_CONF_BUSY,
+   SDP_STATE_TX_REGISTER,
+   SDP_STATE_TX_REGISTER_BUSY,
+   SDP_STATE_TX_STATUS,
+   SDP_STATE_TX_STATUS_BUSY,
+   SDP_STATE_JUMP,
+};
+
+struct f_sdp {
+   struct usb_function usb_function;
+
+   struct usb_descriptor_header**function;
+
+   u8  altsetting;
+   enum sdp_state  state;
+   enum sdp_state  next_state;
+   u32 dnl_address;
+   u32 dnl_bytes_remaining;
+   u32 jmp_address;
+   boolalways_send_status;
+   u32 error_stat

Re: [U-Boot] [PATCH v1 2/7] usb: gadget: add SDP driver

2017-08-10 Thread Stefano Babic
Hi Stefan,

On 05/08/2017 01:38, Stefan Agner wrote:
> From: Stefan Agner 
> 
> Add SDP (Serial Downloader Protocol) implementation for U-Boot. The
> protocol is used in NXP SoC's boot ROM and allows to download program
> images. Beside that, it can also be used to read/write registers and
> download complete Device Configuration Data (DCD) sets. This basic
> implementation supports downloading images with the imx header format
> and reading registers.
> 
> Signed-off-by: Stefan Agner 
> ---
> 
>  drivers/usb/gadget/Kconfig  |   7 +
>  drivers/usb/gadget/Makefile |   1 +
>  drivers/usb/gadget/f_sdp.c  | 723 
> 
>  include/sdp.h   |  16 +
>  4 files changed, 747 insertions(+)
>  create mode 100644 drivers/usb/gadget/f_sdp.c
>  create mode 100644 include/sdp.h
> 
> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
> index 261ed128ac..225b66bc95 100644
> --- a/drivers/usb/gadget/Kconfig
> +++ b/drivers/usb/gadget/Kconfig
> @@ -103,6 +103,13 @@ config USB_GADGET_DOWNLOAD
>  
>  if USB_GADGET_DOWNLOAD
>  
> +config USB_FUNCTION_SDP
> + bool "Enable USB SDP (Serial Download Protocol)"
> + help
> +   Enable Serial Download Protocol (SDP) device support in U-Boot. This
> +   allows to download images into memory and execute (jump to) them
> +   using the same protocol as implemented by the i.MX family's boot ROM.
> +
>  config G_DNL_MANUFACTURER
>   string "Vendor name of USB device"
>  
> diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
> index 5e316a7cff..6a007d1bcb 100644
> --- a/drivers/usb/gadget/Makefile
> +++ b/drivers/usb/gadget/Makefile
> @@ -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_SDP) += f_sdp.o
>  endif
>  endif
>  ifdef CONFIG_USB_ETHER
> diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c
> new file mode 100644
> index 00..eb89695aaf
> --- /dev/null
> +++ b/drivers/usb/gadget/f_sdp.c
> @@ -0,0 +1,723 @@
> +/*
> + * f_sdp.c -- USB HID Serial Download Protocol
> + *
> + * Copyright (C) 2016 Toradex
> + * Author: Stefan Agner 
> + *
> + * This file implements the Serial Download Protocol (SDP) as specified in
> + * the i.MX 6 Reference Manual. The SDP is a USB HID based protocol and
> + * allows to download images directly to memory. The implementation
> + * works with the imx_loader (imx_usb) USB client software on host side.
> + *
> + * Not all commands are implemented, e.g. WRITE_REGISTER, DCD_WRITE and
> + * SKIP_DCD_HEADER are only stubs.
> + *
> + * Parts of the implementation are based on f_dfu and f_thor.
> + *
> + * SPDX-License-Identifier:  GPL-2.0+
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define HID_REPORT_ID_MASK   0x00ff
> +
> +/*
> + * HID class requests
> + */
> +#define HID_REQ_GET_REPORT   0x01
> +#define HID_REQ_GET_IDLE 0x02
> +#define HID_REQ_GET_PROTOCOL 0x03
> +#define HID_REQ_SET_REPORT   0x09
> +#define HID_REQ_SET_IDLE 0x0A
> +#define HID_REQ_SET_PROTOCOL 0x0B
> +
> +#define HID_USAGE_PAGE_LEN   76
> +
> +struct hid_report {
> + u8 usage_page[HID_USAGE_PAGE_LEN];
> +} __packed;
> +
> +#define SDP_READ_REGISTER0x0101
> +#define SDP_WRITE_REGISTER   0x0202
> +#define SDP_WRITE_FILE   0x0404
> +#define SDP_ERROR_STATUS 0x0505
> +#define SDP_DCD_WRITE0x0a0a
> +#define SDP_JUMP_ADDRESS 0x0b0b
> +#define SDP_SKIP_DCD_HEADER  0x0c0c

It looks like that I am again out of sync with documentation. Where is
defined SDP_SKIP_DCD_HEADER ? It is undefined for MX6Q/D, Solo and DL.

> +
> +#define SDP_WRITE_FILE_COMPLETE  0x
> +#define SDP_WRITE_REGISTER_COMPLETE  0x128A8A12
> +#define SDP_SKIP_DCD_HEADER_COMPLETE 0x900DD009
> +#define SDP_ERROR_IMXHEADER  0x000a0533
> +
> +#define SDP_COMMAND_LEN  16
> +
> +struct sdp_command {
> + u16 cmd;
> + u32 addr;
> + u8 format;
> + u32 cnt;
> + u32 data;
> + u8 rsvd;
> +} __packed;
> +
> +enum sdp_state {
> + SDP_STATE_IDLE,
> + SDP_STATE_RX_DCD_DATA,
> + SDP_STATE_RX_FILE_DATA,
> + SDP_STATE_TX_SEC_CONF,
> + SDP_STATE_TX_SEC_CONF_BUSY,
> + SDP_STATE_TX_REGISTER,
> + SDP_STATE_TX_REGISTER_BUSY,
> + SDP_STATE_TX_STATUS,
> + SDP_STATE_TX_STATUS_BUSY,
> + SDP_STATE_JUMP,
> +};
> +
> +struct f_sdp {
> + struct usb_function usb_function;
> +
> + struct usb_descriptor_header**function;
> +
> + u8  altsetting;
> + enum sdp_state  state;
> + enum sdp_state  next_state;
> + u

Re: [U-Boot] [PATCH v1 2/7] usb: gadget: add SDP driver

2017-08-15 Thread Stefan Agner
On 2017-08-10 01:14, Stefano Babic wrote:
> Hi Stefan,
> 
> On 05/08/2017 01:38, Stefan Agner wrote:
>> From: Stefan Agner 
>>
>> Add SDP (Serial Downloader Protocol) implementation for U-Boot. The
>> protocol is used in NXP SoC's boot ROM and allows to download program
>> images. Beside that, it can also be used to read/write registers and
>> download complete Device Configuration Data (DCD) sets. This basic
>> implementation supports downloading images with the imx header format
>> and reading registers.
>>
>> Signed-off-by: Stefan Agner 
>> ---
>>
>>  drivers/usb/gadget/Kconfig  |   7 +
>>  drivers/usb/gadget/Makefile |   1 +
>>  drivers/usb/gadget/f_sdp.c  | 723 
>> 
>>  include/sdp.h   |  16 +
>>  4 files changed, 747 insertions(+)
>>  create mode 100644 drivers/usb/gadget/f_sdp.c
>>  create mode 100644 include/sdp.h
>>
>> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
>> index 261ed128ac..225b66bc95 100644
>> --- a/drivers/usb/gadget/Kconfig
>> +++ b/drivers/usb/gadget/Kconfig
>> @@ -103,6 +103,13 @@ config USB_GADGET_DOWNLOAD
>>
>>  if USB_GADGET_DOWNLOAD
>>
>> +config USB_FUNCTION_SDP
>> +bool "Enable USB SDP (Serial Download Protocol)"
>> +help
>> +  Enable Serial Download Protocol (SDP) device support in U-Boot. This
>> +  allows to download images into memory and execute (jump to) them
>> +  using the same protocol as implemented by the i.MX family's boot ROM.
>> +
>>  config G_DNL_MANUFACTURER
>>  string "Vendor name of USB device"
>>
>> diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
>> index 5e316a7cff..6a007d1bcb 100644
>> --- a/drivers/usb/gadget/Makefile
>> +++ b/drivers/usb/gadget/Makefile
>> @@ -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_SDP) += f_sdp.o
>>  endif
>>  endif
>>  ifdef CONFIG_USB_ETHER
>> diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c
>> new file mode 100644
>> index 00..eb89695aaf
>> --- /dev/null
>> +++ b/drivers/usb/gadget/f_sdp.c
>> @@ -0,0 +1,723 @@
>> +/*
>> + * f_sdp.c -- USB HID Serial Download Protocol
>> + *
>> + * Copyright (C) 2016 Toradex
>> + * Author: Stefan Agner 
>> + *
>> + * This file implements the Serial Download Protocol (SDP) as specified in
>> + * the i.MX 6 Reference Manual. The SDP is a USB HID based protocol and
>> + * allows to download images directly to memory. The implementation
>> + * works with the imx_loader (imx_usb) USB client software on host side.
>> + *
>> + * Not all commands are implemented, e.g. WRITE_REGISTER, DCD_WRITE and
>> + * SKIP_DCD_HEADER are only stubs.
>> + *
>> + * Parts of the implementation are based on f_dfu and f_thor.
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define HID_REPORT_ID_MASK  0x00ff
>> +
>> +/*
>> + * HID class requests
>> + */
>> +#define HID_REQ_GET_REPORT  0x01
>> +#define HID_REQ_GET_IDLE0x02
>> +#define HID_REQ_GET_PROTOCOL0x03
>> +#define HID_REQ_SET_REPORT  0x09
>> +#define HID_REQ_SET_IDLE0x0A
>> +#define HID_REQ_SET_PROTOCOL0x0B
>> +
>> +#define HID_USAGE_PAGE_LEN  76
>> +
>> +struct hid_report {
>> +u8 usage_page[HID_USAGE_PAGE_LEN];
>> +} __packed;
>> +
>> +#define SDP_READ_REGISTER   0x0101
>> +#define SDP_WRITE_REGISTER  0x0202
>> +#define SDP_WRITE_FILE  0x0404
>> +#define SDP_ERROR_STATUS0x0505
>> +#define SDP_DCD_WRITE   0x0a0a
>> +#define SDP_JUMP_ADDRESS0x0b0b
>> +#define SDP_SKIP_DCD_HEADER 0x0c0c
> 
> It looks like that I am again out of sync with documentation. Where is
> defined SDP_SKIP_DCD_HEADER ? It is undefined for MX6Q/D, Solo and DL.
> 

This is only available in newer SoC's e.g. i.MX 7.

It allows to skip the DCD header in a downloaded image. Since the DCD
header is anyway ignored by this SDP implementation, the command is kind
of useless. I still think it is a good idea to have the command type
define for completeness... And I think also some SDP host side
implementation might issue the command...

>> +
>> +#define SDP_WRITE_FILE_COMPLETE 0x
>> +#define SDP_WRITE_REGISTER_COMPLETE 0x128A8A12
>> +#define SDP_SKIP_DCD_HEADER_COMPLETE0x900DD009
>> +#define SDP_ERROR_IMXHEADER 0x000a0533
>> +
>> +#define SDP_COMMAND_LEN 16
>> +
>> +struct sdp_command {
>> +u16 cmd;
>> +u32 addr;
>> +u8 format;
>> +u32 cnt;
>> +u32 data;
>> +u8 rsvd;
>> +} __packed;
>> +
>> +enum sdp_state {
>> +SDP_STATE_IDLE,
>> +SDP_STATE_RX_DCD_DATA,
>> +SDP_STA

Re: [U-Boot] [PATCH v1 2/7] usb: gadget: add SDP driver

2017-08-16 Thread Stefano Babic
Hi Stefan,

On 15/08/2017 23:54, Stefan Agner wrote:
>>
>> It looks like that I am again out of sync with documentation. Where is
>> defined SDP_SKIP_DCD_HEADER ? It is undefined for MX6Q/D, Solo and DL.
>>
> 
> This is only available in newer SoC's e.g. i.MX 7.

ok

> 
> It allows to skip the DCD header in a downloaded image. Since the DCD
> header is anyway ignored by this SDP implementation, the command is kind
> of useless. I still think it is a good idea to have the command type
> define for completeness... 

I agree with you - I just wanted to understand.

>And I think also some SDP host side
> implementation might issue the command...

That's ok, thanks for clarification.

>>
>> It is fine, but I am just missing if this is a use case. DCD is
>> interpreted by boot ROM, and we are here already over in SPL.
>>
> 
> I also don't have a use case currently, but it is rather cheap so why
> don't?

Yes, that's fine.

> 
> Note that the SDP_READ_REGISTER command is actually used by the
> sb_loader to do some verification whether the image got correctly
> downloaded... But I don't think it required DCD_WRITE for something, but
> I would have to retest.
> 
>>> +   case SDP_JUMP_ADDRESS:
>>> +   sdp->always_send_status = false;
>>> +   sdp->error_status = 0;
>>> +
>>> +   sdp->jmp_address = be32_to_cpu(cmd->addr);
>>> +   sdp->state = SDP_STATE_TX_SEC_CONF;
>>> +   sdp->next_state = SDP_STATE_JUMP;
>>> +   break;
>>> +   case SDP_SKIP_DCD_HEADER:
>>> +   sdp->always_send_status = true;
>>> +   sdp->error_status = SDP_SKIP_DCD_HEADER_COMPLETE;
>>> +
>>> +   /* Ignore command, DCD not supported anyway */
>>
>> Right - we load a file, we do not need a DCD.
>>
>>> +   sdp->state = SDP_STATE_TX_SEC_CONF;
>>> +   sdp->next_state = SDP_STATE_IDLE;
>>> +   break;
>>> +   default:
>>> +   error("Unknown command: %08x\n", be16_to_cpu(cmd->cmd));
>>> +   }
>>> +}
>>> +
>>> +static void sdp_rx_data_complete(struct usb_ep *ep, struct usb_request 
>>> *req)
>>> +{
>>> +   struct f_sdp *sdp = req->context;
>>> +   int status = req->status;
>>> +   u8 *data = req->buf;
>>> +   u8 report = data[0];
>>> +   int datalen = req->length - 1;
>>> +
>>> +   if (status != 0) {
>>> +   error("Status: %d", status);
>>> +   return;
>>> +   }
>>> +
>>> +   if (report != 2) {
>>> +   error("Unexpected report %d", report);
>>> +   return;
>>> +   }
>>> +
>>> +   if (sdp->dnl_bytes_remaining < datalen) {
>>> +   /*
>>> +* Some USB stacks require to send a complete buffer as
>>> +* specified in the HID descriptor. This leads to longer
>>> +* transfers than the file length, no problem for us.
>>> +*/
>>> +   sdp->dnl_bytes_remaining = 0;
>>> +   } else {
>>> +   sdp->dnl_bytes_remaining -= datalen;
>>> +   }
>>> +
>>> +   if (sdp->state == SDP_STATE_RX_FILE_DATA) {
>>> +   memcpy((void *)sdp->dnl_address, req->buf + 1, datalen);
>>> +   sdp->dnl_address += datalen;
>>> +   }
>>> +
>>> +   if (sdp->dnl_bytes_remaining)
>>> +   return;
>>> +
>>> +   printf("done\n");
>>> +
>>> +   switch (sdp->state) {
>>> +   case SDP_STATE_RX_FILE_DATA:
>>> +   sdp->state = SDP_STATE_TX_SEC_CONF;
>>> +   break;
>>> +   case SDP_STATE_RX_DCD_DATA:
>>> +   sdp->state = SDP_STATE_TX_SEC_CONF;
>>> +   break;
>>> +   default:
>>> +   error("Invalid state: %d", sdp->state);
>>> +   }
>>> +}
>>> +
>>> +
>>> +
>>> +static void sdp_tx_complete(struct usb_ep *ep, struct usb_request *req)
>>> +{
>>> +   struct f_sdp *sdp = req->context;
>>> +   int status = req->status;
>>> +
>>> +   if (status != 0) {
>>> +   error("Status: %d", status);
>>> +   return;
>>> +   }
>>> +
>>> +   switch (sdp->state) {
>>> +   case SDP_STATE_TX_SEC_CONF_BUSY:
>>> +   /* Not all commands require status report */
>>> +   if (sdp->always_send_status || sdp->error_status)
>>> +   sdp->state = SDP_STATE_TX_STATUS;
>>> +   else
>>> +   sdp->state = sdp->next_state;
>>> +
>>> +   break;
>>> +   case SDP_STATE_TX_STATUS_BUSY:
>>> +   sdp->state = sdp->next_state;
>>> +   break;
>>> +   case SDP_STATE_TX_REGISTER_BUSY:
>>> +   if (sdp->dnl_bytes_remaining)
>>> +   sdp->state = SDP_STATE_TX_REGISTER;
>>> +   else
>>> +   sdp->state = SDP_STATE_IDLE;
>>> +   break;
>>> +   default:
>>> +   error("Wrong State: %d", sdp->state);
>>> +   sdp->state = SDP_STATE_IDLE;
>>> +   break;
>>> +   }
>>> +   debug("%s complete --> %d, %d/%d\n", ep->name,
>>> + status, req->actual, req->length);
>>> +}
>>> +
>>> +static int sdp_setup(struct usb_function *f, const struct usb_ctrlrequest 
>>> *ctrl)
>>> +{
>>> +   struct usb_gadget *gadget = f->config->cdev->gadget;
>>>