[PATCH 1/4] g_file_storage: implement ->reset method

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch (as1598) adds support for the new "reset" callback to the
g_file_storage driver.  Resets are handled slightly differently from
disconnects, in that the driver doesn't sync the backing storage file
during a reset but does during a disconnect.

The problem is that a file sync can take a long time if there are many
dirty pages, which can cause the driver's main thread to miss other
USB events if they arrive too quickly.  After a disconnect we
generally don't expect to see other events in the near future, whereas
after a reset we do.

Unfortunately the driver already contains an FSG_STATE_RESET symbol.
The patch renames it to FSG_STATE_CLASS_RESET, because it refers to a
class-specific reset event rather than a general USB port reset, and
uses FSG_STATE_RESET for port resets.  The g_mass_storage driver
shares a source file with g_file_storage; therefore it had to be
modified accordingly.

Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
Reported-by: Chen Peter-B29397 <B29397@xxxxxxxxxxxxx>

---

 drivers/usb/gadget/f_mass_storage.c |    5 +++--
 drivers/usb/gadget/file_storage.c   |   20 ++++++++++++++++----
 drivers/usb/gadget/storage_common.c |    3 ++-
 3 files changed, 21 insertions(+), 7 deletions(-)

Index: usb-3.5/drivers/usb/gadget/storage_common.c
===================================================================
--- usb-3.5.orig/drivers/usb/gadget/storage_common.c
+++ usb-3.5/drivers/usb/gadget/storage_common.c
@@ -279,9 +279,10 @@ enum fsg_state {
 
 	FSG_STATE_IDLE = 0,
 	FSG_STATE_ABORT_BULK_OUT,
-	FSG_STATE_RESET,
+	FSG_STATE_CLASS_RESET,
 	FSG_STATE_INTERFACE_CHANGE,
 	FSG_STATE_CONFIG_CHANGE,
+	FSG_STATE_RESET,
 	FSG_STATE_DISCONNECT,
 	FSG_STATE_EXIT,
 	FSG_STATE_TERMINATED
Index: usb-3.5/drivers/usb/gadget/file_storage.c
===================================================================
--- usb-3.5.orig/drivers/usb/gadget/file_storage.c
+++ usb-3.5/drivers/usb/gadget/file_storage.c
@@ -676,10 +676,18 @@ static void fsg_disconnect(struct usb_ga
 {
 	struct fsg_dev		*fsg = get_gadget_data(gadget);
 
-	DBG(fsg, "disconnect or port reset\n");
+	DBG(fsg, "disconnect\n");
 	raise_exception(fsg, FSG_STATE_DISCONNECT);
 }
 
+static void fsg_reset(struct usb_gadget *gadget)
+{
+	struct fsg_dev		*fsg = get_gadget_data(gadget);
+
+	DBG(fsg, "port reset\n");
+	raise_exception(fsg, FSG_STATE_RESET);
+}
+
 
 static int ep0_queue(struct fsg_dev *fsg)
 {
@@ -816,7 +824,7 @@ static void received_cbi_adsc(struct fsg
 		/* Raise an exception to stop the current operation
 		 * and reinitialize our state. */
 		DBG(fsg, "cbi reset request\n");
-		raise_exception(fsg, FSG_STATE_RESET);
+		raise_exception(fsg, FSG_STATE_CLASS_RESET);
 		return;
 	}
 
@@ -867,7 +875,7 @@ static int class_setup_req(struct fsg_de
 			/* Raise an exception to stop the current operation
 			 * and reinitialize our state. */
 			DBG(fsg, "bulk reset request\n");
-			raise_exception(fsg, FSG_STATE_RESET);
+			raise_exception(fsg, FSG_STATE_CLASS_RESET);
 			value = DELAYED_STATUS;
 			break;
 
@@ -3006,7 +3014,7 @@ static void handle_exception(struct fsg_
 		spin_unlock_irq(&fsg->lock);
 		break;
 
-	case FSG_STATE_RESET:
+	case FSG_STATE_CLASS_RESET:
 		/* In case we were forced against our will to halt a
 		 * bulk endpoint, clear the halt now.  (The SuperH UDC
 		 * requires this.) */
@@ -3050,6 +3058,9 @@ static void handle_exception(struct fsg_
 	case FSG_STATE_DISCONNECT:
 		for (i = 0; i < fsg->nluns; ++i)
 			fsg_lun_fsync_sub(fsg->luns + i);
+		/* FALL THROUGH */
+
+	case FSG_STATE_RESET:
 		do_set_config(fsg, 0);		// Unconfigured state
 		break;
 
@@ -3608,6 +3619,7 @@ static struct usb_gadget_driver		fsg_dri
 	.function	= (char *) fsg_string_product,
 	.unbind		= fsg_unbind,
 	.disconnect	= fsg_disconnect,
+	.reset		= fsg_reset,
 	.setup		= fsg_setup,
 	.suspend	= fsg_suspend,
 	.resume		= fsg_resume,
Index: usb-3.5/drivers/usb/gadget/f_mass_storage.c
===================================================================
--- usb-3.5.orig/drivers/usb/gadget/f_mass_storage.c
+++ usb-3.5/drivers/usb/gadget/f_mass_storage.c
@@ -554,7 +554,7 @@ static int fsg_setup(struct usb_function
 		 * and reinitialize our state.
 		 */
 		DBG(fsg, "bulk reset request\n");
-		raise_exception(fsg->common, FSG_STATE_RESET);
+		raise_exception(fsg->common, FSG_STATE_CLASS_RESET);
 		return DELAYED_STATUS;
 
 	case US_BULK_GET_MAX_LUN:
@@ -2470,7 +2470,7 @@ static void handle_exception(struct fsg_
 		spin_unlock_irq(&common->lock);
 		break;
 
-	case FSG_STATE_RESET:
+	case FSG_STATE_CLASS_RESET:
 		/*
 		 * In case we were forced against our will to halt a
 		 * bulk endpoint, clear the halt now.  (The SuperH UDC
@@ -2511,6 +2511,7 @@ static void handle_exception(struct fsg_
 
 	case FSG_STATE_INTERFACE_CHANGE:
 	case FSG_STATE_DISCONNECT:
+	case FSG_STATE_RESET:
 	case FSG_STATE_COMMAND_PHASE:
 	case FSG_STATE_DATA_PHASE:
 	case FSG_STATE_STATUS_PHASE:

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux