Commit a21d4fed authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

[PATCH] USB Gadget: file_storage: remove "volatile" declarations

This patch (as612) removes the "volatile" declarations from the
file-storage gadget.  It turns out that they aren't needed for anything
much; adding a few memory barriers does a sufficient job.

The patch also removes a wait_queue.  Not much point having a queue when
only one task is ever going to be on it!
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent bd39b7f1
...@@ -239,7 +239,6 @@ ...@@ -239,7 +239,6 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/utsname.h> #include <linux/utsname.h>
#include <linux/wait.h>
#include <linux/usb_ch9.h> #include <linux/usb_ch9.h>
#include <linux/usb_gadget.h> #include <linux/usb_gadget.h>
...@@ -251,7 +250,7 @@ ...@@ -251,7 +250,7 @@
#define DRIVER_DESC "File-backed Storage Gadget" #define DRIVER_DESC "File-backed Storage Gadget"
#define DRIVER_NAME "g_file_storage" #define DRIVER_NAME "g_file_storage"
#define DRIVER_VERSION "20 October 2004" #define DRIVER_VERSION "28 November 2005"
static const char longname[] = DRIVER_DESC; static const char longname[] = DRIVER_DESC;
static const char shortname[] = DRIVER_NAME; static const char shortname[] = DRIVER_NAME;
...@@ -588,7 +587,7 @@ enum fsg_buffer_state { ...@@ -588,7 +587,7 @@ enum fsg_buffer_state {
struct fsg_buffhd { struct fsg_buffhd {
void *buf; void *buf;
dma_addr_t dma; dma_addr_t dma;
volatile enum fsg_buffer_state state; enum fsg_buffer_state state;
struct fsg_buffhd *next; struct fsg_buffhd *next;
/* The NetChip 2280 is faster, and handles some protocol faults /* The NetChip 2280 is faster, and handles some protocol faults
...@@ -597,9 +596,9 @@ struct fsg_buffhd { ...@@ -597,9 +596,9 @@ struct fsg_buffhd {
unsigned int bulk_out_intended_length; unsigned int bulk_out_intended_length;
struct usb_request *inreq; struct usb_request *inreq;
volatile int inreq_busy; int inreq_busy;
struct usb_request *outreq; struct usb_request *outreq;
volatile int outreq_busy; int outreq_busy;
}; };
enum fsg_state { enum fsg_state {
...@@ -637,11 +636,11 @@ struct fsg_dev { ...@@ -637,11 +636,11 @@ struct fsg_dev {
struct usb_ep *ep0; // Handy copy of gadget->ep0 struct usb_ep *ep0; // Handy copy of gadget->ep0
struct usb_request *ep0req; // For control responses struct usb_request *ep0req; // For control responses
volatile unsigned int ep0_req_tag; unsigned int ep0_req_tag;
const char *ep0req_name; const char *ep0req_name;
struct usb_request *intreq; // For interrupt responses struct usb_request *intreq; // For interrupt responses
volatile int intreq_busy; int intreq_busy;
struct fsg_buffhd *intr_buffhd; struct fsg_buffhd *intr_buffhd;
unsigned int bulk_out_maxpacket; unsigned int bulk_out_maxpacket;
...@@ -671,7 +670,6 @@ struct fsg_dev { ...@@ -671,7 +670,6 @@ struct fsg_dev {
struct fsg_buffhd *next_buffhd_to_drain; struct fsg_buffhd *next_buffhd_to_drain;
struct fsg_buffhd buffhds[NUM_BUFFERS]; struct fsg_buffhd buffhds[NUM_BUFFERS];
wait_queue_head_t thread_wqh;
int thread_wakeup_needed; int thread_wakeup_needed;
struct completion thread_notifier; struct completion thread_notifier;
struct task_struct *thread_task; struct task_struct *thread_task;
...@@ -1076,11 +1074,13 @@ static int populate_config_buf(struct usb_gadget *gadget, ...@@ -1076,11 +1074,13 @@ static int populate_config_buf(struct usb_gadget *gadget,
/* These routines may be called in process context or in_irq */ /* These routines may be called in process context or in_irq */
/* Caller must hold fsg->lock */
static void wakeup_thread(struct fsg_dev *fsg) static void wakeup_thread(struct fsg_dev *fsg)
{ {
/* Tell the main thread that something has happened */ /* Tell the main thread that something has happened */
fsg->thread_wakeup_needed = 1; fsg->thread_wakeup_needed = 1;
wake_up_all(&fsg->thread_wqh); if (fsg->thread_task)
wake_up_process(fsg->thread_task);
} }
...@@ -1167,11 +1167,12 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) ...@@ -1167,11 +1167,12 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
usb_ep_fifo_flush(ep); usb_ep_fifo_flush(ep);
/* Hold the lock while we update the request and buffer states */ /* Hold the lock while we update the request and buffer states */
smp_wmb();
spin_lock(&fsg->lock); spin_lock(&fsg->lock);
bh->inreq_busy = 0; bh->inreq_busy = 0;
bh->state = BUF_STATE_EMPTY; bh->state = BUF_STATE_EMPTY;
spin_unlock(&fsg->lock);
wakeup_thread(fsg); wakeup_thread(fsg);
spin_unlock(&fsg->lock);
} }
static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
...@@ -1188,11 +1189,12 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) ...@@ -1188,11 +1189,12 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
usb_ep_fifo_flush(ep); usb_ep_fifo_flush(ep);
/* Hold the lock while we update the request and buffer states */ /* Hold the lock while we update the request and buffer states */
smp_wmb();
spin_lock(&fsg->lock); spin_lock(&fsg->lock);
bh->outreq_busy = 0; bh->outreq_busy = 0;
bh->state = BUF_STATE_FULL; bh->state = BUF_STATE_FULL;
spin_unlock(&fsg->lock);
wakeup_thread(fsg); wakeup_thread(fsg);
spin_unlock(&fsg->lock);
} }
...@@ -1209,11 +1211,12 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) ...@@ -1209,11 +1211,12 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
usb_ep_fifo_flush(ep); usb_ep_fifo_flush(ep);
/* Hold the lock while we update the request and buffer states */ /* Hold the lock while we update the request and buffer states */
smp_wmb();
spin_lock(&fsg->lock); spin_lock(&fsg->lock);
fsg->intreq_busy = 0; fsg->intreq_busy = 0;
bh->state = BUF_STATE_EMPTY; bh->state = BUF_STATE_EMPTY;
spin_unlock(&fsg->lock);
wakeup_thread(fsg); wakeup_thread(fsg);
spin_unlock(&fsg->lock);
} }
#else #else
...@@ -1264,8 +1267,8 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) ...@@ -1264,8 +1267,8 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
fsg->cbbuf_cmnd_size = req->actual; fsg->cbbuf_cmnd_size = req->actual;
memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size);
spin_unlock(&fsg->lock);
wakeup_thread(fsg); wakeup_thread(fsg);
spin_unlock(&fsg->lock);
} }
#else #else
...@@ -1517,8 +1520,8 @@ static int fsg_setup(struct usb_gadget *gadget, ...@@ -1517,8 +1520,8 @@ static int fsg_setup(struct usb_gadget *gadget,
/* Use this for bulk or interrupt transfers, not ep0 */ /* Use this for bulk or interrupt transfers, not ep0 */
static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
struct usb_request *req, volatile int *pbusy, struct usb_request *req, int *pbusy,
volatile enum fsg_buffer_state *state) enum fsg_buffer_state *state)
{ {
int rc; int rc;
...@@ -1526,8 +1529,11 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, ...@@ -1526,8 +1529,11 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
dump_msg(fsg, "bulk-in", req->buf, req->length); dump_msg(fsg, "bulk-in", req->buf, req->length);
else if (ep == fsg->intr_in) else if (ep == fsg->intr_in)
dump_msg(fsg, "intr-in", req->buf, req->length); dump_msg(fsg, "intr-in", req->buf, req->length);
spin_lock_irq(&fsg->lock);
*pbusy = 1; *pbusy = 1;
*state = BUF_STATE_BUSY; *state = BUF_STATE_BUSY;
spin_unlock_irq(&fsg->lock);
rc = usb_ep_queue(ep, req, GFP_KERNEL); rc = usb_ep_queue(ep, req, GFP_KERNEL);
if (rc != 0) { if (rc != 0) {
*pbusy = 0; *pbusy = 0;
...@@ -1547,14 +1553,23 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, ...@@ -1547,14 +1553,23 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
static int sleep_thread(struct fsg_dev *fsg) static int sleep_thread(struct fsg_dev *fsg)
{ {
int rc; int rc = 0;
/* Wait until a signal arrives or we are woken up */ /* Wait until a signal arrives or we are woken up */
rc = wait_event_interruptible(fsg->thread_wqh, for (;;) {
fsg->thread_wakeup_needed); try_to_freeze();
set_current_state(TASK_INTERRUPTIBLE);
if (signal_pending(current)) {
rc = -EINTR;
break;
}
if (fsg->thread_wakeup_needed)
break;
schedule();
}
__set_current_state(TASK_RUNNING);
fsg->thread_wakeup_needed = 0; fsg->thread_wakeup_needed = 0;
try_to_freeze(); return rc;
return (rc ? -EINTR : 0);
} }
...@@ -1791,6 +1806,7 @@ static int do_write(struct fsg_dev *fsg) ...@@ -1791,6 +1806,7 @@ static int do_write(struct fsg_dev *fsg)
if (bh->state == BUF_STATE_EMPTY && !get_some_more) if (bh->state == BUF_STATE_EMPTY && !get_some_more)
break; // We stopped early break; // We stopped early
if (bh->state == BUF_STATE_FULL) { if (bh->state == BUF_STATE_FULL) {
smp_rmb();
fsg->next_buffhd_to_drain = bh->next; fsg->next_buffhd_to_drain = bh->next;
bh->state = BUF_STATE_EMPTY; bh->state = BUF_STATE_EMPTY;
...@@ -2359,6 +2375,7 @@ static int throw_away_data(struct fsg_dev *fsg) ...@@ -2359,6 +2375,7 @@ static int throw_away_data(struct fsg_dev *fsg)
/* Throw away the data in a filled buffer */ /* Throw away the data in a filled buffer */
if (bh->state == BUF_STATE_FULL) { if (bh->state == BUF_STATE_FULL) {
smp_rmb();
bh->state = BUF_STATE_EMPTY; bh->state = BUF_STATE_EMPTY;
fsg->next_buffhd_to_drain = bh->next; fsg->next_buffhd_to_drain = bh->next;
...@@ -3024,6 +3041,7 @@ static int get_next_command(struct fsg_dev *fsg) ...@@ -3024,6 +3041,7 @@ static int get_next_command(struct fsg_dev *fsg)
if ((rc = sleep_thread(fsg)) != 0) if ((rc = sleep_thread(fsg)) != 0)
return rc; return rc;
} }
smp_rmb();
rc = received_cbw(fsg, bh); rc = received_cbw(fsg, bh);
bh->state = BUF_STATE_EMPTY; bh->state = BUF_STATE_EMPTY;
...@@ -4072,7 +4090,6 @@ static int __init fsg_alloc(void) ...@@ -4072,7 +4090,6 @@ static int __init fsg_alloc(void)
spin_lock_init(&fsg->lock); spin_lock_init(&fsg->lock);
init_rwsem(&fsg->filesem); init_rwsem(&fsg->filesem);
kref_init(&fsg->ref); kref_init(&fsg->ref);
init_waitqueue_head(&fsg->thread_wqh);
init_completion(&fsg->thread_notifier); init_completion(&fsg->thread_notifier);
the_fsg = fsg; the_fsg = fsg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment