[PATCH v3 02/10] usb: gadget: add anonymous definition in struct usb_request

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Some UDC trace event will save usb request information, but it will use
one int size buffer to save one bit information of usb request, so more
than one int buffer to save several bit fields which is not good.

First add an anonymous union which have one u32 member dw1 which can be
used by trace event during fast assign stage to reduce trace buffer
usage, add related macro to extract bit fields from dw1 for later trace
event output state usage.

Also move exist stread_id and other bit fields into one anonymous struct
which inside anonymous union, change them from unsigned to u32 type,
it will make sure union member have same memory size as dw1.

In order to allow trace event output stage access the bit from saved u32
'dw1', add following macros,
define USB_REQ_BITFIELD(n, name) \
	({\
	union {\
		struct {\
			u32	stream_id:16;\
			u32	is_last:1;\
			u32	no_interrupt:1;\
			u32	zero:1;\
			u32	short_not_ok:1;\
			u32	dma_mapped:1;\
		} __packed;\
		u32		dw1;\
	} __aligned(4) __r_u_##name;\
	u32 __r_##name; \
	BUILD_BUG_ON(sizeof(__r_u_##name) != 4);\
	__r_u_##name.dw1 = (n); __r_##name = __r_u_##name.name;\
	__r_##name; })

define USB_REQ_STREAM_ID(n) USB_REQ_BITFIELD((n), stream_id)
...
change to use this kind of macros for all related trace files later.

Signed-off-by: Linyu Yuan <quic_linyyuan@xxxxxxxxxxx>
---
v2: no change
v3: change method to extract bit field

 include/linux/usb/gadget.h | 43 ++++++++++++++++++++++++++++++++------
 1 file changed, 37 insertions(+), 6 deletions(-)

diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index f02e1bd20924..a1717c633942 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -41,6 +41,7 @@ struct usb_ep;
  * @num_sgs: number of SG entries
  * @num_mapped_sgs: number of SG entries mapped to DMA (internal)
  * @length: Length of that data
+ * @dw1: trace event purpose
  * @stream_id: The stream id, when USB3.0 bulk streams are being used
  * @is_last: Indicates if this is the last request of a stream_id before
  *	switching to a different stream (required for DWC3 controllers).
@@ -105,12 +106,17 @@ struct usb_request {
 	unsigned		num_sgs;
 	unsigned		num_mapped_sgs;
 
-	unsigned		stream_id:16;
-	unsigned		is_last:1;
-	unsigned		no_interrupt:1;
-	unsigned		zero:1;
-	unsigned		short_not_ok:1;
-	unsigned		dma_mapped:1;
+	union {
+		struct {
+			u32	stream_id:16;
+			u32	is_last:1;
+			u32	no_interrupt:1;
+			u32	zero:1;
+			u32	short_not_ok:1;
+			u32	dma_mapped:1;
+		} __packed;
+		u32		dw1;
+	} __aligned(4);
 
 	void			(*complete)(struct usb_ep *ep,
 					struct usb_request *req);
@@ -123,6 +129,31 @@ struct usb_request {
 	unsigned		actual;
 };
 
+#define USB_REQ_BITFIELD(n, name) \
+	({\
+	union {\
+		struct {\
+			u32	stream_id:16;\
+			u32	is_last:1;\
+			u32	no_interrupt:1;\
+			u32	zero:1;\
+			u32	short_not_ok:1;\
+			u32	dma_mapped:1;\
+		} __packed;\
+		u32		dw1;\
+	} __aligned(4) __r_u_##name;\
+	u32 __r_##name; \
+	BUILD_BUG_ON(sizeof(__r_u_##name) != 4);\
+	__r_u_##name.dw1 = (n); __r_##name = __r_u_##name.name;\
+	__r_##name; })
+
+#define USB_REQ_STREAM_ID(n) USB_REQ_BITFIELD((n), stream_id)
+#define USB_REQ_IS_LAST(n) USB_REQ_BITFIELD((n), stream_id)
+#define USB_REQ_NO_INTERRUPT(n) USB_REQ_BITFIELD((n), stream_id)
+#define USB_REQ_ZERO(n) USB_REQ_BITFIELD((n), stream_id)
+#define USB_REQ_SHORT_NOT_OK(n) USB_REQ_BITFIELD((n), stream_id)
+#define USB_REQ_DMA_MAPPED(n) USB_REQ_BITFIELD((n), stream_id)
+
 /*-------------------------------------------------------------------------*/
 
 /* endpoint-specific parts of the api to the usb controller hardware.
-- 
2.17.1




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux