diff --git a/Documentation/ABI/testing/configfs-usb-gadget-ffs b/Documentation/ABI/testing/configfs-usb-gadget-ffs index e39b27653c65..bf8936ff6d38 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-ffs +++ b/Documentation/ABI/testing/configfs-usb-gadget-ffs @@ -4,6 +4,14 @@ KernelVersion: 3.13 Description: The purpose of this directory is to create and remove it. A corresponding USB function instance is created/removed. - There are no attributes here. - All parameters are set through FunctionFS. + All attributes are read only: + + ============= ============================================ + ready 1 if the function is ready to be used, E.G. + if userspace has written descriptors and + strings to ep0, so the gadget can be + enabled - 0 otherwise. + ============= ============================================ + + All other parameters are set through FunctionFS. diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index 8cd62c466d20..4ec6b775ebba 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -206,6 +206,14 @@ the standard procedure for using FunctionFS (mount it, run the userspace process which implements the function proper). The gadget should be enabled by writing a suitable string to usb_gadget//UDC. +The FFS function provides just one attribute in its function directory: + + ready + +The attribute is read-only and signals if the function is ready (1) to be +used, E.G. if userspace has written descriptors and strings to ep0, so +the gadget can be enabled. + Testing the FFS function ------------------------ diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 6bff6cb93789..be3851cffb73 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -3445,6 +3445,25 @@ static inline struct f_fs_opts *to_ffs_opts(struct config_item *item) func_inst.group); } +static ssize_t f_fs_opts_ready_show(struct config_item *item, char *page) +{ + struct f_fs_opts *opts = to_ffs_opts(item); + int ready; + + ffs_dev_lock(); + ready = opts->dev->desc_ready; + ffs_dev_unlock(); + + return sprintf(page, "%d\n", ready); +} + +CONFIGFS_ATTR_RO(f_fs_opts_, ready); + +static struct configfs_attribute *ffs_attrs[] = { + &f_fs_opts_attr_ready, + NULL, +}; + static void ffs_attr_release(struct config_item *item) { struct f_fs_opts *opts = to_ffs_opts(item); @@ -3458,6 +3477,7 @@ static struct configfs_item_operations ffs_item_ops = { static const struct config_item_type ffs_func_type = { .ct_item_ops = &ffs_item_ops, + .ct_attrs = ffs_attrs, .ct_owner = THIS_MODULE, };