linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [02/31] usb: usbssp: Added some decoding functions.
@ 2018-07-12 17:07 Greg Kroah-Hartman
  0 siblings, 0 replies; 11+ messages in thread
From: Greg Kroah-Hartman @ 2018-07-12 17:07 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 04:43:27PM +0000, Pawel Laszczak wrote:
> > > > > This patch add additional functions that converts some fields to string.
> > > > >
> > > > > For example function usbssp_trb_comp_code_string take completion c
> > > > > ode value and return string describing completion code.
> > > >
> > > > Odd line-wrapping :(
> > > Do you mean additional space character between "c" and "ode"
> > 
> > It wrapped lines at that point for me, yes.
> > 
> > > > And why do you want a string for these things?  Who cares about them?
> > > It will be used in next version of driver. I have plan to add gadget-debugfs.c
> > file.
> > > At this moment this functions can be useful during debugging driver if
> > > someone want to display some debug information.
> > >
> > > Should I remove this function ?
> > 
> > If no one is using it now, yes, it does not need to be there, right?  We don't
> > have dead code around for no reason, otherwise someone will come along
> > and remove it :)
> 
> I checked again, and these functions are used in gadget-trace.h file added in [PATCH 03/31].
> I didn't want to create too big patch, so I split it into two separate part. [PATCH 02/31] add debugging 
> function used in trace* functions, and [PATCH 03/31/] add all trace* function used in driver.

Ok, that's fine then.

And please wrap your lines in your emails to a sane limit :)

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] 11+ messages in thread
* [02/31] usb: usbssp: Added some decoding functions.
@ 2018-09-11  9:01 Pawel Laszczak
  0 siblings, 0 replies; 11+ messages in thread
From: Pawel Laszczak @ 2018-09-11  9:01 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Felipe Balbi
  Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	Lukasz Tyrala, Alan Douglas

HI, All 
 
Please stop review of this series. It's a pity of your time. 

Probably the design of USBSSP device controller will be significantly changed and simplified, so 
I will have to create new driver. 

The planed change include: 
   - simplification and change registers map
   - removing command queue 
   -  simplification  in input/output endpoint context
   - and other.


It was not my decision. Thanks for all  your comments.
I will take them into account in new driver. 

Cheers,
Pawell




>On Tue, Sep 11, 2018 at 08:48:43AM +0300, Felipe Balbi wrote:
>>
>> Hi,
>>
>> Greg Kroah-Hartman <gregkh@linuxfoundation.org> writes:
>> > On Thu, Jul 19, 2018 at 06:57:35PM +0100, Pawel Laszczak wrote:
>> >> This patch add additional functions that converts some fields to string.
>> >>
>> >> For example function usbssp_trb_comp_code_string take completion
>> >> code value and return string describing completion code.
>> >>
>> >> Signed-off-by: Pawel Laszczak <pawell@cadence.com>
>> >> ---
>> >>  drivers/usb/usbssp/gadget.h | 580 ++++++++++++++++++++++++++++++++++++
>> >>  1 file changed, 580 insertions(+)
>> >>
>> >> diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h
>> >> index 49e7271187cc..b5c17603af78 100644
>> >> --- a/drivers/usb/usbssp/gadget.h
>> >> +++ b/drivers/usb/usbssp/gadget.h
>> >> @@ -930,6 +930,73 @@ struct usbssp_transfer_event {
>> >>  #define COMP_UNDEFINED_ERROR			33
>> >>  #define COMP_INVALID_STREAM_ID_ERROR		34
>> >>
>> >> +static inline const char *usbssp_trb_comp_code_string(u8 status)
>> >
>> > <snip>
>> >
>> >
>> > You have _giant_ inline functions here, why?
>> >
>> > Please just put this all in a .c file and let the linker properly handle
>> > things.  You do not want to duplicate all of these crazy strings all
>> > over the place where ever you call these functions.
>> >
>> > And I am guessing this is only for some sort of "debugging" mode?  If
>> > so, shouldn't there be a way to not even build this in?  Some systems
>> > are very space constrained...
>>
>> many of them seem to be a straight copy from xhci.
>
>Which doesn't mean it's a great model to copy :)
>
>Let's learn from our past mistakes, having had to try to slim down a
>kernel for a limited memory system is a chore that no one should have to
>manually hack up the source tree just to accomplish it.
>
>thanks,
>
>greg k-h

^ permalink raw reply	[flat|nested] 11+ messages in thread
* [02/31] usb: usbssp: Added some decoding functions.
@ 2018-09-11  8:12 Greg Kroah-Hartman
  0 siblings, 0 replies; 11+ messages in thread
From: Greg Kroah-Hartman @ 2018-09-11  8:12 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Pawel Laszczak, linux-usb, linux-kernel, ltyrala, adouglas

On Tue, Sep 11, 2018 at 08:48:43AM +0300, Felipe Balbi wrote:
> 
> Hi,
> 
> Greg Kroah-Hartman <gregkh@linuxfoundation.org> writes:
> > On Thu, Jul 19, 2018 at 06:57:35PM +0100, Pawel Laszczak wrote:
> >> This patch add additional functions that converts some fields to string.
> >> 
> >> For example function usbssp_trb_comp_code_string take completion
> >> code value and return string describing completion code.
> >> 
> >> Signed-off-by: Pawel Laszczak <pawell@cadence.com>
> >> ---
> >>  drivers/usb/usbssp/gadget.h | 580 ++++++++++++++++++++++++++++++++++++
> >>  1 file changed, 580 insertions(+)
> >> 
> >> diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h
> >> index 49e7271187cc..b5c17603af78 100644
> >> --- a/drivers/usb/usbssp/gadget.h
> >> +++ b/drivers/usb/usbssp/gadget.h
> >> @@ -930,6 +930,73 @@ struct usbssp_transfer_event {
> >>  #define COMP_UNDEFINED_ERROR			33
> >>  #define COMP_INVALID_STREAM_ID_ERROR		34
> >>  
> >> +static inline const char *usbssp_trb_comp_code_string(u8 status)
> >
> > <snip>
> >
> >
> > You have _giant_ inline functions here, why?
> >
> > Please just put this all in a .c file and let the linker properly handle
> > things.  You do not want to duplicate all of these crazy strings all
> > over the place where ever you call these functions.
> >
> > And I am guessing this is only for some sort of "debugging" mode?  If
> > so, shouldn't there be a way to not even build this in?  Some systems
> > are very space constrained...
> 
> many of them seem to be a straight copy from xhci.

Which doesn't mean it's a great model to copy :)

Let's learn from our past mistakes, having had to try to slim down a
kernel for a limited memory system is a chore that no one should have to
manually hack up the source tree just to accomplish it.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 11+ messages in thread
* [02/31] usb: usbssp: Added some decoding functions.
@ 2018-09-11  5:48 Felipe Balbi
  0 siblings, 0 replies; 11+ messages in thread
From: Felipe Balbi @ 2018-09-11  5:48 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Pawel Laszczak
  Cc: linux-usb, linux-kernel, ltyrala, adouglas

Hi,

