From: Xiao Jin <jin.xiao@intel.com>
To: akpm@linux-foundation.org, linux-kernel@vger.kernel.org,
mingo@elte.hu, a.p.zijlstra@chello.nl, rusty@rustcorp.com.au,
william.douglas@intel.com, sboyd@codeaurora.org,
gregkh@linuxfoundation.org, jslaby@suse.cz, oliver@neukum.org,
linux-usb@vger.kernel.org
Subject: [PATCH] cdc-acm: put delayed_wb to list
Date: Tue, 08 Oct 2013 17:08:48 +0800 [thread overview]
Message-ID: <1381223328.9531.3.camel@xiaojin> (raw)
From: xiao jin <jin.xiao@intel.com>
Date: Tue, 8 Oct 2013 16:57:29 +0800
Subject: [PATCH] cdc-acm: put delayed_wb to list
If acm_write_start during acm suspend, write acm_wb is backuped
to delayed_wb. When acm resume, the delayed_wb will be started.
This mechanism can only record one write during acm suspend. More
acm write will be abandoned.
This patch is to use list_head to record the write acm_wb during acm
suspend. It can ensure no acm write abandoned.
Signed-off-by: xiao jin <jin.xiao@intel.com>
---
drivers/usb/class/cdc-acm.c | 30 ++++++++++++++++++++----------
drivers/usb/class/cdc-acm.h | 7 ++++++-
2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 9f49bfe..be679be 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -607,6 +607,7 @@ static int acm_tty_write(struct tty_struct *tty,
unsigned long flags;
int wbn;
struct acm_wb *wb;
+ struct delayed_wb *d_wb;
if (!count)
return 0;
@@ -634,12 +635,17 @@ static int acm_tty_write(struct tty_struct *tty,
usb_autopm_get_interface_async(acm->control);
if (acm->susp_count) {
- if (!acm->delayed_wb)
- acm->delayed_wb = wb;
- else
+ d_wb = kmalloc(sizeof(struct delayed_wb), GFP_ATOMIC);
+ if (d_wb == NULL) {
usb_autopm_put_interface_async(acm->control);
- spin_unlock_irqrestore(&acm->write_lock, flags);
- return count; /* A white lie */
+ spin_unlock_irqrestore(&acm->write_lock, flags);
+ return -ENOMEM;
+ } else {
+ d_wb->wb = wb;
+ list_add_tail(&d_wb->list, &acm->delayed_wb_list);
+ spin_unlock_irqrestore(&acm->write_lock, flags);
+ return count; /* A white lie */
+ }
}
usb_mark_last_busy(acm->dev);
@@ -1255,6 +1261,7 @@ made_compressed_probe:
snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
snd->instance = acm;
}
+ INIT_LIST_HEAD(&acm->delayed_wb_list);
usb_set_intfdata(intf, acm);
@@ -1449,6 +1456,7 @@ static int acm_resume(struct usb_interface *intf)
{
struct acm *acm = usb_get_intfdata(intf);
struct acm_wb *wb;
+ struct delayed_wb *d_wb, *nd_wb;
int rv = 0;
int cnt;
@@ -1464,14 +1472,16 @@ static int acm_resume(struct usb_interface
*intf)
rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
spin_lock_irq(&acm->write_lock);
- if (acm->delayed_wb) {
- wb = acm->delayed_wb;
- acm->delayed_wb = NULL;
+ list_for_each_entry_safe(d_wb, nd_wb,
+ &acm->delayed_wb_list, list) {
+ wb = d_wb->wb;
+ list_del(&d_wb->list);
+ kfree(d_wb);
spin_unlock_irq(&acm->write_lock);
acm_start_wb(acm, wb);
- } else {
- spin_unlock_irq(&acm->write_lock);
+ spin_lock_irq(&acm->write_lock);
}
+ spin_unlock_irq(&acm->write_lock);
/*
* delayed error checking because we must
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index 0f76e4a..5eed93f 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -79,6 +79,11 @@ struct acm_rb {
struct acm *instance;
};
+struct delayed_wb {
+ struct list_head list;
+ struct acm_wb *wb;
+}
+
struct acm {
struct usb_device *dev; /* the corresponding usb device */
struct usb_interface *control; /* control interface */
@@ -117,7 +122,7 @@ struct acm {
unsigned int throttled:1; /* actually throttled */
unsigned int throttle_req:1; /* throttle requested */
u8 bInterval;
- struct acm_wb *delayed_wb; /* write queued for a device about to be
woken */
+ struct list_head delayed_wb_list; /* delayed wb list */
};
#define CDC_DATA_INTERFACE_TYPE 0x0a
--
1.7.1
next reply other threads:[~2013-10-08 8:57 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-08 9:08 Xiao Jin [this message]
2013-10-14 18:10 ` [PATCH] USB: cdc-acm: put delayed_wb to list Greg KH
2013-10-15 0:50 ` Xiao Jin
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=1381223328.9531.3.camel@xiaojin \
--to=jin.xiao@intel.com \
--cc=a.p.zijlstra@chello.nl \
--cc=akpm@linux-foundation.org \
--cc=gregkh@linuxfoundation.org \
--cc=jslaby@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=oliver@neukum.org \
--cc=rusty@rustcorp.com.au \
--cc=sboyd@codeaurora.org \
--cc=william.douglas@intel.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.