From: Ivo van Doorn <ivdoorn@gmail.com>
To: "John W. Linville" <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org, users@rt2x00.serialmonkey.com
Subject: [PATCH 2/6] rt2x00: Optimize TX_STA_FIFO register reading
Date: Sat, 30 Apr 2011 17:14:23 +0200 [thread overview]
Message-ID: <201104301714.24685.IvDoorn@gmail.com> (raw)
In-Reply-To: <201104301713.47545.IvDoorn@gmail.com>
Add recycling functionality to rt2x00usb_register_read_async.
When the callback function returns true, resubmit the urb to
read the register again.
This optimizes the rt2800usb driver when multiple TX status reports
are pending in the register, because now we don't need to allocate
the rt2x00_async_read_data and urb structure each time.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800usb.c | 9 +++++----
drivers/net/wireless/rt2x00/rt2x00usb.c | 11 +++++++----
drivers/net/wireless/rt2x00/rt2x00usb.h | 4 +++-
3 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index e4f82d2..b5d5f22 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -114,12 +114,12 @@ static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev)
return false;
}
-static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
+static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
int urb_status, u32 tx_status)
{
if (urb_status) {
WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status);
- return;
+ return false;
}
/* try to read all TX_STA_FIFO entries before scheduling txdone_work */
@@ -129,13 +129,14 @@ static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
"drop tx status report.\n");
queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
} else
- rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO,
- rt2800usb_tx_sta_fifo_read_completed);
+ return true;
} else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) {
queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
} else if (rt2800usb_txstatus_pending(rt2x00dev)) {
mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2));
}
+
+ return false;
}
static void rt2800usb_tx_dma_done(struct queue_entry *entry)
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 570184e..e027ebd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -170,19 +170,22 @@ struct rt2x00_async_read_data {
__le32 reg;
struct usb_ctrlrequest cr;
struct rt2x00_dev *rt2x00dev;
- void (*callback)(struct rt2x00_dev *,int,u32);
+ bool (*callback)(struct rt2x00_dev *, int, u32);
};
static void rt2x00usb_register_read_async_cb(struct urb *urb)
{
struct rt2x00_async_read_data *rd = urb->context;
- rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg));
- kfree(urb->context);
+ if (rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg))) {
+ if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
+ kfree(rd);
+ } else
+ kfree(rd);
}
void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
- void (*callback)(struct rt2x00_dev*,int,u32))
+ bool (*callback)(struct rt2x00_dev*, int, u32))
{
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
struct urb *urb;
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 52b09d2..a69f187 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -349,10 +349,12 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev,
* be called from atomic context. The callback will be called
* when the URB completes. Otherwise the function is similar
* to rt2x00usb_register_read().
+ * When the callback function returns false, the memory will be cleaned up,
+ * when it returns true, the urb will be fired again.
*/
void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
- void (*callback)(struct rt2x00_dev*,int,u32));
+ bool (*callback)(struct rt2x00_dev*, int, u32));
/*
* Radio handlers
--
1.7.2.3
next prev parent reply other threads:[~2011-04-30 15:18 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-30 15:13 [PATCH 1/6] rt2x00: Reduce tx status reading timeout Ivo van Doorn
2011-04-30 15:14 ` Ivo van Doorn [this message]
2011-04-30 15:14 ` [PATCH 3/6] rt2x00: Fix optimize register access for rt2800pci Ivo van Doorn
2011-04-30 15:15 ` [PATCH 4/6] rt2x00: Streamline rt2800 eeprom initialisations Ivo van Doorn
2011-04-30 15:15 ` [PATCH 5/6] rt2x00: Introduce capability flag for Bluetooth co-existence Ivo van Doorn
2011-04-30 15:18 ` [PATCH 6/6] rt2x00: Add autowake support for USB hardware Ivo van Doorn
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=201104301714.24685.IvDoorn@gmail.com \
--to=ivdoorn@gmail.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=users@rt2x00.serialmonkey.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 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).