linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [05/31] usb: usbssp: Added first part of initialization sequence.
@ 2018-07-12  5:47 Pawel Laszczak
  0 siblings, 0 replies; 10+ messages in thread
From: Pawel Laszczak @ 2018-07-12  5:47 UTC (permalink / raw)
  Cc: Greg Kroah-Hartman, linux-usb, Felipe Balbi, linux-kernel,
	ltyrala, adouglas, pawell

Patch adds some initialization function. The initialization sequence
is quite complicated and this patch implements it only partially.
Initialization will be completed in next few patches.

Patch introduce three new files:
1. gadget-dbg.c - file contains functions used for debugging purpose.
2. gadget-ext-caps.h - holds macro definition related to
		       Extended Capabilities
3. gadget-if - file implements stuff related to upper layer
	(e.g usb_ep_ops, usb_gadget_ops interface).

Signed-off-by: Pawel Laszczak <pawell@cadence.com>
---
 drivers/usb/usbssp/Makefile          |   3 +-
 drivers/usb/usbssp/gadget-dbg.c      |  30 ++++
 drivers/usb/usbssp/gadget-ext-caps.h |  53 ++++++
 drivers/usb/usbssp/gadget-if.c       |  24 +++
 drivers/usb/usbssp/gadget.c          | 248 +++++++++++++++++++++++++++
 drivers/usb/usbssp/gadget.h          |  14 ++
 6 files changed, 371 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/usbssp/gadget-dbg.c
 create mode 100644 drivers/usb/usbssp/gadget-ext-caps.h
 create mode 100644 drivers/usb/usbssp/gadget-if.c

diff --git a/drivers/usb/usbssp/Makefile b/drivers/usb/usbssp/Makefile
index 1b6261068fd9..ccc7c5646a6b 100644
--- a/drivers/usb/usbssp/Makefile
+++ b/drivers/usb/usbssp/Makefile
@@ -4,7 +4,8 @@ CFLAGS_gadget-trace.o := -I$(src)
 
 obj-$(CONFIG_USB_USBSSP_GADGET) += usbssp.o
 usbssp-y 			:=  usbssp-plat.o gadget-ring.o \
-				    gadget.o
+				    gadget.o \
+				    gadget-dbg.o
 
 ifneq ($(CONFIG_TRACING),)
 	usbssp-y		+= gadget-trace.o
diff --git a/drivers/usb/usbssp/gadget-dbg.c b/drivers/usb/usbssp/gadget-dbg.c
new file mode 100644
index 000000000000..88e4e8d38e4b
--- /dev/null
+++ b/drivers/usb/usbssp/gadget-dbg.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * USBSSP device controller driver
+ *
+ * Copyright (C) 2018 Cadence.
+ *
+ * Author: Pawel Laszczak
+ *
+ * A lot of code based on Linux XHCI driver.
+ * Origin: Copyright (C) 2008 Intel Corp
+ */
+
+#include "gadget.h"
+
+void usbssp_dbg_trace(struct usbssp_udc *usbssp_data,
+		      void (*trace)(struct va_format *),
+		      const char *fmt, ...)
+{
+	struct va_format vaf;
+	va_list args;
+
+	va_start(args, fmt);
+	vaf.fmt = fmt;
+	vaf.va = &args;
+	usbssp_dbg(usbssp_data, "%pV\n", &vaf);
+	trace(&vaf);
+	va_end(args);
+}
+EXPORT_SYMBOL_GPL(usbssp_dbg_trace);
+
diff --git a/drivers/usb/usbssp/gadget-ext-caps.h b/drivers/usb/usbssp/gadget-ext-caps.h
new file mode 100644
index 000000000000..0107bc18ad7d
--- /dev/null
+++ b/drivers/usb/usbssp/gadget-ext-caps.h
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * USBSSP device controller driver
+ *
+ * Copyright (C) 2018 Cadence.
+ *
+ * Author: Pawel Laszczak
+ *
+ * A lot of code based on Linux XHCI driver.
+ * Origin: Copyright (C) 2008 Intel Corp
+ */
+
+/* Up to 16 ms to halt an DC */
+#define USBSSP_MAX_HALT_USEC		(16*1000)
+
+/* DC not running - set to 1 when run/stop bit is cleared. */
+#define USBSSP_STS_HALT			(1<<0)
+
+/* HCCPARAMS offset from PCI base address */
+#define USBSSP_HCC_PARAMS_OFFSET	0x10
+/* HCCPARAMS contains the first extended capability pointer */
+#define USBSSP_HCC_EXT_CAPS(p)	(((p)>>16)&0xffff)
+
+/* Command and Status registers offset from the Operational Registers address */
+#define USBSSP_CMD_OFFSET		0x00
+#define USBSSP_STS_OFFSET		0x04
+
+/* Capability Register */
+/* bits 7:0 - how long is the Capabilities register */
+#define USBSSP_HC_LENGTH(p)		(((p)>>00)&0x00ff)
+
+/* Extended capability register fields */
+#define USBSSP_EXT_CAPS_ID(p)		(((p)>>0)&0xff)
+#define USBSSP_EXT_CAPS_NEXT(p)		(((p)>>8)&0xff)
+#define	v_EXT_CAPS_VAL(p)		((p)>>16)
+/* Extended capability IDs - ID 0 reserved */
+#define USBSSP_EXT_CAPS_PROTOCOL		2
+
+/* USB 2.0 hardware LMP capability*/
+#define USBSSP_HLC			(1 << 19)
+#define USBSSP_BLC			(1 << 20)
+
+/* command register values to disable interrupts and halt the DC */
+/* start/stop DC execution - do not write unless DC is halted*/
+#define USBSSP_CMD_RUN			(1 << 0)
+/* Event Interrupt Enable - get irq when EINT bit is set in USBSTS register */
+#define USBSSP_CMD_EIE			(1 << 2)
+/* Host System Error Interrupt Enable - get irq when HSEIE bit set in USBSTS */
+#define USBSSP_CMD_HSEIE		(1 << 3)
+/* Enable Wrap Event - '1' means DC generates an event when MFINDEX wraps. */
+#define USBSSP_CMD_EWE			(1 << 10)
+
+#define USBSSP_IRQS	(USBSSP_CMD_EIE | USBSSP_CMD_HSEIE | USBSSP_CMD_EWE)
diff --git a/drivers/usb/usbssp/gadget-if.c b/drivers/usb/usbssp/gadget-if.c
new file mode 100644
index 000000000000..d53e0fb65299
--- /dev/null
+++ b/drivers/usb/usbssp/gadget-if.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * USBSSP device controller driver
+ *
+ * Copyright (C) 2018 Cadence.
+ *
+ * Author: Pawel Laszczak
+ *
+ */
+
+#include <linux/usb/gadget.h>
+#include <linux/usb/composite.h>
+#include "gadget.h"
+
+int usbssp_gadget_init_endpoint(struct usbssp_udc *usbssp_data)
+{
+	/*TODO: it has to be implemented*/
+	return 0;
+}
+
+void usbssp_gadget_free_endpoint(struct usbssp_udc *usbssp_data)
+{
+	/*TODO: it has to be implemented*/
+}
diff --git a/drivers/usb/usbssp/gadget.c b/drivers/usb/usbssp/gadget.c
index 2f60d7dd1fe4..75272dd2447a 100644
--- a/drivers/usb/usbssp/gadget.c
+++ b/drivers/usb/usbssp/gadget.c
@@ -23,6 +23,111 @@
 #include "gadget-trace.h"
 #include "gadget.h"
 
+
+/*
+ * usbssp_handshake - spin reading dc until handshake completes or fails
+ * @ptr: address of dc register to be read
+ * @mask: bits to look at in result of read
+ * @done: value of those bits when handshake succeeds
+ * @usec: timeout in microseconds
+ *
+ * Returns negative errno, or zero on success
+ *
+ * Success happens when the "mask" bits have the specified value (hardware
+ * handshake done). There are two failure modes: "usec" have passed (major
+ * hardware flakeout), or the register reads as all-ones (hardware removed).
+ */
+int usbssp_handshake(void __iomem *ptr, u32 mask, u32 done, int usec)
+{
+	u32	result;
+
+	do {
+		result = readl(ptr);
+		if (result == ~(u32)0)	/* card removed */
+			return -ENODEV;
+		result &= mask;
+		if (result == done)
+			return 0;
+		udelay(1);
+		usec--;
+	} while (usec > 0);
+	return -ETIMEDOUT;
+}
+
+/*
+ * Disable interrupts and begin the DC halting process.
+ */
+void usbssp_quiesce(struct usbssp_udc *usbssp_data)
+{
+	u32 halted;
+	u32 cmd;
+	u32 mask;
+
+	mask = ~(USBSSP_IRQS);
+
+	halted = readl(&usbssp_data->op_regs->status) & STS_HALT;
+	if (!halted)
+		mask &= ~CMD_RUN;
+
+	cmd = readl(&usbssp_data->op_regs->command);
+	cmd &= mask;
+	writel(cmd, &usbssp_data->op_regs->command);
+}
+
+/*
+ * Force DC into halt state.
+ *
+ * Disable any IRQs and clear the run/stop bit.
+ * USBSSP will complete any current and actively pipelined transactions, and
+ * should halt within 16 ms of the run/stop bit being cleared.
+ * Read DC Halted bit in the status register to see when the DC is finished.
+ */
+int usbssp_halt(struct usbssp_udc *usbssp_data)
+{
+	int ret;
+
+	usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_init,
+			 "// Halt the USBSSP");
+	usbssp_quiesce(usbssp_data);
+
+	ret = usbssp_handshake(&usbssp_data->op_regs->status,
+		STS_HALT, STS_HALT, USBSSP_MAX_HALT_USEC);
+
+	if (!ret) {
+		usbssp_warn(usbssp_data, "Device halt failed, %d\n", ret);
+		return ret;
+	}
+
+	usbssp_data->usbssp_state |= USBSSP_STATE_HALTED;
+	usbssp_data->cmd_ring_state = CMD_RING_STATE_STOPPED;
+	return ret;
+}
+
+
+/*
+ * Initialize memory for gadget driver and USBSSP (one-time init).
+ *
+ * Program the PAGESIZE register, initialize the device context array, create
+ * device contexts, set up a command ring segment (or two?), create event
+ * ring (one for now).
+ */
+int usbssp_init(struct usbssp_udc *usbssp_data)
+{
+	int retval = 0;
+
+	usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_init, "usbssp_init");
+
+	spin_lock_init(&usbssp_data->lock);
+	spin_lock_init(&usbssp_data->irq_thread_lock);
+
+	//TODO: memory initialization
+	//retval = usbssp_mem_init(usbssp_data, GFP_KERNEL);
+
+	usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_init,
+			"Finished usbssp_init");
+	return retval;
+}
+
 #ifdef CONFIG_PM
 /*
  * Stop DC (not bus-specific)
@@ -50,9 +155,148 @@ int usbssp_resume(struct usbssp_udc *usbssp_data, bool hibernated)
 
 #endif	/* CONFIG_PM */
 
+int usbssp_gen_setup(struct usbssp_udc *usbssp_data)
+{
+	int	retval;
+
+	mutex_init(&usbssp_data->mutex);
+
+	usbssp_data->cap_regs = usbssp_data->regs;
+	usbssp_data->op_regs = usbssp_data->regs +
+		HC_LENGTH(readl(&usbssp_data->cap_regs->hc_capbase));
+
+	usbssp_data->run_regs = usbssp_data->regs +
+		(readl(&usbssp_data->cap_regs->run_regs_off) & RTSOFF_MASK);
+	/* Cache read-only capability registers */
+	usbssp_data->hcs_params1 = readl(&usbssp_data->cap_regs->hcs_params1);
+	usbssp_data->hcs_params2 = readl(&usbssp_data->cap_regs->hcs_params2);
+	usbssp_data->hcs_params3 = readl(&usbssp_data->cap_regs->hcs_params3);
+	usbssp_data->hcc_params = readl(&usbssp_data->cap_regs->hc_capbase);
+	usbssp_data->hci_version = HC_VERSION(usbssp_data->hcc_params);
+	usbssp_data->hcc_params = readl(&usbssp_data->cap_regs->hcc_params);
+	usbssp_data->hcc_params2 = readl(&usbssp_data->cap_regs->hcc_params2);
+
+	/* Make sure the Device Controller is halted. */
+	retval = usbssp_halt(usbssp_data);
+	if (retval)
+		return retval;
+
+	usbssp_dbg(usbssp_data, "Resetting Device Controller\n");
+	/* Reset the internal DC memory state and registers. */
+	/*TODO: add implementation of usbssp_reset function*/
+	//retval = usbssp_reset(usbssp_data);
+	if (retval)
+		return retval;
+	usbssp_dbg(usbssp_data, "Reset complete\n");
+
+	/* Set dma_mask and coherent_dma_mask to 64-bits,
+	 * if USBSSP supports 64-bit addressing
+	 */
+	if (HCC_64BIT_ADDR(usbssp_data->hcc_params) &&
+	    !dma_set_mask(usbssp_data->dev, DMA_BIT_MASK(64))) {
+		usbssp_dbg(usbssp_data, "Enabling 64-bit DMA addresses.\n");
+		dma_set_coherent_mask(usbssp_data->dev, DMA_BIT_MASK(64));
+	} else {
+		/*
+		 * This is to avoid error in cases where a 32-bit USB
+		 * controller is used on a 64-bit capable system.
+		 */
+		retval = dma_set_mask(usbssp_data->dev, DMA_BIT_MASK(32));
+		if (retval)
+			return retval;
+		usbssp_dbg(usbssp_data, "Enabling 32-bit DMA addresses.\n");
+		dma_set_coherent_mask(usbssp_data->dev, DMA_BIT_MASK(32));
+	}
+
+	usbssp_dbg(usbssp_data, "Calling USBSSP init\n");
+	/* Initialize USBSSP controller data structures. */
+	retval = usbssp_init(usbssp_data);
+	if (retval)
+		return retval;
+	usbssp_dbg(usbssp_data, "Called USBSSPinit\n");
+
+	usbssp_info(usbssp_data, "USBSSP params 0x%08x USBSSP version 0x%x\n",
+		usbssp_data->hcc_params, usbssp_data->hci_version);
+
+	return 0;
+}
+
+/*
+ * gadget-if.c file is part of gadget.c file and implements interface
+ * for gadget driver
+ */
+#include "gadget-if.c"
+
 int usbssp_gadget_init(struct usbssp_udc *usbssp_data)
 {
 	int ret;
+
+	/*
+	 * Check the compiler generated sizes of structures that must be laid
+	 * out in specific ways for hardware access.
+	 */
+	BUILD_BUG_ON(sizeof(struct usbssp_doorbell_array) != 2*32/8);
+	BUILD_BUG_ON(sizeof(struct usbssp_slot_ctx) != 8*32/8);
+	BUILD_BUG_ON(sizeof(struct usbssp_ep_ctx) != 8*32/8);
+	/* usbssp_device has eight fields, and also
+	 * embeds one usbssp_slot_ctx and 31 usbssp_ep_ctx
+	 */
+	BUILD_BUG_ON(sizeof(struct usbssp_stream_ctx) != 4*32/8);
+	BUILD_BUG_ON(sizeof(union usbssp_trb) != 4*32/8);
+	BUILD_BUG_ON(sizeof(struct usbssp_erst_entry) != 4*32/8);
+	BUILD_BUG_ON(sizeof(struct usbssp_cap_regs) != 8*32/8);
+	BUILD_BUG_ON(sizeof(struct usbssp_intr_reg) != 8*32/8);
+	/* usbssp_run_regs has eight fields and embeds 128 usbssp_intr_regs */
+	BUILD_BUG_ON(sizeof(struct usbssp_run_regs) != (8+8*128)*32/8);
+
+	/* fill gadget fields */
+	/*TODO: implements usbssp_gadget_ops object*/
+	//usbssp_data->gadget.ops = &usbssp_gadget_ops;
+	usbssp_data->gadget.name = "usbssp-gadget";
+	usbssp_data->gadget.max_speed = USB_SPEED_SUPER_PLUS;
+	usbssp_data->gadget.speed = USB_SPEED_UNKNOWN;
+	usbssp_data->gadget.sg_supported = true;
+	usbssp_data->gadget.lpm_capable = 1;
+
+	usbssp_data->setup_buf = kzalloc(USBSSP_EP0_SETUP_SIZE, GFP_KERNEL);
+	if (!usbssp_data->setup_buf)
+		return -ENOMEM;
+
+	/*USBSSP support not aligned buffer but this option
+	 * improve performance of this controller.
+	 */
+	usbssp_data->gadget.quirk_ep_out_aligned_size = true;
+	ret = usbssp_gen_setup(usbssp_data);
+	if (ret < 0) {
+		usbssp_err(usbssp_data,
+				"Generic initialization failed with error code%d\n",
+				ret);
+		goto err3;
+	}
+
+	ret = usbssp_gadget_init_endpoint(usbssp_data);
+	if (ret < 0) {
+		usbssp_err(usbssp_data, "failed to initialize endpoints\n");
+		goto err1;
+	}
+
+	ret = usb_add_gadget_udc(usbssp_data->dev, &usbssp_data->gadget);
+
+	if (ret) {
+		usbssp_err(usbssp_data, "failed to register udc\n");
+		goto err2;
+	}
+
+	return ret;
+err2:
+	usbssp_gadget_free_endpoint(usbssp_data);
+err1:
+	usbssp_halt(usbssp_data);
+	/*TODO add implementation of usbssp_reset function*/
+	//usbssp_reset(usbssp_data);
+	//TODO freeing memory
+	//usbssp_mem_cleanup(usbssp_data);
+err3:
 	return ret;
 }
 
@@ -60,5 +304,9 @@ int usbssp_gadget_exit(struct usbssp_udc *usbssp_data)
 {
 	int ret = 0;
 
+	usb_del_gadget_udc(&usbssp_data->gadget);
+	usbssp_gadget_free_endpoint(usbssp_data);
+	/*TODO: add usbssp_stop implementation*/
+	//usbssp_stop(usbssp_data);
 	return ret;
 }
diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h
index 2f9ee3543911..ce0ac6883efc 100644
--- a/drivers/usb/usbssp/gadget.h
+++ b/drivers/usb/usbssp/gadget.h
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/usb/gadget.h>
+#include "gadget-ext-caps.h"
 
 /* Max number slots - only 1 is allowed */
 #define DEV_MAX_SLOTS 1
@@ -1671,7 +1672,18 @@ static inline void usbssp_write_64(struct usbssp_udc *usbssp_data,
 	lo_hi_writeq(val, regs);
 }
 
+/* USBSSP memory management */
+void usbssp_dbg_trace(struct usbssp_udc *usbssp_data,
+		void (*trace)(struct va_format *),
+		const char *fmt, ...);
 /* USBSSP Device controller glue */
+void usbssp_bottom_irq(struct work_struct *work);
+int usbssp_init(struct usbssp_udc *usbssp_data);
+void usbssp_stop(struct usbssp_udc *usbssp_data);
+int usbssp_handshake(void __iomem *ptr, u32 mask, u32 done, int usec);
+void usbssp_quiesce(struct usbssp_udc *usbssp_data);
+extern int usbssp_reset(struct usbssp_udc *usbssp_data);
+
 int usbssp_suspend(struct usbssp_udc *usbssp_data, bool do_wakeup);
 int usbssp_resume(struct usbssp_udc *usbssp_data, bool hibernated);
 
@@ -1684,6 +1696,8 @@ dma_addr_t usbssp_trb_virt_to_dma(struct usbssp_segment *seg,
 /* USBSSP gadget interface*/
 int usbssp_gadget_init(struct usbssp_udc *usbssp_data);
 int  usbssp_gadget_exit(struct usbssp_udc *usbssp_data);
+void usbssp_gadget_free_endpoint(struct usbssp_udc *usbssp_data);
+int usbssp_gadget_init_endpoint(struct usbssp_udc *usbssp_data);
 
 static inline char *usbssp_slot_state_string(u32 state)
 {

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [05/31] usb: usbssp: Added first part of initialization sequence.
@ 2018-07-12  6:27 Greg Kroah-Hartman
  0 siblings, 0 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2018-07-12  6:27 UTC (permalink / raw)
  To: Pawel Laszczak; +Cc: linux-usb, Felipe Balbi, linux-kernel, ltyrala, adouglas

On Thu, Jul 12, 2018 at 06:47:02AM +0100, Pawel Laszczak wrote:
> +/* USB 2.0 hardware LMP capability*/
> +#define USBSSP_HLC			(1 << 19)
> +#define USBSSP_BLC			(1 << 20)

Again, BIT() please.

> +int usbssp_handshake(void __iomem *ptr, u32 mask, u32 done, int usec)
> +{
> +	u32	result;

Some places you use tabs for the variable declarations, and some you do
not.  Pick a single style and stick to it please.

> +
> +	do {
> +		result = readl(ptr);
> +		if (result == ~(u32)0)	/* card removed */
> +			return -ENODEV;
> +		result &= mask;
> +		if (result == done)
> +			return 0;
> +		udelay(1);
> +		usec--;
> +	} while (usec > 0);
> +	return -ETIMEDOUT;

We don't have a built-in kernel function to do this type of thing
already?  That's sad.  Oh well...

> +int usbssp_init(struct usbssp_udc *usbssp_data)
> +{
> +	int retval = 0;
> +
> +	usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_init, "usbssp_init");
> +
> +	spin_lock_init(&usbssp_data->lock);
> +	spin_lock_init(&usbssp_data->irq_thread_lock);
> +
> +	//TODO: memory initialization
> +	//retval = usbssp_mem_init(usbssp_data, GFP_KERNEL);
> +
> +	usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_init,
> +			"Finished usbssp_init");

When your trace functions do nothing but say "entered a function", and
"exited a function", why even have them?  ftrace can provide that for
you already, no need to overload that on the tracing framework, right?

> +/*
> + * gadget-if.c file is part of gadget.c file and implements interface
> + * for gadget driver
> + */
> +#include "gadget-if.c"

Ugh, I know USB hcd drivers love to include .c files in the middle of
them, but do we have to continue that crazy practice in newer drivers?
Is it really necessary?

> +	/*
> +	 * Check the compiler generated sizes of structures that must be laid
> +	 * out in specific ways for hardware access.
> +	 */
> +	BUILD_BUG_ON(sizeof(struct usbssp_doorbell_array) != 2*32/8);
> +	BUILD_BUG_ON(sizeof(struct usbssp_slot_ctx) != 8*32/8);
> +	BUILD_BUG_ON(sizeof(struct usbssp_ep_ctx) != 8*32/8);
> +	/* usbssp_device has eight fields, and also
> +	 * embeds one usbssp_slot_ctx and 31 usbssp_ep_ctx
> +	 */
> +	BUILD_BUG_ON(sizeof(struct usbssp_stream_ctx) != 4*32/8);
> +	BUILD_BUG_ON(sizeof(union usbssp_trb) != 4*32/8);
> +	BUILD_BUG_ON(sizeof(struct usbssp_erst_entry) != 4*32/8);
> +	BUILD_BUG_ON(sizeof(struct usbssp_cap_regs) != 8*32/8);
> +	BUILD_BUG_ON(sizeof(struct usbssp_intr_reg) != 8*32/8);
> +	/* usbssp_run_regs has eight fields and embeds 128 usbssp_intr_regs */
> +	BUILD_BUG_ON(sizeof(struct usbssp_run_regs) != (8+8*128)*32/8);

I love hard-coded numbers as much as the next person, but really?  Is
this necessary now that you have the code up and working properly?


I've stopped reviewing this series here.

thanks,

greg k-h
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [05/31] usb: usbssp: Added first part of initialization sequence.
@ 2018-07-12  9:03 Pawel Laszczak
  0 siblings, 0 replies; 10+ messages in thread
From: Pawel Laszczak @ 2018-07-12  9:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-usb@vger.kernel.org, Felipe Balbi,
	linux-kernel@vger.kernel.org, Lukasz Tyrala, Alan Douglas

PiA+ICsvKiBVU0IgMi4wIGhhcmR3YXJlIExNUCBjYXBhYmlsaXR5Ki8NCj4gPiArI2RlZmluZSBV
U0JTU1BfSExDCQkJKDEgPDwgMTkpDQo+ID4gKyNkZWZpbmUgVVNCU1NQX0JMQwkJCSgxIDw8IDIw
KQ0KPiANCj4gQWdhaW4sIEJJVCgpIHBsZWFzZS4NCj4gDQo+ID4gK2ludCB1c2Jzc3BfaGFuZHNo
YWtlKHZvaWQgX19pb21lbSAqcHRyLCB1MzIgbWFzaywgdTMyIGRvbmUsIGludCB1c2VjKQ0KPiA+
ICt7DQo+ID4gKwl1MzIJcmVzdWx0Ow0KPiANCj4gU29tZSBwbGFjZXMgeW91IHVzZSB0YWJzIGZv
ciB0aGUgdmFyaWFibGUgZGVjbGFyYXRpb25zLCBhbmQgc29tZSB5b3UgZG8NCj4gbm90LiAgUGlj
ayBhIHNpbmdsZSBzdHlsZSBhbmQgc3RpY2sgdG8gaXQgcGxlYXNlLg0KPiANCj4gPiArDQo+ID4g
KwlkbyB7DQo+ID4gKwkJcmVzdWx0ID0gcmVhZGwocHRyKTsNCj4gPiArCQlpZiAocmVzdWx0ID09
IH4odTMyKTApCS8qIGNhcmQgcmVtb3ZlZCAqLw0KPiA+ICsJCQlyZXR1cm4gLUVOT0RFVjsNCj4g
PiArCQlyZXN1bHQgJj0gbWFzazsNCj4gPiArCQlpZiAocmVzdWx0ID09IGRvbmUpDQo+ID4gKwkJ
CXJldHVybiAwOw0KPiA+ICsJCXVkZWxheSgxKTsNCj4gPiArCQl1c2VjLS07DQo+ID4gKwl9IHdo
aWxlICh1c2VjID4gMCk7DQo+ID4gKwlyZXR1cm4gLUVUSU1FRE9VVDsNCj4gDQo+IFdlIGRvbid0
IGhhdmUgYSBidWlsdC1pbiBrZXJuZWwgZnVuY3Rpb24gdG8gZG8gdGhpcyB0eXBlIG9mIHRoaW5n
IGFscmVhZHk/DQo+IFRoYXQncyBzYWQuICBPaCB3ZWxsLi4uDQo+IA0KPiA+ICtpbnQgdXNic3Nw
X2luaXQoc3RydWN0IHVzYnNzcF91ZGMgKnVzYnNzcF9kYXRhKSB7DQo+ID4gKwlpbnQgcmV0dmFs
ID0gMDsNCj4gPiArDQo+ID4gKwl1c2Jzc3BfZGJnX3RyYWNlKHVzYnNzcF9kYXRhLCB0cmFjZV91
c2Jzc3BfZGJnX2luaXQsDQo+ICJ1c2Jzc3BfaW5pdCIpOw0KPiA+ICsNCj4gPiArCXNwaW5fbG9j
a19pbml0KCZ1c2Jzc3BfZGF0YS0+bG9jayk7DQo+ID4gKwlzcGluX2xvY2tfaW5pdCgmdXNic3Nw
X2RhdGEtPmlycV90aHJlYWRfbG9jayk7DQo+ID4gKw0KPiA+ICsJLy9UT0RPOiBtZW1vcnkgaW5p
dGlhbGl6YXRpb24NCj4gPiArCS8vcmV0dmFsID0gdXNic3NwX21lbV9pbml0KHVzYnNzcF9kYXRh
LCBHRlBfS0VSTkVMKTsNCj4gPiArDQo+ID4gKwl1c2Jzc3BfZGJnX3RyYWNlKHVzYnNzcF9kYXRh
LCB0cmFjZV91c2Jzc3BfZGJnX2luaXQsDQo+ID4gKwkJCSJGaW5pc2hlZCB1c2Jzc3BfaW5pdCIp
Ow0KPiANCj4gV2hlbiB5b3VyIHRyYWNlIGZ1bmN0aW9ucyBkbyBub3RoaW5nIGJ1dCBzYXkgImVu
dGVyZWQgYSBmdW5jdGlvbiIsIGFuZA0KPiAiZXhpdGVkIGEgZnVuY3Rpb24iLCB3aHkgZXZlbiBo
YXZlIHRoZW0/ICBmdHJhY2UgY2FuIHByb3ZpZGUgdGhhdCBmb3IgeW91DQo+IGFscmVhZHksIG5v
IG5lZWQgdG8gb3ZlcmxvYWQgdGhhdCBvbiB0aGUgdHJhY2luZyBmcmFtZXdvcmssIHJpZ2h0Pw0K
DQpEbyB5b3Ugc3VnZ2VzdCB0byB1c2Ugb25seTogDQoJdHJhY2VfdXNic3NwX2RiZ19pbml0KCJG
aW5pc2hlZCB1c2Jzc3BfaW5pdCIpOyANCmluc3RlYWQ6IA0KCXVzYnNzcF9kYmcodXNic3NwX2Rh
dGEsICIlcFZcbiIsICJGaW5pc2hlZCB1c2Jzc3BfaW5pdCIpOw0KCXRyYWNlX3VzYnNzcF9kYmdf
aW5pdCgiRmluaXNoZWQgdXNic3NwX2luaXQiKTsNCj8NCg0KSSdtIHNpbXBsZSByZS11c2VkIHRo
ZSBjb2RlIGZyb20gWEhDSSBkcml2ZXIuIEl0J3MgcmVhbGx5IHJlZHVuZGFudCwgDQpidXQgSSBk
b24ndCBrbm93IHRoZSBpbnRlbnRpb24gb2YgYXV0aG9yIPCfmIouICANCiANCj4gPiArLyoNCj4g
PiArICogZ2FkZ2V0LWlmLmMgZmlsZSBpcyBwYXJ0IG9mIGdhZGdldC5jIGZpbGUgYW5kIGltcGxl
bWVudHMgaW50ZXJmYWNlDQo+ID4gKyAqIGZvciBnYWRnZXQgZHJpdmVyDQo+ID4gKyAqLw0KPiA+
ICsjaW5jbHVkZSAiZ2FkZ2V0LWlmLmMiDQo+IA0KPiBVZ2gsIEkga25vdyBVU0IgaGNkIGRyaXZl
cnMgbG92ZSB0byBpbmNsdWRlIC5jIGZpbGVzIGluIHRoZSBtaWRkbGUgb2YgdGhlbSwgYnV0DQo+
IGRvIHdlIGhhdmUgdG8gY29udGludWUgdGhhdCBjcmF6eSBwcmFjdGljZSBpbiBuZXdlciBkcml2
ZXJzPw0KPiBJcyBpdCByZWFsbHkgbmVjZXNzYXJ5Pw0KDQpJdCdzIG5vdCBuZWNlc3NhcnkgSSB3
YW50ZWQgdG8gbGVhdmUgdGhpcyBhcyB0d28gc2VwYXJhdGUgZmlsZSwgYmVjYXVzZSBnYWRnZXQu
YyANCklzIGJhc2VkIG9uIHhoY2kuYyBhbmQgZ2FkZ2V0LWlmLmMgZGVmaW5lIGludGVyZmFjZSBi
ZXR3ZWVuIGdhZGdldC5jIGFuZCANClVTQiBnYWRnZXQgY29yZSBkcml2ZXIuIEkgZGlkbid0IHdh
bnQgdG8gY29tYmluZSB0aGVzZSB0d28gZmlsZXMuIA0KDQpJIHdpbGwgYWRkIHNvbWUgYWRkaXRp
b25hbCBmdW5jdGlvbiBkZWNsYXJhdGlvbiB0byBnYWRnZXQuaCBhbmQgcmVtb3ZlIGl0IA0KZnJv
bSBnYWRnZXQuYyBmaWxlLiANCg0KIA0KPiA+ICsJLyoNCj4gPiArCSAqIENoZWNrIHRoZSBjb21w
aWxlciBnZW5lcmF0ZWQgc2l6ZXMgb2Ygc3RydWN0dXJlcyB0aGF0IG11c3QgYmUgbGFpZA0KPiA+
ICsJICogb3V0IGluIHNwZWNpZmljIHdheXMgZm9yIGhhcmR3YXJlIGFjY2Vzcy4NCj4gPiArCSAq
Lw0KPiA+ICsJQlVJTERfQlVHX09OKHNpemVvZihzdHJ1Y3QgdXNic3NwX2Rvb3JiZWxsX2FycmF5
KSAhPSAyKjMyLzgpOw0KPiA+ICsJQlVJTERfQlVHX09OKHNpemVvZihzdHJ1Y3QgdXNic3NwX3Ns
b3RfY3R4KSAhPSA4KjMyLzgpOw0KPiA+ICsJQlVJTERfQlVHX09OKHNpemVvZihzdHJ1Y3QgdXNi
c3NwX2VwX2N0eCkgIT0gOCozMi84KTsNCj4gPiArCS8qIHVzYnNzcF9kZXZpY2UgaGFzIGVpZ2h0
IGZpZWxkcywgYW5kIGFsc28NCj4gPiArCSAqIGVtYmVkcyBvbmUgdXNic3NwX3Nsb3RfY3R4IGFu
ZCAzMSB1c2Jzc3BfZXBfY3R4DQo+ID4gKwkgKi8NCj4gPiArCUJVSUxEX0JVR19PTihzaXplb2Yo
c3RydWN0IHVzYnNzcF9zdHJlYW1fY3R4KSAhPSA0KjMyLzgpOw0KPiA+ICsJQlVJTERfQlVHX09O
KHNpemVvZih1bmlvbiB1c2Jzc3BfdHJiKSAhPSA0KjMyLzgpOw0KPiA+ICsJQlVJTERfQlVHX09O
KHNpemVvZihzdHJ1Y3QgdXNic3NwX2Vyc3RfZW50cnkpICE9IDQqMzIvOCk7DQo+ID4gKwlCVUlM
RF9CVUdfT04oc2l6ZW9mKHN0cnVjdCB1c2Jzc3BfY2FwX3JlZ3MpICE9IDgqMzIvOCk7DQo+ID4g
KwlCVUlMRF9CVUdfT04oc2l6ZW9mKHN0cnVjdCB1c2Jzc3BfaW50cl9yZWcpICE9IDgqMzIvOCk7
DQo+ID4gKwkvKiB1c2Jzc3BfcnVuX3JlZ3MgaGFzIGVpZ2h0IGZpZWxkcyBhbmQgZW1iZWRzIDEy
OA0KPiB1c2Jzc3BfaW50cl9yZWdzICovDQo+ID4gKwlCVUlMRF9CVUdfT04oc2l6ZW9mKHN0cnVj
dCB1c2Jzc3BfcnVuX3JlZ3MpICE9ICg4KzgqMTI4KSozMi84KTsNCj4gDQo+IEkgbG92ZSBoYXJk
LWNvZGVkIG51bWJlcnMgYXMgbXVjaCBhcyB0aGUgbmV4dCBwZXJzb24sIGJ1dCByZWFsbHk/ICBJ
cyB0aGlzDQo+IG5lY2Vzc2FyeSBub3cgdGhhdCB5b3UgaGF2ZSB0aGUgY29kZSB1cCBhbmQgd29y
a2luZyBwcm9wZXJseT8NCg0KQ29kZSBpcyBzdGlsbCBiZWluZyBkZXZlbG9wZWQsICBhbmQgaXMg
c3RpbGwgdGVzdGVkLiBJdCdzIGJldHRlciB0byBsZWF2ZSB0aGlzIGNvZGUgYXQgDQp0aGlzIG1v
bWVudC4gIEkgd2lsbCByZW1vdmUgaXQgaW4gdGhlIGZlYXR1cmUuIA0KDQp0aGFua3MsDQpQYXdl
bCBMYXN6Y3phaw0K
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [05/31] usb: usbssp: Added first part of initialization sequence.
@ 2018-07-12  9:09 Greg Kroah-Hartman
  0 siblings, 0 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2018-07-12  9:09 UTC (permalink / raw)
  To: Pawel Laszczak
  Cc: linux-usb@vger.kernel.org, Felipe Balbi,
	linux-kernel@vger.kernel.org, Lukasz Tyrala, Alan Douglas

On Thu, Jul 12, 2018 at 09:03:30AM +0000, Pawel Laszczak wrote:
> > > +/* USB 2.0 hardware LMP capability*/
> > > +#define USBSSP_HLC			(1 << 19)
> > > +#define USBSSP_BLC			(1 << 20)
> > 
> > Again, BIT() please.
> > 
> > > +int usbssp_handshake(void __iomem *ptr, u32 mask, u32 done, int usec)
> > > +{
> > > +	u32	result;
> > 
> > Some places you use tabs for the variable declarations, and some you do
> > not.  Pick a single style and stick to it please.
> > 
> > > +
> > > +	do {
> > > +		result = readl(ptr);
> > > +		if (result == ~(u32)0)	/* card removed */
> > > +			return -ENODEV;
> > > +		result &= mask;
> > > +		if (result == done)
> > > +			return 0;
> > > +		udelay(1);
> > > +		usec--;
> > > +	} while (usec > 0);
> > > +	return -ETIMEDOUT;
> > 
> > We don't have a built-in kernel function to do this type of thing already?
> > That's sad.  Oh well...
> > 
> > > +int usbssp_init(struct usbssp_udc *usbssp_data) {
> > > +	int retval = 0;
> > > +
> > > +	usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_init,
> > "usbssp_init");
> > > +
> > > +	spin_lock_init(&usbssp_data->lock);
> > > +	spin_lock_init(&usbssp_data->irq_thread_lock);
> > > +
> > > +	//TODO: memory initialization
> > > +	//retval = usbssp_mem_init(usbssp_data, GFP_KERNEL);
> > > +
> > > +	usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_init,
> > > +			"Finished usbssp_init");
> > 
> > When your trace functions do nothing but say "entered a function", and
> > "exited a function", why even have them?  ftrace can provide that for you
> > already, no need to overload that on the tracing framework, right?
> 
> Do you suggest to use only: 
> 	trace_usbssp_dbg_init("Finished usbssp_init"); 
> instead: 
> 	usbssp_dbg(usbssp_data, "%pV\n", "Finished usbssp_init");
> 	trace_usbssp_dbg_init("Finished usbssp_init");
> ?
> 
> I'm simple re-used the code from XHCI driver. It's really redundant, 
> but I don't know the intention of author

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [05/31] usb: usbssp: Added first part of initialization sequence.
@ 2018-07-12  9:47 Pawel Laszczak
  0 siblings, 0 replies; 10+ messages in thread
From: Pawel Laszczak @ 2018-07-12  9:47 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-usb@vger.kernel.org, Felipe Balbi,
	linux-kernel@vger.kernel.org, Lukasz Tyrala, Alan Douglas

> > > > +/* USB 2.0 hardware LMP capability*/
> > > > +#define USBSSP_HLC			(1 << 19)
> > > > +#define USBSSP_BLC			(1 << 20)
> > >
> > > Again, BIT() please.
> > >
> > > > +int usbssp_handshake(void __iomem *ptr, u32 mask, u32 done, int
> > > > +usec) {
> > > > +	u32	result;
> > >
> > > Some places you use tabs for the variable declarations, and some you
> > > do not.  Pick a single style and stick to it please.
> > >
> > > > +
> > > > +	do {
> > > > +		result = readl(ptr);
> > > > +		if (result == ~(u32)0)	/* card removed */
> > > > +			return -ENODEV;
> > > > +		result &= mask;
> > > > +		if (result == done)
> > > > +			return 0;
> > > > +		udelay(1);
> > > > +		usec--;
> > > > +	} while (usec > 0);
> > > > +	return -ETIMEDOUT;
> > >
> > > We don't have a built-in kernel function to do this type of thing already?
> > > That's sad.  Oh well...
> > >
> > > > +int usbssp_init(struct usbssp_udc *usbssp_data) {
> > > > +	int retval = 0;
> > > > +
> > > > +	usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_init,
> > > "usbssp_init");
> > > > +
> > > > +	spin_lock_init(&usbssp_data->lock);
> > > > +	spin_lock_init(&usbssp_data->irq_thread_lock);
> > > > +
> > > > +	//TODO: memory initialization
> > > > +	//retval = usbssp_mem_init(usbssp_data, GFP_KERNEL);
> > > > +
> > > > +	usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_init,
> > > > +			"Finished usbssp_init");
> > >
> > > When your trace functions do nothing but say "entered a function",
> > > and "exited a function", why even have them?  ftrace can provide
> > > that for you already, no need to overload that on the tracing framework,
> right?
> >
> > Do you suggest to use only:
> > 	trace_usbssp_dbg_init("Finished usbssp_init");
> > instead:
> > 	usbssp_dbg(usbssp_data, "%pV\n", "Finished usbssp_init");
> > 	trace_usbssp_dbg_init("Finished usbssp_init"); ?
> >
> > I'm simple re-used the code from XHCI driver. It's really redundant,
> > but I don't know the intention of author

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [05/31] usb: usbssp: Added first part of initialization sequence.
@ 2018-07-19 17:57 Pawel Laszczak
  0 siblings, 0 replies; 10+ messages in thread
From: Pawel Laszczak @ 2018-07-19 17:57 UTC (permalink / raw)
  Cc: Greg Kroah-Hartman, linux-usb, Felipe Balbi, linux-kernel,
	ltyrala, adouglas, pawell

Patch adds some initialization function. The initialization sequence
is quite complicated and this patch implements it only partially.
Initialization will be completed in next few patches.

Patch introduce three new files:
1. gadget-dbg.c - file contains functions used for debugging purpose.
2. gadget-ext-caps.h - holds macro definition related to
		       Extended Capabilities
3. gadget-if - file implements stuff related to upper layer
	(e.g usb_ep_ops, usb_gadget_ops interface).

Signed-off-by: Pawel Laszczak <pawell@cadence.com>
---
 drivers/usb/usbssp/Makefile          |   1 +
 drivers/usb/usbssp/gadget-dbg.c      |  30 ++++
 drivers/usb/usbssp/gadget-ext-caps.h |  53 ++++++
 drivers/usb/usbssp/gadget-if.c       |  24 +++
 drivers/usb/usbssp/gadget.c          | 242 +++++++++++++++++++++++++++
 drivers/usb/usbssp/gadget.h          |  15 ++
 6 files changed, 365 insertions(+)
 create mode 100644 drivers/usb/usbssp/gadget-dbg.c
 create mode 100644 drivers/usb/usbssp/gadget-ext-caps.h
 create mode 100644 drivers/usb/usbssp/gadget-if.c

diff --git a/drivers/usb/usbssp/Makefile b/drivers/usb/usbssp/Makefile
index d85f15afb51c..0606f3c63cd0 100644
--- a/drivers/usb/usbssp/Makefile
+++ b/drivers/usb/usbssp/Makefile
@@ -5,6 +5,7 @@ CFLAGS_gadget-trace.o := -I$(src)
 obj-$(CONFIG_USB_USBSSP_GADGET) += usbssp.o
 usbssp-y 			:= usbssp-plat.o gadget-ring.o \
 				   gadget.o
+				    gadget-dbg.o
 
 ifneq ($(CONFIG_TRACING),)
 	usbssp-y		+= gadget-trace.o
diff --git a/drivers/usb/usbssp/gadget-dbg.c b/drivers/usb/usbssp/gadget-dbg.c
new file mode 100644
index 000000000000..277617d1a996
--- /dev/null
+++ b/drivers/usb/usbssp/gadget-dbg.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * USBSSP device controller driver
+ *
+ * Copyright (C) 2018 Cadence.
+ *
+ * Author: Pawel Laszczak
+ *
+ * A lot of code based on Linux XHCI driver.
+ * Origin: Copyright (C) 2008 Intel Corp
+ */
+
+#include "gadget.h"
+
+void usbssp_dbg_trace(struct usbssp_udc *usbssp_data,
+		      void (*trace)(struct va_format *),
+		      const char *fmt, ...)
+{
+	struct va_format vaf;
+	va_list args;
+
+	va_start(args, fmt);
+	vaf.fmt = fmt;
+	vaf.va = &args;
+	dev_dbg(usbssp_data->dev, "%pV\n", &vaf);
+	trace(&vaf);
+	va_end(args);
+}
+EXPORT_SYMBOL_GPL(usbssp_dbg_trace);
+
diff --git a/drivers/usb/usbssp/gadget-ext-caps.h b/drivers/usb/usbssp/gadget-ext-caps.h
new file mode 100644
index 000000000000..2bf327046376
--- /dev/null
+++ b/drivers/usb/usbssp/gadget-ext-caps.h
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * USBSSP device controller driver
+ *
+ * Copyright (C) 2018 Cadence.
+ *
+ * Author: Pawel Laszczak
+ *
+ * A lot of code based on Linux XHCI driver.
+ * Origin: Copyright (C) 2008 Intel Corp
+ */
+
+/* Up to 16 ms to halt an DC */
+#define USBSSP_MAX_HALT_USEC		(16*1000)
+
+/* DC not running - set to 1 when run/stop bit is cleared. */
+#define USBSSP_STS_HALT			BIT(0)
+
+/* HCCPARAMS offset from PCI base address */
+#define USBSSP_HCC_PARAMS_OFFSET	0x10
+/* HCCPARAMS contains the first extended capability pointer */
+#define USBSSP_HCC_EXT_CAPS(p)		(((p)>>16)&0xffff)
+
+/* Command and Status registers offset from the Operational Registers address */
+#define USBSSP_CMD_OFFSET		0x00
+#define USBSSP_STS_OFFSET		0x04
+
+/* Capability Register */
+/* bits 7:0 - how long is the Capabilities register */
+#define USBSSP_HC_LENGTH(p)		(((p)>>00)&0x00ff)
+
+/* Extended capability register fields */
+#define USBSSP_EXT_CAPS_ID(p)		(((p)>>0)&0xff)
+#define USBSSP_EXT_CAPS_NEXT(p)		(((p)>>8)&0xff)
+#define	v_EXT_CAPS_VAL(p)		((p)>>16)
+/* Extended capability IDs - ID 0 reserved */
+#define USBSSP_EXT_CAPS_PROTOCOL	2
+
+/* USB 2.0 hardware LMP capability*/
+#define USBSSP_HLC			BIT(19)
+#define USBSSP_BLC			BIT(20)
+
+/* command register values to disable interrupts and halt the DC */
+/* start/stop DC execution - do not write unless DC is halted*/
+#define USBSSP_CMD_RUN			BIT(0)
+/* Event Interrupt Enable - get irq when EINT bit is set in USBSTS register */
+#define USBSSP_CMD_EIE			BIT(2)
+/* Host System Error Interrupt Enable - get irq when HSEIE bit set in USBSTS */
+#define USBSSP_CMD_HSEIE		BIT(3)
+/* Enable Wrap Event - '1' means DC generates an event when MFINDEX wraps. */
+#define USBSSP_CMD_EWE			BIT(10)
+
+#define USBSSP_IRQS	(USBSSP_CMD_EIE | USBSSP_CMD_HSEIE | USBSSP_CMD_EWE)
diff --git a/drivers/usb/usbssp/gadget-if.c b/drivers/usb/usbssp/gadget-if.c
new file mode 100644
index 000000000000..d53e0fb65299
--- /dev/null
+++ b/drivers/usb/usbssp/gadget-if.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * USBSSP device controller driver
+ *
+ * Copyright (C) 2018 Cadence.
+ *
+ * Author: Pawel Laszczak
+ *
+ */
+
+#include <linux/usb/gadget.h>
+#include <linux/usb/composite.h>
+#include "gadget.h"
+
+int usbssp_gadget_init_endpoint(struct usbssp_udc *usbssp_data)
+{
+	/*TODO: it has to be implemented*/
+	return 0;
+}
+
+void usbssp_gadget_free_endpoint(struct usbssp_udc *usbssp_data)
+{
+	/*TODO: it has to be implemented*/
+}
diff --git a/drivers/usb/usbssp/gadget.c b/drivers/usb/usbssp/gadget.c
index 2f60d7dd1fe4..338ec2ec18b1 100644
--- a/drivers/usb/usbssp/gadget.c
+++ b/drivers/usb/usbssp/gadget.c
@@ -23,6 +23,107 @@
 #include "gadget-trace.h"
 #include "gadget.h"
 
+
+/*
+ * usbssp_handshake - spin reading dc until handshake completes or fails
+ * @ptr: address of dc register to be read
+ * @mask: bits to look at in result of read
+ * @done: value of those bits when handshake succeeds
+ * @usec: timeout in microseconds
+ *
+ * Returns negative errno, or zero on success
+ *
+ * Success happens when the "mask" bits have the specified value (hardware
+ * handshake done). There are two failure modes: "usec" have passed (major
+ * hardware flakeout), or the register reads as all-ones (hardware removed).
+ */
+int usbssp_handshake(void __iomem *ptr, u32 mask, u32 done, int usec)
+{
+	u32	result;
+
+	do {
+		result = readl(ptr);
+		if (result == ~(u32)0)	/* card removed */
+			return -ENODEV;
+		result &= mask;
+		if (result == done)
+			return 0;
+		udelay(1);
+		usec--;
+	} while (usec > 0);
+	return -ETIMEDOUT;
+}
+
+/*
+ * Disable interrupts and begin the DC halting process.
+ */
+void usbssp_quiesce(struct usbssp_udc *usbssp_data)
+{
+	u32 halted;
+	u32 cmd;
+	u32 mask;
+
+	mask = ~(u32)(USBSSP_IRQS);
+
+	halted = readl(&usbssp_data->op_regs->status) & STS_HALT;
+	if (!halted)
+		mask &= ~CMD_RUN;
+
+	cmd = readl(&usbssp_data->op_regs->command);
+	cmd &= mask;
+	writel(cmd, &usbssp_data->op_regs->command);
+}
+
+/*
+ * Force DC into halt state.
+ *
+ * Disable any IRQs and clear the run/stop bit.
+ * USBSSP will complete any current and actively pipelined transactions, and
+ * should halt within 16 ms of the run/stop bit being cleared.
+ * Read DC Halted bit in the status register to see when the DC is finished.
+ */
+int usbssp_halt(struct usbssp_udc *usbssp_data)
+{
+	int ret;
+
+	usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_init,
+			"// Halt the USBSSP");
+	usbssp_quiesce(usbssp_data);
+
+	ret = usbssp_handshake(&usbssp_data->op_regs->status,
+		STS_HALT, STS_HALT, USBSSP_MAX_HALT_USEC);
+
+	if (!ret) {
+		dev_warn(usbssp_data->dev, "Device halt failed, %d\n", ret);
+		return ret;
+	}
+
+	usbssp_data->usbssp_state |= USBSSP_STATE_HALTED;
+	usbssp_data->cmd_ring_state = CMD_RING_STATE_STOPPED;
+	return ret;
+}
+
+
+/*
+ * Initialize memory for gadget driver and USBSSP (one-time init).
+ *
+ * Program the PAGESIZE register, initialize the device context array, create
+ * device contexts, set up a command ring segment (or two?), create event
+ * ring (one for now).
+ */
+int usbssp_init(struct usbssp_udc *usbssp_data)
+{
+	int retval = 0;
+
+	spin_lock_init(&usbssp_data->lock);
+	spin_lock_init(&usbssp_data->irq_thread_lock);
+
+	/*TODO: memory initialization*/
+	//retval = usbssp_mem_init(usbssp_data, GFP_KERNEL);
+
+	return retval;
+}
+
 #ifdef CONFIG_PM
 /*
  * Stop DC (not bus-specific)
@@ -50,9 +151,146 @@ int usbssp_resume(struct usbssp_udc *usbssp_data, bool hibernated)
 
 #endif	/* CONFIG_PM */
 
+int usbssp_gen_setup(struct usbssp_udc *usbssp_data)
+{
+	int retval;
+
+	mutex_init(&usbssp_data->mutex);
+
+	usbssp_data->cap_regs = usbssp_data->regs;
+	usbssp_data->op_regs = usbssp_data->regs +
+		HC_LENGTH(readl(&usbssp_data->cap_regs->hc_capbase));
+
+	usbssp_data->run_regs = usbssp_data->regs +
+		(readl(&usbssp_data->cap_regs->run_regs_off) & RTSOFF_MASK);
+	/* Cache read-only capability registers */
+	usbssp_data->hcs_params1 = readl(&usbssp_data->cap_regs->hcs_params1);
+	usbssp_data->hcs_params2 = readl(&usbssp_data->cap_regs->hcs_params2);
+	usbssp_data->hcs_params3 = readl(&usbssp_data->cap_regs->hcs_params3);
+	usbssp_data->hcc_params = readl(&usbssp_data->cap_regs->hc_capbase);
+	usbssp_data->hci_version = HC_VERSION(usbssp_data->hcc_params);
+	usbssp_data->hcc_params = readl(&usbssp_data->cap_regs->hcc_params);
+	usbssp_data->hcc_params2 = readl(&usbssp_data->cap_regs->hcc_params2);
+
+	/* Make sure the Device Controller is halted. */
+	retval = usbssp_halt(usbssp_data);
+	if (retval)
+		return retval;
+
+	dev_dbg(usbssp_data->dev, "Resetting Device Controller\n");
+	/* Reset the internal DC memory state and registers. */
+	/*TODO: add implementation of usbssp_reset function*/
+	//retval = usbssp_reset(usbssp_data);
+	if (retval)
+		return retval;
+	dev_dbg(usbssp_data->dev, "Reset complete\n");
+
+	/* Set dma_mask and coherent_dma_mask to 64-bits,
+	 * if USBSSP supports 64-bit addressing
+	 */
+	if (HCC_64BIT_ADDR(usbssp_data->hcc_params) &&
+	    !dma_set_mask(usbssp_data->dev, DMA_BIT_MASK(64))) {
+		dev_dbg(usbssp_data->dev, "Enabling 64-bit DMA addresses.\n");
+		dma_set_coherent_mask(usbssp_data->dev, DMA_BIT_MASK(64));
+	} else {
+		/*
+		 * This is to avoid error in cases where a 32-bit USB
+		 * controller is used on a 64-bit capable system.
+		 */
+		retval = dma_set_mask(usbssp_data->dev, DMA_BIT_MASK(32));
+		if (retval)
+			return retval;
+		dev_dbg(usbssp_data->dev, "Enabling 32-bit DMA addresses.\n");
+		dma_set_coherent_mask(usbssp_data->dev, DMA_BIT_MASK(32));
+	}
+
+	/* Initialize USBSSP controller data structures. */
+	retval = usbssp_init(usbssp_data);
+	if (retval)
+		return retval;
+
+	dev_info(usbssp_data->dev, "USBSSP params 0x%08x USBSSP version 0x%x\n",
+		usbssp_data->hcc_params, usbssp_data->hci_version);
+
+	return 0;
+}
+
+/*
+ * gadget-if.c file is part of gadget.c file and implements interface
+ * for gadget driver
+ */
+#include "gadget-if.c"
+
 int usbssp_gadget_init(struct usbssp_udc *usbssp_data)
 {
 	int ret;
+
+	/*
+	 * Check the compiler generated sizes of structures that must be laid
+	 * out in specific ways for hardware access.
+	 */
+	BUILD_BUG_ON(sizeof(struct usbssp_doorbell_array) != 2*32/8);
+	BUILD_BUG_ON(sizeof(struct usbssp_slot_ctx) != 8*32/8);
+	BUILD_BUG_ON(sizeof(struct usbssp_ep_ctx) != 8*32/8);
+	/* usbssp_device has eight fields, and also
+	 * embeds one usbssp_slot_ctx and 31 usbssp_ep_ctx
+	 */
+	BUILD_BUG_ON(sizeof(struct usbssp_stream_ctx) != 4*32/8);
+	BUILD_BUG_ON(sizeof(union usbssp_trb) != 4*32/8);
+	BUILD_BUG_ON(sizeof(struct usbssp_erst_entry) != 4*32/8);
+	BUILD_BUG_ON(sizeof(struct usbssp_cap_regs) != 8*32/8);
+	BUILD_BUG_ON(sizeof(struct usbssp_intr_reg) != 8*32/8);
+	/* usbssp_run_regs has eight fields and embeds 128 usbssp_intr_regs */
+	BUILD_BUG_ON(sizeof(struct usbssp_run_regs) != (8+8*128)*32/8);
+
+	/* fill gadget fields */
+	/*TODO: implements usbssp_gadget_ops object*/
+	//usbssp_data->gadget.ops = &usbssp_gadget_ops;
+	usbssp_data->gadget.name = "usbssp-gadget";
+	usbssp_data->gadget.max_speed = USB_SPEED_SUPER_PLUS;
+	usbssp_data->gadget.speed = USB_SPEED_UNKNOWN;
+	usbssp_data->gadget.sg_supported = true;
+	usbssp_data->gadget.lpm_capable = 1;
+
+	usbssp_data->setup_buf = kzalloc(USBSSP_EP0_SETUP_SIZE, GFP_KERNEL);
+	if (!usbssp_data->setup_buf)
+		return -ENOMEM;
+
+	/*USBSSP support not aligned buffer but this option
+	 * improve performance of this controller.
+	 */
+	usbssp_data->gadget.quirk_ep_out_aligned_size = true;
+	ret = usbssp_gen_setup(usbssp_data);
+	if (ret < 0) {
+		dev_err(usbssp_data->dev,
+				"Generic initialization failed with error code%d\n",
+				ret);
+		goto err3;
+	}
+
+	ret = usbssp_gadget_init_endpoint(usbssp_data);
+	if (ret < 0) {
+		dev_err(usbssp_data->dev, "failed to initialize endpoints\n");
+		goto err1;
+	}
+
+	ret = usb_add_gadget_udc(usbssp_data->dev, &usbssp_data->gadget);
+
+	if (ret) {
+		dev_err(usbssp_data->dev, "failed to register udc\n");
+		goto err2;
+	}
+
+	return ret;
+err2:
+	usbssp_gadget_free_endpoint(usbssp_data);
+err1:
+	usbssp_halt(usbssp_data);
+	/*TODO add implementation of usbssp_reset function*/
+	//usbssp_reset(usbssp_data);
+	/*TODO add implementation of freeing memory*/
+	//usbssp_mem_cleanup(usbssp_data);
+err3:
 	return ret;
 }
 
@@ -60,5 +298,9 @@ int usbssp_gadget_exit(struct usbssp_udc *usbssp_data)
 {
 	int ret = 0;
 
+	usb_del_gadget_udc(&usbssp_data->gadget);
+	usbssp_gadget_free_endpoint(usbssp_data);
+	/*TODO: add usbssp_stop implementation*/
+	//usbssp_stop(usbssp_data);
 	return ret;
 }
diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h
index 55e20795d900..5d8918f8da84 100644
--- a/drivers/usb/usbssp/gadget.h
+++ b/drivers/usb/usbssp/gadget.h
@@ -12,8 +12,10 @@
 #ifndef __LINUX_USBSSP_GADGET_H
 #define __LINUX_USBSSP_GADGET_H
 
+#include <linux/irq.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/usb/gadget.h>
+#include "gadget-ext-caps.h"
 
 /* Max number slots - only 1 is allowed */
 #define DEV_MAX_SLOTS		1
@@ -1676,7 +1678,18 @@ static inline void usbssp_write_64(struct usbssp_udc *usbssp_data,
 	lo_hi_writeq(val, regs);
 }
 
+/* USBSSP memory management */
+void usbssp_dbg_trace(struct usbssp_udc *usbssp_data,
+		void (*trace)(struct va_format *),
+		const char *fmt, ...);
 /* USBSSP Device controller glue */
+void usbssp_bottom_irq(struct work_struct *work);
+int usbssp_init(struct usbssp_udc *usbssp_data);
+void usbssp_stop(struct usbssp_udc *usbssp_data);
+int usbssp_handshake(void __iomem *ptr, u32 mask, u32 done, int usec);
+void usbssp_quiesce(struct usbssp_udc *usbssp_data);
+extern int usbssp_reset(struct usbssp_udc *usbssp_data);
+
 int usbssp_suspend(struct usbssp_udc *usbssp_data, bool do_wakeup);
 int usbssp_resume(struct usbssp_udc *usbssp_data, bool hibernated);
 
@@ -1689,6 +1702,8 @@ dma_addr_t usbssp_trb_virt_to_dma(struct usbssp_segment *seg,
 /* USBSSP gadget interface*/
 int usbssp_gadget_init(struct usbssp_udc *usbssp_data);
 int usbssp_gadget_exit(struct usbssp_udc *usbssp_data);
+void usbssp_gadget_free_endpoint(struct usbssp_udc *usbssp_data);
+int usbssp_gadget_init_endpoint(struct usbssp_udc *usbssp_data);
 
 static inline char *usbssp_slot_state_string(u32 state)
 {

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [05/31] usb: usbssp: Added first part of initialization sequence.
@ 2018-08-03 10:17 Roger Quadros
  0 siblings, 0 replies; 10+ messages in thread
From: Roger Quadros @ 2018-08-03 10:17 UTC (permalink / raw)
  To: Pawel Laszczak
  Cc: Greg Kroah-Hartman, linux-usb, Felipe Balbi, linux-kernel,
	ltyrala, adouglas

Hi,

On 19/07/18 20:57, Pawel Laszczak wrote:
> Patch adds some initialization function. The initialization sequence
> is quite complicated and this patch implements it only partially.
> Initialization will be completed in next few patches.
> 
> Patch introduce three new files:
> 1. gadget-dbg.c - file contains functions used for debugging purpose.
> 2. gadget-ext-caps.h - holds macro definition related to
> 		       Extended Capabilities
> 3. gadget-if - file implements stuff related to upper layer
> 	(e.g usb_ep_ops, usb_gadget_ops interface).
> 
> Signed-off-by: Pawel Laszczak <pawell@cadence.com>
> ---
>  drivers/usb/usbssp/Makefile          |   1 +
>  drivers/usb/usbssp/gadget-dbg.c      |  30 ++++
>  drivers/usb/usbssp/gadget-ext-caps.h |  53 ++++++
>  drivers/usb/usbssp/gadget-if.c       |  24 +++
>  drivers/usb/usbssp/gadget.c          | 242 +++++++++++++++++++++++++++
>  drivers/usb/usbssp/gadget.h          |  15 ++
>  6 files changed, 365 insertions(+)
>  create mode 100644 drivers/usb/usbssp/gadget-dbg.c
>  create mode 100644 drivers/usb/usbssp/gadget-ext-caps.h
>  create mode 100644 drivers/usb/usbssp/gadget-if.c
> 
> diff --git a/drivers/usb/usbssp/Makefile b/drivers/usb/usbssp/Makefile
> index d85f15afb51c..0606f3c63cd0 100644
> --- a/drivers/usb/usbssp/Makefile
> +++ b/drivers/usb/usbssp/Makefile
> @@ -5,6 +5,7 @@ CFLAGS_gadget-trace.o := -I$(src)
>  obj-$(CONFIG_USB_USBSSP_GADGET) += usbssp.o
>  usbssp-y 			:= usbssp-plat.o gadget-ring.o \
>  				   gadget.o
> +				    gadget-dbg.o
>  
>  ifneq ($(CONFIG_TRACING),)
>  	usbssp-y		+= gadget-trace.o
> diff --git a/drivers/usb/usbssp/gadget-dbg.c b/drivers/usb/usbssp/gadget-dbg.c
> new file mode 100644
> index 000000000000..277617d1a996
> --- /dev/null
> +++ b/drivers/usb/usbssp/gadget-dbg.c
> @@ -0,0 +1,30 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * USBSSP device controller driver
> + *
> + * Copyright (C) 2018 Cadence.
> + *
> + * Author: Pawel Laszczak
> + *
> + * A lot of code based on Linux XHCI driver.
> + * Origin: Copyright (C) 2008 Intel Corp
> + */
> +
> +#include "gadget.h"
> +
> +void usbssp_dbg_trace(struct usbssp_udc *usbssp_data,
> +		      void (*trace)(struct va_format *),
> +		      const char *fmt, ...)
> +{
> +	struct va_format vaf;
> +	va_list args;
> +
> +	va_start(args, fmt);
> +	vaf.fmt = fmt;
> +	vaf.va = &args;
> +	dev_dbg(usbssp_data->dev, "%pV\n", &vaf);

dev_dbg will mess up with timings to be useful.
Why not just use one of the trace events you defined in gadget-trace.h?

> +	trace(&vaf);
> +	va_end(args);
> +}
> +EXPORT_SYMBOL_GPL(usbssp_dbg_trace);
> +
> diff --git a/drivers/usb/usbssp/gadget-ext-caps.h b/drivers/usb/usbssp/gadget-ext-caps.h
> new file mode 100644
> index 000000000000..2bf327046376
> --- /dev/null
> +++ b/drivers/usb/usbssp/gadget-ext-caps.h
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * USBSSP device controller driver
> + *
> + * Copyright (C) 2018 Cadence.
> + *
> + * Author: Pawel Laszczak
> + *
> + * A lot of code based on Linux XHCI driver.
> + * Origin: Copyright (C) 2008 Intel Corp
> + */
> +
> +/* Up to 16 ms to halt an DC */
> +#define USBSSP_MAX_HALT_USEC		(16*1000)
> +
> +/* DC not running - set to 1 when run/stop bit is cleared. */
> +#define USBSSP_STS_HALT			BIT(0)
> +
> +/* HCCPARAMS offset from PCI base address */
> +#define USBSSP_HCC_PARAMS_OFFSET	0x10
> +/* HCCPARAMS contains the first extended capability pointer */
> +#define USBSSP_HCC_EXT_CAPS(p)		(((p)>>16)&0xffff)
> +
> +/* Command and Status registers offset from the Operational Registers address */
> +#define USBSSP_CMD_OFFSET		0x00
> +#define USBSSP_STS_OFFSET		0x04
> +
> +/* Capability Register */
> +/* bits 7:0 - how long is the Capabilities register */
> +#define USBSSP_HC_LENGTH(p)		(((p)>>00)&0x00ff)
> +
> +/* Extended capability register fields */
> +#define USBSSP_EXT_CAPS_ID(p)		(((p)>>0)&0xff)
> +#define USBSSP_EXT_CAPS_NEXT(p)		(((p)>>8)&0xff)
> +#define	v_EXT_CAPS_VAL(p)		((p)>>16)
> +/* Extended capability IDs - ID 0 reserved */
> +#define USBSSP_EXT_CAPS_PROTOCOL	2
> +
> +/* USB 2.0 hardware LMP capability*/
> +#define USBSSP_HLC			BIT(19)
> +#define USBSSP_BLC			BIT(20)
> +
> +/* command register values to disable interrupts and halt the DC */
> +/* start/stop DC execution - do not write unless DC is halted*/
> +#define USBSSP_CMD_RUN			BIT(0)
> +/* Event Interrupt Enable - get irq when EINT bit is set in USBSTS register */
> +#define USBSSP_CMD_EIE			BIT(2)
> +/* Host System Error Interrupt Enable - get irq when HSEIE bit set in USBSTS */
> +#define USBSSP_CMD_HSEIE		BIT(3)
> +/* Enable Wrap Event - '1' means DC generates an event when MFINDEX wraps. */
> +#define USBSSP_CMD_EWE			BIT(10)
> +
> +#define USBSSP_IRQS	(USBSSP_CMD_EIE | USBSSP_CMD_HSEIE | USBSSP_CMD_EWE)
> diff --git a/drivers/usb/usbssp/gadget-if.c b/drivers/usb/usbssp/gadget-if.c
> new file mode 100644
> index 000000000000..d53e0fb65299
> --- /dev/null
> +++ b/drivers/usb/usbssp/gadget-if.c
> @@ -0,0 +1,24 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * USBSSP device controller driver
> + *
> + * Copyright (C) 2018 Cadence.
> + *
> + * Author: Pawel Laszczak
> + *
> + */
> +
> +#include <linux/usb/gadget.h>
> +#include <linux/usb/composite.h>
> +#include "gadget.h"
> +
> +int usbssp_gadget_init_endpoint(struct usbssp_udc *usbssp_data)
> +{
> +	/*TODO: it has to be implemented*/
> +	return 0;
> +}
> +
> +void usbssp_gadget_free_endpoint(struct usbssp_udc *usbssp_data)
> +{
> +	/*TODO: it has to be implemented*/
> +}
> diff --git a/drivers/usb/usbssp/gadget.c b/drivers/usb/usbssp/gadget.c
> index 2f60d7dd1fe4..338ec2ec18b1 100644
> --- a/drivers/usb/usbssp/gadget.c
> +++ b/drivers/usb/usbssp/gadget.c
> @@ -23,6 +23,107 @@
>  #include "gadget-trace.h"
>  #include "gadget.h"
>  
> +
> +/*

/**

> + * usbssp_handshake - spin reading dc until handshake completes or fails
> + * @ptr: address of dc register to be read
> + * @mask: bits to look at in result of read
> + * @done: value of those bits when handshake succeeds
> + * @usec: timeout in microseconds
> + *
> + * Returns negative errno, or zero on success
> + *
> + * Success happens when the "mask" bits have the specified value (hardware
> + * handshake done). There are two failure modes: "usec" have passed (major
> + * hardware flakeout), or the register reads as all-ones (hardware removed).
> + */
> +int usbssp_handshake(void __iomem *ptr, u32 mask, u32 done, int usec)
> +{
> +	u32	result;
> +
> +	do {
> +		result = readl(ptr);
> +		if (result == ~(u32)0)	/* card removed */
> +			return -ENODEV;
> +		result &= mask;
> +		if (result == done)
> +			return 0;
> +		udelay(1);
> +		usec--;
> +	} while (usec > 0);
> +	return -ETIMEDOUT;
> +}
> +
> +/*
> + * Disable interrupts and begin the DC halting process.
> + */
> +void usbssp_quiesce(struct usbssp_udc *usbssp_data)
> +{
> +	u32 halted;
> +	u32 cmd;
> +	u32 mask;
> +
> +	mask = ~(u32)(USBSSP_IRQS);
> +
> +	halted = readl(&usbssp_data->op_regs->status) & STS_HALT;
> +	if (!halted)
> +		mask &= ~CMD_RUN;
> +
> +	cmd = readl(&usbssp_data->op_regs->command);
> +	cmd &= mask;
> +	writel(cmd, &usbssp_data->op_regs->command);
> +}
> +
> +/*
> + * Force DC into halt state.
> + *
> + * Disable any IRQs and clear the run/stop bit.
> + * USBSSP will complete any current and actively pipelined transactions, and
> + * should halt within 16 ms of the run/stop bit being cleared.
> + * Read DC Halted bit in the status register to see when the DC is finished.
> + */
> +int usbssp_halt(struct usbssp_udc *usbssp_data)
> +{
> +	int ret;
> +
> +	usbssp_dbg_trace(usbssp_data, trace_usbssp_dbg_init,
> +			"// Halt the USBSSP");
> +	usbssp_quiesce(usbssp_data);
> +
> +	ret = usbssp_handshake(&usbssp_data->op_regs->status,
> +		STS_HALT, STS_HALT, USBSSP_MAX_HALT_USEC);
> +
> +	if (!ret) {
> +		dev_warn(usbssp_data->dev, "Device halt failed, %d\n", ret);
> +		return ret;
> +	}
> +
> +	usbssp_data->usbssp_state |= USBSSP_STATE_HALTED;
> +	usbssp_data->cmd_ring_state = CMD_RING_STATE_STOPPED;
> +	return ret;
> +}
> +
> +
> +/*
> + * Initialize memory for gadget driver and USBSSP (one-time init).
> + *
> + * Program the PAGESIZE register, initialize the device context array, create
> + * device contexts, set up a command ring segment (or two?), create event
> + * ring (one for now).
> + */
> +int usbssp_init(struct usbssp_udc *usbssp_data)
> +{
> +	int retval = 0;
> +
> +	spin_lock_init(&usbssp_data->lock);
> +	spin_lock_init(&usbssp_data->irq_thread_lock);
> +
> +	/*TODO: memory initialization*/
> +	//retval = usbssp_mem_init(usbssp_data, GFP_KERNEL);
> +
> +	return retval;
> +}
> +
>  #ifdef CONFIG_PM
>  /*
>   * Stop DC (not bus-specific)
> @@ -50,9 +151,146 @@ int usbssp_resume(struct usbssp_udc *usbssp_data, bool hibernated)
>  
>  #endif	/* CONFIG_PM */
>  
> +int usbssp_gen_setup(struct usbssp_udc *usbssp_data)
> +{
> +	int retval;
> +
> +	mutex_init(&usbssp_data->mutex);
> +
> +	usbssp_data->cap_regs = usbssp_data->regs;
> +	usbssp_data->op_regs = usbssp_data->regs +
> +		HC_LENGTH(readl(&usbssp_data->cap_regs->hc_capbase));
> +
> +	usbssp_data->run_regs = usbssp_data->regs +
> +		(readl(&usbssp_data->cap_regs->run_regs_off) & RTSOFF_MASK);
> +	/* Cache read-only capability registers */
> +	usbssp_data->hcs_params1 = readl(&usbssp_data->cap_regs->hcs_params1);
> +	usbssp_data->hcs_params2 = readl(&usbssp_data->cap_regs->hcs_params2);
> +	usbssp_data->hcs_params3 = readl(&usbssp_data->cap_regs->hcs_params3);
> +	usbssp_data->hcc_params = readl(&usbssp_data->cap_regs->hc_capbase);
> +	usbssp_data->hci_version = HC_VERSION(usbssp_data->hcc_params);
> +	usbssp_data->hcc_params = readl(&usbssp_data->cap_regs->hcc_params);
> +	usbssp_data->hcc_params2 = readl(&usbssp_data->cap_regs->hcc_params2);
> +
> +	/* Make sure the Device Controller is halted. */
> +	retval = usbssp_halt(usbssp_data);
> +	if (retval)
> +		return retval;
> +
> +	dev_dbg(usbssp_data->dev, "Resetting Device Controller\n");

do you really need all these dev_dbg prints? You should just fit them to one
of the trace event classes that you already have or add a new one if needed.

> +	/* Reset the internal DC memory state and registers. */
> +	/*TODO: add implementation of usbssp_reset function*/
> +	//retval = usbssp_reset(usbssp_data);
> +	if (retval)
> +		return retval;
> +	dev_dbg(usbssp_data->dev, "Reset complete\n");
> +
> +	/* Set dma_mask and coherent_dma_mask to 64-bits,
> +	 * if USBSSP supports 64-bit addressing
> +	 */
> +	if (HCC_64BIT_ADDR(usbssp_data->hcc_params) &&
> +	    !dma_set_mask(usbssp_data->dev, DMA_BIT_MASK(64))) {
> +		dev_dbg(usbssp_data->dev, "Enabling 64-bit DMA addresses.\n");
> +		dma_set_coherent_mask(usbssp_data->dev, DMA_BIT_MASK(64));
> +	} else {
> +		/*
> +		 * This is to avoid error in cases where a 32-bit USB
> +		 * controller is used on a 64-bit capable system.
> +		 */
> +		retval = dma_set_mask(usbssp_data->dev, DMA_BIT_MASK(32));
> +		if (retval)
> +			return retval;
> +		dev_dbg(usbssp_data->dev, "Enabling 32-bit DMA addresses.\n");
> +		dma_set_coherent_mask(usbssp_data->dev, DMA_BIT_MASK(32));
> +	}
> +
> +	/* Initialize USBSSP controller data structures. */
> +	retval = usbssp_init(usbssp_data);
> +	if (retval)
> +		return retval;
> +
> +	dev_info(usbssp_data->dev, "USBSSP params 0x%08x USBSSP version 0x%x\n",
> +		usbssp_data->hcc_params, usbssp_data->hci_version);
> +
> +	return 0;
> +}
> +
> +/*
> + * gadget-if.c file is part of gadget.c file and implements interface
> + * for gadget driver
> + */
> +#include "gadget-if.c"
> +

All includes should be together at the beginning of the file.

>  int usbssp_gadget_init(struct usbssp_udc *usbssp_data)
>  {
>  	int ret;
> +
> +	/*
> +	 * Check the compiler generated sizes of structures that must be laid
> +	 * out in specific ways for hardware access.
> +	 */
> +	BUILD_BUG_ON(sizeof(struct usbssp_doorbell_array) != 2*32/8);
> +	BUILD_BUG_ON(sizeof(struct usbssp_slot_ctx) != 8*32/8);
> +	BUILD_BUG_ON(sizeof(struct usbssp_ep_ctx) != 8*32/8);
> +	/* usbssp_device has eight fields, and also
> +	 * embeds one usbssp_slot_ctx and 31 usbssp_ep_ctx
> +	 */
> +	BUILD_BUG_ON(sizeof(struct usbssp_stream_ctx) != 4*32/8);
> +	BUILD_BUG_ON(sizeof(union usbssp_trb) != 4*32/8);
> +	BUILD_BUG_ON(sizeof(struct usbssp_erst_entry) != 4*32/8);
> +	BUILD_BUG_ON(sizeof(struct usbssp_cap_regs) != 8*32/8);
> +	BUILD_BUG_ON(sizeof(struct usbssp_intr_reg) != 8*32/8);
> +	/* usbssp_run_regs has eight fields and embeds 128 usbssp_intr_regs */
> +	BUILD_BUG_ON(sizeof(struct usbssp_run_regs) != (8+8*128)*32/8);
> +
> +	/* fill gadget fields */
> +	/*TODO: implements usbssp_gadget_ops object*/
> +	//usbssp_data->gadget.ops = &usbssp_gadget_ops;
> +	usbssp_data->gadget.name = "usbssp-gadget";
> +	usbssp_data->gadget.max_speed = USB_SPEED_SUPER_PLUS;
> +	usbssp_data->gadget.speed = USB_SPEED_UNKNOWN;
> +	usbssp_data->gadget.sg_supported = true;
> +	usbssp_data->gadget.lpm_capable = 1;
> +
> +	usbssp_data->setup_buf = kzalloc(USBSSP_EP0_SETUP_SIZE, GFP_KERNEL);
> +	if (!usbssp_data->setup_buf)
> +		return -ENOMEM;
> +
> +	/*USBSSP support not aligned buffer but this option
> +	 * improve performance of this controller.
> +	 */

Multi-line comment formatting. Checkpach should complain.

> +	usbssp_data->gadget.quirk_ep_out_aligned_size = true;
> +	ret = usbssp_gen_setup(usbssp_data);
> +	if (ret < 0) {
> +		dev_err(usbssp_data->dev,
> +				"Generic initialization failed with error code%d\n",
> +				ret);
> +		goto err3;
> +	}
> +
> +	ret = usbssp_gadget_init_endpoint(usbssp_data);
> +	if (ret < 0) {
> +		dev_err(usbssp_data->dev, "failed to initialize endpoints\n");
> +		goto err1;
> +	}
> +
> +	ret = usb_add_gadget_udc(usbssp_data->dev, &usbssp_data->gadget);
> +
> +	if (ret) {
> +		dev_err(usbssp_data->dev, "failed to register udc\n");
> +		goto err2;
> +	}
> +
> +	return ret;
> +err2:
> +	usbssp_gadget_free_endpoint(usbssp_data);
> +err1:
> +	usbssp_halt(usbssp_data);
> +	/*TODO add implementation of usbssp_reset function*/
> +	//usbssp_reset(usbssp_data);
> +	/*TODO add implementation of freeing memory*/
> +	//usbssp_mem_cleanup(usbssp_data);
> +err3:
>  	return ret;
>  }
>  
> @@ -60,5 +298,9 @@ int usbssp_gadget_exit(struct usbssp_udc *usbssp_data)
>  {
>  	int ret = 0;
>  
> +	usb_del_gadget_udc(&usbssp_data->gadget);
> +	usbssp_gadget_free_endpoint(usbssp_data);
> +	/*TODO: add usbssp_stop implementation*/
> +	//usbssp_stop(usbssp_data);
>  	return ret;
>  }
> diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h
> index 55e20795d900..5d8918f8da84 100644
> --- a/drivers/usb/usbssp/gadget.h
> +++ b/drivers/usb/usbssp/gadget.h
> @@ -12,8 +12,10 @@
>  #ifndef __LINUX_USBSSP_GADGET_H
>  #define __LINUX_USBSSP_GADGET_H
>  
> +#include <linux/irq.h>
>  #include <linux/io-64-nonatomic-lo-hi.h>
>  #include <linux/usb/gadget.h>
> +#include "gadget-ext-caps.h"
>  
>  /* Max number slots - only 1 is allowed */
>  #define DEV_MAX_SLOTS		1
> @@ -1676,7 +1678,18 @@ static inline void usbssp_write_64(struct usbssp_udc *usbssp_data,
>  	lo_hi_writeq(val, regs);
>  }
>  
> +/* USBSSP memory management */
> +void usbssp_dbg_trace(struct usbssp_udc *usbssp_data,
> +		void (*trace)(struct va_format *),
> +		const char *fmt, ...);

what has this function to do with memory management?

>  /* USBSSP Device controller glue */
> +void usbssp_bottom_irq(struct work_struct *work);

usbssp_bottom_irq() wasn't defined in this patch.

> +int usbssp_init(struct usbssp_udc *usbssp_data);
> +void usbssp_stop(struct usbssp_udc *usbssp_data);
> +int usbssp_handshake(void __iomem *ptr, u32 mask, u32 done, int usec);
> +void usbssp_quiesce(struct usbssp_udc *usbssp_data);
> +extern int usbssp_reset(struct usbssp_udc *usbssp_data);
> +
>  int usbssp_suspend(struct usbssp_udc *usbssp_data, bool do_wakeup);
>  int usbssp_resume(struct usbssp_udc *usbssp_data, bool hibernated);
>  
> @@ -1689,6 +1702,8 @@ dma_addr_t usbssp_trb_virt_to_dma(struct usbssp_segment *seg,
>  /* USBSSP gadget interface*/
>  int usbssp_gadget_init(struct usbssp_udc *usbssp_data);
>  int usbssp_gadget_exit(struct usbssp_udc *usbssp_data);
> +void usbssp_gadget_free_endpoint(struct usbssp_udc *usbssp_data);
> +int usbssp_gadget_init_endpoint(struct usbssp_udc *usbssp_data);
>  
>  static inline char *usbssp_slot_state_string(u32 state)
>  {
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [05/31] usb: usbssp: Added first part of initialization sequence.
@ 2018-08-06  8:57 Pawel Laszczak
  0 siblings, 0 replies; 10+ messages in thread
From: Pawel Laszczak @ 2018-08-06  8:57 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Greg Kroah-Hartman, linux-usb@vger.kernel.org, Felipe Balbi,
	linux-kernel@vger.kernel.org, Lukasz Tyrala, Alan Douglas

SGksDQo+IA0KPiBIaSwNCj4gDQo+IE9uIDE5LzA3LzE4IDIwOjU3LCBQYXdlbCBMYXN6Y3phayB3
cm90ZToNCj4gPiBQYXRjaCBhZGRzIHNvbWUgaW5pdGlhbGl6YXRpb24gZnVuY3Rpb24uIFRoZSBp
bml0aWFsaXphdGlvbiBzZXF1ZW5jZQ0KPiA+IGlzIHF1aXRlIGNvbXBsaWNhdGVkIGFuZCB0aGlz
IHBhdGNoIGltcGxlbWVudHMgaXQgb25seSBwYXJ0aWFsbHkuDQo+ID4gSW5pdGlhbGl6YXRpb24g
d2lsbCBiZSBjb21wbGV0ZWQgaW4gbmV4dCBmZXcgcGF0Y2hlcy4NCj4gPg0KPiA+IFBhdGNoIGlu
dHJvZHVjZSB0aHJlZSBuZXcgZmlsZXM6DQo+ID4gMS4gZ2FkZ2V0LWRiZy5jIC0gZmlsZSBjb250
YWlucyBmdW5jdGlvbnMgdXNlZCBmb3IgZGVidWdnaW5nIHB1cnBvc2UuDQo+ID4gMi4gZ2FkZ2V0
LWV4dC1jYXBzLmggLSBob2xkcyBtYWNybyBkZWZpbml0aW9uIHJlbGF0ZWQgdG8NCj4gPiAJCSAg
ICAgICBFeHRlbmRlZCBDYXBhYmlsaXRpZXMNCj4gPiAzLiBnYWRnZXQtaWYgLSBmaWxlIGltcGxl
bWVudHMgc3R1ZmYgcmVsYXRlZCB0byB1cHBlciBsYXllcg0KPiA+IAkoZS5nIHVzYl9lcF9vcHMs
IHVzYl9nYWRnZXRfb3BzIGludGVyZmFjZSkuDQo+ID4NCj4gPiBTaWduZWQtb2ZmLWJ5OiBQYXdl
bCBMYXN6Y3phayA8cGF3ZWxsQGNhZGVuY2UuY29tPg0KPiA+IC0tLQ0KPiA+ICBkcml2ZXJzL3Vz
Yi91c2Jzc3AvTWFrZWZpbGUgICAgICAgICAgfCAgIDEgKw0KPiA+ICBkcml2ZXJzL3VzYi91c2Jz
c3AvZ2FkZ2V0LWRiZy5jICAgICAgfCAgMzAgKysrKw0KPiA+ICBkcml2ZXJzL3VzYi91c2Jzc3Av
Z2FkZ2V0LWV4dC1jYXBzLmggfCAgNTMgKysrKysrDQo+ID4gIGRyaXZlcnMvdXNiL3VzYnNzcC9n
YWRnZXQtaWYuYyAgICAgICB8ICAyNCArKysNCj4gPiAgZHJpdmVycy91c2IvdXNic3NwL2dhZGdl
dC5jICAgICAgICAgIHwgMjQyICsrKysrKysrKysrKysrKysrKysrKysrKysrKw0KPiA+ICBkcml2
ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LmggICAgICAgICAgfCAgMTUgKysNCj4gPiAgNiBmaWxlcyBj
aGFuZ2VkLCAzNjUgaW5zZXJ0aW9ucygrKQ0KPiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVy
cy91c2IvdXNic3NwL2dhZGdldC1kYmcuYw0KPiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVy
cy91c2IvdXNic3NwL2dhZGdldC1leHQtY2Fwcy5oDQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBk
cml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LWlmLmMNCj4gPg0KPiA+IGRpZmYgLS1naXQgYS9kcml2
ZXJzL3VzYi91c2Jzc3AvTWFrZWZpbGUgYi9kcml2ZXJzL3VzYi91c2Jzc3AvTWFrZWZpbGUNCj4g
PiBpbmRleCBkODVmMTVhZmI1MWMuLjA2MDZmM2M2M2NkMCAxMDA2NDQNCj4gPiAtLS0gYS9kcml2
ZXJzL3VzYi91c2Jzc3AvTWFrZWZpbGUNCj4gPiArKysgYi9kcml2ZXJzL3VzYi91c2Jzc3AvTWFr
ZWZpbGUNCj4gPiBAQCAtNSw2ICs1LDcgQEAgQ0ZMQUdTX2dhZGdldC10cmFjZS5vIDo9IC1JJChz
cmMpDQo+ID4gIG9iai0kKENPTkZJR19VU0JfVVNCU1NQX0dBREdFVCkgKz0gdXNic3NwLm8NCj4g
PiAgdXNic3NwLXkgCQkJOj0gdXNic3NwLXBsYXQubyBnYWRnZXQtcmluZy5vIFwNCj4gPiAgCQkJ
CSAgIGdhZGdldC5vDQo+ID4gKwkJCQkgICAgZ2FkZ2V0LWRiZy5vDQo+ID4NCj4gPiAgaWZuZXEg
KCQoQ09ORklHX1RSQUNJTkcpLCkNCj4gPiAgCXVzYnNzcC15CQkrPSBnYWRnZXQtdHJhY2Uubw0K
PiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LWRiZy5jIGIvZHJpdmVy
cy91c2IvdXNic3NwL2dhZGdldC1kYmcuYw0KPiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ID4g
aW5kZXggMDAwMDAwMDAwMDAwLi4yNzc2MTdkMWE5OTYNCj4gPiAtLS0gL2Rldi9udWxsDQo+ID4g
KysrIGIvZHJpdmVycy91c2IvdXNic3NwL2dhZGdldC1kYmcuYw0KPiA+IEBAIC0wLDAgKzEsMzAg
QEANCj4gPiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjANCj4gPiArLyoNCj4g
PiArICogVVNCU1NQIGRldmljZSBjb250cm9sbGVyIGRyaXZlcg0KPiA+ICsgKg0KPiA+ICsgKiBD
b3B5cmlnaHQgKEMpIDIwMTggQ2FkZW5jZS4NCj4gPiArICoNCj4gPiArICogQXV0aG9yOiBQYXdl
bCBMYXN6Y3phaw0KPiA+ICsgKg0KPiA+ICsgKiBBIGxvdCBvZiBjb2RlIGJhc2VkIG9uIExpbnV4
IFhIQ0kgZHJpdmVyLg0KPiA+ICsgKiBPcmlnaW46IENvcHlyaWdodCAoQykgMjAwOCBJbnRlbCBD
b3JwDQo+ID4gKyAqLw0KPiA+ICsNCj4gPiArI2luY2x1ZGUgImdhZGdldC5oIg0KPiA+ICsNCj4g
PiArdm9pZCB1c2Jzc3BfZGJnX3RyYWNlKHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwN
Cj4gPiArCQkgICAgICB2b2lkICgqdHJhY2UpKHN0cnVjdCB2YV9mb3JtYXQgKiksDQo+ID4gKwkJ
ICAgICAgY29uc3QgY2hhciAqZm10LCAuLi4pDQo+ID4gK3sNCj4gPiArCXN0cnVjdCB2YV9mb3Jt
YXQgdmFmOw0KPiA+ICsJdmFfbGlzdCBhcmdzOw0KPiA+ICsNCj4gPiArCXZhX3N0YXJ0KGFyZ3Ms
IGZtdCk7DQo+ID4gKwl2YWYuZm10ID0gZm10Ow0KPiA+ICsJdmFmLnZhID0gJmFyZ3M7DQo+ID4g
KwlkZXZfZGJnKHVzYnNzcF9kYXRhLT5kZXYsICIlcFZcbiIsICZ2YWYpOw0KPiANCj4gZGV2X2Ri
ZyB3aWxsIG1lc3MgdXAgd2l0aCB0aW1pbmdzIHRvIGJlIHVzZWZ1bC4NCj4gV2h5IG5vdCBqdXN0
IHVzZSBvbmUgb2YgdGhlIHRyYWNlIGV2ZW50cyB5b3UgZGVmaW5lZCBpbiBnYWRnZXQtdHJhY2Uu
aD8NCg0KRnVuY3Rpb24gaXMgZXF1aXZhbGVudCBvZiB4aGNpX2RiZ190cmFjZSBmcm9tIFhIQ0kg
ZHJpdmVyLg0KSXQgaXMgYSBmdW5jdGlvbiBvZiBnZW5lcmFsIHVzZS4gDQpUaGUgcHJvYmxlbSB3
aXRoIHRyYWNlIGlzIHRoYXQgdHJhY2UgbG9nIGlzIGRlbGV0ZWQgYWZ0ZXIgcmVib290aW5nIHN5
c3RlbS4gDQpVc2luZyB0cmFjZSBsb2cgaXMgcHJvYmxlbWF0aWMgZHVyaW5nIGRldmVsb3Bpbmcg
YW5kIGRlYnVnZ2luZyBkcml2ZXIuIA0KRG8geW91IGtub3cgd2hldGhlciAgdHJhY2UgbG9nIGlz
IHNhdmVkIGFueXdoZXJlIG9uIGRpc2sgPyAgDQoNCj4gPiArCXRyYWNlKCZ2YWYpOw0KPiA+ICsJ
dmFfZW5kKGFyZ3MpOw0KPiA+ICt9DQo+ID4gK0VYUE9SVF9TWU1CT0xfR1BMKHVzYnNzcF9kYmdf
dHJhY2UpOw0KPiA+ICsNCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvdXNic3NwL2dhZGdl
dC1leHQtY2Fwcy5oIGIvZHJpdmVycy91c2IvdXNic3NwL2dhZGdldC1leHQtY2Fwcy5oDQo+ID4g
bmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4gPiBpbmRleCAwMDAwMDAwMDAwMDAuLjJiZjMyNzA0NjM3
Ng0KPiA+IC0tLSAvZGV2L251bGwNCj4gPiArKysgYi9kcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0
LWV4dC1jYXBzLmgNCj4gPiBAQCAtMCwwICsxLDUzIEBADQo+ID4gKy8vIFNQRFgtTGljZW5zZS1J
ZGVudGlmaWVyOiBHUEwtMi4wDQo+ID4gKy8qDQo+ID4gKyAqIFVTQlNTUCBkZXZpY2UgY29udHJv
bGxlciBkcml2ZXINCj4gPiArICoNCj4gPiArICogQ29weXJpZ2h0IChDKSAyMDE4IENhZGVuY2Uu
DQo+ID4gKyAqDQo+ID4gKyAqIEF1dGhvcjogUGF3ZWwgTGFzemN6YWsNCj4gPiArICoNCj4gPiAr
ICogQSBsb3Qgb2YgY29kZSBiYXNlZCBvbiBMaW51eCBYSENJIGRyaXZlci4NCj4gPiArICogT3Jp
Z2luOiBDb3B5cmlnaHQgKEMpIDIwMDggSW50ZWwgQ29ycA0KPiA+ICsgKi8NCj4gPiArDQo+ID4g
Ky8qIFVwIHRvIDE2IG1zIHRvIGhhbHQgYW4gREMgKi8NCj4gPiArI2RlZmluZSBVU0JTU1BfTUFY
X0hBTFRfVVNFQwkJKDE2KjEwMDApDQo+ID4gKw0KPiA+ICsvKiBEQyBub3QgcnVubmluZyAtIHNl
dCB0byAxIHdoZW4gcnVuL3N0b3AgYml0IGlzIGNsZWFyZWQuICovDQo+ID4gKyNkZWZpbmUgVVNC
U1NQX1NUU19IQUxUCQkJQklUKDApDQo+ID4gKw0KPiA+ICsvKiBIQ0NQQVJBTVMgb2Zmc2V0IGZy
b20gUENJIGJhc2UgYWRkcmVzcyAqLw0KPiA+ICsjZGVmaW5lIFVTQlNTUF9IQ0NfUEFSQU1TX09G
RlNFVAkweDEwDQo+ID4gKy8qIEhDQ1BBUkFNUyBjb250YWlucyB0aGUgZmlyc3QgZXh0ZW5kZWQg
Y2FwYWJpbGl0eSBwb2ludGVyICovDQo+ID4gKyNkZWZpbmUgVVNCU1NQX0hDQ19FWFRfQ0FQUyhw
KQkJKCgocCk+PjE2KSYweGZmZmYpDQo+ID4gKw0KPiA+ICsvKiBDb21tYW5kIGFuZCBTdGF0dXMg
cmVnaXN0ZXJzIG9mZnNldCBmcm9tIHRoZSBPcGVyYXRpb25hbCBSZWdpc3RlcnMgYWRkcmVzcyAq
Lw0KPiA+ICsjZGVmaW5lIFVTQlNTUF9DTURfT0ZGU0VUCQkweDAwDQo+ID4gKyNkZWZpbmUgVVNC
U1NQX1NUU19PRkZTRVQJCTB4MDQNCj4gPiArDQo+ID4gKy8qIENhcGFiaWxpdHkgUmVnaXN0ZXIg
Ki8NCj4gPiArLyogYml0cyA3OjAgLSBob3cgbG9uZyBpcyB0aGUgQ2FwYWJpbGl0aWVzIHJlZ2lz
dGVyICovDQo+ID4gKyNkZWZpbmUgVVNCU1NQX0hDX0xFTkdUSChwKQkJKCgocCk+PjAwKSYweDAw
ZmYpDQo+ID4gKw0KPiA+ICsvKiBFeHRlbmRlZCBjYXBhYmlsaXR5IHJlZ2lzdGVyIGZpZWxkcyAq
Lw0KPiA+ICsjZGVmaW5lIFVTQlNTUF9FWFRfQ0FQU19JRChwKQkJKCgocCk+PjApJjB4ZmYpDQo+
ID4gKyNkZWZpbmUgVVNCU1NQX0VYVF9DQVBTX05FWFQocCkJCSgoKHApPj44KSYweGZmKQ0KPiA+
ICsjZGVmaW5lCXZfRVhUX0NBUFNfVkFMKHApCQkoKHApPj4xNikNCj4gPiArLyogRXh0ZW5kZWQg
Y2FwYWJpbGl0eSBJRHMgLSBJRCAwIHJlc2VydmVkICovDQo+ID4gKyNkZWZpbmUgVVNCU1NQX0VY
VF9DQVBTX1BST1RPQ09MCTINCj4gPiArDQo+ID4gKy8qIFVTQiAyLjAgaGFyZHdhcmUgTE1QIGNh
cGFiaWxpdHkqLw0KPiA+ICsjZGVmaW5lIFVTQlNTUF9ITEMJCQlCSVQoMTkpDQo+ID4gKyNkZWZp
bmUgVVNCU1NQX0JMQwkJCUJJVCgyMCkNCj4gPiArDQo+ID4gKy8qIGNvbW1hbmQgcmVnaXN0ZXIg
dmFsdWVzIHRvIGRpc2FibGUgaW50ZXJydXB0cyBhbmQgaGFsdCB0aGUgREMgKi8NCj4gPiArLyog
c3RhcnQvc3RvcCBEQyBleGVjdXRpb24gLSBkbyBub3Qgd3JpdGUgdW5sZXNzIERDIGlzIGhhbHRl
ZCovDQo+ID4gKyNkZWZpbmUgVVNCU1NQX0NNRF9SVU4JCQlCSVQoMCkNCj4gPiArLyogRXZlbnQg
SW50ZXJydXB0IEVuYWJsZSAtIGdldCBpcnEgd2hlbiBFSU5UIGJpdCBpcyBzZXQgaW4gVVNCU1RT
IHJlZ2lzdGVyICovDQo+ID4gKyNkZWZpbmUgVVNCU1NQX0NNRF9FSUUJCQlCSVQoMikNCj4gPiAr
LyogSG9zdCBTeXN0ZW0gRXJyb3IgSW50ZXJydXB0IEVuYWJsZSAtIGdldCBpcnEgd2hlbiBIU0VJ
RSBiaXQgc2V0IGluIFVTQlNUUyAqLw0KPiA+ICsjZGVmaW5lIFVTQlNTUF9DTURfSFNFSUUJCUJJ
VCgzKQ0KPiA+ICsvKiBFbmFibGUgV3JhcCBFdmVudCAtICcxJyBtZWFucyBEQyBnZW5lcmF0ZXMg
YW4gZXZlbnQgd2hlbiBNRklOREVYIHdyYXBzLiAqLw0KPiA+ICsjZGVmaW5lIFVTQlNTUF9DTURf
RVdFCQkJQklUKDEwKQ0KPiA+ICsNCj4gPiArI2RlZmluZSBVU0JTU1BfSVJRUwkoVVNCU1NQX0NN
RF9FSUUgfCBVU0JTU1BfQ01EX0hTRUlFIHwgVVNCU1NQX0NNRF9FV0UpDQo+ID4gZGlmZiAtLWdp
dCBhL2RyaXZlcnMvdXNiL3VzYnNzcC9nYWRnZXQtaWYuYyBiL2RyaXZlcnMvdXNiL3VzYnNzcC9n
YWRnZXQtaWYuYw0KPiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ID4gaW5kZXggMDAwMDAwMDAw
MDAwLi5kNTNlMGZiNjUyOTkNCj4gPiAtLS0gL2Rldi9udWxsDQo+ID4gKysrIGIvZHJpdmVycy91
c2IvdXNic3NwL2dhZGdldC1pZi5jDQo+ID4gQEAgLTAsMCArMSwyNCBAQA0KPiA+ICsvLyBTUERY
LUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMA0KPiA+ICsvKg0KPiA+ICsgKiBVU0JTU1AgZGV2
aWNlIGNvbnRyb2xsZXIgZHJpdmVyDQo+ID4gKyAqDQo+ID4gKyAqIENvcHlyaWdodCAoQykgMjAx
OCBDYWRlbmNlLg0KPiA+ICsgKg0KPiA+ICsgKiBBdXRob3I6IFBhd2VsIExhc3pjemFrDQo+ID4g
KyAqDQo+ID4gKyAqLw0KPiA+ICsNCj4gPiArI2luY2x1ZGUgPGxpbnV4L3VzYi9nYWRnZXQuaD4N
Cj4gPiArI2luY2x1ZGUgPGxpbnV4L3VzYi9jb21wb3NpdGUuaD4NCj4gPiArI2luY2x1ZGUgImdh
ZGdldC5oIg0KPiA+ICsNCj4gPiAraW50IHVzYnNzcF9nYWRnZXRfaW5pdF9lbmRwb2ludChzdHJ1
Y3QgdXNic3NwX3VkYyAqdXNic3NwX2RhdGEpDQo+ID4gK3sNCj4gPiArCS8qVE9ETzogaXQgaGFz
IHRvIGJlIGltcGxlbWVudGVkKi8NCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+
ICt2b2lkIHVzYnNzcF9nYWRnZXRfZnJlZV9lbmRwb2ludChzdHJ1Y3QgdXNic3NwX3VkYyAqdXNi
c3NwX2RhdGEpDQo+ID4gK3sNCj4gPiArCS8qVE9ETzogaXQgaGFzIHRvIGJlIGltcGxlbWVudGVk
Ki8NCj4gPiArfQ0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LmMg
Yi9kcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LmMNCj4gPiBpbmRleCAyZjYwZDdkZDFmZTQuLjMz
OGVjMmVjMThiMSAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LmMN
Cj4gPiArKysgYi9kcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LmMNCj4gPiBAQCAtMjMsNiArMjMs
MTA3IEBADQo+ID4gICNpbmNsdWRlICJnYWRnZXQtdHJhY2UuaCINCj4gPiAgI2luY2x1ZGUgImdh
ZGdldC5oIg0KPiA+DQo+ID4gKw0KPiA+ICsvKg0KPiANCj4gLyoqDQo+IA0KPiA+ICsgKiB1c2Jz
c3BfaGFuZHNoYWtlIC0gc3BpbiByZWFkaW5nIGRjIHVudGlsIGhhbmRzaGFrZSBjb21wbGV0ZXMg
b3IgZmFpbHMNCj4gPiArICogQHB0cjogYWRkcmVzcyBvZiBkYyByZWdpc3RlciB0byBiZSByZWFk
DQo+ID4gKyAqIEBtYXNrOiBiaXRzIHRvIGxvb2sgYXQgaW4gcmVzdWx0IG9mIHJlYWQNCj4gPiAr
ICogQGRvbmU6IHZhbHVlIG9mIHRob3NlIGJpdHMgd2hlbiBoYW5kc2hha2Ugc3VjY2VlZHMNCj4g
PiArICogQHVzZWM6IHRpbWVvdXQgaW4gbWljcm9zZWNvbmRzDQo+ID4gKyAqDQo+ID4gKyAqIFJl
dHVybnMgbmVnYXRpdmUgZXJybm8sIG9yIHplcm8gb24gc3VjY2Vzcw0KPiA+ICsgKg0KPiA+ICsg
KiBTdWNjZXNzIGhhcHBlbnMgd2hlbiB0aGUgIm1hc2siIGJpdHMgaGF2ZSB0aGUgc3BlY2lmaWVk
IHZhbHVlIChoYXJkd2FyZQ0KPiA+ICsgKiBoYW5kc2hha2UgZG9uZSkuIFRoZXJlIGFyZSB0d28g
ZmFpbHVyZSBtb2RlczogInVzZWMiIGhhdmUgcGFzc2VkIChtYWpvcg0KPiA+ICsgKiBoYXJkd2Fy
ZSBmbGFrZW91dCksIG9yIHRoZSByZWdpc3RlciByZWFkcyBhcyBhbGwtb25lcyAoaGFyZHdhcmUg
cmVtb3ZlZCkuDQo+ID4gKyAqLw0KPiA+ICtpbnQgdXNic3NwX2hhbmRzaGFrZSh2b2lkIF9faW9t
ZW0gKnB0ciwgdTMyIG1hc2ssIHUzMiBkb25lLCBpbnQgdXNlYykNCj4gPiArew0KPiA+ICsJdTMy
CXJlc3VsdDsNCj4gPiArDQo+ID4gKwlkbyB7DQo+ID4gKwkJcmVzdWx0ID0gcmVhZGwocHRyKTsN
Cj4gPiArCQlpZiAocmVzdWx0ID09IH4odTMyKTApCS8qIGNhcmQgcmVtb3ZlZCAqLw0KPiA+ICsJ
CQlyZXR1cm4gLUVOT0RFVjsNCj4gPiArCQlyZXN1bHQgJj0gbWFzazsNCj4gPiArCQlpZiAocmVz
dWx0ID09IGRvbmUpDQo+ID4gKwkJCXJldHVybiAwOw0KPiA+ICsJCXVkZWxheSgxKTsNCj4gPiAr
CQl1c2VjLS07DQo+ID4gKwl9IHdoaWxlICh1c2VjID4gMCk7DQo+ID4gKwlyZXR1cm4gLUVUSU1F
RE9VVDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyoNCj4gPiArICogRGlzYWJsZSBpbnRlcnJ1cHRz
IGFuZCBiZWdpbiB0aGUgREMgaGFsdGluZyBwcm9jZXNzLg0KPiA+ICsgKi8NCj4gPiArdm9pZCB1
c2Jzc3BfcXVpZXNjZShzdHJ1Y3QgdXNic3NwX3VkYyAqdXNic3NwX2RhdGEpDQo+ID4gK3sNCj4g
PiArCXUzMiBoYWx0ZWQ7DQo+ID4gKwl1MzIgY21kOw0KPiA+ICsJdTMyIG1hc2s7DQo+ID4gKw0K
PiA+ICsJbWFzayA9IH4odTMyKShVU0JTU1BfSVJRUyk7DQo+ID4gKw0KPiA+ICsJaGFsdGVkID0g
cmVhZGwoJnVzYnNzcF9kYXRhLT5vcF9yZWdzLT5zdGF0dXMpICYgU1RTX0hBTFQ7DQo+ID4gKwlp
ZiAoIWhhbHRlZCkNCj4gPiArCQltYXNrICY9IH5DTURfUlVOOw0KPiA+ICsNCj4gPiArCWNtZCA9
IHJlYWRsKCZ1c2Jzc3BfZGF0YS0+b3BfcmVncy0+Y29tbWFuZCk7DQo+ID4gKwljbWQgJj0gbWFz
azsNCj4gPiArCXdyaXRlbChjbWQsICZ1c2Jzc3BfZGF0YS0+b3BfcmVncy0+Y29tbWFuZCk7DQo+
ID4gK30NCj4gPiArDQo+ID4gKy8qDQo+ID4gKyAqIEZvcmNlIERDIGludG8gaGFsdCBzdGF0ZS4N
Cj4gPiArICoNCj4gPiArICogRGlzYWJsZSBhbnkgSVJRcyBhbmQgY2xlYXIgdGhlIHJ1bi9zdG9w
IGJpdC4NCj4gPiArICogVVNCU1NQIHdpbGwgY29tcGxldGUgYW55IGN1cnJlbnQgYW5kIGFjdGl2
ZWx5IHBpcGVsaW5lZCB0cmFuc2FjdGlvbnMsIGFuZA0KPiA+ICsgKiBzaG91bGQgaGFsdCB3aXRo
aW4gMTYgbXMgb2YgdGhlIHJ1bi9zdG9wIGJpdCBiZWluZyBjbGVhcmVkLg0KPiA+ICsgKiBSZWFk
IERDIEhhbHRlZCBiaXQgaW4gdGhlIHN0YXR1cyByZWdpc3RlciB0byBzZWUgd2hlbiB0aGUgREMg
aXMgZmluaXNoZWQuDQo+ID4gKyAqLw0KPiA+ICtpbnQgdXNic3NwX2hhbHQoc3RydWN0IHVzYnNz
cF91ZGMgKnVzYnNzcF9kYXRhKQ0KPiA+ICt7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+ICsNCj4gPiAr
CXVzYnNzcF9kYmdfdHJhY2UodXNic3NwX2RhdGEsIHRyYWNlX3VzYnNzcF9kYmdfaW5pdCwNCj4g
PiArCQkJIi8vIEhhbHQgdGhlIFVTQlNTUCIpOw0KPiA+ICsJdXNic3NwX3F1aWVzY2UodXNic3Nw
X2RhdGEpOw0KPiA+ICsNCj4gPiArCXJldCA9IHVzYnNzcF9oYW5kc2hha2UoJnVzYnNzcF9kYXRh
LT5vcF9yZWdzLT5zdGF0dXMsDQo+ID4gKwkJU1RTX0hBTFQsIFNUU19IQUxULCBVU0JTU1BfTUFY
X0hBTFRfVVNFQyk7DQo+ID4gKw0KPiA+ICsJaWYgKCFyZXQpIHsNCj4gPiArCQlkZXZfd2Fybih1
c2Jzc3BfZGF0YS0+ZGV2LCAiRGV2aWNlIGhhbHQgZmFpbGVkLCAlZFxuIiwgcmV0KTsNCj4gPiAr
CQlyZXR1cm4gcmV0Ow0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXVzYnNzcF9kYXRhLT51c2Jzc3Bf
c3RhdGUgfD0gVVNCU1NQX1NUQVRFX0hBTFRFRDsNCj4gPiArCXVzYnNzcF9kYXRhLT5jbWRfcmlu
Z19zdGF0ZSA9IENNRF9SSU5HX1NUQVRFX1NUT1BQRUQ7DQo+ID4gKwlyZXR1cm4gcmV0Ow0KPiA+
ICt9DQo+ID4gKw0KPiA+ICsNCj4gPiArLyoNCj4gPiArICogSW5pdGlhbGl6ZSBtZW1vcnkgZm9y
IGdhZGdldCBkcml2ZXIgYW5kIFVTQlNTUCAob25lLXRpbWUgaW5pdCkuDQo+ID4gKyAqDQo+ID4g
KyAqIFByb2dyYW0gdGhlIFBBR0VTSVpFIHJlZ2lzdGVyLCBpbml0aWFsaXplIHRoZSBkZXZpY2Ug
Y29udGV4dCBhcnJheSwgY3JlYXRlDQo+ID4gKyAqIGRldmljZSBjb250ZXh0cywgc2V0IHVwIGEg
Y29tbWFuZCByaW5nIHNlZ21lbnQgKG9yIHR3bz8pLCBjcmVhdGUgZXZlbnQNCj4gPiArICogcmlu
ZyAob25lIGZvciBub3cpLg0KPiA+ICsgKi8NCj4gPiAraW50IHVzYnNzcF9pbml0KHN0cnVjdCB1
c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSkNCj4gPiArew0KPiA+ICsJaW50IHJldHZhbCA9IDA7DQo+
ID4gKw0KPiA+ICsJc3Bpbl9sb2NrX2luaXQoJnVzYnNzcF9kYXRhLT5sb2NrKTsNCj4gPiArCXNw
aW5fbG9ja19pbml0KCZ1c2Jzc3BfZGF0YS0+aXJxX3RocmVhZF9sb2NrKTsNCj4gPiArDQo+ID4g
KwkvKlRPRE86IG1lbW9yeSBpbml0aWFsaXphdGlvbiovDQo+ID4gKwkvL3JldHZhbCA9IHVzYnNz
cF9tZW1faW5pdCh1c2Jzc3BfZGF0YSwgR0ZQX0tFUk5FTCk7DQo+ID4gKw0KPiA+ICsJcmV0dXJu
IHJldHZhbDsNCj4gPiArfQ0KPiA+ICsNCj4gPiAgI2lmZGVmIENPTkZJR19QTQ0KPiA+ICAvKg0K
PiA+ICAgKiBTdG9wIERDIChub3QgYnVzLXNwZWNpZmljKQ0KPiA+IEBAIC01MCw5ICsxNTEsMTQ2
IEBAIGludCB1c2Jzc3BfcmVzdW1lKHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwgYm9v
bCBoaWJlcm5hdGVkKQ0KPiA+DQo+ID4gICNlbmRpZgkvKiBDT05GSUdfUE0gKi8NCj4gPg0KPiA+
ICtpbnQgdXNic3NwX2dlbl9zZXR1cChzdHJ1Y3QgdXNic3NwX3VkYyAqdXNic3NwX2RhdGEpDQo+
ID4gK3sNCj4gPiArCWludCByZXR2YWw7DQo+ID4gKw0KPiA+ICsJbXV0ZXhfaW5pdCgmdXNic3Nw
X2RhdGEtPm11dGV4KTsNCj4gPiArDQo+ID4gKwl1c2Jzc3BfZGF0YS0+Y2FwX3JlZ3MgPSB1c2Jz
c3BfZGF0YS0+cmVnczsNCj4gPiArCXVzYnNzcF9kYXRhLT5vcF9yZWdzID0gdXNic3NwX2RhdGEt
PnJlZ3MgKw0KPiA+ICsJCUhDX0xFTkdUSChyZWFkbCgmdXNic3NwX2RhdGEtPmNhcF9yZWdzLT5o
Y19jYXBiYXNlKSk7DQo+ID4gKw0KPiA+ICsJdXNic3NwX2RhdGEtPnJ1bl9yZWdzID0gdXNic3Nw
X2RhdGEtPnJlZ3MgKw0KPiA+ICsJCShyZWFkbCgmdXNic3NwX2RhdGEtPmNhcF9yZWdzLT5ydW5f
cmVnc19vZmYpICYgUlRTT0ZGX01BU0spOw0KPiA+ICsJLyogQ2FjaGUgcmVhZC1vbmx5IGNhcGFi
aWxpdHkgcmVnaXN0ZXJzICovDQo+ID4gKwl1c2Jzc3BfZGF0YS0+aGNzX3BhcmFtczEgPSByZWFk
bCgmdXNic3NwX2RhdGEtPmNhcF9yZWdzLT5oY3NfcGFyYW1zMSk7DQo+ID4gKwl1c2Jzc3BfZGF0
YS0+aGNzX3BhcmFtczIgPSByZWFkbCgmdXNic3NwX2RhdGEtPmNhcF9yZWdzLT5oY3NfcGFyYW1z
Mik7DQo+ID4gKwl1c2Jzc3BfZGF0YS0+aGNzX3BhcmFtczMgPSByZWFkbCgmdXNic3NwX2RhdGEt
PmNhcF9yZWdzLT5oY3NfcGFyYW1zMyk7DQo+ID4gKwl1c2Jzc3BfZGF0YS0+aGNjX3BhcmFtcyA9
IHJlYWRsKCZ1c2Jzc3BfZGF0YS0+Y2FwX3JlZ3MtPmhjX2NhcGJhc2UpOw0KPiA+ICsJdXNic3Nw
X2RhdGEtPmhjaV92ZXJzaW9uID0gSENfVkVSU0lPTih1c2Jzc3BfZGF0YS0+aGNjX3BhcmFtcyk7
DQo+ID4gKwl1c2Jzc3BfZGF0YS0+aGNjX3BhcmFtcyA9IHJlYWRsKCZ1c2Jzc3BfZGF0YS0+Y2Fw
X3JlZ3MtPmhjY19wYXJhbXMpOw0KPiA+ICsJdXNic3NwX2RhdGEtPmhjY19wYXJhbXMyID0gcmVh
ZGwoJnVzYnNzcF9kYXRhLT5jYXBfcmVncy0+aGNjX3BhcmFtczIpOw0KPiA+ICsNCj4gPiArCS8q
IE1ha2Ugc3VyZSB0aGUgRGV2aWNlIENvbnRyb2xsZXIgaXMgaGFsdGVkLiAqLw0KPiA+ICsJcmV0
dmFsID0gdXNic3NwX2hhbHQodXNic3NwX2RhdGEpOw0KPiA+ICsJaWYgKHJldHZhbCkNCj4gPiAr
CQlyZXR1cm4gcmV0dmFsOw0KPiA+ICsNCj4gPiArCWRldl9kYmcodXNic3NwX2RhdGEtPmRldiwg
IlJlc2V0dGluZyBEZXZpY2UgQ29udHJvbGxlclxuIik7DQo+IA0KPiBkbyB5b3UgcmVhbGx5IG5l
ZWQgYWxsIHRoZXNlIGRldl9kYmcgcHJpbnRzPyBZb3Ugc2hvdWxkIGp1c3QgZml0IHRoZW0gdG8g
b25lDQo+IG9mIHRoZSB0cmFjZSBldmVudCBjbGFzc2VzIHRoYXQgeW91IGFscmVhZHkgaGF2ZSBv
ciBhZGQgYSBuZXcgb25lIGlmIG5lZWRlZC4NCg0KVGhleSBhcmUgbm90IHZlcnkgdXNlZnVsIC4g
SSBkZWxldGVkIHRoZW0uDQogDQo+ID4gKwkvKiBSZXNldCB0aGUgaW50ZXJuYWwgREMgbWVtb3J5
IHN0YXRlIGFuZCByZWdpc3RlcnMuICovDQo+ID4gKwkvKlRPRE86IGFkZCBpbXBsZW1lbnRhdGlv
biBvZiB1c2Jzc3BfcmVzZXQgZnVuY3Rpb24qLw0KPiA+ICsJLy9yZXR2YWwgPSB1c2Jzc3BfcmVz
ZXQodXNic3NwX2RhdGEpOw0KPiA+ICsJaWYgKHJldHZhbCkNCj4gPiArCQlyZXR1cm4gcmV0dmFs
Ow0KPiA+ICsJZGV2X2RiZyh1c2Jzc3BfZGF0YS0+ZGV2LCAiUmVzZXQgY29tcGxldGVcbiIpOw0K
PiA+ICsNCj4gPiArCS8qIFNldCBkbWFfbWFzayBhbmQgY29oZXJlbnRfZG1hX21hc2sgdG8gNjQt
Yml0cywNCj4gPiArCSAqIGlmIFVTQlNTUCBzdXBwb3J0cyA2NC1iaXQgYWRkcmVzc2luZw0KPiA+
ICsJICovDQo+ID4gKwlpZiAoSENDXzY0QklUX0FERFIodXNic3NwX2RhdGEtPmhjY19wYXJhbXMp
ICYmDQo+ID4gKwkgICAgIWRtYV9zZXRfbWFzayh1c2Jzc3BfZGF0YS0+ZGV2LCBETUFfQklUX01B
U0soNjQpKSkgew0KPiA+ICsJCWRldl9kYmcodXNic3NwX2RhdGEtPmRldiwgIkVuYWJsaW5nIDY0
LWJpdCBETUEgYWRkcmVzc2VzLlxuIik7DQo+ID4gKwkJZG1hX3NldF9jb2hlcmVudF9tYXNrKHVz
YnNzcF9kYXRhLT5kZXYsIERNQV9CSVRfTUFTSyg2NCkpOw0KPiA+ICsJfSBlbHNlIHsNCj4gPiAr
CQkvKg0KPiA+ICsJCSAqIFRoaXMgaXMgdG8gYXZvaWQgZXJyb3IgaW4gY2FzZXMgd2hlcmUgYSAz
Mi1iaXQgVVNCDQo+ID4gKwkJICogY29udHJvbGxlciBpcyB1c2VkIG9uIGEgNjQtYml0IGNhcGFi
bGUgc3lzdGVtLg0KPiA+ICsJCSAqLw0KPiA+ICsJCXJldHZhbCA9IGRtYV9zZXRfbWFzayh1c2Jz
c3BfZGF0YS0+ZGV2LCBETUFfQklUX01BU0soMzIpKTsNCj4gPiArCQlpZiAocmV0dmFsKQ0KPiA+
ICsJCQlyZXR1cm4gcmV0dmFsOw0KPiA+ICsJCWRldl9kYmcodXNic3NwX2RhdGEtPmRldiwgIkVu
YWJsaW5nIDMyLWJpdCBETUEgYWRkcmVzc2VzLlxuIik7DQo+ID4gKwkJZG1hX3NldF9jb2hlcmVu
dF9tYXNrKHVzYnNzcF9kYXRhLT5kZXYsIERNQV9CSVRfTUFTSygzMikpOw0KPiA+ICsJfQ0KPiA+
ICsNCj4gPiArCS8qIEluaXRpYWxpemUgVVNCU1NQIGNvbnRyb2xsZXIgZGF0YSBzdHJ1Y3R1cmVz
LiAqLw0KPiA+ICsJcmV0dmFsID0gdXNic3NwX2luaXQodXNic3NwX2RhdGEpOw0KPiA+ICsJaWYg
KHJldHZhbCkNCj4gPiArCQlyZXR1cm4gcmV0dmFsOw0KPiA+ICsNCj4gPiArCWRldl9pbmZvKHVz
YnNzcF9kYXRhLT5kZXYsICJVU0JTU1AgcGFyYW1zIDB4JTA4eCBVU0JTU1AgdmVyc2lvbiAweCV4
XG4iLA0KPiA+ICsJCXVzYnNzcF9kYXRhLT5oY2NfcGFyYW1zLCB1c2Jzc3BfZGF0YS0+aGNpX3Zl
cnNpb24pOw0KPiA+ICsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKg0K
PiA+ICsgKiBnYWRnZXQtaWYuYyBmaWxlIGlzIHBhcnQgb2YgZ2FkZ2V0LmMgZmlsZSBhbmQgaW1w
bGVtZW50cyBpbnRlcmZhY2UNCj4gPiArICogZm9yIGdhZGdldCBkcml2ZXINCj4gPiArICovDQo+
ID4gKyNpbmNsdWRlICJnYWRnZXQtaWYuYyINCj4gPiArDQo+IA0KPiBBbGwgaW5jbHVkZXMgc2hv
dWxkIGJlIHRvZ2V0aGVyIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpbGUuDQoNCkdyZWcgS3Jv
YWNoLUhhcm1hbiB3cm90ZSBhYm91dCBpbmNsdWRpbmcgIC5jIGZpbGVzOiANCiJVZ2gsIEkga25v
dyBVU0IgaGNkIGRyaXZlcnMgbG92ZSB0byBpbmNsdWRlIC5jIGZpbGVzIGluIHRoZSBtaWRkbGUg
b2YNCnRoZW0sIGJ1dCBkbyB3ZSBoYXZlIHRvIGNvbnRpbnVlIHRoYXQgY3JhenkgcHJhY3RpY2Ug
aW4gbmV3ZXIgZHJpdmVycz8NCklzIGl0IHJlYWxseSBuZWNlc3Nhcnk/Ig0KDQpJIGZvcmdvdCB0
byBjaGFuZ2UgdGhpcywgSSB3aWxsIHJlbW92ZSB0aGlzIGFuZCBJIHdpbGwgYWRkIGFsbCBuZWNl
c3NhcnkgZGVjbGFyYXRpb24gdG8gZ2FkZ2V0LmggZmlsZS4NCiANCj4gPiAgaW50IHVzYnNzcF9n
YWRnZXRfaW5pdChzdHJ1Y3QgdXNic3NwX3VkYyAqdXNic3NwX2RhdGEpDQo+ID4gIHsNCj4gPiAg
CWludCByZXQ7DQo+ID4gKw0KPiA+ICsJLyoNCj4gPiArCSAqIENoZWNrIHRoZSBjb21waWxlciBn
ZW5lcmF0ZWQgc2l6ZXMgb2Ygc3RydWN0dXJlcyB0aGF0IG11c3QgYmUgbGFpZA0KPiA+ICsJICog
b3V0IGluIHNwZWNpZmljIHdheXMgZm9yIGhhcmR3YXJlIGFjY2Vzcy4NCj4gPiArCSAqLw0KPiA+
ICsJQlVJTERfQlVHX09OKHNpemVvZihzdHJ1Y3QgdXNic3NwX2Rvb3JiZWxsX2FycmF5KSAhPSAy
KjMyLzgpOw0KPiA+ICsJQlVJTERfQlVHX09OKHNpemVvZihzdHJ1Y3QgdXNic3NwX3Nsb3RfY3R4
KSAhPSA4KjMyLzgpOw0KPiA+ICsJQlVJTERfQlVHX09OKHNpemVvZihzdHJ1Y3QgdXNic3NwX2Vw
X2N0eCkgIT0gOCozMi84KTsNCj4gPiArCS8qIHVzYnNzcF9kZXZpY2UgaGFzIGVpZ2h0IGZpZWxk
cywgYW5kIGFsc28NCj4gPiArCSAqIGVtYmVkcyBvbmUgdXNic3NwX3Nsb3RfY3R4IGFuZCAzMSB1
c2Jzc3BfZXBfY3R4DQo+ID4gKwkgKi8NCj4gPiArCUJVSUxEX0JVR19PTihzaXplb2Yoc3RydWN0
IHVzYnNzcF9zdHJlYW1fY3R4KSAhPSA0KjMyLzgpOw0KPiA+ICsJQlVJTERfQlVHX09OKHNpemVv
Zih1bmlvbiB1c2Jzc3BfdHJiKSAhPSA0KjMyLzgpOw0KPiA+ICsJQlVJTERfQlVHX09OKHNpemVv
ZihzdHJ1Y3QgdXNic3NwX2Vyc3RfZW50cnkpICE9IDQqMzIvOCk7DQo+ID4gKwlCVUlMRF9CVUdf
T04oc2l6ZW9mKHN0cnVjdCB1c2Jzc3BfY2FwX3JlZ3MpICE9IDgqMzIvOCk7DQo+ID4gKwlCVUlM
RF9CVUdfT04oc2l6ZW9mKHN0cnVjdCB1c2Jzc3BfaW50cl9yZWcpICE9IDgqMzIvOCk7DQo+ID4g
KwkvKiB1c2Jzc3BfcnVuX3JlZ3MgaGFzIGVpZ2h0IGZpZWxkcyBhbmQgZW1iZWRzIDEyOCB1c2Jz
c3BfaW50cl9yZWdzICovDQo+ID4gKwlCVUlMRF9CVUdfT04oc2l6ZW9mKHN0cnVjdCB1c2Jzc3Bf
cnVuX3JlZ3MpICE9ICg4KzgqMTI4KSozMi84KTsNCj4gPiArDQo+ID4gKwkvKiBmaWxsIGdhZGdl
dCBmaWVsZHMgKi8NCj4gPiArCS8qVE9ETzogaW1wbGVtZW50cyB1c2Jzc3BfZ2FkZ2V0X29wcyBv
YmplY3QqLw0KPiA+ICsJLy91c2Jzc3BfZGF0YS0+Z2FkZ2V0Lm9wcyA9ICZ1c2Jzc3BfZ2FkZ2V0
X29wczsNCj4gPiArCXVzYnNzcF9kYXRhLT5nYWRnZXQubmFtZSA9ICJ1c2Jzc3AtZ2FkZ2V0IjsN
Cj4gPiArCXVzYnNzcF9kYXRhLT5nYWRnZXQubWF4X3NwZWVkID0gVVNCX1NQRUVEX1NVUEVSX1BM
VVM7DQo+ID4gKwl1c2Jzc3BfZGF0YS0+Z2FkZ2V0LnNwZWVkID0gVVNCX1NQRUVEX1VOS05PV047
DQo+ID4gKwl1c2Jzc3BfZGF0YS0+Z2FkZ2V0LnNnX3N1cHBvcnRlZCA9IHRydWU7DQo+ID4gKwl1
c2Jzc3BfZGF0YS0+Z2FkZ2V0LmxwbV9jYXBhYmxlID0gMTsNCj4gPiArDQo+ID4gKwl1c2Jzc3Bf
ZGF0YS0+c2V0dXBfYnVmID0ga3phbGxvYyhVU0JTU1BfRVAwX1NFVFVQX1NJWkUsIEdGUF9LRVJO
RUwpOw0KPiA+ICsJaWYgKCF1c2Jzc3BfZGF0YS0+c2V0dXBfYnVmKQ0KPiA+ICsJCXJldHVybiAt
RU5PTUVNOw0KPiA+ICsNCj4gPiArCS8qVVNCU1NQIHN1cHBvcnQgbm90IGFsaWduZWQgYnVmZmVy
IGJ1dCB0aGlzIG9wdGlvbg0KPiA+ICsJICogaW1wcm92ZSBwZXJmb3JtYW5jZSBvZiB0aGlzIGNv
bnRyb2xsZXIuDQo+ID4gKwkgKi8NCj4gDQo+IE11bHRpLWxpbmUgY29tbWVudCBmb3JtYXR0aW5n
LiBDaGVja3BhY2ggc2hvdWxkIGNvbXBsYWluLg0KSXQgZG9lc24ndCBjb21wbGFpbiBhYm91dCB0
aGlzIGNhc2UuIEkgZG9uJ3Qga25vdyB3aHkuDQoNCj4gPiArCXVzYnNzcF9kYXRhLT5nYWRnZXQu
cXVpcmtfZXBfb3V0X2FsaWduZWRfc2l6ZSA9IHRydWU7DQo+ID4gKwlyZXQgPSB1c2Jzc3BfZ2Vu
X3NldHVwKHVzYnNzcF9kYXRhKTsNCj4gPiArCWlmIChyZXQgPCAwKSB7DQo+ID4gKwkJZGV2X2Vy
cih1c2Jzc3BfZGF0YS0+ZGV2LA0KPiA+ICsJCQkJIkdlbmVyaWMgaW5pdGlhbGl6YXRpb24gZmFp
bGVkIHdpdGggZXJyb3IgY29kZSVkXG4iLA0KPiA+ICsJCQkJcmV0KTsNCj4gPiArCQlnb3RvIGVy
cjM7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0ID0gdXNic3NwX2dhZGdldF9pbml0X2VuZHBv
aW50KHVzYnNzcF9kYXRhKTsNCj4gPiArCWlmIChyZXQgPCAwKSB7DQo+ID4gKwkJZGV2X2Vycih1
c2Jzc3BfZGF0YS0+ZGV2LCAiZmFpbGVkIHRvIGluaXRpYWxpemUgZW5kcG9pbnRzXG4iKTsNCj4g
PiArCQlnb3RvIGVycjE7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0ID0gdXNiX2FkZF9nYWRn
ZXRfdWRjKHVzYnNzcF9kYXRhLT5kZXYsICZ1c2Jzc3BfZGF0YS0+Z2FkZ2V0KTsNCj4gPiArDQo+
ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJZGV2X2Vycih1c2Jzc3BfZGF0YS0+ZGV2LCAiZmFpbGVk
IHRvIHJlZ2lzdGVyIHVkY1xuIik7DQo+ID4gKwkJZ290byBlcnIyOw0KPiA+ICsJfQ0KPiA+ICsN
Cj4gPiArCXJldHVybiByZXQ7DQo+ID4gK2VycjI6DQo+ID4gKwl1c2Jzc3BfZ2FkZ2V0X2ZyZWVf
ZW5kcG9pbnQodXNic3NwX2RhdGEpOw0KPiA+ICtlcnIxOg0KPiA+ICsJdXNic3NwX2hhbHQodXNi
c3NwX2RhdGEpOw0KPiA+ICsJLypUT0RPIGFkZCBpbXBsZW1lbnRhdGlvbiBvZiB1c2Jzc3BfcmVz
ZXQgZnVuY3Rpb24qLw0KPiA+ICsJLy91c2Jzc3BfcmVzZXQodXNic3NwX2RhdGEpOw0KPiA+ICsJ
LypUT0RPIGFkZCBpbXBsZW1lbnRhdGlvbiBvZiBmcmVlaW5nIG1lbW9yeSovDQo+ID4gKwkvL3Vz
YnNzcF9tZW1fY2xlYW51cCh1c2Jzc3BfZGF0YSk7DQo+ID4gK2VycjM6DQo+ID4gIAlyZXR1cm4g
cmV0Ow0KPiA+ICB9DQo+ID4NCj4gPiBAQCAtNjAsNSArMjk4LDkgQEAgaW50IHVzYnNzcF9nYWRn
ZXRfZXhpdChzdHJ1Y3QgdXNic3NwX3VkYyAqdXNic3NwX2RhdGEpDQo+ID4gIHsNCj4gPiAgCWlu
dCByZXQgPSAwOw0KPiA+DQo+ID4gKwl1c2JfZGVsX2dhZGdldF91ZGMoJnVzYnNzcF9kYXRhLT5n
YWRnZXQpOw0KPiA+ICsJdXNic3NwX2dhZGdldF9mcmVlX2VuZHBvaW50KHVzYnNzcF9kYXRhKTsN
Cj4gPiArCS8qVE9ETzogYWRkIHVzYnNzcF9zdG9wIGltcGxlbWVudGF0aW9uKi8NCj4gPiArCS8v
dXNic3NwX3N0b3AodXNic3NwX2RhdGEpOw0KPiA+ICAJcmV0dXJuIHJldDsNCj4gPiAgfQ0KPiA+
IGRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LmggYi9kcml2ZXJzL3VzYi91
c2Jzc3AvZ2FkZ2V0LmgNCj4gPiBpbmRleCA1NWUyMDc5NWQ5MDAuLjVkODkxOGY4ZGE4NCAxMDA2
NDQNCj4gPiAtLS0gYS9kcml2ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LmgNCj4gPiArKysgYi9kcml2
ZXJzL3VzYi91c2Jzc3AvZ2FkZ2V0LmgNCj4gPiBAQCAtMTIsOCArMTIsMTAgQEANCj4gPiAgI2lm
bmRlZiBfX0xJTlVYX1VTQlNTUF9HQURHRVRfSA0KPiA+ICAjZGVmaW5lIF9fTElOVVhfVVNCU1NQ
X0dBREdFVF9IDQo+ID4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2lycS5oPg0KPiA+ICAjaW5jbHVk
ZSA8bGludXgvaW8tNjQtbm9uYXRvbWljLWxvLWhpLmg+DQo+ID4gICNpbmNsdWRlIDxsaW51eC91
c2IvZ2FkZ2V0Lmg+DQo+ID4gKyNpbmNsdWRlICJnYWRnZXQtZXh0LWNhcHMuaCINCj4gPg0KPiA+
ICAvKiBNYXggbnVtYmVyIHNsb3RzIC0gb25seSAxIGlzIGFsbG93ZWQgKi8NCj4gPiAgI2RlZmlu
ZSBERVZfTUFYX1NMT1RTCQkxDQo+ID4gQEAgLTE2NzYsNyArMTY3OCwxOCBAQCBzdGF0aWMgaW5s
aW5lIHZvaWQgdXNic3NwX3dyaXRlXzY0KHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwN
Cj4gPiAgCWxvX2hpX3dyaXRlcSh2YWwsIHJlZ3MpOw0KPiA+ICB9DQo+ID4NCj4gPiArLyogVVNC
U1NQIG1lbW9yeSBtYW5hZ2VtZW50ICovDQo+ID4gK3ZvaWQgdXNic3NwX2RiZ190cmFjZShzdHJ1
Y3QgdXNic3NwX3VkYyAqdXNic3NwX2RhdGEsDQo+ID4gKwkJdm9pZCAoKnRyYWNlKShzdHJ1Y3Qg
dmFfZm9ybWF0ICopLA0KPiA+ICsJCWNvbnN0IGNoYXIgKmZtdCwgLi4uKTsNCj4gDQo+IHdoYXQg
aGFzIHRoaXMgZnVuY3Rpb24gdG8gZG8gd2l0aCBtZW1vcnkgbWFuYWdlbWVudD8NCj4gDQpOb3Ro
aW5nLCANCg0KPiA+ICAvKiBVU0JTU1AgRGV2aWNlIGNvbnRyb2xsZXIgZ2x1ZSAqLw0KPiA+ICt2
b2lkIHVzYnNzcF9ib3R0b21faXJxKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yayk7DQo+IA0KPiB1
c2Jzc3BfYm90dG9tX2lycSgpIHdhc24ndCBkZWZpbmVkIGluIHRoaXMgcGF0Y2guDQpSZW1vdmVk
IGZyb20gdGhpcyBwYXRjaA0KDQo+ID4gK2ludCB1c2Jzc3BfaW5pdChzdHJ1Y3QgdXNic3NwX3Vk
YyAqdXNic3NwX2RhdGEpOw0KPiA+ICt2b2lkIHVzYnNzcF9zdG9wKHN0cnVjdCB1c2Jzc3BfdWRj
ICp1c2Jzc3BfZGF0YSk7DQo+ID4gK2ludCB1c2Jzc3BfaGFuZHNoYWtlKHZvaWQgX19pb21lbSAq
cHRyLCB1MzIgbWFzaywgdTMyIGRvbmUsIGludCB1c2VjKTsNCj4gPiArdm9pZCB1c2Jzc3BfcXVp
ZXNjZShzdHJ1Y3QgdXNic3NwX3VkYyAqdXNic3NwX2RhdGEpOw0KPiA+ICtleHRlcm4gaW50IHVz
YnNzcF9yZXNldChzdHJ1Y3QgdXNic3NwX3VkYyAqdXNic3NwX2RhdGEpOw0KPiA+ICsNCj4gPiAg
aW50IHVzYnNzcF9zdXNwZW5kKHN0cnVjdCB1c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSwgYm9vbCBk
b193YWtldXApOw0KPiA+ICBpbnQgdXNic3NwX3Jlc3VtZShzdHJ1Y3QgdXNic3NwX3VkYyAqdXNi
c3NwX2RhdGEsIGJvb2wgaGliZXJuYXRlZCk7DQo+ID4NCj4gPiBAQCAtMTY4OSw2ICsxNzAyLDgg
QEAgZG1hX2FkZHJfdCB1c2Jzc3BfdHJiX3ZpcnRfdG9fZG1hKHN0cnVjdCB1c2Jzc3Bfc2VnbWVu
dCAqc2VnLA0KPiA+ICAvKiBVU0JTU1AgZ2FkZ2V0IGludGVyZmFjZSovDQo+ID4gIGludCB1c2Jz
c3BfZ2FkZ2V0X2luaXQoc3RydWN0IHVzYnNzcF91ZGMgKnVzYnNzcF9kYXRhKTsNCj4gPiAgaW50
IHVzYnNzcF9nYWRnZXRfZXhpdChzdHJ1Y3QgdXNic3NwX3VkYyAqdXNic3NwX2RhdGEpOw0KPiA+
ICt2b2lkIHVzYnNzcF9nYWRnZXRfZnJlZV9lbmRwb2ludChzdHJ1Y3QgdXNic3NwX3VkYyAqdXNi
c3NwX2RhdGEpOw0KPiA+ICtpbnQgdXNic3NwX2dhZGdldF9pbml0X2VuZHBvaW50KHN0cnVjdCB1
c2Jzc3BfdWRjICp1c2Jzc3BfZGF0YSk7DQo+ID4NCj4gPiAgc3RhdGljIGlubGluZSBjaGFyICp1
c2Jzc3Bfc2xvdF9zdGF0ZV9zdHJpbmcodTMyIHN0YXRlKQ0KPiA+ICB7DQo+ID4NCj4gDQo+IC0t
DQo+IGNoZWVycywNCj4gLXJvZ2VyDQo+IA0KPiBUZXhhcyBJbnN0cnVtZW50cyBGaW5sYW5kIE95
LCBQb3Jra2FsYW5rYXR1IDIyLCAwMDE4MCBIZWxzaW5raS4NCj4gWS10dW5udXMvQnVzaW5lc3Mg
SUQ6IDA2MTU1MjEtNC4gS290aXBhaWtrYS9Eb21pY2lsZTogSGVsc2lua2kNCg0KdGhhbmtzDQpj
aGVlcnMsDQpQYXdlbA0K
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [05/31] usb: usbssp: Added first part of initialization sequence.
@ 2018-08-06 10:33 Roger Quadros
  0 siblings, 0 replies; 10+ messages in thread
From: Roger Quadros @ 2018-08-06 10:33 UTC (permalink / raw)
  To: Pawel Laszczak
  Cc: Greg Kroah-Hartman, linux-usb@vger.kernel.org, Felipe Balbi,
	linux-kernel@vger.kernel.org, Lukasz Tyrala, Alan Douglas

On 06/08/18 11:57, Pawel Laszczak wrote:
> Hi,
>>
>> Hi,
>>
>> On 19/07/18 20:57, Pawel Laszczak wrote:
>>> Patch adds some initialization function. The initialization sequence
>>> is quite complicated and this patch implements it only partially.
>>> Initialization will be completed in next few patches.
>>>
>>> Patch introduce three new files:
>>> 1. gadget-dbg.c - file contains functions used for debugging purpose.
>>> 2. gadget-ext-caps.h - holds macro definition related to
>>> 		       Extended Capabilities
>>> 3. gadget-if - file implements stuff related to upper layer
>>> 	(e.g usb_ep_ops, usb_gadget_ops interface).
>>>
>>> Signed-off-by: Pawel Laszczak <pawell@cadence.com>
>>> ---
>>>  drivers/usb/usbssp/Makefile          |   1 +
>>>  drivers/usb/usbssp/gadget-dbg.c      |  30 ++++
>>>  drivers/usb/usbssp/gadget-ext-caps.h |  53 ++++++
>>>  drivers/usb/usbssp/gadget-if.c       |  24 +++
>>>  drivers/usb/usbssp/gadget.c          | 242 +++++++++++++++++++++++++++
>>>  drivers/usb/usbssp/gadget.h          |  15 ++
>>>  6 files changed, 365 insertions(+)
>>>  create mode 100644 drivers/usb/usbssp/gadget-dbg.c
>>>  create mode 100644 drivers/usb/usbssp/gadget-ext-caps.h
>>>  create mode 100644 drivers/usb/usbssp/gadget-if.c
>>>
>>> diff --git a/drivers/usb/usbssp/Makefile b/drivers/usb/usbssp/Makefile
>>> index d85f15afb51c..0606f3c63cd0 100644
>>> --- a/drivers/usb/usbssp/Makefile
>>> +++ b/drivers/usb/usbssp/Makefile
>>> @@ -5,6 +5,7 @@ CFLAGS_gadget-trace.o := -I$(src)
>>>  obj-$(CONFIG_USB_USBSSP_GADGET) += usbssp.o
>>>  usbssp-y 			:= usbssp-plat.o gadget-ring.o \
>>>  				   gadget.o
>>> +				    gadget-dbg.o
>>>
>>>  ifneq ($(CONFIG_TRACING),)
>>>  	usbssp-y		+= gadget-trace.o
>>> diff --git a/drivers/usb/usbssp/gadget-dbg.c b/drivers/usb/usbssp/gadget-dbg.c
>>> new file mode 100644
>>> index 000000000000..277617d1a996
>>> --- /dev/null
>>> +++ b/drivers/usb/usbssp/gadget-dbg.c
>>> @@ -0,0 +1,30 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * USBSSP device controller driver
>>> + *
>>> + * Copyright (C) 2018 Cadence.
>>> + *
>>> + * Author: Pawel Laszczak
>>> + *
>>> + * A lot of code based on Linux XHCI driver.
>>> + * Origin: Copyright (C) 2008 Intel Corp
>>> + */
>>> +
>>> +#include "gadget.h"
>>> +
>>> +void usbssp_dbg_trace(struct usbssp_udc *usbssp_data,
>>> +		      void (*trace)(struct va_format *),
>>> +		      const char *fmt, ...)
>>> +{
>>> +	struct va_format vaf;
>>> +	va_list args;
>>> +
>>> +	va_start(args, fmt);
>>> +	vaf.fmt = fmt;
>>> +	vaf.va = &args;
>>> +	dev_dbg(usbssp_data->dev, "%pV\n", &vaf);
>>
>> dev_dbg will mess up with timings to be useful.
>> Why not just use one of the trace events you defined in gadget-trace.h?
> 
> Function is equivalent of xhci_dbg_trace from XHCI driver.
> It is a function of general use. 
> The problem with trace is that trace log is deleted after rebooting system. 
> Using trace log is problematic during developing and debugging driver. 

OK. But I think trace log is more useful for I/O related debugging as it
keeps the timing impact minimal. For things that don't come in the I/O path
you could use dev_dbg().

> Do you know whether  trace log is saved anywhere on disk ?  
> 
I think trace_cmd allows you to record on the disk or even send it over the network.
https://lwn.net/Articles/410200/

>>> +	trace(&vaf);
>>> +	va_end(args);
>>> +}
>>> +EXPORT_SYMBOL_GPL(usbssp_dbg_trace);
>>> +

<snip>

>>>  int usbssp_gadget_init(struct usbssp_udc *usbssp_data)
>>>  {
>>>  	int ret;
>>> +
>>> +	/*
>>> +	 * Check the compiler generated sizes of structures that must be laid
>>> +	 * out in specific ways for hardware access.
>>> +	 */
>>> +	BUILD_BUG_ON(sizeof(struct usbssp_doorbell_array) != 2*32/8);
>>> +	BUILD_BUG_ON(sizeof(struct usbssp_slot_ctx) != 8*32/8);
>>> +	BUILD_BUG_ON(sizeof(struct usbssp_ep_ctx) != 8*32/8);
>>> +	/* usbssp_device has eight fields, and also
>>> +	 * embeds one usbssp_slot_ctx and 31 usbssp_ep_ctx
>>> +	 */
>>> +	BUILD_BUG_ON(sizeof(struct usbssp_stream_ctx) != 4*32/8);
>>> +	BUILD_BUG_ON(sizeof(union usbssp_trb) != 4*32/8);
>>> +	BUILD_BUG_ON(sizeof(struct usbssp_erst_entry) != 4*32/8);
>>> +	BUILD_BUG_ON(sizeof(struct usbssp_cap_regs) != 8*32/8);
>>> +	BUILD_BUG_ON(sizeof(struct usbssp_intr_reg) != 8*32/8);
>>> +	/* usbssp_run_regs has eight fields and embeds 128 usbssp_intr_regs */
>>> +	BUILD_BUG_ON(sizeof(struct usbssp_run_regs) != (8+8*128)*32/8);
>>> +
>>> +	/* fill gadget fields */
>>> +	/*TODO: implements usbssp_gadget_ops object*/
>>> +	//usbssp_data->gadget.ops = &usbssp_gadget_ops;
>>> +	usbssp_data->gadget.name = "usbssp-gadget";
>>> +	usbssp_data->gadget.max_speed = USB_SPEED_SUPER_PLUS;
>>> +	usbssp_data->gadget.speed = USB_SPEED_UNKNOWN;
>>> +	usbssp_data->gadget.sg_supported = true;
>>> +	usbssp_data->gadget.lpm_capable = 1;
>>> +
>>> +	usbssp_data->setup_buf = kzalloc(USBSSP_EP0_SETUP_SIZE, GFP_KERNEL);
>>> +	if (!usbssp_data->setup_buf)
>>> +		return -ENOMEM;
>>> +
>>> +	/*USBSSP support not aligned buffer but this option
>>> +	 * improve performance of this controller.
>>> +	 */
>>
>> Multi-line comment formatting. Checkpach should complain.
> It doesn't complain about this case. I don't know why.
> 

Can you try with --strict option to checkpatch?

>>> +	usbssp_data->gadget.quirk_ep_out_aligned_size = true;
>>> +	ret = usbssp_gen_setup(usbssp_data);
>>> +	if (ret < 0) {
>>> +		dev_err(usbssp_data->dev,
>>> +				"Generic initialization failed with error code%d\n",
>>> +				ret);
>>> +		goto err3;
>>> +	}
>>> +
>>> +	ret = usbssp_gadget_init_endpoint(usbssp_data);
>>> +	if (ret < 0) {
>>> +		dev_err(usbssp_data->dev, "failed to initialize endpoints\n");
>>> +		goto err1;
>>> +	}
>>> +
>>> +	ret = usb_add_gadget_udc(usbssp_data->dev, &usbssp_data->gadget);
>>> +
>>> +	if (ret) {
>>> +		dev_err(usbssp_data->dev, "failed to register udc\n");
>>> +		goto err2;
>>> +	}
>>> +
>>> +	return ret;
>>> +err2:
>>> +	usbssp_gadget_free_endpoint(usbssp_data);
>>> +err1:
>>> +	usbssp_halt(usbssp_data);
>>> +	/*TODO add implementation of usbssp_reset function*/
>>> +	//usbssp_reset(usbssp_data);
>>> +	/*TODO add implementation of freeing memory*/
>>> +	//usbssp_mem_cleanup(usbssp_data);
>>> +err3:
>>>  	return ret;
>>>  }
>>>
>>> @@ -60,5 +298,9 @@ int usbssp_gadget_exit(struct usbssp_udc *usbssp_data)
>>>  {
>>>  	int ret = 0;
>>>
>>> +	usb_del_gadget_udc(&usbssp_data->gadget);
>>> +	usbssp_gadget_free_endpoint(usbssp_data);
>>> +	/*TODO: add usbssp_stop implementation*/
>>> +	//usbssp_stop(usbssp_data);
>>>  	return ret;
>>>  }
>>> diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h
>>> index 55e20795d900..5d8918f8da84 100644
>>> --- a/drivers/usb/usbssp/gadget.h
>>> +++ b/drivers/usb/usbssp/gadget.h
>>> @@ -12,8 +12,10 @@
>>>  #ifndef __LINUX_USBSSP_GADGET_H
>>>  #define __LINUX_USBSSP_GADGET_H
>>>
>>> +#include <linux/irq.h>
>>>  #include <linux/io-64-nonatomic-lo-hi.h>
>>>  #include <linux/usb/gadget.h>
>>> +#include "gadget-ext-caps.h"
>>>
>>>  /* Max number slots - only 1 is allowed */
>>>  #define DEV_MAX_SLOTS		1
>>> @@ -1676,7 +1678,18 @@ static inline void usbssp_write_64(struct usbssp_udc *usbssp_data,
>>>  	lo_hi_writeq(val, regs);
>>>  }
>>>
>>> +/* USBSSP memory management */
>>> +void usbssp_dbg_trace(struct usbssp_udc *usbssp_data,
>>> +		void (*trace)(struct va_format *),
>>> +		const char *fmt, ...);
>>
>> what has this function to do with memory management?
>>
> Nothing, 
> 
>>>  /* USBSSP Device controller glue */
>>> +void usbssp_bottom_irq(struct work_struct *work);
>>
>> usbssp_bottom_irq() wasn't defined in this patch.
> Removed from this patch
> 
>>> +int usbssp_init(struct usbssp_udc *usbssp_data);
>>> +void usbssp_stop(struct usbssp_udc *usbssp_data);
>>> +int usbssp_handshake(void __iomem *ptr, u32 mask, u32 done, int usec);
>>> +void usbssp_quiesce(struct usbssp_udc *usbssp_data);
>>> +extern int usbssp_reset(struct usbssp_udc *usbssp_data);
>>> +
>>>  int usbssp_suspend(struct usbssp_udc *usbssp_data, bool do_wakeup);
>>>  int usbssp_resume(struct usbssp_udc *usbssp_data, bool hibernated);
>>>
>>> @@ -1689,6 +1702,8 @@ dma_addr_t usbssp_trb_virt_to_dma(struct usbssp_segment *seg,
>>>  /* USBSSP gadget interface*/
>>>  int usbssp_gadget_init(struct usbssp_udc *usbssp_data);
>>>  int usbssp_gadget_exit(struct usbssp_udc *usbssp_data);
>>> +void usbssp_gadget_free_endpoint(struct usbssp_udc *usbssp_data);
>>> +int usbssp_gadget_init_endpoint(struct usbssp_udc *usbssp_data);
>>>
>>>  static inline char *usbssp_slot_state_string(u32 state)
>>>  {
>>>
>>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [05/31] usb: usbssp: Added first part of initialization sequence.
@ 2018-08-06 12:03 Pawel Laszczak
  0 siblings, 0 replies; 10+ messages in thread
From: Pawel Laszczak @ 2018-08-06 12:03 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Greg Kroah-Hartman, linux-usb@vger.kernel.org, Felipe Balbi,
	linux-kernel@vger.kernel.org, Lukasz Tyrala, Alan Douglas

Hi,
> > Hi,
> >>
> >> Hi,
> >>
> >> On 19/07/18 20:57, Pawel Laszczak wrote:
> >>> Patch adds some initialization function. The initialization sequence
> >>> is quite complicated and this patch implements it only partially.
> >>> Initialization will be completed in next few patches.
> >>>
> >>> Patch introduce three new files:
> >>> 1. gadget-dbg.c - file contains functions used for debugging purpose.
> >>> 2. gadget-ext-caps.h - holds macro definition related to
> >>> 		       Extended Capabilities
> >>> 3. gadget-if - file implements stuff related to upper layer
> >>> 	(e.g usb_ep_ops, usb_gadget_ops interface).
> >>>
> >>> Signed-off-by: Pawel Laszczak <pawell@cadence.com>
> >>> ---
> >>>  drivers/usb/usbssp/Makefile          |   1 +
> >>>  drivers/usb/usbssp/gadget-dbg.c      |  30 ++++
> >>>  drivers/usb/usbssp/gadget-ext-caps.h |  53 ++++++
> >>>  drivers/usb/usbssp/gadget-if.c       |  24 +++
> >>>  drivers/usb/usbssp/gadget.c          | 242 +++++++++++++++++++++++++++
> >>>  drivers/usb/usbssp/gadget.h          |  15 ++
> >>>  6 files changed, 365 insertions(+)
> >>>  create mode 100644 drivers/usb/usbssp/gadget-dbg.c
> >>>  create mode 100644 drivers/usb/usbssp/gadget-ext-caps.h
> >>>  create mode 100644 drivers/usb/usbssp/gadget-if.c
> >>>
> >>> diff --git a/drivers/usb/usbssp/Makefile b/drivers/usb/usbssp/Makefile
> >>> index d85f15afb51c..0606f3c63cd0 100644
> >>> --- a/drivers/usb/usbssp/Makefile
> >>> +++ b/drivers/usb/usbssp/Makefile
> >>> @@ -5,6 +5,7 @@ CFLAGS_gadget-trace.o := -I$(src)
> >>>  obj-$(CONFIG_USB_USBSSP_GADGET) += usbssp.o
> >>>  usbssp-y 			:= usbssp-plat.o gadget-ring.o \
> >>>  				   gadget.o
> >>> +				    gadget-dbg.o
> >>>
> >>>  ifneq ($(CONFIG_TRACING),)
> >>>  	usbssp-y		+= gadget-trace.o
> >>> diff --git a/drivers/usb/usbssp/gadget-dbg.c b/drivers/usb/usbssp/gadget-dbg.c
> >>> new file mode 100644
> >>> index 000000000000..277617d1a996
> >>> --- /dev/null
> >>> +++ b/drivers/usb/usbssp/gadget-dbg.c
> >>> @@ -0,0 +1,30 @@
> >>> +// SPDX-License-Identifier: GPL-2.0
> >>> +/*
> >>> + * USBSSP device controller driver
> >>> + *
> >>> + * Copyright (C) 2018 Cadence.
> >>> + *
> >>> + * Author: Pawel Laszczak
> >>> + *
> >>> + * A lot of code based on Linux XHCI driver.
> >>> + * Origin: Copyright (C) 2008 Intel Corp
> >>> + */
> >>> +
> >>> +#include "gadget.h"
> >>> +
> >>> +void usbssp_dbg_trace(struct usbssp_udc *usbssp_data,
> >>> +		      void (*trace)(struct va_format *),
> >>> +		      const char *fmt, ...)
> >>> +{
> >>> +	struct va_format vaf;
> >>> +	va_list args;
> >>> +
> >>> +	va_start(args, fmt);
> >>> +	vaf.fmt = fmt;
> >>> +	vaf.va = &args;
> >>> +	dev_dbg(usbssp_data->dev, "%pV\n", &vaf);
> >>
> >> dev_dbg will mess up with timings to be useful.
> >> Why not just use one of the trace events you defined in gadget-trace.h?
> >
> > Function is equivalent of xhci_dbg_trace from XHCI driver.
> > It is a function of general use.
> > The problem with trace is that trace log is deleted after rebooting system.
> > Using trace log is problematic during developing and debugging driver.
> 
> OK. But I think trace log is more useful for I/O related debugging as it
> keeps the timing impact minimal. For things that don't come in the I/O path
> you could use dev_dbg().
> 
> > Do you know whether  trace log is saved anywhere on disk ?
> >
> I think trace_cmd allows you to record on the disk or even send it over the network.
> https://urldefense.proofpoint.com/v2/url?u=https-
> 3A__lwn.net_Articles_410200_&d=DwICaQ&c=aUq983L2pue2FqKFoP6PGHMJQyoJ7kl3s3GZ-_haXqY&r=e1OgxfvkL0qo9XO6fX1gscva-
> w03uSYC1nIyxl89-
> rI&m=6MvsISpCCpIMBnuBegpBOtoNlpzPXgvFMxqIROGhRVw&s=N3v03AhO0AP6HlVTyDvCRQqpJx4kcnqdw5appuOYG6U&e=

Thanks, I will try it.

> 
> >>> +	trace(&vaf);
> >>> +	va_end(args);
> >>> +}
> >>> +EXPORT_SYMBOL_GPL(usbssp_dbg_trace);
> >>> +
> 
> <snip>
> 
> >>>  int usbssp_gadget_init(struct usbssp_udc *usbssp_data)
> >>>  {
> >>>  	int ret;
> >>> +
> >>> +	/*
> >>> +	 * Check the compiler generated sizes of structures that must be laid
> >>> +	 * out in specific ways for hardware access.
> >>> +	 */
> >>> +	BUILD_BUG_ON(sizeof(struct usbssp_doorbell_array) != 2*32/8);
> >>> +	BUILD_BUG_ON(sizeof(struct usbssp_slot_ctx) != 8*32/8);
> >>> +	BUILD_BUG_ON(sizeof(struct usbssp_ep_ctx) != 8*32/8);
> >>> +	/* usbssp_device has eight fields, and also
> >>> +	 * embeds one usbssp_slot_ctx and 31 usbssp_ep_ctx
> >>> +	 */
> >>> +	BUILD_BUG_ON(sizeof(struct usbssp_stream_ctx) != 4*32/8);
> >>> +	BUILD_BUG_ON(sizeof(union usbssp_trb) != 4*32/8);
> >>> +	BUILD_BUG_ON(sizeof(struct usbssp_erst_entry) != 4*32/8);
> >>> +	BUILD_BUG_ON(sizeof(struct usbssp_cap_regs) != 8*32/8);
> >>> +	BUILD_BUG_ON(sizeof(struct usbssp_intr_reg) != 8*32/8);
> >>> +	/* usbssp_run_regs has eight fields and embeds 128 usbssp_intr_regs */
> >>> +	BUILD_BUG_ON(sizeof(struct usbssp_run_regs) != (8+8*128)*32/8);
> >>> +
> >>> +	/* fill gadget fields */
> >>> +	/*TODO: implements usbssp_gadget_ops object*/
> >>> +	//usbssp_data->gadget.ops = &usbssp_gadget_ops;
> >>> +	usbssp_data->gadget.name = "usbssp-gadget";
> >>> +	usbssp_data->gadget.max_speed = USB_SPEED_SUPER_PLUS;
> >>> +	usbssp_data->gadget.speed = USB_SPEED_UNKNOWN;
> >>> +	usbssp_data->gadget.sg_supported = true;
> >>> +	usbssp_data->gadget.lpm_capable = 1;
> >>> +
> >>> +	usbssp_data->setup_buf = kzalloc(USBSSP_EP0_SETUP_SIZE, GFP_KERNEL);
> >>> +	if (!usbssp_data->setup_buf)
> >>> +		return -ENOMEM;
> >>> +
> >>> +	/*USBSSP support not aligned buffer but this option
> >>> +	 * improve performance of this controller.
> >>> +	 */
> >>
> >> Multi-line comment formatting. Checkpach should complain.
> > It doesn't complain about this case. I don't know why.
> >
> 
> Can you try with --strict option to checkpatch?

With -options I see this warning and also many others related 
to "spaces preferred"

I have to check all patches again. 
> 
> >>> +	usbssp_data->gadget.quirk_ep_out_aligned_size = true;
> >>> +	ret = usbssp_gen_setup(usbssp_data);
> >>> +	if (ret < 0) {
> >>> +		dev_err(usbssp_data->dev,
> >>> +				"Generic initialization failed with error code%d\n",
> >>> +				ret);
> >>> +		goto err3;
> >>> +	}
> >>> +
> >>> +	ret = usbssp_gadget_init_endpoint(usbssp_data);
> >>> +	if (ret < 0) {
> >>> +		dev_err(usbssp_data->dev, "failed to initialize endpoints\n");
> >>> +		goto err1;
> >>> +	}
> >>> +
> >>> +	ret = usb_add_gadget_udc(usbssp_data->dev, &usbssp_data->gadget);
> >>> +
> >>> +	if (ret) {
> >>> +		dev_err(usbssp_data->dev, "failed to register udc\n");
> >>> +		goto err2;
> >>> +	}
> >>> +
> >>> +	return ret;
> >>> +err2:
> >>> +	usbssp_gadget_free_endpoint(usbssp_data);
> >>> +err1:
> >>> +	usbssp_halt(usbssp_data);
> >>> +	/*TODO add implementation of usbssp_reset function*/
> >>> +	//usbssp_reset(usbssp_data);
> >>> +	/*TODO add implementation of freeing memory*/
> >>> +	//usbssp_mem_cleanup(usbssp_data);
> >>> +err3:
> >>>  	return ret;
> >>>  }
> >>>
> >>> @@ -60,5 +298,9 @@ int usbssp_gadget_exit(struct usbssp_udc *usbssp_data)
> >>>  {
> >>>  	int ret = 0;
> >>>
> >>> +	usb_del_gadget_udc(&usbssp_data->gadget);
> >>> +	usbssp_gadget_free_endpoint(usbssp_data);
> >>> +	/*TODO: add usbssp_stop implementation*/
> >>> +	//usbssp_stop(usbssp_data);
> >>>  	return ret;
> >>>  }
> >>> diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h
> >>> index 55e20795d900..5d8918f8da84 100644
> >>> --- a/drivers/usb/usbssp/gadget.h
> >>> +++ b/drivers/usb/usbssp/gadget.h
> >>> @@ -12,8 +12,10 @@
> >>>  #ifndef __LINUX_USBSSP_GADGET_H
> >>>  #define __LINUX_USBSSP_GADGET_H
> >>>
> >>> +#include <linux/irq.h>
> >>>  #include <linux/io-64-nonatomic-lo-hi.h>
> >>>  #include <linux/usb/gadget.h>
> >>> +#include "gadget-ext-caps.h"
> >>>
> >>>  /* Max number slots - only 1 is allowed */
> >>>  #define DEV_MAX_SLOTS		1
> >>> @@ -1676,7 +1678,18 @@ static inline void usbssp_write_64(struct usbssp_udc *usbssp_data,
> >>>  	lo_hi_writeq(val, regs);
> >>>  }
> >>>
> >>> +/* USBSSP memory management */
> >>> +void usbssp_dbg_trace(struct usbssp_udc *usbssp_data,
> >>> +		void (*trace)(struct va_format *),
> >>> +		const char *fmt, ...);
> >>
> >> what has this function to do with memory management?
> >>
> > Nothing,
> >
> >>>  /* USBSSP Device controller glue */
> >>> +void usbssp_bottom_irq(struct work_struct *work);
> >>
> >> usbssp_bottom_irq() wasn't defined in this patch.
> > Removed from this patch
> >
> >>> +int usbssp_init(struct usbssp_udc *usbssp_data);
> >>> +void usbssp_stop(struct usbssp_udc *usbssp_data);
> >>> +int usbssp_handshake(void __iomem *ptr, u32 mask, u32 done, int usec);
> >>> +void usbssp_quiesce(struct usbssp_udc *usbssp_data);
> >>> +extern int usbssp_reset(struct usbssp_udc *usbssp_data);
> >>> +
> >>>  int usbssp_suspend(struct usbssp_udc *usbssp_data, bool do_wakeup);
> >>>  int usbssp_resume(struct usbssp_udc *usbssp_data, bool hibernated);
> >>>
> >>> @@ -1689,6 +1702,8 @@ dma_addr_t usbssp_trb_virt_to_dma(struct usbssp_segment *seg,
> >>>  /* USBSSP gadget interface*/
> >>>  int usbssp_gadget_init(struct usbssp_udc *usbssp_data);
> >>>  int usbssp_gadget_exit(struct usbssp_udc *usbssp_data);
> >>> +void usbssp_gadget_free_endpoint(struct usbssp_udc *usbssp_data);
> >>> +int usbssp_gadget_init_endpoint(struct usbssp_udc *usbssp_data);
> >>>
> >>>  static inline char *usbssp_slot_state_string(u32 state)
> >>>  {
> >>>
> >>
> 
> --
> cheers,
> -roger
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
cheers,
Pawell

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-08-06 12:03 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-12  9:09 [05/31] usb: usbssp: Added first part of initialization sequence Greg Kroah-Hartman
  -- strict thread matches above, loose matches on Subject: below --
2018-08-06 12:03 Pawel Laszczak
2018-08-06 10:33 Roger Quadros
2018-08-06  8:57 Pawel Laszczak
2018-08-03 10:17 Roger Quadros
2018-07-19 17:57 Pawel Laszczak
2018-07-12  9:47 Pawel Laszczak
2018-07-12  9:03 Pawel Laszczak
2018-07-12  6:27 Greg Kroah-Hartman
2018-07-12  5:47 Pawel Laszczak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).