summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/function/storage_common.h
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2017-04-13 16:37:01 -0400
committerFelipe Balbi <felipe.balbi@linux.intel.com>2017-05-16 10:38:33 +0300
commit225785aec726f3edd5077be8f084b0b70ca197a8 (patch)
tree2584fc140786edbf580a7f79f99ffadeda36bc75 /drivers/usb/gadget/function/storage_common.h
parent78db441d2ea0c804bc43a2bf3f894c4f7a6c7788 (diff)
USB: f_mass_storage: improve memory barriers and synchronization
This patch reworks the way f_mass_storage.c handles memory barriers and synchronization: The driver now uses a wait_queue instead of doing its own task-state manipulations (even though only one task will ever use the wait_queue). The thread_wakeup_needed variable is removed. It was only a source of trouble; although it was what the driver tested to see whether it should wake up, what we really wanted to see was whether a USB transfer had completed. All the explicit memory barriers scattered throughout the driver are replaced by a few calls to smp_load_acquire() and smp_store_release(). The inreq_busy and outreq_busy fields are removed. In their place, the driver keeps track of the current I/O direction by splitting BUF_STATE_BUSY into two states: BUF_STATE_SENDING and BUF_STATE_RECEIVING. The buffer states are no longer protected by a lock. Mutual exclusion isn't needed; the state is changed only by the driver's main thread when it owns the buffer, and only by the request completion routine when the gadget core owns the buffer. The do_write() and throw_away_data() routines were reorganized to make efficient use of the new sleeping mechanism. This resulted in the removal of one indentation level in those routines, making the patch appear to be more more complicated than it really is. In a few places, the driver allowed itself to be frozen although it really shouldn't have (in the middle of executing a SCSI command). Those places have been fixed. The logic in the exception handler for aborting transfers and waiting for them to stop has been simplified. Tested-by: Thinh Nguyen <thinhn@synopsys.com> Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/gadget/function/storage_common.h')
-rw-r--r--drivers/usb/gadget/function/storage_common.h7
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/usb/gadget/function/storage_common.h b/drivers/usb/gadget/function/storage_common.h
index e6095dfbf1d5..e0814a960132 100644
--- a/drivers/usb/gadget/function/storage_common.h
+++ b/drivers/usb/gadget/function/storage_common.h
@@ -133,9 +133,10 @@ static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
#define FSG_MAX_LUNS 16
enum fsg_buffer_state {
+ BUF_STATE_SENDING = -2,
+ BUF_STATE_RECEIVING,
BUF_STATE_EMPTY = 0,
- BUF_STATE_FULL,
- BUF_STATE_BUSY
+ BUF_STATE_FULL
};
struct fsg_buffhd {
@@ -151,9 +152,7 @@ struct fsg_buffhd {
unsigned int bulk_out_intended_length;
struct usb_request *inreq;
- int inreq_busy;
struct usb_request *outreq;
- int outreq_busy;
};
enum fsg_state {