Greg Kroah-Hartman <gregkh@linuxfoundation.org> writes:
> On Thu, Jul 19, 2018 at 06:57:35PM +0100, Pawel Laszczak wrote:
>> This patch add additional functions that converts some fields to string.
>> 
>> For example function usbssp_trb_comp_code_string take completion
>> code value and return string describing completion code.
>> 
>> Signed-off-by: Pawel Laszczak <pawell@cadence.com>
>> ---
>>  drivers/usb/usbssp/gadget.h | 580 ++++++++++++++++++++++++++++++++++++
>>  1 file changed, 580 insertions(+)
>> 
>> diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h
>> index 49e7271187cc..b5c17603af78 100644
>> --- a/drivers/usb/usbssp/gadget.h
>> +++ b/drivers/usb/usbssp/gadget.h
>> @@ -930,6 +930,73 @@ struct usbssp_transfer_event {
>>  #define COMP_UNDEFINED_ERROR			33
>>  #define COMP_INVALID_STREAM_ID_ERROR		34
>>  
>> +static inline const char *usbssp_trb_comp_code_string(u8 status)
>
> <snip>
>
>
> You have _giant_ inline functions here, why?
>
> Please just put this all in a .c file and let the linker properly handle
> things.  You do not want to duplicate all of these crazy strings all
> over the place where ever you call these functions.
>
> And I am guessing this is only for some sort of "debugging" mode?  If
> so, shouldn't there be a way to not even build this in?  Some systems
> are very space constrained...

many of them seem to be a straight copy from xhci.

^ permalink raw reply	[flat|nested] 11+ messages in thread
* [02/31] usb: usbssp: Added some decoding functions.
@ 2018-09-10 18:18 Greg Kroah-Hartman
  0 siblings, 0 replies; 11+ messages in thread
From: Greg Kroah-Hartman @ 2018-09-10 18:18 UTC (permalink / raw)
  To: Pawel Laszczak; +Cc: linux-usb, Felipe Balbi, linux-kernel, ltyrala, adouglas

On Thu, Jul 19, 2018 at 06:57:35PM +0100, Pawel Laszczak wrote:
> This patch add additional functions that converts some fields to string.
> 
> For example function usbssp_trb_comp_code_string take completion
> code value and return string describing completion code.
> 
> Signed-off-by: Pawel Laszczak <pawell@cadence.com>
> ---
>  drivers/usb/usbssp/gadget.h | 580 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 580 insertions(+)
> 
> diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h
> index 49e7271187cc..b5c17603af78 100644
> --- a/drivers/usb/usbssp/gadget.h
> +++ b/drivers/usb/usbssp/gadget.h
> @@ -930,6 +930,73 @@ struct usbssp_transfer_event {
>  #define COMP_UNDEFINED_ERROR			33
>  #define COMP_INVALID_STREAM_ID_ERROR		34
>  
> +static inline const char *usbssp_trb_comp_code_string(u8 status)

<snip>


You have _giant_ inline functions here, why?

Please just put this all in a .c file and let the linker properly handle
things.  You do not want to duplicate all of these crazy strings all
over the place where ever you call these functions.

And I am guessing this is only for some sort of "debugging" mode?  If
so, shouldn't there be a way to not even build this in?  Some systems
are very space constrained...

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 11+ messages in thread
* [02/31] usb: usbssp: Added some decoding functions.
@ 2018-07-19 17:57 Pawel Laszczak
  0 siblings, 0 replies; 11+ 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

This patch add additional functions that converts some fields to string.

For example function usbssp_trb_comp_code_string take completion
code value and return string describing completion code.

Signed-off-by: Pawel Laszczak <pawell@cadence.com>
---
 drivers/usb/usbssp/gadget.h | 580 ++++++++++++++++++++++++++++++++++++
 1 file changed, 580 insertions(+)

diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h
index 49e7271187cc..b5c17603af78 100644
--- a/drivers/usb/usbssp/gadget.h
+++ b/drivers/usb/usbssp/gadget.h
@@ -930,6 +930,73 @@ struct usbssp_transfer_event {
 #define COMP_UNDEFINED_ERROR			33
 #define COMP_INVALID_STREAM_ID_ERROR		34
 
+static inline const char *usbssp_trb_comp_code_string(u8 status)
+{
+	switch (status) {
+	case COMP_INVALID:
+		return "Invalid";
+	case COMP_SUCCESS:
+		return "Success";
+	case COMP_DATA_BUFFER_ERROR:
+		return "Data Buffer Error";
+	case COMP_BABBLE_DETECTED_ERROR:
+		return "Babble Detected";
+	case COMP_USB_TRANSACTION_ERROR:
+		return "USB Transaction Error";
+	case COMP_TRB_ERROR:
+		return "TRB Error";
+	case COMP_RESOURCE_ERROR:
+		return "Resource Error";
+	case COMP_NO_SLOTS_AVAILABLE_ERROR:
+		return "No Slots Available Error";
+	case COMP_INVALID_STREAM_TYPE_ERROR:
+		return "Invalid Stream Type Error";
+	case COMP_SLOT_NOT_ENABLED_ERROR:
+		return "Slot Not Enabled Error";
+	case COMP_ENDPOINT_NOT_ENABLED_ERROR:
+		return "Endpoint Not Enabled Error";
+	case COMP_SHORT_PACKET:
+		return "Short Packet";
+	case COMP_RING_UNDERRUN:
+		return "Ring Underrun";
+	case COMP_RING_OVERRUN:
+		return "Ring Overrun";
+	case COMP_VF_EVENT_RING_FULL_ERROR:
+		return "VF Event Ring Full Error";
+	case COMP_PARAMETER_ERROR:
+		return "Parameter Error";
+	case COMP_CONTEXT_STATE_ERROR:
+		return "Context State Error";
+	case COMP_EVENT_RING_FULL_ERROR:
+		return "Event Ring Full Error";
+	case COMP_INCOMPATIBLE_DEVICE_ERROR:
+		return "Incompatible Device Error";
+	case COMP_MISSED_SERVICE_ERROR:
+		return "Missed Service Error";
+	case COMP_COMMAND_RING_STOPPED:
+		return "Command Ring Stopped";
+	case COMP_COMMAND_ABORTED:
+		return "Command Aborted";
+	case COMP_STOPPED:
+		return "Stopped";
+	case COMP_STOPPED_LENGTH_INVALID:
+		return "Stopped - Length Invalid";
+	case COMP_STOPPED_SHORT_PACKET:
+		return "Stopped - Short Packet";
+	case COMP_MAX_EXIT_LATENCY_TOO_LARGE_ERROR:
+		return "Max Exit Latency Too Large Error";
+	case COMP_ISOCH_BUFFER_OVERRUN:
+		return "Isoch Buffer Overrun";
+	case COMP_EVENT_LOST_ERROR:
+		return "Event Lost Error";
+	case COMP_UNDEFINED_ERROR:
+		return "Undefined Error";
+	case COMP_INVALID_STREAM_ID_ERROR:
+		return "Invalid Stream ID Error";
+	default:
+		return "Unknown!!";
+	}
+}
 struct usbssp_link_trb {
 	/* 64-bit segment pointer*/
 	__le64 segment_ptr;
@@ -1292,6 +1359,27 @@ enum usbssp_ring_type {
 	TYPE_EVENT,
 };
 
+static inline const char *usbssp_ring_type_string(enum usbssp_ring_type type)
+{
+	switch (type) {
+	case TYPE_CTRL:
+		return "CTRL";
+	case TYPE_ISOC:
+		return "ISOC";
+	case TYPE_BULK:
+		return "BULK";
+	case TYPE_INTR:
+		return "INTR";
+	case TYPE_STREAM:
+		return "STREAM";
+	case TYPE_COMMAND:
+		return "CMD";
+	case TYPE_EVENT:
+		return "EVENT";
+	}
+
+	return "UNKNOWN";
+}
 struct usbssp_ring {
 	struct usbssp_segment	*first_seg;
 	struct usbssp_segment	*last_seg;
@@ -1568,4 +1656,496 @@ struct usbssp_udc {
 
 #define USBSSP_CFC_DELAY	10
 
+
+/*
+ * Registers should always be accessed with double word or quad word accesses.
+ *
+ * Registers with 64-bit address pointers should be written to with
+ * dword accesses by writing the low dword first (ptr[0]), then the high dword
+ * (ptr[1]) second. DC implementations that do not support 64-bit address
+ * pointers will ignore the high dword, and write order is irrelevant.
+ */
+static inline u64 usbssp_read_64(const struct usbssp_udc *usbssp_data,
+				__le64 __iomem *regs)
+{
+	return lo_hi_readq(regs);
+}
+
+static inline void usbssp_write_64(struct usbssp_udc *usbssp_data,
+				const u64 val, __le64 __iomem *regs)
+{
+	lo_hi_writeq(val, regs);
+}
+static inline char *usbssp_slot_state_string(u32 state)
+{
+	switch (state) {
+	case SLOT_STATE_ENABLED:
+		return "enabled/disabled";
+	case SLOT_STATE_DEFAULT:
+		return "default";
+	case SLOT_STATE_ADDRESSED:
+		return "addressed";
+	case SLOT_STATE_CONFIGURED:
+		return "configured";
+	default:
+		return "reserved";
+	}
+}
+
+static inline const char *usbssp_decode_trb(u32 field0, u32 field1, u32 field2,
+					u32 field3)
+{
+	static char str[256];
+	int type = TRB_FIELD_TO_TYPE(field3);
+
+	switch (type) {
+	case TRB_LINK:
+		sprintf(str,
+			"LINK %08x%08x intr %d type '%s' flags %c:%c:%c:%c",
+			field1, field0, GET_INTR_TARGET(field2),
+			usbssp_trb_type_string(type),
+			field3 & TRB_IOC ? 'I' : 'i',
+			field3 & TRB_CHAIN ? 'C' : 'c',
+			field3 & TRB_TC ? 'T' : 't',
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_TRANSFER:
+	case TRB_COMPLETION:
+	case TRB_PORT_STATUS:
+	case TRB_DOORBELL:
+	case TRB_HC_EVENT:
+	case TRB_DEV_NOTE:
+	case TRB_MFINDEX_WRAP:
+		sprintf(str,
+			"TRB %08x%08x status '%s' len %d slot %d ep %d:=:"
+			"type '%s' flags %c:%c",
+			field1, field0,
+			usbssp_trb_comp_code_string(GET_COMP_CODE(field2)),
+			EVENT_TRB_LEN(field2), TRB_TO_SLOT_ID(field3),
+			/* Macro decrements 1, maybe it shouldn't?!? */
+			TRB_TO_EP_INDEX(field3) + 1,
+			usbssp_trb_type_string(type),
+			field3 & EVENT_DATA ? 'E' : 'e',
+			field3 & TRB_CYCLE ? 'C' : 'c');
+
+		break;
+	case TRB_SETUP:
+		sprintf(str, "bRequestType %02x bRequest %02x wValue %02x%02x "
+				"wIndex %02x%02x wLength %d length %d "
+				"TD size %d intr %d type '%s' flags %c:%c:%c",
+				field0 & 0xff,
+				(field0 & 0xff00) >> 8,
+				(field0 & 0xff000000) >> 24,
+				(field0 & 0xff0000) >> 16,
+				(field1 & 0xff00) >> 8,
+				field1 & 0xff,
+				(field1 & 0xff000000) >> 16 |
+				(field1 & 0xff0000) >> 16,
+				TRB_LEN(field2), GET_TD_SIZE(field2),
+				GET_INTR_TARGET(field2),
+				usbssp_trb_type_string(type),
+				field3 & TRB_IDT ? 'I' : 'i',
+				field3 & TRB_IOC ? 'I' : 'i',
+				field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_DATA:
+		sprintf(str, "Buffer %08x%08x length %d TD size %d intr %d "
+				"type '%s' flags %c:%c:%c:%c:%c:%c:%c",
+				field1, field0, TRB_LEN(field2),
+				GET_TD_SIZE(field2),
+				GET_INTR_TARGET(field2),
+				usbssp_trb_type_string(type),
+				field3 & TRB_IDT ? 'I' : 'i',
+				field3 & TRB_IOC ? 'I' : 'i',
+				field3 & TRB_CHAIN ? 'C' : 'c',
+				field3 & TRB_NO_SNOOP ? 'S' : 's',
+				field3 & TRB_ISP ? 'I' : 'i',
+				field3 & TRB_ENT ? 'E' : 'e',
+				field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_STATUS:
+		sprintf(str, "Buffer %08x%08x length %d TD size %d intr"
+				"%d type '%s' flags %c:%c:%c:%c",
+				field1, field0, TRB_LEN(field2),
+				GET_TD_SIZE(field2),
+				GET_INTR_TARGET(field2),
+				usbssp_trb_type_string(type),
+				field3 & TRB_IOC ? 'I' : 'i',
+				field3 & TRB_CHAIN ? 'C' : 'c',
+				field3 & TRB_ENT ? 'E' : 'e',
+				field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_NORMAL:
+	case TRB_ISOC:
+	case TRB_EVENT_DATA:
+	case TRB_TR_NOOP:
+		sprintf(str,
+			"Buffer %08x%08x length %d TD size %d intr %d "
+			"type '%s' flags %c:%c:%c:%c:%c:%c:%c:%c",
+			field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2),
+			GET_INTR_TARGET(field2),
+			usbssp_trb_type_string(type),
+			field3 & TRB_BEI ? 'B' : 'b',
+			field3 & TRB_IDT ? 'I' : 'i',
+			field3 & TRB_IOC ? 'I' : 'i',
+			field3 & TRB_CHAIN ? 'C' : 'c',
+			field3 & TRB_NO_SNOOP ? 'S' : 's',
+			field3 & TRB_ISP ? 'I' : 'i',
+			field3 & TRB_ENT ? 'E' : 'e',
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+
+	case TRB_CMD_NOOP:
+	case TRB_ENABLE_SLOT:
+		sprintf(str,
+			"%s: flags %c",
+			usbssp_trb_type_string(type),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_DISABLE_SLOT:
+		sprintf(str,
+			"%s: slot %d flags %c",
+			usbssp_trb_type_string(type),
+			TRB_TO_SLOT_ID(field3),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_ADDR_DEV:
+		sprintf(str,
+			"%s: ctx %08x%08x slot %d flags %c:%c",
+			usbssp_trb_type_string(type),
+			field1, field0,
+			TRB_TO_SLOT_ID(field3),
+			field3 & TRB_BSR ? 'B' : 'b',
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_CONFIG_EP:
+		sprintf(str,
+			"%s: ctx %08x%08x slot %d flags %c:%c",
+			usbssp_trb_type_string(type),
+			field1, field0,
+			TRB_TO_SLOT_ID(field3),
+			field3 & TRB_DC ? 'D' : 'd',
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_EVAL_CONTEXT:
+		sprintf(str,
+			"%s: ctx %08x%08x slot %d flags %c",
+			usbssp_trb_type_string(type),
+			field1, field0,
+			TRB_TO_SLOT_ID(field3),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_RESET_EP:
+	case TRB_HALT_ENDPOINT:
+	case TRB_FLUSH_ENDPOINT:
+		sprintf(str,
+			"%s: ctx %08x%08x slot %d ep %d flags %c",
+			usbssp_trb_type_string(type),
+			field1, field0,
+			TRB_TO_SLOT_ID(field3),
+			/* Macro decrements 1, maybe it shouldn't?!? */
+			TRB_TO_EP_INDEX(field3) + 1,
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_STOP_RING:
+		sprintf(str,
+			"%s: slot %d sp %d ep %d flags %c",
+			usbssp_trb_type_string(type),
+			TRB_TO_SLOT_ID(field3),
+			TRB_TO_SUSPEND_PORT(field3),
+			/* Macro decrements 1, maybe it shouldn't?!? */
+			TRB_TO_EP_INDEX(field3) + 1,
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_SET_DEQ:
+		sprintf(str,
+			"%s: deq %08x%08x stream %d slot %d ep %d flags %c",
+			usbssp_trb_type_string(type),
+			field1, field0,
+			TRB_TO_STREAM_ID(field2),
+			TRB_TO_SLOT_ID(field3),
+			/* Macro decrements 1, maybe it shouldn't?!? */
+			TRB_TO_EP_INDEX(field3) + 1,
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_RESET_DEV:
+		sprintf(str,
+			"%s: slot %d flags %c",
+			usbssp_trb_type_string(type),
+			TRB_TO_SLOT_ID(field3),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_FORCE_EVENT:
+		sprintf(str,
+			"%s: event %08x%08x vf intr %d vf id %d flags %c",
+			usbssp_trb_type_string(type),
+			field1, field0,
+			TRB_TO_VF_INTR_TARGET(field2),
+			TRB_TO_VF_ID(field3),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_SET_LT:
+		sprintf(str,
+			"%s: belt %d flags %c",
+			usbssp_trb_type_string(type),
+			TRB_TO_BELT(field3),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_FORCE_HEADER:
+		sprintf(str,
+			"%s: info %08x%08x%08x pkt type %d roothub port %d flags %c",
+			usbssp_trb_type_string(type),
+			field2, field1, field0 & 0xffffffe0,
+			TRB_TO_PACKET_TYPE(field0),
+			TRB_TO_DEV_PORT(field3),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_ENDPOINT_NRDY:
+		sprintf(str,
+			"%s: flags %c",
+			usbssp_trb_type_string(type),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+	default:
+		sprintf(str,
+			"type '%s' -> raw %08x %08x %08x %08x",
+			usbssp_trb_type_string(type),
+			field0, field1, field2, field3);
+	}
+
+	return str;
+}
+
+static inline const char *usbssp_decode_slot_context(u32 info, u32 info2,
+						u32 int_target, u32 state)
+{
+	static char str[1024];
+	u32 speed;
+	int ret = 0;
+
+	speed = info & DEV_SPEED;
+
+	ret = sprintf(str, "%s Ctx Entries %ld MEL %d us",
+			({ char *s;
+			switch (speed) {
+			case SLOT_SPEED_FS:
+				s = "full-speed";
+				break;
+			case SLOT_SPEED_LS:
+				s = "low-speed";
+				break;
+			case SLOT_SPEED_HS:
+				s = "high-speed";
+				break;
+			case SLOT_SPEED_SS:
+				s = "super-speed";
+				break;
+			case SLOT_SPEED_SSP:
+				s = "super-speed plus";
+				break;
+			default:
+				s = "UNKNOWN speed";
+			} s; }),
+			(info & LAST_CTX_MASK) >> 27,
+			info2 & MAX_EXIT);
+
+	ret += sprintf(str + ret, " [Intr %d] Addr %ld State %s",
+			GET_INTR_TARGET(int_target),
+			state & DEV_ADDR_MASK,
+			usbssp_slot_state_string(GET_SLOT_STATE(state)));
+
+	return str;
+}
+
+
+static inline const char *usbssp_portsc_link_state_string(u32 portsc)
+{
+	switch (portsc & PORT_PLS_MASK) {
+	case XDEV_U0:
+		return "U0";
+	case XDEV_U1:
+		return "U1";
+	case XDEV_U2:
+		return "U2";
+	case XDEV_U3:
+		return "U3";
+	case XDEV_DISABLED:
+		return "Disabled";
+	case XDEV_RXDETECT:
+		return "RxDetect";
+	case XDEV_INACTIVE:
+		return "Inactive";
+	case XDEV_POLLING:
+		return "Polling";
+	case XDEV_RECOVERY:
+		return "Recovery";
+	case XDEV_HOT_RESET:
+		return "Hot Reset";
+	case XDEV_COMP_MODE:
+		return "Compliance mode";
+	case XDEV_TEST_MODE:
+		return "Test mode";
+	case XDEV_RESUME:
+		return "Resume";
+	default:
+		break;
+	}
+	return "Unknown";
+}
+
+static inline const char *usbssp_decode_portsc(u32 portsc)
+{
+	static char str[256];
+	int ret;
+
+	ret = sprintf(str, "%s %s %s Link:%s PortSpeed:%d ",
+			portsc & PORT_POWER	? "Powered" : "Powered-off",
+			portsc & PORT_CONNECT	? "Connected" : "Not-connected",
+			portsc & PORT_PE	? "Enabled" : "Disabled",
+			usbssp_portsc_link_state_string(portsc),
+			DEV_PORT_SPEED(portsc));
+
+	if (portsc & PORT_OC)
+		ret += sprintf(str + ret, "OverCurrent ");
+	if (portsc & PORT_RESET)
+		ret += sprintf(str + ret, "In-Reset ");
+
+	ret += sprintf(str + ret, "Change: ");
+	if (portsc & PORT_CSC)
+		ret += sprintf(str + ret, "CSC ");
+	if (portsc & PORT_PEC)
+		ret += sprintf(str + ret, "PEC ");
+	if (portsc & PORT_WRC)
+		ret += sprintf(str + ret, "WRC ");
+	if (portsc & PORT_OCC)
+		ret += sprintf(str + ret, "OCC ");
+	if (portsc & PORT_RC)
+		ret += sprintf(str + ret, "PRC ");
+	if (portsc & PORT_PLC)
+		ret += sprintf(str + ret, "PLC ");
+	if (portsc & PORT_CEC)
+		ret += sprintf(str + ret, "CEC ");
+	ret += sprintf(str + ret, "Wake: ");
+	if (portsc & PORT_WKCONN_E)
+		ret += sprintf(str + ret, "WCE ");
+	if (portsc & PORT_WKDISC_E)
+		ret += sprintf(str + ret, "WDE ");
+	if (portsc & PORT_WKOC_E)
+		ret += sprintf(str + ret, "WOE ");
+
+	return str;
+}
+
+static inline const char *usbssp_ep_state_string(u8 state)
+{
+	switch (state) {
+	case EP_STATE_DISABLED:
+		return "disabled";
+	case EP_STATE_RUNNING:
+		return "running";
+	case EP_STATE_HALTED:
+		return "halted";
+	case EP_STATE_STOPPED:
+		return "stopped";
+	case EP_STATE_ERROR:
+		return "error";
+	default:
+		return "INVALID";
+	}
+}
+
+static inline const char *usbssp_ep_type_string(u8 type)
+{
+	switch (type) {
+	case ISOC_OUT_EP:
+		return "Isoc OUT";
+	case BULK_OUT_EP:
+		return "Bulk OUT";
+	case INT_OUT_EP:
+		return "Int OUT";
+	case CTRL_EP:
+		return "Ctrl";
+	case ISOC_IN_EP:
+		return "Isoc IN";
+	case BULK_IN_EP:
+		return "Bulk IN";
+	case INT_IN_EP:
+		return "Int IN";
+	default:
+		return "INVALID";
+	}
+}
+
+static inline const char *usbssp_decode_ep_context(u32 info, u32 info2, u64 deq,
+						u32 tx_info)
+{
+	static char str[1024];
+	int ret;
+
+	u32 esit;
+	u16 maxp;
+	u16 avg;
+
+	u8 max_pstr;
+	u8 ep_state;
+	u8 interval;
+	u8 ep_type;
+	u8 burst;
+	u8 cerr;
+	u8 mult;
+
+	bool lsa;
+	bool hid;
+
+	esit = CTX_TO_MAX_ESIT_PAYLOAD_HI(info) << 16 |
+		CTX_TO_MAX_ESIT_PAYLOAD(tx_info);
+
+	ep_state = info & EP_STATE_MASK;
+	max_pstr = CTX_TO_EP_MAXPSTREAMS(info);
+	interval = CTX_TO_EP_INTERVAL(info);
+	mult = CTX_TO_EP_MULT(info) + 1;
+	lsa = !!(info & EP_HAS_LSA);
+
+	cerr = (info2 & (3 << 1)) >> 1;
+	ep_type = CTX_TO_EP_TYPE(info2);
+	hid = !!(info2 & (1 << 7));
+	burst = CTX_TO_MAX_BURST(info2);
+	maxp = MAX_PACKET_DECODED(info2);
+
+	avg = EP_AVG_TRB_LENGTH(tx_info);
+
+	ret = sprintf(str, "State %s mult %d max P. Streams %d %s",
+			usbssp_ep_state_string(ep_state), mult,
+			max_pstr, lsa ? "LSA " : "");
+
+	ret += sprintf(str + ret, "interval %d us max ESIT payload %d CErr %d ",
+			(1 << interval) * 125, esit, cerr);
+
+	ret += sprintf(str + ret, "Type %s %sburst %d maxp %d deq %016llx ",
+			usbssp_ep_type_string(ep_type), hid ? "HID" : "",
+			burst, maxp, deq);
+
+	ret += sprintf(str + ret, "avg trb len %d", avg);
+
+	return str;
+}
+
+/**
+ * next_request - gets the next request on the given list
+ * @list: the request list to operate on
+ *
+ * Caller should take care of locking. This function return %NULL or the first
+ * request available on @list.
+ */
+static inline struct usbssp_request *next_request(struct list_head *list)
+{
+	return list_first_entry_or_null(list, struct usbssp_request, list);
+}
+
+struct usbssp_udc;
+#define to_usbssp_ep(ep) (container_of(ep, struct usbssp_ep, endpoint))
+#define gadget_to_usbssp(g) (container_of(g, struct usbssp_udc, gadget))
+#define request_to_usbssp_request(r) (container_of(r, struct usbssp_request, request))
+
+#define to_usbssp_request(r) (container_of(r, struct usbssp_request, request))
+
 #endif /* __LINUX_USBSSP_GADGET_H */

^ permalink raw reply related	[flat|nested] 11+ messages in thread
* [02/31] usb: usbssp: Added some decoding functions.
@ 2018-07-12 16:43 Pawel Laszczak
  0 siblings, 0 replies; 11+ messages in thread
From: Pawel Laszczak @ 2018-07-12 16:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-usb@vger.kernel.org, Felipe Balbi,
	linux-kernel@vger.kernel.org, Lukasz Tyrala, Alan Douglas

> > > > This patch add additional functions that converts some fields to string.
> > > >
> > > > For example function usbssp_trb_comp_code_string take completion c
> > > > ode value and return string describing completion code.
> > >
> > > Odd line-wrapping :(
> > Do you mean additional space character between "c" and "ode"
> 
> It wrapped lines at that point for me, yes.
> 
> > > And why do you want a string for these things?  Who cares about them?
> > It will be used in next version of driver. I have plan to add gadget-debugfs.c
> file.
> > At this moment this functions can be useful during debugging driver if
> > someone want to display some debug information.
> >
> > Should I remove this function ?
> 
> If no one is using it now, yes, it does not need to be there, right?  We don't
> have dead code around for no reason, otherwise someone will come along
> and remove it :)

I checked again, and these functions are used in gadget-trace.h file added in [PATCH 03/31].
I didn't want to create too big patch, so I split it into two separate part. [PATCH 02/31] add debugging 
function used in trace* functions, and [PATCH 03/31/] add all trace* function used in driver.

thanks,

Pawel Laszczak
---
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] 11+ messages in thread
* [02/31] usb: usbssp: Added some decoding functions.
@ 2018-07-12  6:35 Greg Kroah-Hartman
  0 siblings, 0 replies; 11+ messages in thread
From: Greg Kroah-Hartman @ 2018-07-12  6:35 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 06:28:33AM +0000, Pawel Laszczak wrote:
> > > This patch add additional functions that converts some fields to string.
> > >
> > > For example function usbssp_trb_comp_code_string take completion c ode
> > > value and return string describing completion code.
> > 
> > Odd line-wrapping :(
> Do you mean additional space character between "c" and "ode"

It wrapped lines at that point for me, yes.

> > And why do you want a string for these things?  Who cares about them?
> It will be used in next version of driver. I have plan to add gadget-debugfs.c file.
> At this moment this functions can be useful during debugging driver if someone want to display
> some debug information. 
> 
> Should I remove this function ?

If no one is using it now, yes, it does not need to be there, right?  We
don't have dead code around for no reason, otherwise someone will come
along and remove it :)

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] 11+ messages in thread
* [02/31] usb: usbssp: Added some decoding functions.
@ 2018-07-12  6:28 Pawel Laszczak
  0 siblings, 0 replies; 11+ messages in thread
From: Pawel Laszczak @ 2018-07-12  6:28 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-usb@vger.kernel.org, Felipe Balbi,
	linux-kernel@vger.kernel.org, Lukasz Tyrala, Alan Douglas

> > This patch add additional functions that converts some fields to string.
> >
> > For example function usbssp_trb_comp_code_string take completion c ode
> > value and return string describing completion code.
> 
> Odd line-wrapping :(
Do you mean additional space character between "c" and "ode"

> And why do you want a string for these things?  Who cares about them?
It will be used in next version of driver. I have plan to add gadget-debugfs.c file.
At this moment this functions can be useful during debugging driver if someone want to display
some debug information. 

Should I remove this function ?
 
> 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] 11+ messages in thread
* [02/31] usb: usbssp: Added some decoding functions.
@ 2018-07-12  6:10 Greg Kroah-Hartman
  0 siblings, 0 replies; 11+ messages in thread
From: Greg Kroah-Hartman @ 2018-07-12  6:10 UTC (permalink / raw)
  To: Pawel Laszczak; +Cc: linux-usb, Felipe Balbi, linux-kernel, ltyrala, adouglas

On Thu, Jul 12, 2018 at 06:46:59AM +0100, Pawel Laszczak wrote:
> This patch add additional functions that converts some fields to string.
> 
> For example function usbssp_trb_comp_code_string take completion c
> ode value and return string describing completion code.

Odd line-wrapping :(

And why do you want a string for these things?  Who cares about them?

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] 11+ messages in thread
* [02/31] usb: usbssp: Added some decoding functions.
@ 2018-07-12  5:46 Pawel Laszczak
  0 siblings, 0 replies; 11+ messages in thread
From: Pawel Laszczak @ 2018-07-12  5:46 UTC (permalink / raw)
  Cc: Greg Kroah-Hartman, linux-usb, Felipe Balbi, linux-kernel,
	ltyrala, adouglas, pawell

This patch add additional functions that converts some fields to string.

For example function usbssp_trb_comp_code_string take completion c
ode value and return string describing completion code.

Signed-off-by: Pawel Laszczak <pawell@cadence.com>
---
 drivers/usb/usbssp/gadget.h | 572 ++++++++++++++++++++++++++++++++++++
 1 file changed, 572 insertions(+)

diff --git a/drivers/usb/usbssp/gadget.h b/drivers/usb/usbssp/gadget.h
index 486e868068b7..6b634dc63d9e 100644
--- a/drivers/usb/usbssp/gadget.h
+++ b/drivers/usb/usbssp/gadget.h
@@ -922,6 +922,73 @@ struct usbssp_transfer_event {
 #define COMP_UNDEFINED_ERROR		33
 #define COMP_INVALID_STREAM_ID_ERROR	34
 
+static inline const char *usbssp_trb_comp_code_string(u8 status)
+{
+	switch (status) {
+	case COMP_INVALID:
+		return "Invalid";
+	case COMP_SUCCESS:
+		return "Success";
+	case COMP_DATA_BUFFER_ERROR:
+		return "Data Buffer Error";
+	case COMP_BABBLE_DETECTED_ERROR:
+		return "Babble Detected";
+	case COMP_USB_TRANSACTION_ERROR:
+		return "USB Transaction Error";
+	case COMP_TRB_ERROR:
+		return "TRB Error";
+	case COMP_RESOURCE_ERROR:
+		return "Resource Error";
+	case COMP_NO_SLOTS_AVAILABLE_ERROR:
+		return "No Slots Available Error";
+	case COMP_INVALID_STREAM_TYPE_ERROR:
+		return "Invalid Stream Type Error";
+	case COMP_SLOT_NOT_ENABLED_ERROR:
+		return "Slot Not Enabled Error";
+	case COMP_ENDPOINT_NOT_ENABLED_ERROR:
+		return "Endpoint Not Enabled Error";
+	case COMP_SHORT_PACKET:
+		return "Short Packet";
+	case COMP_RING_UNDERRUN:
+		return "Ring Underrun";
+	case COMP_RING_OVERRUN:
+		return "Ring Overrun";
+	case COMP_VF_EVENT_RING_FULL_ERROR:
+		return "VF Event Ring Full Error";
+	case COMP_PARAMETER_ERROR:
+		return "Parameter Error";
+	case COMP_CONTEXT_STATE_ERROR:
+		return "Context State Error";
+	case COMP_EVENT_RING_FULL_ERROR:
+		return "Event Ring Full Error";
+	case COMP_INCOMPATIBLE_DEVICE_ERROR:
+		return "Incompatible Device Error";
+	case COMP_MISSED_SERVICE_ERROR:
+		return "Missed Service Error";
+	case COMP_COMMAND_RING_STOPPED:
+		return "Command Ring Stopped";
+	case COMP_COMMAND_ABORTED:
+		return "Command Aborted";
+	case COMP_STOPPED:
+		return "Stopped";
+	case COMP_STOPPED_LENGTH_INVALID:
+		return "Stopped - Length Invalid";
+	case COMP_STOPPED_SHORT_PACKET:
+		return "Stopped - Short Packet";
+	case COMP_MAX_EXIT_LATENCY_TOO_LARGE_ERROR:
+		return "Max Exit Latency Too Large Error";
+	case COMP_ISOCH_BUFFER_OVERRUN:
+		return "Isoch Buffer Overrun";
+	case COMP_EVENT_LOST_ERROR:
+		return "Event Lost Error";
+	case COMP_UNDEFINED_ERROR:
+		return "Undefined Error";
+	case COMP_INVALID_STREAM_ID_ERROR:
+		return "Invalid Stream ID Error";
+	default:
+		return "Unknown!!";
+	}
+}
 struct usbssp_link_trb {
 	/* 64-bit segment pointer*/
 	__le64 segment_ptr;
@@ -1274,6 +1341,27 @@ enum usbssp_ring_type {
 	TYPE_EVENT,
 };
 
+static inline const char *usbssp_ring_type_string(enum usbssp_ring_type type)
+{
+	switch (type) {
+	case TYPE_CTRL:
+		return "CTRL";
+	case TYPE_ISOC:
+		return "ISOC";
+	case TYPE_BULK:
+		return "BULK";
+	case TYPE_INTR:
+		return "INTR";
+	case TYPE_STREAM:
+		return "STREAM";
+	case TYPE_COMMAND:
+		return "CMD";
+	case TYPE_EVENT:
+		return "EVENT";
+	}
+
+	return "UNKNOWN";
+}
 struct usbssp_ring {
 	struct usbssp_segment	*first_seg;
 	struct usbssp_segment	*last_seg;
@@ -1564,4 +1652,488 @@ struct usbssp_udc {
 #define usbssp_info(usbssp_data, fmt, args...) \
 	dev_info(usbssp_data->dev, fmt, ## args)
 
+/*
+ * Registers should always be accessed with double word or quad word accesses.
+ *
+ * Registers with 64-bit address pointers should be written to with
+ * dword accesses by writing the low dword first (ptr[0]), then the high dword
+ * (ptr[1]) second. DC implementations that do not support 64-bit address
+ * pointers will ignore the high dword, and write order is irrelevant.
+ */
+static inline u64 usbssp_read_64(const struct usbssp_udc *usbssp_data,
+		__le64 __iomem *regs)
+{
+	return lo_hi_readq(regs);
+}
+
+static inline void usbssp_write_64(struct usbssp_udc *usbssp_data,
+				 const u64 val, __le64 __iomem *regs)
+{
+	lo_hi_writeq(val, regs);
+}
+static inline char *usbssp_slot_state_string(u32 state)
+{
+	switch (state) {
+	case SLOT_STATE_ENABLED:
+		return "enabled/disabled";
+	case SLOT_STATE_DEFAULT:
+		return "default";
+	case SLOT_STATE_ADDRESSED:
+		return "addressed";
+	case SLOT_STATE_CONFIGURED:
+		return "configured";
+	default:
+		return "reserved";
+	}
+}
+
+static inline const char *usbssp_decode_trb(u32 field0, u32 field1, u32 field2,
+		u32 field3)
+{
+	static char str[256];
+	int type = TRB_FIELD_TO_TYPE(field3);
+
+	switch (type) {
+	case TRB_LINK:
+		sprintf(str,
+			"LINK %08x%08x intr %d type '%s' flags %c:%c:%c:%c",
+			field1, field0, GET_INTR_TARGET(field2),
+			usbssp_trb_type_string(type),
+			field3 & TRB_IOC ? 'I' : 'i',
+			field3 & TRB_CHAIN ? 'C' : 'c',
+			field3 & TRB_TC ? 'T' : 't',
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_TRANSFER:
+	case TRB_COMPLETION:
+	case TRB_PORT_STATUS:
+	case TRB_DOORBELL:
+	case TRB_HC_EVENT:
+	case TRB_DEV_NOTE:
+	case TRB_MFINDEX_WRAP:
+		sprintf(str,
+			"TRB %08x%08x status '%s' len %d slot %d ep %d:=:"
+			"type '%s' flags %c:%c",
+			field1, field0,
+			usbssp_trb_comp_code_string(GET_COMP_CODE(field2)),
+			EVENT_TRB_LEN(field2), TRB_TO_SLOT_ID(field3),
+			/* Macro decrements 1, maybe it shouldn't?!? */
+			TRB_TO_EP_INDEX(field3) + 1,
+			usbssp_trb_type_string(type),
+			field3 & EVENT_DATA ? 'E' : 'e',
+			field3 & TRB_CYCLE ? 'C' : 'c');
+
+		break;
+	case TRB_SETUP:
+		sprintf(str, "bRequestType %02x bRequest %02x wValue %02x%02x "
+				"wIndex %02x%02x wLength %d length %d "
+				"TD size %d intr %d type '%s' flags %c:%c:%c",
+				field0 & 0xff,
+				(field0 & 0xff00) >> 8,
+				(field0 & 0xff000000) >> 24,
+				(field0 & 0xff0000) >> 16,
+				(field1 & 0xff00) >> 8,
+				field1 & 0xff,
+				(field1 & 0xff000000) >> 16 |
+				(field1 & 0xff0000) >> 16,
+				TRB_LEN(field2), GET_TD_SIZE(field2),
+				GET_INTR_TARGET(field2),
+				usbssp_trb_type_string(type),
+				field3 & TRB_IDT ? 'I' : 'i',
+				field3 & TRB_IOC ? 'I' : 'i',
+				field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_DATA:
+		sprintf(str, "Buffer %08x%08x length %d TD size %d intr %d "
+				"type '%s' flags %c:%c:%c:%c:%c:%c:%c",
+				field1, field0, TRB_LEN(field2),
+				GET_TD_SIZE(field2),
+				GET_INTR_TARGET(field2),
+				usbssp_trb_type_string(type),
+				field3 & TRB_IDT ? 'I' : 'i',
+				field3 & TRB_IOC ? 'I' : 'i',
+				field3 & TRB_CHAIN ? 'C' : 'c',
+				field3 & TRB_NO_SNOOP ? 'S' : 's',
+				field3 & TRB_ISP ? 'I' : 'i',
+				field3 & TRB_ENT ? 'E' : 'e',
+				field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_STATUS:
+		sprintf(str, "Buffer %08x%08x length %d TD size %d intr"
+				"%d type '%s' flags %c:%c:%c:%c",
+				field1, field0, TRB_LEN(field2),
+				GET_TD_SIZE(field2),
+				GET_INTR_TARGET(field2),
+				usbssp_trb_type_string(type),
+				field3 & TRB_IOC ? 'I' : 'i',
+				field3 & TRB_CHAIN ? 'C' : 'c',
+				field3 & TRB_ENT ? 'E' : 'e',
+				field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_NORMAL:
+	case TRB_ISOC:
+	case TRB_EVENT_DATA:
+	case TRB_TR_NOOP:
+		sprintf(str,
+			"Buffer %08x%08x length %d TD size %d intr %d "
+			"type '%s' flags %c:%c:%c:%c:%c:%c:%c:%c",
+			field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2),
+			GET_INTR_TARGET(field2),
+			usbssp_trb_type_string(type),
+			field3 & TRB_BEI ? 'B' : 'b',
+			field3 & TRB_IDT ? 'I' : 'i',
+			field3 & TRB_IOC ? 'I' : 'i',
+			field3 & TRB_CHAIN ? 'C' : 'c',
+			field3 & TRB_NO_SNOOP ? 'S' : 's',
+			field3 & TRB_ISP ? 'I' : 'i',
+			field3 & TRB_ENT ? 'E' : 'e',
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+
+	case TRB_CMD_NOOP:
+	case TRB_ENABLE_SLOT:
+		sprintf(str,
+			"%s: flags %c",
+			usbssp_trb_type_string(type),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_DISABLE_SLOT:
+		sprintf(str,
+			"%s: slot %d flags %c",
+			usbssp_trb_type_string(type),
+			TRB_TO_SLOT_ID(field3),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_ADDR_DEV:
+		sprintf(str,
+			"%s: ctx %08x%08x slot %d flags %c:%c",
+			usbssp_trb_type_string(type),
+			field1, field0,
+			TRB_TO_SLOT_ID(field3),
+			field3 & TRB_BSR ? 'B' : 'b',
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_CONFIG_EP:
+		sprintf(str,
+			"%s: ctx %08x%08x slot %d flags %c:%c",
+			usbssp_trb_type_string(type),
+			field1, field0,
+			TRB_TO_SLOT_ID(field3),
+			field3 & TRB_DC ? 'D' : 'd',
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_EVAL_CONTEXT:
+		sprintf(str,
+			"%s: ctx %08x%08x slot %d flags %c",
+			usbssp_trb_type_string(type),
+			field1, field0,
+			TRB_TO_SLOT_ID(field3),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_RESET_EP:
+		sprintf(str,
+			"%s: ctx %08x%08x slot %d ep %d flags %c",
+			usbssp_trb_type_string(type),
+			field1, field0,
+			TRB_TO_SLOT_ID(field3),
+			/* Macro decrements 1, maybe it shouldn't?!? */
+			TRB_TO_EP_INDEX(field3) + 1,
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_STOP_RING:
+		sprintf(str,
+			"%s: slot %d sp %d ep %d flags %c",
+			usbssp_trb_type_string(type),
+			TRB_TO_SLOT_ID(field3),
+			TRB_TO_SUSPEND_PORT(field3),
+			/* Macro decrements 1, maybe it shouldn't?!? */
+			TRB_TO_EP_INDEX(field3) + 1,
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_SET_DEQ:
+		sprintf(str,
+			"%s: deq %08x%08x stream %d slot %d ep %d flags %c",
+			usbssp_trb_type_string(type),
+			field1, field0,
+			TRB_TO_STREAM_ID(field2),
+			TRB_TO_SLOT_ID(field3),
+			/* Macro decrements 1, maybe it shouldn't?!? */
+			TRB_TO_EP_INDEX(field3) + 1,
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_RESET_DEV:
+		sprintf(str,
+			"%s: slot %d flags %c",
+			usbssp_trb_type_string(type),
+			TRB_TO_SLOT_ID(field3),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_FORCE_EVENT:
+		sprintf(str,
+			"%s: event %08x%08x vf intr %d vf id %d flags %c",
+			usbssp_trb_type_string(type),
+			field1, field0,
+			TRB_TO_VF_INTR_TARGET(field2),
+			TRB_TO_VF_ID(field3),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_SET_LT:
+		sprintf(str,
+			"%s: belt %d flags %c",
+			usbssp_trb_type_string(type),
+			TRB_TO_BELT(field3),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	case TRB_FORCE_HEADER:
+		sprintf(str,
+			"%s: info %08x%08x%08x pkt type %d roothub port %d flags %c",
+			usbssp_trb_type_string(type),
+			field2, field1, field0 & 0xffffffe0,
+			TRB_TO_PACKET_TYPE(field0),
+			TRB_TO_DEV_PORT(field3),
+			field3 & TRB_CYCLE ? 'C' : 'c');
+		break;
+	default:
+		sprintf(str,
+			"type '%s' -> raw %08x %08x %08x %08x",
+			usbssp_trb_type_string(type),
+			field0, field1, field2, field3);
+	}
+
+	return str;
+}
+
+static inline const char *usbssp_decode_slot_context(u32 info, u32 info2,
+		u32 int_target, u32 state)
+{
+	static char str[1024];
+	u32 speed;
+	int ret = 0;
+
+	speed = info & DEV_SPEED;
+
+	ret = sprintf(str, "%s Ctx Entries %d MEL %d us",
+			({ char *s;
+			switch (speed) {
+			case SLOT_SPEED_FS:
+				s = "full-speed";
+				break;
+			case SLOT_SPEED_LS:
+				s = "low-speed";
+				break;
+			case SLOT_SPEED_HS:
+				s = "high-speed";
+				break;
+			case SLOT_SPEED_SS:
+				s = "super-speed";
+				break;
+			case SLOT_SPEED_SSP:
+				s = "super-speed plus";
+				break;
+			default:
+				s = "UNKNOWN speed";
+			} s; }),
+			(info & LAST_CTX_MASK) >> 27,
+			info2 & MAX_EXIT);
+
+	ret += sprintf(str + ret, " [Intr %d] Addr %d State %s",
+			GET_INTR_TARGET(int_target),
+			state & DEV_ADDR_MASK,
+			usbssp_slot_state_string(GET_SLOT_STATE(state)));
+
+	return str;
+}
+
+
+static inline const char *usbssp_portsc_link_state_string(u32 portsc)
+{
+	switch (portsc & PORT_PLS_MASK) {
+	case XDEV_U0:
+		return "U0";
+	case XDEV_U1:
+		return "U1";
+	case XDEV_U2:
+		return "U2";
+	case XDEV_U3:
+		return "U3";
+	case XDEV_DISABLED:
+		return "Disabled";
+	case XDEV_RXDETECT:
+		return "RxDetect";
+	case XDEV_INACTIVE:
+		return "Inactive";
+	case XDEV_POLLING:
+		return "Polling";
+	case XDEV_RECOVERY:
+		return "Recovery";
+	case XDEV_HOT_RESET:
+		return "Hot Reset";
+	case XDEV_COMP_MODE:
+		return "Compliance mode";
+	case XDEV_TEST_MODE:
+		return "Test mode";
+	case XDEV_RESUME:
+		return "Resume";
+	default:
+		break;
+	}
+	return "Unknown";
+}
+
+static inline const char *usbssp_decode_portsc(u32 portsc)
+{
+	static char str[256];
+	int ret;
+
+	ret = sprintf(str, "%s %s %s Link:%s PortSpeed:%d ",
+			portsc & PORT_POWER	? "Powered" : "Powered-off",
+			portsc & PORT_CONNECT	? "Connected" : "Not-connected",
+			portsc & PORT_PE	? "Enabled" : "Disabled",
+			usbssp_portsc_link_state_string(portsc),
+			DEV_PORT_SPEED(portsc));
+
+	if (portsc & PORT_OC)
+		ret += sprintf(str + ret, "OverCurrent ");
+	if (portsc & PORT_RESET)
+		ret += sprintf(str + ret, "In-Reset ");
+
+	ret += sprintf(str + ret, "Change: ");
+	if (portsc & PORT_CSC)
+		ret += sprintf(str + ret, "CSC ");
+	if (portsc & PORT_PEC)
+		ret += sprintf(str + ret, "PEC ");
+	if (portsc & PORT_WRC)
+		ret += sprintf(str + ret, "WRC ");
+	if (portsc & PORT_OCC)
+		ret += sprintf(str + ret, "OCC ");
+	if (portsc & PORT_RC)
+		ret += sprintf(str + ret, "PRC ");
+	if (portsc & PORT_PLC)
+		ret += sprintf(str + ret, "PLC ");
+	if (portsc & PORT_CEC)
+		ret += sprintf(str + ret, "CEC ");
+	ret += sprintf(str + ret, "Wake: ");
+	if (portsc & PORT_WKCONN_E)
+		ret += sprintf(str + ret, "WCE ");
+	if (portsc & PORT_WKDISC_E)
+		ret += sprintf(str + ret, "WDE ");
+	if (portsc & PORT_WKOC_E)
+		ret += sprintf(str + ret, "WOE ");
+
+	return str;
+}
+
+static inline const char *usbssp_ep_state_string(u8 state)
+{
+	switch (state) {
+	case EP_STATE_DISABLED:
+		return "disabled";
+	case EP_STATE_RUNNING:
+		return "running";
+	case EP_STATE_HALTED:
+		return "halted";
+	case EP_STATE_STOPPED:
+		return "stopped";
+	case EP_STATE_ERROR:
+		return "error";
+	default:
+		return "INVALID";
+	}
+}
+
+static inline const char *usbssp_ep_type_string(u8 type)
+{
+	switch (type) {
+	case ISOC_OUT_EP:
+		return "Isoc OUT";
+	case BULK_OUT_EP:
+		return "Bulk OUT";
+	case INT_OUT_EP:
+		return "Int OUT";
+	case CTRL_EP:
+		return "Ctrl";
+	case ISOC_IN_EP:
+		return "Isoc IN";
+	case BULK_IN_EP:
+		return "Bulk IN";
+	case INT_IN_EP:
+		return "Int IN";
+	default:
+		return "INVALID";
+	}
+}
+
+static inline const char *usbssp_decode_ep_context(u32 info, u32 info2, u64 deq,
+		u32 tx_info)
+{
+	static char str[1024];
+	int ret;
+
+	u32 esit;
+	u16 maxp;
+	u16 avg;
+
+	u8 max_pstr;
+	u8 ep_state;
+	u8 interval;
+	u8 ep_type;
+	u8 burst;
+	u8 cerr;
+	u8 mult;
+
+	bool lsa;
+	bool hid;
+
+	esit = CTX_TO_MAX_ESIT_PAYLOAD_HI(info) << 16 |
+		CTX_TO_MAX_ESIT_PAYLOAD(tx_info);
+
+	ep_state = info & EP_STATE_MASK;
+	max_pstr = CTX_TO_EP_MAXPSTREAMS(info);
+	interval = CTX_TO_EP_INTERVAL(info);
+	mult = CTX_TO_EP_MULT(info) + 1;
+	lsa = !!(info & EP_HAS_LSA);
+
+	cerr = (info2 & (3 << 1)) >> 1;
+	ep_type = CTX_TO_EP_TYPE(info2);
+	hid = !!(info2 & (1 << 7));
+	burst = CTX_TO_MAX_BURST(info2);
+	maxp = MAX_PACKET_DECODED(info2);
+
+	avg = EP_AVG_TRB_LENGTH(tx_info);
+
+	ret = sprintf(str, "State %s mult %d max P. Streams %d %s",
+			usbssp_ep_state_string(ep_state), mult,
+			max_pstr, lsa ? "LSA " : "");
+
+	ret += sprintf(str + ret, "interval %d us max ESIT payload %d CErr %d ",
+			(1 << interval) * 125, esit, cerr);
+
+	ret += sprintf(str + ret, "Type %s %sburst %d maxp %d deq %016llx ",
+			usbssp_ep_type_string(ep_type), hid ? "HID" : "",
+			burst, maxp, deq);
+
+	ret += sprintf(str + ret, "avg trb len %d", avg);
+
+	return str;
+}
+
+/**
+ * next_request - gets the next request on the given list
+ * @list: the request list to operate on
+ *
+ * Caller should take care of locking. This function return %NULL or the first
+ * request available on @list.
+ */
+static inline struct usbssp_request *next_request(struct list_head *list)
+{
+	return list_first_entry_or_null(list, struct usbssp_request, list);
+}
+
+struct usbssp_udc;
+#define to_usbssp_ep(ep) (container_of(ep, struct usbssp_ep, endpoint))
+#define gadget_to_usbssp(g) (container_of(g, struct usbssp_udc, gadget))
+#define request_to_usbssp_request(r) (container_of(r, struct usbssp_request, request))
+
+#define to_usbssp_request(r) (container_of(r, struct usbssp_request, request))
+
 #endif /* __LINUX_USBSSP_GADGET_H */

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

end of thread, other threads:[~2018-09-11  9:01 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-12 17:07 [02/31] usb: usbssp: Added some decoding functions Greg Kroah-Hartman
  -- strict thread matches above, loose matches on Subject: below --
2018-09-11  9:01 Pawel Laszczak
2018-09-11  8:12 Greg Kroah-Hartman
2018-09-11  5:48 Felipe Balbi
2018-09-10 18:18 Greg Kroah-Hartman
2018-07-19 17:57 Pawel Laszczak
2018-07-12 16:43 Pawel Laszczak
2018-07-12  6:35 Greg Kroah-Hartman
2018-07-12  6:28 Pawel Laszczak
2018-07-12  6:10 Greg Kroah-Hartman
2018-07-12  5:46 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).