On Sun, Jul 03, 2011 at 05:29:33PM +0300, Amit Blay wrote:
> 1. Fix dummy_hcd to let the function handle GET_STATUS(Interface) request.
> 2. Fix a bug in f_loopback Gadget which updated the bmAttribute of
> f_sourcesink instead of f_loopback.
> 3. Update f_sourcesink Gadget to support function suspend & wakeup.
> This is done by adding get_status() & func_suspend() handlers.
> The current status of the function is controlable via debug FS:
> (wakeup capable, wakeup enabled, suspended).
> 
> Signed-off-by: Amit Blay <ab...@codeaurora.org>
> 
> ---
>  drivers/usb/gadget/dummy_hcd.c    |    3 +-
>  drivers/usb/gadget/f_loopback.c   |    2 +-
>  drivers/usb/gadget/f_sourcesink.c |  162 
> +++++++++++++++++++++++++++++++++++++
>  3 files changed, 165 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
> index e755a9d..7f6a2d8 100644
> --- a/drivers/usb/gadget/dummy_hcd.c
> +++ b/drivers/usb/gadget/dummy_hcd.c
> @@ -1496,7 +1496,8 @@ static int handle_control_request(struct dummy_hcd 
> *dum_hcd, struct urb *urb,
>                                          Dev_InRequest) {
>                                       buf[0] = (u8)dum->devstatus;
>                               } else
> -                                     buf[0] = 0;
> +                                     /* Let the function handle this */
> +                                     break;
>                       }
>                       if (urb->transfer_buffer_length > 1)
>                               buf[1] = 0;
> diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
> index ca660d4..75bac6d 100644
> --- a/drivers/usb/gadget/f_loopback.c
> +++ b/drivers/usb/gadget/f_loopback.c
> @@ -427,7 +427,7 @@ int __init loopback_add(struct usb_composite_dev *cdev, 
> bool autoresume)
>  
>       /* support autoresume for remote wakeup testing */
>       if (autoresume)
> -             sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
> +             loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;

this change doesn't belong here.

> diff --git a/drivers/usb/gadget/f_sourcesink.c 
> b/drivers/usb/gadget/f_sourcesink.c
> index 5247f07..5c5da19 100644
> --- a/drivers/usb/gadget/f_sourcesink.c
> +++ b/drivers/usb/gadget/f_sourcesink.c
> @@ -59,6 +59,12 @@ struct f_sourcesink {
>  
>       struct usb_ep           *in_ep;
>       struct usb_ep           *out_ep;
> +
> +     /* Function Power Management */
> +     bool                        func_suspended;
> +     bool                        func_wakeup_capable;
> +     bool                        func_wakeup_enabled;
> +     struct                      device dev;

this should *NOT* have a device of its own. And the way you tabified is
wrong.

>  };
>  
>  static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
> @@ -191,6 +197,79 @@ static struct usb_gadget_strings *sourcesink_strings[] = 
> {
>       NULL,
>  };
>  
> +/*************************** DEVICE ATTRIBUTES ***************************/
> +
> +static ssize_t f_sourcesink_show_func_suspend(struct device *dev,
> +     struct device_attribute *attr,
> +     char *buf)
> +{
> +     struct f_sourcesink *ss = container_of(dev, struct f_sourcesink,
> +             dev);
> +     return sprintf(buf, "%d\n", ss->func_suspended);
> +}
> +
> +static ssize_t f_sourcesink_show_func_wakeup_enabled(struct device *dev,
> +     struct device_attribute *attr,
> +     char *buf)
> +{
> +     struct f_sourcesink *ss = container_of(dev, struct f_sourcesink,
> +             dev);
> +     return sprintf(buf, "%d\n", ss->func_wakeup_enabled);
> +}
> +
> +static ssize_t f_sourcesink_show_func_wakeup_capable(struct device *dev,
> +     struct device_attribute *attr,
> +     char *buf)
> +{
> +     struct f_sourcesink *ss = container_of(dev, struct f_sourcesink,
> +             dev);
> +     return sprintf(buf, "%d\n", ss->func_wakeup_capable);
> +}
> +
> +static ssize_t f_sourcesink_store_func_wakeup_capable(struct device *dev,
> +             struct device_attribute *attr, const char *buf, size_t count)
> +{
> +     struct f_sourcesink *ss = container_of(dev, struct f_sourcesink, dev);
> +     unsigned long func_wakeup_capable;
> +
> +     /* Allows changing function wakeup capable field from the file system */
> +     if (strict_strtoul(buf, 2, &func_wakeup_capable))
> +             return -EINVAL;
> +     ss->func_wakeup_capable = (bool)func_wakeup_capable;
> +     return count;
> +}
> +
> +static ssize_t f_sourcesink_store_func_wakeup_trigger(struct device *dev,
> +             struct device_attribute *attr, const char *buf, size_t count)
> +{
> +     struct f_sourcesink *ss = container_of(dev, struct f_sourcesink, dev);
> +
> +     /* Allows trigerring function wakeup from the file system */
> +     if (!ss->func_wakeup_capable || !ss->func_wakeup_enabled)
> +             return -EINVAL;
> +
> +     if (usb_gadget_wakeup(ss->function.config->cdev->gadget,
> +                                    source_sink_intf.bInterfaceNumber) < 0)
> +             return -EINVAL;
> +     return count;
> +}

why didn't you do this for composite.c ? Then all function drivers will
be able to be tested.

> @@ -199,6 +278,7 @@ sourcesink_bind(struct usb_configuration *c, struct 
> usb_function *f)
>       struct usb_composite_dev *cdev = c->cdev;
>       struct f_sourcesink     *ss = func_to_ss(f);
>       int     id;
> +     int     result = 0;
>  
>       /* allocate interface ID(s) */
>       id = usb_interface_id(c, f);
> @@ -243,12 +323,66 @@ autoconf_fail:
>           (gadget_is_superspeed(c->cdev->gadget) ? "super" :
>            (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
>                       f->name, ss->in_ep->name, ss->out_ep->name);
> +
> +     ss->dev.parent = &cdev->gadget->dev;
> +     ss->dev.release = sourcesink_release;
> +     dev_set_name(&ss->dev, "sourcesink");
> +
> +     result = device_register(&ss->dev);
> +     if (result) {
> +             ERROR(cdev, "failed to register: %d\n", result);
> +             goto err_device_register;
> +     }
> +
> +     result = device_create_file(&ss->dev, &dev_attr_func_suspend);
> +     if (result) {
> +             ERROR(cdev, "device_create_file failed\n", result);
> +             goto err_func_suspend_file;
> +     }
> +
> +     result = device_create_file(&ss->dev, &dev_attr_func_wakeup_enabled);
> +     if (result) {
> +             ERROR(cdev, "device_create_file failed\n", result);
> +             goto err_func_wake_enabled_file;
> +     }
> +
> +     result = device_create_file(&ss->dev, &dev_attr_func_wakeup_capable);
> +     if (result) {
> +             ERROR(cdev, "device_create_file failed\n", result);
> +             goto err_func_wake_capable_file;
> +     }
> +
> +     result = device_create_file(&ss->dev, &dev_attr_func_wakeup_trigger);
> +     if (result) {
> +             ERROR(cdev, "device_create_file failed\n", result);
> +             goto err_func_wake_trigger_file;
> +     }

dude ?!? Make a sysfs group ;-)

-- 
balbi

Attachment: signature.asc
Description: Digital signature

Reply via email to