public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Tatyana Brokhman <tlinder@codeaurora.org>
To: greg@kroah.com
Cc: linux-usb@vger.kernel.org, linux-arm-msm@vger.kernel.org,
	balbi@ti.com, ablay@codeaurora.org,
	Tatyana Brokhman <tlinder@codeaurora.org>,
	Amit Blay <ablay@qualcomm.com>,
	linux-kernel@vger.kernel.org (open list)
Subject: [PATCH/RFC 5/5] usb: Add support for streams alloc/dealloc to devio.c
Date: Thu, 16 Jun 2011 16:31:07 +0300	[thread overview]
Message-ID: <1308231068-24038-6-git-send-email-tlinder@codeaurora.org> (raw)
In-Reply-To: <1308231068-24038-2-git-send-email-tlinder@codeaurora.org>

Allow user space applications such as LIBUSB, to request
streams alloc/dealloc from HCD that implements XHCI.

Signed-off-by: Amit Blay <ablay@qualcomm.com>
Signed-off-by: Tatyana Brokhman <tlinder@codeaurora.org>

---
 drivers/usb/core/devio.c     |  128 +++++++++++++++++++++++++++++++++++++++++-
 include/linux/usbdevice_fs.h |    5 ++
 2 files changed, 132 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 37518df..7e73e35 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -943,6 +943,115 @@ static int proc_clearhalt(struct dev_state *ps, void __user *arg)
 	return usb_clear_halt(ps->dev, pipe);
 }
 
+static int proc_allocstreams(struct dev_state *ps, void __user *arg)
+{
+	unsigned int ep_map;
+	int ret;
+	int intf_num;
+	struct usb_interface *intf = NULL;
+	const int max_eps = 32;
+	int max_streams = 0;
+	struct usb_host_endpoint *eps[max_eps];
+	int num_eps = 0;
+	int i;
+	unsigned int ep;
+
+	if (get_user(ep_map, (unsigned int __user *)arg))
+		return -EFAULT;
+
+	for (i = 0; i < max_eps; i++) {
+		if (ep_map & (0x1 << i)) {
+			/* Convert from i to ep address */
+			if (i < 16) /* IN EP */
+				ep = i | USB_ENDPOINT_DIR_MASK;
+			else /* OUT EP */
+				ep = (i - 16);
+
+			intf_num = findintfep(ps->dev, ep);
+			if (intf_num < 0)
+				return intf_num;
+			ret = checkintf(ps, intf_num);
+			if (ret)
+				return ret;
+			intf = usb_ifnum_to_if(ps->dev, intf_num);
+			if (!intf)
+				return -ENOENT;
+
+			if (ep & USB_ENDPOINT_DIR_MASK)
+				eps[num_eps] = ps->dev->ep_in[ep &
+					USB_ENDPOINT_NUMBER_MASK];
+			else
+				eps[num_eps] = ps->dev->ep_out[ep &
+					USB_ENDPOINT_NUMBER_MASK];
+
+			if (!max_streams)
+				max_streams = USB_SS_MAX_STREAMS(
+					eps[num_eps]->ss_ep_comp.bmAttributes);
+
+			num_eps++;
+		}
+	}
+
+	if (!intf || !max_streams)
+		return -ENOENT;
+
+	ret = usb_alloc_streams(intf, eps, num_eps, max_streams, GFP_KERNEL);
+	if (ret > 0)
+		return 0;
+	return ret;
+}
+
+static int proc_freestreams(struct dev_state *ps, void __user *arg)
+{
+	unsigned int ep_map;
+	int ret;
+	int intf_num;
+	struct usb_interface *intf = NULL;
+	const int max_eps = 32;
+	struct usb_host_endpoint *eps[max_eps];
+	int num_eps = 0;
+	int i;
+	unsigned int ep;
+
+	if (get_user(ep_map, (unsigned int __user *)arg))
+		return -EFAULT;
+
+	for (i = 0; i < max_eps; i++) {
+		if (ep_map & (0x1 << i)) {
+			/* Convert from i to ep address */
+			if (i < 16) /* IN EP */
+				ep = i | USB_ENDPOINT_DIR_MASK;
+			else /* OUT EP */
+				ep = (i - 16);
+
+			intf_num = findintfep(ps->dev, ep);
+			if (intf_num < 0)
+				return intf_num;
+			ret = checkintf(ps, intf_num);
+			if (ret)
+				return ret;
+			intf = usb_ifnum_to_if(ps->dev, intf_num);
+			if (!intf)
+				return -ENOENT;
+
+			if (ep & USB_ENDPOINT_DIR_MASK)
+				eps[num_eps] = ps->dev->ep_in[ep &
+					USB_ENDPOINT_NUMBER_MASK];
+			else
+				eps[num_eps] = ps->dev->ep_out[ep &
+					USB_ENDPOINT_NUMBER_MASK];
+
+			num_eps++;
+		}
+	}
+
+	if (!intf)
+		return -ENOENT;
+
+	usb_free_streams(intf, eps, num_eps, GFP_KERNEL);
+	return 0;
+}
+
 static int proc_getdriver(struct dev_state *ps, void __user *arg)
 {
 	struct usbdevfs_getdriver gd;
@@ -1236,6 +1345,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
 		u |= URB_NO_INTERRUPT;
 	as->urb->transfer_flags = u;
 
+	as->urb->stream_id = (uurb->type == USBDEVFS_URB_TYPE_BULK) ?
+		uurb->stream_id : 0;
 	as->urb->transfer_buffer_length = uurb->buffer_length;
 	as->urb->setup_packet = (unsigned char *)dr;
 	as->urb->start_frame = uurb->start_frame;
@@ -1491,7 +1602,8 @@ static int get_urb32(struct usbdevfs_urb *kurb,
 	    __get_user(kurb->start_frame, &uurb->start_frame) ||
 	    __get_user(kurb->number_of_packets, &uurb->number_of_packets) ||
 	    __get_user(kurb->error_count, &uurb->error_count) ||
-	    __get_user(kurb->signr, &uurb->signr))
+	    __get_user(kurb->signr, &uurb->signr) ||
+	    __get_user(kurb->stream_id, &uurb->stream_id))
 		return -EFAULT;
 
 	if (__get_user(uptr, &uurb->buffer))
@@ -1795,6 +1907,20 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
 			inode->i_mtime = CURRENT_TIME;
 		break;
 
+	case USBDEVFS_ALLOC_STREAMS:
+		snoop(&dev->dev, "%s: ALLOC_STREAMS\n", __func__);
+		ret = proc_allocstreams(ps, p);
+		if (ret >= 0)
+			inode->i_mtime = CURRENT_TIME;
+		break;
+
+	case USBDEVFS_FREE_STREAMS:
+		snoop(&dev->dev, "%s: FREE_STREAMS\n", __func__);
+		ret = proc_freestreams(ps, p);
+		if (ret >= 0)
+			inode->i_mtime = CURRENT_TIME;
+		break;
+
 	case USBDEVFS_GETDRIVER:
 		snoop(&dev->dev, "%s: GETDRIVER\n", __func__);
 		ret = proc_getdriver(ps, p);
diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h
index 15591d2..133c216 100644
--- a/include/linux/usbdevice_fs.h
+++ b/include/linux/usbdevice_fs.h
@@ -108,6 +108,7 @@ struct usbdevfs_urb {
 				  or 0 if none should be sent. */
 	void __user *usercontext;
 	struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+	unsigned int stream_id;
 };
 
 /* ioctls for talking directly to drivers */
@@ -165,6 +166,7 @@ struct usbdevfs_urb32 {
 	compat_uint_t signr;
 	compat_caddr_t usercontext; /* unused */
 	struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+	compat_uint_t stream_id;
 };
 
 struct usbdevfs_ioctl32 {
@@ -204,4 +206,7 @@ struct usbdevfs_ioctl32 {
 #define USBDEVFS_CONNECT           _IO('U', 23)
 #define USBDEVFS_CLAIM_PORT        _IOR('U', 24, unsigned int)
 #define USBDEVFS_RELEASE_PORT      _IOR('U', 25, unsigned int)
+#define USBDEVFS_ALLOC_STREAMS     _IOR('U', 26, unsigned int)
+#define USBDEVFS_FREE_STREAMS      _IOR('U', 27, unsigned int)
+
 #endif /* _LINUX_USBDEVICE_FS_H */
-- 
1.7.3.3

--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

  parent reply	other threads:[~2011-06-16 13:32 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-16 13:31 [PATCH/RFC 1/5] usb:tools: usb unittests framework Tatyana Brokhman
2011-06-16 13:31 ` [PATCH/RFC 2/5] usb:dummy_hcd: connect/disconnect test support Tatyana Brokhman
2011-06-16 15:06   ` Alan Stern
2011-06-16 16:16     ` Felipe Balbi
2011-06-16 17:06       ` Alan Stern
2011-06-16 17:19         ` Alan Stern
2011-06-16 15:17   ` Alan Stern
2011-06-16 16:18   ` Felipe Balbi
2011-06-16 13:31 ` [PATCH/RFC 3/5] usb:g_zero: bulk in/out unittest support Tatyana Brokhman
2011-06-16 16:25   ` Felipe Balbi
2011-06-16 13:31 ` [PATCH/RFC 4/5] usb:dummy_hcd: Disable single-request fifo in dummy hcd Tatyana Brokhman
2011-06-16 15:09   ` Alan Stern
2011-06-16 13:31 ` Tatyana Brokhman [this message]
2011-06-16 15:20   ` [PATCH/RFC 5/5] usb: Add support for streams alloc/dealloc to devio.c Alan Stern
2011-06-16 16:28   ` Felipe Balbi
2011-06-16 18:21     ` Greg KH
2011-06-17  8:55       ` ablay
2011-06-17 14:35         ` Alan Stern
2011-06-30 17:45   ` Sarah Sharp
2011-06-30 18:39     ` William Gulland
2011-06-30 18:41     ` Tanya Brokhman
2011-07-19  9:12     ` Amit Blay
2011-07-19  9:18       ` Oliver Neukum
2011-07-19 10:07         ` Amit Blay
2011-07-19 10:26           ` Oliver Neukum
2011-07-19 10:36             ` Amit Blay
2011-07-27  6:21       ` Amit Blay
2011-08-17  7:06         ` Hans Petter Selasky
2011-08-18 22:47         ` Sarah Sharp
2011-08-21 10:18           ` Amit Blay
2011-08-22  7:58             ` Hans Petter Selasky
2011-08-22  7:56           ` Hans Petter Selasky
2011-08-22 16:41             ` Sarah Sharp

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=1308231068-24038-6-git-send-email-tlinder@codeaurora.org \
    --to=tlinder@codeaurora.org \
    --cc=ablay@codeaurora.org \
    --cc=ablay@qualcomm.com \
    --cc=balbi@ti.com \
    --cc=greg@kroah.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox