From: Ming Lei <ming.lei@canonical.com>
To: "David S. Miller" <davem@davemloft.net>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Oliver Neukum <oneukum@suse.de>,
netdev@vger.kernel.org, linux-usb@vger.kernel.org,
Ming Lei <ming.lei@canonical.com>
Subject: [PATCH v2 01/11] usbnet: introduce usbnet 3 command helpers
Date: Thu, 25 Oct 2012 13:46:54 +0800 [thread overview]
Message-ID: <1351144024-16596-2-git-send-email-ming.lei@canonical.com> (raw)
In-Reply-To: <1351144024-16596-1-git-send-email-ming.lei@canonical.com>
This patch introduces the below 3 usb command helpers:
usbnet_read_cmd / usbnet_write_cmd / usbnet_write_cmd_async
so that each low level driver doesn't need to implement them
by itself, and the dma buffer allocation for usb transfer and
runtime PM things can be handled just in one place.
Acked-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
drivers/net/usb/usbnet.c | 132 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/usb/usbnet.h | 6 ++
2 files changed, 138 insertions(+)
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index f9819d1..447d20d 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1611,6 +1611,138 @@ void usbnet_device_suggests_idle(struct usbnet *dev)
EXPORT_SYMBOL(usbnet_device_suggests_idle);
/*-------------------------------------------------------------------------*/
+int usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
+ u16 value, u16 index, void *data, u16 size)
+{
+ void *buf = NULL;
+ int err = -ENOMEM;
+
+ netdev_dbg(dev->net, "usbnet_read_cmd cmd=0x%02x reqtype=%02x"
+ " value=0x%04x index=0x%04x size=%d\n",
+ cmd, reqtype, value, index, size);
+
+ if (data) {
+ buf = kmalloc(size, GFP_KERNEL);
+ if (!buf)
+ goto out;
+ }
+
+ err = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+ cmd, reqtype, value, index, buf, size,
+ USB_CTRL_GET_TIMEOUT);
+ if (err > 0 && err <= size)
+ memcpy(data, buf, err);
+ kfree(buf);
+out:
+ return err;
+}
+EXPORT_SYMBOL_GPL(usbnet_read_cmd);
+
+int usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
+ u16 value, u16 index, const void *data, u16 size)
+{
+ void *buf = NULL;
+ int err = -ENOMEM;
+
+ netdev_dbg(dev->net, "usbnet_write_cmd cmd=0x%02x reqtype=%02x"
+ " value=0x%04x index=0x%04x size=%d\n",
+ cmd, reqtype, value, index, size);
+
+ if (data) {
+ buf = kmemdup(data, size, GFP_KERNEL);
+ if (!buf)
+ goto out;
+ }
+
+ err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+ cmd, reqtype, value, index, buf, size,
+ USB_CTRL_SET_TIMEOUT);
+ kfree(buf);
+
+out:
+ return err;
+}
+EXPORT_SYMBOL_GPL(usbnet_write_cmd);
+
+static void usbnet_async_cmd_cb(struct urb *urb)
+{
+ struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+ int status = urb->status;
+
+ if (status < 0)
+ dev_dbg(&urb->dev->dev, "%s failed with %d",
+ __func__, status);
+
+ kfree(req);
+ usb_free_urb(urb);
+}
+
+int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
+ u16 value, u16 index, const void *data, u16 size)
+{
+ struct usb_ctrlrequest *req = NULL;
+ struct urb *urb;
+ int err = -ENOMEM;
+ void *buf = NULL;
+
+ netdev_dbg(dev->net, "usbnet_write_cmd cmd=0x%02x reqtype=%02x"
+ " value=0x%04x index=0x%04x size=%d\n",
+ cmd, reqtype, value, index, size);
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ netdev_err(dev->net, "Error allocating URB in"
+ " %s!\n", __func__);
+ goto fail;
+ }
+
+ if (data) {
+ buf = kmemdup(data, size, GFP_ATOMIC);
+ if (!buf) {
+ netdev_err(dev->net, "Error allocating buffer"
+ " in %s!\n", __func__);
+ goto fail_free;
+ }
+ }
+
+ req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
+ if (!req) {
+ netdev_err(dev->net, "Failed to allocate memory for %s\n",
+ __func__);
+ goto fail_free_buf;
+ }
+
+ req->bRequestType = reqtype;
+ req->bRequest = cmd;
+ req->wValue = cpu_to_le16(value);
+ req->wIndex = cpu_to_le16(index);
+ req->wLength = cpu_to_le16(size);
+
+ usb_fill_control_urb(urb, dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ (void *)req, buf, size,
+ usbnet_async_cmd_cb, req);
+ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err < 0) {
+ netdev_err(dev->net, "Error submitting the control"
+ " message: status=%d\n", err);
+ goto fail_free;
+ }
+ return 0;
+
+fail_free_buf:
+ kfree(buf);
+fail_free:
+ kfree(req);
+ usb_free_urb(urb);
+fail:
+ return err;
+
+}
+EXPORT_SYMBOL_GPL(usbnet_write_cmd_async);
+/*-------------------------------------------------------------------------*/
static int __init usbnet_init(void)
{
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index ddbbb7d..4410e416 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -163,6 +163,12 @@ extern int usbnet_resume(struct usb_interface *);
extern void usbnet_disconnect(struct usb_interface *);
extern void usbnet_device_suggests_idle(struct usbnet *dev);
+extern int usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
+ u16 value, u16 index, void *data, u16 size);
+extern int usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
+ u16 value, u16 index, const void *data, u16 size);
+extern int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
+ u16 value, u16 index, const void *data, u16 size);
/* Drivers that reuse some of the standard USB CDC infrastructure
* (notably, using multiple interfaces according to the CDC
--
1.7.9.5
next prev parent reply other threads:[~2012-10-25 5:47 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-25 5:46 [PATCH v2 00/11] usbnet: usb_control_msg cleanup Ming Lei
2012-10-25 5:46 ` Ming Lei [this message]
2012-10-25 5:46 ` [PATCH v2 03/11] usbnet: cdc-ncm: apply introduced usb command APIs Ming Lei
2012-10-25 5:46 ` [PATCH v2 04/11] usbnet: dm9601: " Ming Lei
2012-10-25 5:46 ` [PATCH v2 05/11] usbnet: int51x1: " Ming Lei
2012-10-25 5:46 ` [PATCH v2 06/11] usbnet: mcs7830: " Ming Lei
2012-10-25 5:47 ` [PATCH v2 07/11] usbnet: net1080: " Ming Lei
2012-10-25 5:47 ` [PATCH v2 09/11] usbnet: sierra_net: " Ming Lei
[not found] ` <1351144024-16596-1-git-send-email-ming.lei-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
2012-10-25 5:46 ` [PATCH v2 02/11] usbnet: asix: " Ming Lei
2012-10-25 5:47 ` [PATCH v2 08/11] usbnet: plusb: " Ming Lei
2012-10-25 5:47 ` [PATCH v2 10/11] usbnet: smsc75xx: " Ming Lei
2012-10-25 5:47 ` [PATCH v2 11/11] usbnet: smsc95xx: " Ming Lei
2012-10-26 7:37 ` [PATCH v2 00/11] usbnet: usb_control_msg cleanup David Miller
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=1351144024-16596-2-git-send-email-ming.lei@canonical.com \
--to=ming.lei@canonical.com \
--cc=davem@davemloft.net \
--cc=gregkh@linuxfoundation.org \
--cc=linux-usb@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=oneukum@suse.de \
/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;
as well as URLs for NNTP newsgroup(s).