All of lore.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>,
	open list <linux-kernel@vger.kernel.org>
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.

WARNING: multiple messages have this Message-ID (diff)
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: 54+ 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 ` Tatyana Brokhman
2011-06-16 13:31 ` [PATCH/RFC 3/5] usb:g_zero: bulk in/out unittest support Tatyana Brokhman
2011-06-16 13:31   ` Tatyana Brokhman
2011-06-16 16:25   ` Felipe Balbi
     [not found] ` <1308231068-24038-2-git-send-email-tlinder-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2011-06-16 13:31   ` [PATCH/RFC 2/5] usb:dummy_hcd: connect/disconnect test support Tatyana Brokhman
2011-06-16 13:31     ` Tatyana Brokhman
2011-06-16 15:06     ` Alan Stern
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:06           ` Alan Stern
2011-06-16 17:19           ` Alan Stern
2011-06-16 17:19             ` Alan Stern
2011-06-16 15:17     ` Alan Stern
2011-06-16 15:17       ` Alan Stern
2011-06-16 16:18     ` 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 13:31     ` Tatyana Brokhman
2011-06-16 15:09     ` Alan Stern
2011-06-16 15:09       ` Alan Stern
2011-06-16 13:31 ` Tatyana Brokhman [this message]
2011-06-16 13:31   ` [PATCH/RFC 5/5] usb: Add support for streams alloc/dealloc to devio.c Tatyana Brokhman
     [not found]   ` <1308231068-24038-6-git-send-email-tlinder-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2011-06-16 15:20     ` Alan Stern
2011-06-16 15:20       ` Alan Stern
2011-06-30 17:45     ` Sarah Sharp
2011-06-30 17:45       ` Sarah Sharp
2011-06-30 18:39       ` William Gulland
2011-06-30 18:39         ` William Gulland
2011-06-30 18:41       ` Tanya Brokhman
2011-06-30 18:41         ` Tanya Brokhman
2011-07-19  9:12       ` Amit Blay
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:07             ` Amit Blay
2011-07-19 10:26             ` Oliver Neukum
2011-07-19 10:36               ` Amit Blay
2011-07-19 10:36                 ` Amit Blay
2011-07-27  6:21         ` Amit Blay
     [not found]           ` <a9d8b0f164cdb51e88125d8432644213.squirrel-mMfbam+mt9083fI46fginR2eb7JE58TQ@public.gmane.org>
2011-08-17  7:06             ` Hans Petter Selasky
2011-08-17  7:06               ` Hans Petter Selasky
2011-08-18 22:47           ` Sarah Sharp
2011-08-21 10:18             ` Amit Blay
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
2011-06-16 16:28   ` Felipe Balbi
2011-06-16 18:21     ` Greg KH
2011-06-17  8:55       ` ablay
2011-06-17  8:55         ` ablay
2011-06-17 14:35         ` Alan Stern
2011-06-17 14:35           ` Alan Stern

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 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.