All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Diego Elio Pettenò" <flameeyes@flameeyes.com>
To: linux-usb@vger.kernel.org
Cc: "Diego Elio Pettenò" <flameeyes@flameeyes.com>,
	"Pete Zaitcev" <zaitcev@redhat.com>,
	"Paolo Abeni" <pabeni@redhat.com>,
	"Kris Katterjohn" <katterjohn@gmail.com>,
	"Greg KH" <gregkh@linuxfoundation.org>
Subject: [PATCH v3 2/2] usbmon: expose the usbmon structures and constants as an UAPI header.
Date: Mon,  6 Jul 2020 14:10:14 +0100	[thread overview]
Message-ID: <20200706131014.19064-2-flameeyes@flameeyes.com> (raw)
In-Reply-To: <20200706131014.19064-1-flameeyes@flameeyes.com>

Previously any application wanting to implement the usbmon binary
interfaces needed to re-declare the structures and constants, leading to
structure duplication and confusion over whether these structures fall into
the system call exception or not.

Cc: linux-usb@vger.kernel.org
Cc: Pete Zaitcev <zaitcev@redhat.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Kris Katterjohn <katterjohn@gmail.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Signed-off-by: Diego Elio Pettenò <flameeyes@flameeyes.com>
---
 Documentation/usb/usbmon.rst |  70 ++++++++++++-----------
 drivers/usb/mon/mon_bin.c    |  92 +-----------------------------
 include/uapi/linux/usb/mon.h | 107 +++++++++++++++++++++++++++++++++++
 3 files changed, 145 insertions(+), 124 deletions(-)
 create mode 100644 include/uapi/linux/usb/mon.h

diff --git a/Documentation/usb/usbmon.rst b/Documentation/usb/usbmon.rst
index e9ec7e40b3bf..31c14b38fd03 100644
--- a/Documentation/usb/usbmon.rst
+++ b/Documentation/usb/usbmon.rst
@@ -211,35 +211,37 @@ Bulk wrapper to a storage device at address 5::
 Raw binary format and API
 =========================
 
