diff mbox series

[v2,3/3] usb: f_mass_storage: Stop after the host deconfigures us

Message ID 20210722183811.76441-3-sean.anderson@seco.com
State Deferred
Delegated to: Tom Rini
Headers show
Series [v2,1/3] usb: f_mass_storage: Check bh->state in sleep_thread | expand

Commit Message

Sean Anderson July 22, 2021, 6:38 p.m. UTC
At the moment there is no way to signal to U-Boot from the host that we
are done reading/writing data. This stops the gadget after the host
deconfigures us by selecting config 0. In theory, the host could later
select this configuration again, but this rarely happens.

On Linux this may be accomplished by running

	udisksctl power-off -b /dev/sdX

Signed-off-by: Sean Anderson <sean.anderson@seco.com>
---

(no changes since v1)

 cmd/usb_mass_storage.c              | 3 +++
 drivers/usb/gadget/f_mass_storage.c | 7 ++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c
index d4e619b842..bac4ad87b9 100644
--- a/cmd/usb_mass_storage.c
+++ b/cmd/usb_mass_storage.c
@@ -227,6 +227,9 @@  static int do_usb_mass_storage(struct cmd_tbl *cmdtp, int flag,
 			if (rc == -EPIPE)
 				printf("\rCTRL+C - Operation aborted\n");
 
+			if (rc == -ENOLINK)
+				printf("\rHost closed connection\n");
+
 			rc = CMD_RET_SUCCESS;
 			goto cleanup_register;
 		}
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 92e4f22797..0e7a90683b 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2247,7 +2247,10 @@  static void fsg_disable(struct usb_function *f)
 {
 	struct fsg_dev *fsg = fsg_from_func(f);
 	fsg->common->new_fsg = NULL;
-	raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+	if (fsg->common->running)
+		raise_exception(fsg->common, FSG_STATE_EXIT);
+	else
+		raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -2393,6 +2396,8 @@  int fsg_main_thread(void *common_)
 
 	common->thread_task = NULL;
 
+	if (common->state == FSG_STATE_TERMINATED)
+		return -ENOLINK;
 	return 0;
 }