Alan Stern <[email protected]> writes: > 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 <[email protected]> > Reported-by: Chen Peter-B29397 <[email protected]>
Looks good to me.
Even though it makes me wonder whether f_mass_storage isn't missing
something in its original code.
> --- 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
> --- 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,
> --- 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:
--
Best regards, _ _
.o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michał “mina86” Nazarewicz (o o)
ooo +----<email/xmpp: [email protected]>--------------ooO--(_)--Ooo--
pgpEHWQvZohH7.pgp
Description: PGP signature