-The overall architecture of the API is about the same as the one above,
-only the events are delivered in binary format. Each event is sent in
-the following structure (its name is made up, so that we can refer to it)::
-
-  struct usbmon_packet {
-	u64 id;			/*  0: URB ID - from submission to callback */
-	unsigned char type;	/*  8: Same as text; extensible. */
-	unsigned char xfer_type; /*    ISO (0), Intr, Control, Bulk (3) */
-	unsigned char epnum;	/*     Endpoint number and transfer direction */
-	unsigned char devnum;	/*     Device address */
-	u16 busnum;		/* 12: Bus number */
-	char flag_setup;	/* 14: Same as text */
-	char flag_data;		/* 15: Same as text; Binary zero is OK. */
-	s64 ts_sec;		/* 16: gettimeofday */
-	s32 ts_usec;		/* 24: gettimeofday */
-	int status;		/* 28: */
-	unsigned int length;	/* 32: Length of data (submitted or actual) */
-	unsigned int len_cap;	/* 36: Delivered length */
+The overall architecture of the API is about the same as the one above, only the
+events are delivered in binary format. The structures and constants are defined
+in include/uapi/linux/usb/mon.h.
+
+Each event is sent in the following structure::
+
+  struct mon_bin_hdr {
+	__u64 id;		/*  0: URB ID - from submission to callback */
+	__u8 type;		/*  8: Same as text; extensible. */
+	__u8 xfer_type;		/*    ISO (0), Intr, Control, Bulk (3) */
+	__u8 epnum;		/*     Endpoint number and transfer direction */
+	__u8 devnum;		/*     Device address */
+	__u16 busnum;		/* 12: Bus number */
+	__s8 flag_setup;	/* 14: Same as text */
+	__s8 flag_data;		/* 15: Same as text; Binary zero is OK. */
+	__s64 ts_sec;		/* 16: gettimeofday */
+	__s32 ts_usec;		/* 24: gettimeofday */
+	__s32 status;		/* 28: */
+	__u32 length;		/* 32: Length of data (submitted or actual) */
+	__u32 len_cap;		/* 36: Delivered length */
 	union {			/* 40: */
-		unsigned char setup[SETUP_LEN];	/* Only for Control S-type */
+		__u8 setup[MON_USB_SETUP_LEN];	/* Only for Control S-type */
 		struct iso_rec {		/* Only for ISO */
-			int error_count;
-			int numdesc;
+			__s32 error_count;
+			__s32 numdesc;
 		} iso;
 	} s;
-	int interval;		/* 48: Only for Interrupt and ISO */
-	int start_frame;	/* 52: For ISO */
-	unsigned int xfer_flags; /* 56: copy of URB's transfer_flags */
-	unsigned int ndesc;	/* 60: Actual number of ISO descriptors */
+	__s32 interval;		/* 48: Only for Interrupt and ISO */
+	__s32 start_frame;	/* 52: For ISO */
+	__u32 xfer_flags;	/* 56: copy of URB's transfer_flags */
+	__u32 ndesc;		/* 60: Actual number of ISO descriptors */
   };				/* 64 total length */
 
 These events can be received from a character device by reading with read(2),
@@ -267,8 +269,8 @@ no events are available.
 The argument is a pointer to the following structure::
 
   struct mon_bin_stats {
-	u32 queued;
-	u32 dropped;
+	__u32 queued;
+	__u32 dropped;
   };
 
 The member "queued" refers to the number of events currently queued in the
@@ -296,9 +298,9 @@ then return the first event. The argument is a pointer to the following
 structure::
 
   struct mon_get_arg {
-	struct usbmon_packet *hdr;
+	struct mon_bin_hdr *hdr;
 	void *data;
-	size_t alloc;		/* Length of data (can be zero) */
+	__kernel_size_t alloc;		/* Length of data (can be zero) */
   };
 
 Before the call, hdr, data, and alloc should be filled. Upon return, the area
@@ -313,9 +315,9 @@ This ioctl is primarily used when the application accesses the buffer
 with mmap(2). Its argument is a pointer to the following structure::
 
   struct mon_mfetch_arg {
-	uint32_t *offvec;	/* Vector of events fetched */
-	uint32_t nfetch;	/* Number of events to fetch (out: fetched) */
-	uint32_t nflush;	/* Number of events to flush */
+	__u32 *offvec;	/* Vector of events fetched */
+	__u32 nfetch;	/* Number of events to fetch (out: fetched) */
+	__u32 nflush;	/* Number of events to flush */
   };
 
 The ioctl operates in 3 stages.
@@ -350,7 +352,7 @@ To prepare, map the buffer by getting the current size, then using mmap(2).
 Then, execute a loop similar to the one written in pseudo-code below::
 
    struct mon_mfetch_arg fetch;
-   struct usbmon_packet *hdr;
+   struct mon_bin_hdr *hdr;
    int nflush = 0;
    for (;;) {
       fetch.offvec = vec; // Has N 32-bit words
@@ -359,7 +361,7 @@ Then, execute a loop similar to the one written in pseudo-code below::
       ioctl(fd, MON_IOCX_MFETCH, &fetch);   // Process errors, too
       nflush = fetch.nfetch;       // This many packets to flush when done
       for (i = 0; i < nflush; i++) {
-         hdr = (struct ubsmon_packet *) &mmap_area[vec[i]];
+         hdr = (struct mon_bin_hdr *) &mmap_area[vec[i]];
          if (hdr->type == '@')     // Filler packet
             continue;
          caddr_t data = &mmap_area[vec[i]] + 64;
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index f48a23adbc35..e1a7e69a3b0c 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -23,34 +23,10 @@
 #include <linux/time64.h>
 
 #include <linux/uaccess.h>
+#include <linux/usb/mon.h>
 
 #include "usb_mon.h"
 
-/*
- * Defined by USB 2.0 clause 9.3, table 9.2.
- */
-#define SETUP_LEN  8
-
-/* ioctl macros */
-#define MON_IOC_MAGIC 0x92
-
-#define MON_IOCQ_URB_LEN _IO(MON_IOC_MAGIC, 1)
-/* #2 used to be MON_IOCX_URB, removed before it got into Linus tree */
-#define MON_IOCG_STATS _IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats)
-#define MON_IOCT_RING_SIZE _IO(MON_IOC_MAGIC, 4)
-#define MON_IOCQ_RING_SIZE _IO(MON_IOC_MAGIC, 5)
-#define MON_IOCX_GET   _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get)
-#define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch)
-#define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8)
-/* #9 was MON_IOCT_SETAPI */
-#define MON_IOCX_GETX   _IOW(MON_IOC_MAGIC, 10, struct mon_bin_get)
-
-#ifdef CONFIG_COMPAT
-#define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32)
-#define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32)
-#define MON_IOCX_GETX32   _IOW(MON_IOC_MAGIC, 10, struct mon_bin_get32)
-#endif
-
 /*
  * Some architectures have enormous basic pages (16KB for ia64, 64KB for ppc).
  * But it's all right. Just use a simple way to make sure the chunk is never
@@ -81,38 +57,6 @@
 #define BUFF_DFL   CHUNK_ALIGN(300*1024)
 #define BUFF_MIN     CHUNK_ALIGN(8*1024)
 
-/*
- * The per-event API header (2 per URB).
- *
- * This structure is seen in userland as defined by the documentation.
- */
-struct mon_bin_hdr {
-	u64 id;			/* URB ID - from submission to callback */
-	unsigned char type;	/* Same as in text API; extensible. */
-	unsigned char xfer_type;	/* ISO, Intr, Control, Bulk */
-	unsigned char epnum;	/* Endpoint number and transfer direction */
-	unsigned char devnum;	/* Device address */
-	unsigned short busnum;	/* Bus number */
-	char flag_setup;
-	char flag_data;
-	s64 ts_sec;		/* ktime_get_real_ts64 */
-	s32 ts_usec;		/* ktime_get_real_ts64 */
-	int status;
-	unsigned int len_urb;	/* Length of data (submitted or actual) */
-	unsigned int len_cap;	/* Delivered length */
-	union {
-		unsigned char setup[SETUP_LEN];	/* Only for Control S-type */
-		struct iso_rec {
-			int error_count;
-			int numdesc;
-		} iso;
-	} s;
-	int interval;
-	int start_frame;
-	unsigned int xfer_flags;
-	unsigned int ndesc;	/* Actual number of ISO descriptors */
-};
-
 /*
  * ISO vector, packed into the head of data stream.
  * This has to take 16 bytes to make sure that the end of buffer
@@ -125,38 +69,6 @@ struct mon_bin_isodesc {
 	u32 _pad;
 };
 
-/* per file statistic */
-struct mon_bin_stats {
-	u32 queued;
-	u32 dropped;
-};
-
-struct mon_bin_get {
-	struct mon_bin_hdr __user *hdr;	/* Can be 48 bytes or 64. */
-	void __user *data;
-	size_t alloc;		/* Length of data (can be zero) */
-};
-
-struct mon_bin_mfetch {
-	u32 __user *offvec;	/* Vector of events fetched */
-	u32 nfetch;		/* Number of events to fetch (out: fetched) */
-	u32 nflush;		/* Number of events to flush */
-};
-
-#ifdef CONFIG_COMPAT
-struct mon_bin_get32 {
-	u32 hdr32;
-	u32 data32;
-	u32 alloc32;
-};
-
-struct mon_bin_mfetch32 {
-        u32 offvec32;
-        u32 nfetch32;
-        u32 nflush32;
-};
-#endif
-
 /* Having these two values same prevents wrapping of the mon_bin_hdr */
 #define PKT_ALIGN   64
 #define PKT_SIZE    64
@@ -396,7 +308,7 @@ static inline char mon_bin_get_setup(unsigned char *setupb,
 
 	if (urb->setup_packet == NULL)
 		return 'Z';
-	memcpy(setupb, urb->setup_packet, SETUP_LEN);
+	memcpy(setupb, urb->setup_packet, MON_USB_SETUP_LEN);
 	return 0;
 }
 
diff --git a/include/uapi/linux/usb/mon.h b/include/uapi/linux/usb/mon.h
new file mode 100644
index 000000000000..3557fe6a93e6
--- /dev/null
+++ b/include/uapi/linux/usb/mon.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * USB Monitoring (usbmon) definitions
+ *
+ * See documentation in Documentation/usb/usbmon.rst.
+ *
+ * Copyright (C) 2006 Paolo Abeni (paolo.abeni@email.it)
+ * Copyright (C) 2006,2007 Pete Zaitcev (zaitcev@redhat.com)
+ */
+
+#ifndef __UAPI_LINUX_USB_MON_H
+#define __UAPI_LINUX_USB_MON_H
+
+#include <linux/types.h>
+
+/* ioctl macros */
+#define MON_IOC_MAGIC 0x92
+
+#define MON_IOCQ_URB_LEN	_IO(MON_IOC_MAGIC, 1)
+/* #2 used to be MON_IOCX_URB, removed before it got into Linus tree */
+#define MON_IOCG_STATS		_IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats)
+#define MON_IOCT_RING_SIZE	_IO(MON_IOC_MAGIC, 4)
+#define MON_IOCQ_RING_SIZE	_IO(MON_IOC_MAGIC, 5)
+#define MON_IOCX_GET		_IOW(MON_IOC_MAGIC, 6, struct mon_bin_get)
+#define MON_IOCX_MFETCH		_IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch)
+#define MON_IOCH_MFLUSH		_IO(MON_IOC_MAGIC, 8)
+/* #9 was MON_IOCT_SETAPI */
+#define MON_IOCX_GETX		_IOW(MON_IOC_MAGIC, 10, struct mon_bin_get)
+
+/* ioctl structures */
+
+/* per file statistic */
+struct mon_bin_stats {
+	__u32 queued;
+	__u32 dropped;
+};
+
+struct mon_bin_get {
+	struct mon_bin_hdr __user *hdr;	/* Can be 48 bytes or 64. */
+	void __user *data;
+	size_t alloc;		/* Length of data (can be zero) */
+};
+
+struct mon_bin_mfetch {
+	__u32 __user *offvec;	/* Vector of events fetched */
+	__u32 nfetch;		/* Number of events to fetch (out: fetched) */
+	__u32 nflush;		/* Number of events to flush */
+};
+
+
+/* Only defined with CONFIG_COMPAT */
+#define MON_IOCX_GET32		_IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32)
+#define MON_IOCX_MFETCH32	_IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32)
+#define MON_IOCX_GETX32		_IOW(MON_IOC_MAGIC, 10, struct mon_bin_get32)
+
+struct mon_bin_get32 {
+	__u32 hdr32;
+	__u32 data32;
+	__u32 alloc32;
+};
+
+struct mon_bin_mfetch32 {
+	__u32 offvec32;
+	__u32 nfetch32;
+	__u32 nflush32;
+};
+
+/* Data format */
+
+/*
+ * Defined by USB 2.0 clause 9.3, table 9.2.
+ */
+#define MON_USB_SETUP_LEN  8
+
+/*
+ * The per-event API header (2 per URB).
+ *
+ * This structure is seen in userland as defined by the documentation.
+ */
+struct mon_bin_hdr {
+	__u64 id;	/* URB ID - from submission to callback */
+	__u8 type;	/* Same as in text API; extensible. */
+	__u8 xfer_type;	/* ISO, Intr, Control, Bulk */
+	__u8 epnum;	/* Endpoint number and transfer direction */
+	__u8 devnum;	/* Device address */
+	__u16 busnum;	/* Bus number */
+	__s8 flag_setup;
+	__s8 flag_data;
+	__s64 ts_sec;	/* ktime_get_real_ts64 */
+	__s32 ts_usec;	/* ktime_get_real_ts64 */
+	__s32 status;
+	__u32 len_urb;	/* Length of data (submitted or actual) */
+	__u32 len_cap;	/* Delivered length */
+	union {
+		__u8 setup[MON_USB_SETUP_LEN];	/* Only for Control S-type */
+		struct iso_rec {
+			__s32 error_count;
+			__s32 numdesc;
+		} iso;
+	} s;
+	__s32 interval;
+	__s32 start_frame;
+	__u32 xfer_flags;
+	__u32 ndesc;	/* Actual number of ISO descriptors */
+};
+
+#endif /* __UAPI_LINUX_USB_MON_H */
-- 
2.27.0


  reply	other threads:[~2020-07-06 13:10 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-05 15:02 [PATCH] usbmon: expose the usbmon structures and constants as an UAPI header Diego Elio Pettenò
2020-07-06  3:51 ` Pete Zaitcev
2020-07-06  8:32   ` Diego Elio Pettenò
2020-07-06 15:01     ` Pete Zaitcev
2020-07-06  5:46 ` kernel test robot
2020-07-06  5:46   ` kernel test robot
2020-07-06 10:30 ` Greg KH
2020-07-06 12:21   ` Diego Elio Pettenò
2020-07-06 12:15 ` [PATCH v2] " Diego Elio Pettenò
2020-07-06 12:49   ` Greg KH
2020-07-06 13:10     ` Diego Elio Pettenò
2020-07-06 16:15     ` Pete Zaitcev
2020-07-06 13:10 ` [PATCH v3 1/2] Remove documentation line that adds nothing and sounds condescending Diego Elio Pettenò
2020-07-06 13:10   ` Diego Elio Pettenò [this message]
2020-07-06 16:35     ` [PATCH v3 2/2] usbmon: expose the usbmon structures and constants as an UAPI header Greg KH
2020-07-06 16:34   ` [PATCH v3 1/2] Remove documentation line that adds nothing and sounds condescending Greg KH
2020-07-06 22:44 ` [PATCH v4 " Diego Elio Pettenò
2020-07-06 22:44   ` [PATCH v4 2/2] usbmon: expose the usbmon structures and constants as an UAPI header Diego Elio Pettenò
2020-07-09 16:04     ` Greg KH
2020-07-11 13:14     ` kernel test robot
2020-07-11 13:14       ` kernel test robot
2020-07-09 16:03   ` [PATCH v4 1/2] Remove documentation line that adds nothing and sounds condescending Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200706131014.19064-2-flameeyes@flameeyes.com \
    --to=flameeyes@flameeyes.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=katterjohn@gmail.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=zaitcev@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.