Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> 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 <stern@xxxxxxxxxxxxxxxxxxx> > Reported-by: Chen Peter-B29397 <B29397@xxxxxxxxxxxxx> 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: mpn@xxxxxxxxxx>--------------ooO--(_)--Ooo--
Attachment:
pgpn0LmHsjT34.pgp
Description: PGP signature